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)); memset(&pmove, 0, sizeof(pmove));
pmove.numphysent = 1; pmove.numphysent = 1;
memset(&pmove.physents[0], 0, sizeof(physent_t));
VectorClear (pmove.physents[0].origin); VectorClear (pmove.physents[0].origin);
pmove.physents[0].model = cl.worldmodel; pmove.physents[0].model = cl.worldmodel;
#endif #endif

View File

@ -1448,7 +1448,7 @@ void CL_TransitionPacketEntities(packet_entities_t *newpack, packet_entities_t *
} }
le = &cl.lerpents[snew->number]; 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) if (DotProduct(move, move) > 200*200 || snew->modelindex != sold->modelindex)
{ {
sold = snew; //teleported? 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 //bots or powerup glows. items always glow, powerups can be disabled
if (state->modelindex != cl_playerindex || r_powerupglow.value) 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[i] = ent->origin[i] - offs*v_forward[i] + 22*v_right[i];
newent->origin[2] -= 16; newent->origin[2] -= 16;
VectorCopy (ent->angles, newent->angles) VectorCopy (ent->angles, newent->angles);
newent->angles[2] -= 45; newent->angles[2] -= 45;
VectorCopy(newent->angles, angles); VectorCopy(newent->angles, angles);
@ -3102,6 +3102,7 @@ void CL_SetSolidEntities (void)
packet_entities_t *pak; packet_entities_t *pak;
entity_state_t *state; entity_state_t *state;
memset(&pmove.physents[0], 0, sizeof(physent_t));
pmove.physents[0].model = cl.worldmodel; pmove.physents[0].model = cl.worldmodel;
VectorClear (pmove.physents[0].origin); VectorClear (pmove.physents[0].origin);
pmove.physents[0].info = 0; pmove.physents[0].info = 0;
@ -3122,6 +3123,7 @@ void CL_SetSolidEntities (void)
if ( cl.model_precache[state->modelindex]->hulls[1].firstclipnode if ( cl.model_precache[state->modelindex]->hulls[1].firstclipnode
|| cl.model_precache[state->modelindex]->clipbox ) || 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]; pmove.physents[pmove.numphysent].model = cl.model_precache[state->modelindex];
VectorCopy (state->origin, pmove.physents[pmove.numphysent].origin); VectorCopy (state->origin, pmove.physents[pmove.numphysent].origin);
VectorCopy (state->angles, pmove.physents[pmove.numphysent].angles); VectorCopy (state->angles, pmove.physents[pmove.numphysent].angles);
@ -3271,9 +3273,8 @@ void CL_SetSolidPlayers (int playernum)
if (pplayer->flags & PF_DEAD) if (pplayer->flags & PF_DEAD)
continue; // dead players aren't solid continue; // dead players aren't solid
pent->model = 0; memset(pent, 0, sizeof(physent_t));
VectorCopy(pplayer->origin, pent->origin); 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_mins, pent->mins);
VectorCopy(player_maxs, pent->maxs); VectorCopy(player_maxs, pent->maxs);
if (++pmove.numphysent == MAX_PHYSENTS) //we just hit 88 miles per hour. 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)) if (!(flags & DLLF_OVERWRITE) && CL_CheckFile(localname))
return true; return true;
#ifndef CLIENTONLY
if (sv.state)
return true;
#endif
//ZOID - can't download when recording //ZOID - can't download when recording
if (cls.demorecording) if (cls.demorecording)
{ {
@ -738,7 +743,7 @@ void Model_NextDownload (void)
int i; int i;
// extern char gamedirfile[]; // extern char gamedirfile[];
Con_TPrintf (TLC_CHECKINGMODELS); // Con_TPrintf (TLC_CHECKINGMODELS);
/* if (cls.downloadnumber == 0) /* if (cls.downloadnumber == 0)
{ {
@ -905,12 +910,15 @@ int CL_LoadModels(int stage)
{ {
if (!cl.model_name[1][0]) if (!cl.model_name[1][0])
Host_EndGame("Worldmodel name wasn't sent\n"); Host_EndGame("Worldmodel name wasn't sent\n");
else // else
Host_EndGame("Worldmodel wasn't loaded\n"); // 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; cl.hexen2pickups = cl.worldmodel->hulls[MAX_MAP_HULLSDH2-1].available;
else
cl.hexen2pickups = false;
R_CheckSky(); R_CheckSky();
@ -952,8 +960,8 @@ int CL_LoadModels(int stage)
if (atstage()) if (atstage())
{ {
loadmodel = cl.worldmodel; loadmodel = cl.worldmodel;
if (!loadmodel || loadmodel->type == mod_dummy) // if (!loadmodel || loadmodel->type == mod_dummy)
Host_EndGame("No worldmodel was loaded\n"); // Host_EndGame("No worldmodel was loaded\n");
Mod_NowLoadExternal(); Mod_NowLoadExternal();
endstage(); endstage();
@ -964,8 +972,9 @@ int CL_LoadModels(int stage)
if (atstage()) if (atstage())
{ {
loadmodel = cl.worldmodel; loadmodel = cl.worldmodel;
if (!loadmodel || loadmodel->type == mod_dummy) // if (!loadmodel || loadmodel->type == mod_dummy)
Host_EndGame("No worldmodel was loaded\n"); // Host_EndGame("No worldmodel was loaded\n");
cl.model_precaches_added = false;
R_NewMap (); R_NewMap ();
pmove.physents[0].model = cl.worldmodel; pmove.physents[0].model = cl.worldmodel;
@ -1015,7 +1024,7 @@ void Sound_NextDownload (void)
int i; int i;
Con_TPrintf (TLC_CHECKINGSOUNDS); // Con_TPrintf (TLC_CHECKINGSOUNDS);
#ifdef CSQC_DAT #ifdef CSQC_DAT
if (cls.fteprotocolextensions & PEXT_CSQC) if (cls.fteprotocolextensions & PEXT_CSQC)
@ -1955,6 +1964,7 @@ void CL_ParseServerData (void)
if (protover == PROTOCOL_VERSION_FTE) if (protover == PROTOCOL_VERSION_FTE)
{ {
cls.fteprotocolextensions = MSG_ReadLong(); cls.fteprotocolextensions = MSG_ReadLong();
if (developer.value || cl_shownet.value)
Con_TPrintf (TL_FTEEXTENSIONS, cls.fteprotocolextensions); Con_TPrintf (TL_FTEEXTENSIONS, cls.fteprotocolextensions);
continue; continue;
} }
@ -2361,9 +2371,18 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
//fill in the csqc stuff //fill in the csqc stuff
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, "*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, "*csprogssize", va("%i", cl_dp_csqc_progssize), sizeof(cl.serverinfo));
Info_SetValueForStarKey(cl.serverinfo, "*csprogsname", va("%i", cl_dp_csqc_progsname), sizeof(cl.serverinfo)); Info_SetValueForStarKey(cl.serverinfo, "*csprogsname", va("%i", cl_dp_csqc_progsname), sizeof(cl.serverinfo));
}
//update gamemode //update gamemode
if (gametype == 1) if (gametype == 1)
@ -2873,7 +2892,7 @@ qboolean CL_CheckBaselines (int size)
return false; return false;
size = (size + 64) & ~63; // round up to next 64 size = (size + 64) & ~63; // round up to next 64
if (size < cl_baselines_count) if (size <= cl_baselines_count)
return true; return true;
cl_baselines = BZ_Realloc(cl_baselines, sizeof(*cl_baselines)*size); 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); Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
cl.model_precache[i] = model; cl.model_precache[i] = model;
strcpy (cl.model_name[i], s); strcpy (cl.model_name[i], s);
cl.model_precaches_added = true;
} }
else else
Con_Printf("svc_precache: model index %i outside range %i...%i\n", i, 1, MAX_MODELS); 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); cl_dp_csqc_progssize = atoi(s+14);
else if (!strncmp(s, "csqc_progcrc ", 13)) else if (!strncmp(s, "csqc_progcrc ", 13))
cl_dp_csqc_progscrc = atoi(s+13); cl_dp_csqc_progscrc = atoi(s+13);
else if (!strncmp(s, "cl_fullpitch ", 13) || !strncmp(s, "pq_fullpitch ", 13))
{
//
}
else else
{ {
Cbuf_AddText (s, RESTRICT_SERVER); //no cheating here... Cbuf_AddText (s, RESTRICT_SERVER); //no cheating here...
@ -5435,7 +5460,11 @@ void CLNQ_ParseServerMessage (void)
if (i >= MAX_CLIENTS) if (i >= MAX_CLIENTS)
MSG_ReadString(); MSG_ReadString();
else else
{
strcpy(cl.players[i].name, MSG_ReadString()); strcpy(cl.players[i].name, MSG_ReadString());
if (*cl.players[i].name)
cl.players[i].userid = i+1;
}
break; break;
case svc_updatefrags: case svc_updatefrags:
@ -5449,22 +5478,22 @@ void CLNQ_ParseServerMessage (void)
case svc_updatecolors: case svc_updatecolors:
{ {
int a; int a;
Sbar_Changed ();
i = MSG_ReadByte (); i = MSG_ReadByte ();
a = MSG_ReadByte (); a = MSG_ReadByte ();
if (i >= MAX_CLIENTS) if (i < MAX_CLIENTS)
break; {
//FIXME:!!!!
cl.players[i].rtopcolor = a&0x0f; cl.players[i].rtopcolor = a&0x0f;
cl.players[i].rbottomcolor = (a&0xf0)>>4; cl.players[i].rbottomcolor = (a&0xf0)>>4;
sprintf(cl.players[i].team, "%2d", cl.players[i].rbottomcolor);
if (cls.state == ca_active) if (cls.state == ca_active)
Skin_Find (&cl.players[i]); Skin_Find (&cl.players[i]);
Sbar_Changed (); Sbar_Changed ();
CL_NewTranslation (i); CL_NewTranslation (i);
} }
}
break; break;
case svc_lightstyle: case svc_lightstyle:
i = MSG_ReadByte (); i = MSG_ReadByte ();

View File

@ -817,6 +817,19 @@ void CL_PredictMovePNum (int pnum)
} }
*/ } */ }
#endif #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)) if (((cl_nopred.value && cls.demoplayback!=DPB_MVD && cls.demoplayback != DPB_EZTV)|| cl.fixangle))
{ {
fixedorg: fixedorg:

View File

@ -1053,6 +1053,8 @@ void SCR_CalcRefdef (void)
r_refdef.fov_x = 10; r_refdef.fov_x = 10;
else if (r_refdef.fov_x > 170) else if (r_refdef.fov_x > 170)
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); 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 framechange; //marks time of last frame change - for halflife model sequencing.
float oldframechange; float oldframechange;
float lerprate; //inverse rate... float lerprate; //inverse rate...
vec3_t origin; vec3_t origin; //current render position
vec3_t angles; 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 *trailstate; //when to next throw out a trail
trailstate_t *emitstate; //when to next emit trailstate_t *emitstate; //when to next emit
unsigned short frame; unsigned short frame, oldframe;
} lerpents_t; } lerpents_t;
// //
// the client_state_t structure is wiped completely at every // the client_state_t structure is wiped completely at every
@ -539,6 +543,8 @@ typedef struct
char model_csqcname[MAX_CSQCMODELS][MAX_QPATH]; char model_csqcname[MAX_CSQCMODELS][MAX_QPATH];
struct model_s *model_csqcprecache[MAX_CSQCMODELS]; struct model_s *model_csqcprecache[MAX_CSQCMODELS];
qboolean model_precaches_added;
//used for q2 sky/configstrings //used for q2 sky/configstrings
char skyname[MAX_QPATH]; char skyname[MAX_QPATH];
float skyrotate; 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_AllocDlight (int key);
dlight_t *CL_NewDlight (int key, float x, float y, float z, float radius, float time, int type); 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_DecayLights (void);
void CL_ParseDelta (struct entity_state_s *from, struct entity_state_s *to, int bits, qboolean); 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) if (!cl.worldmodel)
Host_EndGame("CGame didn't set a map.\n"); Host_EndGame("CGame didn't set a map.\n");
cl.model_precaches_added = false;
R_NewMap (); R_NewMap ();
SCR_EndLoadingPlaque(); SCR_EndLoadingPlaque();
@ -943,7 +944,8 @@ void CLQ3_SendCmd(usercmd_t *cmd)
// begin a client move command, if any // begin a client move command, if any
if( cmdcount ) if( cmdcount )
{ {
if(!ccs.snap.valid || extern cvar_t cl_nodelta;
if(cl_nodelta.value || !ccs.snap.valid ||
ccs.snap.serverMessageNum != ccs.serverMessageNum) ccs.snap.serverMessageNum != ccs.serverMessageNum)
MSG_WriteBits(&msg, clcq3_nodeltaMove, 8); // no compression MSG_WriteBits(&msg, clcq3_nodeltaMove, 8); // no compression
else else

View File

@ -1319,8 +1319,6 @@ void MasterInfo_Begin(void)
Master_AddMaster("qwmaster.ocrana.de:27000", MT_MASTERQW, "Ocrana2 master server."); 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("213.221.174.165:27000", MT_MASTERQW, "unknown1 master server.");
Master_AddMaster("195.74.0.8", MT_MASTERQW, "unknown2 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("204.182.161.2", MT_MASTERQW, "unknown5 master server.");
Master_AddMaster("255.255.255.255:27500", MT_BCASTQW, "Nearby QuakeWorld UDP servers."); 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 #endif
if (!active_particles) if (!active_particles)
{
RQ_RenderDistAndClear();
return; return;
}
switch(qrenderer) switch(qrenderer)
{ {
@ -229,6 +232,7 @@ static void PClassic_DrawParticles(void)
break; break;
#endif #endif
default: default:
RQ_RenderDistAndClear();
return; 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(); RSpeedRemark();
RQ_RenderDistAndClear(); RQ_RenderDistAndClear();
RSpeedEnd(RSPEED_PARTICLESDRAW); RSpeedEnd(RSPEED_PARTICLESDRAW);
#endif
} }
//called to set up the rendering state (opengl) //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 skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1; int boneidx = G_FLOAT(OFS_PARM1)-1;
float *matrix[4];
float temp[3][4]; float temp[3][4];
float mult[3][4]; float mult[3][4];
skelobject_t *skelobj; 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++) for (i=0 ; i< pmove.numphysent ; i++)
{ {
pe = &pmove.physents[i]; pe = &pmove.physents[i];
if (pe->nonsolid)
continue;
if (pe->model) if (pe->model)
{ {
VectorSubtract(start, pe->origin, ts); 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 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_SetFrustum (void);
void R_SetRenderer(int wanted); void R_SetRenderer(int wanted);
void RQ_Init(void); 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_t vid_conautoscale = SCVARF ("vid_conautoscale", "0",
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK); CVAR_ARCHIVE | CVAR_RENDERERCALLBACK);
cvar_t vid_conheight = SCVARF ("vid_conheight", "480", cvar_t vid_conheight = SCVARF ("vid_conheight", "0",
CVAR_ARCHIVE); CVAR_ARCHIVE);
cvar_t vid_conwidth = SCVARF ("vid_conwidth", "640", cvar_t vid_conwidth = SCVARF ("vid_conwidth", "0",
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK); CVAR_ARCHIVE | CVAR_RENDERERCALLBACK);
//see R_RestartRenderer_f for the effective default 'if (newr.renderer == -1)'. //see R_RestartRenderer_f for the effective default 'if (newr.renderer == -1)'.
cvar_t vid_renderer = SCVARF ("vid_renderer", "", cvar_t vid_renderer = SCVARF ("vid_renderer", "",
@ -2407,17 +2407,12 @@ mleaf_t *r_vischain; // linked list of visible leafs
R_MarkLeaves R_MarkLeaves
=============== ===============
*/ */
void R_MarkLeaves (void)
{
qbyte fatvis[MAX_MAP_LEAFS/8];
qbyte *vis;
mnode_t *node;
int i;
qbyte solid[4096];
#ifdef Q3BSPS #ifdef Q3BSPS
if (cl.worldmodel->fromgame == fg_quake3) void R_MarkLeaves_Q3 (void)
{ {
qbyte *vis;
int i;
int cluster; int cluster;
mleaf_t *leaf; mleaf_t *leaf;
@ -2438,7 +2433,8 @@ void R_MarkLeaves (void)
// mark everything // mark everything
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++) for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{ {
if ( !leaf->nummarksurfaces ) { if (!leaf->nummarksurfaces)
{
continue; continue;
} }
@ -2446,32 +2442,40 @@ void R_MarkLeaves (void)
leaf->vischain = r_vischain; leaf->vischain = r_vischain;
r_vischain = leaf; r_vischain = leaf;
} }
return;
} }
else
{
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel); vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel);
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++) for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{ {
cluster = leaf->cluster; cluster = leaf->cluster;
if ( cluster == -1 || !leaf->nummarksurfaces ) { if (cluster == -1 || !leaf->nummarksurfaces)
{
continue; continue;
} }
if ( vis[cluster>>3] & (1<<(cluster&7)) ) { if (vis[cluster>>3] & (1<<(cluster&7)))
{
leaf->visframe = r_visframecount; leaf->visframe = r_visframecount;
leaf->vischain = r_vischain; leaf->vischain = r_vischain;
r_vischain = leaf; r_vischain = leaf;
} }
} }
return; }
} }
#endif #endif
#ifdef Q2BSPS #ifdef Q2BSPS
if (cl.worldmodel->fromgame == fg_quake2) void R_MarkLeaves_Q2 (void)
{ {
int c; qbyte fatvis[MAX_MAP_LEAFS/8];
mleaf_t *leaf; qbyte *vis;
mnode_t *node;
int i;
int cluster; int cluster;
mleaf_t *leaf;
int c;
if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2) if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2)
return; return;
@ -2525,6 +2529,14 @@ void R_MarkLeaves (void)
} }
#endif #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) if (((r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2) && !r_novis.value) || r_novis.value == 2)
return; return;
@ -2541,7 +2553,7 @@ void R_MarkLeaves (void)
vis = solid; vis = solid;
memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3); memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
} }
else if (r_viewleaf2) else if (r_viewleaf2 && r_viewleaf2 != r_viewleaf)
{ {
int c; int c;
Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis); Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis);
@ -2572,7 +2584,6 @@ void R_MarkLeaves (void)
} }
mplane_t frustum[4]; mplane_t frustum[4];

