]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
csqc: Implement builtin #177 "localsound"
[xonotic/darkplaces.git] / prvm_cmds.c
index 67ccb3f31151dfc810137fcd1c4f71253da8d83d..3ef0b74cf939fc417757249a4e328f1a5d0dcfb8 100644 (file)
@@ -58,6 +58,34 @@ void VM_CheckEmptyString(prvm_prog_t *prog, const char *s)
                prog->error_cmd("%s: Bad string", prog->name);
 }
 
+qbool PRVM_ConsoleCommand (prvm_prog_t *prog, const char *text, int *func, qbool preserve_self, int curself, double ptime, qbool prog_loaded, const char *error_message)
+{
+       int restorevm_tempstringsbuf_cursize;
+       int save_self = 0; // hush compiler warning
+       qbool r = false;
+
+       if(!prog_loaded)
+               return false;
+
+       if(func)
+       {
+               if(preserve_self)
+                       save_self = PRVM_gameglobaledict(self);
+               if(ptime)
+                       PRVM_gameglobalfloat(time) = ptime;
+               PRVM_gameglobaledict(self) = curself;
+               restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
+               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, text);
+               prog->ExecuteProgram(prog, *func, error_message);
+               prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+               if(preserve_self)
+                       PRVM_gameglobaledict(self) = save_self;
+               r = (int) PRVM_G_FLOAT(OFS_RETURN) != 0;
+       }
+
+       return r;
+}
+
 void VM_GenerateFrameGroupBlend(prvm_prog_t *prog, framegroupblend_t *framegroupblend, const prvm_edict_t *ed)
 {
        // self.frame is the interpolation target (new frame)
@@ -558,18 +586,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);
@@ -595,7 +634,7 @@ void VM_break(prvm_prog_t *prog)
 
 /*
 =================
-VM_localcmd_client
+VM_localcmd_local
 
 Sends text over to the client's execution buffer
 
@@ -603,12 +642,12 @@ Sends text over to the client's execution buffer
 cmd (string, ...)
 =================
 */
-void VM_localcmd_client(prvm_prog_t *prog)
+void VM_localcmd_local(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
-       VM_SAFEPARMCOUNTRANGE(1, 8, VM_localcmd_client);
+       VM_SAFEPARMCOUNTRANGE(1, 8, VM_localcmd_local);
        VM_VarString(prog, 0, string, sizeof(string));
-       Cbuf_AddText(cmd_client, string);
+       Cbuf_AddText(cmd_local, string);
 }
 
 /*
@@ -626,7 +665,7 @@ void VM_localcmd_server(prvm_prog_t *prog)
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(1, 8, VM_localcmd_server);
        VM_VarString(prog, 0, string, sizeof(string));
-       Cbuf_AddText(cmd_server, string);
+       Cbuf_AddText(cmd_local, string);
 }
 
 static qbool PRVM_Cvar_ReadOk(prvm_prog_t *prog, const char *string)
@@ -902,7 +941,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;
@@ -1005,7 +1044,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" );
@@ -1043,7 +1082,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)
@@ -1084,7 +1123,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)
                {
@@ -1135,7 +1174,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)
@@ -1186,7 +1225,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;
@@ -1224,7 +1263,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;
@@ -1272,7 +1311,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;
@@ -1335,12 +1374,11 @@ coredump()
 */
 void VM_coredump(prvm_prog_t *prog)
 {
-       cmd_state_t *cmd =      !host_isclient.integer ? cmd_server : cmd_client;
        VM_SAFEPARMCOUNT(0,VM_coredump);
 
-       Cbuf_AddText(cmd, "prvm_edicts ");
-       Cbuf_AddText(cmd, prog->name);
-       Cbuf_AddText(cmd, "\n");
+       Cbuf_AddText(cmd_local, "prvm_edicts ");
+       Cbuf_AddText(cmd_local, prog->name);
+       Cbuf_AddText(cmd_local, "\n");
 }
 
 /*
@@ -1487,7 +1525,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;
@@ -1521,7 +1559,7 @@ void VM_changelevel(prvm_prog_t *prog)
                return;
        svs.changelevel_issued = true;
 
-       Cbuf_AddText(cmd_server, va(vabuf, sizeof(vabuf), "changelevel %s\n", PRVM_G_STRING(OFS_PARM0)));
+       Cbuf_AddText(cmd_local, va(vabuf, sizeof(vabuf), "changelevel %s\n", PRVM_G_STRING(OFS_PARM0)));
 }
 
 /*
@@ -1669,7 +1707,7 @@ void VM_registercvar(prvm_prog_t *prog)
                return;
 
 // check for overlap with a command
-       if (Cmd_Exists(cmd_client, name) || Cmd_Exists(cmd_server, name))
+       if (Cmd_Exists(cmd_local, name))
        {
                VM_Warning(prog, "VM_registercvar: %s is a command\n", name);
                return;
@@ -2010,7 +2048,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;
@@ -2111,7 +2149,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));
@@ -2158,7 +2196,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;
@@ -2971,7 +3009,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);
@@ -4651,7 +4689,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;
@@ -4707,7 +4745,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;
@@ -5109,7 +5147,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)
@@ -6288,7 +6326,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)
@@ -6381,6 +6419,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)
@@ -6399,14 +6438,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)
        {
@@ -6422,15 +6464,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)
        {
@@ -6448,15 +6493,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)
        {
@@ -6473,6 +6521,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;