]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_main.c
faster number to edict lookup (sv.edictstable) and faster edict to number lookup...
[xonotic/darkplaces.git] / sv_main.c
index 1dc26376f23bce324ecb5361977d4af9982cb962..7f250b0d8d45acf34ef73ab7470bdd69bc98031f 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -383,6 +383,7 @@ void SV_CheckForNewClients (void)
                SV_ConnectClient (i);
 
                net_activeconnections++;
+               NET_Heartbeat (1);
        }
 }
 
@@ -489,7 +490,7 @@ loc0:
        }
 
        // node - recurse down the BSP tree
-       switch (BOX_ON_PLANE_SIDE(mins, maxs, node->plane))
+       switch (BoxOnPlaneSide(mins, maxs, node->plane))
        {
        case 1: // front
                node = node->children[0];
@@ -518,7 +519,7 @@ 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;
+       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;
@@ -863,11 +864,11 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
 #else
 void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
 {
-       int e, clentnum, flags, alpha, glowcolor, glowsize, scale, effects;
+       int e, clentnum, flags, alpha, glowcolor, glowsize, scale, effects, modelindex;
        int culled_pvs, culled_portal, culled_trace, visibleentities, totalentities;
-       float alphaf;
+       float alphaf, lightsize;
        qbyte *pvs;
-       vec3_t origin, angles, entmins, entmaxs, testorigin, testeye;
+       vec3_t origin, angles, entmins, entmaxs, lightmins, lightmaxs, testorigin, testeye;
        edict_t *ent;
        eval_t *val;
        trace_t trace;
@@ -881,9 +882,19 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
        Mod_CheckLoaded(sv.worldmodel);
 
 // find the client's PVS
+       // the real place being tested from
        VectorAdd (clent->v.origin, clent->v.view_ofs, testeye);
        pvs = SV_FatPVS (testeye);
-       EntityFrame_Clear(&entityframe, testeye);
+
+       // the place being reported (to consider the fact the client still
+       // applies the view_ofs[2], so we have to only send the fractional part
+       // of view_ofs[2], undoing what the client will redo)
+       VectorCopy (testeye, testorigin);
+       e = (int) clent->v.view_ofs[2] & 255;
+       if (e >= 128)
+               e -= 256;
+       testorigin[2] -= (float) e;
+       EntityFrame_Clear(&entityframe, testorigin);
 
        culled_pvs = 0;
        culled_portal = 0;
@@ -921,17 +932,45 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                }
 
                glowsize = 0;
-
+               effects = ent->v.effects;
                if ((val = GETEDICTFIELDVALUE(ent, eval_glow_size)))
                        glowsize = (int) val->_float >> 2;
                glowsize = bound(0, glowsize, 255);
 
+               lightsize = 0;
+               if (effects & (EF_BRIGHTFIELD | EF_MUZZLEFLASH | EF_BRIGHTLIGHT | EF_DIMLIGHT | EF_RED | EF_BLUE | EF_FLAME | EF_STARDUST))
+               {
+                       if (effects & EF_BRIGHTFIELD)
+                               lightsize = max(lightsize, 80);
+                       if (effects & EF_MUZZLEFLASH)
+                               lightsize = max(lightsize, 100);
+                       if (effects & EF_BRIGHTLIGHT)
+                               lightsize = max(lightsize, 400);
+                       if (effects & EF_DIMLIGHT)
+                               lightsize = max(lightsize, 200);
+                       if (effects & EF_RED)
+                               lightsize = max(lightsize, 200);
+                       if (effects & EF_BLUE)
+                               lightsize = max(lightsize, 200);
+                       if (effects & EF_FLAME)
+                               lightsize = max(lightsize, 250);
+                       if (effects & EF_STARDUST)
+                               lightsize = max(lightsize, 100);
+               }
+               if (glowsize)
+                       lightsize = max(lightsize, glowsize << 2);
+
                if ((val = GETEDICTFIELDVALUE(ent, eval_glow_trail)))
                if (val->_float != 0)
+               {
                        flags |= RENDER_GLOWTRAIL;
+                       lightsize = max(lightsize, 100);
+               }
 
+               modelindex = 0;
                if (ent->v.modelindex >= 0 && ent->v.modelindex < MAX_MODELS && pr_strings[ent->v.model])
                {
+                       modelindex = ent->v.modelindex;
                        model = sv.models[(int)ent->v.modelindex];
                        Mod_CheckLoaded(model);
                }
@@ -939,7 +978,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                {
                        model = NULL;
                        if (ent != clent) // LordHavoc: always send player
-                               if (glowsize == 0 && (flags & RENDER_GLOWTRAIL) == 0) // no effects
+                               if (lightsize == 0) // no effects
                                        continue;
                }
 
@@ -986,18 +1025,24 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                                        VectorAdd(entmaxs, model->normalmaxs, entmaxs);
                                }
                        }
+                       lightmins[0] = min(entmins[0], origin[0] - lightsize);
+                       lightmins[1] = min(entmins[1], origin[1] - lightsize);
+                       lightmins[2] = min(entmins[2], origin[2] - lightsize);
+                       lightmaxs[0] = min(entmaxs[0], origin[0] + lightsize);
+                       lightmaxs[1] = min(entmaxs[1], origin[1] + lightsize);
+                       lightmaxs[2] = min(entmaxs[2], origin[2] + lightsize);
 
                        totalentities++;
 
                        // if not touching a visible leaf
-                       if (sv_cullentities_pvs.integer && !SV_BoxTouchingPVS(pvs, entmins, entmaxs, sv.worldmodel->nodes))
+                       if (sv_cullentities_pvs.integer && !SV_BoxTouchingPVS(pvs, lightmins, lightmaxs, sv.worldmodel->nodes))
                        {
                                culled_pvs++;
                                continue;
                        }
 
                        // or not visible through the portals
