A few tweeks here and there.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1407 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2005-10-01 03:09:17 +00:00
parent 56f3dd788b
commit 4366f644e5
32 changed files with 1019 additions and 221 deletions

View File

@ -499,7 +499,7 @@ static long CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const long
cvar_t *var;
var = Cvar_FindVar(VM_POINTER(arg[0]));
if (var)
Cvar_Set(var, VM_POINTER(arg[1])); //set it
Cvar_Set(var, VM_POINTER(arg[1])?VM_POINTER(arg[1]):""); //set it
else
Cvar_Get(VM_POINTER(arg[0]), VM_POINTER(arg[1]), 0, "Q3CG created"); //create one
}

View File

@ -396,13 +396,13 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean
if (to->frame != from->frame)
{
cl.lerpents[to->number].oldframechange = cl.lerpents[to->number].framechange; //marked for hl models
cl.lerpents[to->number].framechange = cl.time; //marked for hl models
cl.lerpents[to->number].framechange = cl.servertime; //marked for hl models
}
if (to->modelindex != from->modelindex || to->number != from->number || VectorLength(move)>500) //model changed... or entity changed...
{
cl.lerpents[to->number].oldframechange = cl.lerpents[to->number].framechange; //marked for hl models
cl.lerpents[to->number].framechange = cl.time; //marked for hl models
cl.lerpents[to->number].framechange = cl.servertime; //marked for hl models
cl.lerpents[to->number].lerptime = -10;
cl.lerpents[to->number].lerprate = 0;
@ -438,10 +438,10 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean
//2: physics. Objects moving acording to gravity.
//3: both. This is really awkward. And I'm really lazy.
//the real solution would be to seperate the two.
cl.lerpents[to->number].lerprate = cl.time-cl.lerpents[to->number].lerptime; //time per update
cl.lerpents[to->number].lerprate = cl.servertime-cl.lerpents[to->number].lerptime; //time per update
// Con_Printf("%f=%f-%f\n", cl.lerpents[to->number].lerprate, cl.time, cl.lerpents[to->number].lerptime);
cl.lerpents[to->number].frame = from->frame;
cl.lerpents[to->number].lerptime = cl.time;
cl.lerpents[to->number].lerptime = cl.servertime;
if (cl.lerpents[to->number].lerprate>0.2)
cl.lerpents[to->number].lerprate=0.2;
@ -505,7 +505,12 @@ void CL_ParsePacketEntities (qboolean delta)
int word, newnum, oldnum;
qboolean full;
int from;
/*
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
cl.gametime = realtime;
cl.gametimemark = realtime;
*/
newpacket = cls.netchan.incoming_sequence&UPDATE_MASK;
newp = &cl.frames[newpacket].packet_entities;
cl.frames[newpacket].invalid = false;
@ -991,16 +996,38 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o(
to->flags &= ~0x80000000;
if (!from || to->modelindex != from->modelindex || to->number != from->number) //model changed... or entity changed...
{
cl.lerpents[to->number].lerptime = -10;
cl.lerpents[to->number].origin[0] = to->origin[0];
cl.lerpents[to->number].origin[1] = to->origin[1];
cl.lerpents[to->number].origin[2] = to->origin[2];
cl.lerpents[to->number].angles[0] = to->angles[0];
cl.lerpents[to->number].angles[1] = to->angles[1];
cl.lerpents[to->number].angles[2] = to->angles[2];
}
else if (to->frame != from->frame || to->origin[0] != from->origin[0] || to->origin[1] != from->origin[1] || to->origin[2] != from->origin[2])
{
cl.lerpents[to->number].origin[0] = from->origin[0];
cl.lerpents[to->number].origin[1] = from->origin[1];
cl.lerpents[to->number].origin[2] = from->origin[2];
if (from == &defaultstate) //lerp from the new position instead of old, so no lerp
{
cl.lerpents[to->number].origin[0] = to->origin[0];
cl.lerpents[to->number].origin[1] = to->origin[1];
cl.lerpents[to->number].origin[2] = to->origin[2];
cl.lerpents[to->number].angles[0] = from->angles[0];
cl.lerpents[to->number].angles[1] = from->angles[1];
cl.lerpents[to->number].angles[2] = from->angles[2];
cl.lerpents[to->number].angles[0] = to->angles[0];
cl.lerpents[to->number].angles[1] = to->angles[1];
cl.lerpents[to->number].angles[2] = to->angles[2];
}
else
{
cl.lerpents[to->number].origin[0] = from->origin[0];
cl.lerpents[to->number].origin[1] = from->origin[1];
cl.lerpents[to->number].origin[2] = from->origin[2];
cl.lerpents[to->number].angles[0] = from->angles[0];
cl.lerpents[to->number].angles[1] = from->angles[1];
cl.lerpents[to->number].angles[2] = from->angles[2];
}
//we have three sorts of movement.
//1: stepping monsters. These have frames and tick at 10fps.
//2: physics. Objects moving acording to gravity.
@ -1234,9 +1261,9 @@ void CLNQ_ParseEntity(unsigned int bits)
//1: stepping monsters. These have frames and tick at 10fps.
//2: physics. Objects moving acording to gravity.
//3: both. This is really awkward. And I'm really lazy.
cl.lerpents[state->number].lerprate = cl.time-cl.lerpents[state->number].lerptime; //time per update
cl.lerpents[state->number].lerprate = cl.gametime-cl.lerpents[state->number].lerptime; //time per update
cl.lerpents[state->number].frame = from->frame;
cl.lerpents[state->number].lerptime = cl.time;
cl.lerpents[state->number].lerptime = cl.gametime;
if (cl.lerpents[state->number].lerprate>0.2)
cl.lerpents[state->number].lerprate=0.2;
@ -1511,19 +1538,29 @@ void CL_LinkPacketEntities (void)
ent->forcedshader = NULL;
#endif
//figure out the lerp factor
if (cl.lerpents[s1->number].lerprate<=0)
ent->lerpfrac = 0;
if (cl_nolerp.value)
f = 1;
else
ent->lerpfrac = 1-(cl.time-cl.lerpents[s1->number].lerptime)/cl.lerpents[s1->number].lerprate;
{
//figure out the lerp factor
if (cl.lerpents[s1->number].lerprate<=0)
f = 0;
else
f = (cl.servertime-cl.lerpents[s1->number].lerptime)/cl.lerpents[s1->number].lerprate;//(cl.gametime-cl.oldgametime);//1-(cl.time-cl.lerpents[s1->number].lerptime)/cl.lerpents[s1->number].lerprate;
if (f<0)
f=0;
if (f>1)
f=1;
}
ent->lerpfrac = 1-(cl.servertime-cl.lerpents[s1->number].lerptime)/cl.lerpents[s1->number].lerprate;
if (ent->lerpfrac<0)
ent->lerpfrac=0;
if (ent->lerpfrac>1)
ent->lerpfrac=1;
f = 1-ent->lerpfrac;
if (cl_nolerp.value)
f = 1;
// if (s1->modelindex == 87 && !cl.paused)
// Con_Printf("%f %f\n", f, cl.lerpents[s1->number].lerptime-cl.servertime);
// calculate origin
for (i=0 ; i<3 ; i++)
@ -1609,8 +1646,8 @@ void CL_LinkPacketEntities (void)
ent->frame = s1->frame;
ent->oldframe = cl.lerpents[s1->number].frame;
ent->frame1time = cl.time - cl.lerpents[s1->number].framechange;
ent->frame2time = cl.time - cl.lerpents[s1->number].oldframechange;
ent->frame1time = cl.servertime - cl.lerpents[s1->number].framechange;
ent->frame2time = cl.servertime - cl.lerpents[s1->number].oldframechange;
// f = (sin(realtime)+1)/2;
@ -2314,6 +2351,7 @@ void CL_LinkPlayers (void)
entity_t *ent;
int msec;
frame_t *frame;
frame_t *fromf;
int oldphysent;
vec3_t angles;
@ -2321,12 +2359,13 @@ void CL_LinkPlayers (void)
if (playertime > realtime)
playertime = realtime;
frame = &cl.frames[cl.parsecount&UPDATE_MASK];
frame = &cl.frames[cl.validsequence&UPDATE_MASK];
fromf = &cl.frames[cl.oldvalidsequence&UPDATE_MASK];
for (j=0, info=cl.players, state=frame->playerstate ; j < MAX_CLIENTS
; j++, info++, state++)
{
if (state->messagenum != cl.parsecount)
if (state->messagenum != cl.validsequence)
continue; // not present this frame
// spawn light flashes, even ones coming from invisible objects
@ -2429,8 +2468,25 @@ void CL_LinkPlayers (void)
// only predict half the move to minimize overruns
msec = 500*(playertime - state->state_time);
if (pnum < cl.splitclients)
if (1)
{
float f;
int i;
f = (cl.gametime-cl.servertime)/(cl.gametime-cl.oldgametime);
if (f<0)
f=0;
if (f>1)
f=1;
for (i=0 ; i<3 ; i++)
{
ent->origin[i] = state->origin[i] +
f * (fromf->playerstate[j].origin[i] - state->origin[i]);
}
}
else if (pnum < cl.splitclients)
{ //this is a local player
}
else if (msec <= 0 || (!cl_predict_players.value && !cl_predict_players2.value))
{

View File

@ -81,6 +81,8 @@ cvar_t cl_indepphysics = {"cl_indepphysics", "0"};
cvar_t localid = {"localid", ""};
cvar_t cl_antibunch = {"cl_antibunch", "0.013"};
static qboolean allowremotecmd = true;
//
@ -845,6 +847,12 @@ void CL_ClearState (void)
Media_PlayFilm("");
}
for (i = 0; i < UPDATE_BACKUP; i++)
{
if (cl.frames[i].packet_entities.entities)
Z_Free(cl.frames[i].packet_entities.entities);
}
if (cl.lerpents)
BZ_Free(cl.lerpents);
@ -2038,14 +2046,52 @@ CL_ReadPackets
void CL_ReadPackets (void)
{
// while (NET_GetPacket ())
while (CL_GetMessage())
for(;;)
{
if (cl.oldgametime && cl_antibunch.value)
{
float want;
static float clamp;
want = cl.oldgametime + realtime - cl.gametimemark - clamp;
if (want>cl.time) //don't decrease
{
clamp = 0;
cl.time = want;
}
if (cl.time > cl.gametime)
{
clamp += cl.time - cl.gametime;
cl.time = cl.gametime;
}
if (cl.time < cl.oldgametime)
{
clamp -= cl.time - cl.gametime;
cl.time = cl.oldgametime;
}
if (cl.time < cl.gametime-(1/cl_antibunch.value))
{
// if (cl.gametime - 2 > cl.time)
// cl.gametime = 0;
break;
}
}
if (!CL_GetMessage())
break;
#ifdef NQPROT
if (cls.demoplayback == DPB_NETQUAKE)
{
MSG_BeginReading ();
cls.netchan.last_received = realtime;
CLNQ_ParseServerMessage ();
if (!cls.demoplayback)
CL_NextDemo();
continue;
}
#endif
@ -2105,9 +2151,10 @@ void CL_ReadPackets (void)
{
case 0:
break;
case 1:
case 1://datagram
// if (cls.n
cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence - 3;
case 2:
case 2://reliable
CLNQ_ParseServerMessage ();
break;
}
@ -2425,6 +2472,7 @@ void CL_Init (void)
Cvar_Register (&host_mapname, "Scripting");
Cvar_Register (&cl_indepphysics, cl_controlgroup);
Cvar_Register (&cl_antibunch, "evil hacks");
#ifdef IRCCLIENT
Cmd_AddCommand ("irc", CL_IRC_f);

View File

@ -691,6 +691,11 @@ void Sound_NextDownload (void)
unsigned int chksum = strtoul(s, NULL, 0);
if (CSQC_Init(chksum))
CL_SendClientCommand(true, "enablecsqc");
else
Sbar_Start(); //try and start this before we're actually on the server,
//this'll stop the mod from sending so much stuffed data at us, whilst we're frozen while trying to load.
//hopefully this'll make it more robust.
//csqc is expected to use it's own huds, or to run on decent servers. :p
}
}
#endif
@ -1519,6 +1524,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
Con_TPrintf (TLC_GOTSVDATAPACKET);
CL_ClearState ();
Stats_NewMap();
P_NewServer();
protover = MSG_ReadLong ();
@ -1653,7 +1659,6 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
cl.worldmodel = cl.model_precache[1];
R_NewMap ();
if (cls.demoplayback)
@ -1669,6 +1674,9 @@ void CLNQ_SignonReply (void)
{
extern cvar_t topcolor;
extern cvar_t bottomcolor;
extern cvar_t rate;
extern cvar_t model;
extern cvar_t skin;
Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
@ -1685,6 +1693,14 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
CL_SendClientCommand(true, "color %i %i\n", (int)topcolor.value, (int)bottomcolor.value);
CL_SendClientCommand(true, "spawn %s", "");
if (nq_dp_protocol) //dp needs a couple of extras to work properly.
{
CL_SendClientCommand(true, "rate %s", rate.string);
CL_SendClientCommand(true, "playermodel %s", model.string);
CL_SendClientCommand(true, "playerskin %s", skin.string);
}
break;
case 3:
@ -2433,7 +2449,7 @@ void CL_ParseClientdata (void)
frame->senttime = realtime - host_frametime;
parsecounttime = cl.frames[i].senttime;
frame->receivedtime = realtime;
frame->receivedtime = (cl.gametimemark - cl.oldgametimemark)*20;
// calculate latency
latency = frame->receivedtime - frame->senttime;
@ -2690,6 +2706,9 @@ void CL_SetStat (int pnum, int stat, int value)
if (stat == STAT_TIME && cls.z_ext & Z_EXT_SERVERTIME)
{
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
// cl.servertime_works = true;
cl.gametime = value * 0.001;
cl.gametimemark = realtime;
@ -4188,20 +4207,25 @@ void CLNQ_ParseServerMessage (void)
break;
case svc_time:
cls.netchan.outgoing_sequence++;
cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence-1;
cl.validsequence = cls.netchan.incoming_sequence-1;
received_framecount = host_framecount;
cl.last_servermessage = realtime;
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
cl.gametime = MSG_ReadFloat();
cl.gametimemark = realtime;
if (nq_dp_protocol<5)
{
// cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities = cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities;
cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.num_entities=0;
}
cls.netchan.outgoing_sequence++;
cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence-1;
cl.validsequence = cls.netchan.incoming_sequence-1;
break;
case svc_updatename:
@ -4242,7 +4266,11 @@ void CLNQ_ParseServerMessage (void)
case svc_lightstyle:
i = MSG_ReadByte ();
if (i >= MAX_LIGHTSTYLES)
Host_EndGame ("svc_lightstyle > MAX_LIGHTSTYLES");
{
Con_Printf("svc_lightstyle: %i >= MAX_LIGHTSTYLES\n", i);
MSG_ReadString();
break;
}
#ifdef PEXT_LIGHTSTYLECOL
cl_lightstyle[i].colour = 7; //white
#endif

View File

@ -517,6 +517,173 @@ void CL_CalcCrouch (int pnum)
}
}
float LerpAngles360(float to, float from, float frac)
{
int delta;
delta = (from-to);
if (delta > 180)
delta -= 360;
if (delta < -180)
delta += 360;
return to + frac*delta;
}
//shamelessly ripped from zquake
extern cvar_t cl_nolerp;
static void CL_LerpMove (int pnum, float msgtime)
{
static int lastsequence = 0;
static vec3_t lerp_angles[3];
static vec3_t lerp_origin[3];
static float lerp_times[3];
static qboolean nolerp[2];
static float demo_latency = 0.01;
float frac;
float simtime;
int i;
int from, to;
if (cl_nolerp.value)
return;
if (cls.netchan.outgoing_sequence < lastsequence) {
// reset
lastsequence = -1;
lerp_times[0] = -1;
demo_latency = 0.01;
}
if (cls.netchan.outgoing_sequence > lastsequence) {
lastsequence = cls.netchan.outgoing_sequence;
// move along
lerp_times[2] = lerp_times[1];
lerp_times[1] = lerp_times[0];
lerp_times[0] = msgtime;
VectorCopy (lerp_origin[1], lerp_origin[2]);
VectorCopy (lerp_origin[0], lerp_origin[1]);
VectorCopy (cl.simorg[pnum], lerp_origin[0]);
VectorCopy (lerp_angles[1], lerp_angles[2]);
VectorCopy (lerp_angles[0], lerp_angles[1]);
VectorCopy (cl.simangles[pnum], lerp_angles[0]);
nolerp[1] = nolerp[0];
nolerp[0] = false;
for (i = 0; i < 3; i++)
if (fabs(lerp_origin[0][i] - lerp_origin[1][i]) > 40)
break;
if (i < 3)
nolerp[0] = true; // a teleport or something
}
simtime = realtime - demo_latency;
// adjust latency
if (simtime > lerp_times[0]) {
// Com_DPrintf ("HIGH clamp\n");
demo_latency = realtime - lerp_times[0];
}
else if (simtime < lerp_times[2]) {
// Com_DPrintf (" low clamp\n");
demo_latency = realtime - lerp_times[2];
} else {
// drift towards ideal latency
float ideal_latency = (lerp_times[0] - lerp_times[2]) * 0.6;
if (demo_latency > ideal_latency)
demo_latency = max(demo_latency - host_frametime * 0.1, ideal_latency);
}
// decide where to lerp from
if (simtime > lerp_times[1]) {
from = 1;
to = 0;
} else {
from = 2;
to = 1;
}
if (nolerp[to])
return;
frac = (simtime - lerp_times[from]) / (lerp_times[to] - lerp_times[from]);
frac = bound (0, frac, 1);
for (i=0 ; i<3 ; i++)
{
cl.simorg[pnum][i] = lerp_origin[from][i] +
frac * (lerp_origin[to][i] - lerp_origin[from][i]);
cl.simangles[pnum][i] = LerpAngles360(lerp_angles[from][i], lerp_angles[to][i], frac);
}
// LerpVector (lerp_origin[from], lerp_origin[to], frac, cl.simorg);
// LerpAngles (lerp_angles[from], lerp_angles[to], frac, cl.simangles);
}
short LerpAngles16(short to, short from, float frac)
{
int delta;
delta = (from-to);
if (delta > 32767)
delta -= 65535;
if (delta < -32767)
delta += 65535;
return to + frac*delta;
}
void CL_CalcClientTime(void)
{
{
float want;
want = cl.oldgametime + realtime - cl.gametimemark;
if (want>cl.servertime)
cl.servertime = want;
if (cl.servertime > cl.gametime)
cl.servertime = cl.gametime;
if (cl.servertime < cl.oldgametime)
cl.servertime = cl.oldgametime;
}
if (cls.protocol == CP_NETQUAKE || cls.demoplayback)
{
float want;
// float off;
want = cl.oldgametime + realtime - cl.gametimemark;
// off = (want - cl.time);
if (want>cl.time) //don't decrease
cl.time = want;
// Con_Printf("Drifted to %f off by %f\n", cl.time, off);
// Con_Printf("\n");
if (cl.time > cl.gametime)
{
cl.time = cl.gametime;
// Con_Printf("max TimeClamp\n");
}
if (cl.time < cl.oldgametime)
{
cl.time = cl.oldgametime;
// Con_Printf("old TimeClamp\n");
}
}
else
{
cl.time = realtime - cls.latency - cl_pushlatency.value*0.001;
if (cl.time > realtime)
cl.time = realtime;
}
}
/*
==============
CL_PredictMove
@ -549,37 +716,8 @@ void CL_PredictMovePNum (int pnum)
if (cl.paused && !cls.demoplayback!=DPB_MVD && (!cl.spectator || !autocam[pnum]))
return;
if (cl.oldgametime)
{
float want;
float off;
CL_CalcClientTime();
want = cl.oldgametime + realtime - cl.gametimemark;
off = (want - cl.time);
if (want>cl.time)
cl.time = want;
// Con_Printf("Drifted to %f off by %f\n", cl.time, off);
if (cl.time > cl.gametime)
cl.time = cl.gametime;
if (cl.time < cl.oldgametime)
cl.time = cl.oldgametime;
}
else
{
cl.time = realtime - cls.latency - cl_pushlatency.value*0.001;
if (cl.time > realtime)
cl.time = realtime;
}
/* else
{
entitystate_t
cl.crouch = 0;
VectorCopy(cl
return;
}
*/
if (cl.intermission && cl.intermission != 3)
{
cl.crouch[pnum] = 0;
@ -623,13 +761,15 @@ void CL_PredictMovePNum (int pnum)
//figure out the lerp factor
if (cl.lerpents[state->number].lerprate<=0)
f = 1;
f = 0;
else
f = (cl.time-cl.lerpents[state->number].lerptime)/cl.lerpents[state->number].lerprate;
f = (cl.gametime-cl.servertime)/(cl.gametime-cl.oldgametime);//f = (cl.time-cl.lerpents[state->number].lerptime)/cl.lerpents[state->number].lerprate;
if (f<0)
f=0;
if (f>1)
f=1;
f = 1-f;
// Con_Printf("%f\n", f);
// if (cl_nolerp.value)
// f = 1;
@ -642,29 +782,6 @@ void CL_PredictMovePNum (int pnum)
org = lrp;
/*
if (old)
{
float f = (cl.time-cl.lerpents[cl.viewentity[pnum]].lerptime)/cl.lerpents[cl.viewentity[pnum]].lerprate;
f=1-f;
if (f<0)f=0;
if (f>1)f=1;
vel = vec3_origin;
for (i=0 ; i<3 ; i++)
lrp[i] = state->origin[i] +
f * (old->origin[i] - state->origin[i]);
org = lrp;
}
else
{
org = state->origin;
Con_Printf("No old\n");
}
*/
goto fixedorg;
}
}
@ -689,32 +806,64 @@ fixedorg:
to = &cl.frames[cl.validsequence & UPDATE_MASK];
for (i=1 ; i<UPDATE_BACKUP-1 && cl.validsequence+i <
cls.netchan.outgoing_sequence; i++)
if (Cam_TrackNum(pnum)>=0 && !cl_nolerp.value)
{
to = &cl.frames[(cl.validsequence+i) & UPDATE_MASK];
if (cl.intermission)
to->playerstate->pm_type = PM_FLY;
CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]]
, &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]);
float f;
cl.onground[pnum] = pmove.onground;
to = &cl.frames[cl.validsequence & UPDATE_MASK];
from = &cl.frames[cl.oldvalidsequence & UPDATE_MASK];
if (to->senttime >= cl.time)
break;
from = to;
//figure out the lerp factor
f = (cl.gametime-cl.servertime)/(cl.gametime-cl.oldgametime);//f = (cl.time-cl.lerpents[state->number].lerptime)/cl.lerpents[state->number].lerprate;
if (f<0)
f=0;
if (f>1)
f=1;
// f = 1-f;
// calculate origin
for (i=0 ; i<3 ; i++)
{
lrp[i] = to->playerstate[cl.playernum[pnum]].origin[i] +
f * (from->playerstate[cl.playernum[pnum]].origin[i] - to->playerstate[cl.playernum[pnum]].origin[i]);
cl.simangles[pnum][i] = LerpAngles16(to->playerstate[spec_track[pnum]].command.angles[i], from->playerstate[spec_track[pnum]].command.angles[i], f)*360.0f/65535;
}
org = lrp;
goto fixedorg;
}
if (independantphysics[pnum].msec)
else
{
from = to;
to = &ind;
to->cmd[pnum] = independantphysics[pnum];
to->senttime = cl.time;
for (i=1 ; i<UPDATE_BACKUP-1 && cl.validsequence+i <
cls.netchan.outgoing_sequence; i++)
{
to = &cl.frames[(cl.validsequence+i) & UPDATE_MASK];
if (cl.intermission)
to->playerstate->pm_type = PM_FLY;
CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]]
, &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]);
, &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]);
cl.onground[pnum] = pmove.onground;
cl.onground[pnum] = pmove.onground;
if (to->senttime >= cl.time)
break;
from = to;
}
if (independantphysics[pnum].msec)
{
from = to;
to = &ind;
to->cmd[pnum] = independantphysics[pnum];
to->senttime = cl.time;
CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]]
, &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]);
cl.onground[pnum] = pmove.onground;
}
}
pmove.numphysent = oldphysent;
@ -757,6 +906,10 @@ fixedorg:
CL_CatagorizePosition(pnum);
}
if (cls.demoplayback)
CL_LerpMove (pnum, to->senttime);
out:
CL_CalcCrouch (pnum);
cl.waterlevel[pnum] = pmove.waterlevel;

