sv.edicts (and related things) are now dynamically reallocated as more edicts are...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 25 Apr 2003 14:43:10 +0000 (14:43 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 25 Apr 2003 14:43:10 +0000 (14:43 +0000)
no edict_t *'s exist in any persistent structures anymore, using edict numbers in all such cases (as it turns out the only such structs were client_t in server.h and link_t in progs.h)
edicts are unlinked before reallocation and relinked after reallocation to keep the link_t pointers valid

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2985 d7cf8633-e32d-0410-b094-e92efae38249

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

index fa99169..ce00b63 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -1572,7 +1572,7 @@ static void CL_PModel_f (void)
        }
 
        host_client->pmodel = i;
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_pmodel)))
+       if ((val = GETEDICTFIELDVALUE(EDICT_NUM(host_client->edictnumber), eval_pmodel)))
                val->_float = i;
 }
 
diff --git a/host.c b/host.c
index c5c783b..d11b8f6 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--;
 
-       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)
+       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)
        {
        // 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(host_client->edict);
+               pr_global_struct->self = EDICT_TO_PROG(EDICT_NUM(host_client->edictnumber));
                PR_ExecuteProgram (pr_global_struct->ClientDisconnect, "QC function ClientDisconnect is missing");
                pr_global_struct->self = saveSelf;
        }
index 6b0cb34..1aca802 100644 (file)
@@ -89,7 +89,7 @@ void Host_Status_f (void)
                }
                else
                        hours = 0;
-               print ("#%-2u %-16.16s  %3i  %2i:%02i:%02i\n", j+1, client->name, (int)client->edict->v->frags, hours, minutes, seconds);
+               print ("#%-2u %-16.16s  %3i  %2i:%02i:%02i\n", j+1, client->name, (int)EDICT_NUM(client->edictnumber)->v->frags, hours, minutes, seconds);
                print ("   %s\n", client->netconnection->address);
        }
 }
@@ -418,7 +418,7 @@ void Host_Savegame_f (void)
 
        for (i=0 ; i<svs.maxclients ; i++)
        {
-               if (svs.clients[i].active && (svs.clients[i].edict->v->health <= 0) )
+               if (svs.clients[i].active && (EDICT_NUM(svs.clients[i].edictnumber)->v->health <= 0) )
                {
                        Con_Printf ("Can't savegame with a dead player\n");
                        return;
@@ -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);
-       host_client->edict->v->netname = PR_SetString(host_client->name);
+       EDICT_NUM(host_client->edictnumber)->v->netname = PR_SetString(host_client->name);
 
 // send notification to all clients
 
@@ -740,7 +740,7 @@ void Host_Say(qboolean teamonly)
        {
                if (!client || !client->active || !client->spawned)
                        continue;
-               if (teamplay.integer && teamonly && client->edict->v->team != save->edict->v->team)
+               if (teamplay.integer && teamonly && EDICT_NUM(client->edictnumber)->v->team != EDICT_NUM(save->edictnumber)->v->team)
                        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;
-               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
+               pr_global_struct->self = EDICT_TO_PROG(EDICT_NUM(host_client->edictnumber));
                PR_ExecuteProgram (SV_ChangeTeam, "");
        }
        else
        {
                host_client->colors = playercolor;
-               host_client->edict->v->team = bottom + 1;
+               EDICT_NUM(host_client->edictnumber)->v->team = bottom + 1;
 
                // send notification to all clients
                MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
@@ -1034,13 +1034,13 @@ void Host_Spawn_f (void)
        {
                eval_t *val;
                // set up the edict
-               ent = host_client->edict;
+               ent = EDICT_NUM(host_client->edictnumber);
 
                memset (ent->v, 0, progs->entityfields * 4);
                ent->v->colormap = NUM_FOR_EDICT(ent);
                ent->v->team = (host_client->colors & 15) + 1;
                ent->v->netname = PR_SetString(host_client->name);
-               if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_pmodel)))
+               if ((val = GETEDICTFIELDVALUE(ent, eval_pmodel)))
                        val->_float = host_client->pmodel;
 
                // copy spawn parms out of the client_t
