From cb8df07b4ed0f42a349e405dd265f4af28189c29 Mon Sep 17 00:00:00 2001 From: div0 Date: Wed, 15 Apr 2009 22:41:07 +0000 Subject: [PATCH] experimental system for music synced particle effects. Not stable yet! git-svn-id: svn://svn.icculus.org/nexuiz/trunk@6492 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/client/csqc_builtins.qc | 2 + data/qcsrc/client/particles.qc | 115 +++++++++++++++++++++++++++- data/qcsrc/server/clientcommands.qc | 4 +- data/qcsrc/server/extensions.qh | 8 ++ data/qcsrc/server/g_triggers.qc | 1 + 5 files changed, 126 insertions(+), 4 deletions(-) diff --git a/data/qcsrc/client/csqc_builtins.qc b/data/qcsrc/client/csqc_builtins.qc index 6cde20158..6efdec1ab 100644 --- a/data/qcsrc/client/csqc_builtins.qc +++ b/data/qcsrc/client/csqc_builtins.qc @@ -279,3 +279,5 @@ float(entity ent) wasfreed = #353; entity(vector org, float rad) findradius = #22; string(float uselocaltime, string format, ...) strftime = #478; +float(float timer) gettime = #519; +#define GETTIME_CDTRACK 4 diff --git a/data/qcsrc/client/particles.qc b/data/qcsrc/client/particles.qc index 1a629bb27..54d7fbf5b 100644 --- a/data/qcsrc/client/particles.qc +++ b/data/qcsrc/client/particles.qc @@ -49,20 +49,123 @@ float PointInBrush(entity brush, vector point) .float volume; .float absolute; .vector movedir; // trace direction +.string message; // script stuff + +float pointparticles_scriptbuf; +float pointparticles_scriptbufsize; +float pointparticles_scriptbufloaded; +void PointparticlesScript_Init() +{ + string s; + float fh, i; + pointparticles_scriptbuf = pointparticles_scriptbufsize = 0; + pointparticles_scriptbufloaded = 1; + s = strcat("maps/", mi_shortname, ".pp"); + fh = fopen(s, FILE_READ); + if(fh < 0) + return; + pointparticles_scriptbuf = buf_create(); + while((s = fgets(fh))) + { + bufstr_set(pointparticles_scriptbuf, pointparticles_scriptbufsize, s); + ++pointparticles_scriptbufsize; + } + fclose(fh); +} + +.float scriptline; +.float scriptline0; +.float scriptstate; +.float scripttime; +void PointparticlesScript_InitEntity(entity e) +{ + if(e.message != "") + { + if(!pointparticles_scriptbufloaded) + PointparticlesScript_Init(); + + string mychar; + float i; + + e.scriptline0 = -1; + mychar = substring(e.message, 0, 1); + for(i = 0; i < pointparticles_scriptbufsize; ++i) + { + tokenize_sane(bufstr_get(pointparticles_scriptbuf, i)); + if(argv(0) == mychar) + break; + } + e.scriptline = e.scriptline0 = i; + if(i >= pointparticles_scriptbufsize) + { + print("func_pointparticles: script does not define ", mychar, "\n"); + e.message = ""; + } + } +} + +float PointparticlesScript(entity e) +{ + string l; + string mychar; + float mymult; + float t; + + if(e.message == "") + return 1; + + e.scriptstate = !!e.scriptstate; // turns 0 to 0 and 2 to 1 + + mychar = substring(e.message, 0, 1); + mymult = stof(substring(e.message, 1, -1)); + t = gettime(GETTIME_CDTRACK); + + tokenize_sane(bufstr_get(pointparticles_scriptbuf, e.scriptline)); + if(t < e.scripttime) + { + e.scriptline = e.scriptline0; + e.scriptstate = 0; + tokenize_sane(bufstr_get(pointparticles_scriptbuf, e.scriptline)); + } + + if(argv(0) != mychar) + { + e.scriptstate = 0; // end of script, will revert to beginning later + } + else if(t >= stof(argv(1))) + { + // time code reached! + e.scriptstate = stof(argv(2)) * 2; // 0 = off, 2 = on + e.scripttime = stof(argv(1)); + e.scriptline += 1; + } + + if(e.scriptstate) + { + if(mymult >= 1) + return (e.scriptstate == 2); + else + return pow(0.5, (t - e.scripttime) * (mymult / (1 - mymult))); + } + else + return 0; +} void Draw_PointParticles() { - float n, i, fail; + float n, i, fail, force; vector p; vector sz; vector o; o = self.origin; sz = self.maxs - self.mins; n = self.impulse * drawframetime; + n *= PointparticlesScript(self); if(n == 0) return; fail = 0; - for(i = random(); i <= n && fail <= 64*n; ++i) + force = (self.scriptstate == 2); + for(i = random(); (force || i <= n) && fail <= 64*n; ++i) { p = o + self.mins; p_x += random() * sz_x; @@ -83,6 +186,7 @@ void Draw_PointParticles() self.origin = p; sound(self, CHAN_AUTO, self.noise, VOL_BASE * self.volume, self.atten); } + force = 0; } else if(self.absolute) { @@ -98,6 +202,9 @@ void Ent_PointParticles_Remove() if(self.noise) strunzone(self.noise); self.noise = string_null; + if(self.message) + strunzone(self.message); + self.message = string_null; } void Ent_PointParticles() @@ -150,6 +257,10 @@ void Ent_PointParticles() self.atten = ReadByte() / 64.0; self.volume = ReadByte() / 255.0; } + if(self.message) + strunzone(self.message); + self.message = strzone(ReadString()); + PointparticlesScript_InitEntity(self); } if(f & 2) diff --git a/data/qcsrc/server/clientcommands.qc b/data/qcsrc/server/clientcommands.qc index d9b291055..8ca25b106 100644 --- a/data/qcsrc/server/clientcommands.qc +++ b/data/qcsrc/server/clientcommands.qc @@ -145,14 +145,14 @@ void SV_ParseClientCommand(string s) { } else if(argv(0) == "reportcvar") { // old system if(substring(argv(2), 0, 1) == "$") // undefined cvar: use the default value on the server then { - s = strcat(substring(s, argv_start_index(0), argv_end_index(1)), " \"", cvar_defstring(argv(1)), "\""); + s = strcat(substring(s, argv_start_index(0), argv_end_index(1) - argv_start_index(0)), " \"", cvar_defstring(argv(1)), "\""); tokens = tokenize_sane(s); } GetCvars(1); } else if(argv(0) == "sentcvar") { // new system if(tokens == 2) // undefined cvar: use the default value on the server then { - s = strcat(substring(s, argv_start_index(0), argv_end_index(1)), " \"", cvar_defstring(argv(1)), "\""); + s = strcat(substring(s, argv_start_index(0), argv_end_index(1) - argv_start_index(0)), " \"", cvar_defstring(argv(1)), "\""); tokens = tokenize_sane(s); } GetCvars(1); diff --git a/data/qcsrc/server/extensions.qh b/data/qcsrc/server/extensions.qh index c04d000ab..e7bdb01d2 100644 --- a/data/qcsrc/server/extensions.qh +++ b/data/qcsrc/server/extensions.qh @@ -776,6 +776,14 @@ float(float tmr) gettime = #519; //description: //some timers to query... +//DP_QC_GETTIME_CDTRACK +//idea: div0 +//darkplaces implementation: div0 +//constant definitions: +float GETTIME_CDTRACK = 4; +//description: +//returns the playing time of the current cdtrack when passed to gettime() + //DP_QC_MINMAXBOUND //idea: LordHavoc //darkplaces implementation: LordHavoc diff --git a/data/qcsrc/server/g_triggers.qc b/data/qcsrc/server/g_triggers.qc index fd6217346..d42feaff8 100644 --- a/data/qcsrc/server/g_triggers.qc +++ b/data/qcsrc/server/g_triggers.qc @@ -602,6 +602,7 @@ float pointparticles_SendEntity(entity to, float fl) WriteByte(MSG_ENTITY, floor(self.atten * 64)); WriteByte(MSG_ENTITY, floor(self.volume * 255)); } + WriteString(MSG_ENTITY, self.message); } return 1; } -- 2.39.2