]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
cvar: use unsigned for flags and hashindex
[xonotic/darkplaces.git] / prvm_cmds.c
index 07adabf396246c2a6ec3b0e140ff3d389b1813c7..0d281e62ce7f9672edcd6da82f0a6bb5af5c56c2 100644 (file)
@@ -32,7 +32,7 @@ void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
        dpvsnprintf(msg,sizeof(msg),fmt,argptr);
        va_end(argptr);
 
-       Con_Printf(CON_WARN "%s", msg);
+       Con_Printf(CON_WARN "%s VM warning: %s", prog->name, msg);
 
        // TODO: either add a cvar/cmd to control the state dumping or replace some of the calls with Con_Printf [9/13/2006 Black]
        if(prvm_backtraceforwarnings.integer && recursive != host.realtime) // NOTE: this compares to the time, just in case if PRVM_PrintState causes a Host_Error and keeps recursive set
@@ -321,6 +321,10 @@ static qbool checkextension(prvm_prog_t *prog, const char *name)
                        if (!strcasecmp("DP_QC_DIGEST_SHA256", name))
                                return Crypto_Available();
 
+                       // special shreck for libcurl
+                       if (!strcasecmp("DP_QC_URI_GET", name) || !strcasecmp("DP_QC_URI_POST", name))
+                               return Curl_Available();
+
                        return true;
                }
        }
@@ -570,7 +574,7 @@ void VM_vectoangles(prvm_prog_t *prog)
 =================
 VM_random
 
-Returns a number from 0<= num < 1
+Returns a random number > 0 and < 1
 
 float random()
 =================
@@ -586,18 +590,29 @@ void VM_random(prvm_prog_t *prog)
 =========
 VM_localsound
 