index 5bfc0ef..444089d 100644 (file)
@@ -419,7 +419,7 @@ static void Mod_LoadTextures (lump_t *l)
                                {
                                        if (image_width == 256 && image_height == 128)
                                        {
-                                               R_InitSky (data, 4);
+                                               R_InitSky (data, 4);
                                                Mem_Free(data);
                                        }
                                        else
@@ -442,7 +442,7 @@ static void Mod_LoadTextures (lump_t *l)
                                if (loadmodel->ishlbsp)
                                {
                                        // internal texture overrides wad
-                                       qbyte *pixels, *freepixels;
+                                       qbyte *pixels, *freepixels, *fogpixels;
                                        pixels = freepixels = NULL;
                                        if (mtdata)
                                                pixels = W_ConvertWAD3Texture(dmiptex);
@@ -453,12 +453,25 @@ static void Mod_LoadTextures (lump_t *l)
                                                tx->width = image_width;
                                                tx->height = image_height;
                                                tx->skin.base = tx->skin.merged = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+                                               if (Image_CheckAlpha(pixels, image_width * image_height, true))
+                                               {
+                                                       fogpixels = Mem_Alloc(tempmempool, image_width * image_height * 4);
+                                                       for (j = 0;j < image_width * image_height * 4;j += 4)
+                                                       {
+                                                               fogpixels[j + 0] = 255;
+                                                               fogpixels[j + 1] = 255;
+                                                               fogpixels[j + 2] = 255;
+                                                               fogpixels[j + 3] = pixels[j + 3];
+                                                       }
+                                                       tx->skin.fog = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+                                                       Mem_Free(fogpixels);
+                                               }
                                        }
                                        if (freepixels)
                                                Mem_Free(freepixels);
                                }
                                else if (mtdata) // texture included
-                                       Mod_LoadSkinFrame_Internal(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, tx->name[0] != '*' && r_fullbrights.integer, mtdata, tx->width, tx->height);
+                                       Mod_LoadSkinFrame_Internal(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_PRECACHE, false, true, tx->name[0] != '*' && r_fullbrights.integer, mtdata, tx->width, tx->height);
                        }
                }
                if (tx->skin.base == NULL)
index b3f7fae..b271f9d 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_WriteLong(&net_message, (int)client->edict->v->frags);
+               MSG_WriteLong(&net_message, (int)EDICT_NUM(client->edictnumber)->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));
index 5941d6f..0da857a 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -2103,7 +2103,7 @@ void PF_setcolor (void)
 
        client = &svs.clients[entnum-1];
        client->colors = i;
-       client->edict->v->team = (i & 15) + 1;
+       EDICT_NUM(client->edictnumber)->v->team = (i & 15) + 1;
 
        MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
        MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
index 6c54a7e..d7875c5 100644 (file)
@@ -199,6 +199,7 @@ instead of being removed and recreated, which can cause interpolated
 angles and bad trails.
 =================
 */
+extern void SV_IncreaseEdicts(void);
 edict_t *ED_Alloc (void)
 {
        int                     i;
@@ -220,6 +221,8 @@ edict_t *ED_Alloc (void)
                Host_Error ("ED_Alloc: no free edicts");
 
        sv.num_edicts++;
+       if (sv.num_edicts >= sv.max_edicts)
+               SV_IncreaseEdicts();
        e = EDICT_NUM(i);
        ED_ClearEdict (e);
 
@@ -375,7 +378,8 @@ char *PR_ValueString (etype_t type, eval_t *val)
                sprintf (line, "%s", PR_GetString(val->string));
                break;
        case ev_entity:
-               n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
+               //n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
+               n = val->edict;
                if (n < 0 || n >= MAX_EDICTS)
                        sprintf (line, "entity %i (invalid!)", n);
                else
@@ -1564,12 +1568,19 @@ void PR_Init (void)
 }
 
 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
-edict_t *EDICT_NUM_ERROR(int n)
+edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
 {
-       Host_Error ("EDICT_NUM: bad number %i", n);
+       Host_Error ("EDICT_NUM: bad number %i (called at %f:%i)", n, filename, fileline);
        return NULL;
 }
 
+/*
+int NUM_FOR_EDICT_ERROR(edict_t *e)
+{
+       Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
+       return 0;
+}
+
 int NUM_FOR_EDICT(edict_t *e)
 {
        int n;
@@ -1579,10 +1590,10 @@ int NUM_FOR_EDICT(edict_t *e)
        return n;
 }
 
-int NoCrash_NUM_FOR_EDICT(edict_t *e)
-{
-       return e - sv.edicts;
-}
+//int NoCrash_NUM_FOR_EDICT(edict_t *e)
+//{
+//     return e - sv.edicts;
+//}
 
 //#define      EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
 //#define PROG_TO_EDICT(e) (sv.edictstable[(e) / (progs->entityfields * 4)])
@@ -1602,4 +1613,5 @@ edict_t *PROG_TO_EDICT(int n)
        return sv.edictstable[n]; // EXPERIMENTAL
        //return sv.edictstable[(n) / (progs->entityfields * 4)];
 }
+*/
 
