don't use qw nail packets for clients that have replacement deltas. at least we won't repeat lots of angle changes.

tweak some culling with attachments to be a little more in line with DP. This should fix view models randomly disappearing in nexuiz.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4572 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-12-23 21:33:40 +00:00
parent 1f4a0cb80a
commit d7cdc39ccd

View file

@ -121,7 +121,7 @@ qboolean SV_AddNailUpdate (edict_t *ent)
if (ent->v->modelindex != sv_nailmodel if (ent->v->modelindex != sv_nailmodel
&& ent->v->modelindex != sv_supernailmodel) && ent->v->modelindex != sv_supernailmodel)
return false; return false;
if (sv_nailhack.value) if (sv_nailhack.value || (host_client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))
return false; return false;
#ifdef SERVER_DEMO_PLAYBACK #ifdef SERVER_DEMO_PLAYBACK
@ -3040,7 +3040,7 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
{ {
//pvs and clent can be null, but only if the other is also null //pvs and clent can be null, but only if the other is also null
int e, i; int e, i;
edict_t *ent, *trackent; edict_t *ent, *trackent, *tracecullent;
entity_state_t *state; entity_state_t *state;
#define DEPTHOPTIMISE #define DEPTHOPTIMISE
#ifdef DEPTHOPTIMISE #ifdef DEPTHOPTIMISE
@ -3116,6 +3116,8 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
for ( ; e<limit ; e++) for ( ; e<limit ; e++)
{ {
ent = EDICT_NUM(svprogfuncs, e); ent = EDICT_NUM(svprogfuncs, e);
if (ent->isfree)
continue;
if (ent->xv->customizeentityforclient) if (ent->xv->customizeentityforclient)
{ {
@ -3140,46 +3142,56 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
} }
} }
pvsflags = ent->xv->pvsflags;
if (ent->xv->viewmodelforclient) if (ent->xv->viewmodelforclient)
{ {
if (ent->xv->viewmodelforclient != (clent?EDICT_TO_PROG(svprogfuncs, clent):0)) if (ent->xv->viewmodelforclient != (clent?EDICT_TO_PROG(svprogfuncs, clent):0))
continue; continue;
pvsflags = PVSF_IGNOREPVS; tracecullent = NULL;
} }
else if (ent == clent || ent == trackent) else if (ent == clent || ent == trackent)
{ tracecullent = NULL;
pvsflags = PVSF_IGNOREPVS;
}
else else
{ {
// ignore ents without visible models // ignore ents without visible models
if (!ent->xv->SendEntity && (!ent->v->modelindex || !*PR_GetString(svprogfuncs, ent->v->model)) && !((int)ent->xv->pflags & PFLAGS_FULLDYNAMIC) && ent->v->skin >= 0) if (!ent->xv->SendEntity && (!ent->v->modelindex || !*PR_GetString(svprogfuncs, ent->v->model)) && !((int)ent->xv->pflags & PFLAGS_FULLDYNAMIC) && ent->v->skin >= 0)
continue; continue;
pvsflags = ent->xv->pvsflags;
if (pvs) //self doesn't get a pvs test, to cover teleporters if (pvs) //self doesn't get a pvs test, to cover teleporters
{ {
if ((int)ent->v->effects & EF_NODEPTHTEST) if ((int)ent->v->effects & EF_NODEPTHTEST)
{ tracecullent = NULL;
}
else if ((pvsflags & PVSF_MODE_MASK) < PVSF_USEPHS) else if ((pvsflags & PVSF_MODE_MASK) < PVSF_USEPHS)
{ {
//branch out to the pvs testing. //branch out to the pvs testing.
if (ent->xv->tag_entity) if (ent->xv->tag_entity)
{ {
edict_t *p = ent;
int c = 10; int c = 10;
while(p->xv->tag_entity&&c-->0) tracecullent = ent;
while(tracecullent->xv->tag_entity&&c-->0)
{ {
p = EDICT_NUM(svprogfuncs, p->xv->tag_entity); tracecullent = EDICT_NUM(svprogfuncs, tracecullent->xv->tag_entity);
}
if (tracecullent == clent)
tracecullent = NULL;
else if (tracecullent->xv->viewmodelforclient)
{
//special hack so viewmodelforclient on the root of the tagged entity overrides pvs
if (tracecullent->xv->viewmodelforclient != (clent?EDICT_TO_PROG(svprogfuncs, clent):0))
continue;
tracecullent = NULL; //don't tracecull
}
else
{
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)tracecullent)->pvsinfo, pvs))
continue;
} }
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)p)->pvsinfo, pvs))
continue;
} }
else else
{ {
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)ent)->pvsinfo, pvs)) if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)ent)->pvsinfo, pvs))
continue; continue;
tracecullent = ent;
} }
} }
else if ((pvsflags & PVSF_MODE_MASK) == PVSF_USEPHS && sv.world.worldmodel->fromgame == fg_quake) else if ((pvsflags & PVSF_MODE_MASK) == PVSF_USEPHS && sv.world.worldmodel->fromgame == fg_quake)
@ -3197,11 +3209,16 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
continue; continue;
} }
} }
tracecullent = NULL;
} }
else
tracecullent = NULL;
if (client->gibfilter && SV_GibFilter(ent)) if (client->gibfilter && SV_GibFilter(ent))
continue; continue;
} }
else
tracecullent = NULL;
} }
//DP_SV_NODRAWONLYTOCLIENT //DP_SV_NODRAWONLYTOCLIENT
@ -3228,10 +3245,10 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
continue; //not in this dimension - sorry... continue; //not in this dimension - sorry...
if (!ignorepvs && ent != clent && (pvsflags & PVSF_MODE_MASK)==PVSF_NORMALPVS && !((unsigned int)ent->v->effects & (EF_DIMLIGHT|EF_BLUE|EF_RED|EF_BRIGHTLIGHT|EF_BRIGHTFIELD|EF_NODEPTHTEST))) if (!ignorepvs && ent != clent && tracecullent && !((unsigned int)ent->v->effects & (EF_DIMLIGHT|EF_BLUE|EF_RED|EF_BRIGHTLIGHT|EF_BRIGHTFIELD|EF_NODEPTHTEST)))
{ //more expensive culling { //more expensive culling
if ((e <= sv.allocated_client_slots && sv_cullplayers_trace.value) || sv_cullentities_trace.value) if ((e <= sv.allocated_client_slots && sv_cullplayers_trace.value) || sv_cullentities_trace.value)
if (Cull_Traceline(clent, ent)) if (Cull_Traceline(clent, tracecullent))
continue; continue;
} }