My monthly commit. I wonder what I broke.

Contains some stuff to get twig working a little better.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3132 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2009-03-03 01:52:30 +00:00
parent ed0cb0749b
commit b763b5594d
53 changed files with 1588 additions and 851 deletions

View File

@ -180,6 +180,7 @@ trace_t Cam_DoTrace(vec3_t vec1, vec3_t vec2)
memset(&pmove, 0, sizeof(pmove));
pmove.numphysent = 1;
memset(&pmove.physents[0], 0, sizeof(physent_t));
VectorClear (pmove.physents[0].origin);
pmove.physents[0].model = cl.worldmodel;
#endif

View File

@ -1448,7 +1448,7 @@ void CL_TransitionPacketEntities(packet_entities_t *newpack, packet_entities_t *
}
le = &cl.lerpents[snew->number];
VectorSubtract(snew->origin, sold->origin, move)
VectorSubtract(snew->origin, sold->origin, move);
if (DotProduct(move, move) > 200*200 || snew->modelindex != sold->modelindex)
{
sold = snew; //teleported?
@ -1630,7 +1630,7 @@ void CL_LinkPacketEntities (void)
}
VectorCopy(le->origin, ent->origin)
VectorCopy(le->origin, ent->origin);
//bots or powerup glows. items always glow, powerups can be disabled
if (state->modelindex != cl_playerindex || r_powerupglow.value)
@ -2701,7 +2701,7 @@ void CL_AddFlagModels (entity_t *ent, int team)
newent->origin[i] = ent->origin[i] - offs*v_forward[i] + 22*v_right[i];
newent->origin[2] -= 16;
VectorCopy (ent->angles, newent->angles)
VectorCopy (ent->angles, newent->angles);
newent->angles[2] -= 45;
VectorCopy(newent->angles, angles);
@ -3102,6 +3102,7 @@ void CL_SetSolidEntities (void)
packet_entities_t *pak;
entity_state_t *state;
memset(&pmove.physents[0], 0, sizeof(physent_t));
pmove.physents[0].model = cl.worldmodel;
VectorClear (pmove.physents[0].origin);
pmove.physents[0].info = 0;
@ -3122,6 +3123,7 @@ void CL_SetSolidEntities (void)
if ( cl.model_precache[state->modelindex]->hulls[1].firstclipnode
|| cl.model_precache[state->modelindex]->clipbox )
{
memset(&pmove.physents[pmove.numphysent], 0, sizeof(physent_t));
pmove.physents[pmove.numphysent].model = cl.model_precache[state->modelindex];
VectorCopy (state->origin, pmove.physents[pmove.numphysent].origin);
VectorCopy (state->angles, pmove.physents[pmove.numphysent].angles);
@ -3271,9 +3273,8 @@ void CL_SetSolidPlayers (int playernum)
if (pplayer->flags & PF_DEAD)
continue; // dead players aren't solid
pent->model = 0;
memset(pent, 0, sizeof(physent_t));
VectorCopy(pplayer->origin, pent->origin);
pent->angles[0] = pent->angles[1] = pent->angles[2] = 0; //don't bother rotating - only useful with bsps
VectorCopy(player_mins, pent->mins);
VectorCopy(player_maxs, pent->maxs);
if (++pmove.numphysent == MAX_PHYSENTS) //we just hit 88 miles per hour.

View File

@ -545,6 +545,11 @@ qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname, unsigned
if (!(flags & DLLF_OVERWRITE) && CL_CheckFile(localname))
return true;
#ifndef CLIENTONLY
if (sv.state)
return true;
#endif
//ZOID - can't download when recording
if (cls.demorecording)
{
@ -738,7 +743,7 @@ void Model_NextDownload (void)
int i;
// extern char gamedirfile[];
Con_TPrintf (TLC_CHECKINGMODELS);
// Con_TPrintf (TLC_CHECKINGMODELS);
/* if (cls.downloadnumber == 0)
{
@ -905,12 +910,15 @@ int CL_LoadModels(int stage)
{
if (!cl.model_name[1][0])
Host_EndGame("Worldmodel name wasn't sent\n");
else
Host_EndGame("Worldmodel wasn't loaded\n");
// else
// return stage;
// Host_EndGame("Worldmodel wasn't loaded\n");
}
if (cl.worldmodel->fromgame == fg_quake)
if (cl.worldmodel && cl.worldmodel->fromgame == fg_quake)
cl.hexen2pickups = cl.worldmodel->hulls[MAX_MAP_HULLSDH2-1].available;
else
cl.hexen2pickups = false;
R_CheckSky();
@ -952,8 +960,8 @@ int CL_LoadModels(int stage)
if (atstage())
{
loadmodel = cl.worldmodel;
if (!loadmodel || loadmodel->type == mod_dummy)
Host_EndGame("No worldmodel was loaded\n");
// if (!loadmodel || loadmodel->type == mod_dummy)
// Host_EndGame("No worldmodel was loaded\n");
Mod_NowLoadExternal();
endstage();
@ -964,8 +972,9 @@ int CL_LoadModels(int stage)
if (atstage())
{
loadmodel = cl.worldmodel;
if (!loadmodel || loadmodel->type == mod_dummy)
Host_EndGame("No worldmodel was loaded\n");
// if (!loadmodel || loadmodel->type == mod_dummy)
// Host_EndGame("No worldmodel was loaded\n");
cl.model_precaches_added = false;
R_NewMap ();
pmove.physents[0].model = cl.worldmodel;
@ -1015,7 +1024,7 @@ void Sound_NextDownload (void)
int i;
Con_TPrintf (TLC_CHECKINGSOUNDS);
// Con_TPrintf (TLC_CHECKINGSOUNDS);
#ifdef CSQC_DAT
if (cls.fteprotocolextensions & PEXT_CSQC)
@ -1955,7 +1964,8 @@ void CL_ParseServerData (void)
if (protover == PROTOCOL_VERSION_FTE)
{
cls.fteprotocolextensions = MSG_ReadLong();
Con_TPrintf (TL_FTEEXTENSIONS, cls.fteprotocolextensions);
if (developer.value || cl_shownet.value)
Con_TPrintf (TL_FTEEXTENSIONS, cls.fteprotocolextensions);
continue;
}
if (protover == PROTOCOL_VERSION_QW) //this ends the version info
@ -2361,9 +2371,18 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
//fill in the csqc stuff
Info_SetValueForStarKey(cl.serverinfo, "*csprogs", va("%i", cl_dp_csqc_progscrc), sizeof(cl.serverinfo));
Info_SetValueForStarKey(cl.serverinfo, "*csprogssize", va("%i", cl_dp_csqc_progssize), sizeof(cl.serverinfo));
Info_SetValueForStarKey(cl.serverinfo, "*csprogsname", va("%i", cl_dp_csqc_progsname), sizeof(cl.serverinfo));
if (!cl_dp_csqc_progscrc)
{
Info_RemoveKey(cl.serverinfo, "*csprogs");
Info_RemoveKey(cl.serverinfo, "*csprogssize");
Info_RemoveKey(cl.serverinfo, "*csprogsname");
}
else
{
Info_SetValueForStarKey(cl.serverinfo, "*csprogs", va("%i", cl_dp_csqc_progscrc), sizeof(cl.serverinfo));
Info_SetValueForStarKey(cl.serverinfo, "*csprogssize", va("%i", cl_dp_csqc_progssize), sizeof(cl.serverinfo));
Info_SetValueForStarKey(cl.serverinfo, "*csprogsname", va("%i", cl_dp_csqc_progsname), sizeof(cl.serverinfo));
}
//update gamemode
if (gametype == 1)
@ -2873,7 +2892,7 @@ qboolean CL_CheckBaselines (int size)
return false;
size = (size + 64) & ~63; // round up to next 64
if (size < cl_baselines_count)
if (size <= cl_baselines_count)
return true;
cl_baselines = BZ_Realloc(cl_baselines, sizeof(*cl_baselines)*size);
@ -4383,6 +4402,8 @@ void CL_ParsePrecache(void)
Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
cl.model_precache[i] = model;
strcpy (cl.model_name[i], s);
cl.model_precaches_added = true;
}
else
Con_Printf("svc_precache: model index %i outside range %i...%i\n", i, 1, MAX_MODELS);
@ -5338,6 +5359,10 @@ void CLNQ_ParseServerMessage (void)
cl_dp_csqc_progssize = atoi(s+14);
else if (!strncmp(s, "csqc_progcrc ", 13))
cl_dp_csqc_progscrc = atoi(s+13);
else if (!strncmp(s, "cl_fullpitch ", 13) || !strncmp(s, "pq_fullpitch ", 13))
{
//
}
else
{
Cbuf_AddText (s, RESTRICT_SERVER); //no cheating here...
@ -5435,7 +5460,11 @@ void CLNQ_ParseServerMessage (void)
if (i >= MAX_CLIENTS)
MSG_ReadString();
else
{
strcpy(cl.players[i].name, MSG_ReadString());
if (*cl.players[i].name)
cl.players[i].userid = i+1;
}
break;
case svc_updatefrags:
@ -5448,22 +5477,22 @@ void CLNQ_ParseServerMessage (void)
break;
case svc_updatecolors:
{
int a;
Sbar_Changed ();
i = MSG_ReadByte ();
a = MSG_ReadByte ();
if (i >= MAX_CLIENTS)
break;
//FIXME:!!!!
int a;
i = MSG_ReadByte ();
a = MSG_ReadByte ();
if (i < MAX_CLIENTS)
{
cl.players[i].rtopcolor = a&0x0f;
cl.players[i].rbottomcolor = (a&0xf0)>>4;
cl.players[i].rtopcolor = a&0x0f;
cl.players[i].rbottomcolor = (a&0xf0)>>4;
sprintf(cl.players[i].team, "%2d", cl.players[i].rbottomcolor);
if (cls.state == ca_active)
Skin_Find (&cl.players[i]);
if (cls.state == ca_active)
Skin_Find (&cl.players[i]);
Sbar_Changed ();
CL_NewTranslation (i);
Sbar_Changed ();
CL_NewTranslation (i);
}
}
break;
case svc_lightstyle:

View File

@ -817,6 +817,19 @@ void CL_PredictMovePNum (int pnum)
}
*/ }
#endif
if (!from->playerstate[cl.playernum[pnum]].messagenum)
{
//no player states?? put the view on an ent
if (cl.playernum[pnum] < cl.maxlerpents)
{
// Con_Printf("Using lerped pos\n");
org = cl.lerpents[cl.playernum[pnum]+1].origin;
vel = vec3_origin;
goto fixedorg;
}
}
if (((cl_nopred.value && cls.demoplayback!=DPB_MVD && cls.demoplayback != DPB_EZTV)|| cl.fixangle))
{
fixedorg:

View File

@ -1053,6 +1053,8 @@ void SCR_CalcRefdef (void)
r_refdef.fov_x = 10;
else if (r_refdef.fov_x > 170)
r_refdef.fov_x = 170;
r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);

View File

@ -419,11 +419,15 @@ typedef struct {
float framechange; //marks time of last frame change - for halflife model sequencing.
float oldframechange;
float lerprate; //inverse rate...
vec3_t origin;
vec3_t origin; //current render position
vec3_t angles;
vec3_t forigin; //when the frame changed
vec3_t fangles;
vec3_t foldorigin;//
vec3_t foldangles;
trailstate_t *trailstate; //when to next throw out a trail
trailstate_t *emitstate; //when to next emit
unsigned short frame;
unsigned short frame, oldframe;
} lerpents_t;
//
// the client_state_t structure is wiped completely at every
@ -539,6 +543,8 @@ typedef struct
char model_csqcname[MAX_CSQCMODELS][MAX_QPATH];
struct model_s *model_csqcprecache[MAX_CSQCMODELS];
qboolean model_precaches_added;
//used for q2 sky/configstrings
char skyname[MAX_QPATH];
float skyrotate;
@ -690,6 +696,7 @@ extern float server_version; // version of server we connected to
//
dlight_t *CL_AllocDlight (int key);
dlight_t *CL_NewDlight (int key, float x, float y, float z, float radius, float time, int type);
dlight_t *CL_NewDlightRGB (int key, float x, float y, float z, float radius, float time, float r, float g, float b);
void CL_DecayLights (void);
void CL_ParseDelta (struct entity_state_s *from, struct entity_state_s *to, int bits, qboolean);

View File

@ -592,6 +592,7 @@ void CLQ3_ParseGameState(void)
if (!cl.worldmodel)
Host_EndGame("CGame didn't set a map.\n");
cl.model_precaches_added = false;
R_NewMap ();
SCR_EndLoadingPlaque();
@ -943,7 +944,8 @@ void CLQ3_SendCmd(usercmd_t *cmd)
// begin a client move command, if any
if( cmdcount )
{
if(!ccs.snap.valid ||
extern cvar_t cl_nodelta;
if(cl_nodelta.value || !ccs.snap.valid ||
ccs.snap.serverMessageNum != ccs.serverMessageNum)
MSG_WriteBits(&msg, clcq3_nodeltaMove, 8); // no compression
else

View File

@ -1319,8 +1319,6 @@ void MasterInfo_Begin(void)
Master_AddMaster("qwmaster.ocrana.de:27000", MT_MASTERQW, "Ocrana2 master server.");
Master_AddMaster("213.221.174.165:27000", MT_MASTERQW, "unknown1 master server.");
Master_AddMaster("195.74.0.8", MT_MASTERQW, "unknown2 master server.");
Master_AddMaster("192.246.40.37", MT_MASTERQW, "unknown3 master server.");
Master_AddMaster("192.246.40.37:27006", MT_MASTERQW, "unknown4 master server.");
Master_AddMaster("204.182.161.2", MT_MASTERQW, "unknown5 master server.");
Master_AddMaster("255.255.255.255:27500", MT_BCASTQW, "Nearby QuakeWorld UDP servers.");

View File

@ -201,7 +201,10 @@ static void PClassic_DrawParticles(void)
#endif
if (!active_particles)
{
RQ_RenderDistAndClear();
return;
}
switch(qrenderer)
{
@ -229,6 +232,7 @@ static void PClassic_DrawParticles(void)
break;
#endif
default:
RQ_RenderDistAndClear();
return;
}
@ -367,13 +371,9 @@ static void PClassic_DrawParticles(void)
//this... is hard to explain.
//please don't make me do so.
#ifdef RGLQUAKE
RSpeedRemark();
RQ_RenderDistAndClear();
RSpeedEnd(RSPEED_PARTICLESDRAW);
#endif
}
//called to set up the rendering state (opengl)

View File

@ -3600,7 +3600,6 @@ static void PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_globa
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
float *matrix[4];
float temp[3][4];
float mult[3][4];
skelobject_t *skelobj;

View File

@ -167,6 +167,8 @@ qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
for (i=0 ; i< pmove.numphysent ; i++)
{
pe = &pmove.physents[i];
if (pe->nonsolid)
continue;
if (pe->model)
{
VectorSubtract(start, pe->origin, ts);

View File

@ -423,7 +423,9 @@ double Media_TweekCaptureFrameTime(double time);
void MYgluPerspective(double fovx, double fovy, double zNear, double zFar);
void R_MarkLeaves (void);
void R_MarkLeaves_Q1 (void);
void R_MarkLeaves_Q2 (void);
void R_MarkLeaves_Q3 (void);
void R_SetFrustum (void);
void R_SetRenderer(int wanted);
void RQ_Init(void);

View File

@ -165,9 +165,9 @@ cvar_t scr_viewsize = SCVARFC("viewsize", "100",
cvar_t vid_conautoscale = SCVARF ("vid_conautoscale", "0",
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK);
cvar_t vid_conheight = SCVARF ("vid_conheight", "480",
cvar_t vid_conheight = SCVARF ("vid_conheight", "0",
CVAR_ARCHIVE);
cvar_t vid_conwidth = SCVARF ("vid_conwidth", "640",
cvar_t vid_conwidth = SCVARF ("vid_conwidth", "0",
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK);
//see R_RestartRenderer_f for the effective default 'if (newr.renderer == -1)'.
cvar_t vid_renderer = SCVARF ("vid_renderer", "",
@ -2407,71 +2407,75 @@ mleaf_t *r_vischain; // linked list of visible leafs
R_MarkLeaves
===============
*/
#ifdef Q3BSPS
void R_MarkLeaves_Q3 (void)
{
qbyte *vis;
int i;
void R_MarkLeaves (void)
int cluster;
mleaf_t *leaf;
if (r_oldviewcluster == r_viewcluster && !r_novis.value && r_viewcluster != -1)
return;
// development aid to let you run around and see exactly where
// the pvs ends
// if (r_lockpvs->value)
// return;
r_vischain = NULL;
r_visframecount++;
r_oldviewcluster = r_viewcluster;
if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis )
{
// mark everything
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
if (!leaf->nummarksurfaces)
{
continue;
}
leaf->visframe = r_visframecount;
leaf->vischain = r_vischain;
r_vischain = leaf;
}
}
else
{
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel);
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
cluster = leaf->cluster;
if (cluster == -1 || !leaf->nummarksurfaces)
{
continue;
}
if (vis[cluster>>3] & (1<<(cluster&7)))
{
leaf->visframe = r_visframecount;
leaf->vischain = r_vischain;
r_vischain = leaf;
}
}
}
}
#endif
#ifdef Q2BSPS
void R_MarkLeaves_Q2 (void)
{
qbyte fatvis[MAX_MAP_LEAFS/8];
qbyte *vis;
mnode_t *node;
int i;
qbyte solid[4096];
#ifdef Q3BSPS
if (cl.worldmodel->fromgame == fg_quake3)
{
int cluster;
mleaf_t *leaf;
if (r_oldviewcluster == r_viewcluster && !r_novis.value && r_viewcluster != -1)
return;
int cluster;
mleaf_t *leaf;
// development aid to let you run around and see exactly where
// the pvs ends
// if (r_lockpvs->value)
// return;
r_vischain = NULL;
r_visframecount++;
r_oldviewcluster = r_viewcluster;
if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis )
{
// mark everything
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
if ( !leaf->nummarksurfaces ) {
continue;
}
leaf->visframe = r_visframecount;
leaf->vischain = r_vischain;
r_vischain = leaf;
}
return;
}
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel);
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
cluster = leaf->cluster;
if ( cluster == -1 || !leaf->nummarksurfaces ) {
continue;
}
if ( vis[cluster>>3] & (1<<(cluster&7)) ) {
leaf->visframe = r_visframecount;
leaf->vischain = r_vischain;
r_vischain = leaf;
}
}
return;
}
#endif
#ifdef Q2BSPS
if (cl.worldmodel->fromgame == fg_quake2)
{
int c;
mleaf_t *leaf;
int cluster;
if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2)
return;
@ -2525,6 +2529,14 @@ void R_MarkLeaves (void)
}
#endif
void R_MarkLeaves_Q1 (void)
{
qbyte fatvis[MAX_MAP_LEAFS/8];
qbyte *vis;
mnode_t *node;
int i;
qbyte solid[4096];
if (((r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2) && !r_novis.value) || r_novis.value == 2)
return;
@ -2541,7 +2553,7 @@ void R_MarkLeaves (void)
vis = solid;
memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
}
else if (r_viewleaf2)
else if (r_viewleaf2 && r_viewleaf2 != r_viewleaf)
{
int c;
Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis);
@ -2572,7 +2584,6 @@ void R_MarkLeaves (void)
}
mplane_t frustum[4];