diff --git a/progs.h b/progs.h
index 702c445..929bd27 100644 (file)
--- a/progs.h
+++ b/progs.h
@@ -37,7 +37,7 @@ typedef union eval_s
 
 typedef struct link_s
 {
-       void *entity;
+       int entitynumber;
        struct link_s   *prev, *next;
 } link_t;
 
@@ -157,15 +157,19 @@ void ED_ParseGlobals (const char *data);
 
 void ED_LoadFromFile (const char *data);
 
-edict_t *EDICT_NUM_ERROR(int n);
-#define EDICT_NUM(n) ((n >= 0 && n < sv.max_edicts) ? sv.edictstable[(n)] : EDICT_NUM_ERROR(n))
+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__))
 
-int NUM_FOR_EDICT(edict_t *e);
+//int NUM_FOR_EDICT_ERROR(edict_t *e);
+#define NUM_FOR_EDICT(e) ((edict_t *)(e) - sv.edicts)
+//int NUM_FOR_EDICT(edict_t *e);
 
 #define        NEXT_EDICT(e) ((e) + 1)
 
-int EDICT_TO_PROG(edict_t *e);
-edict_t *PROG_TO_EDICT(int n);
+#define EDICT_TO_PROG(e) (NUM_FOR_EDICT(e))
+//int EDICT_TO_PROG(edict_t *e);
+#define PROG_TO_EDICT(n) (EDICT_NUM(n))
+//edict_t *PROG_TO_EDICT(int n);
 
 //============================================================================
 
index 3843e38..47e917c 100644 (file)
--- a/server.h
+++ b/server.h
@@ -127,8 +127,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];
-       // EDICT_NUM(clientnum+1)
-       edict_t *edict;
+       // (clientnum+1)
+       int edictnumber;
        // for printing to other people
        char name[32];
        int colors;
index 53702fe..d6edc1a 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -33,7 +33,7 @@ server_static_t       svs;
 
 static char localmodels[MAX_MODELS][5];                        // inline model names for precache
 
-static mempool_t *sv_edicts_mempool = NULL;
+mempool_t *sv_edicts_mempool = NULL;
 
 //============================================================================
 
@@ -287,7 +287,7 @@ void SV_SendServerinfo (client_t *client)
 
 // set view
        MSG_WriteByte (&client->message, svc_setview);
-       MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict));
+       MSG_WriteShort (&client->message, client->edictnumber);
 
        MSG_WriteByte (&client->message, svc_signonnum);
        MSG_WriteByte (&client->message, 1);
@@ -332,7 +332,7 @@ void SV_ConnectClient (int clientnum)
        strcpy (client->name, "unconnected");
        client->active = true;
        client->spawned = false;
-       client->edict = ent;
+       client->edictnumber = edictnum;
        client->message.data = client->msgbuf;
        client->message.maxsize = sizeof(client->msgbuf);
        client->message.allowoverflow = true;           // we can catch it
@@ -1403,9 +1403,9 @@ qboolean SV_SendClientDatagram (client_t *client)
        if (client->spawned)
        {
                // add the client specific data to the datagram
-               SV_WriteClientdataToMessage (client->edict, &msg);
+               SV_WriteClientdataToMessage (EDICT_NUM(client->edictnumber), &msg);
 
-               SV_WriteEntitiesToClient (client, client->edict, &msg);
+               SV_WriteEntitiesToClient (client, EDICT_NUM(client->edictnumber), &msg);
 
                // copy the server datagram if there is space
                if (msg.cursize + sv.datagram.cursize < msg.maxsize)
@@ -1435,7 +1435,7 @@ void SV_UpdateToReliableMessages (void)
 // 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 != host_client->edict->v->frags)
+               if (host_client->old_frags != EDICT_NUM(host_client->edictnumber)->v->frags)
                {
                        for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
                        {
@@ -1443,10 +1443,10 @@ void SV_UpdateToReliableMessages (void)
                                        continue;
                                MSG_WriteByte (&client->message, svc_updatefrags);
                                MSG_WriteByte (&client->message, i);
-                               MSG_WriteShort (&client->message, host_client->edict->v->frags);
+                               MSG_WriteShort (&client->message, EDICT_NUM(host_client->edictnumber)->v->frags);
                        }
 
-                       host_client->old_frags = host_client->edict->v->frags;
+                       host_client->old_frags = EDICT_NUM(host_client->edictnumber)->v->frags;
                }
        }
 
