3 #include "autocvars.qh"
6 #include "../common/constants.qh"
7 #include "../common/util.qh"
9 #include "../warpzonelib/mathlib.qh"
11 #define TUBA_STARTNOTE(i, n) strcat("weapons/tuba", (i ? ftos(i) : ""), "_loopnote", ftos(n), ".wav")
13 const int TUBA_MIN = -18;
14 const int TUBA_MAX = 27;
15 const int TUBA_INSTRUMENTS = 3;
17 class(Tuba) .int note;
18 class(Tuba) .bool tuba_attenuate;
19 class(Tuba) .float tuba_volume;
20 class(Tuba) .float tuba_volume_initial;
21 class(Tuba) .int tuba_instrument;
25 void tubasound(entity e, bool restart)
27 string snd1 = string_null;
31 string snd2 = string_null;
35 int m = pymod(e.note, Tuba_PitchStep);
37 if (e.note - m < TUBA_MIN) {
39 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
41 speed1 = pow(2.0, (m - Tuba_PitchStep) / 12.0);
42 } else if (e.note - m + Tuba_PitchStep > TUBA_MAX) {
44 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
46 speed1 = pow(2.0, m / 12.0);
49 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
51 vol1 = cos(M_PI_2 * m / Tuba_PitchStep);
52 speed1 = pow(2.0, m / 12.0);
54 snd2 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
56 vol2 = sin(M_PI_2 * m / Tuba_PitchStep);
57 speed2 = pow(2.0, (m - Tuba_PitchStep) / 12.0);
60 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
63 sound7(e, CH_TUBA_SINGLE, snd1, e.tuba_volume * vol1, e.tuba_attenuate * autocvar_g_balance_tuba_attenuation, 100 * speed1, 0);
65 sound7(e.enemy, CH_TUBA_SINGLE, snd2, e.tuba_volume * vol2, e.tuba_attenuate * autocvar_g_balance_tuba_attenuation, 100 * speed2, 0);
69 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
71 sound(e, CH_TUBA_SINGLE, snd1, e.tuba_volume, e.tuba_attenuate * autocvar_g_balance_tuba_attenuation);
75 void Ent_TubaNote_Think()
77 float f = autocvar_g_balance_tuba_fadetime;
79 self.tuba_volume -= frametime * self.tuba_volume_initial / f;
83 self.nextthink = time;
84 if (self.tuba_volume <= 0) {
85 sound(self, CH_TUBA_SINGLE, "misc/null.wav", 0, 0);
87 sound(self.enemy, CH_TUBA_SINGLE, "misc/null.wav", 0, 0);
96 void Ent_TubaNote_UpdateSound()
98 self.enemy.tuba_volume = bound(0, VOL_BASE * autocvar_g_balance_tuba_volume, 1);
99 self.enemy.tuba_volume_initial = self.enemy.tuba_volume;
100 self.enemy.note = self.note;
101 self.enemy.tuba_instrument = self.tuba_instrument;
102 tubasound(self.enemy, 1);
105 void Ent_TubaNote_StopSound()
107 self.enemy.nextthink = time;
111 void Ent_TubaNote(bool isNew)
122 if (n != self.note || i != self.tuba_instrument || isNew) {
123 Ent_TubaNote_StopSound();
126 self.enemy = spawn();
127 self.enemy.classname = "tuba_note";
128 if (Tuba_PitchStep) {
129 self.enemy.enemy = spawn();
130 self.enemy.enemy.classname = "tuba_note_2";
135 self.enemy.tuba_attenuate = att;
139 self.tuba_instrument = i;
145 self.enemy.origin_x = ReadCoord();
146 self.enemy.origin_y = ReadCoord();
147 self.enemy.origin_z = ReadCoord();
148 setorigin(self.enemy, self.enemy.origin);
149 if (self.enemy.enemy) {
150 setorigin(self.enemy.enemy, self.enemy.origin);
154 self.think = Ent_TubaNote_StopSound;
155 self.entremove = Ent_TubaNote_StopSound;
156 self.enemy.think = Ent_TubaNote_Think;
157 self.enemy.nextthink = time + 10;
160 Ent_TubaNote_UpdateSound();
166 Tuba_PitchStep = autocvar_g_balance_tuba_pitchstep;
167 if (Tuba_PitchStep) {
168 if (!checkextension("DP_SND_SOUND7_WIP2") && !checkextension("DP_SND_SOUND7")) {
169 print("^1NOTE:^7 requested pitch shifting, but not supported by this engine build\n");
173 for (int n = TUBA_MIN; n <= TUBA_MAX; ++n) {
174 if (!Tuba_PitchStep || pymod(n, Tuba_PitchStep) == 0) {
175 for (int i = 0; i < TUBA_INSTRUMENTS; ++i) {
176 precache_sound(TUBA_STARTNOTE(i, n));