View File

@ -280,9 +280,13 @@ qbyte *Skin_Cache8 (skin_t *skin)
raw = COM_LoadTempFile (name);
if (!raw)
{
Con_Printf ("Couldn't load skin %s\n", name);
sprintf (name, "skins/%s.pcx", baseskin.string);
raw = COM_LoadTempFile (name);
if (strcmp(skin->name, baseskin.string))
{
//if its not already the base skin, try the base (and warn if anything not base couldn't load).
Con_Printf ("Couldn't load skin %s\n", name);
sprintf (name, "skins/%s.pcx", baseskin.string);
raw = COM_LoadTempFile (name);
}
if (!raw)
{
skin->failedload = true;
@ -519,7 +523,7 @@ void Skin_NextDownload (void)
player_info_t *sc;
int i;
Con_Printf ("Checking skins...\n");
//Con_Printf ("Checking skins...\n");
for (i = 0; i != MAX_CLIENTS; i++)
{

View File

@ -66,6 +66,63 @@ dllhandle_t *Sys_LoadLibrary(char *name, dllfunction_t *funcs)
return (dllhandle_t*)lib;
}
void *Sys_GetAddressForName(dllhandle_t *module, char *exportname)
{
if (!module)
return NULL;
return GetProcAddress((HINSTANCE)module, exportname);
}
#ifdef HLSERVER
char *Sys_GetNameForAddress(dllhandle_t *module, void *address)
{
//windows doesn't provide a function to do this, so we have to do it ourselves.
//this isn't the fastest way...
//halflife needs this function.
char *base = (char *)module;
IMAGE_DATA_DIRECTORY *datadir;
IMAGE_EXPORT_DIRECTORY *block;
IMAGE_NT_HEADERS *ntheader;
IMAGE_DOS_HEADER *dosheader = (void*)base;
int i, j;
DWORD *funclist;
DWORD *namelist;
SHORT *ordilist;
if (!dosheader || dosheader->e_magic != IMAGE_DOS_SIGNATURE)
return NULL; //yeah, that wasn't an exe
ntheader = (void*)(base + dosheader->e_lfanew);
if (!dosheader->e_lfanew || ntheader->Signature != IMAGE_NT_SIGNATURE)
return NULL; //urm, wait, a 16bit dos exe?
datadir = &ntheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
block = (IMAGE_EXPORT_DIRECTORY *)(base + datadir->VirtualAddress);
funclist = (DWORD*)(base+block->AddressOfFunctions);
namelist = (DWORD*)(base+block->AddressOfNames);
ordilist = (SHORT*)(base+block->AddressOfNameOrdinals);
for (i = 0; i < block->NumberOfFunctions; i++)
{
if (base+funclist[i] == address)
{
for (j = 0; j < block->NumberOfNames; j++)
{
if (ordilist[j] == i)
{
return base+namelist[i];
}
}
//it has no name. huh?
return NULL;
}
}
return NULL;
}
#endif
static HINSTANCE game_library;

View File

@ -444,7 +444,11 @@ void Validation_DelatchRulesets(void)
Con_DPrintf("Ruleset deactivated\n");
}
void Validation_Ruleset(void)
void Validation_AllChecks(void)
{
}
void Validation_OldRuleset(void)
{ //this code is more complex than it needs to be
//this allows for the ruleset code to print a ruleset name that is applied via the cvars, but not directly named by the user
cvar_t *var;
@ -611,7 +615,10 @@ void Validation_Auto_Response(int playernum, char *s)
}
else if (!strncmp(s, "f_ruleset", 9) && rulesetresponsetime < Sys_DoubleTime())
{
Validation_Ruleset();
if (1)
Validation_AllChecks();
else
Validation_OldRuleset();
rulesetresponsetime = Sys_DoubleTime() + 5;
}
}

View File

@ -1324,7 +1324,22 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
}
r_refdef.fov_x = scr_fov.value;
r_refdef.fov_y = CalcFov(r_refdef.fov_x, vrect->width, vrect->height);
if (cl.stats[pnum][STAT_VIEWZOOM])
r_refdef.fov_x *= cl.stats[pnum][STAT_VIEWZOOM]/255.0f;
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL && vrect->width < (vrect->height*640)/432)
{
extern int glwidth, glheight;
r_refdef.fov_y = CalcFov(r_refdef.fov_x, (vrect->width*glwidth)/vid.width, (vrect->height*glheight)/vid.height);
// r_refdef.fov_x = CalcFov(r_refdef.fov_y, 432, 640);
}
else
#endif
{
r_refdef.fov_y = CalcFov(r_refdef.fov_x, 640, 432);
r_refdef.fov_x = CalcFov(r_refdef.fov_y, vrect->height, vrect->width);
}
}
void R_DrawNameTags(void)

View File

@ -2101,6 +2101,9 @@ int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr)
{
*offset = (name - s) + 2;
flags = TPM_FAKED;
if (msglen > 4 && *s == '(' && s[-1] == ')')
flags |= TPM_TEAM;
}
}
@ -3022,8 +3025,9 @@ void TP_UpdateAutoStatus(void)
char newstatusbuf[sizeof(vars.autoteamstatus)];
char *newstatus;
if (vars.autoteamstatus_time < realtime)
if (vars.autoteamstatus_time > realtime)
return;
vars.autoteamstatus_time = realtime + 3;
newstatus = Cmd_ExpandString(tp_autostatus.string, newstatusbuf, sizeof(newstatusbuf), tp_autostatus.restriction, true, true);
newstatus = TP_ParseMacroString(newstatus);
@ -3051,7 +3055,6 @@ void TP_UpdateAutoStatus(void)
//the tp code will reexpand it as part of the say team
Cbuf_AddText(va("say_team $\\%s\n", tp_autostatus.string), RESTRICT_LOCAL);
vars.autoteamstatus_time = realtime + 3;
}
void TP_StatChanged (int stat, int value)

View File

@ -123,6 +123,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define Q2CLIENT //client can connect to q2 servers
#define Q3CLIENT
#define Q3SERVER
// #define HLSERVER
#define NQPROT //server and client are capable of using quake1/netquake protocols. (qw is still prefered. uses the command 'nqconnect')
#define FISH //sw rendering only
#define ZLIB //zip/pk3 support

View File

@ -71,6 +71,10 @@ typedef struct cvar_s
char *defaultstr; //default
qbyte restriction;
#ifdef HLSERVER
struct hlcvar_s *hlcvar;
#endif
} cvar_t;
#define FCVARC(ConsoleName,ConsoleName2,Value,Flags,Callback) {ConsoleName, Value, NULL, Flags, 0, 0, 0, ConsoleName2, Callback}

View File

