]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/triggers/target/music.qc
Merge branch 'terencehill/slider_drag_fix' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / target / music.qc
1 #if defined(CSQC)
2 #elif defined(MENUQC)
3 #elif defined(SVQC)
4     #include "../../constants.qh"
5     #include "../../../server/constants.qh"
6     #include "../../../server/defs.qh"
7 #endif
8
9 #ifdef SVQC
10
11 // values:
12 //   volume
13 //   noise
14 //   targetname
15 //   lifetime
16 //   fade_time
17 //   fade_rate
18 // when triggered, the music is overridden for activator until lifetime (or forever, if lifetime is 0)
19 // when targetname is not set, THIS ONE is default
20 void target_music_sendto(float to, float is)
21 {SELFPARAM();
22         WriteByte(to, SVC_TEMPENTITY);
23         WriteByte(to, TE_CSQC_TARGET_MUSIC);
24         WriteShort(to, num_for_edict(self));
25         WriteByte(to, self.volume * 255.0 * is);
26         WriteByte(to, self.fade_time * 16.0);
27         WriteByte(to, self.fade_rate * 16.0);
28         WriteByte(to, self.lifetime);
29         WriteString(to, self.noise);
30 }
31 void target_music_reset()
32 {SELFPARAM();
33         if(self.targetname == "")
34                 target_music_sendto(MSG_ALL, 1);
35 }
36 void target_music_kill()
37 {
38         for(self = world; (self = find(self, classname, "target_music")); )
39         {
40                 self.volume = 0;
41                 if(self.targetname == "")
42                         target_music_sendto(MSG_ALL, 1);
43                 else
44                         target_music_sendto(MSG_ALL, 0);
45         }
46 }
47 void target_music_use()
48 {
49         if(!activator)
50                 return;
51         if(IS_REAL_CLIENT(activator))
52         {
53                 msg_entity = activator;
54                 target_music_sendto(MSG_ONE, 1);
55         }
56         entity head;
57         FOR_EACH_SPEC(head) if(head.enemy == activator) { msg_entity = head; target_music_sendto(MSG_ONE, 1); }
58 }
59 spawnfunc(target_music)
60 {
61         self.use = target_music_use;
62         self.reset = target_music_reset;
63         if(!self.volume)
64                 self.volume = 1;
65         if(self.targetname == "")
66                 target_music_sendto(MSG_INIT, 1);
67         else
68                 target_music_sendto(MSG_INIT, 0);
69 }
70 void TargetMusic_RestoreGame()
71 {SELFPARAM();
72         for(entity e = world; (e = find(e, classname, "target_music")); )
73         {
74                 setself(e);
75                 if(self.targetname == "")
76                         target_music_sendto(MSG_INIT, 1);
77                 else
78                         target_music_sendto(MSG_INIT, 0);
79         }
80 }
81 // values:
82 //   volume
83 //   noise
84 //   targetname
85 //   fade_time
86 // spawnflags:
87 //   1 = START_OFF
88 // when triggered, it is disabled/enabled for everyone
89 bool trigger_music_SendEntity(entity this, entity to, float sf)
90 {
91         WriteByte(MSG_ENTITY, ENT_CLIENT_TRIGGER_MUSIC);
92         sf &= ~0x80;
93         if(self.cnt)
94                 sf |= 0x80;
95         WriteByte(MSG_ENTITY, sf);
96         if(sf & 4)
97         {
98                 WriteCoord(MSG_ENTITY, self.origin.x);
99                 WriteCoord(MSG_ENTITY, self.origin.y);
100                 WriteCoord(MSG_ENTITY, self.origin.z);
101         }
102         if(sf & 1)
103         {
104                 if(self.model != "null")
105                 {
106                         WriteShort(MSG_ENTITY, self.modelindex);
107                         WriteCoord(MSG_ENTITY, self.mins.x);
108                         WriteCoord(MSG_ENTITY, self.mins.y);
109                         WriteCoord(MSG_ENTITY, self.mins.z);
110                         WriteCoord(MSG_ENTITY, self.maxs.x);
111                         WriteCoord(MSG_ENTITY, self.maxs.y);
112                         WriteCoord(MSG_ENTITY, self.maxs.z);
113                 }
114                 else
115                 {
116                         WriteShort(MSG_ENTITY, 0);
117                         WriteCoord(MSG_ENTITY, self.maxs.x);
118                         WriteCoord(MSG_ENTITY, self.maxs.y);
119                         WriteCoord(MSG_ENTITY, self.maxs.z);
120                 }
121                 WriteByte(MSG_ENTITY, self.volume * 255.0);
122                 WriteByte(MSG_ENTITY, self.fade_time * 16.0);
123                 WriteByte(MSG_ENTITY, self.fade_rate * 16.0);
124                 WriteString(MSG_ENTITY, self.noise);
125         }
126         return 1;
127 }
128 void trigger_music_reset()
129 {SELFPARAM();
130         self.cnt = !(self.spawnflags & 1);
131         self.SendFlags |= 0x80;
132 }
133 void trigger_music_use()
134 {SELFPARAM();
135         self.cnt = !self.cnt;
136         self.SendFlags |= 0x80;
137 }
138 spawnfunc(trigger_music)
139 {
140         if(self.model != "")
141                 _setmodel(self, self.model);
142         if(!self.volume)
143                 self.volume = 1;
144         if(!self.modelindex)
145         {
146                 setorigin(self, self.origin + self.mins);
147                 setsize(self, '0 0 0', self.maxs - self.mins);
148         }
149         trigger_music_reset();
150
151         self.use = trigger_music_use;
152         self.reset = trigger_music_reset;
153
154         Net_LinkEntity(self, false, 0, trigger_music_SendEntity);
155 }
156 #elif defined(CSQC)
157
158 void TargetMusic_Advance()
159 {
160         // run AFTER all the thinks!
161         entity best, e;
162         float vol, vol0;
163         best = music_default;
164         if(music_target && time < music_target.lifetime)
165                 best = music_target;
166         if(music_trigger)
167                 best = music_trigger;
168         for(e = world; (e = findfloat(e, enttype, ENT_CLIENT_TRIGGER_MUSIC)); ) if(e.noise)
169         {
170                 vol0 = e.lastvol;
171                 if(getsoundtime(e, CH_BGM_SINGLE) < 0)
172                 {
173                         vol0 = -1;
174                 }
175                 if(e == best)
176                 {
177                         // increase volume
178                         if(e.fade_time > 0)
179                                 e.state = bound(0, e.state + frametime / e.fade_time, 1);
180                         else
181                                 e.state = 1;
182                 }
183                 else
184                 {
185                         // decrease volume
186                         if(e.fade_rate > 0)
187                                 e.state = bound(0, e.state - frametime / e.fade_rate, 1);
188                         else
189                                 e.state = 0;
190                 }
191                 vol = e.state * e.volume * autocvar_bgmvolume;
192                 if(vol != vol0)
193                 {
194                         if(vol0 < 0)
195                                 _sound(e, CH_BGM_SINGLE, e.noise, vol, ATTEN_NONE); // restart
196                         else
197                                 _sound(e, CH_BGM_SINGLE, "", vol, ATTEN_NONE);
198                         e.lastvol = vol;
199                 }
200         }
201         music_trigger = world;
202
203         if(best)
204                 bgmtime = getsoundtime(best, CH_BGM_SINGLE);
205         else
206                 bgmtime = gettime(GETTIME_CDTRACK);
207 }
208
209 void Net_TargetMusic()
210 {
211         int id = ReadShort();
212         float vol = ReadByte() / 255.0;
213         float fai = ReadByte() / 16.0;
214         float fao = ReadByte() / 16.0;
215         float tim = ReadByte();
216         string noi = ReadString();
217
218         entity e;
219         for(e = world; (e = findfloat(e, enttype, ENT_CLIENT_TRIGGER_MUSIC)); )
220         {
221                 if(e.count == id)
222                         break;
223         }
224         if(!e)
225         {
226                 e = spawn();
227                 e.enttype = ENT_CLIENT_TRIGGER_MUSIC;
228                 e.count = id;
229         }
230         if(e.noise != noi)
231         {
232                 if(e.noise)
233                         strunzone(e.noise);
234                 e.noise = strzone(noi);
235                 precache_sound(e.noise);
236                 _sound(e, CH_BGM_SINGLE, e.noise, 0, ATTEN_NONE);
237                 if(getsoundtime(e, CH_BGM_SINGLE) < 0)
238                 {
239                         LOG_TRACEF("Cannot initialize sound %s\n", e.noise);
240                         strunzone(e.noise);
241                         e.noise = string_null;
242                 }
243         }
244         e.volume = vol;
245         e.fade_time = fai;
246         e.fade_rate = fao;
247         if(vol > 0)
248         {
249                 if(tim == 0)
250                 {
251                         music_default = e;
252                         if(!music_disabled)
253                         {
254                                 e.state = 2;
255                                 cvar_settemp("music_playlist_index", "-1"); // don't use playlists
256                                 localcmd("cd stop\n"); // just in case
257                                 music_disabled = 1;
258                         }
259                 }
260                 else
261                 {
262                         music_target = e;
263                         e.lifetime = time + tim;
264                 }
265         }
266 }
267
268 void Ent_TriggerMusic_Think()
269 {SELFPARAM();
270         if(WarpZoneLib_BoxTouchesBrush(view_origin, view_origin, self, world))
271         {
272                 music_trigger = self;
273         }
274         self.nextthink = time;
275 }
276
277 void Ent_TriggerMusic_Remove()
278 {SELFPARAM();
279         if(self.noise)
280                 strunzone(self.noise);
281         self.noise = string_null;
282 }
283
284 void Ent_ReadTriggerMusic()
285 {SELFPARAM();
286         int f = ReadByte();
287         if(f & 4)
288         {
289                 self.origin_x = ReadCoord();
290                 self.origin_y = ReadCoord();
291                 self.origin_z = ReadCoord();
292         }
293         if(f & 1)
294         {
295                 self.modelindex = ReadShort();
296                 if(self.modelindex)
297                 {
298                         self.mins_x = ReadCoord();
299                         self.mins_y = ReadCoord();
300                         self.mins_z = ReadCoord();
301                         self.maxs_x = ReadCoord();
302                         self.maxs_y = ReadCoord();
303                         self.maxs_z = ReadCoord();
304                 }
305                 else
306                 {
307                         self.mins    = '0 0 0';
308                         self.maxs_x = ReadCoord();
309                         self.maxs_y = ReadCoord();
310                         self.maxs_z = ReadCoord();
311                 }
312
313                 self.volume = ReadByte() / 255.0;
314                 self.fade_time = ReadByte() / 16.0;
315                 self.fade_rate = ReadByte() / 16.0;
316                 string s = self.noise;
317                 if(self.noise)
318                         strunzone(self.noise);
319                 self.noise = strzone(ReadString());
320                 if(self.noise != s)
321                 {
322                         precache_sound(self.noise);
323                         _sound(self, CH_BGM_SINGLE, self.noise, 0, ATTEN_NONE);
324                         if(getsoundtime(self, CH_BGM_SINGLE) < 0)
325                         {
326                                 LOG_TRACEF("Cannot initialize sound %s\n", self.noise);
327                                 strunzone(self.noise);
328                                 self.noise = string_null;
329                         }
330                 }
331         }
332
333         setorigin(self, self.origin);
334         setsize(self, self.mins, self.maxs);
335         self.cnt = 1;
336         self.think = Ent_TriggerMusic_Think;
337         self.nextthink = time;
338 }
339
340 #endif