View File

@ -459,6 +459,11 @@ typedef struct
// the client simulates or interpolates movement to get these values
double time; // this is the time value that the client
// is rendering at. always <= realtime
float servertime; //current server time, bound between gametime and gametimemark
float mtime; //server time as on the server when we last received a packet. not allowed to decrease.
float oldmtime; //server time as on the server for the previously received packet.
float gametime;
float gametimemark;
float oldgametime; //used as the old time to lerp cl.time from.

View File

@ -513,7 +513,7 @@ void CLQ3_ParseGameState(void)
//
// wipe the client_state_t struct
//
memset(&cl, 0, sizeof(cl));
CL_ClearState();
cl.minpitch = -90;
cl.maxpitch = 90;

View File

@ -204,7 +204,6 @@ void M_Download_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
if (!cls.downloadmethod && (info->parsedsourcenum==-1 || downloadablelist[info->parsedsourcenum]))
{ //done downloading
char basename[64];
char *absolutename;
info->parsedsourcenum++;

View File

@ -33,8 +33,6 @@ cvar_t pr_menuqc_coreonerror = {"pr_menuqc_coreonerror", "1"};
//pr_cmds.c builtins that need to be moved to a common.
void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...);
void PF_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_print (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_dprint (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_error (progfuncs_t *prinst, struct globalvars_s *pr_globals);
@ -190,7 +188,30 @@ void PF_mod (progfuncs_t *prinst, struct globalvars_s *pr_globals)
G_FLOAT(OFS_RETURN) = (float)(((int)G_FLOAT(OFS_PARM0))%((int)G_FLOAT(OFS_PARM1)));
}
char *RemapCvarNameFromDPToFTE(char *name)
{
if (!stricmp(name, "vid_bitsperpixel"))
return "vid_bpp";
if (!stricmp(name, "_cl_playermodel"))
return "model";
if (!stricmp(name, "_cl_playerskin"))
return "skin";
if (!stricmp(name, "_cl_color"))
return "topcolor";
if (!stricmp(name, "_cl_name"))
return "name";
if (!stricmp(name, "v_contrast"))
return "v_contrast";
if (!stricmp(name, "v_hwgamma"))
return "vid_hardwaregamma";
if (!stricmp(name, "showfps"))
return "show_fps";
if (!stricmp(name, "sv_progs"))
return "progs";
return name;
}
static void PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -198,6 +219,7 @@ static void PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
char *str;
str = PR_GetStringOfs(prinst, OFS_PARM0);
str = RemapCvarNameFromDPToFTE(str);
{
var = Cvar_Get(str, "", 0, "menu cvars");
if (var)
@ -210,23 +232,39 @@ static void PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
G_FLOAT(OFS_RETURN) = 0;
}
}
static void PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *var_name, *val;
cvar_t *var;
var_name = PR_GetStringOfs(prinst, OFS_PARM0);
var_name = RemapCvarNameFromDPToFTE(var_name);
val = PR_GetStringOfs(prinst, OFS_PARM1);
var = Cvar_Get(var_name, val, 0, "QC variables");
Cvar_Set (var, val);
}
static void PF_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
cvar_t *cv = Cvar_Get(RemapCvarNameFromDPToFTE(str), "", 0, "QC variables");
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, cv->string );
}
qboolean M_Vid_GetMove(int num, int *w, int *h);
//a bit pointless really
void PF_cl_getresolution (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float mode = G_FLOAT(OFS_PARM0);
float *ret = G_VECTOR(OFS_RETURN);
#pragma message("fixme: PF_getresolution should return other modes")
if (mode > 0)
{
ret[0] = 0;
ret[1] = 0;
ret[2] = 0;
}
else
{
ret[0] = vid.width;
ret[1] = vid.height;
ret[2] = 0;
}
int w, h;
w=h=0;
M_Vid_GetMove(mode, &w, &h);
ret[0] = w;
ret[1] = h;
ret[2] = 0;
}
@ -475,12 +513,45 @@ void PF_CL_drawfill (progfuncs_t *prinst, struct globalvars_s *pr_globals)
//void drawsetcliparea(float x, float y, float width, float height) = #458;
void PF_CL_drawsetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float x = G_FLOAT(OFS_PARM0), y = G_FLOAT(OFS_PARM1), w = G_FLOAT(OFS_PARM2), h = G_FLOAT(OFS_PARM3);
#ifdef RGLQUAKE
if (qrenderer == QR_OPENGL && qglScissor)
{
x *= (float)glwidth/vid.width;
y *= (float)glheight/vid.height;
w *= (float)glwidth/vid.width;
h *= (float)glheight/vid.height;
//add a pixel because this makes DP's menus come out right.
x-=1;
y-=1;
w+=2;
h+=2;
qglScissor (x, glheight-(y+h), w, h);
qglEnable(GL_SCISSOR_TEST);
G_FLOAT(OFS_RETURN) = 1;
return;
}
#endif
G_FLOAT(OFS_RETURN) = 0;
}
//void drawresetcliparea(void) = #459;
void PF_CL_drawresetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
#ifdef RGLQUAKE
if (qrenderer == QR_OPENGL)
{
qglDisable(GL_SCISSOR_TEST);
G_FLOAT(OFS_RETURN) = 1;
return;
}
#endif
G_FLOAT(OFS_RETURN) = 0;
}
//void (float width, vector rgb, float alpha, float flags, vector pos1, ...) drawline;

