]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
reverted dynamic allocation of sv.edicts because there are FAR too many broken pointe...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 26 Apr 2003 10:21:02 +0000 (10:21 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 26 Apr 2003 10:21:02 +0000 (10:21 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2989 d7cf8633-e32d-0410-b094-e92efae38249

12 files changed:
cl_main.c
host.c
host_cmd.c
net_dgrm.c
pr_cmds.c
pr_edict.c
progs.h
server.h
sv_main.c
sv_phys.c
sv_user.c
world.c

index ce00b637c92814b5accb451bb556e7f8c080586c..03e340702f19cd01f4900e44344f39289f932fd0 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -1572,7 +1572,7 @@ static void CL_PModel_f (void)
        }
 
        host_client->pmodel = i;
        }
 
        host_client->pmodel = i;
-       if ((val = GETEDICTFIELDVALUE(EDICT_NUM(host_client->edictnumber), eval_pmodel)))
+       if ((val = GETEDICTFIELDVALUE(sv_player, eval_pmodel)))
                val->_float = i;
 }
 
                val->_float = i;
 }
 
diff --git a/host.c b/host.c
index d11b8f66fe1444d03c9c64c7623fad4240b1ee27..c5c783b56eec9cd3dd702f078da35ad2f68a2e0e 100644 (file)
--- a/host.c
+++ b/host.c
@@ -455,12 +455,12 @@ void SV_DropClient (qboolean crash)
        // note: don't clear name yet
        net_activeconnections--;
 
        // note: don't clear name yet
        net_activeconnections--;
 
-       if (sv.active && host_client->edictnumber && host_client->spawned) // LordHavoc: don't call QC if server is dead (avoids recursive Host_Error in some mods when they run out of edicts)
+       if (sv.active && host_client->edict && host_client->spawned) // LordHavoc: don't call QC if server is dead (avoids recursive Host_Error in some mods when they run out of edicts)
        {
        // call the prog function for removing a client
        // this will set the body to a dead frame, among other things
                saveSelf = pr_global_struct->self;
        {
        // call the prog function for removing a client
        // this will set the body to a dead frame, among other things
                saveSelf = pr_global_struct->self;
-               pr_global_struct->self = EDICT_TO_PROG(EDICT_NUM(host_client->edictnumber));
+               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
                PR_ExecuteProgram (pr_global_struct->ClientDisconnect, "QC function ClientDisconnect is missing");
                pr_global_struct->self = saveSelf;
        }
                PR_ExecuteProgram (pr_global_struct->ClientDisconnect, "QC function ClientDisconnect is missing");
                pr_global_struct->self = saveSelf;
        }
index 1aca802bfb70d287e68cf5d86c47037644ae960e..f2737124f97d6926cddb0ac4cc097afff20a3cf5 100644 (file)
@@ -89,7 +89,7 @@ void Host_Status_f (void)
                }
                else
                        hours = 0;
                }
                else
                        hours = 0;
-               print ("#%-2u %-16.16s  %3i  %2i:%02i:%02i\n", j+1, client->name, (int)EDICT_NUM(client->edictnumber)->v->frags, hours, minutes, seconds);
+               print ("#%-2u %-16.16s  %3i  %2i:%02i:%02i\n", j+1, client->name, (int)client->edict->v->frags, hours, minutes, seconds);
                print ("   %s\n", client->netconnection->address);
        }
 }
                print ("   %s\n", client->netconnection->address);
        }
 }
@@ -418,7 +418,7 @@ void Host_Savegame_f (void)
 
        for (i=0 ; i<svs.maxclients ; i++)
        {
 
        for (i=0 ; i<svs.maxclients ; i++)
        {
-               if (svs.clients[i].active && (EDICT_NUM(svs.clients[i].edictnumber)->v->health <= 0) )
+               if (svs.clients[i].active && (svs.clients[i].edict->v->health <= 0) )
                {
                        Con_Printf ("Can't savegame with a dead player\n");
                        return;
                {
                        Con_Printf ("Can't savegame with a dead player\n");
                        return;
@@ -602,11 +602,11 @@ void Host_PerformLoadGame(char *name)
                        // parse an edict
                        ent = EDICT_NUM(entnum);
                        memset (ent->v, 0, progs->entityfields * 4);
                        // parse an edict
                        ent = EDICT_NUM(entnum);
                        memset (ent->v, 0, progs->entityfields * 4);
-                       ent->free = false;
+                       ent->e->free = false;
                        ED_ParseEdict (start, ent);
 
                        // link it into the bsp tree
                        ED_ParseEdict (start, ent);
 
                        // link it into the bsp tree
-                       if (!ent->free)
+                       if (!ent->e->free)
                                SV_LinkEdict (ent, false);
                }
 
                                SV_LinkEdict (ent, false);
                }
 
@@ -665,7 +665,7 @@ void Host_Name_f (void)
                if (strcmp(host_client->name, newName) != 0)
                        Con_Printf ("%s renamed to %s\n", host_client->name, newName);
        strcpy (host_client->name, newName);
                if (strcmp(host_client->name, newName) != 0)
                        Con_Printf ("%s renamed to %s\n", host_client->name, newName);
        strcpy (host_client->name, newName);
-       EDICT_NUM(host_client->edictnumber)->v->netname = PR_SetString(host_client->name);
+       sv_player->v->netname = PR_SetString(host_client->name);
 
 // send notification to all clients
 
 
 // send notification to all clients
 
@@ -740,7 +740,7 @@ void Host_Say(qboolean teamonly)
        {
                if (!client || !client->active || !client->spawned)
                        continue;
        {
                if (!client || !client->active || !client->spawned)
                        continue;
-               if (teamplay.integer && teamonly && EDICT_NUM(client->edictnumber)->v->team != EDICT_NUM(save->edictnumber)->v->team)
+               if (teamplay.integer && teamonly && client->edict->v->team != save->edict->v->team)
                        continue;
                host_client = client;
                SV_ClientPrintf("%s", text);
                        continue;
                host_client = client;
                SV_ClientPrintf("%s", text);
@@ -883,13 +883,13 @@ void Host_Color_f(void)
                Con_DPrintf("Calling SV_ChangeTeam\n");
                pr_global_struct->time = sv.time;
                pr_globals[OFS_PARM0] = playercolor;
                Con_DPrintf("Calling SV_ChangeTeam\n");
                pr_global_struct->time = sv.time;
                pr_globals[OFS_PARM0] = playercolor;
-               pr_global_struct->self = EDICT_TO_PROG(EDICT_NUM(host_client->edictnumber));
+               pr_global_struct->self = EDICT_TO_PROG(sv_player);
                PR_ExecuteProgram (SV_ChangeTeam, "");
        }
        else
        {
                host_client->colors = playercolor;
                PR_ExecuteProgram (SV_ChangeTeam, "");
        }
        else
        {
                host_client->colors = playercolor;
-               EDICT_NUM(host_client->edictnumber)->v->team = bottom + 1;
+               sv_player->v->team = bottom + 1;
 
                // send notification to all clients
                MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
 
                // send notification to all clients
                MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
@@ -918,7 +918,7 @@ void Host_Kill_f (void)
        }
 
        pr_global_struct->time = sv.time;
        }
 
        pr_global_struct->time = sv.time;
-       pr_global_struct->self = EDICT_TO_PROG(sv_player);
+       pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
        PR_ExecuteProgram (pr_global_struct->ClientKill, "QC function ClientKill is missing");
 }
 
        PR_ExecuteProgram (pr_global_struct->ClientKill, "QC function ClientKill is missing");
 }
 
@@ -1014,6 +1014,8 @@ void Host_Spawn_f (void)
 // send all current names, colors, and frag counts
        SZ_Clear (&host_client->message);
 
 // send all current names, colors, and frag counts
        SZ_Clear (&host_client->message);
 