-localsound(string sample)
+localsound(string sample, float chan, float vol)
 =========
 */
 void VM_localsound(prvm_prog_t *prog)
 {
        const char *s;
+       float chan, vol;
 
-       VM_SAFEPARMCOUNT(1,VM_localsound);
+       VM_SAFEPARMCOUNTRANGE(1, 3,VM_localsound);
 
        s = PRVM_G_STRING(OFS_PARM0);
-
-       if(!S_LocalSound (s))
+       if(prog->argc == 3)
+       {
+               chan = PRVM_G_FLOAT(OFS_PARM1);
+               vol = PRVM_G_FLOAT(OFS_PARM2) == 0 ? 1 : PRVM_G_FLOAT(OFS_PARM2);
+               if(!S_LocalSoundEx(s, chan, vol))
+               {
+                       PRVM_G_FLOAT(OFS_RETURN) = -4;
+                       VM_Warning(prog, "VM_localsound: Failed to play %s for %s !\n", s, prog->name);
+                       return;
+               }
+       }
+       else if(!S_LocalSound (s))
        {
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                VM_Warning(prog, "VM_localsound: Failed to play %s for %s !\n", s, prog->name);
@@ -930,7 +945,7 @@ void VM_ftoe(prvm_prog_t *prog)
        VM_SAFEPARMCOUNT(1, VM_ftoe);
 
        ent = (prvm_int_t)PRVM_G_FLOAT(OFS_PARM0);
-       if (ent < 0 || ent >= prog->max_edicts || PRVM_PROG_TO_EDICT(ent)->priv.required->free)
+       if (ent < 0 || ent >= prog->max_edicts || PRVM_PROG_TO_EDICT(ent)->free)
                ent = 0; // return world instead of a free or invalid entity
 
        PRVM_G_INT(OFS_RETURN) = ent;
@@ -1033,7 +1048,7 @@ void VM_remove(prvm_prog_t *prog)
                if (developer.integer > 0)
                        VM_Warning(prog, "VM_remove: tried to remove the null entity or a reserved entity!\n" );
        }
-       else if( ed->priv.required->free )
+       else if( ed->free )
        {
                if (developer.integer > 0)
                        VM_Warning(prog, "VM_remove: tried to remove an already freed entity!\n" );
@@ -1071,7 +1086,7 @@ void VM_find(prvm_prog_t *prog)
        {
                prog->xfunction->builtinsprofile++;
                ed = PRVM_EDICT_NUM(e);
-               if (ed->priv.required->free)
+               if (ed->free)
                        continue;
                t = PRVM_E_STRING(ed,f);
                if (!t)
@@ -1112,7 +1127,7 @@ void VM_findfloat(prvm_prog_t *prog)
        {
                prog->xfunction->builtinsprofile++;
                ed = PRVM_EDICT_NUM(e);
-               if (ed->priv.required->free)
+               if (ed->free)
                        continue;
                if (PRVM_E_FLOAT(ed,f) == s)
                {
@@ -1163,7 +1178,7 @@ void VM_findchain(prvm_prog_t *prog)
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                prog->xfunction->builtinsprofile++;
-               if (ent->priv.required->free)
+               if (ent->free)
                        continue;
                t = PRVM_E_STRING(ent,f);
                if (!t)
@@ -1203,7 +1218,7 @@ void VM_findchainfloat(prvm_prog_t *prog)
        else
                chainfield = prog->fieldoffsets.chain;
        if (chainfield < 0)
-               prog->error_cmd("VM_findchain: %s doesnt have the specified chain field !", prog->name);
+               prog->error_cmd("VM_findchainfloat: %s doesnt have the specified chain field !", prog->name);
 
        chain = (prvm_edict_t *)prog->edicts;
 
@@ -1214,7 +1229,7 @@ void VM_findchainfloat(prvm_prog_t *prog)
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                prog->xfunction->builtinsprofile++;
-               if (ent->priv.required->free)
+               if (ent->free)
                        continue;
                if (PRVM_E_FLOAT(ent,f) != s)
                        continue;
@@ -1252,7 +1267,7 @@ void VM_findflags(prvm_prog_t *prog)
        {
                prog->xfunction->builtinsprofile++;
                ed = PRVM_EDICT_NUM(e);
-               if (ed->priv.required->free)
+               if (ed->free)
                        continue;
                if (!PRVM_E_FLOAT(ed,f))
                        continue;
@@ -1289,7 +1304,7 @@ void VM_findchainflags(prvm_prog_t *prog)
        else
                chainfield = prog->fieldoffsets.chain;
        if (chainfield < 0)
-               prog->error_cmd("VM_findchain: %s doesnt have the specified chain field !", prog->name);
+               prog->error_cmd("VM_findchainflags: %s doesnt have the specified chain field !", prog->name);
 
        chain = (prvm_edict_t *)prog->edicts;
 
@@ -1300,7 +1315,7 @@ void VM_findchainflags(prvm_prog_t *prog)
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                prog->xfunction->builtinsprofile++;
-               if (ent->priv.required->free)
+               if (ent->free)
                        continue;
                if (!PRVM_E_FLOAT(ent,f))
                        continue;
@@ -1514,7 +1529,7 @@ void VM_nextent(prvm_prog_t *prog)
                        return;
                }
                ent = PRVM_EDICT_NUM(i);
-               if (!ent->priv.required->free)
+               if (!ent->free)
                {
                        VM_RETURN_EDICT(ent);
                        return;
@@ -2037,7 +2052,7 @@ void VM_writetofile(prvm_prog_t *prog)
        }
 
        ent = PRVM_G_EDICT(OFS_PARM1);
-       if(ent->priv.required->free)
+       if(ent->free)
        {
                VM_Warning(prog, "VM_writetofile: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent));
                return;
@@ -2138,7 +2153,7 @@ void VM_getentityfieldstring(prvm_prog_t *prog)
        
        // get the entity
        ent = PRVM_G_EDICT(OFS_PARM1);
-       if(ent->priv.required->free)
+       if(ent->free)
        {
                PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "");
                VM_Warning(prog, "VM_entityfielddata: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent));
@@ -2185,7 +2200,7 @@ void VM_putentityfieldstring(prvm_prog_t *prog)
 
        // get the entity
        ent = PRVM_G_EDICT(OFS_PARM1);
-       if(ent->priv.required->free)
+       if(ent->free)
        {
                VM_Warning(prog, "VM_entityfielddata: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent));
                PRVM_G_FLOAT(OFS_RETURN) = 0.0f;
@@ -2307,11 +2322,11 @@ void VM_strtoupper(prvm_prog_t *prog)
 =========
 VM_strcat
 
-string strcat(string,string,...[string])
+string strcat(string s, string...)
 =========
 */
-//string(string s1, string s2) strcat = #115;
-// concatenates two strings (for example "abc", "def" would return "abcdef")
+//string(string s, string...) strcat = #115;
+// concatenates strings (for example "abc", "def" would return "abcdef")
 // and returns as a tempstring
 void VM_strcat(prvm_prog_t *prog)
 {
@@ -2998,7 +3013,7 @@ void VM_parseentitydata(prvm_prog_t *prog)
 
        // get edict and test it
        ent = PRVM_G_EDICT(OFS_PARM0);
-       if (ent->priv.required->free)
+       if (ent->free)
                prog->error_cmd("VM_parseentitydata: %s: Can only set already spawned entities (entity %i is free)!", prog->name, PRVM_NUM_FOR_EDICT(ent));
 
        data = PRVM_G_STRING(OFS_PARM1);
@@ -3053,13 +3068,21 @@ float   mod(float val, float m)
 */
 void VM_modulo(prvm_prog_t *prog)
 {
-       prvm_int_t val, m;
+       vec_t val, m;
+
        VM_SAFEPARMCOUNT(2, VM_modulo);
 
-       val = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM0);
-       m       = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM1);
+       val = PRVM_G_FLOAT(OFS_PARM0);
+       m   = PRVM_G_FLOAT(OFS_PARM1);
 
-       PRVM_G_FLOAT(OFS_RETURN) = (prvm_vec_t) (val % m);
+       // matches how gmqcc implements % when mod() builtin isn't defined, and FTEQW mod()
+       if (m)
+               PRVM_G_FLOAT(OFS_RETURN) = val - m * (prvm_int_t)(val / m);
+       else
+       {
+               VM_Warning(prog, "Attempted modulo of %f by zero\n", val);
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
+       }
 }
 
 static void VM_Search_Init(prvm_prog_t *prog)
@@ -3257,10 +3280,10 @@ string keynumtostring(float keynum)
 */
 void VM_keynumtostring (prvm_prog_t *prog)
 {
-       char tinystr[2];
+       char tinystr[TINYSTR_LEN];
        VM_SAFEPARMCOUNT(1, VM_keynumtostring);
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Key_KeynumToString((int)PRVM_G_FLOAT(OFS_PARM0), tinystr, sizeof(tinystr)));
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Key_KeynumToString((int)PRVM_G_FLOAT(OFS_PARM0), tinystr, TINYSTR_LEN));
 }
 
 /*
@@ -4678,7 +4701,7 @@ void VM_changeyaw (prvm_prog_t *prog)
                VM_Warning(prog, "changeyaw: can not modify world entity\n");
                return;
        }
-       if (ent->priv.server->free)
+       if (ent->free)
        {
                VM_Warning(prog, "changeyaw: can not modify free entity\n");
                return;
@@ -4734,7 +4757,7 @@ void VM_changepitch (prvm_prog_t *prog)
                VM_Warning(prog, "changepitch: can not modify world entity\n");
                return;
        }
-       if (ent->priv.server->free)
+       if (ent->free)
        {
                VM_Warning(prog, "changepitch: can not modify free entity\n");
                return;
@@ -5136,7 +5159,7 @@ void VM_digest_hex(prvm_prog_t *prog)
 void VM_wasfreed (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_wasfreed);
-       PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_EDICT(OFS_PARM0)->priv.required->free;
+       PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_EDICT(OFS_PARM0)->free;
 }
 
 void VM_SetTraceGlobals(prvm_prog_t *prog, const trace_t *trace)
@@ -5552,6 +5575,41 @@ void VM_SV_getextresponse (prvm_prog_t *prog)
        }
 }
 
+// DP_QC_NUDGEOUTOFSOLID
+// float(entity ent) nudgeoutofsolid = #567;
+void VM_nudgeoutofsolid(prvm_prog_t *prog)
+{
+       prvm_edict_t *ent;
+
+       VM_SAFEPARMCOUNTRANGE(1, 1, VM_nudgeoutofsolid);
+
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       if (ent == prog->edicts)
+       {
+               VM_Warning(prog, "nudgeoutofsolid: can not modify world entity\n");
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
+               return;
+       }
+       if (ent->free)
+       {
+               VM_Warning(prog, "nudgeoutofsolid: can not modify free entity\n");
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
+               return;
+       }
+
+       PRVM_G_FLOAT(OFS_RETURN) = PHYS_NudgeOutOfSolid(prog, ent);
+
+       if (PRVM_G_FLOAT(OFS_RETURN) > 0)
+       {
+               if (prog == SVVM_prog)
+                       SV_LinkEdict(ent);
+               else if (prog == CLVM_prog)
+                       CL_LinkEdict(ent);
+               else
+                       Sys_Error("PHYS_NudgeOutOfSolid: cannot be called from %s VM\n", prog->name);
+       }
+}
+
 /*
 =========
 Common functions between menu.dat and clsprogs
@@ -6315,7 +6373,7 @@ void VM_getsurfacenearpoint(prvm_prog_t *prog)
        ed = PRVM_G_EDICT(OFS_PARM0);
        VectorCopy(PRVM_G_VECTOR(OFS_PARM1), point);
 
-       if (!ed || ed->priv.server->free)
+       if (!ed || ed->free)
                return;
        model = getmodel(prog, ed);
        if (!model || !model->num_surfaces)
@@ -6408,6 +6466,7 @@ void VM_getsurfacetriangle(prvm_prog_t *prog)
 // physics builtins
 //
 
+#ifdef USEODE
 #define VM_physics_ApplyCmd(ed,f) if (!ed->priv.server->ode_body) VM_physics_newstackfunction(prog, ed, f); else World_Physics_ApplyCmd(ed, f)
 
 static edict_odefunc_t *VM_physics_newstackfunction(prvm_prog_t *prog, prvm_edict_t *ed, edict_odefunc_t *f)
@@ -6426,14 +6485,17 @@ static edict_odefunc_t *VM_physics_newstackfunction(prvm_prog_t *prog, prvm_edic
        }
        return newfunc;
 }
+#endif
 
 // void(entity e, float physics_enabled) physics_enable = #;
 void VM_physics_enable(prvm_prog_t *prog)
 {
+#ifdef USEODE
        prvm_edict_t *ed;
        edict_odefunc_t f;
-       
+#endif
        VM_SAFEPARMCOUNT(2, VM_physics_enable);
+#ifdef USEODE
        ed = PRVM_G_EDICT(OFS_PARM0);
        if (!ed)
        {
@@ -6449,15 +6511,18 @@ void VM_physics_enable(prvm_prog_t *prog)
        }
        f.type = PRVM_G_FLOAT(OFS_PARM1) == 0 ? ODEFUNC_DISABLE : ODEFUNC_ENABLE;
        VM_physics_ApplyCmd(ed, &f);
+#endif
 }
 
 // void(entity e, vector force, vector relative_ofs) physics_addforce = #;
 void VM_physics_addforce(prvm_prog_t *prog)
 {
+#ifdef USEODE
        prvm_edict_t *ed;
        edict_odefunc_t f;
-       
+#endif
        VM_SAFEPARMCOUNT(3, VM_physics_addforce);
+#ifdef USEODE
        ed = PRVM_G_EDICT(OFS_PARM0);
        if (!ed)
        {
@@ -6475,15 +6540,18 @@ void VM_physics_addforce(prvm_prog_t *prog)
        VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f.v1);
        VectorCopy(PRVM_G_VECTOR(OFS_PARM2), f.v2);
        VM_physics_ApplyCmd(ed, &f);
+#endif
 }
 
 // void(entity e, vector torque) physics_addtorque = #;
 void VM_physics_addtorque(prvm_prog_t *prog)
 {
+#ifdef USEODE
        prvm_edict_t *ed;
        edict_odefunc_t f;
-       
+#endif
        VM_SAFEPARMCOUNT(2, VM_physics_addtorque);
+#ifdef USEODE
        ed = PRVM_G_EDICT(OFS_PARM0);
        if (!ed)
        {
@@ -6500,6 +6568,7 @@ void VM_physics_addtorque(prvm_prog_t *prog)
        f.type = ODEFUNC_TORQUE;
        VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f.v1);
        VM_physics_ApplyCmd(ed, &f);
+#endif
 }
 
 extern cvar_t prvm_coverage;