@ -151,7 +151,8 @@ int fs_hash_files;
int COM_FileOpenRead (char *path, FILE **hndl);
static int COM_FileOpenRead (char *path, FILE **hndl);
qboolean Sys_PathProtection(char *pattern);
@ -274,6 +275,9 @@ vfsfile_t *FSOS_OpenVFS(void *handle, flocation_t *loc, char *mode)
{
char diskname[MAX_OSPATH];
if (Sys_PathProtection(loc->rawname))
return NULL;
snprintf(diskname, sizeof(diskname), "%s/%s", (char*)handle, loc->rawname);
return VFSOS_Open(diskname, mode);
@ -455,7 +459,7 @@ qboolean FSPAK_FLocate(void *handle, flocation_t *loc, char *filename, void *has
if (loc)
{
loc->index = pf - pak->files;
snprintf(loc->rawname, sizeof(loc->rawname), "%s/%s", pak->descname, filename);
snprintf(loc->rawname, sizeof(loc->rawname), "%s", pak->descname);
loc->offset = pf->filepos;
loc->len = pf->filelen;
}
@ -1392,7 +1396,8 @@ int COM_filelength (FILE *f)
return end;
}
int COM_FileOpenRead (char *path, FILE **hndl)
/*
static int COM_FileOpenRead (char *path, FILE **hndl)
{
FILE *f;
@ -1406,6 +1411,7 @@ int COM_FileOpenRead (char *path, FILE **hndl)
return COM_filelength(f);
}
*/
int COM_FileSize(char *path)
{
@ -1575,7 +1581,8 @@ Copies a file over from the net to the local cache, creating any directories
needed. This is for the convenience of developers using ISDN from home.
===========
*/
void COM_CopyFile (char *netpath, char *cachepath)
/*
static void COM_CopyFile (char *netpath, char *cachepath)
{
FILE *in, *out;
int remaining, count;
@ -1601,6 +1608,7 @@ void COM_CopyFile (char *netpath, char *cachepath)
fclose (in);
fclose (out);
}
//*/
int fs_hash_dups;
int fs_hash_files;
@ -1681,6 +1689,12 @@ int FS_FLocateFile(char *filename, FSLF_ReturnType_e returntype, flocation_t *lo
void *pf;
//Con_Printf("Finding %s: ", filename);
if (Sys_PathProtection(filename))
{
pf = NULL;
goto fail;
}
if (com_fs_cache.value)
{
if (com_fschanged)
@ -1896,22 +1910,39 @@ int COM_FOpenWriteFile(char *filename, FILE **file)
//true if protection kicks in
qboolean Sys_PathProtection(char *pattern)
{
char *s;
if (strchr(pattern, '\\'))
{
char *s;
Con_Printf("Warning: \\ characters in filename %s\n", pattern);
while((s = strchr(pattern, '\\')))
*s = '/';
}
if (strstr(pattern, "//"))
{
//amiga uses // as equivelent to /../
Con_Printf("Warning: // characters in filename %s\n", pattern);
while (s=strstr(pattern, "//"))
{
s++;
while (*s)
{
*s = *(s+1);
s++;
}
}
}
if (strstr(pattern, ".."))
Con_Printf("Error: '..' characters in filename %s\n", pattern);
else if (pattern[0] == '/')
Con_Printf("Error: absolute path in filename %s\n", pattern);
else if (strstr(pattern, ":")) //win32 drive seperator (or mac path seperator, but / works there and they're used to it)
else if (strstr(pattern, ":")) //win32 drive seperator (or mac path seperator, but / works there and they're used to it) (or amiga device separator)
Con_Printf("Error: absolute path in filename %s\n", pattern);
else
{
return false;
}
return true;
}
@ -2475,6 +2506,18 @@ qbyte *COM_LoadStackFile (char *path, void *buffer, int bufsize)
int FS_LoadFile(char *name, void **file)
{
*file = COM_LoadMallocFile(name);
return com_filesize;
}
void FS_FreeFile(void *file)
{
BZ_Free(file);
}
void COM_EnumerateFiles (char *match, int (*func)(char *, int, void *), void *parm)
{
searchpath_t *search;
@ -2924,6 +2967,8 @@ gamemode_info_t gamemode_info[] = {
{"FTE-JK2", "jk2", "-jk2", "base/assets0.pk3", NULL, "base", "fte"},
{"FTE-HalfLife", "hl", "-hl", "valve/liblist.gam",NULL, "valve", "fte"},
{NULL}
};
@ -3117,6 +3162,125 @@ void FS_ReloadPackFiles_f(void)
FS_ReloadPackFilesFlags((unsigned int)-1);
}
#ifdef _WIN32
#include <windows.h>
qboolean Sys_FindGameData(char *gamename, char *basepath, int basepathlen)
{
if (!strcmp(gamename, "q1"))
{
//try and find it via steam
//reads HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam\InstallPath
//append SteamApps\common\quake
//use it if we find winquake.exe there
FILE *f;
DWORD resultlen;
HKEY key = NULL;
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Valve\\Steam", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key)))
{
resultlen = basepathlen;
RegQueryValueEx(key, "InstallPath", NULL, NULL, basepath, &resultlen);
RegCloseKey(key);
Q_strncatz(basepath, "/SteamApps/common/quake", basepathlen);
if (f = fopen(va("%s/Winquake.exe", basepath), "rb"))
{
fclose(f);
return true;
}
}
//well, okay, so they don't have quake installed from steam.
//quite a lot of people have it in c:\quake, as that's the default install location from the quake cd.
if (f = fopen("c:/quake/quake.exe", "rb"))
{
//HAHAHA! Found it!
fclose(f);
Q_strncpyz(basepath, "c:/quake", basepathlen);
return true;
}
}
if (!strcmp(gamename, "q2"))
{
//try and find it via steam
//reads HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam\InstallPath
//append SteamApps\common\quake 2
//use it if we find quake2.exe there
FILE *f;
DWORD resultlen;
HKEY key = NULL;
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Valve\\Steam", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key)))
{
resultlen = basepathlen;
RegQueryValueEx(key, "InstallPath", NULL, NULL, basepath, &resultlen);
RegCloseKey(key);
Q_strncatz(basepath, "/SteamApps/common/quake 2", basepathlen);
if (f = fopen(va("%s/quake2.exe", basepath), "rb"))
{
fclose(f);
return true;
}
}
//well, okay, so they don't have quake2 installed from steam.
//look for HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Quake2_exe\Path
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Quake2_exe", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key)))
{
resultlen = basepathlen;
RegQueryValueEx(key, "Path", NULL, NULL, basepath, &resultlen);
RegCloseKey(key);
if (f = fopen(va("%s/quake2.exe", basepath), "rb"))
{
fclose(f);
return true;
}
}
}
if (!strcmp(gamename, "q3"))
{
DWORD resultlen;
HKEY key = NULL;
//reads HKEY_LOCAL_MACHINE\SOFTWARE\id\Quake III Arena\InstallPath
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\id\\Quake III Arena", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key)))
{
resultlen = basepathlen;
RegQueryValueEx(key, "InstallPath", NULL, NULL, basepath, &resultlen);
RegCloseKey(key);
return true;
}
}
/*
if (!strcmp(gamename, "d3"))
{
DWORD resultlen;
HKEY key = NULL;
//reads HKEY_LOCAL_MACHINE\SOFTWARE\id\Doom 3\InstallPath
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\id\\Doom 3", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key)))
{
resultlen = basepathlen;
RegQueryValueEx(key, "InstallPath", NULL, NULL, basepath, &resultlen);
RegCloseKey(key);
return true;
}
}
*/
if (!strcmp(gamename, "h3"))
{
//try and find it via steam
//reads HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam\InstallPath
//append SteamApps\common\hexen 2
}
return false;
}
#else
qboolean Sys_FindGameData(char *gamename, char *basepath, int basepathlen)
{
return false;
}
#endif
/*
================
COM_InitFilesystem
@ -3181,9 +3345,40 @@ void COM_InitFilesystem (void)
for (i = 0; gamemode_info[i].gamename; i++)
{
if (COM_CheckParm(gamemode_info[i].argname))
{
gamenum = i;
if (gamemode_info[gamenum].auniquefile)
{
f = fopen(va("%s%s", com_quakedir, gamemode_info[i].auniquefile), "rb");
if (f)
{
//we found it, its all okay
fclose(f);
break;
}
#ifdef _WIN32
if (Sys_FindGameData(gamemode_info[i].exename, com_quakedir, sizeof(com_quakedir)))
{
if (com_quakedir[strlen(com_quakedir)-1] == '\\')
com_quakedir[strlen(com_quakedir)-1] = '/';
else if (com_quakedir[strlen(com_quakedir)-1] != '/')
{
com_quakedir[strlen(com_quakedir)+1] = '\0';
com_quakedir[strlen(com_quakedir)] = '/';
}
}
else
#endif
{
Con_Printf("Couldn't find the gamedata for this game mode!\n");
}
}
break;
}
}
//still failed? find quake and use that one by default
if (gamenum<0)
{
for (i = 0; gamemode_info[i].gamename; i++)
@ -3192,6 +3387,7 @@ void COM_InitFilesystem (void)
gamenum = i;
}
}
Cvar_Set(&com_gamename, gamemode_info[gamenum].gamename);
if (gamemode_info[gamenum].customexec)

View File

@ -3778,7 +3778,7 @@ void SWR_Q2BSP_StainNode (mnode_t *node, float *parms)
#ifndef CLIENTONLY
void Q2BSP_FatPVS (model_t *mod, vec3_t org, qboolean add);
qboolean Q2BSP_EdictInFatPVS(model_t *mod, edict_t *ent);
void Q2BSP_FindTouchedLeafs(model_t *mod, edict_t *ent);
void Q2BSP_FindTouchedLeafs(model_t *mod, edict_t *ent, float *mins, float *maxs);
#endif
void GLQ2BSP_LightPointValues(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void SWQ2BSP_LightPointValues(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);

View File

@ -318,6 +318,61 @@ void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up)
CrossProduct(right, forward, up);
}
void VectorAngles(float *forward, float *up, float *result) //up may be NULL
{
float yaw, pitch, roll;
if (forward[1] == 0 && forward[0] == 0)
{
if (forward[2] > 0)
{
pitch = 90;
yaw = up ? atan2(-up[1], -up[0]) : 0;
}
else
{
pitch = 270;
yaw = up ? atan2(up[1], up[0]) : 0;
}
roll = 0;
}
else
{
yaw = atan2(forward[1], forward[0]);
pitch = -atan2(forward[2], sqrt (forward[0]*forward[0] + forward[1]*forward[1]));
if (up)
{
vec_t cp = cos(pitch), sp = sin(pitch);
vec_t cy = cos(yaw), sy = sin(yaw);
vec3_t tleft, tup;
tleft[0] = -sy;
tleft[1] = cy;
tleft[2] = 0;
tup[0] = sp*cy;
tup[1] = sp*sy;
tup[2] = cp;
roll = -atan2(DotProduct(up, tleft), DotProduct(up, tup));
}
else
roll = 0;
}
pitch *= -180 / M_PI;
yaw *= 180 / M_PI;
roll *= 180 / M_PI;
if (pitch < 0)
pitch += 360;
if (yaw < 0)
yaw += 360;
if (roll < 0)
roll += 360;
result[0] = pitch;
result[1] = yaw;
result[2] = roll;
}
void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
{
float angle;

View File

@ -45,9 +45,9 @@ extern int nanmask;
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
#define VectorSubtract(a,b,c) do{(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}while(0)
#define VectorAdd(a,b,c) do{(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}while(0)
#define VectorCopy(a,b) do{(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}while(0)
#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0)
#define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2])
#define VectorLength(a) Length(a)
@ -87,6 +87,7 @@ void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out);
void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs);
float anglemod (float a);
void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void VectorAngles (float *forward, float *up, float *angles); //up may be NULL
void VARGS BOPS_Error (void);
int VARGS BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
void ClearBounds (vec3_t mins, vec3_t maxs);

View File

@ -123,6 +123,8 @@ int PM_SlideMove (void)
time_left = frametime;
// VectorAdd(pmove.velocity, pmove.basevelocity, pmove.velocity);
for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++)
{
for (i=0 ; i<3 ; i++)
@ -540,7 +542,7 @@ void PM_WaterMove (void)
/*
*/
void PM_FlyMove ()
void PM_FlyMove (void)
{
int i;
vec3_t wishvel;
@ -580,11 +582,11 @@ void PM_LadderMove (void)
for (i=0 ; i<3 ; i++)
wishvel[i] = forward[i]*pmove.cmd.forwardmove + right[i]*pmove.cmd.sidemove + up[i]*pmove.cmd.upmove;
if (wishvel[2] > 100 || wishvel[2] < -100) //large up/down move
if (wishvel[2] >= 100 || wishvel[2] <= -100) //large up/down move
wishvel[2]*=10;
if (pmove.cmd.buttons & 2)
wishvel[2]+=100;
wishvel[2]+=movevars.maxspeed;
VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize(wishdir);
@ -762,6 +764,11 @@ void PM_CategorizePosition (void)
}
}
if (cont & FTECONTENTS_LADDER)
pmove.onladder = true;
else
pmove.onladder = false;
//are we on a ladder?
#ifdef Q2BSPS
if (pmove.physents[0].model->fromgame == fg_quake3)
@ -808,6 +815,14 @@ void PM_CategorizePosition (void)
}
#endif
//bsp objects marked as ladders mark regions to stand in to be classed as on a ladder.
cont = PM_ExtraBoxContents(pmove.origin);
if (cont & FTECONTENTS_LADDER)
{
pmove.onladder = true;
pmove.onground = false; // too steep
}
if (pmove.onground && pmove.pm_type != PM_FLY && pmove.waterlevel < 2)
{
// snap to ground so that we can't jump higher than we're supposed to

View File

@ -41,6 +41,7 @@ typedef struct
unsigned short info; // for client or server to identify
qbyte nonsolid;
qbyte notouch;
unsigned int forcecontentsmask;
} physent_t;
typedef struct
@ -51,6 +52,7 @@ typedef struct
vec3_t origin;
vec3_t angles;
vec3_t velocity;
vec3_t basevelocity;
qboolean jump_held;
int jump_msec; // msec since last jump
float waterjumptime;

View File

@ -129,7 +129,62 @@ int PM_PointContents (vec3_t p)
pe = &pmove.physents[num];
pm = pe->model;
if (pm)
pc |= PM_TransformedModelPointContents(pm, p, pe->origin, pe->angles);
{
if (pe->forcecontentsmask)
{
if (PM_TransformedModelPointContents(pm, p, pe->origin, pe->angles))
pc |= pe->forcecontentsmask;
}
else
{
if (pe->nonsolid)
continue;
pc |= PM_TransformedModelPointContents(pm, p, pe->origin, pe->angles);
}
}
else if (pe->forcecontentsmask)
{
if (p[0] >= pe->mins[0] && p[0] <= pe->maxs[0] &&
p[1] >= pe->mins[1] && p[1] <= pe->maxs[1] &&
p[2] >= pe->mins[2] && p[2] <= pe->maxs[2])
pc |= pe->forcecontentsmask;
}
}
return pc;
}
int PM_ExtraBoxContents (vec3_t p)
{
int num;
int pc = 0;
physent_t *pe;
model_t *pm;
trace_t tr;
for (num = 1; num < pmove.numphysent; num++)
{
pe = &pmove.physents[num];
if (!pe->nonsolid)
continue;
pm = pe->model;
if (pm)
{
if (pe->forcecontentsmask)
{
PM_TransformedHullCheck(pm, p, p, &tr, pe->origin, pe->angles);
if (tr.startsolid)
pc |= pe->forcecontentsmask;
}
}
else if (pe->forcecontentsmask)
{
if (p[0]+player_maxs[0] >= pe->mins[0] && p[0]+player_mins[0] <= pe->maxs[0] &&
p[1]+player_maxs[1] >= pe->mins[1] && p[1]+player_mins[1] <= pe->maxs[1] &&
p[2]+player_maxs[2] >= pe->mins[2] && p[2]+player_mins[2] <= pe->maxs[2])
pc |= pe->forcecontentsmask;
}
}
return pc;
@ -185,7 +240,7 @@ qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, trac
}
// sweep the box through the model
if (model)
if (model && model->funcs.Trace)
result = model->funcs.Trace(model, 0, 0, start_l, end_l, player_mins, player_maxs, trace);
else
{
@ -242,6 +297,9 @@ qboolean PM_TestPlayerPosition (vec3_t pos)
{
pe = &pmove.physents[i];
if (pe->nonsolid)
continue;
// get the clipping hull
if (pe->model)
{
@ -299,6 +357,9 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end)
{
pe = &pmove.physents[i];
if (pe->nonsolid)
continue;
if (!pe->model)
{
vec3_t mins, maxs;

View File

@ -934,7 +934,7 @@ SV_FindTouchedLeafs
Links the edict to the right leafs so we can get it's potential visability.
===============
*/
void Q1BSP_RFindTouchedLeafs (edict_t *ent, mnode_t *node)
void Q1BSP_RFindTouchedLeafs (edict_t *ent, mnode_t *node, float *mins, float *maxs)
{
mplane_t *splitplane;
mleaf_t *leaf;
@ -965,20 +965,20 @@ void Q1BSP_RFindTouchedLeafs (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(mins, maxs, splitplane);
// recurse down the contacted sides
if (sides & 1)
Q1BSP_RFindTouchedLeafs (ent, node->children[0]);
Q1BSP_RFindTouchedLeafs (ent, node->children[0], mins, maxs);
if (sides & 2)
Q1BSP_RFindTouchedLeafs (ent, node->children[1]);
Q1BSP_RFindTouchedLeafs (ent, node->children[1], mins, maxs);
}
void Q1BSP_FindTouchedLeafs(model_t *mod, edict_t *ent)
void Q1BSP_FindTouchedLeafs(model_t *mod, edict_t *ent, float *mins, float *maxs)
{
ent->num_leafs = 0;
if (ent->v->modelindex)
Q1BSP_RFindTouchedLeafs (ent, mod->nodes);
Q1BSP_RFindTouchedLeafs (ent, mod->nodes, mins, maxs);
}
#endif

View File

@ -66,90 +66,31 @@ struct vm_s {
int (VARGS *vmMain)(int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);
};
#ifdef _WIN32
#include "winquake.h"
void *Sys_LoadDLL(const char *name, void **vmMain, sys_calldll_t syscall)
{
void (VARGS *dllEntry)(sys_calldll_t syscall);
char dllname[MAX_OSPATH];
HINSTANCE hVM;
sprintf(dllname, "%sx86.dll", name);
hVM=NULL;
{
char name[MAX_OSPATH];
char *gpath;
// run through the search paths
gpath = NULL;
while (1)
{
gpath = COM_NextPath (gpath);
if (!gpath)
return NULL; // couldn't find one anywhere
snprintf (name, sizeof(name), "%s/%s", gpath, dllname);
hVM = LoadLibrary (name);
if (hVM)
{
Con_DPrintf ("LoadLibrary (%s)\n",name);
break;
}
}
}
if(!hVM) return NULL;
dllEntry=(void *)GetProcAddress(hVM, "dllEntry");
if(!dllEntry)
{
Con_Printf ("Sys_LoadDLL: %s lacks a dllEntry function\n",name);
FreeLibrary(hVM);
return NULL;
}
dllEntry(syscall);
*vmMain=(void *)GetProcAddress(hVM, "vmMain");
if(!*vmMain)
{
Con_Printf ("Sys_LoadDLL: %s lacks a vmMain function\n",name);
FreeLibrary(hVM);
return NULL;
}
return hVM;
}
/*
** Sys_UnloadDLL
*/
void Sys_UnloadDLL(void *handle)
{
if(handle)
{
if(!FreeLibrary((HMODULE)handle))
Sys_Error("Sys_UnloadDLL FreeLibrary failed");
}
}
#else
#if defined(__MORPHOS__) && I_AM_BIGFOOT
#include <proto/dynload.h>
#else
#include <dlfcn.h>
#endif
void *Sys_LoadDLL(const char *name, void **vmMain, int (EXPORT_FN *syscall)(int arg, ... ))
dllhandle_t *QVM_LoadDLL(const char *name, void **vmMain, int (EXPORT_FN *syscall)(int arg, ... ))
{
void (*dllEntry)(int (EXPORT_FN *syscall)(int arg, ... ));
char dllname[MAX_OSPATH];
void *hVM;
dllhandle_t *hVM;
dllfunction_t funcs[] =
{
{(void*)&dllEntry, "dllEntry"},
{(void*)vmMain, "vmMain"},
{NULL, NULL},
};
#if defined(__MORPHOS__) && I_AM_BIGFOOT
if (DynLoadBase == 0)
return 0;
#endif
#if defined(__amd64__)
#ifdef _WIN32
sprintf(dllname, "%sx86.dll", name);
#elif defined(__amd64__)
return 0; //give up early, don't even try going there
sprintf(dllname, "%samd.so", name);
#elif defined(_M_IX86) || defined(__i386__)
@ -173,57 +114,34 @@ void *Sys_LoadDLL(const char *name, void **vmMain, int (EXPORT_FN *syscall)(int
gpath = COM_NextPath (gpath);
if (!gpath)
return NULL; // couldn't find one anywhere
_snprintf (name, sizeof(name), "%s/%s", gpath, dllname);
snprintf (name, sizeof(name), "%s/%s", gpath, dllname);
Con_Printf("Loading native: %s\n", name);
hVM = dlopen (name, RTLD_NOW);
hVM = Sys_LoadLibrary(name, funcs);
if (hVM)
{
Con_DPrintf ("Sys_LoadDLL: dlopen (%s)\n",name);
break;
}
else
{
Con_DPrintf("Sys_LoadDLL: dlerror()=\"%s\"", dlerror());
}
}
}
if(!hVM) return NULL;
dllEntry=(void *)dlsym(hVM, "dllEntry");
if(!dllEntry)
{
Con_Printf("Sys_LoadDLL: %s does not have a dllEntry function\n");
dlclose(hVM);
return NULL;
}
(*dllEntry)(syscall);
*vmMain=(void *)dlsym(hVM, "vmMain");
if(!*vmMain)
{
Con_Printf("Sys_LoadDLL: %s does not have a vmMain function\n");
dlclose(hVM);
return NULL;
}
return hVM;
}
/*
** Sys_UnloadDLL
*/
void Sys_UnloadDLL(void *handle)
void QVM_UnloadDLL(dllhandle_t *handle)
{
if(handle)
{
if(dlclose(handle))
Sys_Error("Sys_UnloadDLL FreeLibrary failed");
Sys_CloseLibrary(handle);
}
}
#endif
@ -292,9 +210,9 @@ typedef struct qvm_s
sys_callqvm_t syscall;
} qvm_t;
qvm_t *QVM_Load(const char *name, sys_callqvm_t syscall);
void QVM_UnLoad(qvm_t *qvm);
int QVM_Exec(qvm_t *qvm, int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7);
qvm_t *QVM_LoadVM(const char *name, sys_callqvm_t syscall);
void QVM_UnLoadVM(qvm_t *qvm);
int QVM_ExecVM(qvm_t *qvm, int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7);
// ------------------------- * OP.CODES * -------------------------
@ -397,7 +315,7 @@ typedef enum qvm_op_e
/*
** QVM_Load
*/
qvm_t *QVM_Load(const char *name, sys_callqvm_t syscall)
qvm_t *QVM_LoadVM(const char *name, sys_callqvm_t syscall)
{
char path[MAX_QPATH];
vmHeader_t *header;
@ -547,7 +465,7 @@ qvm_t *QVM_Load(const char *name, sys_callqvm_t syscall)
/*
** QVM_UnLoad
*/
void QVM_UnLoad(qvm_t *qvm)
void QVM_UnLoadVM(qvm_t *qvm)
{
Z_Free(qvm->mem_ptr);
Z_Free(qvm);
@ -648,7 +566,7 @@ static void inline QVM_Return(qvm_t *vm, int size)
/*
** VM_Exec
*/
int QVM_Exec(register qvm_t *qvm, int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7)
int QVM_ExecVM(register qvm_t *qvm, int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7)
{
//remember that the stack is backwards. push takes 1.
@ -1026,7 +944,7 @@ vm_t *VM_Create(vm_t *vm, const char *name, sys_calldll_t syscalldll, sys_callqv
{
if (!COM_CheckParm("-nodlls") && !COM_CheckParm("-nosos")) //:)
{
if((vm->hInst=Sys_LoadDLL(name, (void**)&vm->vmMain, syscalldll)))
if((vm->hInst=QVM_LoadDLL(name, (void**)&vm->vmMain, syscalldll)))
{
Con_DPrintf("Creating native machine \"%s\"\n", name);
vm->type=VM_NATIVE;
@ -1038,7 +956,7 @@ vm_t *VM_Create(vm_t *vm, const char *name, sys_calldll_t syscalldll, sys_callqv
if (syscallqvm)
{
if((vm->hInst=QVM_Load(name, syscallqvm)))
if((vm->hInst=QVM_LoadVM(name, syscallqvm)))
{
Con_DPrintf("Creating virtual machine \"%s\"\n", name);
vm->type=VM_BYTECODE;
@ -1060,11 +978,11 @@ void VM_Destroy(vm_t *vm)
switch(vm->type)
{
case VM_NATIVE:
if(vm->hInst) Sys_UnloadDLL(vm->hInst);
if(vm->hInst) QVM_UnloadDLL(vm->hInst);
break;
case VM_BYTECODE:
if(vm->hInst) QVM_UnLoad(vm->hInst);
if(vm->hInst) QVM_UnLoadVM(vm->hInst);
break;
case VM_NONE:
@ -1094,11 +1012,11 @@ qboolean VM_Restart(vm_t *vm)
switch(vm->type)
{
case VM_NATIVE:
if(vm->hInst) Sys_UnloadDLL(vm->hInst);
if(vm->hInst) QVM_UnloadDLL(vm->hInst);
break;
case VM_BYTECODE:
if(vm->hInst) QVM_UnLoad(vm->hInst);
if(vm->hInst) QVM_UnLoadVM(vm->hInst);
break;
case VM_NONE:
@ -1148,7 +1066,7 @@ int VARGS VM_Call(vm_t *vm, int instruction, ...)
return vm->vmMain(instruction, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
case VM_BYTECODE:
return QVM_Exec(vm->hInst, instruction, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
return QVM_ExecVM(vm->hInst, instruction, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
case VM_NONE:
return 0;

View File

@ -37,6 +37,8 @@ int Sys_FileTime (char *path);
void Sys_mkdir (char *path);
qboolean Sys_remove (char *path);
qboolean Sys_FindGameData(char *gamename, char *basepath, int basepathlen);
//
// memory protection
//
@ -62,6 +64,8 @@ typedef struct {
typedef void *dllhandle_t;
dllhandle_t *Sys_LoadLibrary(char *name, dllfunction_t *funcs);
void Sys_CloseLibrary(dllhandle_t *lib);
void *Sys_GetAddressForName(dllhandle_t *module, char *exportname);
char *Sys_GetNameForAddress(dllhandle_t *module, void *address);
unsigned int Sys_Milliseconds (void);
double Sys_DoubleTime (void);

View File

@ -66,7 +66,7 @@ typedef struct trace_s
cplane_t plane; // surface normal at impact
q2csurface_t *surface; // surface hit
int contents; // contents on other side of surface hit
struct edict_s *ent; // not set by CM_*() functions
void *ent; // not set by CM_*() functions
//AND THIS LINE
int entnum;

View File

@ -914,17 +914,24 @@ void D3D7_DrawWorld(void)
}
#ifdef Q3BSPS
if (ent.model->fromgame == fg_quake3)
{
{
R_MarkLeaves_Q3 ();
D3D7_LeafWorldNode ();
}
else
#endif
D3D7_RecursiveQ2WorldNode (cl.worldmodel->nodes);
#endif
{
R_MarkLeaves_Q2 ();
D3D7_RecursiveQ2WorldNode (cl.worldmodel->nodes);
}
}
else
#endif
*/
D3D7_RecursiveWorldNode (cl.worldmodel->nodes);
*/
{
R_MarkLeaves_Q1 ();
D3D7_RecursiveWorldNode (cl.worldmodel->nodes);
}
RSpeedEnd(RSPEED_WORLDNODE);
TRACE(("dbg: calling PPL_DrawWorld\n"));
@ -947,7 +954,6 @@ void D3D7_R_RenderScene(void)
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
R_MarkLeaves (); // done here so we know if we're in water
D3D7_DrawWorld (); // adds static entities to the list
}

View File

@ -1328,16 +1328,23 @@ void D3D9_DrawWorld(void)
}
#ifdef Q3BSPS
if (ent.model->fromgame == fg_quake3)
{
{
R_MarkLeaves_Q3 ();
D3D9_LeafWorldNode ();
}
else
#endif
D3D9_RecursiveQ2WorldNode (cl.worldmodel->nodes);
#endif
{
R_MarkLeaves_Q2 ();
D3D9_RecursiveQ2WorldNode (cl.worldmodel->nodes);
}
}
else
#endif
D3D9_RecursiveWorldNode (cl.worldmodel->nodes);
#endif
{
R_MarkLeaves_Q1 ();
D3D9_RecursiveWorldNode (cl.worldmodel->nodes);
}
RSpeedEnd(RSPEED_WORLDNODE);
TRACE(("dbg: calling PPL_DrawWorld\n"));
@ -1360,7 +1367,6 @@ void D3D9_R_RenderScene(void)
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
R_MarkLeaves (); // done here so we know if we're in water
D3D9_DrawWorld (); // adds static entities to the list
}

View File

@ -595,7 +595,7 @@ qboolean Heightmap_EdictInFatPVS (model_t *mod, edict_t *edict)
return true;
}
void Heightmap_FindTouchedLeafs (model_t *mod, edict_t *ent)
void Heightmap_FindTouchedLeafs (model_t *mod, edict_t *ent, float *mins, float *maxs)
{
}
#endif

View File

@ -393,6 +393,9 @@ void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, fl
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
frametime *= sequence->timing;
if (frametime < 0)
frametime = 0;
frame = (int)frametime;
frametime -= frame;

View File

@ -46,7 +46,7 @@ typedef struct {
void (*FatPVS) (struct model_s *model, vec3_t org, qboolean add);
qboolean (*EdictInFatPVS) (struct model_s *model, struct edict_s *edict);
void (*FindTouchedLeafs_Q1) (struct model_s *model, struct edict_s *ent); //edict system as opposed to q2 game dll system.
void (*FindTouchedLeafs_Q1) (struct model_s *model, struct edict_s *ent, vec3_t cullmins, vec3_t cullmaxs); //edict system as opposed to q2 game dll system.
void (*LightPointValues) (struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void (*StainNode) (struct mnode_s *node, float *parms);
@ -401,7 +401,7 @@ qboolean Q1BSP_Trace(struct model_s *model, int forcehullnum, int frame, vec3_t
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace);
void Q1BSP_FatPVS (struct model_s *mod, vec3_t org, qboolean add);
qboolean Q1BSP_EdictInFatPVS(struct model_s *mod, struct edict_s *ent);
void Q1BSP_FindTouchedLeafs(struct model_s *mod, struct edict_s *ent);
void Q1BSP_FindTouchedLeafs(struct model_s *mod, struct edict_s *ent, float *mins, float *maxs);
qbyte *Q1BSP_LeafPVS (struct model_s *model, mleaf_t *leaf, qbyte *buffer);
/*

View File

@ -1165,8 +1165,6 @@ void R_RenderScene (void)
if (!GLR_DoomWorld ())
#endif
{
TRACE(("dbg: calling GLR_MarkLeaves\n"));
R_MarkLeaves (); // done here so we know if we're in water
TRACE(("dbg: calling R_DrawWorld\n"));
R_DrawWorld (); // adds static entities to the list
}

View File

@ -2771,6 +2771,80 @@ e->angles[0] = -e->angles[0]; // stupid quake bug
=============================================================
*/
#if 0
void R_MarkLeafSurfaces_Q1 (void)
{
static qbyte fatvis[MAX_MAP_LEAFS/8];
static qbyte *vis;
mleaf_t *leaf;
int i, j;
qbyte solid[4096];
msurface_t *surf;
int shift;
r_visframecount++;
if (1)//r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2)
{
}
else
{
r_oldviewleaf = r_viewleaf;
r_oldviewleaf2 = r_viewleaf2;
if ((int)r_novis.value&1)
{
vis = solid;
memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
}
else if (r_viewleaf2 && r_viewleaf2 != r_viewleaf)
{
int c;
Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis);
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL);
c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i];
vis = fatvis;
}
else
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL);
}
shift = GLR_LightmapShift(cl.worldmodel);
for (i=0 ; i<cl.worldmodel->numleafs ; i++)
{
if (vis[i>>3] & (1<<(i&7)))
{
leaf = (mleaf_t *)&cl.worldmodel->leafs[i+1];
if (R_CullBox (leaf->minmaxs, leaf->minmaxs+3))
continue;
leaf->visframe = r_visframecount;
for (j = 0; j < leaf->nummarksurfaces; j++)
{
surf = leaf->firstmarksurface[j];
if (surf->visframe == r_visframecount)
continue;
surf->visframe = r_visframecount;
R_RenderDynamicLightmaps (surf, shift);
surf->texturechain = surf->texinfo->texture->texturechain;
surf->texinfo->texture->texturechain = surf;
}
//deal with static ents.
if (leaf->efrags)
R_StoreEfrags (&leaf->efrags);
}
}
}
#else
/*
================
R_RecursiveWorldNode
@ -2890,6 +2964,7 @@ start:
node = node->children[!side];
goto start;
}
#endif
#ifdef Q2BSPS
static void GLR_RecursiveQ2WorldNode (mnode_t *node)
@ -3118,15 +3193,26 @@ void R_DrawWorld (void)
#ifdef Q3BSPS
if (ent.model->fromgame == fg_quake3)
{
R_MarkLeaves_Q3 ();
GLR_LeafWorldNode ();
}
else
#endif
{
R_MarkLeaves_Q2 ();
GLR_RecursiveQ2WorldNode (cl.worldmodel->nodes);
}
}
else
#endif
{
#if 0
R_MarkLeafSurfaces_Q1();
#else
R_MarkLeaves_Q1 ();
GLR_RecursiveWorldNode (cl.worldmodel->nodes);
#endif
}
RSpeedEnd(RSPEED_WORLDNODE);
TRACE(("dbg: calling PPL_DrawWorld\n"));

View File

@ -40,15 +40,58 @@ extern qboolean scr_drawloading;
extern int scr_chatmode;
extern cvar_t scr_chatmodecvar;
extern cvar_t vid_conautoscale;
// console size manipulation callbacks
void GLVID_Console_Resize(void)
{
extern cvar_t vid_conwidth, vid_conheight;
int cwidth, cheight;
float xratio;
float yratio=0;
cwidth = vid_conwidth.value;
cheight = vid_conheight.value;
vid.width = vid.conwidth = vid_conwidth.value;
vid.height = vid.conheight = vid_conheight.value;
xratio = vid_conautoscale.value;
if (xratio > 0)
{
char *s = strchr(vid_conautoscale.string, ' ');
if (s)
yratio = atof(s + 1);
if (yratio <= 0)
yratio = xratio;
xratio = 1 / xratio;
yratio = 1 / yratio;
//autoscale overrides conwidth/height (without actually changing them)
cwidth = glwidth;
cheight = glheight;
}
else
{
xratio = 1;
yratio = 1;
}
if (!cwidth)
cwidth = glwidth;
if (!cheight)
cheight = glheight;
cwidth*=xratio;
cheight*=yratio;
if (cwidth < 320)
cwidth = 320;
if (cheight < 200)
cheight = 200;
vid.width = vid.conwidth = cwidth;
vid.height = vid.conheight = cheight;
vid.recalc_refdef = true;
Con_CheckResize();
@ -65,7 +108,7 @@ void GLVID_Conheight_Callback(struct cvar_s *var, char *oldvalue)
Cvar_ForceSet(var, "1536");
return;
}
if (var->value < 200) //lower would be wrong
if (var->value < 200 && var->value) //lower would be wrong
{
Cvar_ForceSet(var, "200");
return;
@ -82,7 +125,7 @@ void GLVID_Conwidth_Callback(struct cvar_s *var, char *oldvalue)
Cvar_ForceSet(var, "2048");
return;
}
if (var->value < 320) //lower would be wrong
if (var->value < 320 && var->value) //lower would be wrong
{
Cvar_ForceSet(var, "320");
return;
@ -93,26 +136,7 @@ void GLVID_Conwidth_Callback(struct cvar_s *var, char *oldvalue)
void GLVID_Conautoscale_Callback(struct cvar_s *var, char *oldvalue)
{
extern cvar_t vid_conwidth, vid_conheight;
float xratio, yratio = 0;
xratio = var->value;
if (xratio > 0)
{
char *s = strchr(var->string, ' ');
if (s)
yratio = atof(s + 1);
if (yratio <= 0)
yratio = xratio;
xratio = 1 / xratio;
yratio = 1 / yratio;
Cvar_SetValue(&vid_conwidth, glwidth * xratio);
Cvar_SetValue(&vid_conheight, glheight * yratio);
}
GLVID_Console_Resize();
}
/*

View File

@ -45,16 +45,6 @@ cvar_t r_vertexlight = SCVAR("r_vertexlight", "0");
#define Com_sprintf snprintf
#define clamp(v,min, max) (v) = (((v)<(min))?(min):(((v)>(max))?(max):(v)));
int FS_LoadFile(char *name, void **file)
{
*file = COM_LoadMallocFile(name);
return com_filesize;
}
void FS_FreeFile(void *file)
{
BZ_Free(file);
}
typedef union {
float f;
unsigned int i;

View File

@ -116,26 +116,30 @@ typedef struct {
builtin_t pr_builtin[1024];
extern BuiltinList_t BuiltinList[];
struct {
func_t ChatMessage;
func_t getplayerstat[MAX_CL_STATS];
func_t getplayerstati[MAX_CL_STATS];
func_t UserCmd, ParseClientCommand, ParseConnectionlessPacket;
func_t ConsoleCmd;
func_t UserInfo_Changed;
func_t localinfoChanged;
func_t PausedTic;
func_t ShouldPause;
func_t ClassChangeWeapon;
} gfuncs;
func_t getplayerstat[MAX_CL_STATS];
func_t getplayerstati[MAX_CL_STATS];
func_t SpectatorConnect;
func_t SpectatorThink;
func_t SpectatorDisconnect;
func_t ChatMessage;
func_t getplayerstat[MAX_CL_STATS];
func_t getplayerstati[MAX_CL_STATS];
func_t mod_UserCmd, SV_ParseClientCommand, SV_ParseConnectionlessPacket;
func_t mod_ConsoleCmd;
func_t UserInfo_Changed;
func_t localinfoChanged;
func_t pr_SV_PausedTic;
func_t pr_SV_ShouldPause;
func_t SV_PlayerPhysicsQC; //DP's DP_SV_PLAYERPHYSICS extension
func_t EndFrameQC;
func_t pr_ClassChangeWeapon;
qboolean pr_items2;
@ -459,6 +463,14 @@ void PR_Deinit(void)
Z_FreeTags(Z_QC_TAG);
}
svprogfuncs=NULL;
//clear out function pointers (so changing game modes cannot lead to confusions)
memset(&gfuncs, 0, sizeof(gfuncs));
memset(&getplayerstat, 0, sizeof(getplayerstat));
memset(&getplayerstati, 0, sizeof(getplayerstati));
SpectatorConnect = 0;
SpectatorThink = 0;
SpectatorDisconnect = 0;
}
@ -560,18 +572,18 @@ void PR_LoadGlabalStruct(void)
getplayerstati[i] = PR_FindFunction(svprogfuncs, va("SetPlayerStat%ii", i), PR_ANY);
}
SV_ParseClientCommand = PR_FindFunction(svprogfuncs, "SV_ParseClientCommand", PR_ANY);
SV_ParseConnectionlessPacket = PR_FindFunction(svprogfuncs, "SV_ParseConnectionlessPacket", PR_ANY);
gfuncs.ParseClientCommand = PR_FindFunction(svprogfuncs, "SV_ParseClientCommand", PR_ANY);
gfuncs.ParseConnectionlessPacket = PR_FindFunction(svprogfuncs, "SV_ParseConnectionlessPacket", PR_ANY);
UserInfo_Changed = PR_FindFunction(svprogfuncs, "UserInfo_Changed", PR_ANY);
localinfoChanged = PR_FindFunction(svprogfuncs, "localinfoChanged", PR_ANY);
ChatMessage = PR_FindFunction(svprogfuncs, "ChatMessage", PR_ANY);
mod_UserCmd = PR_FindFunction(svprogfuncs, "UserCmd", PR_ANY);
mod_ConsoleCmd = PR_FindFunction(svprogfuncs, "ConsoleCmd", PR_ANY);
gfuncs.UserInfo_Changed = PR_FindFunction(svprogfuncs, "UserInfo_Changed", PR_ANY);
gfuncs.localinfoChanged = PR_FindFunction(svprogfuncs, "localinfoChanged", PR_ANY);
gfuncs.ChatMessage = PR_FindFunction(svprogfuncs, "ChatMessage", PR_ANY);
gfuncs.UserCmd = PR_FindFunction(svprogfuncs, "UserCmd", PR_ANY);
gfuncs.ConsoleCmd = PR_FindFunction(svprogfuncs, "ConsoleCmd", PR_ANY);
pr_SV_PausedTic = PR_FindFunction(svprogfuncs, "SV_PausedTic", PR_ANY);
pr_SV_ShouldPause = PR_FindFunction(svprogfuncs, "SV_ShouldPause", PR_ANY);
pr_ClassChangeWeapon = PR_FindFunction(svprogfuncs, "ClassChangeWeapon", PR_ANY);
gfuncs.PausedTic = PR_FindFunction(svprogfuncs, "SV_PausedTic", PR_ANY);
gfuncs.ShouldPause = PR_FindFunction(svprogfuncs, "SV_ShouldPause", PR_ANY);
gfuncs.ClassChangeWeapon = PR_FindFunction(svprogfuncs, "ClassChangeWeapon", PR_ANY);
if (pr_no_playerphysics.value)
SV_PlayerPhysicsQC = 0;
@ -859,7 +871,7 @@ void PR_ApplyCompilation_f (void)
PR_LoadGlabalStruct();
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
SV_ClearWorld ();
@ -1368,14 +1380,16 @@ void Q_InitProgs(void)
qboolean PR_QCChat(char *text, int say_type)
{
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
globalvars_t *pr_globals;
if (!ChatMessage || pr_imitatemvdsv.value >= 0)
if (!gfuncs.ChatMessage || pr_imitatemvdsv.value >= 0)
return false;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
G_INT(OFS_PARM0) = (int)PR_SetString(svprogfuncs, text);
G_FLOAT(OFS_PARM1) = say_type;
PR_ExecuteProgram (svprogfuncs, ChatMessage);
PR_ExecuteProgram (svprogfuncs, gfuncs.ChatMessage);
if (G_FLOAT(OFS_RETURN))
return true;
@ -1386,13 +1400,13 @@ qboolean PR_GameCodePausedTic(float pausedtime)
{ //notications to the gamecode that the server is paused.
globalvars_t *pr_globals;
if (!svprogfuncs || !pr_SV_ShouldPause)
if (!svprogfuncs || !gfuncs.ShouldPause)
return false;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = pausedtime;
PR_ExecuteProgram (svprogfuncs, pr_SV_PausedTic);
PR_ExecuteProgram (svprogfuncs, gfuncs.PausedTic);
if (G_FLOAT(OFS_RETURN))
return true;
@ -1402,7 +1416,7 @@ qboolean PR_ShouldTogglePause(client_t *initiator, qboolean newpaused)
{
globalvars_t *pr_globals;
if (!svprogfuncs || !pr_SV_ShouldPause)
if (!svprogfuncs || !gfuncs.ShouldPause)
return true;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
@ -1412,7 +1426,7 @@ qboolean PR_ShouldTogglePause(client_t *initiator, qboolean newpaused)
else
pr_global_struct->self = 0;
G_FLOAT(OFS_PARM0) = newpaused;
PR_ExecuteProgram (svprogfuncs, pr_SV_ShouldPause);
PR_ExecuteProgram (svprogfuncs, gfuncs.ShouldPause);
return G_FLOAT(OFS_RETURN);
}
@ -1424,13 +1438,13 @@ qboolean PR_GameCodePacket(char *s)
client_t *cl;
char adr[MAX_ADR_SIZE];
if (!SV_ParseConnectionlessPacket)
if (!gfuncs.ParseConnectionlessPacket)
return false;
if (!svprogfuncs)
return false;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
// check for packets from connected clients
pr_global_struct->self = 0;
@ -1449,7 +1463,7 @@ qboolean PR_GameCodePacket(char *s)
G_INT(OFS_PARM0) = PR_TempString(svprogfuncs, NET_AdrToString (adr, sizeof(adr), net_from));
G_INT(OFS_PARM1) = PR_TempString(svprogfuncs, s);
PR_ExecuteProgram (svprogfuncs, SV_ParseConnectionlessPacket);
PR_ExecuteProgram (svprogfuncs, gfuncs.ParseConnectionlessPacket);
return G_FLOAT(OFS_RETURN);
}
@ -1464,15 +1478,15 @@ qboolean PR_KrimzonParseCommand(char *s)
if (!svprogfuncs)
return false;
if (SV_ParseClientCommand)
if (gfuncs.ParseClientCommand)
{ //the QC is expected to send it back to use via a builtin.
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
G_INT(OFS_PARM0) = (int)PR_TempString(svprogfuncs, s);
PR_ExecuteProgram (svprogfuncs, SV_ParseClientCommand);
PR_ExecuteProgram (svprogfuncs, gfuncs.ParseClientCommand);
return true;
}
@ -1493,29 +1507,29 @@ qboolean PR_UserCmd(char *s)
if (!svprogfuncs)
return false;
if (SV_ParseClientCommand)
if (gfuncs.ParseClientCommand)
{ //the QC is expected to send it back to use via a builtin.
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
G_INT(OFS_PARM0) = (int)PR_TempString(svprogfuncs, s);
PR_ExecuteProgram (svprogfuncs, SV_ParseClientCommand);
PR_ExecuteProgram (svprogfuncs, gfuncs.ParseClientCommand);
return true;
}
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
{
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
Q1QVM_ClientCommand();
return true; //qvm can print something if it wants
}
#endif
if (mod_UserCmd && pr_imitatemvdsv.value >= 0)
if (gfuncs.UserCmd && pr_imitatemvdsv.value >= 0)
{ //we didn't recognise it. see if the mod does.
//ktpro bug warning:
@ -1529,11 +1543,11 @@ qboolean PR_UserCmd(char *s)
}
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
G_INT(OFS_PARM0) = (int)PR_TempString(svprogfuncs, s);
PR_ExecuteProgram (svprogfuncs, mod_UserCmd);
PR_ExecuteProgram (svprogfuncs, gfuncs.UserCmd);
return !!G_FLOAT(OFS_RETURN);
}
@ -1562,15 +1576,15 @@ qboolean PR_ConsoleCmd(void)
if (svprogfuncs)
{
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
if (mod_ConsoleCmd && pr_imitatemvdsv.value >= 0)
if (gfuncs.ConsoleCmd && pr_imitatemvdsv.value >= 0)
{
if (sv_redirected != RD_OBLIVION)
{
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
}
PR_ExecuteProgram (svprogfuncs, mod_ConsoleCmd);
PR_ExecuteProgram (svprogfuncs, gfuncs.ConsoleCmd);
return (int) G_FLOAT(OFS_RETURN);
}
}
@ -1580,37 +1594,37 @@ qboolean PR_ConsoleCmd(void)
void PR_ClientUserInfoChanged(char *name, char *oldivalue, char *newvalue)
{
if (UserInfo_Changed && pr_imitatemvdsv.value >= 0)
if (gfuncs.UserInfo_Changed && pr_imitatemvdsv.value >= 0)
{
globalvars_t *pr_globals;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
G_INT(OFS_PARM0) = PR_TempString(svprogfuncs, name);
G_INT(OFS_PARM1) = PR_TempString(svprogfuncs, oldivalue);
G_INT(OFS_PARM2) = PR_TempString(svprogfuncs, newvalue);
PR_ExecuteProgram (svprogfuncs, UserInfo_Changed);
PR_ExecuteProgram (svprogfuncs, gfuncs.UserInfo_Changed);
}
}
void PR_LocalInfoChanged(char *name, char *oldivalue, char *newvalue)
{
if (localinfoChanged && sv.state && pr_imitatemvdsv.value >= 0)
if (gfuncs.localinfoChanged && sv.state && pr_imitatemvdsv.value >= 0)
{
globalvars_t *pr_globals;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
G_INT(OFS_PARM0) = PR_TempString(svprogfuncs, name);
G_INT(OFS_PARM1) = PR_TempString(svprogfuncs, oldivalue);
G_INT(OFS_PARM2) = PR_TempString(svprogfuncs, newvalue);
PR_ExecuteProgram (svprogfuncs, localinfoChanged);
PR_ExecuteProgram (svprogfuncs, gfuncs.localinfoChanged);
}
}
@ -1944,7 +1958,7 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m)
SV_LinkEdict (e, false);
}
}
//qw was fixed - it never sets the size of an alias model.
//qw was fixed - it never sets the size of an alias model, mostly because it doesn't know it.
}
}
}
@ -2496,7 +2510,7 @@ void PF_sound (progfuncs_t *prinst, struct globalvars_s *pr_globals)
if (volume > 255)
volume = 255;
SV_StartSound (entity, channel, sample, volume, attenuation);
SVQ1_StartSound (entity, channel, sample, volume, attenuation);
}
//an evil one from telejano.
@ -3648,8 +3662,8 @@ void PF_aim (progfuncs_t *prinst, struct globalvars_s *pr_globals)
VectorCopy (P_VEC(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.value || ent->v->team <=0 || ent->v->team != tr.ent->v->team) )
if (tr.ent && ((edict_t *)tr.ent)->v->takedamage == DAMAGE_AIM
&& (!teamplay.value || ent->v->team <=0 || ent->v->team != ((edict_t *)tr.ent)->v->team) )
{
VectorCopy (P_VEC(v_forward), G_VECTOR(OFS_RETURN));
return;
@ -6696,10 +6710,10 @@ void PR_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc)
if (!fromqc)
{
cl->sendinfo = true;
if (cl->state == cs_spawned && pr_ClassChangeWeapon)
if (cl->state == cs_spawned && gfuncs.ClassChangeWeapon)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
PR_ExecuteProgram (svprogfuncs, pr_ClassChangeWeapon);
PR_ExecuteProgram (svprogfuncs, gfuncs.ClassChangeWeapon);
}
}
}
@ -8542,14 +8556,14 @@ void PF_getsurfacenearpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals
if (surf->flags & SURF_PLANEBACK)
{
VectorSubtract(v1->position, v2->position, edgedir)
VectorSubtract(v1->position, v2->position, edgedir);
CrossProduct(edgedir, surf->plane->normal, edgenormal);
if (DotProduct(edgenormal, v1->position) > DotProduct(edgenormal, point))
break;
}
else
{
VectorSubtract(v1->position, v2->position, edgedir)
VectorSubtract(v1->position, v2->position, edgedir);
CrossProduct(edgedir, surf->plane->normal, edgenormal);
if (DotProduct(edgenormal, v1->position) < DotProduct(edgenormal, point))
break;

View File

@ -661,7 +661,7 @@ static int syscallqvm (void *offset, unsigned int mask, int fn, const int *arg)
case G_SOUND:
// ( int edn, int channel, char *samp, float vol, float att )
SV_StartSound (Q1QVMPF_EdictNum(svprogfuncs, VM_LONG(arg[0])), VM_LONG(arg[1]), VM_POINTER(arg[2]), VM_FLOAT(arg[3])*255, VM_FLOAT(arg[4]));
SVQ1_StartSound (Q1QVMPF_EdictNum(svprogfuncs, VM_LONG(arg[0])), VM_LONG(arg[1]), VM_POINTER(arg[2]), VM_FLOAT(arg[3])*255, VM_FLOAT(arg[4]));
break;
case G_TRACELINE:
@ -1380,12 +1380,12 @@ void Q1QVM_ClientConnect(client_t *cl)
strcpy(cl->name, cl->namebuf);
}
// call the spawn function
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
VM_Call(q1qvm, GAME_CLIENT_CONNECT, cl->spectator);
// actually spawn the player
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
VM_Call(q1qvm, GAME_PUT_CLIENT_IN_SERVER, cl->spectator);
}
@ -1399,7 +1399,7 @@ qboolean Q1QVM_GameConsoleCommand(void)
//FIXME: if an rcon command from someone on the server, mvdsv sets self to match the ip of that player
//this is not required (broken by proxies anyway) but is a nice handy feature
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
oldself = pr_global_struct->self; //these are usually useless
oldother = pr_global_struct->other; //but its possible that someone makes a mod that depends on the 'mod' command working via redirectcmd+co
//this at least matches mvdsv
@ -1421,7 +1421,7 @@ qboolean Q1QVM_ClientSay(edict_t *player, qboolean team)
SV_EndRedirect();
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, player);
washandled = VM_Call(q1qvm, GAME_CLIENT_SAY, team);
@ -1435,7 +1435,7 @@ qboolean Q1QVM_UserInfoChanged(edict_t *player)
if (!q1qvm)
return false;
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, player);
return VM_Call(q1qvm, GAME_CLIENT_USERINFO_CHANGED);
}

View File

@ -110,6 +110,7 @@ extern progparms_t svprogparms;
extern progsnum_t svmainprogs;
extern progsnum_t clmainprogs;
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
#define HLEDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,hledict_t,area)
#define Q2EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,q2edict_t,area)
#define Q3EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,q3serverEntity_t,area)

View File

@ -36,6 +36,13 @@ void SV_SavegameComment (char *text)
kills[0] = '\0';
}
else
#endif
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
sprintf (kills,"kills:moo");
}
else
#endif
sprintf (kills,"kills:%3i/%3i", (int)pr_global_struct->killed_monsters, (int)pr_global_struct->total_monsters);
memcpy (text+22, kills, strlen(kills));
@ -404,8 +411,7 @@ void SV_Loadgame_f(void)
sv.time = time;
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
fclose (f);
@ -663,7 +669,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
PR_LoadGlabalStruct();
pr_global_struct->time = sv.time = time;
pr_global_struct->time = sv.time = sv.physicstime = time;
sv.starttime = Sys_DoubleTime() - sv.time;
VFS_SEEK(f, modelpos);
@ -710,7 +716,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
if (spawnparamglobals[j])
*spawnparamglobals[j] = host_client->spawn_parms[j];
}
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
ent->area.next = ent->area.prev = NULL;
G_FLOAT(OFS_PARM0) = sv.time-host_client->spawninfotime;
@ -787,6 +793,14 @@ void SV_SaveLevelCache(qboolean dontharmgame)
}
#endif
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
SVHL_SaveLevelCache(name);
return;
}
#endif
f = fopen (name, "wb");
if (!f)
{

View File

@ -115,7 +115,7 @@ typedef struct
double time;
double starttime;
float physicstime; //nq clients do so much better with times sent with physics than real.
double physicstime; //This is the time at which the physics were last run.
int framenum;
int lastcheck; // used by PF_checkclient
@ -370,9 +370,13 @@ typedef struct client_s
int viewent; //fake the entity positioning.
edict_t *edict; // EDICT_NUM(clientnum+1)
//additional game modes use additional edict pointers. this ensures that references are crashes.
#ifdef Q2SERVER
q2edict_t *q2edict; // EDICT_NUM(clientnum+1)
#endif
#ifdef HLSERVER
struct hledict_s *hledict;
#endif
int playercolor;
int playerclass;
@ -691,6 +695,7 @@ typedef struct filteredip_s {
typedef enum {
GT_PROGS, //q1, qw, h2 are similar enough that we consider it only one game mode. (We don't support the h2 protocol)
GT_Q1QVM,
GT_HALFLIFE,
GT_QUAKE2, //q2 servers run from a q2 game dll
GT_QUAKE3, //q3 servers run off the q3 qvm api
GT_MAX
@ -1009,8 +1014,8 @@ void VARGS SV_Multicast (vec3_t origin, multicast_t to);
#define FULLDIMENSIONMASK 0xffffffff
void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int with, int without);
void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
float attenuation);
void SV_StartSound (int entnum, vec3_t origin, int seenmask, int channel, char *sample, int volume, float attenuation);
void SVQ1_StartSound (edict_t *entity, int channel, char *sample, int volume, float attenuation);
void SV_PrintToClient(client_t *cl, int level, char *string);
void VARGS SV_ClientPrintf (client_t *cl, int level, char *fmt, ...);
void VARGS SV_ClientTPrintf (client_t *cl, int level, translation_t text, ...);

View File

@ -254,15 +254,17 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg)
int en;
int currentsequence = client->netchan.outgoing_sequence;
unsigned short mask;
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
globalvars_t *pr_globals;
edict_t *ent;
qboolean writtenheader = false;
//we don't check that we got some already - because this is delta compressed!
if (!(client->csqcactive))
if (!(client->csqcactive) || !svprogfuncs)
return;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
//FIXME: prioritise the list of csqc ents somehow
csqcmsgbuffer.data = messagebuffer;
@ -700,7 +702,10 @@ void SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *
if (newnum < oldnum)
{ // this is a new entity, send it from the baseline
ent = EDICT_NUM(svprogfuncs, newnum);
if (svprogfuncs)
ent = EDICT_NUM(svprogfuncs, newnum);
else
ent = NULL;
//Con_Printf ("baseline %i\n", newnum);
#ifdef PROTOCOLEXTENSIONS
SV_WriteDelta (&ent->baseline, &to->entities[newindex], msg, true, client->fteprotocolextensions);
@ -2685,7 +2690,12 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
else
{
clent = client->edict;
pvs = SV_Snapshot_SetupPVS(client);
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
pvs = SVHL_Snapshot_SetupPVS(client);
else
#endif
pvs = SV_Snapshot_SetupPVS(client);
}
host_client = client;
@ -2693,7 +2703,8 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
SV_Snapshot_Clear(pack);
// send over the players in the PVS
SV_WritePlayersToClient (client, clent, pvs, msg);
if (svs.gametype != GT_HALFLIFE)
SV_WritePlayersToClient (client, clent, pvs, msg);
// put other visible entities into either a packet_entities or a nails message
@ -2703,7 +2714,12 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
}
else
{
SV_Snapshot_BuildQ1(client, pack, pvs, clent, ignorepvs);
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
SVHL_Snapshot_Build(client, pack, pvs, clent, ignorepvs);
else
#endif
SV_Snapshot_BuildQ1(client, pack, pvs, clent, ignorepvs);
}
#ifdef NQPROT

View File

@ -540,6 +540,9 @@ void SV_UnspawnServer (void) //terminate the running server.
}
#ifdef Q2SERVER
SVQ2_ShutdownGameProgs();
#endif
#ifdef HLSERVER
SVHL_ShutdownGame();
#endif
sv.worldmodel = NULL;
sv.state = ss_dead;
@ -863,6 +866,11 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
sv.state = ss_loading;
newgametype = svs.gametype;
#ifdef HLSERVER
if (SVHL_InitGame())
newgametype = GT_HALFLIFE;
else
#endif
#ifdef Q3SERVER
if (SVQ3_InitGame())
newgametype = GT_QUAKE3;
@ -897,6 +905,10 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
}
svs.gametype = newgametype;
#ifdef HLSERVER
if (newgametype != GT_HALFLIFE)
SVHL_ShutdownGame();
#endif
#ifdef Q3SERVER
if (newgametype != GT_QUAKE3)
SVQ3_ShutdownGame();
@ -1053,6 +1065,11 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
case GT_QUAKE3:
#ifdef Q3SERVER
sv.allocated_client_slots = 32;
#endif
break;
case GT_HALFLIFE:
#ifdef HLSERVER
SVHL_SetupGame();
#endif
break;
}
@ -1218,6 +1235,11 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
break;
case GT_QUAKE3:
break;
case GT_HALFLIFE:
#ifdef HLSERVER
SVHL_SpawnEntities(file);
#endif
break;
}
BZ_Free(file);
}
@ -1239,6 +1261,11 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
break;
case GT_QUAKE3:
break;
case GT_HALFLIFE:
#ifdef HLSERVER
SVHL_SpawnEntities(sv.worldmodel->entities);
#endif
break;
}
}
@ -1365,12 +1392,12 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
sv_player->xv->clientcolors = atoi(Info_ValueForKey(host_client->userinfo, "topcolor"))*16 + atoi(Info_ValueForKey(host_client->userinfo, "bottomcolor"));
// call the spawn function
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);

View File

@ -487,6 +487,11 @@ void SV_DropClient (client_t *drop)
case GT_QUAKE3:
#ifdef Q3SERVER
SVQ3_DropClient(drop);
#endif
break;
case GT_HALFLIFE:
#ifdef HLSERVER
SVHL_DropClient(drop);
#endif
break;
}
@ -1935,9 +1940,26 @@ client_t *SVC_DirectConnect(void)
}
}
//set up the gamecode for this player, optionally drop them here
edictnum = (newcl-svs.clients)+1;
switch (svs.gametype)
{
#ifdef HLSERVER
//fallthrough
case GT_HALFLIFE:
{
char reject[128];
if (!SVHL_ClientConnect(newcl, adr, reject))
{
SV_RejectMessage(protocol, "%s", reject);
return NULL;
}
}
break;
#endif
#ifdef VM_Q1
case GT_Q1QVM:
#endif
@ -1948,37 +1970,6 @@ client_t *SVC_DirectConnect(void)
#endif
temp.edict = ent;
// build a new connection
// accept the new client
// this is the only place a client_t is ever initialized, for q1 mods at least
#ifdef Q3SERVER
if (ISQ3CLIENT(newcl))
{
Huff_PreferedCompressionCRC();
temp.frameunion.q3frames = BZ_Malloc(Q3UPDATE_BACKUP*sizeof(*temp.frameunion.q3frames));
}
else
#endif
{
temp.frameunion.frames = newcl->frameunion.frames; //don't touch these.
if (temp.frameunion.frames)
{
Con_Printf("Debug: frames were set?\n");
Z_Free(temp.frameunion.frames);
}
temp.frameunion.frames = Z_Malloc((sizeof(client_frame_t)+sizeof(entity_state_t)*maxpacketentities)*UPDATE_BACKUP);
for (i = 0; i < UPDATE_BACKUP; i++)
{
temp.frameunion.frames[i].entities.max_entities = maxpacketentities;
temp.frameunion.frames[i].entities.entities = (entity_state_t*)(temp.frameunion.frames+UPDATE_BACKUP) + i*temp.frameunion.frames[i].entities.max_entities;
}
}
break;
#ifdef Q2SERVER
@ -1992,6 +1983,25 @@ client_t *SVC_DirectConnect(void)
ge->ClientUserinfoChanged(q2ent, temp.userinfo);
break;
#endif
default:
Sys_Error("Bad svs.gametype in SVC_DirectConnect");
break;
}
//initialise the client's frames, based on that client's protocol
switch(newcl->protocol)
{
case CP_QUAKE3:
Huff_PreferedCompressionCRC();
if (temp.frameunion.q3frames)
Z_Free(temp.frameunion.q3frames);
temp.frameunion.q3frames = Z_Malloc(Q3UPDATE_BACKUP*sizeof(*temp.frameunion.q3frames));
break;
case CP_QUAKE2:
// build a new connection
// accept the new client
// this is the only place a client_t is ever initialized
@ -2001,9 +2011,21 @@ client_t *SVC_DirectConnect(void)
temp.frameunion.q2frames = Z_Malloc(sizeof(q2client_frame_t)*Q2UPDATE_BACKUP);
break;
#endif
default:
Sys_Error("Bad svs.gametype in SVC_DirectConnect");
temp.frameunion.frames = newcl->frameunion.frames; //don't touch these.
if (temp.frameunion.frames)
{
Con_Printf("Debug: frames were set?\n");
Z_Free(temp.frameunion.frames);
}
temp.frameunion.frames = Z_Malloc((sizeof(client_frame_t)+sizeof(entity_state_t)*maxpacketentities)*UPDATE_BACKUP);
for (i = 0; i < UPDATE_BACKUP; i++)
{
temp.frameunion.frames[i].entities.max_entities = maxpacketentities;
temp.frameunion.frames[i].entities.entities = (entity_state_t*)(temp.frameunion.frames+UPDATE_BACKUP) + i*temp.frameunion.frames[i].entities.max_entities;
}
break;
}
@ -3063,7 +3085,7 @@ void SV_Impulse_f (void)
if (!svprogfuncs)
return;
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
svs.clients[i].state = cs_connected;
@ -3074,7 +3096,7 @@ void SV_Impulse_f (void)
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
@ -3708,7 +3730,7 @@ void Master_Heartbeat (void)
}
if (sv_reportheartbeats.value)
Con_Printf ("Sending heartbeat to %s\n", NET_AdrToString (adr, sizeof(adr), sv_masterlist[i].adr));
Con_Printf ("Sending heartbeat to %s (%s)\n", NET_AdrToString (adr, sizeof(adr), sv_masterlist[i].adr), sv_masterlist[i].cv.string);
NET_SendPacket (NS_SERVER, strlen(string), string, sv_masterlist[i].adr);
}
@ -3717,7 +3739,7 @@ void Master_Heartbeat (void)
if (sv_listen_dp.value) //set listen to 1 to allow qw connections, 2 to allow nq connections too.
{
if (sv_reportheartbeats.value)
Con_Printf ("Sending heartbeat to %s\n", NET_AdrToString (adr, sizeof(adr), sv_masterlist[i].adr));
Con_Printf ("Sending heartbeat to %s (%s)\n", NET_AdrToString (adr, sizeof(adr), sv_masterlist[i].adr), sv_masterlist[i].cv.string);
{
char *str = "\377\377\377\377heartbeat DarkPlaces\x0A";

View File

@ -146,11 +146,11 @@ qboolean SV_RunThink (edict_t *ent)
if (sv_nomsec.value>=2) //try and imitate nq as closeley as possible
{
thinktime = ent->v->nextthink;
if (thinktime <= 0 || thinktime > sv.time + host_frametime)
if (thinktime <= 0 || thinktime > sv.physicstime + host_frametime)
return true;
if (thinktime < sv.time)
thinktime = sv.time; // don't let things stay in the past.
if (thinktime < sv.physicstime)
thinktime = sv.physicstime; // 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;
@ -171,11 +171,11 @@ qboolean SV_RunThink (edict_t *ent)
thinktime = ent->v->nextthink;
if (thinktime <= 0)
return true;
if (thinktime > sv.time + host_frametime)
if (thinktime > sv.physicstime + host_frametime)
return true;
if (thinktime < sv.time)
thinktime = sv.time; // don't let things stay in the past.
if (thinktime < sv.physicstime)
thinktime = sv.physicstime; // 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;
@ -214,7 +214,7 @@ void SV_Impact (edict_t *e1, edict_t *e2)
old_self = pr_global_struct->self;
old_other = pr_global_struct->other;
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
if (e1->v->touch && e1->v->solid != SOLID_NOT)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, e1);
@ -338,7 +338,7 @@ int 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)
if (((edict_t *)trace.ent)->v->solid == SOLID_BSP)
{
ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
ent->v->groundentity = EDICT_TO_PROG(svprogfuncs, trace.ent);
@ -903,7 +903,7 @@ float l;
VectorCopy (ent->v->origin, oldorg);
VectorCopy (ent->v->angles, oldang);
ent->v->nextthink = 0;
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
#ifdef VM_Q1
@ -1034,7 +1034,7 @@ void SV_CheckWaterTransition (edict_t *ent)
{
if (ent->v->watertype == Q1CONTENTS_EMPTY)
{ // just crossed into water
SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
SVQ1_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
}
ent->v->watertype = cont;
ent->v->waterlevel = 1;
@ -1043,7 +1043,7 @@ void SV_CheckWaterTransition (edict_t *ent)
{
if (ent->v->watertype != Q1CONTENTS_EMPTY)
{ // just crossed into open
SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
SVQ1_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
}
ent->v->watertype = Q1CONTENTS_EMPTY;
ent->v->waterlevel = cont;
@ -1183,9 +1183,9 @@ void SV_Physics_Step (edict_t *ent)
if (hitsound)
{
if (progstype == PROG_H2)
SV_StartSound (ent, 0, "fx/thngland.wav", 255, 1);
SVQ1_StartSound (ent, 0, "fx/thngland.wav", 255, 1);
else
SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
SVQ1_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
}
}
}
@ -1204,7 +1204,7 @@ void SV_ProgStartFrame (void)
// let the progs know that a new frame has started
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_StartFrame();
@ -1732,8 +1732,8 @@ void SV_MoveChain(edict_t *ent, edict_t *movechain, float *initial_origin, float
{
vec3_t moveang, moveorg;
int i;
VectorSubtract(ent->v->angles, initial_angle, moveang)
VectorSubtract(ent->v->origin, initial_origin, moveorg)
VectorSubtract(ent->v->angles, initial_angle, moveang);
VectorSubtract(ent->v->origin, initial_origin, moveorg);
for(i=16;i && movechain != sv.edicts && !movechain->isfree;i--, movechain = PROG_TO_EDICT(svprogfuncs, movechain->xv->movechain))
{
@ -1791,7 +1791,7 @@ void SV_RunEntity (edict_t *ent)
//
// call standard client pre-think
//
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
@ -1876,7 +1876,7 @@ void SV_RunEntity (edict_t *ent)
{
SV_LinkEdict (ent, true);
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
@ -1970,16 +1970,15 @@ qboolean SV_Physics (void)
int i;
qboolean retouch;
edict_t *ent;
static double old_time;
if (svs.gametype != GT_PROGS && svs.gametype != GT_Q1QVM) //make tics multiples of sv_maxtic (defaults to 0.1)
if (svs.gametype != GT_PROGS && svs.gametype != GT_Q1QVM && svs.gametype != GT_HALFLIFE) //make tics multiples of sv_maxtic (defaults to 0.1)
{
host_frametime = sv.time - old_time;
host_frametime = sv.time - sv.physicstime;
if (host_frametime<0)
{
if (host_frametime < -1)
old_time = sv.time;
sv.physicstime = sv.time;
host_frametime = 0;
}
if (svs.gametype != GT_QUAKE3)
@ -1990,7 +1989,7 @@ qboolean SV_Physics (void)
}
if (host_frametime > sv_maxtic.value)
host_frametime = sv_maxtic.value;
old_time = sv.time;
sv.physicstime = sv.time;
sv.framenum++;
@ -2012,7 +2011,7 @@ qboolean SV_Physics (void)
return false;
}
if (/*sv.botsonthemap &&*/ progstype == PROG_QW)
if (svs.gametype != GT_HALFLIFE && /*sv.botsonthemap &&*/ progstype == PROG_QW)
{
//DP_SV_BOTCLIENT - make the bots move with qw physics.
//They only move when there arn't any players on the server, but they should move at the right kind of speed if there are... hopefully
@ -2065,84 +2064,105 @@ qboolean SV_Physics (void)
}
}
// don't bother running a frame if sys_ticrate seconds haven't passed
host_frametime = realtime - old_time;
if (host_frametime < -1)
old_time = 0;
if (host_frametime < sv_mintic.value)
return false;
if (host_frametime > sv_maxtic.value)
host_frametime = sv_maxtic.value;
old_time = realtime;
sv.physicstime = sv.time;
pr_global_struct->frametime = host_frametime;
SV_ProgStartFrame ();
PR_RunThreads();
retouch = (pr_nqglobal_struct->force_retouch && *pr_nqglobal_struct->force_retouch);
//
// treat each object in turn
// even the world gets a chance to think
//
for (i=0 ; i<sv.num_edicts ; i++)
while (1)
{
ent = EDICT_NUM(svprogfuncs, i);
if (ent->isfree)
host_frametime = sv.time - sv.physicstime;
if (host_frametime < 0)
{
sv.physicstime = sv.time;
break;
}
if (host_frametime <= 0 || host_frametime < sv_mintic.value)
break;
if (host_frametime > ((/*sv_captic.value<=*/0)?1:sv_maxtic.value*5))
{
//cap the distance to run physics
host_frametime = sv_maxtic.value;
sv.physicstime = sv.time;
}
else
{
if (host_frametime > sv_maxtic.value)
host_frametime = sv_maxtic.value;
sv.physicstime += host_frametime;
}
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
SVHL_RunFrame();
continue;
if (ent->solidtype != ent->v->solid)
{
// Con_Printf("Entity \"%s\" improperly changed solid type\n", svprogfuncs->stringtable+ent->v->classname);
SV_LinkEdict (ent, true); // a change of solidity should always relink the edict. someone messed up.
}
else if (retouch)
SV_LinkEdict (ent, true); // force retouch even for stationary
#endif
if (i > 0 && i <= sv.allocated_client_slots)
pr_global_struct->frametime = host_frametime;
SV_ProgStartFrame ();
PR_RunThreads();
retouch = (pr_nqglobal_struct->force_retouch && *pr_nqglobal_struct->force_retouch);
//
// treat each object in turn
// even the world gets a chance to think
//
for (i=0 ; i<sv.num_edicts ; i++)
{
if (!svs.clients[i-1].isindependant)
ent = EDICT_NUM(svprogfuncs, i);
if (ent->isfree)
continue;
if (ent->solidtype != ent->v->solid)
{
SV_RunEntity(ent);
SV_RunNewmis ();
// Con_Printf("Entity \"%s\" improperly changed solid type\n", svprogfuncs->stringtable+ent->v->classname);
SV_LinkEdict (ent, true); // a change of solidity should always relink the edict. someone messed up.
}
else
SV_LinkEdict(ent, true);
continue; // clients are run directly from packets
else if (retouch)
SV_LinkEdict (ent, true); // force retouch even for stationary
if (i > 0 && i <= sv.allocated_client_slots)
{
if (!svs.clients[i-1].isindependant)
{
SV_RunEntity(ent);
SV_RunNewmis ();
}
else
SV_LinkEdict(ent, true);
continue; // clients are run directly from packets
}
SV_RunEntity (ent);
SV_RunNewmis ();
}
SV_RunEntity (ent);
SV_RunNewmis ();
}
if (retouch)
pr_global_struct->force_retouch-=1;
if (retouch)
pr_global_struct->force_retouch-=1;
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->time = sv.time;
Q1QVM_EndFrame();
}
else
if (svs.gametype == GT_Q1QVM)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->time = sv.physicstime;
Q1QVM_EndFrame();
}
else
#endif
if (EndFrameQC)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->time = sv.time;
PR_ExecuteProgram (svprogfuncs, EndFrameQC);
}
if (EndFrameQC)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->time = sv.physicstime;
PR_ExecuteProgram (svprogfuncs, EndFrameQC);
}
NPP_Flush(); //flush it just in case there was an error and we stopped preparsing. This is only really needed while debugging.
NPP_Flush(); //flush it just in case there was an error and we stopped preparsing. This is only really needed while debugging.
}
return false;
}

View File

@ -663,24 +663,27 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
}
if (svprogfuncs)
{
if (!((int)client->edict->xv->dimension_see & dimension_mask))
continue;
if (to == MULTICAST_PHS_R || to == MULTICAST_PHS) {
vec3_t delta;
VectorSubtract(origin, client->edict->v->origin, delta);
if (Length(delta) <= 1024)
goto inrange;
}
// -1 is because pvs rows are 1 based, not 0 based like leafs
if (mask != sv.pvs)
{
leafnum = sv.worldmodel->funcs.LeafnumForPoint (sv.worldmodel, client->edict->v->origin)-1;
if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
if (to == MULTICAST_PHS_R || to == MULTICAST_PHS)
{
// Con_Printf ("PVS supressed multicast\n");
continue;
vec3_t delta;
VectorSubtract(origin, client->edict->v->origin, delta);
if (Length(delta) <= 1024)
goto inrange;
}
// -1 is because pvs rows are 1 based, not 0 based like leafs
if (mask != sv.pvs)
{
leafnum = sv.worldmodel->funcs.LeafnumForPoint (sv.worldmodel, client->edict->v->origin)-1;
if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
{
// Con_Printf ("PVS supressed multicast\n");
continue;
}
}
}
@ -774,15 +777,12 @@ Larger attenuations will drop off. (max 4 attenuation)
==================
*/
void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
float attenuation)
void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sample, int volume, float attenuation)
{
int sound_num;
int extfield_mask;
int qwflags;
int i;
int ent;
vec3_t origin;
qboolean use_phs;
qboolean reliable = false;
int requiredextensions = 0;
@ -817,8 +817,6 @@ void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
return;
}
ent = NUM_FOR_EDICT(svprogfuncs, entity);
if ((channel & 8) || !sv_phs.value) // no PHS flag
{
if (channel & 8)
@ -829,17 +827,6 @@ void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
else
use_phs = true;
// use the entity origin unless it is a bmodel, in which case use its bbox middle
if (entity->v->solid == SOLID_BSP)
{
for (i=0 ; i<3 ; i++)
origin[i] = entity->v->origin[i]+0.5*(entity->v->mins[i]+entity->v->maxs[i]);
}
else
{
VectorCopy (entity->v->origin, origin);
}
// if (channel == CHAN_BODY || channel == CHAN_VOICE)
// reliable = true;
@ -931,9 +918,26 @@ void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
MSG_WriteCoord (&sv.nqmulticast, origin[i]);
#endif
if (use_phs)
SV_MulticastProtExt(origin, reliable ? MULTICAST_PHS_R : MULTICAST_PHS, entity->xv->dimension_seen, requiredextensions, 0);
SV_MulticastProtExt(origin, reliable ? MULTICAST_PHS_R : MULTICAST_PHS, seenmask, requiredextensions, 0);
else
SV_MulticastProtExt(origin, reliable ? MULTICAST_ALL_R : MULTICAST_ALL, entity->xv->dimension_seen, requiredextensions, 0);
SV_MulticastProtExt(origin, reliable ? MULTICAST_ALL_R : MULTICAST_ALL, seenmask, requiredextensions, 0);
}
void SVQ1_StartSound (edict_t *entity, int channel, char *sample, int volume, float attenuation)
{
int i;
vec3_t origin;
if (entity->v->solid == SOLID_BSP)
{
for (i=0 ; i<3 ; i++)
origin[i] = entity->v->origin[i]+0.5*(entity->v->mins[i]+entity->v->maxs[i]);
}
else
{
VectorCopy (entity->v->origin, origin);
}
SV_StartSound(NUM_FOR_EDICT(svprogfuncs, entity), origin, entity->xv->dimension_seen, channel, sample, volume, attenuation);
}
/*
@ -975,6 +979,9 @@ void SV_WriteEntityDataToMessage (client_t *client, sizebuf_t *msg, int pnum)
ent = client->edict;
if (!ent)
return;
// send a damage message if the player got hit this frame
if (ent->v->dmg_take || ent->v->dmg_save)
{
@ -1379,80 +1386,90 @@ void SV_UpdateClientStats (client_t *client, int pnum)
if (client->spectator && client->spec_track > 0)
ent = svs.clients[client->spec_track - 1].edict;
statsf[STAT_HEALTH] = ent->v->health; //sorry, but mneh
statsi[STAT_WEAPON] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel));
if (host_client->fteprotocolextensions & PEXT_MODELDBL)
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
if ((unsigned)statsi[STAT_WEAPON] >= 512)
statsi[STAT_WEAPON] = 0;
}
else
{
if ((unsigned)statsi[STAT_WEAPON] >= 256)
statsi[STAT_WEAPON] = 0;
}
statsf[STAT_AMMO] = ent->v->currentammo;
statsf[STAT_ARMOR] = ent->v->armorvalue;
statsf[STAT_SHELLS] = ent->v->ammo_shells;
statsf[STAT_NAILS] = ent->v->ammo_nails;
statsf[STAT_ROCKETS] = ent->v->ammo_rockets;
statsf[STAT_CELLS] = ent->v->ammo_cells;
if (!client->spectator)
{
statsi[STAT_ACTIVEWEAPON] = ent->v->weapon;
if (client->csqcactive)
statsi[STAT_WEAPONFRAME] = ent->v->weaponframe;
}
SVHL_BuildStats(client, statsi, statsf, statss);
// stuff the sigil bits into the high bits of items for sbar
if (pr_items2)
statsi[STAT_ITEMS] = (int)ent->v->items | ((int)ent->xv->items2 << 23);
pr_globals = NULL;
}
else
statsi[STAT_ITEMS] = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28);
statsf[STAT_VIEWHEIGHT] = ent->v->view_ofs[2];
#ifdef PEXT_VIEW2
if (ent->xv->view2)
statsi[STAT_VIEW2] = NUM_FOR_EDICT(svprogfuncs, PROG_TO_EDICT(svprogfuncs, ent->xv->view2));
else
statsi[STAT_VIEW2] = 0;
#endif
if (!ent->xv->viewzoom)
statsi[STAT_VIEWZOOM] = 255;
else
statsi[STAT_VIEWZOOM] = ent->xv->viewzoom*255;
if (host_client->protocol == SCP_DARKPLACES7)
{
float *statsfi = (float*)statsi;
// statsfi[STAT_MOVEVARS_WALLFRICTION] = sv_wall
statsfi[STAT_MOVEVARS_FRICTION] = sv_friction.value;
statsfi[STAT_MOVEVARS_WATERFRICTION] = sv_waterfriction.value;
statsfi[STAT_MOVEVARS_TICRATE] = 72;
statsfi[STAT_MOVEVARS_TIMESCALE] = sv_gamespeed.value;
statsfi[STAT_MOVEVARS_GRAVITY] = sv_gravity.value;
statsfi[STAT_MOVEVARS_STOPSPEED] = sv_stopspeed.value;
statsfi[STAT_MOVEVARS_MAXSPEED] = host_client->maxspeed;
statsfi[STAT_MOVEVARS_SPECTATORMAXSPEED] = sv_spectatormaxspeed.value;
statsfi[STAT_MOVEVARS_ACCELERATE] = sv_accelerate.value;
statsfi[STAT_MOVEVARS_AIRACCELERATE] = sv_airaccelerate.value;
statsfi[STAT_MOVEVARS_WATERACCELERATE] = sv_wateraccelerate.value;
statsfi[STAT_MOVEVARS_ENTGRAVITY] = host_client->entgravity;
statsfi[STAT_MOVEVARS_JUMPVELOCITY] = 280;//sv_jumpvelocity.value; //bah
statsfi[STAT_MOVEVARS_EDGEFRICTION] = sv_edgefriction.value;
statsfi[STAT_MOVEVARS_MAXAIRSPEED] = host_client->maxspeed;
statsfi[STAT_MOVEVARS_STEPHEIGHT] = 18;
statsfi[STAT_MOVEVARS_AIRACCEL_QW] = 1;
statsfi[STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION] = sv_gravity.value;
statsf[STAT_HEALTH] = ent->v->health; //sorry, but mneh
statsi[STAT_WEAPON] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel));
if (host_client->fteprotocolextensions & PEXT_MODELDBL)
{
if ((unsigned)statsi[STAT_WEAPON] >= 512)
statsi[STAT_WEAPON] = 0;
}
else
{
if ((unsigned)statsi[STAT_WEAPON] >= 256)
statsi[STAT_WEAPON] = 0;
}
statsf[STAT_AMMO] = ent->v->currentammo;
statsf[STAT_ARMOR] = ent->v->armorvalue;
statsf[STAT_SHELLS] = ent->v->ammo_shells;
statsf[STAT_NAILS] = ent->v->ammo_nails;
statsf[STAT_ROCKETS] = ent->v->ammo_rockets;
statsf[STAT_CELLS] = ent->v->ammo_cells;
if (!client->spectator)
{
statsi[STAT_ACTIVEWEAPON] = ent->v->weapon;
if (client->csqcactive)
statsi[STAT_WEAPONFRAME] = ent->v->weaponframe;
}
// stuff the sigil bits into the high bits of items for sbar
if (pr_items2)
statsi[STAT_ITEMS] = (int)ent->v->items | ((int)ent->xv->items2 << 23);
else
statsi[STAT_ITEMS] = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28);
statsf[STAT_VIEWHEIGHT] = ent->v->view_ofs[2];
#ifdef PEXT_VIEW2
if (ent->xv->view2)
statsi[STAT_VIEW2] = NUM_FOR_EDICT(svprogfuncs, PROG_TO_EDICT(svprogfuncs, ent->xv->view2));
else
statsi[STAT_VIEW2] = 0;
#endif
if (!ent->xv->viewzoom)
statsi[STAT_VIEWZOOM] = 255;
else
statsi[STAT_VIEWZOOM] = ent->xv->viewzoom*255;
if (host_client->protocol == SCP_DARKPLACES7)
{
float *statsfi = (float*)statsi;
// statsfi[STAT_MOVEVARS_WALLFRICTION] = sv_wall
statsfi[STAT_MOVEVARS_FRICTION] = sv_friction.value;
statsfi[STAT_MOVEVARS_WATERFRICTION] = sv_waterfriction.value;
statsfi[STAT_MOVEVARS_TICRATE] = 72;
statsfi[STAT_MOVEVARS_TIMESCALE] = sv_gamespeed.value;
statsfi[STAT_MOVEVARS_GRAVITY] = sv_gravity.value;
statsfi[STAT_MOVEVARS_STOPSPEED] = sv_stopspeed.value;
statsfi[STAT_MOVEVARS_MAXSPEED] = host_client->maxspeed;
statsfi[STAT_MOVEVARS_SPECTATORMAXSPEED] = sv_spectatormaxspeed.value;
statsfi[STAT_MOVEVARS_ACCELERATE] = sv_accelerate.value;
statsfi[STAT_MOVEVARS_AIRACCELERATE] = sv_airaccelerate.value;
statsfi[STAT_MOVEVARS_WATERACCELERATE] = sv_wateraccelerate.value;
statsfi[STAT_MOVEVARS_ENTGRAVITY] = host_client->entgravity;
statsfi[STAT_MOVEVARS_JUMPVELOCITY] = 280;//sv_jumpvelocity.value; //bah
statsfi[STAT_MOVEVARS_EDGEFRICTION] = sv_edgefriction.value;
statsfi[STAT_MOVEVARS_MAXAIRSPEED] = host_client->maxspeed;
statsfi[STAT_MOVEVARS_STEPHEIGHT] = 18;
statsfi[STAT_MOVEVARS_AIRACCEL_QW] = 1;
statsfi[STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION] = sv_gravity.value;
}
SV_UpdateQCStats(ent, statsi, statss, statsf);
//dmw tweek for stats
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
}
SV_UpdateQCStats(ent, statsi, statss, statsf);
//dmw tweek for stats
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
m = MAX_QW_STATS;
if (client->fteprotocolextensions & PEXT_HEXEN2)
m = MAX_CL_STATS;
@ -1698,12 +1715,15 @@ SV_UpdateToReliableMessages
*/
void SV_UpdateToReliableMessages (void)
{
volatile float newval; // needed to ensure 32/32-bit fp comparisons
int i, j;
client_t *client, *sp;
edict_t *ent;
char *name;
float curgrav;
float curspeed;
int curfrags;
// check for changes to be sent over the reliable streams to all clients
for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++)
{
@ -1777,6 +1797,34 @@ void SV_UpdateToReliableMessages (void)
}
continue;
}
if (svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM)
{
ent = host_client->edict;
curfrags = host_client->edict->v->frags;
curgrav = ent->xv->gravity*sv_gravity.value;
curspeed = ent->xv->maxspeed;
if (progstype != PROG_QW)
{
if (!curgrav)
curgrav = 1;
if (!curspeed)
curspeed = sv_maxspeed.value;
}
if (ent->xv->hasted)
curspeed*=ent->xv->hasted;
}
else
{
curgrav = sv_gravity.value;
curspeed = sv_maxspeed.value;
curfrags = 0;
}
#ifdef SVCHAT //enforce a no moving time when chatting. Prevent client prediction going mad.
if (host_client->chat.active)
curspeed = 0;
#endif
if (!ISQ2CLIENT(host_client))
{
if (host_client->sendinfo)
@ -1784,7 +1832,7 @@ void SV_UpdateToReliableMessages (void)
host_client->sendinfo = false;
SV_FullClientUpdate (host_client, &sv.reliable_datagram, host_client->fteprotocolextensions);
}
if (host_client->old_frags != (int)host_client->edict->v->frags)
if (host_client->old_frags != curfrags)
{
for (j=0, client = svs.clients ; j<MAX_CLIENTS ; j++, client++)
{
@ -1794,7 +1842,7 @@ void SV_UpdateToReliableMessages (void)
continue;
ClientReliableWrite_Begin(client, svc_updatefrags, 4);
ClientReliableWrite_Byte(client, i);
ClientReliableWrite_Short(client, host_client->edict->v->frags);
ClientReliableWrite_Short(client, curfrags);
}
if (sv.mvdrecording)
@ -1802,45 +1850,24 @@ void SV_UpdateToReliableMessages (void)
MVDWrite_Begin(dem_all, 0, 4);
MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updatefrags);
MSG_WriteByte((sizebuf_t*)demo.dbuf, i);
MSG_WriteShort((sizebuf_t*)demo.dbuf, host_client->edict->v->frags);
MSG_WriteShort((sizebuf_t*)demo.dbuf, curfrags);
}
host_client->old_frags = host_client->edict->v->frags;
host_client->old_frags = curfrags;
}
{
// maxspeed/entgravity changes
ent = host_client->edict;
newval = ent->xv->gravity*sv_gravity.value;
if (progstype != PROG_QW)
{
if (!newval)
newval = 1;
}
if (host_client->entgravity != newval)
if (host_client->entgravity != curgrav)
{
if (ISQWCLIENT(host_client))
{
sp = SV_SplitClientDest(host_client, svc_entgravity, 5);
ClientReliableWrite_Float(sp, newval/movevars.gravity); //lie to the client in a cunning way
ClientReliableWrite_Float(sp, curgrav/movevars.gravity); //lie to the client in a cunning way
}
host_client->entgravity = newval;
host_client->entgravity = curgrav;
}
newval = ent->xv->maxspeed;
if (progstype != PROG_QW)
{
if (!newval)
newval = sv_maxspeed.value;
}
if (ent->xv->hasted)
newval*=ent->xv->hasted;
#ifdef SVCHAT //enforce a no moving time when chatting. Prevent client prediction going mad.
if (host_client->chat.active)
newval = 0;
#endif
if (host_client->maxspeed != newval)
if (host_client->maxspeed != curspeed)
{ //MSVC can really suck at times (optimiser bug)
if (ISQWCLIENT(host_client))
{
@ -1860,15 +1887,15 @@ void SV_UpdateToReliableMessages (void)
ClientReliableWrite_Begin (sp, svcfte_choosesplitclient, 7);
ClientReliableWrite_Byte (sp, pnum);
ClientReliableWrite_Byte (sp, svc_maxspeed);
ClientReliableWrite_Float(sp, newval);
ClientReliableWrite_Float(sp, curspeed);
}
else
{
ClientReliableWrite_Begin(host_client, svc_maxspeed, 5);
ClientReliableWrite_Float(host_client, newval);
ClientReliableWrite_Float(host_client, curspeed);
}
}
host_client->maxspeed = newval;
host_client->maxspeed = curspeed;
}
}
}