View File

@ -956,16 +956,17 @@ HWND hwnd_dialog;
#ifndef CLIENTONLY
qboolean isDedicated = false;
#endif
/*
#ifdef _MSC_VER
#include <signal.h>
void VARGS Signal_Error_Handler(int i)
{
int *basepointer;
__asm {mov basepointer,ebp};
Sys_Error("Receieved signal, offset was 0x%8x", basepointer[73]);
Sys_Error("Received signal, offset was 0x%8x", basepointer[73]);
}
#endif
*/
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
@ -980,7 +981,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
/* previous instances do not exist in Win32 */
if (hPrevInstance)
return 0;
/*
#ifndef _DEBUG
#ifdef _MSC_VER
signal (SIGFPE, Signal_Error_Handler);
@ -988,7 +989,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
signal (SIGSEGV, Signal_Error_Handler);
#endif
#endif
*/
global_hInstance = hInstance;
global_nCmdShow = nCmdShow;

View File

@ -730,7 +730,7 @@ void Draw_CursorLine(int ox, int y, fileblock_t *b)
int cx;
int a = 0, i;
int colour=COLOR_WHITE;
int colour=COLOR_BLUE;
int ts = edittabspacing.value;
if (ts < 1)

View File

@ -1103,8 +1103,6 @@ void V_CalcRefdef (int pnum)
return;
#endif
V_DriftPitch (pnum);
// view is the weapon model (only visible from inside body)
view = &cl.viewent[pnum];
@ -1341,6 +1339,7 @@ void V_RenderPlayerViews(int plnum)
}
else
{
V_DriftPitch (plnum);
V_CalcRefdef (plnum);
}