View File

@ -280,9 +280,13 @@ qbyte *Skin_Cache8 (skin_t *skin)
raw = COM_LoadTempFile (name); raw = COM_LoadTempFile (name);
if (!raw) if (!raw)
{ {
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); Con_Printf ("Couldn't load skin %s\n", name);
sprintf (name, "skins/%s.pcx", baseskin.string); sprintf (name, "skins/%s.pcx", baseskin.string);
raw = COM_LoadTempFile (name); raw = COM_LoadTempFile (name);
}
if (!raw) if (!raw)
{ {
skin->failedload = true; skin->failedload = true;
@ -519,7 +523,7 @@ void Skin_NextDownload (void)
player_info_t *sc; player_info_t *sc;
int i; int i;
Con_Printf ("Checking skins...\n"); //Con_Printf ("Checking skins...\n");
for (i = 0; i != MAX_CLIENTS; i++) 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; 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; static HINSTANCE game_library;

View File

@ -444,7 +444,11 @@ void Validation_DelatchRulesets(void)
Con_DPrintf("Ruleset deactivated\n"); 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 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 //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; 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()) else if (!strncmp(s, "f_ruleset", 9) && rulesetresponsetime < Sys_DoubleTime())
{ {
Validation_Ruleset(); if (1)
Validation_AllChecks();
else
Validation_OldRuleset();
rulesetresponsetime = Sys_DoubleTime() + 5; 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_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) 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; *offset = (name - s) + 2;
flags = TPM_FAKED; 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 newstatusbuf[sizeof(vars.autoteamstatus)];
char *newstatus; char *newstatus;
if (vars.autoteamstatus_time < realtime) if (vars.autoteamstatus_time > realtime)
return; return;
vars.autoteamstatus_time = realtime + 3;
newstatus = Cmd_ExpandString(tp_autostatus.string, newstatusbuf, sizeof(newstatusbuf), tp_autostatus.restriction, true, true); newstatus = Cmd_ExpandString(tp_autostatus.string, newstatusbuf, sizeof(newstatusbuf), tp_autostatus.restriction, true, true);
newstatus = TP_ParseMacroString(newstatus); newstatus = TP_ParseMacroString(newstatus);
@ -3051,7 +3055,6 @@ void TP_UpdateAutoStatus(void)
//the tp code will reexpand it as part of the say team //the tp code will reexpand it as part of the say team
Cbuf_AddText(va("say_team $\\%s\n", tp_autostatus.string), RESTRICT_LOCAL); Cbuf_AddText(va("say_team $\\%s\n", tp_autostatus.string), RESTRICT_LOCAL);
vars.autoteamstatus_time = realtime + 3;
} }
void TP_StatChanged (int stat, int value) 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 Q2CLIENT //client can connect to q2 servers
#define Q3CLIENT #define Q3CLIENT
#define Q3SERVER #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 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 FISH //sw rendering only
#define ZLIB //zip/pk3 support #define ZLIB //zip/pk3 support

View File

@ -71,6 +71,10 @@ typedef struct cvar_s
char *defaultstr; //default char *defaultstr; //default
qbyte restriction; qbyte restriction;
#ifdef HLSERVER
struct hlcvar_s *hlcvar;
#endif
} cvar_t; } cvar_t;
#define FCVARC(ConsoleName,ConsoleName2,Value,Flags,Callback) {ConsoleName, Value, NULL, Flags, 0, 0, 0, ConsoleName2, Callback} #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]; char diskname[MAX_OSPATH];
if (Sys_PathProtection(loc->rawname))
return NULL;
snprintf(diskname, sizeof(diskname), "%s/%s", (char*)handle, loc->rawname); snprintf(diskname, sizeof(diskname), "%s/%s", (char*)handle, loc->rawname);
return VFSOS_Open(diskname, mode); return VFSOS_Open(diskname, mode);
@ -455,7 +459,7 @@ qboolean FSPAK_FLocate(void *handle, flocation_t *loc, char *filename, void *has
if (loc) if (loc)
{ {
loc->index = pf - pak->files; 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->offset = pf->filepos;
loc->len = pf->filelen; loc->len = pf->filelen;
} }
@ -1392,7 +1396,8 @@ int COM_filelength (FILE *f)
return end; return end;
} }
int COM_FileOpenRead (char *path, FILE **hndl) /*
static int COM_FileOpenRead (char *path, FILE **hndl)
{ {
FILE *f; FILE *f;
@ -1406,6 +1411,7 @@ int COM_FileOpenRead (char *path, FILE **hndl)
return COM_filelength(f); return COM_filelength(f);
} }
*/
int COM_FileSize(char *path) 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. 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; FILE *in, *out;
int remaining, count; int remaining, count;
@ -1601,6 +1608,7 @@ void COM_CopyFile (char *netpath, char *cachepath)
fclose (in); fclose (in);
fclose (out); fclose (out);
} }
//*/
int fs_hash_dups; int fs_hash_dups;
int fs_hash_files; int fs_hash_files;
@ -1681,6 +1689,12 @@ int FS_FLocateFile(char *filename, FSLF_ReturnType_e returntype, flocation_t *lo
void *pf; void *pf;
//Con_Printf("Finding %s: ", filename); //Con_Printf("Finding %s: ", filename);
if (Sys_PathProtection(filename))
{
pf = NULL;
goto fail;
}
if (com_fs_cache.value) if (com_fs_cache.value)
{ {
if (com_fschanged) if (com_fschanged)
@ -1896,22 +1910,39 @@ int COM_FOpenWriteFile(char *filename, FILE **file)
//true if protection kicks in //true if protection kicks in
qboolean Sys_PathProtection(char *pattern) qboolean Sys_PathProtection(char *pattern)
{ {
char *s;
if (strchr(pattern, '\\')) if (strchr(pattern, '\\'))
{ {
char *s;
Con_Printf("Warning: \\ characters in filename %s\n", pattern); Con_Printf("Warning: \\ characters in filename %s\n", pattern);
while((s = strchr(pattern, '\\'))) while((s = strchr(pattern, '\\')))
*s = '/'; *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, "..")) if (strstr(pattern, ".."))
Con_Printf("Error: '..' characters in filename %s\n", pattern); Con_Printf("Error: '..' characters in filename %s\n", pattern);
else if (pattern[0] == '/') else if (pattern[0] == '/')
Con_Printf("Error: absolute path in filename %s\n", pattern); 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); Con_Printf("Error: absolute path in filename %s\n", pattern);
else else
{
return false; return false;
}
return true; 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) void COM_EnumerateFiles (char *match, int (*func)(char *, int, void *), void *parm)
{ {
searchpath_t *search; searchpath_t *search;
@ -2924,6 +2967,8 @@ gamemode_info_t gamemode_info[] = {
{"FTE-JK2", "jk2", "-jk2", "base/assets0.pk3", NULL, "base", "fte"}, {"FTE-JK2", "jk2", "-jk2", "base/assets0.pk3", NULL, "base", "fte"},
{"FTE-HalfLife", "hl", "-hl", "valve/liblist.gam",NULL, "valve", "fte"},
{NULL} {NULL}
}; };
@ -3117,6 +3162,125 @@ void FS_ReloadPackFiles_f(void)
FS_ReloadPackFilesFlags((unsigned int)-1); 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 COM_InitFilesystem
@ -3181,9 +3345,40 @@ void COM_InitFilesystem (void)
for (i = 0; gamemode_info[i].gamename; i++) for (i = 0; gamemode_info[i].gamename; i++)
{ {
if (COM_CheckParm(gamemode_info[i].argname)) if (COM_CheckParm(gamemode_info[i].argname))
{
gamenum = i; 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) if (gamenum<0)
{ {
for (i = 0; gamemode_info[i].gamename; i++) for (i = 0; gamemode_info[i].gamename; i++)
@ -3192,6 +3387,7 @@ void COM_InitFilesystem (void)
gamenum = i; gamenum = i;
} }
} }
Cvar_Set(&com_gamename, gamemode_info[gamenum].gamename); Cvar_Set(&com_gamename, gamemode_info[gamenum].gamename);
if (gamemode_info[gamenum].customexec) if (gamemode_info[gamenum].customexec)

View File

@ -3778,7 +3778,7 @@ void SWR_Q2BSP_StainNode (mnode_t *node, float *parms)
#ifndef CLIENTONLY #ifndef CLIENTONLY
void Q2BSP_FatPVS (model_t *mod, vec3_t org, qboolean add); void Q2BSP_FatPVS (model_t *mod, vec3_t org, qboolean add);
qboolean Q2BSP_EdictInFatPVS(model_t *mod, edict_t *ent); 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 #endif
void GLQ2BSP_LightPointValues(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); 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); 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); 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) void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
{ {
float angle; float angle;

View File

@ -45,9 +45,9 @@ extern int nanmask;
#define IS_NAN(x) (((*(int *)&x)&nanmask)==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 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 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) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];} #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) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];} #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 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 VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2])
#define VectorLength(a) Length(a) #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); void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs);
float anglemod (float a); float anglemod (float a);
void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); 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); void VARGS BOPS_Error (void);
int VARGS BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane); int VARGS BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
void ClearBounds (vec3_t mins, vec3_t maxs); void ClearBounds (vec3_t mins, vec3_t maxs);