@@ -1714,13 +1714,50 @@ void SV_SaveSpawnparms (void)
                        continue;
 
        // call the progs to get default spawn parms for the new client
-               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
+               pr_global_struct->self = EDICT_TO_PROG(EDICT_NUM(host_client->edictnumber));
                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];
        }
 }
 
+void SV_IncreaseEdicts(void)
+{
+       int i;
+       edict_t *e;
+       int oldmax_edicts = sv.max_edicts;
+       void *oldedicts = sv.edicts;
+       void *oldedictsfields = sv.edictsfields;
+       void *oldedictstable = sv.edictstable;
+       void *oldmoved_edicts = sv.moved_edicts;
+
+       for (i = 0;i < sv.max_edicts;i++)
+               SV_UnlinkEdict (sv.edictstable[i]);
+       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.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 *));
+
+       memcpy(sv.edicts      , oldedicts      , oldmax_edicts * sizeof(edict_t));
+       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);
+               if (i > 0)
+                       SV_LinkEdict(e, false);
+       }
+
+       Mem_Free(oldedicts);
+       Mem_Free(oldedictsfields);
+       Mem_Free(oldedictstable);
+       Mem_Free(oldmoved_edicts);
+}
+
 /*
 ================
 SV_SpawnServer
@@ -1772,7 +1809,9 @@ void SV_SpawnServer (const char *server)
        PR_LoadProgs ();
 
 // allocate server memory
-       sv.max_edicts = MAX_EDICTS;
+       // 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);
 
        // clear the edict memory pool
        Mem_EmptyPool(sv_edicts_mempool);
@@ -1780,15 +1819,14 @@ void SV_SpawnServer (const char *server)
        sv.edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t));
        // progs fields, often accessed by server
        sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size);
-       // table of edict pointers, for quicker lookup of edicts
+       // 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++)
        {
-               ent = sv.edicts + i;
-               ent->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
-               sv.edictstable[i] = ent;
+               sv.edictstable[i] = sv.edicts + i;
+               sv.edictstable[i]->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
        }
 
        sv.datagram.maxsize = sizeof(sv.datagram_buf);
@@ -1806,10 +1844,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++)
-       {
-               ent = EDICT_NUM(i+1);
-               svs.clients[i].edict = ent;
-       }
+               svs.clients[i].edictnumber = i+1;
 
        sv.state = ss_loading;
        sv.paused = false;
index 152ec78..6e02dcb 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -464,6 +464,7 @@ void SV_ReadClientMove (usercmd_t *move)
        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 ();
@@ -476,7 +477,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 ((val = GETEDICTFIELDVALUE(host_client->edict, eval_ping)))
+       if ((val = GETEDICTFIELDVALUE(e, eval_ping)))
                val->_float = host_client->ping * 1000.0;
 
        // read current angles
@@ -484,13 +485,13 @@ void SV_ReadClientMove (usercmd_t *move)
        for (i = 0;i < 3;i++)
                angle[i] = MSG_ReadFloat ();
 
-       VectorCopy (angle, host_client->edict->v->v_angle);
+       VectorCopy (angle, e->v->v_angle);
 
        // read movement
        move->forwardmove = MSG_ReadShort ();
        move->sidemove = MSG_ReadShort ();
        move->upmove = MSG_ReadShort ();
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_movement)))
+       if ((val = GETEDICTFIELDVALUE(e, eval_movement)))
        {
                val->vector[0] = move->forwardmove;
                val->vector[1] = move->sidemove;
@@ -499,19 +500,19 @@ void SV_ReadClientMove (usercmd_t *move)
 
        // read buttons
        bits = MSG_ReadByte ();
-       host_client->edict->v->button0 = bits & 1;
-       host_client->edict->v->button2 = (bits & 2)>>1;
+       e->v->button0 = bits & 1;
+       e->v->button2 = (bits & 2)>>1;
        // LordHavoc: added 6 new buttons
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button3))) val->_float = ((bits >> 2) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button4))) val->_float = ((bits >> 3) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button5))) val->_float = ((bits >> 4) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button6))) val->_float = ((bits >> 5) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button7))) val->_float = ((bits >> 6) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button8))) val->_float = ((bits >> 7) & 1);
+       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);
 
        i = MSG_ReadByte ();
        if (i)
-               host_client->edict->v->impulse = i;
+               e->v->impulse = i;
 }
 
 /*
@@ -638,7 +639,7 @@ void SV_RunClients (void)
                if (!host_client->active)
                        continue;
 
-               sv_player = host_client->edict;
+               sv_player = EDICT_NUM(host_client->edictnumber);
 
                if (!SV_ReadClientMessage ())
                {
diff --git a/world.c b/world.c
index de5df5c..6fceef7 100644 (file)
--- a/world.c
+++ b/world.c
@@ -72,41 +72,30 @@ typedef struct
 }
 moveclip_t;
 
-//#define EDICT_FROM_AREA(l) ((edict_t *)((qbyte *)l - (int)&(((edict_t *)0)->area)))
-#define EDICT_FROM_AREA(l) ((edict_t *)l->entity)
-
 //============================================================================
 
 // ClearLink is used for new headnodes
-void ClearLink (link_t *l)
+static void ClearLink (link_t *l)
 {
-       l->entity = NULL;
+       l->entitynumber = 0;
        l->prev = l->next = l;
 }
 
-void RemoveLink (link_t *l)
+static void RemoveLink (link_t *l)
 {
        l->next->prev = l->prev;
        l->prev->next = l->next;
 }
 
-void InsertLinkBefore (link_t *l, link_t *before, void *ent)
+static void InsertLinkBefore (link_t *l, link_t *before, int entitynumber)
 {
-       l->entity = ent;
+       l->entitynumber = entitynumber;
        l->next = before;
        l->prev = before->prev;
        l->prev->next = l;
        l->next->prev = l;
 }
 
-void InsertLinkAfter (link_t *l, link_t *after)
-{
-       l->next = after->next;
-       l->prev = after;
-       l->prev->next = l;
-       l->next->prev = l;
-}
-
 
 /*
 ===============================================================================
@@ -228,7 +217,7 @@ void SV_TouchAreaGrid(edict_t *ent)
        for (l = sv_areagrid_outside.trigger_edicts.next;l != &sv_areagrid_outside.trigger_edicts;l = next)
        {
                next = l->next;
-               touch = EDICT_FROM_AREA(l);
+               touch = EDICT_NUM(l->entitynumber);
                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]
@@ -260,7 +249,7 @@ void SV_TouchAreaGrid(edict_t *ent)
                        for (l = grid->trigger_edicts.next;l != &grid->trigger_edicts;l = next)
                        {
                                next = l->next;
-                               touch = EDICT_FROM_AREA(l);
+                               touch = EDICT_NUM(l->entitynumber);
                                if (touch->areagridmarknumber == sv_areagrid_marknumber)
                                        continue;
                                touch->areagridmarknumber = sv_areagrid_marknumber;
@@ -305,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)
-                       InsertLinkBefore (&ent->areagrid[0], &sv_areagrid_outside.trigger_edicts, ent);
+                       InsertLinkBefore (&ent->areagrid[0], &sv_areagrid_outside.trigger_edicts, NUM_FOR_EDICT(ent));
                else
-                       InsertLinkBefore (&ent->areagrid[0], &sv_areagrid_outside.solid_edicts, ent);
+                       InsertLinkBefore (&ent->areagrid[0], &sv_areagrid_outside.solid_edicts, NUM_FOR_EDICT(ent));
                return;
        }
 
@@ -318,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)
-                               InsertLinkBefore (&ent->areagrid[gridnum], &grid->trigger_edicts, ent);
+                               InsertLinkBefore (&ent->areagrid[gridnum], &grid->trigger_edicts, NUM_FOR_EDICT(ent));
                        else
-                               InsertLinkBefore (&ent->areagrid[gridnum], &grid->solid_edicts, ent);
+                               InsertLinkBefore (&ent->areagrid[gridnum], &grid->solid_edicts, NUM_FOR_EDICT(ent));
                }
        }
 }
@@ -505,7 +494,7 @@ void SV_ClipToNode(moveclip_t *clip, link_t *list)
        for (l = list->next;l != list;l = next)
        {
                next = l->next;
-               touch = EDICT_FROM_AREA(l);
+               touch = EDICT_NUM(l->entitynumber);
                if (touch->areagridmarknumber == sv_areagrid_marknumber)
                        continue;
                touch->areagridmarknumber = sv_areagrid_marknumber;