View File

@ -1927,7 +1927,7 @@ skipwhite:
// parse a regular word
do
{
if (len >= sizeof(com_token)-1)
if (len >= TOKENSIZE-1)
break;
com_token[len] = c;
data++;
@ -2400,6 +2400,55 @@ char *Info_ValueForKey (char *s, const char *key)
}
}
char *Info_KeyForNumber (char *s, int num)
{
static char pkey[1024];
char *o;
if (*s == '\\')
s++;
while (1)
{
o = pkey;
while (*s != '\\')
{
if (!*s)
{
*pkey='\0';
return pkey;
}
*o++ = *s++;
if (o+2 >= pkey+sizeof(pkey)) //hrm. hackers at work..
{
*pkey='\0';
return pkey;
}
}
*o = 0;
s++;
while (*s != '\\' && *s)
{
if (!*s)
{
*pkey='\0';
return pkey;
}
s++;
}
if (!num--)
return pkey; //found the right one
if (!*s)
{
*pkey='\0';
return pkey;
}
s++;
}
}
void Info_RemoveKey (char *s, const char *key)
{
char *start;

View File

@ -1887,7 +1887,7 @@ gamemode_info_t gamemode_info[] = {
{"Darkplaces-Quake", "darkplaces", "-quake", "id1/pak0.pak", "id1", "qw", "fte"},
{"Darkplaces-Hipnotic", "hipnotic", "-hipnotic", NULL/*"hipnotic/pak0.pak"*/,"id1", "qw", "hipnotic", "fte"},
{"Darkplaces-Rogue", "rogue", "-rogue", NULL/*"rogue/pak0.pak", "id1"*/, "qw", "rogue", "fte"},
{"Nexuiz", "nexuiz", "-nexuiz", "data/data20050531.pk3", "id1", "qw", "data", "fte"},
{"Nexuiz", "nexuiz", "-nexuiz", "data/cvars.txt", "id1", "qw", "data", "fte"},
//supported commercial mods (some are currently only partially supported)
{"FTE-Hexen2", "hexen", "-hexen2", "data1/pak0.pak", "data1", "fte"},

View File

@ -3310,7 +3310,7 @@ void Q2BSP_MarkLights (dlight_t *light, int bit, mnode_t *node)
}
surf->dlightbits |= bit;
}
return;
return;
}
splitplane = node->plane;

View File