View File

@ -123,6 +123,8 @@ int PM_SlideMove (void)
time_left = frametime; time_left = frametime;
// VectorAdd(pmove.velocity, pmove.basevelocity, pmove.velocity);
for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++) for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++)
{ {
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
@ -540,7 +542,7 @@ void PM_WaterMove (void)
/* /*
*/ */
void PM_FlyMove () void PM_FlyMove (void)
{ {
int i; int i;
vec3_t wishvel; vec3_t wishvel;
@ -580,11 +582,11 @@ void PM_LadderMove (void)
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
wishvel[i] = forward[i]*pmove.cmd.forwardmove + right[i]*pmove.cmd.sidemove + up[i]*pmove.cmd.upmove; 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; wishvel[2]*=10;
if (pmove.cmd.buttons & 2) if (pmove.cmd.buttons & 2)
wishvel[2]+=100; wishvel[2]+=movevars.maxspeed;
VectorCopy (wishvel, wishdir); VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize(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? //are we on a ladder?
#ifdef Q2BSPS #ifdef Q2BSPS
if (pmove.physents[0].model->fromgame == fg_quake3) if (pmove.physents[0].model->fromgame == fg_quake3)
@ -808,6 +815,14 @@ void PM_CategorizePosition (void)
} }
#endif #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) 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 // 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 unsigned short info; // for client or server to identify
qbyte nonsolid; qbyte nonsolid;
qbyte notouch; qbyte notouch;
unsigned int forcecontentsmask;
} physent_t; } physent_t;
typedef struct typedef struct
@ -51,6 +52,7 @@ typedef struct
vec3_t origin; vec3_t origin;
vec3_t angles; vec3_t angles;
vec3_t velocity; vec3_t velocity;
vec3_t basevelocity;
qboolean jump_held; qboolean jump_held;
int jump_msec; // msec since last jump int jump_msec; // msec since last jump
float waterjumptime; float waterjumptime;

View File

@ -129,8 +129,63 @@ int PM_PointContents (vec3_t p)
pe = &pmove.physents[num]; pe = &pmove.physents[num];
pm = pe->model; pm = pe->model;
if (pm) if (pm)
{
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); 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; 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 // 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); result = model->funcs.Trace(model, 0, 0, start_l, end_l, player_mins, player_maxs, trace);
else else
{ {
@ -242,6 +297,9 @@ qboolean PM_TestPlayerPosition (vec3_t pos)
{ {
pe = &pmove.physents[i]; pe = &pmove.physents[i];
if (pe->nonsolid)
continue;
// get the clipping hull // get the clipping hull
if (pe->model) if (pe->model)
{ {
@ -299,6 +357,9 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end)
{ {
pe = &pmove.physents[i]; pe = &pmove.physents[i];
if (pe->nonsolid)
continue;
if (!pe->model) if (!pe->model)
{ {
vec3_t mins, maxs; 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. 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; mplane_t *splitplane;
mleaf_t *leaf; mleaf_t *leaf;
@ -965,20 +965,20 @@ void Q1BSP_RFindTouchedLeafs (edict_t *ent, mnode_t *node)
// NODE_MIXED // NODE_MIXED
splitplane = node->plane; splitplane = node->plane;
sides = BOX_ON_PLANE_SIDE(ent->v->absmin, ent->v->absmax, splitplane); sides = BOX_ON_PLANE_SIDE(mins, maxs, splitplane);
// recurse down the contacted sides // recurse down the contacted sides
if (sides & 1) if (sides & 1)
Q1BSP_RFindTouchedLeafs (ent, node->children[0]); Q1BSP_RFindTouchedLeafs (ent, node->children[0], mins, maxs);
if (sides & 2) 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; ent->num_leafs = 0;
if (ent->v->modelindex) if (ent->v->modelindex)
Q1BSP_RFindTouchedLeafs (ent, mod->nodes); Q1BSP_RFindTouchedLeafs (ent, mod->nodes, mins, maxs);
} }
#endif #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); 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 #if defined(__MORPHOS__) && I_AM_BIGFOOT
#include <proto/dynload.h> #include <proto/dynload.h>
#else
#include <dlfcn.h>
#endif #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, ... )); void (*dllEntry)(int (EXPORT_FN *syscall)(int arg, ... ));
char dllname[MAX_OSPATH]; 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 defined(__MORPHOS__) && I_AM_BIGFOOT
if (DynLoadBase == 0) if (DynLoadBase == 0)
return 0; return 0;
#endif #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 return 0; //give up early, don't even try going there
sprintf(dllname, "%samd.so", name); sprintf(dllname, "%samd.so", name);
#elif defined(_M_IX86) || defined(__i386__) #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); gpath = COM_NextPath (gpath);
if (!gpath) if (!gpath)
return NULL; // couldn't find one anywhere 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); Con_Printf("Loading native: %s\n", name);
hVM = dlopen (name, RTLD_NOW); hVM = Sys_LoadLibrary(name, funcs);
if (hVM) if (hVM)
{ {
Con_DPrintf ("Sys_LoadDLL: dlopen (%s)\n",name);
break; break;
} }
else
{
Con_DPrintf("Sys_LoadDLL: dlerror()=\"%s\"", dlerror());
}
} }
} }
if(!hVM) return NULL; 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); (*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; return hVM;
} }
/* /*
** Sys_UnloadDLL ** Sys_UnloadDLL
*/ */
void Sys_UnloadDLL(void *handle) void QVM_UnloadDLL(dllhandle_t *handle)
{ {
if(handle) if(handle)
{ {
if(dlclose(handle)) Sys_CloseLibrary(handle);
Sys_Error("Sys_UnloadDLL FreeLibrary failed");
} }
} }
#endif
@ -292,9 +210,9 @@ typedef struct qvm_s
sys_callqvm_t syscall; sys_callqvm_t syscall;
} qvm_t; } qvm_t;
qvm_t *QVM_Load(const char *name, sys_callqvm_t syscall); qvm_t *QVM_LoadVM(const char *name, sys_callqvm_t syscall);
void QVM_UnLoad(qvm_t *qvm); void QVM_UnLoadVM(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); 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 * ------------------------- // ------------------------- * OP.CODES * -------------------------
@ -397,7 +315,7 @@ typedef enum qvm_op_e
/* /*
** QVM_Load ** 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]; char path[MAX_QPATH];
vmHeader_t *header; vmHeader_t *header;
@ -547,7 +465,7 @@ qvm_t *QVM_Load(const char *name, sys_callqvm_t syscall)
/* /*
** QVM_UnLoad ** QVM_UnLoad
*/ */
void QVM_UnLoad(qvm_t *qvm) void QVM_UnLoadVM(qvm_t *qvm)
{ {
Z_Free(qvm->mem_ptr); Z_Free(qvm->mem_ptr);
Z_Free(qvm); Z_Free(qvm);
@ -648,7 +566,7 @@ static void inline QVM_Return(qvm_t *vm, int size)
/* /*
** VM_Exec ** 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. //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 (!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); Con_DPrintf("Creating native machine \"%s\"\n", name);
vm->type=VM_NATIVE; 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 (syscallqvm)
{ {
if((vm->hInst=QVM_Load(name, syscallqvm))) if((vm->hInst=QVM_LoadVM(name, syscallqvm)))
{ {
Con_DPrintf("Creating virtual machine \"%s\"\n", name); Con_DPrintf("Creating virtual machine \"%s\"\n", name);
vm->type=VM_BYTECODE; vm->type=VM_BYTECODE;
@ -1060,11 +978,11 @@ void VM_Destroy(vm_t *vm)
switch(vm->type) switch(vm->type)
{ {
case VM_NATIVE: case VM_NATIVE:
if(vm->hInst) Sys_UnloadDLL(vm->hInst); if(vm->hInst) QVM_UnloadDLL(vm->hInst);
break; break;
case VM_BYTECODE: case VM_BYTECODE:
if(vm->hInst) QVM_UnLoad(vm->hInst); if(vm->hInst) QVM_UnLoadVM(vm->hInst);
break; break;
case VM_NONE: case VM_NONE:
@ -1094,11 +1012,11 @@ qboolean VM_Restart(vm_t *vm)
switch(vm->type) switch(vm->type)
{ {
case VM_NATIVE: case VM_NATIVE:
if(vm->hInst) Sys_UnloadDLL(vm->hInst); if(vm->hInst) QVM_UnloadDLL(vm->hInst);
break; break;
case VM_BYTECODE: case VM_BYTECODE:
if(vm->hInst) QVM_UnLoad(vm->hInst); if(vm->hInst) QVM_UnLoadVM(vm->hInst);
break; break;
case VM_NONE: 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); return vm->vmMain(instruction, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
case VM_BYTECODE: 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: case VM_NONE:
return 0; return 0;

View File

@ -37,6 +37,8 @@ int Sys_FileTime (char *path);
void Sys_mkdir (char *path); void Sys_mkdir (char *path);
qboolean Sys_remove (char *path); qboolean Sys_remove (char *path);
qboolean Sys_FindGameData(char *gamename, char *basepath, int basepathlen);
// //
// memory protection // memory protection
// //
@ -62,6 +64,8 @@ typedef struct {
typedef void *dllhandle_t; typedef void *dllhandle_t;
dllhandle_t *Sys_LoadLibrary(char *name, dllfunction_t *funcs); dllhandle_t *Sys_LoadLibrary(char *name, dllfunction_t *funcs);
void Sys_CloseLibrary(dllhandle_t *lib); 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); unsigned int Sys_Milliseconds (void);
double Sys_DoubleTime (void); double Sys_DoubleTime (void);

View File

@ -66,7 +66,7 @@ typedef struct trace_s
cplane_t plane; // surface normal at impact cplane_t plane; // surface normal at impact
q2csurface_t *surface; // surface hit q2csurface_t *surface; // surface hit
int contents; // contents on other side of 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 //AND THIS LINE
int entnum; int entnum;

View File

@ -915,16 +915,23 @@ void D3D7_DrawWorld(void)
#ifdef Q3BSPS #ifdef Q3BSPS
if (ent.model->fromgame == fg_quake3) if (ent.model->fromgame == fg_quake3)
{ {
R_MarkLeaves_Q3 ();
D3D7_LeafWorldNode (); D3D7_LeafWorldNode ();
} }
else else
#endif #endif
{
R_MarkLeaves_Q2 ();
D3D7_RecursiveQ2WorldNode (cl.worldmodel->nodes); D3D7_RecursiveQ2WorldNode (cl.worldmodel->nodes);
} }
}
else else
#endif #endif
*/ */
{
R_MarkLeaves_Q1 ();
D3D7_RecursiveWorldNode (cl.worldmodel->nodes); D3D7_RecursiveWorldNode (cl.worldmodel->nodes);
}
RSpeedEnd(RSPEED_WORLDNODE); RSpeedEnd(RSPEED_WORLDNODE);
TRACE(("dbg: calling PPL_DrawWorld\n")); TRACE(("dbg: calling PPL_DrawWorld\n"));
@ -947,7 +954,6 @@ void D3D7_R_RenderScene(void)
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) 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 D3D7_DrawWorld (); // adds static entities to the list
} }

