#include "quakedef.h"
cvar_t chase_back = {CVAR_SAVE, "chase_back", "48"};
-cvar_t chase_up = {CVAR_SAVE, "chase_up", "48"};
+cvar_t chase_up = {CVAR_SAVE, "chase_up", "24"};
cvar_t chase_active = {CVAR_SAVE, "chase_active", "0"};
void Chase_Init (void)
for (i=0 ; i<3 ; i++)
MSG_WriteAngle (&buf, cl.viewangles[i]);
}
-
+
MSG_WriteShort (&buf, forwardmove);
MSG_WriteShort (&buf, sidemove);
MSG_WriteShort (&buf, upmove);
// send button bits
//
bits = 0;
-
+
if ( in_attack.state & 3 )
bits |= 1;
in_attack.state &= ~2;
-
+
if (in_jump.state & 3)
bits |= 2;
in_jump.state &= ~2;
if (in_button6.state & 3) bits |= 32;in_button6.state &= ~2;
if (in_button7.state & 3) bits |= 64;in_button7.state &= ~2;
if (in_button8.state & 3) bits |= 128;in_button8.state &= ~2;
-
+
MSG_WriteByte (&buf, bits);
MSG_WriteByte (&buf, in_impulse);
in_impulse = 0;
+ // LordHavoc: should we ack this on receipt instead? would waste net bandwidth though
+ i = EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase);
+ if (i > 0)
+ {
+ MSG_WriteByte (&buf, clc_ackentities);
+ MSG_WriteLong (&buf, i);
+ }
+
//
// deliver the message
//
*/
static float CL_LerpPoint (void)
{
- float f, frac;
+ float f;
- f = cl.mtime[0] - cl.mtime[1];
+ // dropped packet, or start of demo
+ if (cl.mtime[1] < cl.mtime[0] - 0.1)
+ cl.mtime[1] = cl.mtime[0] - 0.1;
+
+ cl.time = bound(cl.mtime[1], cl.time, cl.mtime[0]);
// LordHavoc: lerp in listen games as the server is being capped below the client (usually)
+ f = cl.mtime[0] - cl.mtime[1];
if (!f || cl_nolerp.integer || cls.timedemo || (sv.active && svs.maxclients == 1))
{
cl.time = cl.mtime[0];
return 1;
}
- if (f > 0.1)
- { // dropped packet, or start of demo
- cl.mtime[1] = cl.mtime[0] - 0.1;
- f = 0.1;
- }
- frac = (cl.time - cl.mtime[1]) / f;
-// Con_Printf ("frac: %f\n",frac);
- if (frac < 0)
- {
- if (frac < -0.01)
- {
- cl.time = cl.mtime[1];
-// Con_Printf ("low frac\n");
- }
- frac = 0;
- }
- else if (frac > 1)
- {
- if (frac > 1.01)
- {
- cl.time = cl.mtime[0];
-// Con_Printf ("high frac\n");
- }
- frac = 1;
- }
-
- return frac;
+ f = (cl.time - cl.mtime[1]) / f;
+ return bound(0, f, 1);
}
static void CL_RelinkStaticEntities(void)
else
bobjoffset = 0;
- CL_RelinkStaticEntities();
-
// start on the entity after the world
for (i = 1, ent = cl_entities + 1;i < MAX_EDICTS /*cl.num_entities*/;i++, ent++)
{
}
}
-static void CL_LerpPlayerVelocity (void)
+void CL_LerpPlayerEye(float frac)
{
- int i;
- float frac, d;
+ if (cl.entitydatabase.numframes)
+ {
+ cl.viewentorigin[0] = cl.viewentoriginold[0] + frac * (cl.viewentoriginnew[0] - cl.viewentoriginold[0]);
+ cl.viewentorigin[1] = cl.viewentoriginold[1] + frac * (cl.viewentoriginnew[1] - cl.viewentoriginold[1]);
+ cl.viewentorigin[2] = cl.viewentoriginold[2] + frac * (cl.viewentoriginnew[2] - cl.viewentoriginold[2]);
+ }
+ else
+ VectorCopy (cl_entities[cl.viewentity].render.origin, cl.viewentorigin);
+}
- // fraction from previous network update to current
- frac = CL_LerpPoint ();
+static void CL_LerpPlayerVelocity (float frac)
+{
+ int i;
+ float d;
for (i = 0;i < 3;i++)
cl.velocity[i] = cl.mvelocity[1][i] + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]);
void CL_RelinkEntities (void)
{
+ float frac;
+
+ // fraction from previous network update to current
+ frac = CL_LerpPoint ();
+
CL_DecayLights ();
- CL_LerpPlayerVelocity();
+ CL_RelinkStaticEntities();
CL_RelinkNetworkEntities();
TraceLine_ScanForBModels();
CL_RelinkEffects();
CL_MoveParticles();
CL_UpdateTEnts();
+
+ CL_LerpPlayerEye(frac);
+ CL_LerpPlayerVelocity(frac);
}
"svc_updatecolors", // [byte] [byte]
"svc_particle", // [vec3] <variable>
"svc_damage", // [byte] impact [byte] blood [vec3] from
-
+
"svc_spawnstatic",
"OBSOLETE svc_spawnbinary",
"svc_spawnbaseline",
}
qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
-qboolean dpprotocol; // LordHavoc: whether or not the current network stream is the enhanced DarkPlaces protocol
+int dpprotocol; // LordHavoc: version of network protocol, or 0 if not DarkPlaces
/*
===============
// parse protocol version number
i = MSG_ReadLong ();
- if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
+ if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != 250)
{
- Con_Printf ("Server returned version %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
+ Con_Printf ("Server is protocol %i, not %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, PROTOCOL_VERSION);
return;
}
Nehahrademcompatibility = false;
Nehahrademcompatibility = true;
if (cls.demoplayback && demo_nehahra.integer)
Nehahrademcompatibility = true;
- dpprotocol = i == DPPROTOCOL_VERSION;
+ dpprotocol = i;
+ if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2)
+ dpprotocol = 0;
// parse maxclients
cl.maxclients = MSG_ReadByte ();
entity_t *ent;
entity_state_t new;
- if (cls.signon == SIGNONS - 1)
- { // first update is the final signon stage
- cls.signon = SIGNONS;
- CL_SignonReply ();
- }
-
if (bits & U_MOREBITS)
bits |= (MSG_ReadByte()<<8);
if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
}
}
+void CL_ReadEntityFrame(void)
+{
+ entity_t *ent;
+ entity_state_t *s;
+ entity_frame_t entityframe;
+ int i;
+ EntityFrame_Read(&cl.entitydatabase);
+ EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
+ for (i = 0;i < entityframe.numentities;i++)
+ {
+ s = &entityframe.entitydata[i];
+ entkill[s->number] = 0;
+ ent = &cl_entities[s->number];
+ memcpy(&ent->state_previous, &ent->state_current, sizeof(*s));
+ memcpy(&ent->state_current, s, sizeof(*s));
+ ent->state_current.time = cl.mtime[0];
+ }
+ VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
+ VectorCopy(entityframe.eye, cl.viewentoriginnew);
+}
+
char *bitprofilenames[32] =
{
"U_MOREBITS",
else
cl.punchangle[i] = 0;
if (bits & (SU_PUNCHVEC1<<i))
- cl.punchvector[i] = MSG_ReadFloatCoord();
+ cl.punchvector[i] = MSG_ReadCoord();
else
cl.punchvector[i] = 0;
if (bits & (SU_VELOCITY1<<i) )
sound_num = MSG_ReadByte ();
vol = MSG_ReadByte ();
atten = MSG_ReadByte ();
-
+
S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
}
byte cmdlog[32];
char *cmdlogname[32], *temp;
int cmdindex, cmdcount = 0;
-
+
//
// if recording demos, copy the message out
//
Con_Printf ("%i ",net_message.cursize);
else if (cl_shownet.integer == 2)
Con_Printf ("------------------\n");
-
- cl.onground = false; // unless the server says otherwise
+
+ cl.onground = false; // unless the server says otherwise
//
// parse the message
//
entitiesupdated = false;
CL_EntityUpdateSetup();
-
+
while (1)
{
if (msg_badread)
temp = "entity";
cmdlogname[cmdindex] = temp;
SHOWNET("fast update");
+ if (cls.signon == SIGNONS - 1)
+ { // first update is the final signon stage
+ cls.signon = SIGNONS;
+ CL_SignonReply ();
+ }
CL_ParseUpdate (cmd&127);
continue;
}
case svc_version:
i = MSG_ReadLong ();
- if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
- Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
+ if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != 250)
+ Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, PROTOCOL_VERSION);
Nehahrademcompatibility = false;
if (i == 250)
Nehahrademcompatibility = true;
if (cls.demoplayback && demo_nehahra.integer)
Nehahrademcompatibility = true;
- dpprotocol = i == DPPROTOCOL_VERSION;
+ dpprotocol = i;
+ if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2)
+ dpprotocol = 0;
break;
-
+
case svc_disconnect:
Host_EndGame ("Server disconnected\n");
CL_ParseServerInfo ();
// vid.recalc_refdef = true; // leave intermission full screen
break;
-
+
case svc_setangle:
for (i=0 ; i<3 ; i++)
cl.viewangles[i] = MSG_ReadAngle ();
break;
-
+
case svc_setview:
cl.viewentity = MSG_ReadShort ();
break;
-
+
case svc_lightstyle:
i = MSG_ReadByte ();
if (i >= MAX_LIGHTSTYLES)
if (i >= cl.maxclients)
Host_Error ("CL_ParseServerMessage: svc_updatefrags >= MAX_SCOREBOARD");
cl.scores[i].frags = MSG_ReadShort ();
- break;
+ break;
case svc_updatecolors:
i = MSG_ReadByte ();
Host_Error ("CL_ParseServerMessage: svc_updatecolors >= MAX_SCOREBOARD");
cl.scores[i].colors = MSG_ReadByte ();
break;
-
+
case svc_particle:
CL_ParseParticleEffect ();
break;
else
CDAudio_Resume ();
break;
-
+
case svc_signonnum:
i = MSG_ReadByte ();
if (i <= cls.signon)
cl.intermission = 3;
cl.completed_time = cl.time;
// vid.recalc_refdef = true; // go to full screen
- SCR_CenterPrint (MSG_ReadString ());
+ SCR_CenterPrint (MSG_ReadString ());
break;
case svc_sellscreen:
CL_CGVM_ParseNetwork(cgamenetbuffer, length);
}
break;
+ case svc_entities:
+ if (cls.signon == SIGNONS - 1)
+ { // first update is the final signon stage
+ cls.signon = SIGNONS;
+ CL_SignonReply ();
+ }
+ CL_ReadEntityFrame();
+ break;
}
}
// frag scoreboard
scoreboard_t *scores; // [cl.maxclients]
+
+ vec3_t viewentorigin;
+
+ // entity database stuff
+ vec3_t viewentoriginold, viewentoriginnew;
+ entity_database_t entitydatabase;
}
client_state_t;
SZ_Write (sb, s, strlen(s)+1);
}
-// used by server (always dpprotocol)
-// moved to common.h as #define
-/*
-void MSG_WriteFloatCoord (sizebuf_t *sb, float f)
+// used by server (always latest dpprotocol)
+void MSG_WriteDPCoord (sizebuf_t *sb, float f)
{
- MSG_WriteFloat(sb, f);
+ if (f >= 0)
+ MSG_WriteShort (sb, (int)(f + 0.5f));
+ else
+ MSG_WriteShort (sb, (int)(f - 0.5f));
}
-*/
// used by client
void MSG_WriteCoord (sizebuf_t *sb, float f)
{
- if (dpprotocol)
+ if (dpprotocol == DPPROTOCOL_VERSION2)
+ {
+ if (f >= 0)
+ MSG_WriteShort (sb, (int)(f + 0.5f));
+ else
+ MSG_WriteShort (sb, (int)(f - 0.5f));
+ }
+ else if (dpprotocol == DPPROTOCOL_VERSION1)
MSG_WriteFloat(sb, f);
else
{
int MSG_ReadChar (void)
{
int c;
-
+
// LordHavoc: minor optimization
if (msg_readcount >= net_message.cursize)
// if (msg_readcount+1 > net_message.cursize)
msg_badread = true;
return -1;
}
-
+
c = (signed char)net_message.data[msg_readcount];
msg_readcount++;
int MSG_ReadByte (void)
{
int c;
-
+
// LordHavoc: minor optimization
if (msg_readcount >= net_message.cursize)
// if (msg_readcount+1 > net_message.cursize)
c = (unsigned char)net_message.data[msg_readcount];
msg_readcount++;
-
+
return c;
}
*/
msg_badread = true;
return -1;
}
-
+
c = (short)(net_message.data[msg_readcount]
+ (net_message.data[msg_readcount+1]<<8));
-
+
msg_readcount += 2;
-
+
return c;
}
int MSG_ReadLong (void)
{
int c;
-
+
if (msg_readcount+4 > net_message.cursize)
{
msg_badread = true;
+ (net_message.data[msg_readcount+1]<<8)
+ (net_message.data[msg_readcount+2]<<16)
+ (net_message.data[msg_readcount+3]<<24);
-
+
msg_readcount += 4;
-
+
return c;
}
float f;
int l;
} dat;
-
+
dat.b[0] = net_message.data[msg_readcount];
dat.b[1] = net_message.data[msg_readcount+1];
dat.b[2] = net_message.data[msg_readcount+2];
dat.b[3] = net_message.data[msg_readcount+3];
msg_readcount += 4;
-
+
dat.l = LittleLong (dat.l);
- return dat.f;
+ return dat.f;
}
char *MSG_ReadString (void)
{
static char string[2048];
int l,c;
-
+
l = 0;
do
{
string[l] = c;
l++;
} while (l < sizeof(string)-1);
-
+
string[l] = 0;
-
+
return string;
}
-// used by server (always dpprotocol)
-// moved to common.h as #define
-/*
-float MSG_ReadFloatCoord (void)
+// used by server (always latest dpprotocol)
+float MSG_ReadDPCoord (void)
{
- return MSG_ReadFloat();
+ return (signed short) MSG_ReadShort();
}
-*/
// used by client
float MSG_ReadCoord (void)
{
- if (dpprotocol)
+ if (dpprotocol == DPPROTOCOL_VERSION2)
+ return (signed short) MSG_ReadShort();
+ else if (dpprotocol == DPPROTOCOL_VERSION1)
return MSG_ReadFloat();
else
return MSG_ReadShort() * (1.0f/8.0f);
void MSG_WriteCoord (sizebuf_t *sb, float f);
void MSG_WriteAngle (sizebuf_t *sb, float f);
void MSG_WritePreciseAngle (sizebuf_t *sb, float f);
-
-#define MSG_WriteFloatCoord MSG_WriteFloat
+void MSG_WriteDPCoord (sizebuf_t *sb, float f);
extern int msg_readcount;
extern qboolean msg_badread; // set if a read goes beyond end of message
float MSG_ReadCoord (void);
//float MSG_ReadAngle (void);
-#define MSG_ReadFloatCoord MSG_ReadFloat
+float MSG_ReadDPCoord (void);
#define MSG_ReadAngle() (MSG_ReadByte() * (360.0f / 256.0f))
#define MSG_ReadPreciseAngle() (MSG_ReadShort() * (360.0f / 65536.0f))
#define MSG_ReadVector(v) {(v)[0] = MSG_ReadCoord();(v)[1] = MSG_ReadCoord();(v)[2] = MSG_ReadCoord();}
-extern qboolean dpprotocol;
+extern int dpprotocol;
//============================================================================
MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
for (i=0 ; i<3 ; i++)
- MSG_WriteFloatCoord(&sv.signon, pos[i]);
+ MSG_WriteDPCoord(&sv.signon, pos[i]);
if (large)
MSG_WriteShort (&sv.signon, soundnum);
void PF_WriteCoord (void)
{
- MSG_WriteFloatCoord (WriteDest(), G_FLOAT(OFS_PARM1));
+ MSG_WriteDPCoord (WriteDest(), G_FLOAT(OFS_PARM1));
}
void PF_WriteString (void)
MSG_WriteByte (&sv.signon, ent->v.skin);
for (i=0 ; i<3 ; i++)
{
- MSG_WriteFloatCoord(&sv.signon, ent->v.origin[i]);
+ MSG_WriteDPCoord(&sv.signon, ent->v.origin[i]);
MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_BLOOD);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
// velocity
MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
// min
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
// max
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
// speed
- MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
+ MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
// count
MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
// color
MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
// min
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
// max
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
// velocity
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
// count
MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
// color
// gravity true/false
MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
// randomvel
- MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
+ MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
}
void PF_te_particlerain (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
// min
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
// max
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
// velocity
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
// count
MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
// color
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
// min
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
// max
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
// velocity
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
// count
MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
// color
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SPARK);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
// velocity
MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_spikequad (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_superspikequad (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_explosionquad (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_smallflash (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_customflash (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
// radius
MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
// lifetime
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_spike (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SPIKE);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_superspike (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_explosion (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_tarexplosion (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_wizspike (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_knightspike (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_lavasplash (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_teleport (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_TELEPORT);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_te_explosion2 (void)
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
// origin
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
// color
MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
}
// owner entity
MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
// start
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
// end
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
}
void PF_te_lightning2 (void)
// owner entity
MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
// start
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
// end
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
}
void PF_te_lightning3 (void)
// owner entity
MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
// start
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
// end
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
}
void PF_te_beam (void)
// owner entity
MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
// start
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
// end
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
}
void PF_te_plasmaburn (void)
{
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
- MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
+ MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
}
void PF_Fixme (void)
qboolean free;
link_t area;
+#ifdef QUAKEENTITIES
entity_state_t baseline;
entity_state_t deltabaseline; // LordHavoc: previous frame
+#endif
float freetime; // sv.time when the object was freed
entvars_t v; // C exported fields from progs
void ClearStateToDefault(entity_state_t *s)
{
+ s->active = 0;
s->time = 0;
VectorClear(s->origin);
VectorClear(s->angles);
s->glowsize = 0;
s->glowcolor = 254;
s->flags = 0;
- s->active = 0;
}
// (server) clears the database to contain no frames (thus delta compression compresses against nothing)
void EntityFrame_ClearDatabase(entity_database_t *d)
{
memset(d, 0, sizeof(*d));
- d->ackframe = -1;
}
// (server and client) removes frames older than 'frame' from database
void EntityFrame_AckFrame(entity_database_t *d, int frame)
{
int i;
- for (i = 0;i < d->numframes && d->frames[i].framenum >= frame;i++);
+ if (d->ackframe < frame)
+ d->ackframe = frame;
+ for (i = 0;i < d->numframes && d->frames[i].framenum < frame;i++);
// ignore outdated frame acks (out of order packets)
if (i == 0)
return;
- d->ackframe = frame;
d->numframes -= i;
// if some queue is left, slide it down to beginning of array
if (d->numframes)
- memcpy(&d->frames[0], &d->frames[i], sizeof(d->frames[0]) * d->numframes);
+ memmove(&d->frames[0], &d->frames[i], sizeof(d->frames[0]) * d->numframes);
}
// (server) clears frame, to prepare for adding entities
return e;
}
+// (server and client) reads a frame from the database
void EntityFrame_FetchFrame(entity_database_t *d, int framenum, entity_frame_t *f)
{
int i, n;
memset(f, 0, sizeof(*f));
for (i = 0;i < d->numframes && d->frames[i].framenum < framenum;i++);
- if (framenum == d->frames[i].framenum)
+ if (i < d->numframes && framenum == d->frames[i].framenum)
{
f->framenum = framenum;
f->numentities = d->frames[i].endentity - d->frames[i].firstentity;
memcpy(f->entitydata, d->entitydata + d->frames[i].firstentity % MAX_ENTITY_DATABASE, sizeof(*f->entitydata) * n);
if (f->numentities > n)
memcpy(f->entitydata + n, d->entitydata, sizeof(*f->entitydata) * (f->numentities - n));
+ VectorCopy(d->eye, f->eye);
}
else
f->framenum = -1;
{
int n, e;
entity_frameinfo_t *info;
+
+ VectorCopy(f->eye, d->eye);
+
// figure out how many entity slots are used already
if (d->numframes)
{
info = &d->frames[d->numframes];
info->framenum = f->framenum;
+ e = -1000;
+ // make sure we check the newly added frame as well, but we haven't incremented numframes yet
+ for (n = 0;n <= d->numframes;n++)
+ {
+ if (e >= d->frames[n].framenum)
+ {
+ if (e == f->framenum)
+ Con_Printf("EntityFrame_AddFrame: tried to add out of sequence frame to database\n");
+ else
+ Con_Printf("EntityFrame_AddFrame: out of sequence frames in database\n");
+ return;
+ }
+ e = d->frames[n].framenum;
+ }
// if database still has frames after that...
if (d->numframes)
info->firstentity = d->frames[d->numframes - 1].endentity;
else
info->firstentity = 0;
info->endentity = info->firstentity + f->numentities;
+ d->numframes++;
n = info->firstentity % MAX_ENTITY_DATABASE;
e = MAX_ENTITY_DATABASE - n;
}
// (server) writes a frame to network stream
-void EntityFrame_Write(entity_database_t *d, entity_frame_t *f, int newframe, sizebuf_t *msg)
+void EntityFrame_Write(entity_database_t *d, entity_frame_t *f, sizebuf_t *msg)
{
int i, onum, bits, number;
entity_frame_t deltaframe, *o = &deltaframe;
EntityFrame_AddFrame(d, f);
ClearStateToDefault(&baseline);
- EntityFrame_FetchFrame(d, d->ackframe, o);
+ EntityFrame_FetchFrame(d, d->ackframe > 0 ? d->ackframe : -1, o);
MSG_WriteByte (msg, svc_entities);
MSG_WriteLong (msg, o->framenum);
- MSG_WriteLong (msg, newframe);
+ MSG_WriteLong (msg, f->framenum);
MSG_WriteFloat (msg, f->eye[0]);
MSG_WriteFloat (msg, f->eye[1]);
MSG_WriteFloat (msg, f->eye[2]);
delta = &baseline;
}
bits = 0;
- if (ent->origin[0] != delta->origin[0])
+ if ((int) ent->origin[0] != (int) delta->origin[0])
bits |= E_ORIGIN1;
- if (ent->origin[1] != delta->origin[1])
+ if ((int) ent->origin[1] != (int) delta->origin[1])
bits |= E_ORIGIN2;
- if (ent->origin[2] != delta->origin[2])
+ if ((int) ent->origin[2] != (int) delta->origin[2])
bits |= E_ORIGIN3;
- if (ent->angles[0] != delta->angles[0])
+ if ((byte) (ent->angles[0] * (256.0f / 360.0f)) != (byte) (delta->angles[0] * (256.0f / 360.0f)))
bits |= E_ANGLE1;
- if (ent->angles[1] != delta->angles[1])
+ if ((byte) (ent->angles[1] * (256.0f / 360.0f)) != (byte) (delta->angles[1] * (256.0f / 360.0f)))
bits |= E_ANGLE2;
- if (ent->angles[2] != delta->angles[2])
+ if ((byte) (ent->angles[2] * (256.0f / 360.0f)) != (byte) (delta->angles[2] * (256.0f / 360.0f)))
bits |= E_ANGLE3;
if ((ent->modelindex ^ delta->modelindex) & 0x00FF)
bits |= E_MODEL1;
}
}
if (bits & E_ORIGIN1)
- MSG_WriteFloat(msg, ent->origin[0]);
+ MSG_WriteShort(msg, ent->origin[0]);
if (bits & E_ORIGIN2)
- MSG_WriteFloat(msg, ent->origin[1]);
+ MSG_WriteShort(msg, ent->origin[1]);
if (bits & E_ORIGIN3)
- MSG_WriteFloat(msg, ent->origin[2]);
+ MSG_WriteShort(msg, ent->origin[2]);
if (bits & E_ANGLE1)
MSG_WriteAngle(msg, ent->angles[0]);
if (bits & E_ANGLE2)
// (client) reads a frame from network stream
void EntityFrame_Read(entity_database_t *d)
{
- int newframenum, deltaframenum, onum, number, removed, bits;
+ int number, removed, bits;
entity_frame_t framedata, *f = &framedata, deltaframedata, *delta = &deltaframedata;
- entity_state_t *e, baseline;
+ entity_state_t *e, baseline, *old, *oldend;
ClearStateToDefault(&baseline);
memset(f, 0, sizeof(*f));
// read the frame header info
f->time = cl.mtime[0];
- deltaframenum = MSG_ReadLong();
- newframenum = MSG_ReadLong();
+ number = MSG_ReadLong();
+ f->framenum = MSG_ReadLong();
f->eye[0] = MSG_ReadFloat();
f->eye[1] = MSG_ReadFloat();
f->eye[2] = MSG_ReadFloat();
- EntityFrame_AckFrame(d, deltaframenum);
- EntityFrame_FetchFrame(d, deltaframenum, delta);
- f->framenum = newframenum;
- onum = 0;
- f->numentities = 0;
+ EntityFrame_AckFrame(d, number);
+ EntityFrame_FetchFrame(d, number, delta);
+ old = delta->entitydata;
+ oldend = old + delta->numentities;
// read entities until we hit the magic 0xFFFF end tag
- while ((number = MSG_ReadShort()) != 0xFFFF)
+ while ((number = (unsigned short) MSG_ReadShort()) != 0xFFFF)
{
if (msg_badread)
Host_Error("EntityFrame_Read: read error\n");
Host_Error("EntityFrame_Read: number (%i) >= MAX_EDICTS (%i)\n", number, MAX_EDICTS);
// seek to entity, while copying any skipped entities (assume unchanged)
- while (onum < delta->numentities && delta->entitydata[onum].number < number)
+ while (old < oldend && old->number < number)
{
if (f->numentities >= MAX_ENTITY_DATABASE)
Host_Error("EntityFrame_Read: entity list too big\n");
- memcpy(f->entitydata + f->numentities, delta->entitydata + onum, sizeof(entity_state_t));
- onum++;
+ memcpy(f->entitydata + f->numentities, old, sizeof(entity_state_t));
+ f->entitydata[f->numentities].time = cl.mtime[0];
+ old++;
f->numentities++;
}
if (removed)
{
- if (onum < delta->numentities && delta->entitydata[onum].number == number)
- onum++;
+ if (old < oldend && old->number == number)
+ old++;
else
- Con_Printf("EntityFrame_Read: REMOVE on unused entity!\n");
+ Con_Printf("EntityFrame_Read: REMOVE on unused entity %i\n", number);
}
else
{
if (f->numentities >= MAX_ENTITY_DATABASE)
Host_Error("EntityFrame_Read: entity list too big\n");
- if (onum < delta->numentities && delta->entitydata[onum].number == number)
+
+ // reserve this slot
+ e = f->entitydata + f->numentities++;
+
+ if (old < oldend && old->number == number)
{
// delta from old entity
- memcpy(f->entitydata + f->numentities, delta->entitydata + onum++, sizeof(*e));
+ memcpy(e, old++, sizeof(*e));
}
else
{
// delta from baseline
- memcpy(f->entitydata + f->numentities, &baseline, sizeof(*e));
+ memcpy(e, &baseline, sizeof(*e));
}
- // reserve this slot
- e = f->entitydata + f->numentities++;
-
e->active = true;
e->time = cl.mtime[0];
+ e->number = number;
bits = MSG_ReadByte();
if (bits & E_EXTEND1)
}
if (bits & E_ORIGIN1)
- e->origin[0] = MSG_ReadFloat();
+ e->origin[0] = (signed short) MSG_ReadShort();
if (bits & E_ORIGIN2)
- e->origin[1] = MSG_ReadFloat();
+ e->origin[1] = (signed short) MSG_ReadShort();
if (bits & E_ORIGIN3)
- e->origin[2] = MSG_ReadFloat();
+ e->origin[2] = (signed short) MSG_ReadShort();
if (bits & E_ANGLE1)
e->angles[0] = MSG_ReadAngle();
if (bits & E_ANGLE2)
e->flags = MSG_ReadByte();
}
}
- while (onum < delta->numentities)
+ while (old < oldend)
{
if (f->numentities >= MAX_ENTITY_DATABASE)
Host_Error("EntityFrame_Read: entity list too big\n");
- memcpy(f->entitydata + f->numentities, delta->entitydata + onum, sizeof(entity_state_t));
- onum++;
+ memcpy(f->entitydata + f->numentities, old, sizeof(entity_state_t));
+ f->entitydata[f->numentities].time = cl.mtime[0];
+ old++;
f->numentities++;
}
EntityFrame_AddFrame(d, f);
}
-void EntityFrame_FetchEye(entity_database_t *d, vec3_t eye, double time)
+/*
+// (client) reads (and interpolates) the eye location from the database,
+// given a current time
+int EntityFrame_FetchEye(entity_database_t *d, vec3_t eye, double time)
{
float frac;
if (d->numframes == 0)
- Host_Error("EntityFrame_FetchEye: no frames\n");
+ return false;
+// Host_Error("EntityFrame_FetchEye: no frames\n");
if (d->numframes > 1 && d->frames[d->numframes - 2].time != d->frames[d->numframes - 1].time)
{
frac = (time - d->frames[d->numframes - 2].time) / (d->frames[d->numframes - 1].time - d->frames[d->numframes - 2].time);
}
else
VectorCopy(d->frames[0].eye, eye);
+ return true;
}
// (client) fetchs an entity from a frame, index is the index into the frame's entity list, returns false if index is out of bounds
ClearStateToDefault(e);
return false;
}
+*/
+
+// (client) returns the frame number of the most recent frame recieved
+int EntityFrame_MostRecentlyRecievedFrameNum(entity_database_t *d)
+{
+ if (d->numframes)
+ return d->frames[d->numframes - 1].framenum;
+ else
+ return -1;
+}
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
// protocol.h -- communications protocols
#define PROTOCOL_VERSION 15
-#define DPPROTOCOL_VERSION 96
+#define DPPROTOCOL_VERSION1 96
+#define DPPROTOCOL_VERSION2 97
// model effects
#define EF_ROCKET 1 // leave a trail
#define svc_hidelmp 36 // [string] slotname
#define svc_skybox 37 // [string] skyname
+// LordHavoc: my svc_ range, 50-59
#define svc_cgame 50 // [short] length [bytes] data
#define svc_fog 51 // unfinished and obsolete
#define svc_effect 52 // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
#define clc_move 3 // [usercmd_t]
#define clc_stringcmd 4 // [string] message
+// LordHavoc: my clc_ range, 50-59
+#define clc_ackentities 50 // [int] framenumber
+#define clc_unusedlh1 51
+#define clc_unusedlh2 52
+#define clc_unusedlh3 53
+#define clc_unusedlh4 54
+#define clc_unusedlh5 55
+#define clc_unusedlh6 56
+#define clc_unusedlh7 57
+#define clc_unusedlh8 58
+#define clc_unusedlh9 59
//
// temp entity events
#define TE_TELEPORT 11 // [vector] origin
#define TE_EXPLOSION2 12 // [vector] origin [byte] startcolor [byte] colorcount
-// PGM 01/21/97
+// PGM 01/21/97
#define TE_BEAM 13 // [entity] entity [vector] start [vector] end
// PGM 01/21/97
typedef struct
{
double time;
- vec3_t eye;
int framenum;
int firstentity; // index into entitydata, modulo MAX_ENTITY_DATABASE
int endentity; // index into entitydata, firstentity + numentities
// the only reason this system is used is to avoid copying memory when frames are removed
int numframes;
int ackframe; // server only: last acknowledged frame
+ vec3_t eye;
entity_frameinfo_t frames[MAX_ENTITY_HISTORY];
entity_state_t entitydata[MAX_ENTITY_DATABASE];
}
void EntityFrame_Clear(entity_frame_t *f, vec3_t eye);
// (server) allocates an entity slot in frame, returns NULL if full
entity_state_t *EntityFrame_NewEntity(entity_frame_t *f, int number);
+// (server and client) reads a frame from the database
+void EntityFrame_FetchFrame(entity_database_t *d, int framenum, entity_frame_t *f);
// (server and client) adds a entity_frame to the database, for future
// reference
void EntityFrame_AddFrame(entity_database_t *d, entity_frame_t *f);
// (server) writes a frame to network stream
-void EntityFrame_Write(entity_database_t *d, entity_frame_t *f, int newframe, sizebuf_t *msg);
+void EntityFrame_Write(entity_database_t *d, entity_frame_t *f, sizebuf_t *msg);
// (client) reads a frame from network stream
void EntityFrame_Read(entity_database_t *d);
+// (client) reads (and interpolates) the eye location from the database,
+// given a current time
+//int EntityFrame_FetchEye(entity_database_t *d, vec3_t eye, double time);
// (client) fetchs an entity from the frame by index into the entity list
-int EntityFrame_FetchEntityByIndex(entity_frame_t *f, entity_state_t *e, int index);
+//int EntityFrame_FetchEntityByIndex(entity_frame_t *f, entity_state_t *e, int index);
// (client) fetchs an entity from the frame by entity number
-int EntityFrame_FetchEntityByNumber(entity_frame_t *f, entity_state_t *e, int number);
+//int EntityFrame_FetchEntityByNumber(entity_frame_t *f, entity_state_t *e, int number);
+// (client) returns the frame number of the most recent frame recieved
+int EntityFrame_MostRecentlyRecievedFrameNum(entity_database_t *d);
int old_frags;
int pmodel;
+#ifdef QUAKEENTITIES
// delta compression state
float nextfullupdate[MAX_EDICTS];
- float lastvisible[MAX_EDICTS];
+#endif
+ // visibility state
+ float visibletime[MAX_EDICTS];
+
+#ifndef QUAKEENTITIES
+ entity_database_t entitydatabase;
+ int entityframenumber; // incremented each time an entity frame is sent
+#endif
} client_t;
if (sv.datagram.cursize > MAX_DATAGRAM-16)
return;
MSG_WriteByte (&sv.datagram, svc_particle);
- MSG_WriteFloatCoord (&sv.datagram, org[0]);
- MSG_WriteFloatCoord (&sv.datagram, org[1]);
- MSG_WriteFloatCoord (&sv.datagram, org[2]);
+ MSG_WriteDPCoord (&sv.datagram, org[0]);
+ MSG_WriteDPCoord (&sv.datagram, org[1]);
+ MSG_WriteDPCoord (&sv.datagram, org[2]);
for (i=0 ; i<3 ; i++)
{
v = dir[i]*16;
if (modelindex >= 256 || startframe >= 256)
{
MSG_WriteByte (&sv.datagram, svc_effect2);
- MSG_WriteFloatCoord (&sv.datagram, org[0]);
- MSG_WriteFloatCoord (&sv.datagram, org[1]);
- MSG_WriteFloatCoord (&sv.datagram, org[2]);
+ MSG_WriteDPCoord (&sv.datagram, org[0]);
+ MSG_WriteDPCoord (&sv.datagram, org[1]);
+ MSG_WriteDPCoord (&sv.datagram, org[2]);
MSG_WriteShort (&sv.datagram, modelindex);
MSG_WriteShort (&sv.datagram, startframe);
MSG_WriteByte (&sv.datagram, framecount);
else
{
MSG_WriteByte (&sv.datagram, svc_effect);
- MSG_WriteFloatCoord (&sv.datagram, org[0]);
- MSG_WriteFloatCoord (&sv.datagram, org[1]);
- MSG_WriteFloatCoord (&sv.datagram, org[2]);
+ MSG_WriteDPCoord (&sv.datagram, org[0]);
+ MSG_WriteDPCoord (&sv.datagram, org[1]);
+ MSG_WriteDPCoord (&sv.datagram, org[2]);
MSG_WriteByte (&sv.datagram, modelindex);
MSG_WriteByte (&sv.datagram, startframe);
MSG_WriteByte (&sv.datagram, framecount);
else
MSG_WriteByte (&sv.datagram, sound_num);
for (i=0 ; i<3 ; i++)
- MSG_WriteFloatCoord (&sv.datagram, entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i]));
+ MSG_WriteDPCoord (&sv.datagram, entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i]));
}
/*
char **s;
char message[2048];
+ // LordHavoc: clear entityframe tracking
+ client->entityframenumber = 0;
+ EntityFrame_ClearDatabase(&client->entitydatabase);
+
MSG_WriteByte (&client->message, svc_print);
sprintf (message, "\002\nServer: %s build %s (progs %i crc)", gamename, buildstring, pr_crc);
MSG_WriteString (&client->message,message);
MSG_WriteByte (&client->message, svc_serverinfo);
- MSG_WriteLong (&client->message, DPPROTOCOL_VERSION);
+ MSG_WriteLong (&client->message, DPPROTOCOL_VERSION2);
MSG_WriteByte (&client->message, svs.maxclients);
if (!coop.integer && deathmatch.integer)
=============
*/
+#ifdef QUAKEENTITIES
void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
{
int e, clentnum, bits, alpha, glowcolor, glowsize, scale, effects;
SV_RecursiveHullCheck (sv.worldmodel->hulls->firstclipnode, 0, 1, testeye, testorigin);
if (trace.fraction == 1)
- client->lastvisible[e] = realtime;
+ client->visibletime[e] = realtime + 1;
else
{
- if (realtime - client->lastvisible[e] >= 1)
+ if (realtime > client->visibletime[e])
{
culled_trace++;
continue;
for (;e < sv.num_edicts;e++)
{
client->nextfullupdate[e] = -1;
- client->lastvisible[e] = -1;
+ client->visibletime[e] = -1;
}
return;
}
if (bits & U_COLORMAP) MSG_WriteByte (msg, ent->v.colormap);
if (bits & U_SKIN) MSG_WriteByte (msg, ent->v.skin);
if (bits & U_EFFECTS) MSG_WriteByte (msg, ent->v.effects);
- if (bits & U_ORIGIN1) MSG_WriteFloatCoord (msg, origin[0]);
+ if (bits & U_ORIGIN1) MSG_WriteDPCoord (msg, origin[0]);
if (bits & U_ANGLE1) MSG_WriteAngle(msg, angles[0]);
- if (bits & U_ORIGIN2) MSG_WriteFloatCoord (msg, origin[1]);
+ if (bits & U_ORIGIN2) MSG_WriteDPCoord (msg, origin[1]);
if (bits & U_ANGLE2) MSG_WriteAngle(msg, angles[1]);
- if (bits & U_ORIGIN3) MSG_WriteFloatCoord (msg, origin[2]);
+ if (bits & U_ORIGIN3) MSG_WriteDPCoord (msg, origin[2]);
if (bits & U_ANGLE3) MSG_WriteAngle(msg, angles[2]);
// LordHavoc: new stuff
if (sv_cullentities_stats.integer)
Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d portal %d trace\n", client->name, totalentities, visibleentities, culled_pvs + culled_portal + culled_trace, culled_pvs, culled_portal, culled_trace);
}
+#else
+void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
+{
+ int e, clentnum, flags, alpha, glowcolor, glowsize, scale, effects;
+ int culled_pvs, culled_portal, culled_trace, visibleentities, totalentities;
+ byte *pvs;
+ vec3_t org, origin, angles, entmins, entmaxs;
+ edict_t *ent;
+ eval_t *val;
+ trace_t trace;
+ model_t *model;
+ double testeye[3];
+ double testorigin[3];
+ entity_frame_t entityframe;
+ entity_state_t *s;
+
+ if (client->sendsignon)
+ return;
+
+ Mod_CheckLoaded(sv.worldmodel);
+
+// find the client's PVS
+ VectorAdd (clent->v.origin, clent->v.view_ofs, testeye);
+ VectorCopy (testeye, org);
+ pvs = SV_FatPVS (org);
+ EntityFrame_Clear(&entityframe, org);
+
+ culled_pvs = 0;
+ culled_portal = 0;
+ culled_trace = 0;
+ visibleentities = 0;
+ totalentities = 0;
+
+ clentnum = EDICT_TO_PROG(clent); // LordHavoc: for comparison purposes
+ // send all entities that touch the pvs
+ ent = NEXT_EDICT(sv.edicts);
+ for (e = 1;e < sv.num_edicts;e++, ent = NEXT_EDICT(ent))
+ {
+ flags = 0;
+
+ if (ent != clent) // LordHavoc: always send player
+ {
+ if ((val = GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict)
+ {
+ if (val->edict == clentnum)
+ flags |= RENDER_VIEWMODEL; // show relative to the view
+ else
+ {
+ // don't show to anyone else
+ continue;
+ }
+ }
+ else
+ {
+ // LordHavoc: never draw something told not to display to this client
+ if ((val = GETEDICTFIELDVALUE(ent, eval_nodrawtoclient)) && val->edict == clentnum)
+ continue;
+ if ((val = GETEDICTFIELDVALUE(ent, eval_drawonlytoclient)) && val->edict && val->edict != clentnum)
+ continue;
+ }
+ }
+
+ glowsize = 0;
+
+ if ((val = GETEDICTFIELDVALUE(ent, eval_glow_size)))
+ glowsize = (int) val->_float >> 2;
+ glowsize = bound(0, glowsize, 255);
+
+ if ((val = GETEDICTFIELDVALUE(ent, eval_glow_trail)))
+ if (val->_float != 0)
+ flags |= RENDER_GLOWTRAIL;
+
+ if (ent->v.modelindex >= 0 && ent->v.modelindex < MAX_MODELS && pr_strings[ent->v.model])
+ {
+ model = sv.models[(int)ent->v.modelindex];
+ Mod_CheckLoaded(model);
+ }
+ else
+ {
+ model = NULL;
+ if (ent != clent) // LordHavoc: always send player
+ if (glowsize == 0 && (flags & RENDER_GLOWTRAIL) == 0) // no effects
+ continue;
+ }
+
+ VectorCopy(ent->v.angles, angles);
+ if (DotProduct(ent->v.velocity, ent->v.velocity) >= 1.0f && host_client->latency >= 0.01f)
+ {
+ VectorMA(ent->v.origin, host_client->latency, ent->v.velocity, origin);
+ // LordHavoc: trace predicted movement to avoid putting things in walls
+ trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, origin, MOVE_NORMAL, ent);
+ VectorCopy(trace.endpos, origin);
+ }
+ else
+ {
+ VectorCopy(ent->v.origin, origin);
+ }
+
+ // ent has survived every check so far, check if it is visible
+ // always send embedded brush models, they don't generate much traffic
+ if (ent != clent && ((flags & RENDER_VIEWMODEL) == 0) && (model == NULL || model->type != mod_brush || model->name[0] != '*'))
+ {
+ // use the predicted origin
+ entmins[0] = origin[0] - 1.0f;
+ entmins[1] = origin[1] - 1.0f;
+ entmins[2] = origin[2] - 1.0f;
+ entmaxs[0] = origin[0] + 1.0f;
+ entmaxs[1] = origin[1] + 1.0f;
+ entmaxs[2] = origin[2] + 1.0f;
+ // using the model's bounding box to ensure things are visible regardless of their physics box
+ if (model)
+ {
+ if (ent->v.angles[0] || ent->v.angles[2]) // pitch and roll
+ {
+ VectorAdd(entmins, model->rotatedmins, entmins);
+ VectorAdd(entmaxs, model->rotatedmaxs, entmaxs);
+ }
+ else if (ent->v.angles[1])
+ {
+ VectorAdd(entmins, model->yawmins, entmins);
+ VectorAdd(entmaxs, model->yawmaxs, entmaxs);
+ }
+ else
+ {
+ VectorAdd(entmins, model->normalmins, entmins);
+ VectorAdd(entmaxs, model->normalmaxs, entmaxs);
+ }
+ }
+
+ totalentities++;
+
+ // if not touching a visible leaf
+ if (sv_cullentities_pvs.integer && !SV_BoxTouchingPVS(pvs, entmins, entmaxs, sv.worldmodel->nodes))
+ {
+ culled_pvs++;
+ continue;
+ }
+
+ // or not visible through the portals
+ if (sv_cullentities_portal.integer && !Portal_CheckBox(sv.worldmodel, org, entmins, entmaxs))
+ {
+ culled_portal++;
+ continue;
+ }
+
+ if (sv_cullentities_trace.integer)
+ {
+ // LordHavoc: test random offsets, to maximize chance of detection
+ testorigin[0] = lhrandom(entmins[0], entmaxs[0]);
+ testorigin[1] = lhrandom(entmins[1], entmaxs[1]);
+ testorigin[2] = lhrandom(entmins[2], entmaxs[2]);
+
+ memset (&trace, 0, sizeof(trace_t));
+ trace.fraction = 1;
+ trace.allsolid = true;
+ VectorCopy(testorigin, trace.endpos);
+
+ VectorCopy(org, RecursiveHullCheckInfo.start);
+ VectorSubtract(testorigin, testeye, RecursiveHullCheckInfo.dist);
+ RecursiveHullCheckInfo.hull = sv.worldmodel->hulls;
+ RecursiveHullCheckInfo.trace = &trace;
+ SV_RecursiveHullCheck (sv.worldmodel->hulls->firstclipnode, 0, 1, testeye, testorigin);
+
+ if (trace.fraction == 1)
+ client->visibletime[e] = realtime + 1;
+ else
+ {
+ if (realtime > client->visibletime[e])
+ {
+ culled_trace++;
+ continue;
+ }
+ }
+ }
+ visibleentities++;
+ }
+
+ alpha = 255;
+ scale = 16;
+ glowcolor = 254;
+ effects = ent->v.effects;
+
+ if ((val = GETEDICTFIELDVALUE(ent, eval_alpha)))
+ if (val->_float != 0)
+ alpha = (int) (val->_float * 255.0);
+
+ // HalfLife support
+ if ((val = GETEDICTFIELDVALUE(ent, eval_renderamt)))
+ if (val->_float != 0)
+ alpha = (int) val->_float;
+
+ if (alpha == 0)
+ alpha = 255;
+ alpha = bound(0, alpha, 255);
+
+ if ((val = GETEDICTFIELDVALUE(ent, eval_scale)))
+ if ((scale = (int) (val->_float * 16.0)) == 0) scale = 16;
+ if (scale < 0) scale = 0;
+ if (scale > 255) scale = 255;
+
+ if ((val = GETEDICTFIELDVALUE(ent, eval_glow_color)))
+ if (val->_float != 0)
+ glowcolor = (int) val->_float;
+
+ if ((val = GETEDICTFIELDVALUE(ent, eval_fullbright)))
+ if (val->_float != 0)
+ effects |= EF_FULLBRIGHT;
+
+ if (ent != clent)
+ {
+ if (glowsize == 0 && (flags & RENDER_GLOWTRAIL) == 0) // no effects
+ {
+ if (model) // model
+ {
+ // don't send if flagged for NODRAW and there are no effects
+ if (model->flags == 0 && ((effects & EF_NODRAW) || scale <= 0 || alpha <= 0))
+ continue;
+ }
+ else // no model and no effects
+ continue;
+ }
+ }
+
+ if ((val = GETEDICTFIELDVALUE(ent, eval_exteriormodeltoclient)) && val->edict == clentnum)
+ flags |= RENDER_EXTERIORMODEL;
+
+ if (ent->v.movetype == MOVETYPE_STEP)
+ flags |= RENDER_STEP;
+
+ s = EntityFrame_NewEntity(&entityframe, e);
+ // if we run out of space, abort
+ if (!s)
+ break;
+ VectorCopy(origin, s->origin);
+ VectorCopy(angles, s->angles);
+ s->colormap = ent->v.colormap;
+ s->skin = ent->v.skin;
+ s->frame = ent->v.frame;
+ s->modelindex = ent->v.modelindex;
+ s->effects = effects;
+ s->alpha = alpha;
+ s->scale = scale;
+ s->glowsize = glowsize;
+ s->glowcolor = glowcolor;
+ s->flags = flags;
+ }
+ entityframe.framenum = ++client->entityframenumber;
+ EntityFrame_Write(&client->entitydatabase, &entityframe, msg);
+
+ if (sv_cullentities_stats.integer)
+ Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d portal %d trace\n", client->name, totalentities, visibleentities, culled_pvs + culled_portal + culled_trace, culled_pvs, culled_portal, culled_trace);
+}
+#endif
/*
=============
MSG_WriteByte (msg, ent->v.dmg_save);
MSG_WriteByte (msg, ent->v.dmg_take);
for (i=0 ; i<3 ; i++)
- MSG_WriteFloatCoord (msg, other->v.origin[i] + 0.5*(other->v.mins[i] + other->v.maxs[i]));
+ MSG_WriteDPCoord (msg, other->v.origin[i] + 0.5*(other->v.mins[i] + other->v.maxs[i]));
ent->v.dmg_take = 0;
ent->v.dmg_save = 0;
bits = 0;
- if (ent->v.view_ofs[2] != DEFAULT_VIEWHEIGHT)
+ //if (ent->v.view_ofs[2] != DEFAULT_VIEWHEIGHT)
bits |= SU_VIEWHEIGHT;
if (ent->v.idealpitch)
MSG_WriteByte(msg, bits >> 24);
if (bits & SU_VIEWHEIGHT)
- MSG_WriteChar (msg, ent->v.view_ofs[2]);
+ //MSG_WriteChar (msg, ent->v.view_ofs[2]);
+ MSG_WriteChar (msg, 0);
if (bits & SU_IDEALPITCH)
MSG_WriteChar (msg, ent->v.idealpitch);
if (bits & (SU_PUNCH1<<i))
MSG_WritePreciseAngle(msg, ent->v.punchangle[i]); // dpprotocol
if (bits & (SU_PUNCHVEC1<<i)) // dpprotocol
- MSG_WriteFloatCoord(msg, punchvector[i]); // dpprotocol
+ MSG_WriteDPCoord(msg, punchvector[i]); // dpprotocol
if (bits & (SU_VELOCITY1<<i))
MSG_WriteChar (msg, ent->v.velocity[i]/16);
}
return i;
}
+#ifdef SV_QUAKEENTITIES
/*
================
SV_CreateBaseline
MSG_WriteByte (&sv.signon, svent->baseline.skin);
for (i=0 ; i<3 ; i++)
{
- MSG_WriteFloatCoord(&sv.signon, svent->baseline.origin[i]);
+ MSG_WriteDPCoord(&sv.signon, svent->baseline.origin[i]);
MSG_WriteAngle(&sv.signon, svent->baseline.angles[i]);
}
}
}
+#endif
/*
Mod_PurgeUnused();
+#ifdef QUAKEENTITIES
// create a baseline for more efficient communications
SV_CreateBaseline ();
+#endif
// send serverinfo to all connected clients
for (i=0,host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
bottom[0] = top[0];
bottom[1] = top[1];
bottom[2] = top[2] - 160;
-
+
tr = SV_Move (top, vec3_origin, vec3_origin, bottom, MOVE_NOMONSTERS, sv_player);
if (tr.allsolid)
return; // looking at a wall, leave ideal the way is was
eval_t *val;
len = VectorNormalizeLength (sv_player->v.punchangle);
-
+
len -= 10*sv.frametime;
if (len < 0)
len = 0;
case clc_move:
SV_ReadClientMove (&host_client->cmd);
break;
+
+ case clc_ackentities:
+ EntityFrame_AckFrame(&host_client->entitydatabase, MSG_ReadLong());
+ break;
}
}
} while (ret == 1);
side = DotProduct (velocity, right);
sign = side < 0 ? -1 : 1;
side = fabs(side);
-
+
value = cl_rollangle.value;
// if (cl.inwater)
// value *= 6;
V_DriftPitch ();
- VectorCopy (ent->render.origin, r_refdef.vieworg);
+ VectorCopy (cl.viewentorigin, r_refdef.vieworg);
if (!intimerefresh)
VectorCopy (cl.viewangles, r_refdef.viewangles);
if (cl.intermission)
{
view->render.model = NULL;
+ VectorCopy (ent->render.angles, r_refdef.viewangles);
V_AddIdle (1);
}
else if (chase_active.value)
{
+ r_refdef.vieworg[2] += cl.viewheight;
Chase_Update ();
V_AddIdle (v_idlescale.value);
}
// set up gun
view->state_current.modelindex = cl.stats[STAT_WEAPON];
view->state_current.frame = cl.stats[STAT_WEAPONFRAME];
- view->render.origin[0] = ent->render.origin[0] + bob * 0.4 * forward[0];
- view->render.origin[1] = ent->render.origin[1] + bob * 0.4 * forward[1];
- view->render.origin[2] = ent->render.origin[2] + bob * 0.4 * forward[2] + cl.viewheight + bob;
+ VectorCopy(r_refdef.vieworg, view->render.origin);
+ //view->render.origin[0] = ent->render.origin[0] + bob * 0.4 * forward[0];
+ //view->render.origin[1] = ent->render.origin[1] + bob * 0.4 * forward[1];
+ //view->render.origin[2] = ent->render.origin[2] + bob * 0.4 * forward[2] + cl.viewheight + bob;
view->render.angles[PITCH] = -r_refdef.viewangles[PITCH] - v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value;
view->render.angles[YAW] = r_refdef.viewangles[YAW] - v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value;
view->render.angles[ROLL] = r_refdef.viewangles[ROLL] - v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value;