@ -279,12 +279,16 @@ qboolean NQNetChan_Process(netchan_t *chan)
}
drop = sequence - chan->incoming_unreliable - 1;
if (drop > 0)
{
Con_DPrintf("Dropped %i datagrams\n", drop);
chan->drop_count += drop;
}
chan->incoming_unreliable = sequence;
chan->last_received = realtime;
chan->incoming_acknowledged++;
chan->good_count++;
return 1;
}
if (header & NETFLAG_DATA)

View File

@ -836,8 +836,8 @@ int UDP_OpenSocket (int port, qboolean bcast)
int i;
int maxport = port + 100;
if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
Sys_Error ("UDP_OpenSocket: socket: %s", strerror(qerrno));
if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
return INVALID_SOCKET;
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno));

View File

@ -683,34 +683,41 @@ typedef struct entity_state_s
int bitmask; // for dp ents, so lost state can be repeated in replacement packets.
int flags; // nolerp, etc
int effects;
vec3_t origin;
vec3_t old_origin; //q2
vec3_t angles;
unsigned short modelindex2; //q2
#if defined(Q2CLIENT) || defined(Q2SERVER)
int renderfx; //q2
vec3_t old_origin; //q2/q3
qbyte modelindex3; //q2
qbyte modelindex4; //q2
unsigned short frame;
unsigned short colormap;
unsigned short skinnum;
int effects;
int renderfx; //q2
qbyte sound; //q2
qbyte event; //q2
unsigned short modelindex2; //q2
#endif
unsigned short frame;
unsigned short colormap;
unsigned short skinnum;
qbyte glowsize;
qbyte glowcolour;
qbyte scale;
qbyte trans;
char fatness;
qbyte hexen2flags;
qbyte abslight;
qbyte dpflags;
qbyte solid;
unsigned short light[4];
qbyte solid;
qbyte colormod[3];
qbyte lightstyle;
qbyte lightpflags;
unsigned short light[4];
unsigned short tagentity;
unsigned short tagindex;
@ -736,6 +743,8 @@ typedef struct usercmd_s
short forwardmove, sidemove, upmove;
qbyte impulse;
qbyte lightlevel;
//freestyle
qbyte weapon;
int servertime;
} usercmd_t;

View File

@ -91,6 +91,9 @@ typedef struct q2trace_s
#define MOVE_NOMONSTERS 1
#define MOVE_MISSILE 2
#define MOVE_HITMODEL 4
#define MOVE_RESERVED 8 //so we are less likly to get into tricky situations when we want to steal annother future DP extension.
#define MOVE_TRIGGERS 16 //triggers must be marked with FINDABLE_NONSOLID (an alternative to solid-corpse)
#define MOVE_EVERYTHING 32 //doesn't use the area grid stuff, and can return triggers and non-solid items if they're marked with FINDABLE_NONSOLID
typedef struct areanode_s
{

View File

@ -197,6 +197,8 @@ void VARGS Z_Free (void *c)
if (nz == zone_head)
zone_head = nz->next;
// Con_Printf("Free of %i bytes\n", nz->size);
free(nz);
}
@ -279,7 +281,9 @@ void *Z_BaseTagMalloc (int size, int tag, qboolean clear)
zone_t *nt;
// Z_CheckSentinals();
//Con_Printf("Malloc of %i bytes\n", size);
//if (size>20)
//Con_Printf("Big malloc\n");
if (size <= 0)
Sys_Error ("Z_Malloc: size %i", size);

View File

@ -1668,6 +1668,7 @@ void Shader_UpdateRegistration (void)
}
}
*/
/*
void Shader_UploadCinematic (shader_t *shader)
{
int j;
@ -1677,7 +1678,7 @@ void Shader_UploadCinematic (shader_t *shader)
pass = shader->passes;
for ( j = 0; j < shader->numpasses; j++, pass++ ) {
if ( pass->flags & SHADER_PASS_VIDEOMAP ) {
// pass->anim_frames[0] = GL_ResampleCinematicFrame ( pass );
pass->anim_frames[0] = GL_ResampleCinematicFrame ( pass );
}
}
}
@ -1700,9 +1701,8 @@ void Shader_RunCinematic (void)
if ( !(pass->flags & SHADER_PASS_VIDEOMAP) )
continue;
//FIXME: videomaps
// reinitialize
/* if ( pass->cin->frame == -1 ) {
if ( pass->cin->frame == -1 ) {
GL_StopCinematic ( pass->cin );
GL_PlayCinematic( pass->cin );
@ -1715,10 +1715,10 @@ void Shader_RunCinematic (void)
}
GL_RunCinematic ( pass->cin );
*/
}
}
}
*/
void Shader_DefaultBSP(char *shortname, shader_t *s)
{

View File

@ -4992,13 +4992,21 @@ void QCC_PR_ParseStatement (void)
if (e == &def_ret)
{ //copy it out, so our hack just below doesn't crash us
if (e->type->type == ev_vector)
/* if (e->type->type == ev_vector)
e = QCC_PR_Statement(pr_opcodes+OP_STORE_V, e, QCC_GetTemp(type_vector), NULL);
else
e = QCC_PR_Statement(pr_opcodes+OP_STORE_F, e, QCC_GetTemp(type_float), NULL);
if (e == &def_ret) //this shouldn't be happening
QCC_Error(ERR_INTERNAL, "internal error: switch: e == &def_ret");
*/
et = NULL;
}
else
{
et = e->temp;
e->temp = NULL; //so noone frees it until we finish this loop
}
et = e->temp;
e->temp = NULL; //so noone frees it until we finish this loop
//expands
@ -5216,8 +5224,11 @@ void QCC_PR_ParseStatement (void)
num_breaks = breaks;
}
e->temp = et;
QCC_FreeTemp(e);
if (et)
{
e->temp = et;
QCC_FreeTemp(e);
}
return;
}

View File