+       ent = sv_player;
+
 // run the entrance script
        if (sv.loadgame)
        {
 // run the entrance script
        if (sv.loadgame)
        {
@@ -1034,9 +1036,7 @@ void Host_Spawn_f (void)
        {
                eval_t *val;
                // set up the edict
        {
                eval_t *val;
                // set up the edict
-               ent = EDICT_NUM(host_client->edictnumber);
-
-               memset (ent->v, 0, progs->entityfields * 4);
+               ED_ClearEdict(ent);
                ent->v->colormap = NUM_FOR_EDICT(ent);
                ent->v->team = (host_client->colors & 15) + 1;
                ent->v->netname = PR_SetString(host_client->name);
                ent->v->colormap = NUM_FOR_EDICT(ent);
                ent->v->team = (host_client->colors & 15) + 1;
                ent->v->netname = PR_SetString(host_client->name);
@@ -1110,7 +1110,6 @@ void Host_Spawn_f (void)
 // in a state where it is expecting the client to correct the angle
 // and it won't happen if the game was just loaded, so you wind up
 // with a permanent head tilt
 // in a state where it is expecting the client to correct the angle
 // and it won't happen if the game was just loaded, so you wind up
 // with a permanent head tilt
-       ent = EDICT_NUM( 1 + (host_client - svs.clients) );
        MSG_WriteByte (&host_client->message, svc_setangle);
        for (i=0 ; i < 2 ; i++)
                MSG_WriteAngle (&host_client->message, ent->v->angles[i] );
        MSG_WriteByte (&host_client->message, svc_setangle);
        for (i=0 ; i < 2 ; i++)
                MSG_WriteAngle (&host_client->message, ent->v->angles[i] );
index b271f9d7017f010744135d360c9210a0390d3dea..b3f7fae2c4d67a41bc63a311506051ef0e4ab17a 100644 (file)
@@ -916,7 +916,7 @@ static qsocket_t *_Datagram_CheckNewConnections (void)
                MSG_WriteByte(&net_message, playerNumber);
                MSG_WriteString(&net_message, client->name);
                MSG_WriteLong(&net_message, client->colors);
                MSG_WriteByte(&net_message, playerNumber);
                MSG_WriteString(&net_message, client->name);
                MSG_WriteLong(&net_message, client->colors);
-               MSG_WriteLong(&net_message, (int)EDICT_NUM(client->edictnumber)->v->frags);
+               MSG_WriteLong(&net_message, (int)client->edict->v->frags);
                MSG_WriteLong(&net_message, (int)(net_time - client->netconnection->connecttime));
                MSG_WriteString(&net_message, client->netconnection->address);
                *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
                MSG_WriteLong(&net_message, (int)(net_time - client->netconnection->connecttime));
                MSG_WriteString(&net_message, client->netconnection->address);
                *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
index 0da857a852ed0c6196311235bcb7737e9e1d7441..e33360bb569f551ddbddcf71bda9fd3539e168f3 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -851,7 +851,7 @@ int PF_newcheckclient (int check)
                if (i == check)
                        break;  // didn't find anything else
 
                if (i == check)
                        break;  // didn't find anything else
 
-               if (ent->free)
+               if (ent->e->free)
                        continue;
                if (ent->v->health <= 0)
                        continue;
                        continue;
                if (ent->v->health <= 0)
                        continue;
@@ -903,7 +903,7 @@ void PF_checkclient (void)
 
        // return check if it might be visible
        ent = EDICT_NUM(sv.lastcheck);
 
        // return check if it might be visible
        ent = EDICT_NUM(sv.lastcheck);
-       if (ent->free || ent->v->health <= 0)
+       if (ent->e->free || ent->v->health <= 0)
        {
                RETURN_EDICT(sv.edicts);
                return;
        {
                RETURN_EDICT(sv.edicts);
                return;
@@ -1036,7 +1036,7 @@ void PF_findradius (void)
        for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
        {
                pr_xfunction->builtinsprofile++;
        for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
        {
                pr_xfunction->builtinsprofile++;
-               if (ent->free)
+               if (ent->e->free)
                        continue;
                if (ent->v->solid == SOLID_NOT)
                        continue;
                        continue;
                if (ent->v->solid == SOLID_NOT)
                        continue;
@@ -1159,7 +1159,7 @@ void PF_Find (void)
        {
                pr_xfunction->builtinsprofile++;
                ed = EDICT_NUM(e);
        {
                pr_xfunction->builtinsprofile++;
                ed = EDICT_NUM(e);
-               if (ed->free)
+               if (ed->e->free)
                        continue;
                t = E_STRING(ed,f);
                if (!t)
                        continue;
                t = E_STRING(ed,f);
                if (!t)
@@ -1190,7 +1190,7 @@ void PF_FindFloat (void)
        {
                pr_xfunction->builtinsprofile++;
                ed = EDICT_NUM(e);
        {
                pr_xfunction->builtinsprofile++;
                ed = EDICT_NUM(e);
-               if (ed->free)
+               if (ed->e->free)
                        continue;
                if (E_FLOAT(ed,f) == s)
                {
                        continue;
                if (E_FLOAT(ed,f) == s)
                {
@@ -1225,7 +1225,7 @@ void PF_findchain (void)
        for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
        {
                pr_xfunction->builtinsprofile++;
        for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
        {
                pr_xfunction->builtinsprofile++;
-               if (ent->free)
+               if (ent->e->free)
                        continue;
                t = E_STRING(ent,f);
                if (!t)
                        continue;
                t = E_STRING(ent,f);
                if (!t)
@@ -1258,7 +1258,7 @@ void PF_findchainfloat (void)
        for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
        {
                pr_xfunction->builtinsprofile++;
        for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
        {
                pr_xfunction->builtinsprofile++;
-               if (ent->free)
+               if (ent->e->free)
                        continue;
                if (E_FLOAT(ent,f) != s)
                        continue;
                        continue;
                if (E_FLOAT(ent,f) != s)
                        continue;
@@ -1428,7 +1428,7 @@ void PF_droptofloor (void)
                ent->v->groundentity = EDICT_TO_PROG(trace.ent);
                G_FLOAT(OFS_RETURN) = 1;
                // if support is destroyed, keep suspended (gross hack for floating items in various maps)
                ent->v->groundentity = EDICT_TO_PROG(trace.ent);
                G_FLOAT(OFS_RETURN) = 1;
                // if support is destroyed, keep suspended (gross hack for floating items in various maps)
-               ent->suspendedinairflag = true;
+               ent->e->suspendedinairflag = true;
        }
 }
 
        }
 }
 
@@ -1527,7 +1527,7 @@ void PF_nextent (void)
                        return;
                }
                ent = EDICT_NUM(i);
                        return;
                }
                ent = EDICT_NUM(i);
-               if (!ent->free)
+               if (!ent->e->free)
                {
                        RETURN_EDICT(ent);
                        return;
                {
                        RETURN_EDICT(ent);
                        return;
@@ -2103,7 +2103,7 @@ void PF_setcolor (void)
 
        client = &svs.clients[entnum-1];
        client->colors = i;
 
        client = &svs.clients[entnum-1];
        client->colors = i;
-       EDICT_NUM(client->edictnumber)->v->team = (i & 15) + 1;
+       client->edict->v->team = (i & 15) + 1;
 
        MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
        MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
 
        MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
        MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
@@ -2547,7 +2547,7 @@ static msurface_t *getsurface(edict_t *ed, int surfnum)
 {
        int modelindex;
        model_t *model;
 {
        int modelindex;
        model_t *model;
-       if (!ed || ed->free)
+       if (!ed || ed->e->free)
                return NULL;
        modelindex = ed->v->modelindex;
        if (modelindex < 1 || modelindex >= MAX_MODELS)
                return NULL;
        modelindex = ed->v->modelindex;
        if (modelindex < 1 || modelindex >= MAX_MODELS)
@@ -2582,7 +2582,7 @@ void PF_getsurfacepoint(void)
        int pointnum;
        VectorClear(G_VECTOR(OFS_RETURN));
        ed = G_EDICT(OFS_PARM0);
        int pointnum;
        VectorClear(G_VECTOR(OFS_RETURN));
        ed = G_EDICT(OFS_PARM0);
-       if (!ed || ed->free)
+       if (!ed || ed->e->free)
                return;
        if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
                return;
                return;
        if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
                return;
@@ -2628,7 +2628,7 @@ void PF_getsurfacenearpoint(void)
        ed = G_EDICT(OFS_PARM0);
        point = G_VECTOR(OFS_PARM1);
 
        ed = G_EDICT(OFS_PARM0);
        point = G_VECTOR(OFS_PARM1);
 
-       if (!ed || ed->free)
+       if (!ed || ed->e->free)
                return;
        modelindex = ed->v->modelindex;
        if (modelindex < 1 || modelindex >= MAX_MODELS)
                return;
        modelindex = ed->v->modelindex;
        if (modelindex < 1 || modelindex >= MAX_MODELS)
@@ -2668,7 +2668,7 @@ void PF_getsurfaceclippedpoint(void)
        vec3_t p, out;
        VectorClear(G_VECTOR(OFS_RETURN));
        ed = G_EDICT(OFS_PARM0);
        vec3_t p, out;
        VectorClear(G_VECTOR(OFS_RETURN));
        ed = G_EDICT(OFS_PARM0);
-       if (!ed || ed->free)
+       if (!ed || ed->e->free)
                return;
        if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
                return;
                return;
        if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
                return;
index d7875c5dcdeb344d6326555ceeea084c1c7ff3cf..ec7ffb83786dbb981d27c6d20364eee9e5f119b8 100644 (file)
@@ -185,7 +185,7 @@ Sets everything to NULL
 void ED_ClearEdict (edict_t *e)
 {
        memset (e->v, 0, progs->entityfields * 4);
 void ED_ClearEdict (edict_t *e)
 {
        memset (e->v, 0, progs->entityfields * 4);
-       e->free = false;
+       e->e->free = false;
 }
 
 /*
 }
 
 /*
@@ -210,7 +210,7 @@ edict_t *ED_Alloc (void)
                e = EDICT_NUM(i);
                // the first couple seconds of server time can involve a lot of
                // freeing and allocating, so relax the replacement policy
                e = EDICT_NUM(i);
                // the first couple seconds of server time can involve a lot of
                // freeing and allocating, so relax the replacement policy
-               if (e->free && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) )
+               if (e->e->free && ( e->e->freetime < 2 || sv.time - e->e->freetime > 0.5 ) )
                {
                        ED_ClearEdict (e);
                        return e;
                {
                        ED_ClearEdict (e);
                        return e;
@@ -241,7 +241,7 @@ void ED_Free (edict_t *ed)
 {
        SV_UnlinkEdict (ed);            // unlink from world bsp
 
 {
        SV_UnlinkEdict (ed);            // unlink from world bsp
 
-       ed->free = true;
+       ed->e->free = true;
        ed->v->model = 0;
        ed->v->takedamage = 0;
        ed->v->modelindex = 0;
        ed->v->model = 0;
        ed->v->takedamage = 0;
        ed->v->modelindex = 0;
@@ -253,7 +253,7 @@ void ED_Free (edict_t *ed)
        ed->v->nextthink = -1;
        ed->v->solid = 0;
 
        ed->v->nextthink = -1;
        ed->v->solid = 0;
 
-       ed->freetime = sv.time;
+       ed->e->freetime = sv.time;
 }
 
 //===========================================================================
 }
 
 //===========================================================================
@@ -561,7 +561,7 @@ void ED_Print (edict_t *ed)
        int             type;
        char    tempstring[8192], tempstring2[260]; // temporary string buffers
 
        int             type;
        char    tempstring[8192], tempstring2[260]; // temporary string buffers
 
-       if (ed->free)
+       if (ed->e->free)
        {
                Con_Printf ("FREE\n");
                return;
        {
                Con_Printf ("FREE\n");
                return;
@@ -636,7 +636,7 @@ void ED_Write (qfile_t *f, edict_t *ed)
 
        FS_Printf (f, "{\n");
 
 
        FS_Printf (f, "{\n");
 
-       if (ed->free)
+       if (ed->e->free)
        {
                FS_Printf (f, "}\n");
                return;
        {
                FS_Printf (f, "}\n");
                return;
@@ -724,7 +724,7 @@ void ED_Count (void)
        for (i=0 ; i<sv.num_edicts ; i++)
        {
                ent = EDICT_NUM(i);
        for (i=0 ; i<sv.num_edicts ; i++)
        {
                ent = EDICT_NUM(i);
-               if (ent->free)
+               if (ent->e->free)
                        continue;
                active++;
                if (ent->v->solid)
                        continue;
                active++;
                if (ent->v->solid)
@@ -1021,7 +1021,7 @@ const char *ED_ParseEdict (const char *data, edict_t *ent)
        }
 
        if (!init)
        }
 
        if (!init)
-               ent->free = true;
+               ent->e->free = true;
 
        return data;
 }
 
        return data;
 }
@@ -1118,7 +1118,7 @@ void ED_LoadFromFile (const char *data)
                pr_global_struct->self = EDICT_TO_PROG(ent);
                PR_ExecuteProgram (func - pr_functions, "");
                spawned++;
                pr_global_struct->self = EDICT_TO_PROG(ent);
                PR_ExecuteProgram (func - pr_functions, "");
                spawned++;
-               if (ent->free)
+               if (ent->e->free)
                        died++;
        }
 
                        died++;
        }
 
@@ -1413,7 +1413,7 @@ void PR_Fields_f (void)
        for (ednum = 0;ednum < MAX_EDICTS;ednum++)
        {
                ed = EDICT_NUM(ednum);
        for (ednum = 0;ednum < MAX_EDICTS;ednum++)
        {
                ed = EDICT_NUM(ednum);
-               if (ed->free)
+               if (ed->e->free)
                        continue;
                for (i = 1;i < progs->numfielddefs;i++)
                {
                        continue;
                for (i = 1;i < progs->numfielddefs;i++)
                {
@@ -1596,7 +1596,7 @@ int NUM_FOR_EDICT(edict_t *e)
 //}
 
 //#define      EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
 //}
 
 //#define      EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
-//#define PROG_TO_EDICT(e) (sv.edictstable[(e) / (progs->entityfields * 4)])
+//#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
 int EDICT_TO_PROG(edict_t *e)
 {
        int n;
 int EDICT_TO_PROG(edict_t *e)
 {
        int n;
@@ -1610,8 +1610,8 @@ edict_t *PROG_TO_EDICT(int n)
 {
        if ((unsigned int)n >= (unsigned int)sv.max_edicts)
                Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
 {
        if ((unsigned int)n >= (unsigned int)sv.max_edicts)
                Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
-       return sv.edictstable[n]; // EXPERIMENTAL
-       //return sv.edictstable[(n) / (progs->entityfields * 4)];
+       return sv.edicts + n; // EXPERIMENTAL
+       //return sv.edicts + ((n) / (progs->entityfields * 4));
 }
 */
 
 }
 */
 
diff --git a/progs.h b/progs.h
index 929bd27c0b1a636bd38ddd6b7e33e5fb96038d71..415a11d65b519ea1f1b1a7010ff03370ef65a9da 100644 (file)
--- a/progs.h
+++ b/progs.h
@@ -43,11 +43,14 @@ typedef struct link_s
 
 #define ENTITYGRIDAREAS 16
 
 
 #define ENTITYGRIDAREAS 16
 
-// the entire server entity structure
-typedef struct edict_s
+typedef struct edict_engineprivate_s
 {
        // true if this edict is unused
        qboolean free;
 {
        // true if this edict is unused
        qboolean free;
+       // sv.time when the object was freed (to prevent early reuse which could
+       // mess up client interpolation or obscure severe QuakeC bugs)
+       float freetime;
+
        // physics grid areas this edict is linked into
        link_t areagrid[ENTITYGRIDAREAS];
        // since the areagrid can have multiple references to one entity,
        // physics grid areas this edict is linked into
        link_t areagrid[ENTITYGRIDAREAS];
        // since the areagrid can have multiple references to one entity,
@@ -64,16 +67,23 @@ typedef struct edict_s
 
        // LordHavoc: gross hack to make floating items still work
        int suspendedinairflag;
 
        // LordHavoc: gross hack to make floating items still work
        int suspendedinairflag;
-       // sv.time when the object was freed (to prevent early reuse which could
-       // mess up client interpolation or obscure severe QuakeC bugs)
-       float freetime;
        // used by PushMove to keep track of where objects were before they were
        // moved, in case they need to be moved back
        vec3_t moved_from;
        vec3_t moved_fromangles;
        // used by PushMove to keep track of where objects were before they were
        // moved, in case they need to be moved back
        vec3_t moved_from;
        vec3_t moved_fromangles;
-       // edict fields (stored in another array)
+}
+edict_engineprivate_t;
+
+// the entire server entity structure
+// NOTE: keep this small!  priv and v are dynamic but this struct is not!
+typedef struct edict_s
+{
+       // engine-private fields (stored in dynamically resized array)
+       edict_engineprivate_t *e;
+       // QuakeC fields (stored in dynamically resized array)
        entvars_t *v;
        entvars_t *v;
-} edict_t;
+}
+edict_t;
 
 // LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue...  see pr_edict.c for the functions which use these.
 extern int eval_gravity;
 
 // LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue...  see pr_edict.c for the functions which use these.
 extern int eval_gravity;
@@ -144,6 +154,7 @@ void PR_Crash (void);
 
 edict_t *ED_Alloc (void);
 void ED_Free (edict_t *ed);
 
 edict_t *ED_Alloc (void);
 void ED_Free (edict_t *ed);
+void ED_ClearEdict (edict_t *e);
 
 char   *ED_NewString (const char *string);
 // returns a copy of the string allocated from the server's string heap
 
 char   *ED_NewString (const char *string);
 // returns a copy of the string allocated from the server's string heap
@@ -158,7 +169,7 @@ void ED_ParseGlobals (const char *data);
 void ED_LoadFromFile (const char *data);
 
 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline);
 void ED_LoadFromFile (const char *data);
 
 edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline);
-#define EDICT_NUM(n) (((n) >= 0 && (n) < sv.max_edicts) ? sv.edictstable[(n)] : EDICT_NUM_ERROR(n, __FILE__, __LINE__))
+#define EDICT_NUM(n) (((n) >= 0 && (n) < sv.max_edicts) ? sv.edicts + (n) : EDICT_NUM_ERROR(n, __FILE__, __LINE__))
 
 //int NUM_FOR_EDICT_ERROR(edict_t *e);
 #define NUM_FOR_EDICT(e) ((edict_t *)(e) - sv.edicts)
 
 //int NUM_FOR_EDICT_ERROR(edict_t *e);
 #define NUM_FOR_EDICT(e) ((edict_t *)(e) - sv.edicts)
index 47e917c24e6171bbdf8a5c22dbf2b5579c96bfa1..a54fbf00e8d70a74477fe5bcc777cfd8a8526e54 100644 (file)
--- a/server.h
+++ b/server.h
@@ -67,13 +67,17 @@ typedef struct
        char *lightstyles[MAX_LIGHTSTYLES];
        int num_edicts;
        int max_edicts;
        char *lightstyles[MAX_LIGHTSTYLES];
        int num_edicts;
        int max_edicts;
-       // can NOT be array indexed, because edict_t is variable sized, but can be used to reference the world ent
+       // small edict_t structures which just contain pointers
+       // (allocated at server startup only)
        edict_t *edicts;
        edict_t *edicts;
-       // can be array indexed
-       edict_t **edictstable;
-       // array of QC edict field variables
+       // engine private edict information
+       // (dynamically resized - always access through edict_t!)
+       edict_engineprivate_t *edictsengineprivate;
+       // QuakeC fields array
+       // (dynamically resized - always access through edict_t!)
        void *edictsfields;
        // PushMove sometimes has to move entities back from a failed move
        void *edictsfields;
        // PushMove sometimes has to move entities back from a failed move
+       // (dynamically resized)
        edict_t **moved_edicts;
        // some actions are only valid during load
        server_state_t state;
        edict_t **moved_edicts;
        // some actions are only valid during load
        server_state_t state;
@@ -127,8 +131,8 @@ typedef struct client_s
        // can be added to at any time, copied and clear once per frame
        sizebuf_t message;
        qbyte msgbuf[MAX_DATAGRAM];
        // can be added to at any time, copied and clear once per frame
        sizebuf_t message;
        qbyte msgbuf[MAX_DATAGRAM];
-       // (clientnum+1)
-       int edictnumber;
+       // EDICT_NUM(clientnum+1)
+       edict_t *edict;
        // for printing to other people
        char name[32];
        int colors;
        // for printing to other people
        char name[32];
        int colors;
index d6edc1a89eee4e2f01fc3f981ad94c626c3ef6f1..73827de419f9fae920ecf696fb8f77863c67458e 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -287,7 +287,7 @@ void SV_SendServerinfo (client_t *client)
 
 // set view
        MSG_WriteByte (&client->message, svc_setview);
 
 // set view
        MSG_WriteByte (&client->message, svc_setview);
-       MSG_WriteShort (&client->message, client->edictnumber);
+       MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict));
 
        MSG_WriteByte (&client->message, svc_signonnum);
        MSG_WriteByte (&client->message, 1);
 
        MSG_WriteByte (&client->message, svc_signonnum);
        MSG_WriteByte (&client->message, 1);
@@ -306,9 +306,7 @@ once for a player each game, not once for each level change.
 */
 void SV_ConnectClient (int clientnum)
 {
 */
 void SV_ConnectClient (int clientnum)
 {
-       edict_t                 *ent;
        client_t                *client;
        client_t                *client;
-       int                             edictnum;
        struct qsocket_s *netconnection;
        int                             i;
        float                   spawn_parms[NUM_SPAWN_PARMS];
        struct qsocket_s *netconnection;
        int                             i;
        float                   spawn_parms[NUM_SPAWN_PARMS];
@@ -317,10 +315,6 @@ void SV_ConnectClient (int clientnum)
 
        Con_DPrintf ("Client %s connected\n", client->netconnection->address);
 
 
        Con_DPrintf ("Client %s connected\n", client->netconnection->address);
 
-       edictnum = clientnum+1;
-
-       ent = EDICT_NUM(edictnum);
-
 // set up the client_t
        netconnection = client->netconnection;
 
 // set up the client_t
        netconnection = client->netconnection;
 
@@ -332,7 +326,7 @@ void SV_ConnectClient (int clientnum)
        strcpy (client->name, "unconnected");
        client->active = true;
        client->spawned = false;
        strcpy (client->name, "unconnected");
        client->active = true;
        client->spawned = false;
-       client->edictnumber = edictnum;
+       client->edict = EDICT_NUM(clientnum+1);
        client->message.data = client->msgbuf;
        client->message.maxsize = sizeof(client->msgbuf);
        client->message.allowoverflow = true;           // we can catch it
        client->message.data = client->msgbuf;
        client->message.maxsize = sizeof(client->msgbuf);
        client->message.allowoverflow = true;           // we can catch it
@@ -761,7 +755,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                        bits = bits | U_EXTERIORMODEL;
 
 // send an update
                        bits = bits | U_EXTERIORMODEL;
 
 // send an update
-               baseline = &ent->baseline;
+               baseline = &ent->e->baseline;
 
                if (((int)ent->v->effects & EF_DELTA) && sv_deltacompress.integer)
                {
 
                if (((int)ent->v->effects & EF_DELTA) && sv_deltacompress.integer)
                {
@@ -769,7 +763,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                        if (realtime < client->nextfullupdate[e])
                        {
                                bits |= U_DELTA;
                        if (realtime < client->nextfullupdate[e])
                        {
                                bits |= U_DELTA;
-                               baseline = &ent->deltabaseline;
+                               baseline = &ent->e->deltabaseline;
                        }
                        else
                                nextfullupdate = realtime + 0.5f;
                        }
                        else
                                nextfullupdate = realtime + 0.5f;
@@ -809,17 +803,17 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                if (((int) baseline->frame & 0xFF00) != ((int) ent->v->modelindex & 0xFF00))            bits |= U_MODEL2;
 
                // update delta baseline
                if (((int) baseline->frame & 0xFF00) != ((int) ent->v->modelindex & 0xFF00))            bits |= U_MODEL2;
 
                // update delta baseline
-               VectorCopy(ent->v->origin, ent->deltabaseline.origin);
-               VectorCopy(ent->v->angles, ent->deltabaseline.angles);
-               ent->deltabaseline.colormap = ent->v->colormap;
-               ent->deltabaseline.skin = ent->v->skin;
-               ent->deltabaseline.frame = ent->v->frame;
-               ent->deltabaseline.effects = ent->v->effects;
-               ent->deltabaseline.modelindex = ent->v->modelindex;
-               ent->deltabaseline.alpha = alpha;
-               ent->deltabaseline.scale = scale;
-               ent->deltabaseline.glowsize = glowsize;
-               ent->deltabaseline.glowcolor = glowcolor;
+               VectorCopy(ent->v->origin, ent->e->deltabaseline.origin);
+               VectorCopy(ent->v->angles, ent->e->deltabaseline.angles);
+               ent->e->deltabaseline.colormap = ent->v->colormap;
+               ent->e->deltabaseline.skin = ent->v->skin;
+               ent->e->deltabaseline.frame = ent->v->frame;
+               ent->e->deltabaseline.effects = ent->v->effects;
+               ent->e->deltabaseline.modelindex = ent->v->modelindex;
+               ent->e->deltabaseline.alpha = alpha;
+               ent->e->deltabaseline.scale = scale;
+               ent->e->deltabaseline.glowsize = glowsize;
+               ent->e->deltabaseline.glowcolor = glowcolor;
 
                // write the message
                if (bits >= 16777216)
 
                // write the message
                if (bits >= 16777216)
@@ -915,7 +909,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
        ent = NEXT_EDICT(sv.edicts);
        for (e = 1;e < sv.num_edicts;e++, ent = NEXT_EDICT(ent))
        {
        ent = NEXT_EDICT(sv.edicts);
        for (e = 1;e < sv.num_edicts;e++, ent = NEXT_EDICT(ent))
        {
-               if (ent->free)
+               if (ent->e->free)
                        continue;
                flags = 0;
 
                        continue;
                flags = 0;
 
@@ -1403,9 +1397,9 @@ qboolean SV_SendClientDatagram (client_t *client)
        if (client->spawned)
        {
                // add the client specific data to the datagram
        if (client->spawned)
        {
                // add the client specific data to the datagram
-               SV_WriteClientdataToMessage (EDICT_NUM(client->edictnumber), &msg);
+               SV_WriteClientdataToMessage (client->edict, &msg);
 
 
-               SV_WriteEntitiesToClient (client, EDICT_NUM(client->edictnumber), &msg);
+               SV_WriteEntitiesToClient (client, client->edict, &msg);
 
                // copy the server datagram if there is space
                if (msg.cursize + sv.datagram.cursize < msg.maxsize)
 
                // copy the server datagram if there is space
                if (msg.cursize + sv.datagram.cursize < msg.maxsize)
@@ -1429,13 +1423,14 @@ SV_UpdateToReliableMessages
 */
 void SV_UpdateToReliableMessages (void)
 {
 */
 void SV_UpdateToReliableMessages (void)
 {
-       int                     i, j;
+       int i, j;
        client_t *client;
 
 // check for changes to be sent over the reliable streams
        for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
        {
        client_t *client;
 
 // check for changes to be sent over the reliable streams
        for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
        {
-               if (host_client->old_frags != EDICT_NUM(host_client->edictnumber)->v->frags)
+               sv_player = host_client->edict;
+               if (host_client->old_frags != sv_player->v->frags)
                {
                        for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
                        {
                {
                        for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
                        {
@@ -1443,18 +1438,18 @@ void SV_UpdateToReliableMessages (void)
                                        continue;
                                MSG_WriteByte (&client->message, svc_updatefrags);
                                MSG_WriteByte (&client->message, i);
                                        continue;
                                MSG_WriteByte (&client->message, svc_updatefrags);
                                MSG_WriteByte (&client->message, i);
-                               MSG_WriteShort (&client->message, EDICT_NUM(host_client->edictnumber)->v->frags);
+                               MSG_WriteShort (&client->message, sv_player->v->frags);
                        }
 
                        }
 
-                       host_client->old_frags = EDICT_NUM(host_client->edictnumber)->v->frags;
+                       host_client->old_frags = sv_player->v->frags;
                }
        }
 
                }
        }
 
-       for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
+       for (j=0, host_client = svs.clients ; j<svs.maxclients ; j++, host_client++)
        {
        {
-               if (!client->active)
+               if (!host_client->active)
                        continue;
                        continue;
-               SZ_Write (&client->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
+               SZ_Write (&host_client->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
        }
 
        SZ_Clear (&sv.reliable_datagram);
        }
 
        SZ_Clear (&sv.reliable_datagram);
@@ -1613,31 +1608,31 @@ void SV_CreateBaseline (void)
                svent = EDICT_NUM(entnum);
 
                // LordHavoc: always clear state values, whether the entity is in use or not
                svent = EDICT_NUM(entnum);
 
                // LordHavoc: always clear state values, whether the entity is in use or not
-               ClearStateToDefault(&svent->baseline);
+               ClearStateToDefault(&svent->e->baseline);
 
 
-               if (svent->free)
+               if (svent->e->free)
                        continue;
                if (entnum > svs.maxclients && !svent->v->modelindex)
                        continue;
 
                // create entity baseline
                        continue;
                if (entnum > svs.maxclients && !svent->v->modelindex)
                        continue;
 
                // create entity baseline
-               VectorCopy (svent->v->origin, svent->baseline.origin);
-               VectorCopy (svent->v->angles, svent->baseline.angles);
-               svent->baseline.frame = svent->v->frame;
-               svent->baseline.skin = svent->v->skin;
+               VectorCopy (svent->v->origin, svent->e->baseline.origin);
+               VectorCopy (svent->v->angles, svent->e->baseline.angles);
+               svent->e->baseline.frame = svent->v->frame;
+               svent->e->baseline.skin = svent->v->skin;
                if (entnum > 0 && entnum <= svs.maxclients)
                {
                if (entnum > 0 && entnum <= svs.maxclients)
                {
-                       svent->baseline.colormap = entnum;
-                       svent->baseline.modelindex = SV_ModelIndex("progs/player.mdl");
+                       svent->e->baseline.colormap = entnum;
+                       svent->e->baseline.modelindex = SV_ModelIndex("progs/player.mdl");
                }
                else
                {
                }
                else
                {
-                       svent->baseline.colormap = 0;
-                       svent->baseline.modelindex = svent->v->modelindex;
+                       svent->e->baseline.colormap = 0;
+                       svent->e->baseline.modelindex = svent->v->modelindex;
                }
 
                large = false;
                }
 
                large = false;
-               if (svent->baseline.modelindex & 0xFF00 || svent->baseline.frame & 0xFF00)
+               if (svent->e->baseline.modelindex & 0xFF00 || svent->e->baseline.frame & 0xFF00)
                        large = true;
 
                // add to the message
                        large = true;
 
                // add to the message
@@ -1649,20 +1644,20 @@ void SV_CreateBaseline (void)
 
                if (large)
                {
 
                if (large)
                {
-                       MSG_WriteShort (&sv.signon, svent->baseline.modelindex);
-                       MSG_WriteShort (&sv.signon, svent->baseline.frame);
+                       MSG_WriteShort (&sv.signon, svent->e->baseline.modelindex);
+                       MSG_WriteShort (&sv.signon, svent->e->baseline.frame);
                }
                else
                {
                }
                else
                {
-                       MSG_WriteByte (&sv.signon, svent->baseline.modelindex);
-                       MSG_WriteByte (&sv.signon, svent->baseline.frame);
+                       MSG_WriteByte (&sv.signon, svent->e->baseline.modelindex);
+                       MSG_WriteByte (&sv.signon, svent->e->baseline.frame);
                }
                }
-               MSG_WriteByte (&sv.signon, svent->baseline.colormap);
-               MSG_WriteByte (&sv.signon, svent->baseline.skin);
+               MSG_WriteByte (&sv.signon, svent->e->baseline.colormap);
+               MSG_WriteByte (&sv.signon, svent->e->baseline.skin);
                for (i=0 ; i<3 ; i++)
                {
                for (i=0 ; i<3 ; i++)
                {
-                       MSG_WriteDPCoord(&sv.signon, svent->baseline.origin[i]);
-                       MSG_WriteAngle(&sv.signon, svent->baseline.angles[i]);
+                       MSG_WriteDPCoord(&sv.signon, svent->e->baseline.origin[i]);
+                       MSG_WriteAngle(&sv.signon, svent->e->baseline.angles[i]);
                }
        }
 }
                }
        }
 }
@@ -1714,7 +1709,7 @@ void SV_SaveSpawnparms (void)
                        continue;
 
        // call the progs to get default spawn parms for the new client
                        continue;
 
        // call the progs to get default spawn parms for the new client
-               pr_global_struct->self = EDICT_TO_PROG(EDICT_NUM(host_client->edictnumber));
+               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
                PR_ExecuteProgram (pr_global_struct->SetChangeParms, "QC function SetChangeParms is missing");
                for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
                        host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j];
                PR_ExecuteProgram (pr_global_struct->SetChangeParms, "QC function SetChangeParms is missing");
                for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
                        host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j];
@@ -1724,37 +1719,37 @@ void SV_SaveSpawnparms (void)
 void SV_IncreaseEdicts(void)
 {
        int i;
 void SV_IncreaseEdicts(void)
 {
        int i;
-       edict_t *e;
+       edict_t *ent;
        int oldmax_edicts = sv.max_edicts;
        int oldmax_edicts = sv.max_edicts;
-       void *oldedicts = sv.edicts;
+       void *oldedictsengineprivate = sv.edictsengineprivate;
        void *oldedictsfields = sv.edictsfields;
        void *oldedictsfields = sv.edictsfields;
-       void *oldedictstable = sv.edictstable;
        void *oldmoved_edicts = sv.moved_edicts;
 
        void *oldmoved_edicts = sv.moved_edicts;
 
+       // links don't survive the transition, so unlink everything
        for (i = 0;i < sv.max_edicts;i++)
        for (i = 0;i < sv.max_edicts;i++)
-               SV_UnlinkEdict (sv.edictstable[i]);
+               SV_UnlinkEdict (sv.edicts + i);
        SV_ClearWorld();
 
        sv.max_edicts   = min(sv.max_edicts + 32, MAX_EDICTS);
        SV_ClearWorld();
 
        sv.max_edicts   = min(sv.max_edicts + 32, MAX_EDICTS);
-       sv.edicts       = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t));
+       sv.edictsengineprivate = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_engineprivate_t));
        sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size);
        sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size);
-       sv.edictstable  = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
        sv.moved_edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
 
        sv.moved_edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
 
-       memcpy(sv.edicts      , oldedicts      , oldmax_edicts * sizeof(edict_t));
+       memcpy(sv.edictsengineprivate, oldedictsengineprivate, oldmax_edicts * sizeof(edict_engineprivate_t));
        memcpy(sv.edictsfields, oldedictsfields, oldmax_edicts * pr_edict_size);
 
        for (i = 0;i < sv.max_edicts;i++)
        {
        memcpy(sv.edictsfields, oldedictsfields, oldmax_edicts * pr_edict_size);
 
        for (i = 0;i < sv.max_edicts;i++)
        {
-               e = sv.edictstable[i] = sv.edicts + i;
-               e->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
+               ent = sv.edicts + i;
+               ent->e = sv.edictsengineprivate + i;
+               ent->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
+               // link every entity except world
                if (i > 0)
                if (i > 0)
-                       SV_LinkEdict(e, false);
+                       SV_LinkEdict(ent, false);
        }
 
        }
 
-       Mem_Free(oldedicts);
+       Mem_Free(oldedictsengineprivate);
        Mem_Free(oldedictsfields);
        Mem_Free(oldedictsfields);
-       Mem_Free(oldedictstable);
        Mem_Free(oldmoved_edicts);
 }
 
        Mem_Free(oldmoved_edicts);
 }
 
@@ -1810,23 +1805,24 @@ void SV_SpawnServer (const char *server)
 
 // allocate server memory
        // start out with just enough room for clients and a reasonable estimate of entities
 
 // allocate server memory
        // start out with just enough room for clients and a reasonable estimate of entities
-       sv.max_edicts = ((svs.maxclients + 1) + 31) & ~31;
-       sv.max_edicts = max(sv.max_edicts, 128);
+       sv.max_edicts = ((svs.maxclients + 128) + 31) & ~31;
+       sv.max_edicts = min(sv.max_edicts, MAX_EDICTS);
 
        // clear the edict memory pool
        Mem_EmptyPool(sv_edicts_mempool);
        // edict_t structures (hidden from progs)
 
        // clear the edict memory pool
        Mem_EmptyPool(sv_edicts_mempool);
        // edict_t structures (hidden from progs)
-       sv.edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t));
+       sv.edicts = Mem_Alloc(sv_edicts_mempool, MAX_EDICTS * sizeof(edict_t));
+       // engine private structures (hidden from progs)
+       sv.edictsengineprivate = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_engineprivate_t));
        // progs fields, often accessed by server
        sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size);
        // progs fields, often accessed by server
        sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size);
-       // table of edict pointers, for quick lookup of edicts
-       sv.edictstable = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
        // used by PushMove to move back pushed entities
        sv.moved_edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
        for (i = 0;i < sv.max_edicts;i++)
        {
        // used by PushMove to move back pushed entities
        sv.moved_edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *));
        for (i = 0;i < sv.max_edicts;i++)
        {
-               sv.edictstable[i] = sv.edicts + i;
-               sv.edictstable[i]->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
+               ent = sv.edicts + i;
+               ent->e = sv.edictsengineprivate + i;
+               ent->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
        }
 
        sv.datagram.maxsize = sizeof(sv.datagram_buf);
        }
 
        sv.datagram.maxsize = sizeof(sv.datagram_buf);
@@ -1844,7 +1840,7 @@ void SV_SpawnServer (const char *server)
 // leave slots at start for clients only
        sv.num_edicts = svs.maxclients+1;
        for (i=0 ; i<svs.maxclients ; i++)
 // leave slots at start for clients only
        sv.num_edicts = svs.maxclients+1;
        for (i=0 ; i<svs.maxclients ; i++)
-               svs.clients[i].edictnumber = i+1;
+               svs.clients[i].edict = EDICT_NUM(i+1);
 
        sv.state = ss_loading;
        sv.paused = false;
 
        sv.state = ss_loading;
        sv.paused = false;
@@ -1884,7 +1880,7 @@ void SV_SpawnServer (const char *server)
 //
        ent = EDICT_NUM(0);
        memset (ent->v, 0, progs->entityfields * 4);
 //
        ent = EDICT_NUM(0);
        memset (ent->v, 0, progs->entityfields * 4);
-       ent->free = false;
+       ent->e->free = false;
        ent->v->model = PR_SetString(sv.modelname);
        ent->v->modelindex = 1;         // world model
        ent->v->solid = SOLID_BSP;
        ent->v->model = PR_SetString(sv.modelname);
        ent->v->modelindex = 1;         // world model
        ent->v->solid = SOLID_BSP;
index 5847ad5219ac144e77fa01b105918a9a2acca626..e031f19e6e5074e28db9f6bcd4295df7efaf1eeb 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -75,7 +75,7 @@ void SV_CheckAllEnts (void)
        check = NEXT_EDICT(sv.edicts);
        for (e = 1;e < sv.num_edicts;e++, check = NEXT_EDICT(check))
        {
        check = NEXT_EDICT(sv.edicts);
        for (e = 1;e < sv.num_edicts;e++, check = NEXT_EDICT(check))
        {
-               if (check->free)
+               if (check->e->free)
                        continue;
                if (check->v->movetype == MOVETYPE_PUSH
                 || check->v->movetype == MOVETYPE_NONE
                        continue;
                if (check->v->movetype == MOVETYPE_PUSH
                 || check->v->movetype == MOVETYPE_NONE
@@ -154,7 +154,7 @@ qboolean SV_RunThink (edict_t *ent)
        pr_global_struct->self = EDICT_TO_PROG(ent);
        pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
        PR_ExecuteProgram (ent->v->think, "NULL think function");
        pr_global_struct->self = EDICT_TO_PROG(ent);
        pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
        PR_ExecuteProgram (ent->v->think, "NULL think function");
-       return !ent->free;
+       return !ent->e->free;
 }
 
 /*
 }
 
 /*
@@ -304,7 +304,7 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                                SV_Impact (ent, trace.ent);
 
                                // break if removed by the impact function
                                SV_Impact (ent, trace.ent);
 
                                // break if removed by the impact function
-                               if (ent->free)
+                               if (ent->e->free)
                                        break;
                        }
 
                                        break;
                        }
 
@@ -399,7 +399,7 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                                SV_Impact (ent, trace.ent);
 
                                // break if removed by the impact function
                                SV_Impact (ent, trace.ent);
 
                                // break if removed by the impact function
-                               if (ent->free)
+                               if (ent->e->free)
                                        break;
                        }
 
                                        break;
                        }
 
@@ -646,7 +646,7 @@ void SV_PushMove (edict_t *pusher, float movetime)
        check = NEXT_EDICT(sv.edicts);
        for (e = 1;e < sv.num_edicts;e++, check = NEXT_EDICT(check))
        {
        check = NEXT_EDICT(sv.edicts);
        for (e = 1;e < sv.num_edicts;e++, check = NEXT_EDICT(check))
        {
-               if (check->free)
+               if (check->e->free)
                        continue;
                if (check->v->movetype == MOVETYPE_PUSH
                 || check->v->movetype == MOVETYPE_NONE
                        continue;
                if (check->v->movetype == MOVETYPE_PUSH
                 || check->v->movetype == MOVETYPE_NONE
@@ -686,8 +686,8 @@ void SV_PushMove (edict_t *pusher, float movetime)
                if (check->v->movetype != MOVETYPE_WALK)
                        check->v->flags = (int)check->v->flags & ~FL_ONGROUND;
 
                if (check->v->movetype != MOVETYPE_WALK)
                        check->v->flags = (int)check->v->flags & ~FL_ONGROUND;
 
-               VectorCopy (check->v->origin, check->moved_from);
-               VectorCopy (check->v->angles, check->moved_fromangles);
+               VectorCopy (check->v->origin, check->e->moved_from);
+               VectorCopy (check->v->angles, check->e->moved_fromangles);
                sv.moved_edicts[num_moved++] = check;
 
                // try moving the contacted entity
                sv.moved_edicts[num_moved++] = check;
 
                // try moving the contacted entity
@@ -727,8 +727,8 @@ void SV_PushMove (edict_t *pusher, float movetime)
                                for (i = 0;i < num_moved;i++)
                                {
                                        ed = sv.moved_edicts[i];
                                for (i = 0;i < num_moved;i++)
                                {
                                        ed = sv.moved_edicts[i];
-                                       VectorCopy (ed->moved_from, ed->v->origin);
-                                       VectorCopy (ed->moved_fromangles, ed->v->angles);
+                                       VectorCopy (ed->e->moved_from, ed->v->origin);
+                                       VectorCopy (ed->e->moved_fromangles, ed->v->angles);
                                        SV_LinkEdict (ed, false);
                                }
 
                                        SV_LinkEdict (ed, false);
                                }
 
@@ -778,7 +778,7 @@ void SV_Physics_Pusher (edict_t *ent)
                pr_global_struct->self = EDICT_TO_PROG(ent);
                pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
                PR_ExecuteProgram (ent->v->think, "NULL think function");
                pr_global_struct->self = EDICT_TO_PROG(ent);
                pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
                PR_ExecuteProgram (ent->v->think, "NULL think function");
-               if (ent->free)
+               if (ent->e->free)
                        return;
        }
 
                        return;
        }
 
@@ -1000,7 +1000,7 @@ void SV_WalkMove (edict_t *ent)
        if (sv_nostep.integer)
                return;
 
        if (sv_nostep.integer)
                return;
 
-       if ( (int)sv_player->v->flags & FL_WATERJUMP )
+       if ( (int)ent->v->flags & FL_WATERJUMP )
                return;
 
        VectorCopy (ent->v->origin, nosteporg);
                return;
 
        VectorCopy (ent->v->origin, nosteporg);
@@ -1277,18 +1277,18 @@ void SV_Physics_Toss (edict_t *ent)
                groundentity = PROG_TO_EDICT(ent->v->groundentity);
                if (groundentity->v->solid == SOLID_BSP)
                {
                groundentity = PROG_TO_EDICT(ent->v->groundentity);
                if (groundentity->v->solid == SOLID_BSP)
                {
-                       ent->suspendedinairflag = true;
+                       ent->e->suspendedinairflag = true;
                        return;
                }
                        return;
                }
-               else if (ent->suspendedinairflag && groundentity->free)
+               else if (ent->e->suspendedinairflag && groundentity->e->free)
                {
                        // leave it suspended in the air
                        ent->v->groundentity = 0;
                {
                        // leave it suspended in the air
                        ent->v->groundentity = 0;
-                       ent->suspendedinairflag = false;
+                       ent->e->suspendedinairflag = false;
                        return;
                }
        }
                        return;
                }
        }
-       ent->suspendedinairflag = false;
+       ent->e->suspendedinairflag = false;
 
        SV_CheckVelocity (ent);
 
 
        SV_CheckVelocity (ent);
 
@@ -1302,7 +1302,7 @@ void SV_Physics_Toss (edict_t *ent)
 // move origin
        VectorScale (ent->v->velocity, sv.frametime, move);
        trace = SV_PushEntity (ent, move, vec3_origin);
 // move origin
        VectorScale (ent->v->velocity, sv.frametime, move);
        trace = SV_PushEntity (ent, move, vec3_origin);
-       if (ent->free)
+       if (ent->e->free)
                return;
 
        if (trace.fraction < 1)
                return;
 
        if (trace.fraction < 1)
@@ -1437,7 +1437,7 @@ void SV_Physics (void)
        ent = sv.edicts;
        for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
        {
        ent = sv.edicts;
        for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
        {
-               if (ent->free)
+               if (ent->e->free)
                        continue;
 
                if (pr_global_struct->force_retouch)
                        continue;
 
                if (pr_global_struct->force_retouch)
index 6e02dcbdd8e6401a136bdf75ccdcea6ae8856035..f895390fd635365e710092243376677092d08ccb 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -464,7 +464,6 @@ void SV_ReadClientMove (usercmd_t *move)
        int bits;
        eval_t *val;
        float total;
        int bits;
        eval_t *val;
        float total;
-       edict_t *e = EDICT_NUM(host_client->edictnumber);
 
        // read ping time
        host_client->ping_times[host_client->num_pings % NUM_PING_TIMES] = sv.time - MSG_ReadFloat ();
 
        // read ping time
        host_client->ping_times[host_client->num_pings % NUM_PING_TIMES] = sv.time - MSG_ReadFloat ();
@@ -477,7 +476,7 @@ void SV_ReadClientMove (usercmd_t *move)
        // if paused or a local game, don't predict
        if (sv_predict.integer && (svs.maxclients > 1) && (!sv.paused))
                host_client->latency = host_client->ping;
        // if paused or a local game, don't predict
        if (sv_predict.integer && (svs.maxclients > 1) && (!sv.paused))
                host_client->latency = host_client->ping;
-       if ((val = GETEDICTFIELDVALUE(e, eval_ping)))
+       if ((val = GETEDICTFIELDVALUE(sv_player, eval_ping)))
                val->_float = host_client->ping * 1000.0;
 
        // read current angles
                val->_float = host_client->ping * 1000.0;
 
        // read current angles
@@ -485,13 +484,13 @@ void SV_ReadClientMove (usercmd_t *move)
        for (i = 0;i < 3;i++)
                angle[i] = MSG_ReadFloat ();
 
        for (i = 0;i < 3;i++)
                angle[i] = MSG_ReadFloat ();
 
-       VectorCopy (angle, e->v->v_angle);
+       VectorCopy (angle, sv_player->v->v_angle);
 
        // read movement
        move->forwardmove = MSG_ReadShort ();
        move->sidemove = MSG_ReadShort ();
        move->upmove = MSG_ReadShort ();
 
        // read movement
        move->forwardmove = MSG_ReadShort ();
        move->sidemove = MSG_ReadShort ();
        move->upmove = MSG_ReadShort ();
-       if ((val = GETEDICTFIELDVALUE(e, eval_movement)))
+       if ((val = GETEDICTFIELDVALUE(sv_player, eval_movement)))
        {
                val->vector[0] = move->forwardmove;
                val->vector[1] = move->sidemove;
        {
                val->vector[0] = move->forwardmove;
                val->vector[1] = move->sidemove;
@@ -500,19 +499,19 @@ void SV_ReadClientMove (usercmd_t *move)
 
        // read buttons
        bits = MSG_ReadByte ();
 
        // read buttons
        bits = MSG_ReadByte ();
-       e->v->button0 = bits & 1;
-       e->v->button2 = (bits & 2)>>1;
+       sv_player->v->button0 = bits & 1;
+       sv_player->v->button2 = (bits & 2)>>1;
        // LordHavoc: added 6 new buttons
        // LordHavoc: added 6 new buttons
-       if ((val = GETEDICTFIELDVALUE(e, eval_button3))) val->_float = ((bits >> 2) & 1);
-       if ((val = GETEDICTFIELDVALUE(e, eval_button4))) val->_float = ((bits >> 3) & 1);
-       if ((val = GETEDICTFIELDVALUE(e, eval_button5))) val->_float = ((bits >> 4) & 1);
-       if ((val = GETEDICTFIELDVALUE(e, eval_button6))) val->_float = ((bits >> 5) & 1);
-       if ((val = GETEDICTFIELDVALUE(e, eval_button7))) val->_float = ((bits >> 6) & 1);
-       if ((val = GETEDICTFIELDVALUE(e, eval_button8))) val->_float = ((bits >> 7) & 1);
+       if ((val = GETEDICTFIELDVALUE(sv_player, eval_button3))) val->_float = ((bits >> 2) & 1);
+       if ((val = GETEDICTFIELDVALUE(sv_player, eval_button4))) val->_float = ((bits >> 3) & 1);
+       if ((val = GETEDICTFIELDVALUE(sv_player, eval_button5))) val->_float = ((bits >> 4) & 1);
+       if ((val = GETEDICTFIELDVALUE(sv_player, eval_button6))) val->_float = ((bits >> 5) & 1);
+       if ((val = GETEDICTFIELDVALUE(sv_player, eval_button7))) val->_float = ((bits >> 6) & 1);
+       if ((val = GETEDICTFIELDVALUE(sv_player, eval_button8))) val->_float = ((bits >> 7) & 1);
 
        i = MSG_ReadByte ();
        if (i)
 
        i = MSG_ReadByte ();
        if (i)
-               e->v->impulse = i;
+               sv_player->v->impulse = i;
 }
 
 /*
 }
 
 /*
@@ -639,7 +638,7 @@ void SV_RunClients (void)
                if (!host_client->active)
                        continue;
 
                if (!host_client->active)
                        continue;
 
-               sv_player = EDICT_NUM(host_client->edictnumber);
+               sv_player = host_client->edict;
 
                if (!SV_ReadClientMessage ())
                {
 
                if (!SV_ReadClientMessage ())
                {
diff --git a/world.c b/world.c
index 6fceef78097595f637210c50b9ecc531dc855861..b121576248dd107c86a8fe6cefc77e385dde2852 100644 (file)
--- a/world.c
+++ b/world.c
@@ -184,10 +184,10 @@ void SV_UnlinkEdict (edict_t *ent)
        int i;
        for (i = 0;i < ENTITYGRIDAREAS;i++)
        {
        int i;
        for (i = 0;i < ENTITYGRIDAREAS;i++)
        {
-               if (ent->areagrid[i].prev)
+               if (ent->e->areagrid[i].prev)
                {
                {
-                       RemoveLink (&ent->areagrid[i]);
-                       ent->areagrid[i].prev = ent->areagrid[i].next = NULL;
+                       RemoveLink (&ent->e->areagrid[i]);
+                       ent->e->areagrid[i].prev = ent->e->areagrid[i].next = NULL;
                }
        }
 }
                }
        }
 }
@@ -250,9 +250,9 @@ void SV_TouchAreaGrid(edict_t *ent)
                        {
                                next = l->next;
                                touch = EDICT_NUM(l->entitynumber);
                        {
                                next = l->next;
                                touch = EDICT_NUM(l->entitynumber);
-                               if (touch->areagridmarknumber == sv_areagrid_marknumber)
+                               if (touch->e->areagridmarknumber == sv_areagrid_marknumber)
                                        continue;
                                        continue;
-                               touch->areagridmarknumber = sv_areagrid_marknumber;
+                               touch->e->areagridmarknumber = sv_areagrid_marknumber;
                                if (ent->v->absmin[0] > touch->v->absmax[0]
                                 || ent->v->absmax[0] < touch->v->absmin[0]
                                 || ent->v->absmin[1] > touch->v->absmax[1]
                                if (ent->v->absmin[0] > touch->v->absmax[0]
                                 || ent->v->absmax[0] < touch->v->absmin[0]
                                 || ent->v->absmin[1] > touch->v->absmax[1]
@@ -294,9 +294,9 @@ void SV_LinkEdict_AreaGrid(edict_t *ent)
        {
                // wow, something outside the grid, store it as such
                if (ent->v->solid == SOLID_TRIGGER)
        {
                // wow, something outside the grid, store it as such
                if (ent->v->solid == SOLID_TRIGGER)
-                       InsertLinkBefore (&ent->areagrid[0], &sv_areagrid_outside.trigger_edicts, NUM_FOR_EDICT(ent));
+                       InsertLinkBefore (&ent->e->areagrid[0], &sv_areagrid_outside.trigger_edicts, NUM_FOR_EDICT(ent));
                else
                else
-                       InsertLinkBefore (&ent->areagrid[0], &sv_areagrid_outside.solid_edicts, NUM_FOR_EDICT(ent));
+                       InsertLinkBefore (&ent->e->areagrid[0], &sv_areagrid_outside.solid_edicts, NUM_FOR_EDICT(ent));
                return;
        }
 
                return;
        }
 
@@ -307,9 +307,9 @@ void SV_LinkEdict_AreaGrid(edict_t *ent)
                for (igrid[0] = igridmins[0];igrid[0] < igridmaxs[0];igrid[0]++, grid++, gridnum++)
                {
                        if (ent->v->solid == SOLID_TRIGGER)
                for (igrid[0] = igridmins[0];igrid[0] < igridmaxs[0];igrid[0]++, grid++, gridnum++)
                {
                        if (ent->v->solid == SOLID_TRIGGER)
-                               InsertLinkBefore (&ent->areagrid[gridnum], &grid->trigger_edicts, NUM_FOR_EDICT(ent));
+                               InsertLinkBefore (&ent->e->areagrid[gridnum], &grid->trigger_edicts, NUM_FOR_EDICT(ent));
                        else
                        else
-                               InsertLinkBefore (&ent->areagrid[gridnum], &grid->solid_edicts, NUM_FOR_EDICT(ent));
+                               InsertLinkBefore (&ent->e->areagrid[gridnum], &grid->solid_edicts, NUM_FOR_EDICT(ent));
                }
        }
 }
                }
        }
 }
@@ -324,13 +324,13 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
 {
        model_t *model;
 
 {
        model_t *model;
 
-       if (ent->areagrid[0].prev)
+       if (ent->e->areagrid[0].prev)
                SV_UnlinkEdict (ent);   // unlink from old position
 
        if (ent == sv.edicts)
                return;         // don't add the world
 
                SV_UnlinkEdict (ent);   // unlink from old position
 
        if (ent == sv.edicts)
                return;         // don't add the world
 
-       if (ent->free)
+       if (ent->e->free)
                return;
 
 // set the abs box
                return;
 
 // set the abs box
@@ -495,9 +495,9 @@ void SV_ClipToNode(moveclip_t *clip, link_t *list)
        {
                next = l->next;
                touch = EDICT_NUM(l->entitynumber);
        {
                next = l->next;
                touch = EDICT_NUM(l->entitynumber);
-               if (touch->areagridmarknumber == sv_areagrid_marknumber)
+               if (touch->e->areagridmarknumber == sv_areagrid_marknumber)
                        continue;
                        continue;
-               touch->areagridmarknumber = sv_areagrid_marknumber;
+               touch->e->areagridmarknumber = sv_areagrid_marknumber;
                sv_areagrid_stats_entitychecks++;
 
                if (clip->boxmins[0] > touch->v->absmax[0]
                sv_areagrid_stats_entitychecks++;
 
                if (clip->boxmins[0] > touch->v->absmax[0]