View File

@ -261,12 +261,21 @@ void SV_New_f (void)
splitnum = 0;
for (split = host_client; split; split = split->controlled)
{
#ifdef Q2SERVER
if (!svprogfuncs)
playernum = Q2NUM_FOR_EDICT(split->q2edict)-1;
else
switch(svs.gametype)
{
#ifdef HLSERVER
case GT_HALFLIFE:
playernum = split - svs.clients;
break;
#endif
#ifdef Q2SERVER
case GT_QUAKE2:
playernum = Q2NUM_FOR_EDICT(split->q2edict)-1;
break;
#endif
default:
playernum = NUM_FOR_EDICT(svprogfuncs, split->edict)-1;
}
if (sv.demostate)
{
playernum = (MAX_CLIENTS-1-splitnum)|128;
@ -1241,6 +1250,8 @@ void SV_Spawn_f (void)
client_t *client, *split;
edict_t *ent;
int secret_total, secret_found, monsters_total, monsters_found;
if (host_client->state != cs_connected)
{
Con_Printf ("Spawn not valid -- already spawned\n");
@ -1302,45 +1313,66 @@ void SV_Spawn_f (void)
}
}
// set up the edict
for (split = host_client; split; split = split->controlled)
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
ent = split->edict;
if (split->istobeloaded) //minimal setup
for (split = host_client; split; split = split->controlled)
{
split->entgravity = ent->xv->gravity;
split->maxspeed = ent->xv->maxspeed;
}
else
{
SV_SetUpClientEdict(split, ent);
split->entgravity = 1;
split->maxspeed = 320;
}
//
// force stats to be updated
//
memset (host_client->statsi, 0, sizeof(host_client->statsi));
memset (host_client->statsf, 0, sizeof(host_client->statsf));
memset (host_client->statss, 0, sizeof(host_client->statss));
secret_total = 0;
secret_found = 0;
monsters_total = 0;
monsters_found = 0;
}
else
#endif
{
// set up the edict
for (split = host_client; split; split = split->controlled)
{
ent = split->edict;
if (split->istobeloaded) //minimal setup
{
split->entgravity = ent->xv->gravity;
split->maxspeed = ent->xv->maxspeed;
}
else
{
SV_SetUpClientEdict(split, ent);
}
//
// force stats to be updated
//
memset (host_client->statsi, 0, sizeof(host_client->statsi));
memset (host_client->statsf, 0, sizeof(host_client->statsf));
memset (host_client->statss, 0, sizeof(host_client->statss));
}
secret_total = pr_global_struct->total_secrets;
secret_found = pr_global_struct->found_secrets;
monsters_total = pr_global_struct->total_monsters;
monsters_found = pr_global_struct->killed_monsters;
}
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALSECRETS);
ClientReliableWrite_Long (host_client, pr_global_struct->total_secrets);
ClientReliableWrite_Long (host_client, secret_total);
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALMONSTERS);
ClientReliableWrite_Long (host_client, pr_global_struct->total_monsters);
ClientReliableWrite_Long (host_client, monsters_total);
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_SECRETS);
ClientReliableWrite_Long (host_client, pr_global_struct->found_secrets);
ClientReliableWrite_Long (host_client, secret_found);
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_MONSTERS);
ClientReliableWrite_Long (host_client, pr_global_struct->killed_monsters);
ClientReliableWrite_Long (host_client, monsters_found);
// get the client to check and download skins
// when that is completed, a begin command will be issued
ClientReliableWrite_Begin (host_client, svc_stufftext, 8);
@ -1385,42 +1417,94 @@ void SV_Begin_Core(client_t *split)
int i;
if (progstype == PROG_H2 && host_client->playerclass)
host_client->edict->xv->playerclass = host_client->playerclass; //make sure it's set the same as the userinfo
#ifdef Q2SERVER
if (ge)
{
ge->ClientBegin(split->q2edict);
split->istobeloaded = false;
}
else
#endif
if (split->istobeloaded)
{
func_t f;
split->istobeloaded = false;
f = PR_FindFunction(svprogfuncs, "RestoreGame", PR_ANY);
if (f)
#ifdef Q2SERVER
if (ge)
{
ge->ClientBegin(split->q2edict);
split->istobeloaded = false;
}
else
#endif
if (split->istobeloaded)
{
func_t f;
split->istobeloaded = false;
f = PR_FindFunction(svprogfuncs, "RestoreGame", PR_ANY);
if (f)
{
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, f);
}
}
else
{
if (split->spectator)
{
SV_SpawnSpectator ();
if (SpectatorConnect)
{
pr_global_struct->time = sv.time;
//keep the spectator tracking the player from the previous map
if (split->spec_track > 0)
split->edict->v->goalentity = EDICT_TO_PROG(svprogfuncs, svs.clients[split->spec_track-1].edict);
else
split->edict->v->goalentity = 0;
// copy spawn parms out of the client_t
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
{
if (spawnparamglobals[i])
*spawnparamglobals[i] = split->spawn_parms[i];
}
// call the spawn function
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, f);
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
}
}
else
{
if (split->spectator)
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
SV_SpawnSpectator ();
if (SpectatorConnect)
SVHL_PutClientInServer(split);
}
else
#endif
if (svprogfuncs)
{
eval_t *eval, *eval2;
eval = PR_FindGlobal(svprogfuncs, "ClientReEnter", 0);
if (eval && split->spawninfo)
{
//keep the spectator tracking the player from the previous map
if (split->spec_track > 0)
split->edict->v->goalentity = EDICT_TO_PROG(svprogfuncs, svs.clients[split->spec_track-1].edict);
else
split->edict->v->goalentity = 0;
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
int j;
edict_t *ent;
ent = split->edict;
j = strlen(split->spawninfo);
SV_UnlinkEdict(ent);
svprogfuncs->restoreent(svprogfuncs, split->spawninfo, &j, ent);
eval2 = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, "stats_restored", NULL);
if (eval2)
eval2->_float = 1;
for (j=0 ; j< NUM_SPAWN_PARMS ; j++)
{
if (spawnparamglobals[j])
*spawnparamglobals[j] = split->spawn_parms[j];
}
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
G_FLOAT(OFS_PARM0) = sv.time - split->spawninfotime;
PR_ExecuteProgram(svprogfuncs, eval->function);
}
else
{
// copy spawn parms out of the client_t
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
{
@ -1429,88 +1513,44 @@ void SV_Begin_Core(client_t *split)
}
// call the spawn function
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
}
}
else
{
if (svprogfuncs)
{
eval_t *eval, *eval2;
eval = PR_FindGlobal(svprogfuncs, "ClientReEnter", 0);
if (eval && split->spawninfo)
{
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
int j;
edict_t *ent;
ent = split->edict;
j = strlen(split->spawninfo);
SV_UnlinkEdict(ent);
svprogfuncs->restoreent(svprogfuncs, split->spawninfo, &j, ent);
eval2 = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, "stats_restored", NULL);
if (eval2)
eval2->_float = 1;
for (j=0 ; j< NUM_SPAWN_PARMS ; j++)
{
if (spawnparamglobals[j])
*spawnparamglobals[j] = split->spawn_parms[j];
}
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
G_FLOAT(OFS_PARM0) = sv.time - split->spawninfotime;
PR_ExecuteProgram(svprogfuncs, eval->function);
}
else
{
// copy spawn parms out of the client_t
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
{
if (spawnparamglobals[i])
*spawnparamglobals[i] = split->spawn_parms[i];
}
// call the spawn function
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_ClientConnect(split);
else
if (svs.gametype == GT_Q1QVM)
Q1QVM_ClientConnect(split);
else
#endif
{
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
}
oh = host_client;
host_client = split;
sv_player = host_client->edict;
SV_PreRunCmd();
{
usercmd_t cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.msec = 0;
#define ANGLE2SHORT(x) (x) * (65536/360.0)
cmd.angles[0] = ANGLE2SHORT(split->edict->v->v_angle[0]);
cmd.angles[1] = ANGLE2SHORT(split->edict->v->v_angle[1]);
cmd.angles[2] = ANGLE2SHORT(split->edict->v->v_angle[2]);
SV_RunCmd(&cmd, false);
}
SV_PostRunCmd();
host_client = oh;
sv_player = host_client->edict;
{
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
}
oh = host_client;
host_client = split;
sv_player = host_client->edict;
SV_PreRunCmd();
{
usercmd_t cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.msec = 0;
#define ANGLE2SHORT(x) (x) * (65536/360.0)
cmd.angles[0] = ANGLE2SHORT(split->edict->v->v_angle[0]);
cmd.angles[1] = ANGLE2SHORT(split->edict->v->v_angle[1]);
cmd.angles[2] = ANGLE2SHORT(split->edict->v->v_angle[2]);
SV_RunCmd(&cmd, false);
}
SV_PostRunCmd();
host_client = oh;
sv_player = host_client->edict;
}
}
}
}
}
/*
==================
@ -2722,16 +2762,26 @@ SV_Kill_f
void SV_Kill_f (void)
{
float floodtime;
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
HLSV_ClientCommand(host_client);
return;
}
#endif
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
{
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
Q1QVM_ClientCommand();
return;
}
#endif
if (svs.gametype != GT_PROGS)
return;
if (sv_player->v->health <= 0)
{
@ -2749,7 +2799,7 @@ void SV_Kill_f (void)
SV_PushFloodProt(host_client);
}
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientKill);
@ -3553,12 +3603,12 @@ void Cmd_Join_f (void)
}
// call the spawn function
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
@ -3648,7 +3698,7 @@ void Cmd_Observe_f (void)
// call the spawn function
if (SpectatorConnect)
{
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
}
@ -3886,6 +3936,14 @@ void SV_ExecuteUserCommand (char *s, qboolean fromQC)
if (!u->name)
{
#ifdef HLSERVER
if (HLSV_ClientCommand(host_client))
{
host_client = oldhost;
return;
}
#endif
if (!fromQC)
if (PR_UserCmd(s)) //Q2 and MVDSV command handling only happens if the engine didn't recognise it.
{
@ -4062,7 +4120,7 @@ void SVNQ_Begin_f (void)
}
// call the spawn function
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
}
@ -4077,12 +4135,12 @@ void SVNQ_Begin_f (void)
}
// call the spawn function
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
}
@ -5344,7 +5402,13 @@ haveannothergo:
newcmd.upmove = 0;
}
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
SVHL_RunPlayerCommand(cl, &oldest, &oldcmd, &newcmd);
}
else
#endif
if (!sv.paused)
{
if (sv_nomsec.value)
@ -6213,7 +6277,7 @@ void SV_ClientThink (void)
if (SV_PlayerPhysicsQC)
{
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, SV_PlayerPhysicsQC);
return;

View File

@ -2051,7 +2051,7 @@ void SVQ3_EmitPacketEntities(client_t *client, q3client_frame_t *from, q3client_
{
// this is a new entity, send it from the baseline
if (svs.gametype == GT_QUAKE3)
MSGQ3_WriteDeltaEntity( msg, &q3_baselines[newnum], newent, true );
MSGQ3_WriteDeltaEntity( msg, &q3_baselines[newnum], newent, true );
else
{
q3entityState_t q3base;
@ -2128,7 +2128,7 @@ void SVQ3_WriteSnapshotToClient(client_t *client, sizebuf_t *msg)
// write snapshot header
MSG_WriteBits(msg, svcq3_snapshot, 8);
MSG_WriteBits(msg, (int)(sv.time*1000), 32);
MSG_WriteBits(msg, snap->serverTime, 32);
MSG_WriteBits(msg, delta, 8); // what we are delta'ing from
// write snapFlags
@ -2362,8 +2362,8 @@ void SVQ3_BuildClientSnapshot( client_t *client )
clientNum = client - svs.clients;
if (svs.gametype == GT_QUAKE3)
{
clent = GENTITY_FOR_NUM( clientNum );
ps = PS_FOR_NUM( clientNum );
clent = GENTITY_FOR_NUM( clientNum );
ps = PS_FOR_NUM( clientNum );
}
else
{
@ -2374,7 +2374,7 @@ void SVQ3_BuildClientSnapshot( client_t *client )
// this is the frame we are creating
snap = &client->frameunion.q3frames[client->netchan.outgoing_sequence & Q3UPDATE_MASK];
snap->serverTime = Sys_DoubleTime()*1000;//svs.levelTime; // save it for ping calc later
snap->serverTime = sv.time*1000;//svs.levelTime; // save it for ping calc later
snap->flags = 0;
if( client->state < cs_spawned )
@ -2418,50 +2418,50 @@ void SVQ3_BuildClientSnapshot( client_t *client )
if (svs.gametype == GT_QUAKE3)
{
// check for SVF_PORTAL entities first
for( i=0 ; i<numq3entities ; i++ )
{
ent = GENTITY_FOR_NUM( i );
if( ent == clent )
continue;
if( !(ent->r.svFlags & SVF_PORTAL) )
continue;
if( !SVQ3_EntityIsVisible( ent ) )
continue;
// merge PVS if portal
portalarea = CM_PointLeafnum(sv.worldmodel, ent->s.origin2);
portalarea = CM_LeafArea(sv.worldmodel, portalarea);
// CM_MergePVS ( ent->s.origin2 );
// CM_MergeAreaBits( snap->areabits, portalarea );
}
// add all visible entities
for( i=0 ; i<numq3entities ; i++ )
{
ent = GENTITY_FOR_NUM( i );
if (ent == clent)
continue;
if( !SVQ3_EntityIsVisible( ent ) )
continue;
if (ent->s.number != i)
{
Con_DPrintf( "FIXING ENT->S.NUMBER!!!\n" );
ent->s.number = i;
}
entityStates[snap->num_entities++] = &ent->s;
if( snap->num_entities >= MAX_ENTITIES_IN_SNAPSHOT )
for( i=0 ; i<numq3entities ; i++ )
{
Con_DPrintf( "MAX_ENTITIES_IN_SNAPSHOT\n" );
break;
ent = GENTITY_FOR_NUM( i );
if( ent == clent )
continue;
if( !(ent->r.svFlags & SVF_PORTAL) )
continue;
if( !SVQ3_EntityIsVisible( ent ) )
continue;
// merge PVS if portal
portalarea = CM_PointLeafnum(sv.worldmodel, ent->s.origin2);
portalarea = CM_LeafArea(sv.worldmodel, portalarea);
// CM_MergePVS ( ent->s.origin2 );
// CM_MergeAreaBits( snap->areabits, portalarea );
}
// add all visible entities
for( i=0 ; i<numq3entities ; i++ )
{
ent = GENTITY_FOR_NUM( i );
if (ent == clent)
continue;
if( !SVQ3_EntityIsVisible( ent ) )
continue;
if (ent->s.number != i)
{
Con_DPrintf( "FIXING ENT->S.NUMBER!!!\n" );
ent->s.number = i;
}
entityStates[snap->num_entities++] = &ent->s;
if( snap->num_entities >= MAX_ENTITIES_IN_SNAPSHOT )
{
Con_DPrintf( "MAX_ENTITIES_IN_SNAPSHOT\n" );
break;
}
}
}
}
else
{ //our q1->q3 converter
@ -2690,29 +2690,29 @@ void SVQ3_SendGameState(client_t *client)
switch (svs.gametype)
{
case GT_QUAKE3:
// write configstrings
for( i=0; i<MAX_CONFIGSTRINGS; i++ )
{
configString = svq3_configstrings[i];
if( !configString )
continue;
MSG_WriteBits( &msg, svcq3_configstring, 8);
MSG_WriteBits( &msg, i, 16 );
for (j = 0; configString[j]; j++)
MSG_WriteBits(&msg, configString[j], 8);
MSG_WriteBits(&msg, 0, 8);
}
// write baselines
for( i=0; i<MAX_GENTITIES; i++ )
{
if (!q3_baselines[i].number)
// write configstrings
for( i=0; i<MAX_CONFIGSTRINGS; i++ )
{
configString = svq3_configstrings[i];
if( !configString )
continue;
MSG_WriteBits(&msg, svcq3_baseline, 8);
MSGQ3_WriteDeltaEntity( &msg, NULL, &q3_baselines[i], true );
}
MSG_WriteBits( &msg, svcq3_configstring, 8);
MSG_WriteBits( &msg, i, 16 );
for (j = 0; configString[j]; j++)
MSG_WriteBits(&msg, configString[j], 8);
MSG_WriteBits(&msg, 0, 8);
}
// write baselines
for( i=0; i<MAX_GENTITIES; i++ )
{
if (!q3_baselines[i].number)
continue;
MSG_WriteBits(&msg, svcq3_baseline, 8);
MSGQ3_WriteDeltaEntity( &msg, NULL, &q3_baselines[i], true );
}
break;
case GT_PROGS:
case GT_Q1QVM:
@ -2976,6 +2976,8 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
SV_Begin_Core(client);
}
client->state = cs_spawned;
client->lastcmd.servertime = sv.time*1000;
break;
case cs_spawned:
// run G_ClientThink() on each usercmd
@ -2991,7 +2993,7 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
memcpy( &client->lastcmd, to, sizeof(client->lastcmd));
if (svs.gametype == GT_QUAKE3)
SVQ3_ClientThink(client);
SVQ3_ClientThink(client);
else
{
usercmd_t temp;
@ -3007,7 +3009,7 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
if (temp.buttons & 64)
temp.buttons |= 2;
SV_RunCmd(&temp, false);
}
}
}
if (svs.gametype != GT_QUAKE3)
SV_PostRunCmd();
@ -3025,7 +3027,7 @@ void SVQ3_UpdateUserinfo_f(client_t *cl)
SV_ExtractFromUserinfo (cl);
if (svs.gametype == GT_QUAKE3)
VM_Call(q3gamevm, GAME_CLIENT_USERINFO_CHANGED, (int)(cl-svs.clients));
VM_Call(q3gamevm, GAME_CLIENT_USERINFO_CHANGED, (int)(cl-svs.clients));
}
void SVQ3_Drop_f(client_t *cl)

View File

@ -273,7 +273,7 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node )
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, touch);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->time = sv.time;
pr_global_struct->time = sv.physicstime;
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Touch();
@ -299,7 +299,7 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node )
}
#ifdef Q2BSPS
void Q2BSP_FindTouchedLeafs(model_t *model, edict_t *ent)
void Q2BSP_FindTouchedLeafs(model_t *model, edict_t *ent, float *mins, float *maxs)
{
#define MAX_TOTAL_ENT_LEAFS 128
int leafs[MAX_TOTAL_ENT_LEAFS];
@ -315,7 +315,7 @@ void Q2BSP_FindTouchedLeafs(model_t *model, edict_t *ent)
ent->areanum2 = 0;
//get all leafs, including solids
num_leafs = CM_BoxLeafnums (model, ent->v->absmin, ent->v->absmax,
num_leafs = CM_BoxLeafnums (model, mins, maxs,
leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
// set areas
@ -462,8 +462,10 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
{
ent->v->absmin[0] -= 15;
ent->v->absmin[1] -= 15;
ent->v->absmin[2] -= 1;
ent->v->absmax[0] += 15;
ent->v->absmax[1] += 15;
ent->v->absmax[2] += 1;
}
else
{ // because movement is clipped an epsilon away from an actual edge,
@ -477,7 +479,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
}
// link to PVS leafs
sv.worldmodel->funcs.FindTouchedLeafs_Q1(sv.worldmodel, ent);
sv.worldmodel->funcs.FindTouchedLeafs_Q1(sv.worldmodel, ent, ent->v->absmin, ent->v->absmax);
/*
#ifdef Q2BSPS
if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3)