@ -59,6 +59,9 @@ cvar_t pr_compatabilitytest = {"pr_compatabilitytest", "0", NULL, CVAR_LATCH};
cvar_t pr_ssqc_coreonerror = {"pr_coreonerror", "1"};
cvar_t pr_tempstringcount = {"pr_tempstringcount", "16"};
cvar_t pr_tempstringsize = {"pr_tempstringsize", "4096"};
cvar_t sv_addon[MAXADDONS];
char cvargroup_progs[] = "Progs variables";
@ -886,6 +889,9 @@ void PR_Init(void)
Cvar_Register (&pr_overridebuiltins, cvargroup_progs);
Cvar_Register (&pr_ssqc_coreonerror, cvargroup_progs);
Cvar_Register (&pr_tempstringcount, cvargroup_progs);
Cvar_Register (&pr_tempstringsize, cvargroup_progs);
}
void Q_InitProgs(void)
@ -1463,12 +1469,11 @@ char *PF_VarString (progfuncs_t *prinst, int first, globalvars_t *pr_globals)
s = PR_GetStringOfs(prinst, OFS_PARM0+i*3);
if (s)
{
strcat (out, Translate(s));
s = Translate(s);
if (strlen(out)+strlen(s)+1 >= sizeof(buffer[0]))
SV_Error("VarString (builtin call ending with strings) exceeded maximum string length of %i chars", sizeof(buffer[0]));
//#ifdef PARANOID
if (strlen(out)+1 >= sizeof(buffer[0]))
Sys_Error("VarString (builtin call ending with strings) exceeded maximum string length of %i chars", sizeof(buffer[0]));
//#endif
strcat (out, s);
}
}
return out;
@ -3268,7 +3273,7 @@ void PF_findradius (progfuncs_t *prinst, struct globalvars_s *pr_globals)
ent = EDICT_NUM(svprogfuncs, i);
if (ent->isfree)
continue;
if (ent->v->solid == SOLID_NOT)
if (ent->v->solid == SOLID_NOT && (progstype != PROG_QW || !((int)ent->v->flags & FL_FINDABLE_NONSOLID)))
continue;
for (j=0 ; j<3 ; j++)
eorg[j] = org[j] - (ent->v->origin[j] + (ent->v->mins[j] + ent->v->maxs[j])*0.5);
@ -3338,8 +3343,8 @@ void PF_printv (progfuncs_t *prinst, struct globalvars_s *pr_globals)
Con_Printf (PR_GetStringOfs(prinst, OFS_PARM0),temp);
}
#define MAX_TEMPSTRS 16
#define MAXTEMPBUFFERLEN 4096
#define MAX_TEMPSTRS ((int)pr_tempstringcount.value)
#define MAXTEMPBUFFERLEN ((int)pr_tempstringsize.value)
char *PF_TempStr(progfuncs_t *prinst)
{
if (prinst->tempstringnum == MAX_TEMPSTRS)
@ -3356,6 +3361,13 @@ string_t PR_TempString(progfuncs_t *prinst, char *str)
void PF_InitTempStrings(progfuncs_t *prinst)
{
if (pr_tempstringcount.value < 2)
pr_tempstringcount.value = 2;
if (pr_tempstringsize.value < 256)
pr_tempstringsize.value = 256;
pr_tempstringcount.flags |= CVAR_NOSET;
pr_tempstringsize.flags |= CVAR_NOSET;
prinst->tempstringbase = prinst->AddString(prinst, "", MAXTEMPBUFFERLEN*MAX_TEMPSTRS);
prinst->tempstringnum = 0;
}
@ -3827,11 +3839,14 @@ void PF_lightstyle (progfuncs_t *prinst, struct globalvars_s *pr_globals)
continue;
if ( client->state == cs_spawned )
{
if (style >= MAX_STANDARDLIGHTSTYLES)
if (!*val)
continue;
#ifdef PEXT_LIGHTSTYLECOL
if (client->fteprotocolextensions & PEXT_LIGHTSTYLECOL && col!=7)
{
ClientReliableWrite_Begin (client, svc_lightstylecol, strlen(val)+4);
ClientReliableWrite_Char (client, style);
ClientReliableWrite_Byte (client, style);
ClientReliableWrite_Char (client, col);
ClientReliableWrite_String (client, val);
}
@ -3839,7 +3854,7 @@ void PF_lightstyle (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
#endif
ClientReliableWrite_Begin (client, svc_lightstyle, strlen(val)+3);
ClientReliableWrite_Char (client, style);
ClientReliableWrite_Byte (client, style);
ClientReliableWrite_String (client, val);
#ifdef PEXT_LIGHTSTYLECOL
}
@ -5475,6 +5490,8 @@ static int chrconv_number(int i, int base, int conv)
switch (conv)
{
default:
case 5:
case 6:
case 0:
break;
case 1:
@ -5509,7 +5526,7 @@ static int chrconv_punct(int i, int base, int conv)
}
return i + base;
}
static int chrchar_alpha(int i, int basec, int baset, int convc, int convt)
static int chrchar_alpha(int i, int basec, int baset, int convc, int convt, int charnum)
{
//convert case and colour seperatly...
@ -5525,6 +5542,11 @@ static int chrchar_alpha(int i, int basec, int baset, int convc, int convt)
case 2:
baset = 128;
break;
case 5:
case 6:
baset = 128*((charnum&1) == (convt-5));
break;
}
switch (convc)
@ -5570,13 +5592,13 @@ void PF_strconv (progfuncs_t *prinst, struct globalvars_s *pr_globals)
*result = chrconv_number(*string, '0'-30, redchars);
else if (*string >= 'a' && *string <= 'z') //normal numbers...
*result = chrchar_alpha(*string, 0, 'a', ccase, redchars);
*result = chrchar_alpha(*string, 'a', 0, ccase, redchars, i);
else if (*string >= 'A' && *string <= 'Z') //normal numbers...
*result = chrchar_alpha(*string, 0, 'A', ccase, redchars);
*result = chrchar_alpha(*string, 'A', 0, ccase, redchars, i);
else if (*string >= 'a'+128 && *string <= 'z'+128) //normal numbers...
*result = chrchar_alpha(*string, 128, 'a', ccase, redchars);
*result = chrchar_alpha(*string, 'a', 128, ccase, redchars, i);
else if (*string >= 'A'+128 && *string <= 'Z'+128) //normal numbers...
*result = chrchar_alpha(*string, 128, 'A', ccase, redchars);
*result = chrchar_alpha(*string, 'A', 128, ccase, redchars, i);
else if ((*string & 127) < 16 || !redalpha) //special chars..
*result = *string;
@ -6169,6 +6191,7 @@ lh_extension_t QSG_Extensions[] = {
#ifdef SVCHAT
{"FTE_NPCCHAT", 1, NULL, {"chat"}}, //server looks at chat files. It automagically branches through calling qc functions as requested.
#endif
{"FTE_QC_CHECKPVS", 1, NULL, {"checkpvs"}},
{"FTE_QC_MATCHCLIENTNAME", 1, NULL, {"matchclient"}},
{"FTE_SOLID_LADDER"}, //part of a worthy hl implementation. Allows a simple trigger to remove effects of gravity (solid 20)
@ -6530,7 +6553,7 @@ void PF_strpad (progfuncs_t *prinst, struct globalvars_s *pr_globals)
Q_strncpyz(dest, src, MAXTEMPBUFFERLEN);
dest+=strlen(dest);
while(pad)
while(pad-->0)
*dest++ = ' ';
*dest = '\0';
}
@ -8821,6 +8844,120 @@ void PF_runclientphys(progfuncs_t *prinst, struct globalvars_s *pr_globals)
PM_PlayerMove(sv.gamespeed);
}
//DP_QC_GETSURFACE
// #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
void PF_getsurfacenumpoints(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int surfnum;
model_t *model;
int modelindex;
edict_t *ent;
ent = G_EDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
modelindex = ent->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS)
model = sv.models[(int)ent->v->modelindex];
else
model = NULL;
if (!model || surfnum >= model->numsurfaces)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = model->surfaces[surfnum].mesh->numvertexes;
}
// #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
void PF_getsurfacepoint(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int surfnum, pointnum;
model_t *model;
int modelindex;
edict_t *ent;
ent = G_EDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
pointnum = G_FLOAT(OFS_PARM2);
modelindex = ent->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS)
model = sv.models[(int)ent->v->modelindex];
else
model = NULL;
if (!model || surfnum >= model->numsurfaces)
{
G_FLOAT(OFS_RETURN+0) = 0;
G_FLOAT(OFS_RETURN+1) = 0;
G_FLOAT(OFS_RETURN+2) = 0;
}
else
{
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->xyz_array[pointnum][2];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->xyz_array[pointnum][2];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].mesh->xyz_array[pointnum][2];
}
}
// #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
void PF_getsurfacenormal(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int surfnum, pointnum;
model_t *model;
int modelindex;
edict_t *ent;
ent = G_EDICT(prinst, OFS_PARM0);
surfnum = G_FLOAT(OFS_PARM1);
pointnum = G_FLOAT(OFS_PARM2);
modelindex = ent->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS)
model = sv.models[(int)ent->v->modelindex];
else
model = NULL;
if (!model || surfnum >= model->numsurfaces)
{
G_FLOAT(OFS_RETURN+0) = 0;
G_FLOAT(OFS_RETURN+1) = 0;
G_FLOAT(OFS_RETURN+2) = 0;
}
else
{
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].plane->normal[0];
G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].plane->normal[1];
G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].plane->normal[2];
if (model->surfaces[surfnum].flags & SURF_PLANEBACK)
VectorInverse(G_VECTOR(OFS_RETURN));
}
}
// #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
void PF_getsurfacetexture(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
}
// #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
void PF_getsurfacenearpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
}
// #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
void PF_getsurfaceclippedpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
}
//#240 float(vector viewpos, entity viewee) checkpvs (FTE_QC_CHECKPVS)
//note: this requires a correctly setorigined entity.
void PF_checkpvs(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *viewpos = G_VECTOR(OFS_PARM0);
edict_t *ent = G_EDICT(prinst, OFS_PARM1);
//FIXME: Make all alternatives of FatPVS not recalulate the pvs.
//and yeah, this is overkill what with the whole fat thing and all.
sv.worldmodel->funcs.FatPVS(sv.worldmodel, viewpos, false);
G_FLOAT(OFS_RETURN) = sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, ent);
}
//entity(string match [, float matchnum]) matchclient = #241;
void PF_matchclient(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -9155,6 +9292,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"isbackbuffered", PF_isbackbuffered, 0, 0, 0, 234},
{"te_bloodqw", PF_te_bloodqw, 0, 0, 0, 239},
{"checkpvs", PF_checkpvs, 0, 0, 0, 240},
{"matchclientname", PF_matchclient, 0, 0, 0, 241},
//end fte extras
@ -9213,14 +9351,14 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"vectorvectors", PF_vectorvectors, 0, 0, 0, 432},// #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
{"te_plasmaburn", PF_te_plasmaburn, 0, 0, 0, 433},// #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
/*
{"getsurfacenumpoints",PF_getsurfacenumpoints,0,0, 0, 434},// #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
{"getsurfacepoint",PF_getsurfacepoint, 0, 0, 0, 435},// #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
{"getsurfacenormal",PF_getsurfacenormal,0, 0, 0, 436},// #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
{"getsurfacetexture",PF_getsurfacetexture,0, 0, 0, 437},// #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
// {"getsurfacetexture",PF_getsurfacetexture,0, 0, 0, 437},// #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
{"getsurfacenearpoint",PF_getsurfacenearpoint,0,0, 0, 438},// #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
{"getsurfaceclippedpoint",PF_getsurfaceclippedpoint,0,0,0, 439},// #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
*/
//KRIMZON_SV_PARSECLIENTCOMMAND
{"clientcommand", PF_clientcommand, 0, 0, 0, 440},// #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
{"tokenize", PF_Tokenize, 0, 0, 0, 441},// #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)

