]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_edict.c
Added an implementation of Lehmer random number generator with Lecuyer constant,...
[xonotic/darkplaces.git] / prvm_edict.c
index 7dcf6daa39b6045760c2a311b153a30438ea920e..79c937a492767aa72088748435fe4536a8b49f30 100644 (file)
@@ -215,8 +215,8 @@ const char *PRVM_AllocationOrigin(prvm_prog_t *prog)
        if(prog->leaktest_active)
        if(prog->depth > 0) // actually in QC code and not just parsing the entities block of a map/savegame
        {
-               buf = (char *)PRVM_Alloc(128);
-               PRVM_ShortStackTrace(prog, buf, 128);
+               buf = (char *)PRVM_Alloc(256);
+               PRVM_ShortStackTrace(prog, buf, 256);
        }
        return buf;
 }
@@ -1938,6 +1938,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
        unsigned int d;
        char vabuf[1024];
        char vabuf2[1024];
+       cvar_t *cvar;
 
        if (prog->loaded)
                prog->error_cmd("PRVM_LoadProgs: there is already a %s program loaded!", prog->name );
@@ -2353,6 +2354,9 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                }
        }
 
+       for (cvar = cvar_vars; cvar; cvar = cvar->next)
+               cvar->globaldefindex[prog - prvm_prog_list] = -1;
+
        for (i=0 ; i<prog->numglobaldefs ; i++)
        {
                const char *name;
@@ -2364,7 +2368,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                )
                {
                        prvm_eval_t *val = PRVM_GLOBALFIELDVALUE(prog->globaldefs[i].ofs);
-                       cvar_t *cvar = Cvar_FindVar(name + 9);
+                       cvar = Cvar_FindVar(name + 9);
                        //Con_Printf("PRVM_LoadProgs: autocvar global %s in %s, processing...\n", name, prog->name);
                        if(!cvar)
                        {
@@ -2398,7 +2402,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                                }
                                if(!cvar)
                                        prog->error_cmd("PRVM_LoadProgs: could not create cvar for autocvar global %s in %s", name, prog->name);
-                               cvar->globaldefindex_progid[prog - prvm_prog_list] = prog->id;
                                cvar->globaldefindex[prog - prvm_prog_list] = i;
                        }
                        else if((cvar->flags & CVAR_PRIVATE) == 0)
@@ -2435,7 +2438,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                                                Con_Printf("PRVM_LoadProgs: invalid type of autocvar global %s in %s\n", name, prog->name);
                                                goto fail;
                                }
-                               cvar->globaldefindex_progid[prog - prvm_prog_list] = prog->id;
                                cvar->globaldefindex[prog - prvm_prog_list] = i;
                        }
                        else
@@ -3284,18 +3286,6 @@ static qboolean PRVM_IsEdictReferenced(prvm_prog_t *prog, prvm_edict_t *edict, i
                if(!*targetname) // ""
                        targetname = NULL;
 
-       if(mark == 0)
-       {
-               for (i = 0;i < prog->numglobaldefs;i++)
-               {
-                       ddef_t *d = &prog->globaldefs[i];
-                       if((etype_t)((int) d->type & ~DEF_SAVEGLOBAL) != ev_entity)
-                               continue;
-                       if(edictnum == PRVM_GLOBALFIELDEDICT(d->ofs))
-                               return true;
-               }
-       }
-
        for(j = 0; j < prog->num_edicts; ++j)
        {
                prvm_edict_t *ed = PRVM_EDICT_NUM(j);
@@ -3325,19 +3315,35 @@ static qboolean PRVM_IsEdictReferenced(prvm_prog_t *prog, prvm_edict_t *edict, i
 
 static void PRVM_MarkReferencedEdicts(prvm_prog_t *prog)
 {
-       int j;
+       int i, j;
        qboolean found_new;
        int stage;
 
+       // Stage 1: world, all entities that are relevant, and all entities that are referenced by globals.
+       stage = 1;
        for(j = 0; j < prog->num_edicts; ++j)
        {
                prvm_edict_t *ed = PRVM_EDICT_NUM(j);
                if(ed->priv.required->free)
                        continue;
-               ed->priv.required->mark = PRVM_IsEdictRelevant(prog, ed) ? 1 : 0;
+               ed->priv.required->mark = PRVM_IsEdictRelevant(prog, ed) ? stage : 0;
+       }
+       for (i = 0;i < prog->numglobaldefs;i++)
+       {
+               ddef_t *d = &prog->globaldefs[i];
+               prvm_edict_t *ed;
+               if((etype_t)((int) d->type & ~DEF_SAVEGLOBAL) != ev_entity)
+                       continue;
+               j = PRVM_GLOBALFIELDEDICT(d->ofs);
+               if (i < 0 || j >= prog->max_edicts) {
+                       Con_Printf("Invalid entity reference from global %s.\n", PRVM_GetString(prog, d->s_name));
+                       continue;
+               }
+               ed = PRVM_EDICT_NUM(j);;
+               ed->priv.required->mark = stage;
        }
 
-       stage = 1;
+       // Future stages: all entities that are referenced by an entity of the previous stage.
        do
        {
                found_new = false;