View File

@ -1329,15 +1329,22 @@ void D3D9_DrawWorld(void)
#ifdef Q3BSPS #ifdef Q3BSPS
if (ent.model->fromgame == fg_quake3) if (ent.model->fromgame == fg_quake3)
{ {
R_MarkLeaves_Q3 ();
D3D9_LeafWorldNode (); D3D9_LeafWorldNode ();
} }
else else
#endif #endif
{
R_MarkLeaves_Q2 ();
D3D9_RecursiveQ2WorldNode (cl.worldmodel->nodes); D3D9_RecursiveQ2WorldNode (cl.worldmodel->nodes);
} }
}
else else
#endif #endif
{
R_MarkLeaves_Q1 ();
D3D9_RecursiveWorldNode (cl.worldmodel->nodes); D3D9_RecursiveWorldNode (cl.worldmodel->nodes);
}
RSpeedEnd(RSPEED_WORLDNODE); RSpeedEnd(RSPEED_WORLDNODE);
TRACE(("dbg: calling PPL_DrawWorld\n")); TRACE(("dbg: calling PPL_DrawWorld\n"));
@ -1360,7 +1367,6 @@ void D3D9_R_RenderScene(void)
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) 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 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; 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 #endif

View File

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

View File

@ -46,7 +46,7 @@ typedef struct {
void (*FatPVS) (struct model_s *model, vec3_t org, qboolean add); void (*FatPVS) (struct model_s *model, vec3_t org, qboolean add);
qboolean (*EdictInFatPVS) (struct model_s *model, struct edict_s *edict); 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 (*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); 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); 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); void Q1BSP_FatPVS (struct model_s *mod, vec3_t org, qboolean add);
qboolean Q1BSP_EdictInFatPVS(struct model_s *mod, struct edict_s *ent); 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); 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 ()) if (!GLR_DoomWorld ())
#endif #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")); TRACE(("dbg: calling R_DrawWorld\n"));
R_DrawWorld (); // adds static entities to the list 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 R_RecursiveWorldNode
@ -2890,6 +2964,7 @@ start:
node = node->children[!side]; node = node->children[!side];
goto start; goto start;
} }
#endif
#ifdef Q2BSPS #ifdef Q2BSPS
static void GLR_RecursiveQ2WorldNode (mnode_t *node) static void GLR_RecursiveQ2WorldNode (mnode_t *node)
@ -3118,15 +3193,26 @@ void R_DrawWorld (void)
#ifdef Q3BSPS #ifdef Q3BSPS
if (ent.model->fromgame == fg_quake3) if (ent.model->fromgame == fg_quake3)
{ {
R_MarkLeaves_Q3 ();
GLR_LeafWorldNode (); GLR_LeafWorldNode ();
} }
else else
#endif #endif
{
R_MarkLeaves_Q2 ();
GLR_RecursiveQ2WorldNode (cl.worldmodel->nodes); GLR_RecursiveQ2WorldNode (cl.worldmodel->nodes);
} }
}
else else
#endif #endif
{
#if 0
R_MarkLeafSurfaces_Q1();
#else
R_MarkLeaves_Q1 ();
GLR_RecursiveWorldNode (cl.worldmodel->nodes); GLR_RecursiveWorldNode (cl.worldmodel->nodes);
#endif
}
RSpeedEnd(RSPEED_WORLDNODE); RSpeedEnd(RSPEED_WORLDNODE);
TRACE(("dbg: calling PPL_DrawWorld\n")); TRACE(("dbg: calling PPL_DrawWorld\n"));