View File

@ -784,6 +784,7 @@ typedef struct
#define FL_PARTIALGROUND 1024 // not all corners are valid
#define FL_WATERJUMP 2048 // player jumping out of water
#define FL_FINDABLE_NONSOLID 16384 //a cpqwsv feature
#define FL_MOVECHAIN_ANGLE 32768 // when in a move chain, will update the angle
#define FL_CLASS_DEPENDENT 2097152

View File

@ -1179,6 +1179,25 @@ void SV_Serverinfo_f (void)
if (Cmd_Argv(1)[0] == '*')
{
if (!strcmp(Cmd_Argv(1), "*"))
if (!strcmp(Cmd_Argv(2), ""))
{ //clear it out
char *k;
for(i=0;;)
{
k = Info_KeyForNumber(svs.info, i);
if (!*k)
break; //no more.
else if (*k == '*')
i++; //can't remove * keys
else if ((var = Cvar_FindVar(k)) && var->flags&CVAR_SERVERINFO)
i++; //this one is a cvar.
else
Info_RemoveKey(svs.info, k); //we can remove this one though, so yay.
}
return;
}
Con_TPrintf (TL_STARKEYPROTECTED);
return;
}
@ -1233,6 +1252,12 @@ void SV_Localinfo_f (void)
if (Cmd_Argv(1)[0] == '*')
{
if (!strcmp(Cmd_Argv(1), "*"))
if (!strcmp(Cmd_Argv(2), ""))
{ //clear it out
Info_RemoveNonStarKeys(localinfo);
return;
}
Con_TPrintf (TL_STARKEYPROTECTED);
return;
}
@ -1272,8 +1297,10 @@ void SV_SaveInfo(FILE *f, char *info, char *commandname)
void SV_SaveInfos(FILE *f)
{
fwrite("\n", 1, 1, f);
fwrite("serverinfo * \"\"\n", 16, 1, f);
SV_SaveInfo(f, svs.info, "serverinfo");
fwrite("\n", 1, 1, f);
fwrite("localinfo * \"\"\n", 15, 1, f);
SV_SaveInfo(f, localinfo, "localinfo");
}

View File

