]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_edict.c
support skin and pflags in light entity loader
[xonotic/darkplaces.git] / prvm_edict.c
index a55dcffed020db5242864184335c2ca4adc6b701..daa322d031e6e857a7190f8e8b1f427aa0d70646 100644 (file)
@@ -50,11 +50,13 @@ void PRVM_MEM_Alloc()
 {
        int i;
 
+       // reserve space for the null entity aka world
        // check bound of max_edicts
-       prog->max_edicts = min(prog->max_edicts,prog->limit_edicts);
+       prog->max_edicts = bound(1, prog->max_edicts, prog->limit_edicts);
+       prog->num_edicts = bound(1, prog->num_edicts, prog->max_edicts);        
 
        // edictprivate_size has to be min as big prvm_edict_private_t
-       prog->edictprivate_size = max(prog->edictprivate_size,sizeof(prvm_edict_private_t)); 
+       prog->edictprivate_size = max(prog->edictprivate_size,(int)sizeof(prvm_edict_private_t)); 
 
        // alloc edicts
        prog->edicts = Mem_Alloc(prog->edicts_mempool,prog->limit_edicts * sizeof(prvm_edict_t));
@@ -215,13 +217,15 @@ prvm_edict_t *PRVM_ED_Alloc (void)
 
        // the client qc dont need maxclients
        // thus it doesnt need to use svs.maxclients
-       // AK: changed i=svs.maxclients+1
-       for (i = 0;i < prog->num_edicts;i++)
+       // AK:  changed i=svs.maxclients+1
+       // AK:  changed so the edict 0 wont spawn -> used as reserved/world entity
+       //              although the menu/client has no world
+       for (i = 1;i < prog->num_edicts;i++)
        {
                e = PRVM_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->e->free && ( e->e->freetime < 2 || prog->time - e->e->freetime > 0.5 ) )
+               if (e->e->free && ( e->e->freetime < 2 || (*prog->time - e->e->freetime) > 0.5 ) )
                {
                        PRVM_ED_ClearEdict (e);
                        return e;
@@ -251,10 +255,14 @@ FIXME: walk all entities and NULL out references to this entity
 */
 void PRVM_ED_Free (prvm_edict_t *ed)
 {
+       // dont delete the null entity (world)
+       if(PRVM_NUM_FOR_EDICT(ed) == 0)
+               return;
+
        PRVM_GCALL(free_edict)(ed);
 
        ed->e->free = true;
-       ed->e->freetime = prog->time;
+       ed->e->freetime = *prog->time;
 }
 
 //===========================================================================
@@ -682,7 +690,7 @@ void PRVM_ED_PrintEdicts_f (void)
 
        if(Cmd_Argc() != 2)
        {
-               Con_Print("prvm_edicts <program name>\n");
+               Con_Printf("prvm_edicts <program name>\n");
                return;
        }
        
@@ -710,7 +718,7 @@ void PRVM_ED_PrintEdict_f (void)
 
        if(Cmd_Argc() != 3)
        {
-               Con_Print("prvm_edict <program name> <edict number>\n");
+               Con_Printf("prvm_edict <program name> <edict number>\n");
                return;
        }
 
@@ -722,6 +730,7 @@ void PRVM_ED_PrintEdict_f (void)
        if (i >= prog->num_edicts)
        {
                Con_Printf("Bad edict number\n");
+               PRVM_End;
                return;
        }
        PRVM_ED_PrintNum (i);
@@ -746,7 +755,7 @@ void PRVM_ED_Count_f (void)
 
        if(Cmd_Argc() != 2)
        {
-               Con_Print("prvm_count <program name>\n");
+               Con_Printf("prvm_count <program name>\n");
                return;
        }
 
@@ -767,7 +776,7 @@ void PRVM_ED_Count_f (void)
                        active++;
                }
                
-               Con_Printf ("num_edicts:%3i\n", sv.num_edicts);
+               Con_Printf ("num_edicts:%3i\n", prog->num_edicts);
                Con_Printf ("active    :%3i\n", active);
        }
 
@@ -887,7 +896,6 @@ char *PRVM_ED_NewString (const char *string)
        return new;
 }
 
