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;
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++)
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
int EntityState5_Priority(entityframe5_database_t *d, int stateindex)
{
- int lowprecision, limit, priority;
- double distance;
- int changedbits;
- entity_state_t *view, *s;
- changedbits = d->deltabits[stateindex];
- priority = d->priorities[stateindex];
+ int limit, priority;
+ entity_state_t *s;
+ // if it is the player, update urgently
+ if (stateindex == d->viewentnum)
+ return E5_PROTOCOL_PRIORITYLEVELS - 1;
+ // 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)
- return E5_PROTOCOL_PRIORITYLEVELS - 1;
- // check whole attachment chain to judge relevance to player
- view = d->states + d->viewentnum;
- lowprecision = false;
+ {
+ 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 it is the player, update urgently
- if (s == view)
- return E5_PROTOCOL_PRIORITYLEVELS - 1;
- // if it is one of the player's viewmodels, update urgently
if (s->flags & RENDER_VIEWMODEL)
- return E5_PROTOCOL_PRIORITYLEVELS - 1;
- if (s->flags & RENDER_LOWPRECISION)
- lowprecision = true;
- if (!s->tagentity)
+ 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_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 and other factors
- // TODO: add velocity check for things moving toward you (+1 priority)
- distance = VectorDistance(view->origin, s->origin);
- // if it is not far from the player, update more often
- if (distance < 1024.0f && !lowprecision)
- priority++;
- if (changedbits & E5_FULLUPDATE)
+ // distance from the player
+ if (VectorDistance(d->states[d->viewentnum].origin, s->origin) < 1024.0f)
priority++;
- if (changedbits & (E5_ATTACHMENT | E5_MODEL | E5_FLAGS | E5_COLORMAP))
- priority++;
- return (int) bound(1, priority, E5_PROTOCOL_PRIORITYLEVELS - 1);
+ 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 (bits)
{
d->deltabits[s->number] |= bits;
- d->priorities[s->number] = 1;
+ // 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
{
CLEARPVSBIT(d->visiblebits, num);
d->deltabits[num] = E5_FULLUPDATE;
- d->priorities[num] = E5_PROTOCOL_PRIORITYLEVELS - 1;
+ 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] = 1;
+ 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] = E5_PROTOCOL_PRIORITYLEVELS - 1;
+ 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]++;
d->priorities[num] = EntityState5_Priority(d, num);
- }
l = num;
priority = d->priorities[num];
if (entityframe5_prioritychaincounts[priority] < ENTITYFRAME5_MAXSTATES)