@ -782,7 +782,7 @@ void SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *
// flag
#define E5_FRAME16 (1<<21)
// unused
#define E5_UNUSED22 (1<<22)
#define E5_COLORMOD (1<<22)
// bits >= (1<<24)
#define E5_EXTEND3 (1<<23)
@ -803,8 +803,6 @@ void SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *
// bits2 > 0
#define E5_EXTEND4 (1<<31)
void SVDP_EmitEntity(entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean isnew)
{
int bits;
@ -847,8 +845,8 @@ void SVDP_EmitEntity(entity_state_t *from, entity_state_t *to, sizebuf_t *msg, q
bits |= E5_LIGHT;
if (from->glowsize != to->glowsize || from->glowcolour != to->glowcolour)
bits |= E5_GLOW;
// if (from->colormod[0] != to->colormod[0] || o->colormod[1] != to->colormod[1] || o->colormod[2] != to->colormod[2])
// bits |= E5_COLORMOD;
if (from->colormod[0] != to->colormod[0] || from->colormod[1] != to->colormod[1] || from->colormod[2] != to->colormod[2])
bits |= E5_COLORMOD;
if ((bits & E5_ORIGIN) && (/*!(to->flags & RENDER_LOWPRECISION) ||*/ to->origin[0] < -4096 || to->origin[0] >= 4096 || to->origin[1] < -4096 || to->origin[1] >= 4096 || to->origin[2] < -4096 || to->origin[2] >= 4096))
bits |= E5_ORIGIN32;
@ -968,12 +966,12 @@ void SVDP_EmitEntity(entity_state_t *from, entity_state_t *to, sizebuf_t *msg, q
MSG_WriteByte(msg, to->glowsize);
MSG_WriteByte(msg, to->glowcolour);
}
// if (bits & E5_COLORMOD)
// {
// MSG_WriteByte(msg, to->colormod[0]);
// MSG_WriteByte(msg, to->colormod[1]);
// MSG_WriteByte(msg, to->colormod[2]);
// }
if (bits & E5_COLORMOD)
{
MSG_WriteByte(msg, to->colormod[0]);
MSG_WriteByte(msg, to->colormod[1]);
MSG_WriteByte(msg, to->colormod[2]);
}
}
entity_state_t defaultstate;

View File

@ -71,15 +71,15 @@ typedef struct svm_server_s {
} svm_server_t;
typedef struct {
int socketudp;
float time;
int port;
int socketudp;
svm_server_t *firstserver;
int numservers;
} masterserver_t;
masterserver_t svm;
masterserver_t svm = {INVALID_SOCKET};
void SVM_RemoveOldServers(void)
{
@ -155,14 +155,17 @@ void SVM_Heartbeat(netadr_t *adr, int numclients, float validuntil)
void SVM_Init(int port)
{
if (!svm.socketudp)
if (svm.socketudp == INVALID_SOCKET)
svm.socketudp = UDP_OpenSocket(port, false);
}
void SVM_ShutDown (void)
{
if (svm.socketudp)
if (svm.socketudp != INVALID_SOCKET)
{
UDP_CloseSocket(svm.socketudp);
svm.socketudp = INVALID_SOCKET;
}
}
void SVM_Think(int port)
@ -187,11 +190,14 @@ void SVM_Think(int port)
addrlen = sizeof(addr);
net_message.cursize = recvfrom(svm.socketudp, net_message_buffer, sizeof(net_message_buffer)-1, 0, (struct sockaddr *)&addr, &addrlen);
net_message.data[net_message.cursize] = '\0'; //null term all strings.
if (net_message.cursize < 0)
if (net_message.cursize <= 0)
{
addrlen = WSAGetLastError();
return;
}
net_message.data[net_message.cursize] = '\0'; //null term all strings.
SockadrToNetadr(&addr, &netaddr);
svm.time = Sys_DoubleTime();

View File

@ -989,13 +989,13 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
// every now and then, send an update so that extrapolation
// on client side doesn't stray too far off
if (ISQWCLIENT(client))
if (client->zquake_extensions & Z_EXT_SERVERTIME && sv.time - client->nextservertimeupdate > 0)
if (client->zquake_extensions & Z_EXT_SERVERTIME && sv.physicstime - client->nextservertimeupdate > 0)
{
MSG_WriteByte (msg, svc_updatestatlong);
MSG_WriteByte (msg, STAT_TIME);
MSG_WriteLong (msg, (int)(sv.time * 1000));
MSG_WriteLong (msg, (int)(sv.physicstime * 1000));
client->nextservertimeupdate = sv.time+10;
client->nextservertimeupdate = sv.physicstime;//+10;
}
#ifdef NQPROT

View File

@ -1101,28 +1101,35 @@ void SV_Spawn_f (void)
{
if (sv.democausesreconnect)
{
if (i >= MAX_STANDARDLIGHTSTYLES)
continue;
ClientReliableWrite_Begin (host_client, svc_lightstyle,
3 + (sv.demolightstyles[i] ? strlen(sv.demolightstyles[i]) : 1));
ClientReliableWrite_Byte (host_client, (char)i);
ClientReliableWrite_String (host_client, sv.demolightstyles[i]);
}
else
{
if (i >= MAX_STANDARDLIGHTSTYLES)
if (!sv.lightstyles[i])
continue;
#ifdef PEXT_LIGHTSTYLECOL
if (host_client->fteprotocolextensions & PEXT_LIGHTSTYLECOL && sv.lightstylecolours[i]!=7)
{
ClientReliableWrite_Begin (host_client, svc_lightstylecol,
3 + (sv.lightstyles[i] ? strlen(sv.lightstyles[i]) : 1));
ClientReliableWrite_Byte (host_client, (char)i);
ClientReliableWrite_Char (host_client, sv.lightstylecolours[i]);
ClientReliableWrite_String (host_client, sv.lightstyles[i]);
}
else
if (host_client->fteprotocolextensions & PEXT_LIGHTSTYLECOL && sv.lightstylecolours[i]!=7)
{
ClientReliableWrite_Begin (host_client, svc_lightstylecol,
3 + (sv.lightstyles[i] ? strlen(sv.lightstyles[i]) : 1));
ClientReliableWrite_Byte (host_client, (char)i);
ClientReliableWrite_Char (host_client, sv.lightstylecolours[i]);
ClientReliableWrite_String (host_client, sv.lightstyles[i]);
}
else
#endif
{
ClientReliableWrite_Begin (host_client, svc_lightstyle,
3 + (sv.lightstyles[i] ? strlen(sv.lightstyles[i]) : 1));
ClientReliableWrite_Byte (host_client, (char)i);
ClientReliableWrite_String (host_client, sv.lightstyles[i]);
{
ClientReliableWrite_Begin (host_client, svc_lightstyle,
3 + (sv.lightstyles[i] ? strlen(sv.lightstyles[i]) : 1));
ClientReliableWrite_Byte (host_client, (char)i);
ClientReliableWrite_String (host_client, sv.lightstyles[i]);
}
}
}

View File

@ -588,7 +588,7 @@ Build a client frame structure
=============================================================================
*/
qbyte fatpvs[(MAX_MAP_LEAFS+1)/4];
extern qbyte fatpvs[(MAX_MAP_LEAFS+1)/4];
/*
=============

View File

@ -6,7 +6,7 @@
#ifdef Q3SERVER
//#define USEBOTLIB
#define USEBOTLIB
#ifdef USEBOTLIB
@ -24,8 +24,43 @@
#define Z_TAG_BOTLIB 221726
#ifdef _WIN32
#if 0
#pragma comment (lib, "botlib.lib")
#define FTE_GetBotLibAPI GetBotLibAPI
#else
botlib_export_t *FTE_GetBotLibAPI( int apiVersion, botlib_import_t *import )
{
botlib_export_t *(*QDECL pGetBotLibAPI)( int apiVersion, botlib_import_t *import );
#pragma comment (lib, "H:/quake/quake3/quake3-1.32b/code/botlib/botlib_vc6/Debug/botlib_vc6.lib")
static HINSTANCE hmod;
if (!hmod)
hmod = LoadLibrary("botlib.dll");
if (!hmod)
return NULL;
pGetBotLibAPI = (void*)GetProcAddress(hmod, "GetBotLibAPI");
if (!pGetBotLibAPI)
return NULL;
return pGetBotLibAPI(apiVersion, import);
}
#endif
#elif defined(__linux__)
#include "dlopen.h"
botlib_export_t *FTE_GetBotLibAPI( int apiVersion, botlib_import_t *import )
{
void *handle;
dlopen();
}
#else
botlib_export_t *FTE_GetBotLibAPI(int version, int apiVersion, botlib_import_t *import)
{ //a stub that will prevent botlib from loading.
return NULL;
}
#endif
botlib_export_t *botlib;
@ -1751,7 +1786,7 @@ void SV_InitBotLib()
// Z_FreeTags(Z_TAG_BOTLIB);
botlibmemoryavailable = 1024*1024*16;
botlib = GetBotLibAPI(BOTLIB_API_VERSION, &import);
botlib = FTE_GetBotLibAPI(BOTLIB_API_VERSION, &import);
if (!botlib)
{
bot_enable->flags |= CVAR_LATCH;
@ -1773,10 +1808,14 @@ void SV_InitBotLib()
qboolean SVQ3_InitGame(void)
{
char buffer[8192];
extern cvar_t progs;
if (sv.worldmodel->fromgame == fg_quake)
return false; //always fail on q1bsp
if (*progs.string) //don't load q3 gamecode if we're explicitally told to load a progs.
return false;
SVQ3_ShutdownGame();
@ -1826,7 +1865,8 @@ void SVQ3_RunFrame(void)
{
VM_Call(q3gamevm, GAME_RUN_FRAME, (int)(sv.time*1000));
#ifdef USEBOTLIB
VM_Call(q3gamevm, BOTAI_START_FRAME, (int)(sv.time*1000));
if (botlib)
VM_Call(q3gamevm, BOTAI_START_FRAME, (int)(sv.time*1000));
#endif
}

View File

@ -1498,6 +1498,85 @@ void SVQ2_ClipMoveToEntities ( moveclip_t *clip, int contentsmask )
#endif
//===========================================================================
/*
====================
SV_ClipToEverything
like SV_ClipToLinks, but doesn't use the links part. This can be used for checking triggers, solid entities, not-solid entities.
Sounds pointless, I know.
====================
*/
void SV_ClipToEverything (moveclip_t *clip)
{
int e;
trace_t trace;
edict_t *touch;
for (e=1 ; e<sv.num_edicts ; e++)
{
touch = EDICT_NUM(svprogfuncs, e);
if (touch->isfree)
continue;
if (touch->v->solid == SOLID_NOT && !((int)touch->v->flags & FL_FINDABLE_NONSOLID))
continue;
if (touch->v->solid == SOLID_TRIGGER && !((int)touch->v->flags & FL_FINDABLE_NONSOLID))
continue;
if (touch == clip->passedict)
continue;
if (clip->type & MOVE_NOMONSTERS && touch->v->solid != SOLID_BSP)
continue;
if (clip->passedict)
{
// don't clip corpse against character
if (clip->passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE))
continue;
// don't clip character against corpse
if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE)
continue;
if (!((int)clip->passedict->v->dimension_hit & (int)touch->v->dimension_solid))
continue;
}
if (clip->boxmins[0] > touch->v->absmax[0]
|| clip->boxmins[1] > touch->v->absmax[1]
|| clip->boxmins[2] > touch->v->absmax[2]
|| clip->boxmaxs[0] < touch->v->absmin[0]
|| clip->boxmaxs[1] < touch->v->absmin[1]
|| clip->boxmaxs[2] < touch->v->absmin[2] )
continue;
if (clip->passedict && clip->passedict->v->size[0] && !touch->v->size[0])
continue; // points never interact
// might intersect, so do an exact clip
if (clip->trace.allsolid)
return;
if (clip->passedict)
{
if (PROG_TO_EDICT(svprogfuncs, touch->v->owner) == clip->passedict)
continue; // don't clip against own missiles
if (PROG_TO_EDICT(svprogfuncs, clip->passedict->v->owner) == touch)
continue; // don't clip against owner
}
if ((int)touch->v->flags & FL_MONSTER)
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
else
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction)
{
trace.ent = touch;
clip->trace = trace;
}
}
}
/*
====================
SV_ClipToLinks
@ -1511,6 +1590,71 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip )
edict_t *touch;
trace_t trace;
if (clip->type & MOVE_TRIGGERS)
{
for (l = node->trigger_edicts.next ; l != &node->trigger_edicts ; l = next)
{
next = l->next;
touch = EDICT_FROM_AREA(l);
if (!((int)touch->v->flags & FL_FINDABLE_NONSOLID))
continue;
if (touch->v->solid != SOLID_TRIGGER)
continue;
if (touch == clip->passedict)
continue;
if (clip->type & MOVE_NOMONSTERS && touch->v->solid != SOLID_BSP)
continue;
if (clip->passedict)
{
/* These can never happen, touch is a SOLID_TRIGGER
// don't clip corpse against character
if (clip->passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE))
continue;
// don't clip character against corpse
if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE)
continue;
*/
if (!((int)clip->passedict->v->dimension_hit & (int)touch->v->dimension_solid))
continue;
}
if (clip->boxmins[0] > touch->v->absmax[0]
|| clip->boxmins[1] > touch->v->absmax[1]
|| clip->boxmins[2] > touch->v->absmax[2]
|| clip->boxmaxs[0] < touch->v->absmin[0]
|| clip->boxmaxs[1] < touch->v->absmin[1]
|| clip->boxmaxs[2] < touch->v->absmin[2] )
continue;
if (clip->passedict && clip->passedict->v->size[0] && !touch->v->size[0])
continue; // points never interact
// might intersect, so do an exact clip
if (clip->trace.allsolid)
return;
if (clip->passedict)
{
if (PROG_TO_EDICT(svprogfuncs, touch->v->owner) == clip->passedict)
continue; // don't clip against own missiles
if (PROG_TO_EDICT(svprogfuncs, clip->passedict->v->owner) == touch)
continue; // don't clip against owner
}
if ((int)touch->v->flags & FL_MONSTER)
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
else
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction)
{
trace.ent = touch;
clip->trace = trace;
}
}
}
// touch linked edicts
for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next)
{
@ -1754,12 +1898,9 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs );
// clip to entities
/*#ifdef Q2BSPS
if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3)
SV_ClipMoveToEntities(&clip);
if (clip.type & MOVE_EVERYTHING)
SV_ClipToEverything (&clip);
else
#endif
*/
SV_ClipToLinks ( sv_areanodes, &clip );
if (clip.trace.startsolid)