-                       if (sv_cullentities_portal.integer && !Portal_CheckBox(sv.worldmodel, testeye, entmins, entmaxs))
+                       if (sv_cullentities_portal.integer && !Portal_CheckBox(sv.worldmodel, testeye, lightmins, lightmaxs))
                        {
                                culled_portal++;
                                continue;
@@ -1005,21 +1050,50 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
 
                        if (sv_cullentities_trace.integer)
                        {
-                               // 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]);
-
+                               // LordHavoc: test center first
+                               testorigin[0] = (entmins[0] + entmaxs[0]) * 0.5f;
+                               testorigin[1] = (entmins[1] + entmaxs[1]) * 0.5f;
+                               testorigin[2] = (entmins[2] + entmaxs[2]) * 0.5f;
                                Collision_ClipTrace(&trace, NULL, sv.worldmodel, vec3_origin, vec3_origin, vec3_origin, vec3_origin, testeye, vec3_origin, vec3_origin, testorigin);
-
                                if (trace.fraction == 1)
                                        client->visibletime[e] = realtime + 1;
                                else
                                {
-                                       if (realtime > client->visibletime[e])
+                                       // 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]);
+                                       Collision_ClipTrace(&trace, NULL, sv.worldmodel, vec3_origin, vec3_origin, vec3_origin, vec3_origin, testeye, vec3_origin, vec3_origin, testorigin);
+                                       if (trace.fraction == 1)
+                                               client->visibletime[e] = realtime + 1;
+                                       else
                                        {
-                                               culled_trace++;
-                                               continue;
+                                               if (lightsize)
+                                               {
+                                                       // LordHavoc: test random offsets, to maximize chance of detection
+                                                       testorigin[0] = lhrandom(lightmins[0], lightmaxs[0]);
+                                                       testorigin[1] = lhrandom(lightmins[1], lightmaxs[1]);
+                                                       testorigin[2] = lhrandom(lightmins[2], lightmaxs[2]);
+                                                       Collision_ClipTrace(&trace, NULL, sv.worldmodel, vec3_origin, vec3_origin, vec3_origin, vec3_origin, testeye, vec3_origin, vec3_origin, testorigin);
+                                                       if (trace.fraction == 1)
+                                                               client->visibletime[e] = realtime + 1;
+                                                       else
+                                                       {
+                                                               if (realtime > client->visibletime[e])
+                                                               {
+                                                                       culled_trace++;
+                                                                       continue;
+                                                               }
+                                                       }
+                                               }
+                                               else
+                                               {
+                                                       if (realtime > client->visibletime[e])
+                                                       {
+                                                               culled_trace++;
+                                                               continue;
+                                                       }
+                                               }
                                        }
                                }
                        }
@@ -1059,7 +1133,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
 
                if (ent != clent)
                {
-                       if (glowsize == 0 && (flags & RENDER_GLOWTRAIL) == 0) // no effects
+                       if (lightsize == 0) // no effects
                        {
                                if (model) // model
                                {
@@ -1087,10 +1161,12 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                        break;
                VectorCopy(origin, s->origin);
                VectorCopy(angles, s->angles);
+               if (ent->v.colormap >= 1024)
+                       flags |= RENDER_COLORMAPPED;
                s->colormap = ent->v.colormap;
                s->skin = ent->v.skin;
                s->frame = ent->v.frame;
-               s->modelindex = ent->v.modelindex;
+               s->modelindex = modelindex;
                s->effects = effects;
                s->alpha = alpha;
                s->scale = scale;
@@ -1170,7 +1246,8 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
 
        bits = 0;
 
-       bits |= SU_VIEWHEIGHT;
+       if (ent->v.view_ofs[2] != DEFAULT_VIEWHEIGHT)
+               bits |= SU_VIEWHEIGHT;
 
        if (ent->v.idealpitch)
                bits |= SU_IDEALPITCH;
@@ -1244,8 +1321,7 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
                MSG_WriteByte(msg, bits >> 24);
 
        if (bits & SU_VIEWHEIGHT)
-               //MSG_WriteChar (msg, ent->v.view_ofs[2]);
-               MSG_WriteChar (msg, 0);
+               MSG_WriteChar (msg, ent->v.view_ofs[2]);
 
        if (bits & SU_IDEALPITCH)
                MSG_WriteChar (msg, ent->v.idealpitch);
@@ -1493,9 +1569,9 @@ SV_ModelIndex
 
 ================
 */
-int SV_ModelIndex (char *name)
+int SV_ModelIndex (const char *name)
 {
-       int             i;
+       int i;
 
        if (!name || !name[0])
                return 0;
@@ -1644,7 +1720,7 @@ This is called at the start of each level
 */
 extern float           scr_centertime_off;
 
-void SV_SpawnServer (char *server)
+void SV_SpawnServer (const char *server)
 {
        edict_t         *ent;
        int                     i;
@@ -1690,6 +1766,13 @@ void SV_SpawnServer (char *server)
        // clear the edict memory pool
        Mem_EmptyPool(sv_edicts_mempool);
        sv.edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size);
+       sv.edictstable = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
+       for (i = 0;i < MAX_EDICTS;i++)
+       {
+               ent = (edict_t *)((qbyte *)sv.edicts + (i * pr_edict_size));
+               ent->number = i;
+               sv.edictstable[i] = ent;
+       }
 
        sv.datagram.maxsize = sizeof(sv.datagram_buf);
        sv.datagram.cursize = 0;
@@ -1793,5 +1876,6 @@ void SV_SpawnServer (char *server)
                        SV_SendServerinfo (host_client);
 
        Con_DPrintf ("Server spawned.\n");
+       NET_Heartbeat (2);
 }