-
 /*
 =============
 PRVM_ED_ParseEval
@@ -910,7 +918,7 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
        switch (key->type & ~DEF_SAVEGLOBAL)
        {
        case ev_string:
-               val->string = PRVM_SetString(ED_NewString(s));
+               val->string = PRVM_SetString(PRVM_ED_NewString(s));
                break;
 
        case ev_float:
@@ -953,7 +961,7 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
                def = PRVM_ED_FindField(s);
                if (!def)
                {
-                       Con_DPrintf("PRVM_ED_ParseEpair: Can't find field %s on %s\n", s, PRVM_NAME);
+                       Con_DPrintf("PRVM_ED_ParseEpair: Can't find field %s in %s\n", s, PRVM_NAME);
                        return false;
                }
                val->_int = PRVM_G_INT(def->ofs);
@@ -963,7 +971,7 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
                func = PRVM_ED_FindFunction(s);
                if (!func)
                {
-                       Con_Printf ("PRVM_ED_ParseEpair: Can't find function %s on %s\n", s, PRVM_NAME);
+                       Con_Printf ("PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, PRVM_NAME);
                        return false;
                }
                val->function = func - prog->functions;
@@ -976,6 +984,44 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
        return true;
 }
 
+/*
+=============
+PRVM_ED_EdictSet_f
+
+Console command to set a field of a specified edict
+=============
+*/
+void PRVM_ED_EdictSet_f(void)
+{
+       prvm_edict_t *ed;
+       ddef_t *key;
+
+       if(Cmd_Argc() != 5)
+       {
+               Con_Printf("prvm_edictset <program name> <edict number> <field> <value>\n");
+               return;
+       }
+
+       PRVM_Begin;
+       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+       {
+               Con_Printf("Wrong program name %s !\n", Cmd_Argv(1));
+               return;
+       }
+
+       ed = PRVM_EDICT_NUM(atoi(Cmd_Argv(2)));
+
+       if((key = PRVM_ED_FindField(Cmd_Argv(3))) == 0)
+       {
+               Con_Printf("Key %s not found !\n", Cmd_Argv(3));
+               return;
+       }
+
+       PRVM_ED_ParseEpair(ed, key, Cmd_Argv(4));
+
+       PRVM_End;
+}
+
 /*
 ====================
 PRVM_ED_ParseEdict
@@ -1024,7 +1070,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent)
 
                strcpy (keyname, com_token);
 
-               // another hack to fix heynames with trailing spaces
+               // another hack to fix keynames with trailing spaces
                n = strlen(keyname);
                while (n && keyname[n-1] == ' ')
                {
@@ -1092,16 +1138,12 @@ void PRVM_ED_LoadFromFile (const char *data)
        int parsed, inhibited, spawned, died;
        mfunction_t *func;
 
-       ent = NULL;
        parsed = 0;
        inhibited = 0;
        spawned = 0;
        died = 0;
 
-       // time defined ?
-       if(prog->flag & PRVM_GE_TIME)
-               PRVM_G_FLOAT(PRVM_ED_FindFieldOffset("time")) = prog->time;
-       
+
 // parse ents
        while (1)
        {
@@ -1109,12 +1151,14 @@ void PRVM_ED_LoadFromFile (const char *data)
                if (!COM_ParseToken(&data, false))
                        break;
                if (com_token[0] != '{')
-                       PRVM_ERROR ("PRVM_ED_LoadFromFile: found %s when expecting (%s) {",com_token, PRVM_NAME);
+                       PRVM_ERROR ("PRVM_ED_LoadFromFile: %s: found %s when expecting {", PRVM_NAME, com_token);
 
-               if (!ent)
+               // CHANGED: this is not conform to ED_LoadFromFile
+               if(!prog->num_edicts) 
                        ent = PRVM_EDICT_NUM(0);
-               else
-                       ent = PRVM_ED_Alloc ();
+               else 
+                       ent = PRVM_ED_Alloc();
+
                data = PRVM_ED_ParseEdict (data, ent);
                parsed++;
 
@@ -1127,7 +1171,7 @@ void PRVM_ED_LoadFromFile (const char *data)
                }
 
 //
-// immediately call spawn function, but only if there is a self global
+// immediately call spawn function, but only if there is a self global and a classname
 //
                if(prog->self && prog->flag & PRVM_FE_CLASSNAME)
                {
@@ -1164,8 +1208,8 @@ void PRVM_ED_LoadFromFile (const char *data)
                        died++;
        }
 
-       Con_DPrintf ("%s: %i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", PRVM_NAME, parsed, inhibited, spawned, died, spawned - died);
-}
+       Con_DPrintf ("%s: %i new entities parsed, %i new inhibited, %i (%i new) spawned (whereas %i removed self, %i stayed)\n", PRVM_NAME, parsed, inhibited, prog->num_edicts, spawned, died, spawned - died);
+}      
 
 // not used
 /*
@@ -1191,7 +1235,7 @@ PRVM_ResetProg
 
 void PRVM_ResetProg()
 {
-       mempool_t *t1, *t2, *t3;
+       /*mempool_t *t1, *t2, *t3;
 
        t1 = prog->progs_mempool;
        t2 = prog->edictstring_mempool;
@@ -1199,14 +1243,18 @@ void PRVM_ResetProg()
        
        Mem_EmptyPool(prog->progs_mempool);
        Mem_EmptyPool(prog->edictstring_mempool);
-       Mem_EmptyPool(prog->edicts_mempool);
+       Mem_EmptyPool(prog->edicts_mempool);*/
+       Mem_FreePool(&prog->progs_mempool);
+       Mem_FreePool(&prog->edictstring_mempool);
+       Mem_FreePool(&prog->edicts_mempool);
        
        memset(prog,0,sizeof(prvm_prog_t));
        
