#include "quakedef.h"
+#define E5_PROTOCOL_PRIORITYLEVELS 32
+
// this is 88 bytes (must match entity_state_t in protocol.h)
entity_state_t defaultstate =
{
// ! means this is not sent to client
0,//double time; // ! time this state was built (used on client for interpolation)
+ {0,0,0},//float netcenter[3]; // ! for network prioritization, this is the center of the bounding box (which may differ from the origin)
{0,0,0},//float origin[3];
{0,0,0},//float angles[3];
0,//int number; // entity number this state is for
0,//unsigned char tagindex;
{32, 32, 32},//unsigned char colormod[3];
// padding to a multiple of 8 bytes (to align the double time)
- {0,0,0,0,0,0}//unsigned char unused[6]; // !
+ {0,0}//unsigned char unused[2]; // !
};
// LordHavoc: I own protocol ranges 96, 97, 3500-3599
{0, NULL}
};
+static mempool_t *sv2csqc = NULL;
+int csqc_clent = 0;
+sizebuf_t *sv2csqcbuf = NULL;
+static unsigned char *sv2csqcents_version[MAX_SCOREBOARD];
+
+static entity_frame_t deltaframe; // FIXME?
+static entity_frame_t framedata; // FIXME?
+
+int entityframe5_prioritychaincounts[E5_PROTOCOL_PRIORITYLEVELS];
+unsigned short entityframe5_prioritychains[E5_PROTOCOL_PRIORITYLEVELS][ENTITYFRAME5_MAXSTATES];
+
protocolversion_t Protocol_EnumForName(const char *s)
{
int i;
}
}
-// keep track of quake entities because they need to be killed if they get stale
-int cl_lastquakeentity = 0;
-unsigned char cl_isquakeentity[MAX_EDICTS];
-
void EntityFrameQuake_ReadEntity(int bits)
{
int num;
if (num < 1)
Host_Error("EntityFrameQuake_ReadEntity: invalid entity number (%i)", num);
- if (cl_num_entities <= num)
+ if (cl.num_entities <= num)
{
- cl_num_entities = num + 1;
- if (num >= cl_max_entities)
+ cl.num_entities = num + 1;
+ if (num >= cl.max_entities)
CL_ExpandEntities(num);
}
- ent = cl_entities + num;
+ ent = cl.entities + num;
// note: this inherits the 'active' state of the baseline chosen
// (state_baseline is always active, state_current may not be active if
s.active = true;
}
- cl_isquakeentity[num] = true;
- if (cl_lastquakeentity < num)
- cl_lastquakeentity = num;
+ cl.isquakeentity[num] = true;
+ if (cl.lastquakeentity < num)
+ cl.lastquakeentity = num;
s.number = num;
s.time = cl.mtime[0];
s.flags = 0;
if (cls.protocol == PROTOCOL_NEHAHRAMOVIE && (bits & U_EXTEND1))
{
// LordHavoc: evil format
- int i = MSG_ReadFloat();
- int j = MSG_ReadFloat() * 255.0f;
+ int i = (int)MSG_ReadFloat();
+ int j = (int)(MSG_ReadFloat() * 255.0f);
if (i == 2)
{
- i = MSG_ReadFloat();
+ i = (int)MSG_ReadFloat();
if (i)
s.effects |= EF_FULLBRIGHT;
}
if (ent->state_current.active)
{
CL_MoveLerpEntityStates(ent);
- cl_entities_active[ent->state_current.number] = true;
+ cl.entities_active[ent->state_current.number] = true;
}
if (msg_badread)
void EntityFrameQuake_ISeeDeadEntities(void)
{
int num, lastentity;
- if (cl_lastquakeentity == 0)
+ if (cl.lastquakeentity == 0)
return;
- lastentity = cl_lastquakeentity;
- cl_lastquakeentity = 0;
+ lastentity = cl.lastquakeentity;
+ cl.lastquakeentity = 0;
for (num = 0;num <= lastentity;num++)
{
- if (cl_isquakeentity[num])
+ if (cl.isquakeentity[num])
{
- if (cl_entities_active[num] && cl_entities[num].state_current.time == cl.mtime[0])
+ if (cl.entities_active[num] && cl.entities[num].state_current.time == cl.mtime[0])
{
- cl_isquakeentity[num] = true;
- cl_lastquakeentity = num;
+ cl.isquakeentity[num] = true;
+ cl.lastquakeentity = num;
}
else
{
- cl_isquakeentity[num] = false;
- cl_entities_active[num] = false;
- cl_entities[num].state_current = defaultstate;
- cl_entities[num].state_current.number = num;
+ cl.isquakeentity[num] = false;
+ cl.entities_active[num] = false;
+ cl.entities[num].state_current = defaultstate;
+ cl.entities[num].state_current.number = num;
}
}
}
}
-static mempool_t *sv2csqc = NULL;
-int csqc_clent = 0;
-sizebuf_t *sv2csqcbuf = NULL;
-static unsigned char *sv2csqcents_version[64];
-
void EntityFrameCSQC_ClearVersions (void)
{
if(sv2csqc)
Mem_FreePool(&sv2csqc);
sv2csqc = NULL;
}
- memset(sv2csqcents_version, 0, 64*sizeof(unsigned char *));
+ memset(sv2csqcents_version, 0, MAX_SCOREBOARD*sizeof(unsigned char *));
}
void EntityFrameCSQC_InitClientVersions (int client, qboolean clear)
Mem_Free(sv2csqcents_version[client]);
sv2csqcents_version[client] = NULL;
}
- sv2csqcents_version[client] = Mem_Alloc(sv2csqc, MAX_EDICTS);
+ sv2csqcents_version[client] = (unsigned char *)Mem_Alloc(sv2csqc, MAX_EDICTS);
memset(sv2csqcents_version[client], 0, MAX_EDICTS);
}
prvm_eval_t *val, *val2;
int csqcents = 0;
- if(!eval_SendEntity || !eval_Version)
+ if(prog->fieldoffsets.SendEntity < 0 || prog->fieldoffsets.Version < 0)
return;
--csqc_clent;
if(!sv2csqcents_version[csqc_clent])
// if(!s->active)
// continue;
- val = PRVM_GETEDICTFIELDVALUE((&prog->edicts[s->number]), eval_SendEntity);
+ val = PRVM_EDICTFIELDVALUE((&prog->edicts[s->number]), prog->fieldoffsets.SendEntity);
if(val->function)
{
- val2 = PRVM_GETEDICTFIELDVALUE((&prog->edicts[s->number]), eval_Version);
+ val2 = PRVM_EDICTFIELDVALUE((&prog->edicts[s->number]), prog->fieldoffsets.Version);
if(sv2csqcents_version[csqc_clent][s->number] == (unsigned char)val2->_float)
continue;
if(!csqcents)
for (i = 0, s = states;i < numstates;i++, s++)
{
- val = PRVM_GETEDICTFIELDVALUE((&prog->edicts[s->number]), eval_SendEntity);
+ val = PRVM_EDICTFIELDVALUE((&prog->edicts[s->number]), prog->fieldoffsets.SendEntity);
if(val && val->function)
continue;
}
// (server) writes a frame to network stream
-static entity_frame_t deltaframe; // FIXME?
void EntityFrame_WriteFrame(sizebuf_t *msg, entityframe_database_t *d, int numstates, const entity_state_t *states, int viewentnum)
{
int i, onum, number;
ent = states + i;
number = ent->number;
- val = PRVM_GETEDICTFIELDVALUE((&prog->edicts[number]), eval_SendEntity);
+ val = PRVM_EDICTFIELDVALUE((&prog->edicts[number]), prog->fieldoffsets.SendEntity);
if(val && val->function)
continue;
for (;onum < o->numentities && o->entitydata[onum].number < number;onum++)
}
// (client) reads a frame from network stream
-static entity_frame_t framedata; // FIXME?
void EntityFrame_CL_ReadFrame(void)
{
int i, number, removed;
entity_t *ent;
entityframe_database_t *d;
if (!cl.entitydatabase)
- cl.entitydatabase = EntityFrame_AllocDatabase(cl_mempool);
+ cl.entitydatabase = EntityFrame_AllocDatabase(cls.levelmempool);
d = cl.entitydatabase;
EntityFrame_Clear(f, NULL, -1);
*e = defaultstate;
}
- if (cl_num_entities <= number)
+ if (cl.num_entities <= number)
{
- cl_num_entities = number + 1;
- if (number >= cl_max_entities)
+ cl.num_entities = number + 1;
+ if (number >= cl.max_entities)
CL_ExpandEntities(number);
}
- cl_entities_active[number] = true;
+ cl.entities_active[number] = true;
e->active = true;
e->time = cl.mtime[0];
e->number = number;
}
EntityFrame_AddFrame(d, f->eye, f->framenum, f->numentities, f->entitydata);
- memset(cl_entities_active, 0, cl_num_entities * sizeof(unsigned char));
+ memset(cl.entities_active, 0, cl.num_entities * sizeof(unsigned char));
number = 1;
for (i = 0;i < f->numentities;i++)
{
- for (;number < f->entitydata[i].number && number < cl_num_entities;number++)
+ for (;number < f->entitydata[i].number && number < cl.num_entities;number++)
{
- if (cl_entities_active[number])
+ if (cl.entities_active[number])
{
- cl_entities_active[number] = false;
- cl_entities[number].state_current.active = false;
+ cl.entities_active[number] = false;
+ cl.entities[number].state_current.active = false;
}
}
- if (number >= cl_num_entities)
+ if (number >= cl.num_entities)
break;
// update the entity
- ent = &cl_entities[number];
+ ent = &cl.entities[number];
ent->state_previous = ent->state_current;
ent->state_current = f->entitydata[i];
CL_MoveLerpEntityStates(ent);
// the entity lives again...
- cl_entities_active[number] = true;
+ cl.entities_active[number] = true;
number++;
}
- for (;number < cl_num_entities;number++)
+ for (;number < cl.num_entities;number++)
{
- if (cl_entities_active[number])
+ if (cl.entities_active[number])
{
- cl_entities_active[number] = false;
- cl_entities[number].state_current.active = false;
+ cl.entities_active[number] = false;
+ cl.entities[number].state_current.active = false;
}
}
}
entity_state_t *s;
entityframe4_database_t *d;
if (!cl.entitydatabase4)
- cl.entitydatabase4 = EntityFrame4_AllocDatabase(cl_mempool);
+ cl.entitydatabase4 = EntityFrame4_AllocDatabase(cls.levelmempool);
d = cl.entitydatabase4;
// read the number of the frame this refers to
referenceframenum = MSG_ReadLong();
// high bit means it's a remove message
cnumber = n & 0x7FFF;
// if this is a live entity we may need to expand the array
- if (cl_num_entities <= cnumber && !(n & 0x8000))
+ if (cl.num_entities <= cnumber && !(n & 0x8000))
{
- cl_num_entities = cnumber + 1;
- if (cnumber >= cl_max_entities)
+ cl.num_entities = cnumber + 1;
+ if (cnumber >= cl.max_entities)
CL_ExpandEntities(cnumber);
}
// add one (the changed one) if not done
// process entities in range from the last one to the changed one
for (;enumber < stopnumber;enumber++)
{
- if (skip || enumber >= cl_num_entities)
+ if (skip || enumber >= cl.num_entities)
{
if (enumber == cnumber && (n & 0x8000) == 0)
{
continue;
}
// slide the current into the previous slot
- cl_entities[enumber].state_previous = cl_entities[enumber].state_current;
+ cl.entities[enumber].state_previous = cl.entities[enumber].state_current;
// copy a new current from reference database
- cl_entities[enumber].state_current = *EntityFrame4_GetReferenceEntity(d, enumber);
- s = &cl_entities[enumber].state_current;
+ cl.entities[enumber].state_current = *EntityFrame4_GetReferenceEntity(d, enumber);
+ s = &cl.entities[enumber].state_current;
// if this is the one to modify, read more data...
if (enumber == cnumber)
{
}
else if (developer_networkentities.integer >= 4)
Con_Printf("entity %i: copy\n", enumber);
- // set the cl_entities_active flag
- cl_entities_active[enumber] = s->active;
+ // set the cl.entities_active flag
+ cl.entities_active[enumber] = s->active;
// set the update time
s->time = cl.mtime[0];
// fix the number (it gets wiped occasionally by copying from defaultstate)
s->number = enumber;
// check if we need to update the lerp stuff
if (s->active)
- CL_MoveLerpEntityStates(&cl_entities[enumber]);
+ CL_MoveLerpEntityStates(&cl.entities[enumber]);
// add this to the commit entry whether it is modified or not
if (d->currentcommit)
- EntityFrame4_AddCommitEntity(d, &cl_entities[enumber].state_current);
+ EntityFrame4_AddCommitEntity(d, &cl.entities[enumber].state_current);
// print extra messages if desired
- if (developer_networkentities.integer >= 2 && cl_entities[enumber].state_current.active != cl_entities[enumber].state_previous.active)
+ if (developer_networkentities.integer >= 2 && cl.entities[enumber].state_current.active != cl.entities[enumber].state_previous.active)
{
- if (cl_entities[enumber].state_current.active)
+ if (cl.entities[enumber].state_current.active)
Con_Printf("entity #%i has become active\n", enumber);
- else if (cl_entities[enumber].state_previous.active)
+ else if (cl.entities[enumber].state_previous.active)
Con_Printf("entity #%i has become inactive\n", enumber);
}
}
d->currententitynumber = 1;
for (i = 0, n = startnumber;n < prog->max_edicts;n++)
{
- val = PRVM_GETEDICTFIELDVALUE((&prog->edicts[n]), eval_SendEntity);
+ val = PRVM_EDICTFIELDVALUE((&prog->edicts[n]), prog->fieldoffsets.SendEntity);
if(val && val->function)
continue;
// find the old state to delta from
-#define E5_PROTOCOL_PRIORITYLEVELS 32
-
entityframe5_database_t *EntityFrame5_AllocDatabase(mempool_t *pool)
{
int i;
int EntityState5_Priority(entityframe5_database_t *d, int stateindex)
{
- int lowprecision, limit, priority;
- double distance;
- int changedbits;
- int age;
- entity_state_t *view, *s;
- changedbits = d->deltabits[stateindex];
- if (!changedbits)
- return 0;
- if (!d->states[stateindex].active/* && changedbits & E5_FULLUPDATE*/)
+ int limit, priority;
+ entity_state_t *s;
+ // if it is the player, update urgently
+ if (stateindex == d->viewentnum)
return E5_PROTOCOL_PRIORITYLEVELS - 1;
- // check whole attachment chain to judge relevance to player
- view = d->states + d->viewentnum;
- lowprecision = false;
+ // priority increases each frame no matter what happens
+ priority = d->priorities[stateindex] + 1;
+ // players get an extra priority boost
+ if (stateindex <= svs.maxclients)
+ priority++;
+ // remove dead entities very quickly because they are just 2 bytes
+ if (!d->states[stateindex].active)
+ {
+ priority++;
+ return bound(1, priority, E5_PROTOCOL_PRIORITYLEVELS - 1);
+ }
+ // certain changes are more noticable than others
+ if (d->deltabits[stateindex] & (E5_FULLUPDATE | E5_ATTACHMENT | E5_MODEL | E5_FLAGS | E5_COLORMAP))
+ priority++;
+ // find the root entity this one is attached to, and judge relevance by it
for (limit = 0;limit < 256;limit++)
{
- if (d->maxedicts < stateindex)
- EntityFrame5_ExpandEdicts(d, (stateindex+256)&~255);
s = d->states + stateindex;
- if (s == view)
- return E5_PROTOCOL_PRIORITYLEVELS - 1;
if (s->flags & RENDER_VIEWMODEL)
- return E5_PROTOCOL_PRIORITYLEVELS - 1;
- if (s->flags & RENDER_LOWPRECISION)
- lowprecision = true;
- if (!s->tagentity)
- {
- if (VectorCompare(s->origin, view->origin))
- return E5_PROTOCOL_PRIORITYLEVELS - 1;
+ stateindex = d->viewentnum;
+ else if (s->tagentity)
+ stateindex = s->tagentity;
+ else
break;
- }
- stateindex = s->tagentity;
+ if (d->maxedicts < stateindex)
+ EntityFrame5_ExpandEdicts(d, (stateindex+256)&~255);
}
if (limit >= 256)
- {
- Con_Printf("Protocol: Runaway loop recursing tagentity links on entity %i\n", stateindex);
- return 0;
- }
- // it's not a viewmodel for this client
- distance = VectorDistance(view->origin, s->origin);
- age = d->latestframenum - d->updateframenum[stateindex];
- priority = (E5_PROTOCOL_PRIORITYLEVELS / 2) + age - (int)(distance * (E5_PROTOCOL_PRIORITYLEVELS / 16384.0f));
- if (lowprecision)
- priority -= (E5_PROTOCOL_PRIORITYLEVELS / 4);
- //if (changedbits & E5_FULLUPDATE)
- // priority += 4;
- //if (changedbits & (E5_ATTACHMENT | E5_MODEL | E5_FLAGS | E5_COLORMAP))
- // priority += 4;
- return (int) bound(1, priority, E5_PROTOCOL_PRIORITYLEVELS - 1);
+ Con_DPrintf("Protocol: Runaway loop recursing tagentity links on entity %i\n", stateindex);
+ // now that we have the parent entity we can make some decisions based on
+ // distance from the player
+ if (VectorDistance(d->states[d->viewentnum].netcenter, s->netcenter) < 1024.0f)
+ priority++;
+ return bound(1, priority, E5_PROTOCOL_PRIORITYLEVELS - 1);
}
void EntityState5_WriteUpdate(int number, const entity_state_t *s, int changedbits, sizebuf_t *msg)
unsigned int bits = 0;
prvm_eval_t *val;
- val = PRVM_GETEDICTFIELDVALUE((&prog->edicts[s->number]), eval_SendEntity);
+ val = PRVM_EDICTFIELDVALUE((&prog->edicts[s->number]), prog->fieldoffsets.SendEntity);
if(val && val->function)
return;
if (developer_networkentities.integer)
Con_Printf("recv: svc_entities %i\n", cl.latestframenums[LATESTFRAMENUMS-1]);
if (cls.protocol != PROTOCOL_QUAKE && cls.protocol != PROTOCOL_QUAKEDP && cls.protocol != PROTOCOL_NEHAHRAMOVIE && cls.protocol != PROTOCOL_DARKPLACES1 && cls.protocol != PROTOCOL_DARKPLACES2 && cls.protocol != PROTOCOL_DARKPLACES3 && cls.protocol != PROTOCOL_DARKPLACES4 && cls.protocol != PROTOCOL_DARKPLACES5 && cls.protocol != PROTOCOL_DARKPLACES6)
- cl.servermovesequence = MSG_ReadLong();
+ cls.servermovesequence = MSG_ReadLong();
// read entity numbers until we find a 0x8000
// (which would be remove world entity, but is actually a terminator)
while ((n = (unsigned short)MSG_ReadShort()) != 0x8000 && !msg_badread)
// get the entity number
enumber = n & 0x7FFF;
// we may need to expand the array
- if (cl_num_entities <= enumber)
+ if (cl.num_entities <= enumber)
{
- cl_num_entities = enumber + 1;
- if (enumber >= cl_max_entities)
+ cl.num_entities = enumber + 1;
+ if (enumber >= cl.max_entities)
CL_ExpandEntities(enumber);
}
// look up the entity
- ent = cl_entities + enumber;
+ ent = cl.entities + enumber;
// slide the current into the previous slot
ent->state_previous = ent->state_current;
// read the update
// update entity
EntityState5_ReadUpdate(s);
}
- // set the cl_entities_active flag
- cl_entities_active[enumber] = s->active;
+ // set the cl.entities_active flag
+ cl.entities_active[enumber] = s->active;
// set the update time
s->time = cl.mtime[0];
// fix the number (it gets wiped occasionally by copying from defaultstate)
s->number = enumber;
// check if we need to update the lerp stuff
if (s->active)
- CL_MoveLerpEntityStates(&cl_entities[enumber]);
+ CL_MoveLerpEntityStates(&cl.entities[enumber]);
// print extra messages if desired
- if (developer_networkentities.integer >= 2 && cl_entities[enumber].state_current.active != cl_entities[enumber].state_previous.active)
+ if (developer_networkentities.integer >= 2 && cl.entities[enumber].state_current.active != cl.entities[enumber].state_previous.active)
{
- if (cl_entities[enumber].state_current.active)
+ if (cl.entities[enumber].state_current.active)
Con_Printf("entity #%i has become active\n", enumber);
- else if (cl_entities[enumber].state_previous.active)
+ else if (cl.entities[enumber].state_previous.active)
Con_Printf("entity #%i has become inactive\n", enumber);
}
}
if (bits)
{
d->deltabits[s->number] |= bits;
- d->priorities[s->number] = EntityState5_Priority(d, s->number);
+ // if it was a very important update, set priority higher
+ if (bits & (E5_FULLUPDATE | E5_ATTACHMENT | E5_MODEL || E5_COLORMAP))
+ d->priorities[s->number] = max(d->priorities[s->number], 4);
+ else
+ d->priorities[s->number] = max(d->priorities[s->number], 1);
}
}
// mark lost stats
d->packetlog[i].packetnumber = 0;
}
-int entityframe5_prioritychaincounts[E5_PROTOCOL_PRIORITYLEVELS];
-unsigned short entityframe5_prioritychains[E5_PROTOCOL_PRIORITYLEVELS][ENTITYFRAME5_MAXSTATES];
-
void EntityFrame5_WriteFrame(sizebuf_t *msg, entityframe5_database_t *d, int numstates, const entity_state_t *states, int viewentnum, int *stats, int movesequence)
{
const entity_state_t *n;
{
CLEARPVSBIT(d->visiblebits, num);
d->deltabits[num] = E5_FULLUPDATE;
- d->priorities[num] = EntityState5_Priority(d, num);
+ d->priorities[num] = max(d->priorities[num], 8); // removal is cheap
d->states[num] = defaultstate;
d->states[num].number = num;
}
// entity just spawned in, don't let it completely hog priority
// because of being ancient on the first frame
d->updateframenum[num] = framenum;
+ // initial priority is a bit high to make projectiles send on the
+ // first frame, among other things
+ d->priorities[num] = max(d->priorities[num], 4);
}
SETPVSBIT(d->visiblebits, num);
d->deltabits[num] |= EntityState5_DeltaBits(d->states + num, n);
- d->priorities[num] = EntityState5_Priority(d, num);
+ d->priorities[num] = max(d->priorities[num], 1);
d->states[num] = *n;
d->states[num].number = num;
// advance to next entity so the next iteration doesn't immediately remove it
{
CLEARPVSBIT(d->visiblebits, num);
d->deltabits[num] = E5_FULLUPDATE;
- d->priorities[num] = EntityState5_Priority(d, num);
+ d->priorities[num] = max(d->priorities[num], 8); // removal is cheap
d->states[num] = defaultstate;
d->states[num].number = num;
}
{
if (d->priorities[num])
{
+ if (d->priorities[num] < (E5_PROTOCOL_PRIORITYLEVELS - 1))
+ d->priorities[num] = EntityState5_Priority(d, num);
l = num;
priority = d->priorities[num];
if (entityframe5_prioritychaincounts[priority] < ENTITYFRAME5_MAXSTATES)
int bits;
entity_state_t *s;
// look up the entity
- entity_t *ent = cl_entities + enumber;
+ entity_t *ent = cl.entities + enumber;
vec3_t viewangles;
vec3_t velocity;
cl.stats[STAT_VIEWHEIGHT] = 22;
}
- // set the cl_entities_active flag
- cl_entities_active[enumber] = s->active;
+ // set the cl.entities_active flag
+ cl.entities_active[enumber] = s->active;
// set the update time
s->time = cl.mtime[0] - msec * 0.001; // qw has no clock
// fix the number (it gets wiped occasionally by copying from defaultstate)
s->number = enumber;
// check if we need to update the lerp stuff
if (s->active)
- CL_MoveLerpEntityStates(&cl_entities[enumber]);
+ CL_MoveLerpEntityStates(&cl.entities[enumber]);
}
static void EntityStateQW_ReadEntityUpdate(entity_state_t *s, int bits)
entityframeqw_snapshot_t *oldsnap, *newsnap;
if (!cl.entitydatabaseqw)
- cl.entitydatabaseqw = EntityFrameQW_AllocDatabase(cl_mempool);
+ cl.entitydatabaseqw = EntityFrameQW_AllocDatabase(cls.levelmempool);
d = cl.entitydatabaseqw;
- newsnapindex = cls.netcon->qw.incoming_sequence & QW_UPDATE_MASK;
+ // there is no cls.netcon in demos, so this reading code can't access
+ // cls.netcon-> at all... so cls.qw_incoming_sequence and
+ // cls.qw_outgoing_sequence are updated every time the corresponding
+ // cls.netcon->qw. variables are updated
+ // read the number of this frame to echo back in next input packet
+ cl.qw_validsequence = cls.qw_incoming_sequence;
+ newsnapindex = cl.qw_validsequence & QW_UPDATE_MASK;
newsnap = d->snapshot + newsnapindex;
memset(newsnap, 0, sizeof(*newsnap));
oldsnapindex = -1;
Con_DPrintf("WARNING: from mismatch\n");
if (oldsnapindex != -1)
{
- if (cls.netcon->qw.outgoing_sequence - oldsnapindex >= QW_UPDATE_BACKUP-1)
+ if (cls.qw_outgoing_sequence - oldsnapindex >= QW_UPDATE_BACKUP-1)
{
Con_DPrintf("delta update too old\n");
newsnap->invalid = invalid = true; // too old
delta = false;
}
- // read the number of this frame to echo back in next input packet
- cl.qw_validsequence = cls.netcon->qw.incoming_sequence;
+ // if we can't decode this frame properly, report that to the server
if (invalid)
cl.qw_validsequence = 0;
{
if (newsnap->num_entities >= QW_MAX_PACKET_ENTITIES)
Host_Error("EntityFrameQW_CL_ReadFrame: newsnap->num_entities == MAX_PACKETENTITIES");
- newsnap->entities[newsnap->num_entities] = (newnum == oldnum) ? oldsnap->entities[oldindex] : cl_entities[newnum].state_baseline;
+ newsnap->entities[newsnap->num_entities] = (newnum == oldnum) ? oldsnap->entities[oldindex] : cl.entities[newnum].state_baseline;
EntityStateQW_ReadEntityUpdate(newsnap->entities + newsnap->num_entities, word);
newsnap->num_entities++;
}
oldindex++;
}
- // expand cl_num_entities to include every entity we've seen this game
+ // expand cl.num_entities to include every entity we've seen this game
newnum = newsnap->num_entities ? newsnap->entities[newsnap->num_entities - 1].number : 1;
- if (cl_num_entities <= newnum)
+ if (cl.num_entities <= newnum)
{
- cl_num_entities = newnum + 1;
- if (cl_max_entities < newnum + 1)
+ cl.num_entities = newnum + 1;
+ if (cl.max_entities < newnum + 1)
CL_ExpandEntities(newnum);
}
number = cl.maxclients + 1;
for (newindex = 0;;newindex++)
{
- newnum = newindex >= newsnap->num_entities ? cl_num_entities : newsnap->entities[newindex].number;
+ newnum = newindex >= newsnap->num_entities ? cl.num_entities : newsnap->entities[newindex].number;
// kill any missing entities
for (;number < newnum;number++)
{
- if (cl_entities_active[number])
+ if (cl.entities_active[number])
{
- cl_entities_active[number] = false;
- cl_entities[number].state_current.active = false;
+ cl.entities_active[number] = false;
+ cl.entities[number].state_current.active = false;
}
}
- if (number >= cl_num_entities)
+ if (number >= cl.num_entities)
break;
// update the entity
- ent = &cl_entities[number];
+ ent = &cl.entities[number];
ent->state_previous = ent->state_current;
ent->state_current = newsnap->entities[newindex];
ent->state_current.time = cl.mtime[0];
CL_MoveLerpEntityStates(ent);
// the entity lives again...
- cl_entities_active[number] = true;
+ cl.entities_active[number] = true;
number++;
}
}