MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times
- if (dpprotocol == DPPROTOCOL_VERSION2)
+ if (dpprotocol == DPPROTOCOL_VERSION2 || dpprotocol == DPPROTOCOL_VERSION3)
{
for (i = 0;i < 3;i++)
MSG_WriteFloat (&buf, cl.viewangles[i]);
// parse protocol version number
i = MSG_ReadLong ();
- if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != 250)
+ if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
{
- Con_Printf ("Server is protocol %i, not %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, PROTOCOL_VERSION);
+ Con_Printf ("Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
return;
}
Nehahrademcompatibility = false;
if (cls.demoplayback && demo_nehahra.integer)
Nehahrademcompatibility = true;
dpprotocol = i;
- if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2)
+ if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
dpprotocol = 0;
// parse maxclients
Mod_CheckLoaded(model);
if (model && s->frame >= model->numframes)
{
- Con_Printf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
+ Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
s->frame = 0;
}
if (model && s->skin > 0 && s->skin >= model->numskins)
{
- Con_Printf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
+ Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
s->skin = 0;
}
}
case svc_version:
i = MSG_ReadLong ();
- 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);
+ if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
+ Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
Nehahrademcompatibility = false;
if (i == 250)
Nehahrademcompatibility = true;
if (cls.demoplayback && demo_nehahra.integer)
Nehahrademcompatibility = true;
dpprotocol = i;
- if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2)
+ if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
dpprotocol = 0;
break;
MSG_WriteShort (sb, (int)(f - 0.5f));
}
-// used by client
-void MSG_WriteCoord (sizebuf_t *sb, float f)
-{
- 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
- {
- if (f >= 0)
- MSG_WriteShort (sb, (int)(f*8.0f + 0.5f));
- else
- MSG_WriteShort (sb, (int)(f*8.0f - 0.5f));
- }
-}
-
void MSG_WritePreciseAngle (sizebuf_t *sb, float f)
{
if (f >= 0)
// used by client
float MSG_ReadCoord (void)
{
- if (dpprotocol == DPPROTOCOL_VERSION2)
+ if (dpprotocol == DPPROTOCOL_VERSION2 || dpprotocol == DPPROTOCOL_VERSION3)
return (signed short) MSG_ReadShort();
else if (dpprotocol == DPPROTOCOL_VERSION1)
return MSG_ReadFloat();
delta = &baseline;
}
bits = 0;
- if ((int) ent->origin[0] != (int) delta->origin[0])
- bits |= E_ORIGIN1;
- if ((int) ent->origin[1] != (int) delta->origin[1])
- bits |= E_ORIGIN2;
- if ((int) ent->origin[2] != (int) delta->origin[2])
- bits |= E_ORIGIN3;
+ if (ent->flags & RENDER_LOWPRECISION)
+ {
+ if ((int) ent->origin[0] != (int) delta->origin[0])
+ bits |= E_ORIGIN1;
+ if ((int) ent->origin[1] != (int) delta->origin[1])
+ bits |= E_ORIGIN2;
+ if ((int) ent->origin[2] != (int) delta->origin[2])
+ bits |= E_ORIGIN3;
+ }
+ else
+ {
+ if (fabs(ent->origin[0] - delta->origin[0]) > 0.01f)
+ bits |= E_ORIGIN1;
+ if (fabs(ent->origin[1] - delta->origin[1]) > 0.01f)
+ bits |= E_ORIGIN2;
+ if (fabs(ent->origin[2] - delta->origin[2]) > 0.01f)
+ bits |= E_ORIGIN3;
+ }
if ((qbyte) (ent->angles[0] * (256.0f / 360.0f)) != (qbyte) (delta->angles[0] * (256.0f / 360.0f)))
bits |= E_ANGLE1;
if ((qbyte) (ent->angles[1] * (256.0f / 360.0f)) != (qbyte) (delta->angles[1] * (256.0f / 360.0f)))
MSG_WriteByte(msg, (bits >> 24) & 0xFF);
}
}
- if (bits & E_ORIGIN1)
- MSG_WriteShort(msg, ent->origin[0]);
- if (bits & E_ORIGIN2)
- MSG_WriteShort(msg, ent->origin[1]);
- if (bits & E_ORIGIN3)
- MSG_WriteShort(msg, ent->origin[2]);
+ // LordHavoc: have to write flags first, as they can modify protocol
+ if (bits & E_FLAGS)
+ MSG_WriteByte(msg, ent->flags);
+ if (ent->flags & RENDER_LOWPRECISION)
+ {
+ if (bits & E_ORIGIN1)
+ MSG_WriteShort(msg, ent->origin[0]);
+ if (bits & E_ORIGIN2)
+ MSG_WriteShort(msg, ent->origin[1]);
+ if (bits & E_ORIGIN3)
+ MSG_WriteShort(msg, ent->origin[2]);
+ }
+ else
+ {
+ if (bits & E_ORIGIN1)
+ MSG_WriteFloat(msg, ent->origin[0]);
+ if (bits & E_ORIGIN2)
+ MSG_WriteFloat(msg, ent->origin[1]);
+ if (bits & E_ORIGIN3)
+ MSG_WriteFloat(msg, ent->origin[2]);
+ }
if (bits & E_ANGLE1)
MSG_WriteAngle(msg, ent->angles[0]);
if (bits & E_ANGLE2)
MSG_WriteByte(msg, ent->glowsize);
if (bits & E_GLOWCOLOR)
MSG_WriteByte(msg, ent->glowcolor);
- if (bits & E_FLAGS)
- MSG_WriteByte(msg, ent->flags);
}
}
for (;onum < o->numentities;onum++)
}
}
- if (bits & E_ORIGIN1)
- e->origin[0] = (signed short) MSG_ReadShort();
- if (bits & E_ORIGIN2)
- e->origin[1] = (signed short) MSG_ReadShort();
- if (bits & E_ORIGIN3)
- e->origin[2] = (signed short) MSG_ReadShort();
+ if (dpprotocol == DPPROTOCOL_VERSION2)
+ {
+ if (bits & E_ORIGIN1)
+ e->origin[0] = (signed short) MSG_ReadShort();
+ if (bits & E_ORIGIN2)
+ e->origin[1] = (signed short) MSG_ReadShort();
+ if (bits & E_ORIGIN3)
+ e->origin[2] = (signed short) MSG_ReadShort();
+ }
+ else
+ {
+ if (bits & E_FLAGS)
+ e->flags = MSG_ReadByte();
+ if (e->flags & RENDER_LOWPRECISION || dpprotocol == DPPROTOCOL_VERSION2)
+ {
+ if (bits & E_ORIGIN1)
+ e->origin[0] = (signed short) MSG_ReadShort();
+ if (bits & E_ORIGIN2)
+ e->origin[1] = (signed short) MSG_ReadShort();
+ if (bits & E_ORIGIN3)
+ e->origin[2] = (signed short) MSG_ReadShort();
+ }
+ else
+ {
+ if (bits & E_ORIGIN1)
+ e->origin[0] = MSG_ReadFloat();
+ if (bits & E_ORIGIN2)
+ e->origin[1] = MSG_ReadFloat();
+ if (bits & E_ORIGIN3)
+ e->origin[2] = MSG_ReadFloat();
+ }
+ }
if (bits & E_ANGLE1)
e->angles[0] = MSG_ReadAngle();
if (bits & E_ANGLE2)
e->glowsize = MSG_ReadByte();
if (bits & E_GLOWCOLOR)
e->glowcolor = MSG_ReadByte();
- if (bits & E_FLAGS)
- e->flags = MSG_ReadByte();
+ if (dpprotocol == DPPROTOCOL_VERSION2)
+ if (bits & E_FLAGS)
+ e->flags = MSG_ReadByte();
}
}
while (old < oldend)
#define PROTOCOL_VERSION 15
#define DPPROTOCOL_VERSION1 96
#define DPPROTOCOL_VERSION2 97
+// LordHavoc: I think the 96-99 range was going to run out too soon... so here I jump to 3500
+#define DPPROTOCOL_VERSION3 3500
// model effects
#define EF_ROCKET 1 // leave a trail
#define EF_ADDITIVE 32
#define EF_BLUE 64
#define EF_RED 128
-#define EF_DELTA 8388608 // LordHavoc: entity is delta compressed to save network bandwidth
+#define EF_DELTA 8388608 // LordHavoc: (obsolete) entity is delta compressed to save network bandwidth (no longer used)
+#define EF_LOWPRECISION 4194304 // LordHavoc: entity is low precision (integer coordinates) to save network bandwidth
// effects/model (can be used as model flags or entity effects)
-#define EF_REFLECTIVE 256 // LordHavoc: shiny metal objects :)
+#define EF_REFLECTIVE 256 // LordHavoc: shiny metal objects :) (not currently supported)
#define EF_FULLBRIGHT 512 // LordHavoc: fullbright
#define EF_FLAME 1024 // LordHavoc: on fire
// PGM 01/21/97
#define TE_BEAM 13 // [entity] entity [vector] start [vector] end
-// PGM 01/21/97
+// PGM 01/21/97
// Nehahra effects used in the movie (TE_EXPLOSION3 also got written up in a QSG tutorial, hence it's not marked NEH)
#define TE_EXPLOSION3 16 // [vector] origin [coord] red [coord] green [coord] blue
#define RENDER_GLOWTRAIL 2
#define RENDER_VIEWMODEL 4
#define RENDER_EXTERIORMODEL 8
+#define RENDER_LOWPRECISION 16 // send as low precision coordinates to save bandwidth
typedef struct
{
MSG_WriteString (&client->message,message);
MSG_WriteByte (&client->message, svc_serverinfo);
- MSG_WriteLong (&client->message, DPPROTOCOL_VERSION2);
+ MSG_WriteLong (&client->message, DPPROTOCOL_VERSION3);
MSG_WriteByte (&client->message, svs.maxclients);
if (!coop.integer && deathmatch.integer)
VectorCopy(ent->v.origin, origin);
}
- // don't send an entity if it's coordinates would wrap around
- if (origin[0] < -32768 || origin[1] < -32768 || origin[2] < -32768 || origin[0] > 32767 || origin[1] > 32767 || origin[2] > 32767)
- continue;
-
// 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] != '*'))
if (ent->v.movetype == MOVETYPE_STEP)
flags |= RENDER_STEP;
+ // don't send an entity if it's coordinates would wrap around
+ if ((effects & EF_LOWPRECISION) && origin[0] >= -32768 && origin[1] >= -32768 && origin[2] >= -32768 && origin[0] <= 32767 && origin[1] <= 32767 && origin[2] <= 32767)
+ flags |= RENDER_LOWPRECISION;
s = EntityFrame_NewEntity(&entityframe, e);
// if we run out of space, abort