]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/tuba.qc
#include this
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / tuba.qc
1 #if defined(CSQC)
2         #include "../dpdefs/csprogsdefs.qc"
3         #include "../common/constants.qh"
4         #include "../warpzonelib/mathlib.qh"
5         #include "../common/util.qh"
6         #include "autocvars.qh"
7         #include "main.qh"
8         #include "../csqcmodellib/cl_model.qh"
9 #elif defined(MENUQC)
10 #elif defined(SVQC)
11 #endif
12
13 const float TUBA_MIN = -18;
14 const float TUBA_MAX =  27;
15 const float TUBA_INSTRUMENTS = 3;
16
17 #define TUBA_STARTNOTE(i,n) strcat("weapons/tuba", (i ? ftos(i) : ""), "_loopnote", ftos(n), ".wav")
18 .int note; // note
19 .float attenuate; // if set, attenuate it
20 .float cnt; // current volume
21 .float count; // initial volume
22 .float tuba_instrument;
23
24 int Tuba_PitchStep;
25
26 void tubasound(entity e, float restart)
27 {
28         string snd1;
29
30         snd1 = string_null;
31
32         if(Tuba_PitchStep)
33         {
34                 string snd2;
35                 float f1, f2;
36                 float p1, p2;
37                 float m;
38
39                 f1 = 1;
40                 p1 = 1;
41                 snd2 = string_null;
42                 f2 = 0;
43                 p2 = 1;
44
45                 m = e.note % Tuba_PitchStep;
46                 if(m)
47                 {
48                         if(e.note - m < TUBA_MIN)
49                         {
50                                 if(restart)
51                                         snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
52                                 p1 = pow(2.0, (m - Tuba_PitchStep) / 12.0);
53                         }
54                         else if(e.note - m + Tuba_PitchStep > TUBA_MAX)
55                         {
56                                 if(restart)
57                                         snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
58                                 p1 = pow(2.0, m / 12.0);
59                         }
60                         else
61                         {
62                                 if(restart)
63                                         snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
64                                 f1 = cos(M_PI_2 * m / Tuba_PitchStep);
65                                 p1 = pow(2.0, m / 12.0);
66                                 if(restart)
67                                         snd2 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
68                                 f2 = sin(M_PI_2 * m / Tuba_PitchStep);
69                                 p2 = pow(2.0, (m - Tuba_PitchStep) / 12.0);
70                         }
71                 }
72                 else
73                 {
74                         if(restart)
75                                 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
76                 }
77
78                 sound7(e, CH_TUBA_SINGLE, snd1, e.cnt * f1, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p1, 0);
79                 if(f2)
80                         sound7(e.enemy, CH_TUBA_SINGLE, snd2, e.cnt * f2, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p2, 0);
81         }
82         else
83         {
84                 if(restart)
85                         snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
86                 sound(e, CH_TUBA_SINGLE, snd1, e.cnt, e.attenuate * autocvar_g_balance_tuba_attenuation);
87         }
88 }
89
90 void Ent_TubaNote_Think()
91 {
92         float f;
93         f = autocvar_g_balance_tuba_fadetime;
94         if(f > 0)
95                 self.cnt -= frametime * self.count / f;
96         else
97                 self.cnt = 0;
98         self.nextthink = time;
99         if(self.cnt <= 0)
100         {
101                 sound(self, CH_TUBA_SINGLE, "misc/null.wav", 0, 0);
102                 if(self.enemy)
103                 {
104                         sound(self.enemy, CH_TUBA_SINGLE, "misc/null.wav", 0, 0);
105                         remove(self.enemy);
106                 }
107                 remove(self);
108         }
109         else
110         {
111                 tubasound(self, 0);
112         }
113 }
114
115 void Ent_TubaNote_UpdateSound()
116 {
117         self.enemy.cnt = bound(0, VOL_BASE * autocvar_g_balance_tuba_volume, 1);
118         self.enemy.count = self.enemy.cnt;
119         self.enemy.note = self.note;
120         self.enemy.tuba_instrument = self.tuba_instrument;
121         tubasound(self.enemy, 1);
122 }
123
124 void Ent_TubaNote_StopSound()
125 {
126         self.enemy.nextthink = time;
127         self.enemy = world;
128 }
129
130 void Ent_TubaNote(float bIsNew)
131 {
132     int f, n, i;
133         float att, upd;
134         f = ReadByte();
135
136         upd = 0;
137
138         if(f & 1)
139         {
140                 n = ReadChar();
141                 i = ReadByte();
142                 att = (i & 1);
143                 i = floor(i / 2);
144
145                 if(n != self.note || i != self.tuba_instrument || bIsNew)
146                 {
147                         if(self.enemy)
148                                 Ent_TubaNote_StopSound();
149                 }
150
151                 if(!self.enemy)
152                 {
153                         self.enemy = spawn();
154                         self.enemy.classname = "tuba_note";
155                         if(Tuba_PitchStep)
156                         {
157                                 self.enemy.enemy = spawn();
158                                 self.enemy.enemy.classname = "tuba_note_2";
159                         }
160                         bIsNew = true;
161                 }
162
163                 self.enemy.attenuate = att;
164
165                 if(bIsNew)
166                 {
167                         self.note = n;
168                         self.tuba_instrument = i;
169                         upd = 1;
170                 }
171         }
172
173         if(f & 2)
174         {
175                 self.enemy.origin_x = ReadCoord();
176                 self.enemy.origin_y = ReadCoord();
177                 self.enemy.origin_z = ReadCoord();
178                 setorigin(self.enemy, self.enemy.origin);
179                 if(self.enemy.enemy)
180                         setorigin(self.enemy.enemy, self.enemy.origin);
181         }
182
183         self.think = Ent_TubaNote_StopSound;
184         self.entremove = Ent_TubaNote_StopSound;
185         self.enemy.think = Ent_TubaNote_Think;
186         self.enemy.nextthink = time + 10;
187
188         if(upd)
189                 Ent_TubaNote_UpdateSound();
190 }
191
192 void Tuba_Precache()
193 {
194         float i;
195     int n;
196         Tuba_PitchStep = autocvar_g_balance_tuba_pitchstep;
197         if(Tuba_PitchStep)
198         {
199                 if(!checkextension("DP_SND_SOUND7_WIP2") && !checkextension("DP_SND_SOUND7"))
200                 {
201                         print("^1NOTE:^7 requested pitch shifting, but not supported by this engine build\n");
202                         Tuba_PitchStep = 0;
203                 }
204         }
205         for(n = TUBA_MIN; n <= TUBA_MAX; ++n)
206         {
207                 if(!Tuba_PitchStep || ((n % Tuba_PitchStep) == 0))
208                 {
209                         for(i = 0; i < TUBA_INSTRUMENTS; ++i)
210                                 precache_sound(TUBA_STARTNOTE(i, n));
211                 }
212         }
213 }