+       /*prog->time = &prog->_time;
        
        prog->progs_mempool = t1;
        prog->edictstring_mempool = t2;
-       prog->edicts_mempool = t3;
+       prog->edicts_mempool = t3;*/
 
        PRVM_GCALL(reset_cmd)();
 }
@@ -1441,16 +1489,20 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
        prog->self = PRVM_ED_FindGlobal("self");
 
        if(PRVM_ED_FindGlobal("time"))
-               prog->flag |= PRVM_GE_TIME;
+               prog->time = &PRVM_G_FLOAT(PRVM_ED_FindGlobal("time")->ofs);
 
-       if(PRVM_ED_FindFieldOffset ("classname"))
+       if(PRVM_ED_FindField ("chain"))
+               prog->flag |= PRVM_FE_CHAIN;
+
+       if(PRVM_ED_FindField ("classname"))
                prog->flag |= PRVM_FE_CLASSNAME; 
 
-       if(PRVM_ED_FindFieldOffset ("nextthink") && PRVM_ED_FindFieldOffset("frame") && PRVM_ED_FindFieldOffset("think") 
-               && prog->flag &  PRVM_GE_TIME && prog->self) 
+       if(PRVM_ED_FindField ("nextthink") && PRVM_ED_FindField ("frame") && PRVM_ED_FindField ("think") 
+               && prog->flag && prog->self) 
                prog->flag |= PRVM_OP_STATE;
        
        PRVM_GCALL(reset_cmd)();
+       PRVM_GCALL(init_cmd)();
 
        // init mempools
        PRVM_MEM_Alloc();
@@ -1477,7 +1529,7 @@ void PRVM_Fields_f (void)
 
        if(Cmd_Argc() != 2)
        {
-               Con_Print("prvm_fields <program name>\n");
+               Con_Printf("prvm_fields <program name>\n");
                return;
        }
 
@@ -1590,7 +1642,7 @@ void PRVM_Globals_f (void)
        }*/
        if(Cmd_Argc () != 2)
        {
-               Con_Print ("prvm_globals <program name>\n");
+               Con_Printf("prvm_globals <program name>\n");
                return;
        }
 
@@ -1601,7 +1653,7 @@ void PRVM_Globals_f (void)
        Con_Printf("%s :", PRVM_NAME);
 
        for (i = 0;i < prog->progs->numglobaldefs;i++)
-               Con_Printf("%s\n", PRVM_GetString(pr_globaldefs[i].s_name));
+               Con_Printf("%s\n", PRVM_GetString(prog->globaldefs[i].s_name));
        Con_Printf("%i global variables, totalling %i bytes\n", prog->progs->numglobals, prog->progs->numglobals * 4);
 
        PRVM_End;
@@ -1620,11 +1672,12 @@ void PRVM_Init (void)
        Cmd_AddCommand ("prvm_profile", PRVM_Profile_f);
        Cmd_AddCommand ("prvm_fields", PRVM_Fields_f);
        Cmd_AddCommand ("prvm_globals", PRVM_Globals_f);
+       Cmd_AddCommand ("prvm_edictset", PRVM_ED_EdictSet_f);
        // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
        Cvar_RegisterVariable (&prvm_boundscheck);
        Cvar_RegisterVariable (&prvm_traceqc);
 
-       VM_Cmd_Init();
+       //VM_Cmd_Init();
 }
 
 /*
@@ -1639,9 +1692,12 @@ void PRVM_InitProg(int prognr)
 
        prog = &prog_list[prognr];
 
+       if(prog->loaded)
+               PRVM_ResetProg();
+
        memset(prog, 0, sizeof(prvm_prog_t));
 
-       PRVM_GCALL(init_cmd)();
+       prog->time = &prog->_time;
 }
 
 int PRVM_GetProgNr()
@@ -1656,6 +1712,12 @@ prvm_edict_t *PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline)
        return NULL;
 }
 
+void PRVM_ProcessError(void)
+{
+       if(prog)
+               PRVM_GCALL(error_cmd)();
+}
+
 /*
 int NUM_FOR_EDICT_ERROR(edict_t *e)
 {