-int fatbytes;
-qbyte fatpvs[MAX_MAP_LEAFS/8];
-
-void SV_AddToFatPVS (vec3_t org, mnode_t *node)
-{
- int i;
- qbyte *pvs;
- mplane_t *plane;
- float d;
-
- while (1)
- {
- // if this is a leaf, accumulate the pvs bits
- if (node->contents < 0)
- {
- if (node->contents != CONTENTS_SOLID)
- {
- pvs = sv.worldmodel->brushq1.LeafPVS(sv.worldmodel, (mleaf_t *)node);
- for (i=0 ; i<fatbytes ; i++)
- fatpvs[i] |= pvs[i];
- }
- return;
- }
-
- plane = node->plane;
- d = DotProduct (org, plane->normal) - plane->dist;
- if (d > 8)
- node = node->children[0];
- else if (d < -8)
- node = node->children[1];
- else
- { // go down both
- SV_AddToFatPVS (org, node->children[0]);
- node = node->children[1];
- }
- }
-}
-
-/*
-=============
-SV_FatPVS
-
-Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the
-given point.
-=============
-*/
-qbyte *SV_FatPVS (vec3_t org)
-{
- fatbytes = (sv.worldmodel->brushq1.numleafs+31)>>3;
- memset (fatpvs, 0, fatbytes);
- SV_AddToFatPVS (org, sv.worldmodel->brushq1.nodes);
- return fatpvs;
-}
-
-//=============================================================================
-
-
-int SV_BoxTouchingPVS (qbyte *pvs, vec3_t mins, vec3_t maxs, mnode_t *node)
-{
- int leafnum;
-loc0:
- if (node->contents < 0)
- {
- // leaf
- if (node->contents == CONTENTS_SOLID)
- return false;
- leafnum = (mleaf_t *)node - sv.worldmodel->brushq1.leafs - 1;
- return pvs[leafnum >> 3] & (1 << (leafnum & 7));
- }
-
- // node - recurse down the BSP tree
- switch (BoxOnPlaneSide(mins, maxs, node->plane))
- {
- case 1: // front
- node = node->children[0];
- goto loc0;
- case 2: // back
- node = node->children[1];
- goto loc0;
- default: // crossing
- if (node->children[0]->contents != CONTENTS_SOLID)
- if (SV_BoxTouchingPVS (pvs, mins, maxs, node->children[0]))
- return true;
- node = node->children[1];
- goto loc0;
- }
- // never reached
- return false;
-}
-
-
-/*
-=============
-SV_WriteEntitiesToClient
-
-=============
-*/
-#ifdef QUAKEENTITIES
-void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
-{
- int e, clentnum, bits, alpha, glowcolor, glowsize, scale, effects, lightsize;
- int culled_pvs, culled_portal, culled_trace, visibleentities, totalentities;
- qbyte *pvs;
- vec3_t origin, angles, entmins, entmaxs, testorigin, testeye;
- float nextfullupdate, alphaf;
- edict_t *ent;
- eval_t *val;
- entity_state_t *baseline; // LordHavoc: delta or startup baseline
- model_t *model;
-
- Mod_CheckLoaded(sv.worldmodel);
-
-// find the client's PVS
- VectorAdd (clent->v->origin, clent->v->view_ofs, testeye);
- pvs = SV_FatPVS (testeye);
-
- 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))
- {
- bits = 0;
-
- // prevent delta compression against this frame (unless actually sent, which will restore this later)
- nextfullupdate = client->nextfullupdate[e];
- client->nextfullupdate[e] = -1;
-
- if (ent != clent) // LordHavoc: always send player
- {
- if ((val = GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict)
- {
- if (val->edict != clentnum)
- {
- // don't show to anyone else
- continue;
- }
- else
- bits |= U_VIEWMODEL; // show relative to the view
- }
- 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;
- if (glowsize > 255) glowsize = 255;
- if (glowsize < 0) glowsize = 0;
-
- if ((val = GETEDICTFIELDVALUE(ent, eval_glow_trail)))
- if (val->_float != 0)
- bits |= U_GLOWTRAIL;
-
- if (ent->v->modelindex >= 0 && ent->v->modelindex < MAX_MODELS && *PR_GetString(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 && (bits & U_GLOWTRAIL) == 0) // no effects
- continue;
- }
-
- VectorCopy(ent->v->angles, angles);
- VectorCopy(ent->v->origin, origin);
-
- // ent has survived every check so far, check if it is visible
- if (ent != clent && ((bits & U_VIEWMODEL) == 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->brushq1.nodes))
- {
- culled_pvs++;
- continue;
- }
-
- // or not visible through the portals
- if (sv_cullentities_portal.integer && !Portal_CheckBox(sv.worldmodel, testeye, entmins, entmaxs))
- {
- culled_portal++;
- continue;
- }
-
- // don't try to cull embedded brush models with this, they're sometimes huge (spanning several rooms)
- if (sv_cullentities_trace.integer && (model == NULL || model->type != mod_brush || model->name[0] != '*'))
- {
- // 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]);
-
- if (SV_Move(testeye, vec3_origin, vec3_origin, testorigin, MOVE_NOMONSTERS, NULL).fraction == 1)
- client->visibletime[e] = realtime + 1;
- else
- {
- //test nearest point on bbox
- testorigin[0] = bound(entmins[0], testeye[0], entmaxs[0]);
- testorigin[1] = bound(entmins[1], testeye[1], entmaxs[1]);
- testorigin[2] = bound(entmins[2], testeye[2], entmaxs[2]);
-
- if (SV_Move(testeye, vec3_origin, vec3_origin, testorigin, MOVE_NOMONSTERS, NULL).fraction == 1)
- client->visibletime[e] = realtime + 1;
- else if (realtime > client->visibletime[e])
- {
- culled_trace++;
- continue;
- }
- }
- }
- visibleentities++;
- }
-
- alphaf = 255.0f;
- scale = 16;
- glowcolor = 254;
- effects = ent->v->effects;
-
- if ((val = GETEDICTFIELDVALUE(ent, eval_alpha)))
- if (val->_float != 0)
- alphaf = val->_float * 255.0f;
-
- // HalfLife support
- if ((val = GETEDICTFIELDVALUE(ent, eval_renderamt)))
- if (val->_float != 0)
- alphaf = val->_float;
-
- if (alphaf == 0.0f)
- alphaf = 255.0f;
- alpha = bound(0, alphaf, 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 && (bits & U_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 (msg->maxsize - msg->cursize < 32) // LordHavoc: increased check from 16 to 32
- {
- Con_Printf ("packet overflow\n");
- // mark the rest of the entities so they can't be delta compressed against this frame
- for (;e < sv.num_edicts;e++)
- {
- client->nextfullupdate[e] = -1;
- client->visibletime[e] = -1;
- }
- return;
- }
-
- if ((val = GETEDICTFIELDVALUE(ent, eval_exteriormodeltoclient)) && val->edict == clentnum)
- bits = bits | U_EXTERIORMODEL;
-
-// send an update
- baseline = &ent->e->baseline;