From 3b559840aaf1e5a218052d893881c1dd8c1b0780 Mon Sep 17 00:00:00 2001 From: havoc Date: Fri, 25 Apr 2003 14:43:10 +0000 Subject: [PATCH] sv.edicts (and related things) are now dynamically reallocated as more edicts are used 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 --- cl_main.c | 2 +- host.c | 4 +-- host_cmd.c | 16 ++++++------ model_brush.c | 19 +++++++++++--- net_dgrm.c | 2 +- pr_cmds.c | 2 +- pr_edict.c | 26 ++++++++++++++----- progs.h | 16 +++++++----- server.h | 4 +-- sv_main.c | 71 ++++++++++++++++++++++++++++++++++++++------------- sv_user.c | 27 ++++++++++---------- world.c | 35 +++++++++---------------- 12 files changed, 139 insertions(+), 85 deletions(-) diff --git a/cl_main.c b/cl_main.c index fa991693..ce00b637 100644 --- 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 c5c783b5..d11b8f66 100644 --- 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; } diff --git a/host_cmd.c b/host_cmd.c index 6b0cb342..1aca802b 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -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 ; iv->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 diff --git a/model_brush.c b/model_brush.c index 5bfc0ef5..444089da 100644 --- a/model_brush.c +++ b/model_brush.c @@ -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) diff --git a/net_dgrm.c b/net_dgrm.c index b3f7fae2..b271f9d7 100644 --- a/net_dgrm.c +++ b/net_dgrm.c @@ -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)); diff --git a/pr_cmds.c b/pr_cmds.c index 5941d6f7..0da857a8 100644 --- 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); diff --git a/pr_edict.c b/pr_edict.c index 6c54a7ed..d7875c5d 100644 --- a/pr_edict.c +++ b/pr_edict.c @@ -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 702c4459..929bd27c 100644 --- 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); //============================================================================ diff --git a/server.h b/server.h index 3843e38d..47e917c2 100644 --- 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; diff --git a/sv_main.c b/sv_main.c index 53702fee..d6edc1a8 100644 --- 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 ; iold_frags != host_client->edict->v->frags) + if (host_client->old_frags != EDICT_NUM(host_client->edictnumber)->v->frags) { for (j=0, client = svs.clients ; jmessage, 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 ; jspawn_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 ; iedictnumber); // 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 de5df5c5..6fceef78 100644 --- 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; -- 2.39.2