Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
tuba.qc
Go to the documentation of this file.
1#include "tuba.qh"
2
3#ifdef SVQC
4
5.entity tuba_note;
7
8#define MAX_TUBANOTES 32
10.float tuba_lastnotes_cnt; // over
12
13bool W_Tuba_HasPlayed(entity pl, .entity weaponentity, string melody, int instrument, bool ignorepitch, float mintempo, float maxtempo)
14{
15 float i, j, mmin, mmax, nolength;
16 float n = tokenize_console(melody);
17 if(n > pl.(weaponentity).tuba_lastnotes_cnt)
18 return false;
19 float pitchshift = 0;
20
21 if(instrument >= 0)
22 if(pl.(weaponentity).tuba_instrument != instrument)
23 return false;
24
25 // verify notes...
26 nolength = false;
27 for(i = 0; i < n; ++i)
28 {
29 vector v = pl.(weaponentity).(tuba_lastnotes[(pl.(weaponentity).tuba_lastnotes_last - i + MAX_TUBANOTES) % MAX_TUBANOTES]);
30 float ai = stof(argv(n - i - 1));
31 float np = floor(ai);
32 if(ai == np)
33 nolength = true;
34 // n counts the last played notes BACKWARDS
35 // _x is start
36 // _y is end
37 // _z is note pitch
38 if(ignorepitch && i == 0)
39 {
40 pitchshift = np - v.z;
41 }
42 else
43 {
44 if(v.z + pitchshift != np)
45 return false;
46 }
47 }
48
49 // now we know the right NOTES were played
50 if(!nolength)
51 {
52 // verify rhythm...
53 float ti = 0;
54 if(maxtempo > 0)
55 mmin = 240 / maxtempo; // 60 = "0.25 means 1 sec", at 120 0.5 means 1 sec, at 240 1 means 1 sec
56 else
57 mmin = 0;
58 if(mintempo > 0)
59 mmax = 240 / mintempo; // 60 = "0.25 means 1 sec", at 120 0.5 means 1 sec, at 240 1 means 1 sec
60 else
61 mmax = 240; // you won't try THAT hard... (tempo 1)
62 //printf("initial tempo rules: %f %f\n", mmin, mmax);
63
64 for(i = 0; i < n; ++i)
65 {
66 vector vi = pl.(weaponentity).(tuba_lastnotes[(pl.(weaponentity).tuba_lastnotes_last - i + MAX_TUBANOTES) % MAX_TUBANOTES]);
67 float ai = stof(argv(n - i - 1));
68 ti -= 1 / (ai - floor(ai));
69 float tj = ti;
70 for(j = i+1; j < n; ++j)
71 {
72 vector vj = pl.(weaponentity).(tuba_lastnotes[(pl.(weaponentity).tuba_lastnotes_last - j + MAX_TUBANOTES) % MAX_TUBANOTES]);
73 float aj = stof(argv(n - j - 1));
74 tj -= (aj - floor(aj));
75
76 // note i should be at m*ti+b
77 // note j should be at m*tj+b
78 // so:
79 // we have a LINE l, so that
80 // vi_x <= l(ti) <= vi_y
81 // vj_x <= l(tj) <= vj_y
82 // what is m?
83
84 // vi_x <= vi_y <= vj_x <= vj_y
85 // ti <= tj
86 //printf("first note: %f to %f, should be %f\n", vi_x, vi_y, ti);
87 //printf("second note: %f to %f, should be %f\n", vj_x, vj_y, tj);
88 //printf("m1 = %f\n", (vi_x - vj_y) / (ti - tj));
89 //printf("m2 = %f\n", (vi_y - vj_x) / (ti - tj));
90 mmin = max(mmin, (vi.x - vj.y) / (ti - tj)); // lower bound
91 mmax = min(mmax, (vi.y - vj.x) / (ti - tj)); // upper bound
92 }
93 }
94
95 if(mmin > mmax) // rhythm fail
96 return false;
97 }
98
99 pl.(weaponentity).tuba_lastnotes_cnt = 0;
100
101 return true;
102}
103
105{
106 entity actor = this.owner;
107 // we have a note:
108 // on: this.spawnshieldtime
109 // off: time
110 // note: this.cnt
111 .entity weaponentity = this.weaponentity_fld;
112 if (actor.(weaponentity).tuba_note == this)
113 {
114 actor.(weaponentity).tuba_lastnotes_last = (actor.(weaponentity).tuba_lastnotes_last + 1) % MAX_TUBANOTES;
115 actor.(weaponentity).(tuba_lastnotes[actor.(weaponentity).tuba_lastnotes_last]) = vec3(this.spawnshieldtime, time, this.cnt);
116 actor.(weaponentity).tuba_note = NULL;
117 actor.(weaponentity).tuba_lastnotes_cnt = bound(0, actor.(weaponentity).tuba_lastnotes_cnt + 1, MAX_TUBANOTES);
118
120 if (s != "")
121 {
122 // simulate a server message
123 switch (this.tuba_instrument)
124 {
125 default:
126 case 0: // Tuba
127 bprint(strcat("\{1}\{13}* ^3", actor.netname, "^3 played on the @!#%'n Tuba: ^7", s, "\n"));
128 break;
129 case 1:
130 bprint(strcat("\{1}\{13}* ^3", actor.netname, "^3 played on the @!#%'n Accordeon: ^7", s, "\n"));
131 break;
132 case 2:
133 bprint(strcat("\{1}\{13}* ^3", actor.netname, "^3 played on the @!#%'n Klein Bottle: ^7", s, "\n"));
134 break;
135 }
136 }
137 }
138 delete(this);
139}
140
141int W_Tuba_GetNote(entity pl, int hittype)
142{
143 float movestate = 5;
144 if (CS(pl).movement.x < 0) movestate -= 3;
145 else if (CS(pl).movement.x > 0) movestate += 3;
146 if (CS(pl).movement.y < 0) movestate -= 1;
147 else if (CS(pl).movement.y > 0) movestate += 1;
148
149 int note = 0;
150 switch (movestate)
151 {
152 // layout: originally I wanted
153 // eb e e#=f
154 // B c d
155 // Gb G G#
156 // but then you only use forward and right key. So to make things more
157 // interesting, I swapped B with e#. Har har har...
158 // eb e B
159 // f=e# c d
160 // Gb G G#
161 case 1: note = -6; break; // Gb
162 case 2: note = -5; break; // G
163 case 3: note = -4; break; // G#
164 case 4: note = +5; break; // e#
165 default:
166 case 5: note = 0; break; // c
167 case 6: note = +2; break; // d
168 case 7: note = +3; break; // eb
169 case 8: note = +4; break; // e
170 case 9: note = -1; break; // B
171 }
173 note -= 12;
175 note += 12;
176 if(hittype & HITTYPE_SECONDARY)
177 note += 7;
178
179 // we support two kinds of tubas, those tuned in Eb and those tuned in C
180 // kind of tuba currently is player slot number, or team number if in
181 // teamplay
182 // that way, holes in the range of notes are "plugged"
183 if(teamplay)
184 {
185 if(pl.team == NUM_TEAM_2 || pl.team == NUM_TEAM_4)
186 note += 3;
187 }
188 else
189 {
190 if(pl.clientcolors & 1)
191 note += 3;
192 }
193
194 // total range of notes:
195 // 0
196 // *** ** ****
197 // *** ** ****
198 // *** ** ****
199 // *** ** ****
200 // *** ********************* ****
201 // -18.........................+12
202 // *** ********************* ****
203 // -18............................+15
204 // with jump: ... +24
205 // ... +27
206 return note;
207}
208
209bool W_Tuba_NoteSendEntity(entity this, entity to, int sf)
210{
211 msg_entity = to;
212 if (!sound_allowed(MSG_ONE, this.realowner)) return false;
213
214 WriteHeader(MSG_ENTITY, ENT_CLIENT_TUBANOTE);
216 if (sf & 1)
217 {
218 WriteChar(MSG_ENTITY, this.cnt);
219 int f = 0;
220 f |= 1 * (this.realowner != to);
221 f |= 2 * this.tuba_instrument;
223 }
224 if (sf & 2)
225 {
226 WriteVector(MSG_ENTITY, this.origin);
227 }
228 return true;
229}
230
232{
233 float dist_mult;
234 float vol0, vol1;
235 vector dir0, dir1;
236 vector v;
237 if(time > this.teleport_time)
238 {
239 W_Tuba_NoteOff(this);
240 return;
241 }
242 this.nextthink = time;
243 dist_mult = WEP_CVAR(WEP_TUBA, attenuation) / autocvar_snd_soundradius;
244 FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != this.realowner, {
245 v = this.origin - (it.origin + it.view_ofs);
246 vol0 = max(0, 1 - vlen(v) * dist_mult);
247 dir0 = normalize(v);
248 v = this.realowner.origin - (it.origin + it.view_ofs);
249 vol1 = max(0, 1 - vlen(v) * dist_mult);
250 dir1 = normalize(v);
251 if(fabs(vol0 - vol1) > 0.005) // 0.5 percent change in volume
252 {
253 setorigin(this, this.realowner.origin);
254 this.SendFlags |= 2;
255 break;
256 }
257 if(dir0 * dir1 < 0.9994) // 2 degrees change in angle
258 {
259 setorigin(this, this.realowner.origin);
260 this.SendFlags |= 2;
261 break;
262 }
263 });
264}
265
266void W_Tuba_NoteOn(entity actor, .entity weaponentity, float hittype)
267{
268 float n = W_Tuba_GetNote(actor, hittype);
269
270 hittype = HITTYPE_SOUND;
271 if(actor.(weaponentity).tuba_instrument & 1)
272 hittype |= HITTYPE_SECONDARY;
273 if(actor.(weaponentity).tuba_instrument & 2)
274 hittype |= HITTYPE_BOUNCE;
275
276 W_SetupShot(actor, weaponentity, false, 2, SND_Null, 0, WEP_CVAR(WEP_TUBA, damage), hittype | WEP_TUBA.m_id);
277
278 if(actor.(weaponentity).tuba_note)
279 {
280 if(actor.(weaponentity).tuba_note.cnt != n || actor.(weaponentity).tuba_note.tuba_instrument != actor.(weaponentity).tuba_instrument)
281 {
282 W_Tuba_NoteOff(actor.(weaponentity).tuba_note);
283 }
284 }
285
286 if(!actor.(weaponentity).tuba_note)
287 {
288 entity note = new(tuba_note);
289 note.weaponentity_fld = weaponentity;
290 actor.(weaponentity).tuba_note = note;
291 note.owner = note.realowner = actor;
292 note.cnt = n;
293 note.tuba_instrument = actor.(weaponentity).tuba_instrument;
295 note.nextthink = time;
296 note.spawnshieldtime = time;
297 Net_LinkEntity(note, false, 0, W_Tuba_NoteSendEntity);
298 }
299
300 actor.(weaponentity).tuba_note.teleport_time = time + WEP_CVAR(WEP_TUBA, refire) * 2 * W_WeaponRateFactor(actor); // so it can get prolonged safely
301
302 //sound(actor, c, TUBA_NOTE(n), bound(0, VOL_BASE * autocvar_cl_tuba_volume, 1), autocvar_cl_tuba_attenuation);
303 RadiusDamage(actor, actor, WEP_CVAR(WEP_TUBA, damage), WEP_CVAR(WEP_TUBA, edgedamage), WEP_CVAR(WEP_TUBA, radius), NULL, NULL, WEP_CVAR(WEP_TUBA, force), hittype | WEP_TUBA.m_id, weaponentity, NULL);
304
305 if(time > actor.(weaponentity).tuba_smoketime)
306 {
307 // FIXME gettaginfo(actor.(weaponentity), 0) doesn't return the real origin of the weapon
308 vector org = gettaginfo(actor.(weaponentity), 0);
309 if(actor.(weaponentity).tuba_instrument == 1)
310 Send_Effect(EFFECT_SMOKE_RING, org + v_up * 25 + v_right * 10 + v_forward * 14, v_up * 100, 1);
311 else if(actor.(weaponentity).tuba_instrument == 2)
312 Send_Effect(EFFECT_SMOKE_RING, org + v_up * 50 + v_right * 10 + v_forward * 45, v_up * 100, 1);
313 else
314 Send_Effect(EFFECT_SMOKE_RING, org + v_up * 40 + v_right * 10 + v_forward * 14, v_up * 100, 1);
315 actor.(weaponentity).tuba_smoketime = time + 0.25;
316 }
317}
318#endif
319
320#ifdef SVQC
321METHOD(Tuba, wr_aim, void(Tuba this, entity actor, .entity weaponentity))
322{
323 // bots cannot play the Tuba well yet
324 // I think they should start with the recorder first
325 if (vdist((actor.origin - actor.enemy.origin), <, WEP_CVAR(WEP_TUBA, radius)))
326 {
327 if (random() > 0.5)
328 PHYS_INPUT_BUTTON_ATCK(actor) = true;
329 else
330 PHYS_INPUT_BUTTON_ATCK2(actor) = true;
331 }
332}
333
334METHOD(Tuba, wr_think, void(Tuba this, entity actor, .entity weaponentity, int fire))
335{
336 if (fire & 1)
337 if (weapon_prepareattack(this, actor, weaponentity, false, WEP_CVAR(WEP_TUBA, refire)))
338 {
339 W_Tuba_NoteOn(actor, weaponentity, 0);
340 weapon_thinkf(actor, weaponentity, WFRAME_IDLE, WEP_CVAR(WEP_TUBA, animtime), w_ready);
341 }
342 if (fire & 2)
343 if (weapon_prepareattack(this, actor, weaponentity, true, WEP_CVAR(WEP_TUBA, refire)))
344 {
345 W_Tuba_NoteOn(actor, weaponentity, HITTYPE_SECONDARY);
346 weapon_thinkf(actor, weaponentity, WFRAME_IDLE, WEP_CVAR(WEP_TUBA, animtime), w_ready);
347 }
348 if (actor.(weaponentity).tuba_note)
349 {
350 if (!(fire & (1 | 2)))
351 {
352 W_Tuba_NoteOff(actor.(weaponentity).tuba_note);
353 }
354 }
355}
356
357METHOD(Tuba, wr_setup, void(Tuba this, entity actor, .entity weaponentity))
358{
359 actor.(weaponentity).tuba_instrument = 0;
360}
361
362METHOD(Tuba, wr_reload, void(Tuba this, entity actor, .entity weaponentity))
363{
364 // switch to alternate instruments :)
365 if (actor.(weaponentity).state == WS_READY)
366 {
367 switch (actor.(weaponentity).tuba_instrument)
368 {
369 case 0:
370 actor.(weaponentity).tuba_instrument = 1;
371 actor.(weaponentity).weaponname = "akordeon";
372 break;
373 case 1:
374 actor.(weaponentity).tuba_instrument = 2;
375 actor.(weaponentity).weaponname = "kleinbottle";
376 break;
377 case 2:
378 actor.(weaponentity).tuba_instrument = 0;
379 actor.(weaponentity).weaponname = "tuba";
380 break;
381 }
382 int hittype = 0;
383 if(actor.(weaponentity).tuba_instrument & 1)
384 hittype |= HITTYPE_SECONDARY;
385 if(actor.(weaponentity).tuba_instrument & 2)
386 hittype |= HITTYPE_BOUNCE;
387 W_SetupShot(actor, weaponentity, false, 0, SND_Null, 0, 0, hittype | WEP_TUBA.m_id);
388 Send_Effect(EFFECT_TELEPORT, w_shotorg, '0 0 0', 1);
389 actor.(weaponentity).state = WS_INUSE;
390 weapon_thinkf(actor, weaponentity, WFRAME_RELOAD, 0.5, w_ready);
391 }
392}
393#endif
394
395#ifdef SVQC
396
397// infinite ammo
398METHOD(Tuba, wr_checkammo1, bool(Tuba this, entity actor, .entity weaponentity)) { return true; }
399METHOD(Tuba, wr_checkammo2, bool(Tuba this, entity actor, .entity weaponentity)) { return true; }
400
401METHOD(Tuba, wr_suicidemessage, Notification(Tuba this))
402{
404 return WEAPON_KLEINBOTTLE_SUICIDE;
406 return WEAPON_ACCORDEON_SUICIDE;
407 else
408 return WEAPON_TUBA_SUICIDE;
409}
410METHOD(Tuba, wr_killmessage, Notification(Tuba this))
411{
413 return WEAPON_KLEINBOTTLE_MURDER;
415 return WEAPON_ACCORDEON_MURDER;
416 else
417 return WEAPON_TUBA_MURDER;
418}
419
420#elif defined(CSQC)
421
422METHOD(Tuba, wr_viewmodel, string(Tuba this, entity wep))
423{
424 return (wep.tuba_instrument == 0) ? "tuba" :
425 (wep.tuba_instrument == 1) ? "akordeon" :
426 "kleinbottle";
427}
428
429#endif
430
431#ifdef CSQC
432
433#define TUBA_STARTNOTE(i, n) _Sound_fixpath(W_Sound(strcat("tuba", (i ? ftos(i) : ""), "_loopnote", ftos(n))))
434
435const int TUBA_MIN = -18;
436const int TUBA_MAX = 27;
437const int TUBA_INSTRUMENTS = 3;
438
440
441void tubasound(entity e, bool restart)
442{
443 string snd1 = string_null;
444 if (Tuba_PitchStep) {
445 float vol1 = 1;
446 float speed1 = 1;
447 string snd2 = string_null;
448 float vol2 = 0;
449 float speed2 = 1;
450
451 int m = pymod(e.note, Tuba_PitchStep);
452 if (m) {
453 if (e.note - m < TUBA_MIN) {
454 if (restart) {
455 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
456 }
457 speed1 = (2.0 ** ((m - Tuba_PitchStep) / 12.0));
458 } else if (e.note - m + Tuba_PitchStep > TUBA_MAX) {
459 if (restart) {
460 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
461 }
462 speed1 = (2.0 ** (m / 12.0));
463 } else {
464 if (restart) {
465 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
466 }
467 vol1 = cos(M_PI_2 * m / Tuba_PitchStep);
468 speed1 = (2.0 ** (m / 12.0));
469 if (restart) {
470 snd2 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
471 }
472 vol2 = sin(M_PI_2 * m / Tuba_PitchStep);
473 speed2 = (2.0 ** ((m - Tuba_PitchStep) / 12.0));
474 }
475 } else if (restart) {
476 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
477 }
478
479 sound7(e, CH_TUBA_SINGLE, snd1, e.tuba_volume * vol1, e.tuba_attenuate * autocvar_cl_tuba_attenuation, 100 * speed1, 0);
480 if (vol2) {
481 sound7(e.enemy, CH_TUBA_SINGLE, snd2, e.tuba_volume * vol2, e.tuba_attenuate * autocvar_cl_tuba_attenuation, 100 * speed2, 0);
482 }
483 } else {
484 if (restart) {
485 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
486 }
487 _sound(e, CH_TUBA_SINGLE, snd1, e.tuba_volume, e.tuba_attenuate * autocvar_cl_tuba_attenuation);
488 }
489}
490
492{
494 if (f > 0) {
495 this.tuba_volume -= frametime * this.tuba_volume_initial / f;
496 } else {
497 this.tuba_volume = 0;
498 }
499 this.nextthink = time;
500 if (this.tuba_volume <= 0) {
501 sound(this, CH_TUBA_SINGLE, SND_Null, 0, 0);
502 if (this.enemy) {
503 sound(this.enemy, CH_TUBA_SINGLE, SND_Null, 0, 0);
504 delete(this.enemy);
505 }
506 delete(this);
507 } else {
508 tubasound(this, 0);
509 }
510}
511
513{
514 this.enemy.tuba_volume = bound(0, VOL_BASE * autocvar_cl_tuba_volume, 1);
515 this.enemy.tuba_volume_initial = this.enemy.tuba_volume;
516 this.enemy.note = this.note;
517 this.enemy.tuba_instrument = this.tuba_instrument;
518 tubasound(this.enemy, 1);
519}
520
522{
523 this.enemy.nextthink = time;
524 this.enemy = NULL;
525}
526
527NET_HANDLE(ENT_CLIENT_TUBANOTE, bool isNew)
528{
529 bool upd = false;
530 int f = ReadByte();
531 if (f & 1) {
532 int n = ReadChar();
533 int i = ReadByte();
534 bool att = (i & 1);
535 i >>= 1;
536
537 if (this.enemy) {
538 if (n != this.note || i != this.tuba_instrument || isNew) {
540 }
541 } else {
542 this.enemy = new(tuba_note);
543 if (Tuba_PitchStep) {
544 this.enemy.enemy = new(tuba_note_2);
545 }
546 isNew = true;
547 }
548
549 this.enemy.tuba_attenuate = att;
550
551 if (isNew) {
552 this.note = n;
553 this.tuba_instrument = i;
554 upd = true;
555 }
556 }
557
558 if (f & 2) {
559 this.enemy.origin = ReadVector();
560 setorigin(this.enemy, this.enemy.origin);
561 if (this.enemy.enemy) {
562 setorigin(this.enemy.enemy, this.enemy.origin);
563 }
564 }
565
567 this.entremove = Ent_TubaNote_StopSound;
569 this.enemy.nextthink = time + 10;
570
571 if (upd) {
573 }
574 return true;
575}
576
578{
580 if (Tuba_PitchStep) {
581 if (!checkextension("DP_SND_SOUND7_WIP2") && !checkextension("DP_SND_SOUND7")) {
582 LOG_WARN("requested pitch shifting, but not supported by this engine build");
583 Tuba_PitchStep = 0;
584 }
585 }
586 for (int n = TUBA_MIN; n <= TUBA_MAX; ++n) {
587 if (!Tuba_PitchStep || pymod(n, Tuba_PitchStep) == 0) {
588 for (int i = 0; i < TUBA_INSTRUMENTS; ++i) {
590 }
591 }
592 }
593}
594
595#endif
596#ifdef MENUQC
597
598METHOD(Tuba, describe, string(Tuba this))
599{
600 TC(Tuba, this);
602 PAR(_("The %s is a unique weapon that makes the ears of nearby enemies bleed by playing awful sounds, also slightly knocking them back."), COLORED_NAME(this));
603 PAR(_("The secondary fire works the same way, playing a higher pitch."));
604 PAR(_("The only ammo it needs to operate is the breath from your lungs."));
605 PAR(_("Since your enemies need to be close by to hear your rubbish music, the %s is only effective at very close ranges."), COLORED_NAME(this));
606 PAR(_("The pitch the %s plays depends on the movement keys pressed."), COLORED_NAME(this));
607 PAR(W_Guide_Keybinds(this));
609 return PAGE_TEXT;
610}
611
612#endif
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
Definition tuba.qh:20
string netname
Definition powerups.qc:20
float cnt
Definition powerups.qc:24
entity owner
Definition main.qh:87
#define COLORED_NAME(this)
Definition color.qh:195
float radius
Definition impulse.qh:11
#define PHYS_INPUT_BUTTON_CROUCH(s)
Definition player.qh:154
vector movement
Definition player.qh:229
#define PHYS_INPUT_BUTTON_JUMP(s)
Definition player.qh:151
float teleport_time
Definition player.qh:216
#define PHYS_INPUT_BUTTON_ATCK(s)
Definition player.qh:150
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition player.qh:152
float W_WeaponRateFactor(entity this)
vector v_up
float frametime
float time
vector v_right
float nextthink
vector v_forward
vector origin
float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
Definition damage.qc:981
float spawnshieldtime
Definition damage.qh:61
int state
int w_deathtype
const int HITTYPE_BOUNCE
Definition all.qh:31
const int HITTYPE_SECONDARY
Definition all.qh:29
const int HITTYPE_SOUND
Definition all.qh:33
#define tokenize_console
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:124
#define TC(T, sym)
Definition _all.inc:82
int SendFlags
Definition net.qh:118
#define NET_HANDLE(id, param)
Definition net.qh:15
const int MSG_ENTITY
Definition net.qh:115
#define ReadVector()
Definition net.qh:367
#define WriteHeader(to, id)
Definition net.qh:221
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
Definition net.qh:123
int ReadByte()
#define LOG_WARN(...)
Definition log.qh:61
string trigger_magicear_processmessage_forallears(entity source, float teamsay, entity privatesay, string msgin)
Definition magicear.qc:149
float pymod(float e, float f)
Pythonic mod: TODO: %% operator?
Definition mathlib.qc:194
const float M_PI_2
Definition mathlib.qh:109
float MSG_ONE
Definition menudefs.qc:56
float stof(string val,...)
float bound(float min, float value, float max)
void WriteChar(float data, float dest, float desto)
float cos(float f)
float random(void)
void bprint(string text,...)
float vlen(vector v)
string precache_sound(string sample)
float sin(float f)
float min(float f,...)
float checkextension(string ext)
vector normalize(vector v)
void WriteByte(float data, float dest, float desto)
float fabs(float f)
float floor(float f)
string argv(float n)
float max(float f,...)
string string_null
Definition nil.qh:9
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
entity Notification
always last
Definition all.qh:81
#define METHOD(cname, name, prototype)
Definition oo.qh:269
#define NULL
Definition post.qh:14
#define gettaginfo
Definition post.qh:32
entity msg_entity
Definition progsdefs.qc:63
#define setthink(e, f)
vector
Definition self.qh:92
vector org
Definition self.qh:92
const float VOL_BASE
Definition sound.qh:36
#define _sound(e, c, s, v, a)
Definition sound.qh:43
const int CH_TUBA_SINGLE
Definition sound.qh:17
#define sound(e, c, s, v, a)
Definition sound.qh:52
bool sound_allowed(int to, entity e)
Definition all.qc:9
ClientState CS(Client this)
Definition state.qh:47
#define PRECACHE(func)
directly after STATIC_INIT_LATE
Definition static.qh:42
#define PAGE_TEXT
Definition string.qh:643
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
Definition string.qh:649
#define PAGE_TEXT_INIT()
Definition string.qh:642
entity enemy
Definition sv_ctf.qh:153
float speed2
const int NUM_TEAM_2
Definition teams.qh:14
const int NUM_TEAM_4
Definition teams.qh:16
bool teamplay
Definition teams.qh:59
entity realowner
vector w_shotorg
Definition tracing.qh:19
#define W_SetupShot(ent, wepent, antilag, recoil, snd, chan, maxdamage, deathtype)
Definition tracing.qh:34
int W_Tuba_GetNote(entity pl, int hittype)
Definition tuba.qc:141
void Ent_TubaNote_UpdateSound(entity this)
Definition tuba.qc:512
const int TUBA_MIN
Definition tuba.qc:435
void Ent_TubaNote_StopSound(entity this)
Definition tuba.qc:521
void Ent_TubaNote_Think(entity this)
Definition tuba.qc:491
void tubasound(entity e, bool restart)
Definition tuba.qc:441
entity tuba_note
Definition tuba.qc:5
vector tuba_lastnotes[MAX_TUBANOTES]
Definition tuba.qc:11
bool W_Tuba_HasPlayed(entity pl,.entity weaponentity, string melody, int instrument, bool ignorepitch, float mintempo, float maxtempo)
Definition tuba.qc:13
const int TUBA_MAX
Definition tuba.qc:436
const int TUBA_INSTRUMENTS
Definition tuba.qc:437
float tuba_lastnotes_cnt
Definition tuba.qc:10
#define MAX_TUBANOTES
Definition tuba.qc:8
float tuba_smoketime
Definition tuba.qc:6
int Tuba_PitchStep
Definition tuba.qc:439
bool W_Tuba_NoteSendEntity(entity this, entity to, int sf)
Definition tuba.qc:209
void W_Tuba_NoteOn(entity actor,.entity weaponentity, float hittype)
Definition tuba.qc:266
void W_Tuba_NoteOff(entity this)
Definition tuba.qc:104
void W_Tuba_NoteThink(entity this)
Definition tuba.qc:231
#define TUBA_STARTNOTE(i, n)
Definition tuba.qc:433
float tuba_lastnotes_last
Definition tuba.qc:9
float autocvar_cl_tuba_fadetime
Definition tuba.qh:15
float autocvar_cl_tuba_attenuation
Definition tuba.qh:14
float autocvar_cl_tuba_pitchstep
Definition tuba.qh:16
float autocvar_cl_tuba_volume
Definition tuba.qh:17
float autocvar_snd_soundradius
Definition tuba.qh:71
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:50
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8
#define vec3(_x, _y, _z)
Definition vector.qh:95
string W_Guide_Keybinds(Weapon wep)
Definition all.qc:836
string W_Guide_DPS_onlyOne_unnamed(string name)
Definition all.qc:913
string weaponname
Definition all.qh:388
#define WEP_CVAR(wep, name)
Definition all.qh:321
const int WS_READY
idle frame
Definition weapon.qh:41
const int WS_INUSE
fire state
Definition weapon.qh:39
void weapon_thinkf(entity actor,.entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor,.entity weaponentity, int fire) func)
bool weapon_prepareattack(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
void w_ready(Weapon thiswep, entity actor,.entity weaponentity, int fire)
entity weaponentity_fld
int tuba_instrument
Definition wepent.qh:10