View File

@ -40,15 +40,58 @@ extern qboolean scr_drawloading;
extern int scr_chatmode; extern int scr_chatmode;
extern cvar_t scr_chatmodecvar; extern cvar_t scr_chatmodecvar;
extern cvar_t vid_conautoscale;
// console size manipulation callbacks // console size manipulation callbacks
void GLVID_Console_Resize(void) void GLVID_Console_Resize(void)
{ {
extern cvar_t vid_conwidth, vid_conheight; 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; xratio = vid_conautoscale.value;
vid.height = vid.conheight = vid_conheight.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; vid.recalc_refdef = true;
Con_CheckResize(); Con_CheckResize();
@ -65,7 +108,7 @@ void GLVID_Conheight_Callback(struct cvar_s *var, char *oldvalue)
Cvar_ForceSet(var, "1536"); Cvar_ForceSet(var, "1536");
return; return;
} }
if (var->value < 200) //lower would be wrong if (var->value < 200 && var->value) //lower would be wrong
{ {
Cvar_ForceSet(var, "200"); Cvar_ForceSet(var, "200");
return; return;
@ -82,7 +125,7 @@ void GLVID_Conwidth_Callback(struct cvar_s *var, char *oldvalue)
Cvar_ForceSet(var, "2048"); Cvar_ForceSet(var, "2048");
return; return;
} }
if (var->value < 320) //lower would be wrong if (var->value < 320 && var->value) //lower would be wrong
{ {
Cvar_ForceSet(var, "320"); Cvar_ForceSet(var, "320");
return; 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) void GLVID_Conautoscale_Callback(struct cvar_s *var, char *oldvalue)
{ {
extern cvar_t vid_conwidth, vid_conheight; GLVID_Console_Resize();
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);
}
} }
/* /*

View File

@ -45,16 +45,6 @@ cvar_t r_vertexlight = SCVAR("r_vertexlight", "0");
#define Com_sprintf snprintf #define Com_sprintf snprintf
#define clamp(v,min, max) (v) = (((v)<(min))?(min):(((v)>(max))?(max):(v))); #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 { typedef union {
float f; float f;
unsigned int i; unsigned int i;

View File

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

View File

@ -661,7 +661,7 @@ static int syscallqvm (void *offset, unsigned int mask, int fn, const int *arg)
case G_SOUND: case G_SOUND:
// ( int edn, int channel, char *samp, float vol, float att ) // ( 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; break;
case G_TRACELINE: case G_TRACELINE:
@ -1380,12 +1380,12 @@ void Q1QVM_ClientConnect(client_t *cl)
strcpy(cl->name, cl->namebuf); strcpy(cl->name, cl->namebuf);
} }
// call the spawn function // 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); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
VM_Call(q1qvm, GAME_CLIENT_CONNECT, cl->spectator); VM_Call(q1qvm, GAME_CLIENT_CONNECT, cl->spectator);
// actually spawn the player // 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); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
VM_Call(q1qvm, GAME_PUT_CLIENT_IN_SERVER, cl->spectator); 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 //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 //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 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 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 //this at least matches mvdsv
@ -1421,7 +1421,7 @@ qboolean Q1QVM_ClientSay(edict_t *player, qboolean team)
SV_EndRedirect(); SV_EndRedirect();
pr_global_struct->time = sv.time; pr_global_struct->time = sv.physicstime;
pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, player); pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, player);
washandled = VM_Call(q1qvm, GAME_CLIENT_SAY, team); washandled = VM_Call(q1qvm, GAME_CLIENT_SAY, team);
@ -1435,7 +1435,7 @@ qboolean Q1QVM_UserInfoChanged(edict_t *player)
if (!q1qvm) if (!q1qvm)
return false; return false;
pr_global_struct->time = sv.time; pr_global_struct->time = sv.physicstime;
pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, player); pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, player);
return VM_Call(q1qvm, GAME_CLIENT_USERINFO_CHANGED); 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 svmainprogs;
extern progsnum_t clmainprogs; extern progsnum_t clmainprogs;
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) #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 Q2EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,q2edict_t,area)
#define Q3EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,q3serverEntity_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'; kills[0] = '\0';
} }
else else
#endif
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
sprintf (kills,"kills:moo");
}
else
#endif #endif
sprintf (kills,"kills:%3i/%3i", (int)pr_global_struct->killed_monsters, (int)pr_global_struct->total_monsters); sprintf (kills,"kills:%3i/%3i", (int)pr_global_struct->killed_monsters, (int)pr_global_struct->total_monsters);
memcpy (text+22, kills, strlen(kills)); memcpy (text+22, kills, strlen(kills));
@ -404,8 +411,7 @@ void SV_Loadgame_f(void)
sv.time = time; sv.time = time;
pr_global_struct->time = sv.time; pr_global_struct->time = sv.physicstime;
pr_global_struct->time = sv.time;
fclose (f); fclose (f);
@ -663,7 +669,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
PR_LoadGlabalStruct(); PR_LoadGlabalStruct();
pr_global_struct->time = sv.time = time; pr_global_struct->time = sv.time = sv.physicstime = time;
sv.starttime = Sys_DoubleTime() - sv.time; sv.starttime = Sys_DoubleTime() - sv.time;
VFS_SEEK(f, modelpos); VFS_SEEK(f, modelpos);
@ -710,7 +716,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
if (spawnparamglobals[j]) if (spawnparamglobals[j])
*spawnparamglobals[j] = host_client->spawn_parms[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); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
ent->area.next = ent->area.prev = NULL; ent->area.next = ent->area.prev = NULL;
G_FLOAT(OFS_PARM0) = sv.time-host_client->spawninfotime; G_FLOAT(OFS_PARM0) = sv.time-host_client->spawninfotime;
@ -787,6 +793,14 @@ void SV_SaveLevelCache(qboolean dontharmgame)
} }
#endif #endif
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
SVHL_SaveLevelCache(name);
return;
}
#endif
f = fopen (name, "wb"); f = fopen (name, "wb");
if (!f) if (!f)
{ {

View File

@ -115,7 +115,7 @@ typedef struct
double time; double time;
double starttime; 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 framenum;
int lastcheck; // used by PF_checkclient int lastcheck; // used by PF_checkclient
@ -370,9 +370,13 @@ typedef struct client_s
int viewent; //fake the entity positioning. int viewent; //fake the entity positioning.
edict_t *edict; // EDICT_NUM(clientnum+1) edict_t *edict; // EDICT_NUM(clientnum+1)
//additional game modes use additional edict pointers. this ensures that references are crashes.
#ifdef Q2SERVER #ifdef Q2SERVER
q2edict_t *q2edict; // EDICT_NUM(clientnum+1) q2edict_t *q2edict; // EDICT_NUM(clientnum+1)
#endif #endif
#ifdef HLSERVER
struct hledict_s *hledict;
#endif
int playercolor; int playercolor;
int playerclass; int playerclass;
@ -691,6 +695,7 @@ typedef struct filteredip_s {
typedef enum { 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_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_Q1QVM,
GT_HALFLIFE,
GT_QUAKE2, //q2 servers run from a q2 game dll GT_QUAKE2, //q2 servers run from a q2 game dll
GT_QUAKE3, //q3 servers run off the q3 qvm api GT_QUAKE3, //q3 servers run off the q3 qvm api
GT_MAX GT_MAX
@ -1009,8 +1014,8 @@ void VARGS SV_Multicast (vec3_t origin, multicast_t to);
#define FULLDIMENSIONMASK 0xffffffff #define FULLDIMENSIONMASK 0xffffffff
void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int with, int without); 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, void SV_StartSound (int entnum, vec3_t origin, int seenmask, int channel, char *sample, int volume, float attenuation);
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 SV_PrintToClient(client_t *cl, int level, char *string);
void VARGS SV_ClientPrintf (client_t *cl, int level, char *fmt, ...); void VARGS SV_ClientPrintf (client_t *cl, int level, char *fmt, ...);
void VARGS SV_ClientTPrintf (client_t *cl, int level, translation_t text, ...); 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 en;
int currentsequence = client->netchan.outgoing_sequence; int currentsequence = client->netchan.outgoing_sequence;
unsigned short mask; unsigned short mask;
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT); globalvars_t *pr_globals;
edict_t *ent; edict_t *ent;
qboolean writtenheader = false; qboolean writtenheader = false;
//we don't check that we got some already - because this is delta compressed! //we don't check that we got some already - because this is delta compressed!
if (!(client->csqcactive)) if (!(client->csqcactive) || !svprogfuncs)
return; return;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
//FIXME: prioritise the list of csqc ents somehow //FIXME: prioritise the list of csqc ents somehow
csqcmsgbuffer.data = messagebuffer; csqcmsgbuffer.data = messagebuffer;
@ -700,7 +702,10 @@ void SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *
if (newnum < oldnum) if (newnum < oldnum)
{ // this is a new entity, send it from the baseline { // this is a new entity, send it from the baseline
if (svprogfuncs)
ent = EDICT_NUM(svprogfuncs, newnum); ent = EDICT_NUM(svprogfuncs, newnum);
else
ent = NULL;
//Con_Printf ("baseline %i\n", newnum); //Con_Printf ("baseline %i\n", newnum);
#ifdef PROTOCOLEXTENSIONS #ifdef PROTOCOLEXTENSIONS
SV_WriteDelta (&ent->baseline, &to->entities[newindex], msg, true, client->fteprotocolextensions); SV_WriteDelta (&ent->baseline, &to->entities[newindex], msg, true, client->fteprotocolextensions);
@ -2685,6 +2690,11 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
else else
{ {
clent = client->edict; clent = client->edict;
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
pvs = SVHL_Snapshot_SetupPVS(client);
else
#endif
pvs = SV_Snapshot_SetupPVS(client); pvs = SV_Snapshot_SetupPVS(client);
} }
@ -2693,6 +2703,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
SV_Snapshot_Clear(pack); SV_Snapshot_Clear(pack);
// send over the players in the PVS // send over the players in the PVS
if (svs.gametype != GT_HALFLIFE)
SV_WritePlayersToClient (client, clent, pvs, msg); SV_WritePlayersToClient (client, clent, pvs, msg);
// put other visible entities into either a packet_entities or a nails message // put other visible entities into either a packet_entities or a nails message
@ -2703,6 +2714,11 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
} }
else else
{ {
#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); SV_Snapshot_BuildQ1(client, pack, pvs, clent, ignorepvs);
} }

View File

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

View File

@ -487,6 +487,11 @@ void SV_DropClient (client_t *drop)
case GT_QUAKE3: case GT_QUAKE3:
#ifdef Q3SERVER #ifdef Q3SERVER
SVQ3_DropClient(drop); SVQ3_DropClient(drop);
#endif
break;
case GT_HALFLIFE:
#ifdef HLSERVER
SVHL_DropClient(drop);
#endif #endif
break; 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; edictnum = (newcl-svs.clients)+1;
switch (svs.gametype) 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 #ifdef VM_Q1
case GT_Q1QVM: case GT_Q1QVM:
#endif #endif
@ -1948,37 +1970,6 @@ client_t *SVC_DirectConnect(void)
#endif #endif
temp.edict = ent; 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; break;
#ifdef Q2SERVER #ifdef Q2SERVER
@ -1992,6 +1983,25 @@ client_t *SVC_DirectConnect(void)
ge->ClientUserinfoChanged(q2ent, temp.userinfo); 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 // build a new connection
// accept the new client // accept the new client
// this is the only place a client_t is ever initialized // 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); temp.frameunion.q2frames = Z_Malloc(sizeof(q2client_frame_t)*Q2UPDATE_BACKUP);
break; break;
#endif
default: 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; break;
} }
@ -3063,7 +3085,7 @@ void SV_Impulse_f (void)
if (!svprogfuncs) if (!svprogfuncs)
return; return;
pr_global_struct->time = sv.time; pr_global_struct->time = sv.physicstime;
svs.clients[i].state = cs_connected; 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_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect); 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_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer); PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
@ -3708,7 +3730,7 @@ void Master_Heartbeat (void)
} }
if (sv_reportheartbeats.value) 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); 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_listen_dp.value) //set listen to 1 to allow qw connections, 2 to allow nq connections too.
{ {
if (sv_reportheartbeats.value) 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"; 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 if (sv_nomsec.value>=2) //try and imitate nq as closeley as possible
{ {
thinktime = ent->v->nextthink; thinktime = ent->v->nextthink;
if (thinktime <= 0 || thinktime > sv.time + host_frametime) if (thinktime <= 0 || thinktime > sv.physicstime + host_frametime)
return true; return true;
if (thinktime < sv.time) if (thinktime < sv.physicstime)
thinktime = sv.time; // don't let things stay in the past. thinktime = sv.physicstime; // don't let things stay in the past.
// it is possible to start that way // it is possible to start that way
// by a trigger with a local time. // by a trigger with a local time.
ent->v->nextthink = 0; ent->v->nextthink = 0;
@ -171,11 +171,11 @@ qboolean SV_RunThink (edict_t *ent)
thinktime = ent->v->nextthink; thinktime = ent->v->nextthink;
if (thinktime <= 0) if (thinktime <= 0)
return true; return true;
if (thinktime > sv.time + host_frametime) if (thinktime > sv.physicstime + host_frametime)
return true; return true;
if (thinktime < sv.time) if (thinktime < sv.physicstime)
thinktime = sv.time; // don't let things stay in the past. thinktime = sv.physicstime; // don't let things stay in the past.
// it is possible to start that way // it is possible to start that way
// by a trigger with a local time. // by a trigger with a local time.
ent->v->nextthink = 0; ent->v->nextthink = 0;
@ -214,7 +214,7 @@ void SV_Impact (edict_t *e1, edict_t *e2)
old_self = pr_global_struct->self; old_self = pr_global_struct->self;
old_other = pr_global_struct->other; 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) if (e1->v->touch && e1->v->solid != SOLID_NOT)
{ {
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, e1); 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) if (trace.plane.normal[2] > 0.7)
{ {
blocked |= 1; // floor 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->flags = (int)ent->v->flags | FL_ONGROUND;
ent->v->groundentity = EDICT_TO_PROG(svprogfuncs, trace.ent); ent->v->groundentity = EDICT_TO_PROG(svprogfuncs, trace.ent);
@ -903,7 +903,7 @@ float l;
VectorCopy (ent->v->origin, oldorg); VectorCopy (ent->v->origin, oldorg);
VectorCopy (ent->v->angles, oldang); VectorCopy (ent->v->angles, oldang);
ent->v->nextthink = 0; 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->self = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts); pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
#ifdef VM_Q1 #ifdef VM_Q1
@ -1034,7 +1034,7 @@ void SV_CheckWaterTransition (edict_t *ent)
{ {
if (ent->v->watertype == Q1CONTENTS_EMPTY) if (ent->v->watertype == Q1CONTENTS_EMPTY)
{ // just crossed into water { // 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->watertype = cont;
ent->v->waterlevel = 1; ent->v->waterlevel = 1;
@ -1043,7 +1043,7 @@ void SV_CheckWaterTransition (edict_t *ent)
{ {
if (ent->v->watertype != Q1CONTENTS_EMPTY) if (ent->v->watertype != Q1CONTENTS_EMPTY)
{ // just crossed into open { // 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->watertype = Q1CONTENTS_EMPTY;
ent->v->waterlevel = cont; ent->v->waterlevel = cont;
@ -1183,9 +1183,9 @@ void SV_Physics_Step (edict_t *ent)
if (hitsound) if (hitsound)
{ {
if (progstype == PROG_H2) if (progstype == PROG_H2)
SV_StartSound (ent, 0, "fx/thngland.wav", 255, 1); SVQ1_StartSound (ent, 0, "fx/thngland.wav", 255, 1);
else 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 // let the progs know that a new frame has started
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = 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 #ifdef VM_Q1
if (svs.gametype == GT_Q1QVM) if (svs.gametype == GT_Q1QVM)
Q1QVM_StartFrame(); Q1QVM_StartFrame();
@ -1732,8 +1732,8 @@ void SV_MoveChain(edict_t *ent, edict_t *movechain, float *initial_origin, float
{ {
vec3_t moveang, moveorg; vec3_t moveang, moveorg;
int i; int i;
VectorSubtract(ent->v->angles, initial_angle, moveang) VectorSubtract(ent->v->angles, initial_angle, moveang);
VectorSubtract(ent->v->origin, initial_origin, moveorg) 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)) 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 // 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); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
#ifdef VM_Q1 #ifdef VM_Q1
if (svs.gametype == GT_Q1QVM) if (svs.gametype == GT_Q1QVM)
@ -1876,7 +1876,7 @@ void SV_RunEntity (edict_t *ent)
{ {
SV_LinkEdict (ent, true); 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); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
#ifdef VM_Q1 #ifdef VM_Q1
if (svs.gametype == GT_Q1QVM) if (svs.gametype == GT_Q1QVM)
@ -1970,16 +1970,15 @@ qboolean SV_Physics (void)
int i; int i;
qboolean retouch; qboolean retouch;
edict_t *ent; 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<0)
{ {
if (host_frametime < -1) if (host_frametime < -1)
old_time = sv.time; sv.physicstime = sv.time;
host_frametime = 0; host_frametime = 0;
} }
if (svs.gametype != GT_QUAKE3) if (svs.gametype != GT_QUAKE3)
@ -1990,7 +1989,7 @@ qboolean SV_Physics (void)
} }
if (host_frametime > sv_maxtic.value) if (host_frametime > sv_maxtic.value)
host_frametime = sv_maxtic.value; host_frametime = sv_maxtic.value;
old_time = sv.time; sv.physicstime = sv.time;
sv.framenum++; sv.framenum++;
@ -2012,7 +2011,7 @@ qboolean SV_Physics (void)
return false; 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. //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 //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,18 +2064,37 @@ qboolean SV_Physics (void)
} }
} }
// don't bother running a frame if sys_ticrate seconds haven't passed // don't bother running a frame if sys_ticrate seconds haven't passed
host_frametime = realtime - old_time; while (1)
if (host_frametime < -1) {
old_time = 0; host_frametime = sv.time - sv.physicstime;
if (host_frametime < sv_mintic.value) if (host_frametime < 0)
return false; {
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) if (host_frametime > sv_maxtic.value)
host_frametime = sv_maxtic.value; host_frametime = sv_maxtic.value;
old_time = realtime; sv.physicstime += host_frametime;
}
sv.physicstime = sv.time; #ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
SVHL_RunFrame();
continue;
}
#endif
pr_global_struct->frametime = host_frametime; pr_global_struct->frametime = host_frametime;
@ -2129,7 +2147,7 @@ qboolean SV_Physics (void)
{ {
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = 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;
Q1QVM_EndFrame(); Q1QVM_EndFrame();
} }
else else
@ -2138,11 +2156,13 @@ qboolean SV_Physics (void)
{ {
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts);
pr_global_struct->other = 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;
PR_ExecuteProgram (svprogfuncs, EndFrameQC); 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; return false;
} }

View File

@ -663,10 +663,12 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
} }
if (svprogfuncs) if (svprogfuncs)
{
if (!((int)client->edict->xv->dimension_see & dimension_mask)) if (!((int)client->edict->xv->dimension_see & dimension_mask))
continue; continue;
if (to == MULTICAST_PHS_R || to == MULTICAST_PHS) { if (to == MULTICAST_PHS_R || to == MULTICAST_PHS)
{
vec3_t delta; vec3_t delta;
VectorSubtract(origin, client->edict->v->origin, delta); VectorSubtract(origin, client->edict->v->origin, delta);
if (Length(delta) <= 1024) if (Length(delta) <= 1024)
@ -683,6 +685,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
continue; continue;
} }
} }
}
inrange: inrange:
switch (client->protocol) switch (client->protocol)
@ -774,15 +777,12 @@ Larger attenuations will drop off. (max 4 attenuation)
================== ==================
*/ */
void SV_StartSound (edict_t *entity, int channel, char *sample, int volume, void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sample, int volume, float attenuation)
float attenuation)
{ {
int sound_num; int sound_num;
int extfield_mask; int extfield_mask;
int qwflags; int qwflags;
int i; int i;
int ent;
vec3_t origin;
qboolean use_phs; qboolean use_phs;
qboolean reliable = false; qboolean reliable = false;
int requiredextensions = 0; int requiredextensions = 0;
@ -817,8 +817,6 @@ void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
return; return;
} }
ent = NUM_FOR_EDICT(svprogfuncs, entity);
if ((channel & 8) || !sv_phs.value) // no PHS flag if ((channel & 8) || !sv_phs.value) // no PHS flag
{ {
if (channel & 8) if (channel & 8)
@ -829,17 +827,6 @@ void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
else else
use_phs = true; 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) // if (channel == CHAN_BODY || channel == CHAN_VOICE)
// reliable = true; // reliable = true;
@ -931,9 +918,26 @@ void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
MSG_WriteCoord (&sv.nqmulticast, origin[i]); MSG_WriteCoord (&sv.nqmulticast, origin[i]);
#endif #endif
if (use_phs) 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 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; ent = client->edict;
if (!ent)
return;
// send a damage message if the player got hit this frame // send a damage message if the player got hit this frame
if (ent->v->dmg_take || ent->v->dmg_save) if (ent->v->dmg_take || ent->v->dmg_save)
{ {
@ -1379,6 +1386,16 @@ void SV_UpdateClientStats (client_t *client, int pnum)
if (client->spectator && client->spec_track > 0) if (client->spectator && client->spec_track > 0)
ent = svs.clients[client->spec_track - 1].edict; ent = svs.clients[client->spec_track - 1].edict;
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
SVHL_BuildStats(client, statsi, statsf, statss);
pr_globals = NULL;
}
else
#endif
{
statsf[STAT_HEALTH] = ent->v->health; //sorry, but mneh statsf[STAT_HEALTH] = ent->v->health; //sorry, but mneh
statsi[STAT_WEAPON] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel)); statsi[STAT_WEAPON] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel));
if (host_client->fteprotocolextensions & PEXT_MODELDBL) if (host_client->fteprotocolextensions & PEXT_MODELDBL)
@ -1452,7 +1469,7 @@ void SV_UpdateClientStats (client_t *client, int pnum)
//dmw tweek for stats //dmw tweek for stats
pr_globals = PR_globals(svprogfuncs, PR_CURRENT); pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
}
m = MAX_QW_STATS; m = MAX_QW_STATS;
if (client->fteprotocolextensions & PEXT_HEXEN2) if (client->fteprotocolextensions & PEXT_HEXEN2)
m = MAX_CL_STATS; m = MAX_CL_STATS;
@ -1698,12 +1715,15 @@ SV_UpdateToReliableMessages
*/ */
void SV_UpdateToReliableMessages (void) void SV_UpdateToReliableMessages (void)
{ {
volatile float newval; // needed to ensure 32/32-bit fp comparisons
int i, j; int i, j;
client_t *client, *sp; client_t *client, *sp;
edict_t *ent; edict_t *ent;
char *name; char *name;
float curgrav;
float curspeed;
int curfrags;
// check for changes to be sent over the reliable streams to all clients // 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++) for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++)
{ {
@ -1777,6 +1797,34 @@ void SV_UpdateToReliableMessages (void)
} }
continue; 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 (!ISQ2CLIENT(host_client))
{ {
if (host_client->sendinfo) if (host_client->sendinfo)
@ -1784,7 +1832,7 @@ void SV_UpdateToReliableMessages (void)
host_client->sendinfo = false; host_client->sendinfo = false;
SV_FullClientUpdate (host_client, &sv.reliable_datagram, host_client->fteprotocolextensions); 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++) for (j=0, client = svs.clients ; j<MAX_CLIENTS ; j++, client++)
{ {
@ -1794,7 +1842,7 @@ void SV_UpdateToReliableMessages (void)
continue; continue;
ClientReliableWrite_Begin(client, svc_updatefrags, 4); ClientReliableWrite_Begin(client, svc_updatefrags, 4);
ClientReliableWrite_Byte(client, i); ClientReliableWrite_Byte(client, i);
ClientReliableWrite_Short(client, host_client->edict->v->frags); ClientReliableWrite_Short(client, curfrags);
} }
if (sv.mvdrecording) if (sv.mvdrecording)
@ -1802,45 +1850,24 @@ void SV_UpdateToReliableMessages (void)
MVDWrite_Begin(dem_all, 0, 4); MVDWrite_Begin(dem_all, 0, 4);
MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updatefrags); MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updatefrags);
MSG_WriteByte((sizebuf_t*)demo.dbuf, i); 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 if (host_client->entgravity != curgrav)
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 (ISQWCLIENT(host_client)) if (ISQWCLIENT(host_client))
{ {
sp = SV_SplitClientDest(host_client, svc_entgravity, 5); 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 (host_client->maxspeed != curspeed)
{
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)
{ //MSVC can really suck at times (optimiser bug) { //MSVC can really suck at times (optimiser bug)
if (ISQWCLIENT(host_client)) if (ISQWCLIENT(host_client))
{ {
@ -1860,15 +1887,15 @@ void SV_UpdateToReliableMessages (void)
ClientReliableWrite_Begin (sp, svcfte_choosesplitclient, 7); ClientReliableWrite_Begin (sp, svcfte_choosesplitclient, 7);
ClientReliableWrite_Byte (sp, pnum); ClientReliableWrite_Byte (sp, pnum);
ClientReliableWrite_Byte (sp, svc_maxspeed); ClientReliableWrite_Byte (sp, svc_maxspeed);
ClientReliableWrite_Float(sp, newval); ClientReliableWrite_Float(sp, curspeed);
} }
else else
{ {
ClientReliableWrite_Begin(host_client, svc_maxspeed, 5); 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; splitnum = 0;
for (split = host_client; split; split = split->controlled) for (split = host_client; split; split = split->controlled)
{ {
#ifdef Q2SERVER switch(svs.gametype)
if (!svprogfuncs) {
playernum = Q2NUM_FOR_EDICT(split->q2edict)-1; #ifdef HLSERVER
else case GT_HALFLIFE:
playernum = split - svs.clients;
break;
#endif #endif
#ifdef Q2SERVER
case GT_QUAKE2:
playernum = Q2NUM_FOR_EDICT(split->q2edict)-1;
break;
#endif
default:
playernum = NUM_FOR_EDICT(svprogfuncs, split->edict)-1; playernum = NUM_FOR_EDICT(svprogfuncs, split->edict)-1;
}
if (sv.demostate) if (sv.demostate)
{ {
playernum = (MAX_CLIENTS-1-splitnum)|128; playernum = (MAX_CLIENTS-1-splitnum)|128;
@ -1241,6 +1250,8 @@ void SV_Spawn_f (void)
client_t *client, *split; client_t *client, *split;
edict_t *ent; edict_t *ent;
int secret_total, secret_found, monsters_total, monsters_found;
if (host_client->state != cs_connected) if (host_client->state != cs_connected)
{ {
Con_Printf ("Spawn not valid -- already spawned\n"); Con_Printf ("Spawn not valid -- already spawned\n");
@ -1302,6 +1313,23 @@ void SV_Spawn_f (void)
} }
} }
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
for (split = host_client; split; split = split->controlled)
{
split->entgravity = 1;
split->maxspeed = 320;
}
secret_total = 0;
secret_found = 0;
monsters_total = 0;
monsters_found = 0;
}
else
#endif
{
// set up the edict // set up the edict
for (split = host_client; split; split = split->controlled) for (split = host_client; split; split = split->controlled)
{ {
@ -1325,22 +1353,26 @@ void SV_Spawn_f (void)
memset (host_client->statss, 0, sizeof(host_client->statss)); 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_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALSECRETS); 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_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALMONSTERS); 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_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_SECRETS); 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_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_MONSTERS); 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 // get the client to check and download skins
// when that is completed, a begin command will be issued // when that is completed, a begin command will be issued
ClientReliableWrite_Begin (host_client, svc_stufftext, 8); ClientReliableWrite_Begin (host_client, svc_stufftext, 8);
@ -1385,6 +1417,7 @@ void SV_Begin_Core(client_t *split)
int i; int i;
if (progstype == PROG_H2 && host_client->playerclass) 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 host_client->edict->xv->playerclass = host_client->playerclass; //make sure it's set the same as the userinfo
#ifdef Q2SERVER #ifdef Q2SERVER
if (ge) if (ge)
{ {
@ -1401,7 +1434,7 @@ void SV_Begin_Core(client_t *split)
f = PR_FindFunction(svprogfuncs, "RestoreGame", PR_ANY); f = PR_FindFunction(svprogfuncs, "RestoreGame", PR_ANY);
if (f) if (f)
{ {
pr_global_struct->time = sv.time; pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, f); PR_ExecuteProgram (svprogfuncs, f);
} }
@ -1429,13 +1462,20 @@ void SV_Begin_Core(client_t *split)
} }
// call the spawn function // call the spawn function
pr_global_struct->time = sv.time; pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorConnect); PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
} }
} }
else else
{ {
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
SVHL_PutClientInServer(split);
}
else
#endif
if (svprogfuncs) if (svprogfuncs)
{ {
eval_t *eval, *eval2; eval_t *eval, *eval2;
@ -1458,7 +1498,7 @@ void SV_Begin_Core(client_t *split)
if (spawnparamglobals[j]) if (spawnparamglobals[j])
*spawnparamglobals[j] = split->spawn_parms[j]; *spawnparamglobals[j] = split->spawn_parms[j];
} }
pr_global_struct->time = sv.time; pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
G_FLOAT(OFS_PARM0) = sv.time - split->spawninfotime; G_FLOAT(OFS_PARM0) = sv.time - split->spawninfotime;
PR_ExecuteProgram(svprogfuncs, eval->function); PR_ExecuteProgram(svprogfuncs, eval->function);
@ -1479,12 +1519,12 @@ void SV_Begin_Core(client_t *split)
else else
#endif #endif
{ {
pr_global_struct->time = sv.time; pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect); PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player // actually spawn the player
pr_global_struct->time = sv.time; pr_global_struct->time = sv.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer); PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
} }
@ -2723,15 +2763,25 @@ void SV_Kill_f (void)
{ {
float floodtime; float floodtime;
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
HLSV_ClientCommand(host_client);
return;
}
#endif
#ifdef VM_Q1 #ifdef VM_Q1
if (svs.gametype == GT_Q1QVM) 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); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
Q1QVM_ClientCommand(); Q1QVM_ClientCommand();
return; return;
} }
#endif #endif
if (svs.gametype != GT_PROGS)
return;
if (sv_player->v->health <= 0) if (sv_player->v->health <= 0)
{ {
@ -2749,7 +2799,7 @@ void SV_Kill_f (void)
SV_PushFloodProt(host_client); 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_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientKill); PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientKill);
@ -3553,12 +3603,12 @@ void Cmd_Join_f (void)
} }
// call the spawn function // 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_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect); PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player // 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_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer); PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
@ -3648,7 +3698,7 @@ void Cmd_Observe_f (void)
// call the spawn function // call the spawn function
if (SpectatorConnect) 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_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, SpectatorConnect); PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
} }
@ -3886,6 +3936,14 @@ void SV_ExecuteUserCommand (char *s, qboolean fromQC)
if (!u->name) if (!u->name)
{ {
#ifdef HLSERVER
if (HLSV_ClientCommand(host_client))
{
host_client = oldhost;
return;
}
#endif
if (!fromQC) if (!fromQC)
if (PR_UserCmd(s)) //Q2 and MVDSV command handling only happens if the engine didn't recognise it. 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 // 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_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, SpectatorConnect); PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
} }
@ -4077,12 +4135,12 @@ void SVNQ_Begin_f (void)
} }
// call the spawn function // 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_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect); PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player // 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_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer); PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
} }
@ -5344,7 +5402,13 @@ haveannothergo:
newcmd.upmove = 0; newcmd.upmove = 0;
} }
#ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE)
{
SVHL_RunPlayerCommand(cl, &oldest, &oldcmd, &newcmd);
}
else
#endif
if (!sv.paused) if (!sv.paused)
{ {
if (sv_nomsec.value) if (sv_nomsec.value)
@ -6213,7 +6277,7 @@ void SV_ClientThink (void)
if (SV_PlayerPhysicsQC) 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_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, SV_PlayerPhysicsQC); PR_ExecuteProgram (svprogfuncs, SV_PlayerPhysicsQC);
return; return;

View File

@ -2128,7 +2128,7 @@ void SVQ3_WriteSnapshotToClient(client_t *client, sizebuf_t *msg)
// write snapshot header // write snapshot header
MSG_WriteBits(msg, svcq3_snapshot, 8); 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 MSG_WriteBits(msg, delta, 8); // what we are delta'ing from
// write snapFlags // write snapFlags
@ -2374,7 +2374,7 @@ void SVQ3_BuildClientSnapshot( client_t *client )
// this is the frame we are creating // this is the frame we are creating
snap = &client->frameunion.q3frames[client->netchan.outgoing_sequence & Q3UPDATE_MASK]; 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; snap->flags = 0;
if( client->state < cs_spawned ) if( client->state < cs_spawned )
@ -2976,6 +2976,8 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
SV_Begin_Core(client); SV_Begin_Core(client);
} }
client->state = cs_spawned; client->state = cs_spawned;
client->lastcmd.servertime = sv.time*1000;
break; break;
case cs_spawned: case cs_spawned:
// run G_ClientThink() on each usercmd // run G_ClientThink() on each usercmd

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