]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/tuba.qc
cd518e091d3c2ecdd3677aaf7c2ca50a5f6217aa
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / tuba.qc
1 #include "tuba.qh"
2
3 #define TUBA_STARTNOTE(i, n) strcat("weapons/tuba", (i ? ftos(i) : ""), "_loopnote", ftos(n), ".wav")
4
5 const int TUBA_MIN = -18;
6 const int TUBA_MAX = 27;
7 const int TUBA_INSTRUMENTS = 3;
8
9 .int note;
10 .bool tuba_attenuate;
11 .float tuba_volume;
12 .float tuba_volume_initial;
13 .int tuba_instrument;
14
15 int Tuba_PitchStep;
16
17 void tubasound(entity e, bool restart)
18 {
19         string snd1 = string_null;
20         if (Tuba_PitchStep) {
21                 float vol1 = 1;
22                 float speed1 = 1;
23                 string snd2 = string_null;
24                 float vol2 = 0;
25                 float speed2 = 1;
26
27                 int m = pymod(e.note, Tuba_PitchStep);
28                 if (m) {
29                         if (e.note - m < TUBA_MIN) {
30                                 if (restart) {
31                                         snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
32                                 }
33                                 speed1 = pow(2.0, (m - Tuba_PitchStep) / 12.0);
34                         } else if (e.note - m + Tuba_PitchStep > TUBA_MAX) {
35                                 if (restart) {
36                                         snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
37                                 }
38                                 speed1 = pow(2.0, m / 12.0);
39                         } else {
40                                 if (restart) {
41                                         snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
42                                 }
43                                 vol1 = cos(M_PI_2 * m / Tuba_PitchStep);
44                                 speed1 = pow(2.0, m / 12.0);
45                                 if (restart) {
46                                         snd2 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
47                                 }
48                                 vol2 = sin(M_PI_2 * m / Tuba_PitchStep);
49                                 speed2 = pow(2.0, (m - Tuba_PitchStep) / 12.0);
50                         }
51                 } else if (restart) {
52                         snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
53                 }
54
55                 sound7(e, CH_TUBA_SINGLE, snd1, e.tuba_volume * vol1, e.tuba_attenuate * autocvar_g_balance_tuba_attenuation, 100 * speed1, 0);
56                 if (vol2) {
57                         sound7(e.enemy, CH_TUBA_SINGLE, snd2, e.tuba_volume * vol2, e.tuba_attenuate * autocvar_g_balance_tuba_attenuation, 100 * speed2, 0);
58                 }
59         } else {
60                 if (restart) {
61                         snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
62                 }
63                 sound(e, CH_TUBA_SINGLE, snd1, e.tuba_volume, e.tuba_attenuate * autocvar_g_balance_tuba_attenuation);
64         }
65 }
66
67 void Ent_TubaNote_Think()
68 {
69         float f = autocvar_g_balance_tuba_fadetime;
70         if (f > 0) {
71                 self.tuba_volume -= frametime * self.tuba_volume_initial / f;
72         } else {
73                 self.tuba_volume = 0;
74         }
75         self.nextthink = time;
76         if (self.tuba_volume <= 0) {
77                 sound(self, CH_TUBA_SINGLE, "misc/null.wav", 0, 0);
78                 if (self.enemy) {
79                         sound(self.enemy, CH_TUBA_SINGLE, "misc/null.wav", 0, 0);
80                         remove(self.enemy);
81                 }
82                 remove(self);
83         } else {
84                 tubasound(self, 0);
85         }
86 }
87
88 void Ent_TubaNote_UpdateSound()
89 {
90         self.enemy.tuba_volume = bound(0, VOL_BASE * autocvar_g_balance_tuba_volume, 1);
91         self.enemy.tuba_volume_initial = self.enemy.tuba_volume;
92         self.enemy.note = self.note;
93         self.enemy.tuba_instrument = self.tuba_instrument;
94         tubasound(self.enemy, 1);
95 }
96
97 void Ent_TubaNote_StopSound()
98 {
99         self.enemy.nextthink = time;
100         self.enemy = world;
101 }
102
103 void Ent_TubaNote(bool isNew)
104 {
105         bool upd = false;
106         int f = ReadByte();
107         if (f & 1) {
108                 int n = ReadChar();
109                 int i = ReadByte();
110                 bool att = (i & 1);
111                 i >>= 1;
112
113                 if (self.enemy) {
114                         if (n != self.note || i != self.tuba_instrument || isNew) {
115                                 Ent_TubaNote_StopSound();
116                         }
117                 } else {
118                         self.enemy = spawn();
119                         self.enemy.classname = "tuba_note";
120                         if (Tuba_PitchStep) {
121                                 self.enemy.enemy = spawn();
122                                 self.enemy.enemy.classname = "tuba_note_2";
123                         }
124                         isNew = true;
125                 }
126
127                 self.enemy.tuba_attenuate = att;
128
129                 if (isNew) {
130                         self.note = n;
131                         self.tuba_instrument = i;
132                         upd = true;
133                 }
134         }
135
136         if (f & 2) {
137                 self.enemy.origin_x = ReadCoord();
138                 self.enemy.origin_y = ReadCoord();
139                 self.enemy.origin_z = ReadCoord();
140                 setorigin(self.enemy, self.enemy.origin);
141                 if (self.enemy.enemy) {
142                         setorigin(self.enemy.enemy, self.enemy.origin);
143                 }
144         }
145
146         self.think = Ent_TubaNote_StopSound;
147         self.entremove = Ent_TubaNote_StopSound;
148         self.enemy.think = Ent_TubaNote_Think;
149         self.enemy.nextthink = time + 10;
150
151         if (upd) {
152                 Ent_TubaNote_UpdateSound();
153         }
154 }
155
156 void Tuba_Precache()
157 {
158         Tuba_PitchStep = autocvar_g_balance_tuba_pitchstep;
159         if (Tuba_PitchStep) {
160                 if (!checkextension("DP_SND_SOUND7_WIP2") && !checkextension("DP_SND_SOUND7")) {
161                         print("^1NOTE:^7 requested pitch shifting, but not supported by this engine build\n");
162                         Tuba_PitchStep = 0;
163                 }
164         }
165         for (int n = TUBA_MIN; n <= TUBA_MAX; ++n) {
166                 if (!Tuba_PitchStep || pymod(n, Tuba_PitchStep) == 0) {
167                         for (int i = 0; i < TUBA_INSTRUMENTS; ++i) {
168                                 precache_sound(TUBA_STARTNOTE(i, n));
169                         }
170                 }
171         }
172 }