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 n = tokenize_console(melody);
16 if (n > pl.(weaponentity).tuba_lastnotes_cnt)
17 return false;
18 float pitchshift = 0;
19
20 if (instrument >= 0 && pl.(weaponentity).tuba_instrument != instrument)
21 return false;
22
23 // verify notes...
24 int i;
25 bool nolength = false;
26 for (i = 0; i < n; ++i)
27 {
28 vector v = pl.(weaponentity).(tuba_lastnotes[(pl.(weaponentity).tuba_lastnotes_last - i + MAX_TUBANOTES) % MAX_TUBANOTES]);
29 float ai = stof(argv(n - i - 1));
30 float np = floor(ai);
31 if (ai == np)
32 nolength = true;
33 // n counts the last played notes BACKWARDS
34 // .x is start
35 // .y is end
36 // .z is note pitch
37 if (ignorepitch && i == 0)
38 pitchshift = np - v.z;
39 else if (v.z + pitchshift != np)
40 return false;
41 }
42
43 // now we know the right NOTES were played
44 if (!nolength)
45 {
46 // verify rhythm...
47 float mmin, mmax;
48 if (maxtempo > 0)
49 mmin = 240 / maxtempo; // 60 = "0.25 means 1 sec", at 120 0.5 means 1 sec, at 240 1 means 1 sec
50 else
51 mmin = 0;
52 if (mintempo > 0)
53 mmax = 240 / mintempo; // 60 = "0.25 means 1 sec", at 120 0.5 means 1 sec, at 240 1 means 1 sec
54 else
55 mmax = 240; // you won't try THAT hard... (tempo 1)
56 //printf("initial tempo rules: %f %f\n", mmin, mmax);
57
58 float ti = 0;
59 for (i = 0; i < n; ++i)
60 {
61 vector vi = pl.(weaponentity).(tuba_lastnotes[(pl.(weaponentity).tuba_lastnotes_last - i + MAX_TUBANOTES) % MAX_TUBANOTES]);
62 float ai = stof(argv(n - i - 1));
63 ti -= 1 / (ai - floor(ai));
64 float tj = ti;
65 for (int j = i + 1; j < n; ++j)
66 {
67 vector vj = pl.(weaponentity).(tuba_lastnotes[(pl.(weaponentity).tuba_lastnotes_last - j + MAX_TUBANOTES) % MAX_TUBANOTES]);
68 float aj = stof(argv(n - j - 1));
69 tj -= aj - floor(aj);
70
71 // note i should be at m*ti+b
72 // note j should be at m*tj+b
73 // so:
74 // we have a LINE l, so that
75 // vi.x <= l(ti) <= vi.y
76 // vj.x <= l(tj) <= vj.y
77 // what is m?
78
79 // vi.x <= vi.y <= vj.x <= vj.y
80 // ti <= tj
81 //printf("first note: %f to %f, should be %f\n", vi.x, vi.y, ti);
82 //printf("second note: %f to %f, should be %f\n", vj.x, vj.y, tj);
83 //printf("m1 = %f\n", (vi.x - vj.y) / (ti - tj));
84 //printf("m2 = %f\n", (vi.y - vj.x) / (ti - tj));
85 mmin = max(mmin, (vi.x - vj.y) / (ti - tj)); // lower bound
86 mmax = min(mmax, (vi.y - vj.x) / (ti - tj)); // upper bound
87 }
88 }
89
90 if (mmin > mmax) // rhythm fail
91 return false;
92 }
93
94 pl.(weaponentity).tuba_lastnotes_cnt = 0;
95
96 return true;
97}
98
100{
101 entity actor = this.owner;
102 // we have a note:
103 // on: this.spawnshieldtime
104 // off: time
105 // note: this.cnt
106 .entity weaponentity = this.weaponentity_fld;
107 if (actor.(weaponentity).tuba_note == this)
108 {
109 actor.(weaponentity).tuba_lastnotes_last = (actor.(weaponentity).tuba_lastnotes_last + 1) % MAX_TUBANOTES;
110 actor.(weaponentity).(tuba_lastnotes[actor.(weaponentity).tuba_lastnotes_last]) = vec3(this.spawnshieldtime, time, this.cnt);
111 actor.(weaponentity).tuba_note = NULL;
112 actor.(weaponentity).tuba_lastnotes_cnt = bound(0, actor.(weaponentity).tuba_lastnotes_cnt + 1, MAX_TUBANOTES);
113
115 if (s != "")
116 {
117 // simulate a server message
118 switch (this.tuba_instrument)
119 {
120 default:
121 case 0: // Tuba
122 bprint(strcat("\{1}\{13}* ^3", actor.netname, "^3 played on the @!#%'n Tuba: ^7", s, "\n"));
123 break;
124 case 1:
125 bprint(strcat("\{1}\{13}* ^3", actor.netname, "^3 played on the @!#%'n Accordeon: ^7", s, "\n"));
126 break;
127 case 2:
128 bprint(strcat("\{1}\{13}* ^3", actor.netname, "^3 played on the @!#%'n Klein Bottle: ^7", s, "\n"));
129 break;
130 }
131 }
132 }
133 delete(this);
134}
135
136int W_Tuba_GetNote(entity pl, int hittype)
137{
138 float movestate = 5;
139 if (CS(pl).movement.x < 0) movestate -= 3;
140 else if (CS(pl).movement.x > 0) movestate += 3;
141 if (CS(pl).movement.y < 0) movestate -= 1;
142 else if (CS(pl).movement.y > 0) movestate += 1;
143
144 int note = 0;
145 switch (movestate)
146 {
147 // layout: originally I wanted
148 // eb e e#=f
149 // B c d
150 // Gb G G#
151 // but then you only use forward and right key. So to make things more
152 // interesting, I swapped B with e#. Har har har...
153 // eb e B
154 // f=e# c d
155 // Gb G G#
156 case 1: note = -6; break; // Gb
157 case 2: note = -5; break; // G
158 case 3: note = -4; break; // G#
159 case 4: note = +5; break; // e#
160 default:
161 case 5: note = 0; break; // c
162 case 6: note = +2; break; // d
163 case 7: note = +3; break; // eb
164 case 8: note = +4; break; // e
165 case 9: note = -1; break; // B
166 }
168 note -= 12;
170 note += 12;
171 if (hittype & HITTYPE_SECONDARY)
172 note += 7;
173
174 // we support two kinds of tubas, those tuned in Eb and those tuned in C
175 // kind of tuba currently is player slot number, or team number if in
176 // teamplay
177 // that way, holes in the range of notes are "plugged"
178 if (teamplay)
179 {
180 if (pl.team == NUM_TEAM_2
181 || pl.team == NUM_TEAM_4)
182 note += 3;
183 }
184 else
185 {
186 if (pl.clientcolors & 1)
187 note += 3;
188 }
189
190 // total range of notes:
191 // 0
192 // *** ** ****
193 // *** ** ****
194 // *** ** ****
195 // *** ** ****
196 // *** ********************* ****
197 // -18.........................+12
198 // *** ********************* ****
199 // -18............................+15
200 // with jump: ... +24
201 // ... +27
202 return note;
203}
204
205bool W_Tuba_NoteSendEntity(entity this, entity to, int sf)
206{
207 msg_entity = to;
208 if (!sound_allowed(MSG_ONE, this.realowner))
209 return false;
210
211 WriteHeader(MSG_ENTITY, ENT_CLIENT_TUBANOTE);
213 if (sf & 1)
214 {
215 WriteChar(MSG_ENTITY, this.cnt);
216 int f = 0;
217 f |= 1 * (this.realowner != to);
218 f |= 2 * this.tuba_instrument;
220 }
221 if (sf & 2)
222 WriteVector(MSG_ENTITY, this.origin);
223 return true;
224}
225
227{
228 if (time > this.teleport_time)
229 {
230 W_Tuba_NoteOff(this);
231 return;
232 }
233 this.nextthink = time;
234
235 float vol0, vol1;
236 vector dir0, dir1;
237 vector v;
238 float dist_mult = WEP_CVAR(WEP_TUBA, attenuation) / autocvar_snd_soundradius;
239 FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != this.realowner,
240 {
241 v = this.origin - (it.origin + it.view_ofs);
242 vol0 = max(0, 1 - vlen(v) * dist_mult);
243 dir0 = normalize(v);
244 v = this.realowner.origin - (it.origin + it.view_ofs);
245 vol1 = max(0, 1 - vlen(v) * dist_mult);
246 dir1 = normalize(v);
247 if (fabs(vol0 - vol1) > 0.005) // 0.5 percent change in volume
248 {
249 setorigin(this, this.realowner.origin);
250 this.SendFlags |= 2;
251 break;
252 }
253 if (dir0 * dir1 < 0.9994) // 2 degrees change in angle
254 {
255 setorigin(this, this.realowner.origin);
256 this.SendFlags |= 2;
257 break;
258 }
259 });
260}
261
262void W_Tuba_NoteOn(entity actor, .entity weaponentity, float hittype)
263{
264 float n = W_Tuba_GetNote(actor, hittype);
265
266 hittype = HITTYPE_SOUND;
267 if (actor.(weaponentity).tuba_instrument & 1)
268 hittype |= HITTYPE_SECONDARY;
269 if (actor.(weaponentity).tuba_instrument & 2)
270 hittype |= HITTYPE_BOUNCE;
271
272 W_SetupShot(actor, weaponentity, false, 2, SND_Null, 0, WEP_CVAR(WEP_TUBA, damage), hittype | WEP_TUBA.m_id);
273
274 if (actor.(weaponentity).tuba_note
275 && (actor.(weaponentity).tuba_note.cnt != n || actor.(weaponentity).tuba_note.tuba_instrument != actor.(weaponentity).tuba_instrument))
276 W_Tuba_NoteOff(actor.(weaponentity).tuba_note);
277
278 if (!actor.(weaponentity).tuba_note)
279 {
280 entity note = new(tuba_note);
281 note.weaponentity_fld = weaponentity;
282 actor.(weaponentity).tuba_note = note;
283 note.owner = note.realowner = actor;
284 note.cnt = n;
285 note.tuba_instrument = actor.(weaponentity).tuba_instrument;
287 note.nextthink = time;
288 note.spawnshieldtime = time;
289 Net_LinkEntity(note, false, 0, W_Tuba_NoteSendEntity);
290 }
291
292 actor.(weaponentity).tuba_note.teleport_time = time + WEP_CVAR(WEP_TUBA, refire) * 2 * W_WeaponRateFactor(actor); // so it can get prolonged safely
293
294 //sound(actor, c, TUBA_NOTE(n), bound(0, VOL_BASE * autocvar_cl_tuba_volume, 1), autocvar_cl_tuba_attenuation);
295 RadiusDamage(actor, actor,
296 WEP_CVAR(WEP_TUBA, damage),
297 WEP_CVAR(WEP_TUBA, edgedamage),
298 WEP_CVAR(WEP_TUBA, radius),
299 NULL,
300 NULL,
301 WEP_CVAR(WEP_TUBA, force),
302 hittype | WEP_TUBA.m_id,
303 weaponentity,
304 NULL
305 );
306
307 if (time > actor.(weaponentity).tuba_smoketime)
308 {
309 // FIXME gettaginfo(actor.(weaponentity), 0) doesn't return the real origin of the weapon
310 vector org = gettaginfo(actor.(weaponentity), 0);
311 if (actor.(weaponentity).tuba_instrument == 1)
312 Send_Effect(EFFECT_SMOKE_RING, org + v_up * 25 + v_right * 10 + v_forward * 14, v_up * 100, 1);
313 else if (actor.(weaponentity).tuba_instrument == 2)
314 Send_Effect(EFFECT_SMOKE_RING, org + v_up * 50 + v_right * 10 + v_forward * 45, v_up * 100, 1);
315 else
316 Send_Effect(EFFECT_SMOKE_RING, org + v_up * 40 + v_right * 10 + v_forward * 14, v_up * 100, 1);
317 actor.(weaponentity).tuba_smoketime = time + 0.25;
318 }
319}
320
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 if (!(fire & (1 | 2)))
350 {
351 W_Tuba_NoteOff(actor.(weaponentity).tuba_note);
352 }
353}
354
355METHOD(Tuba, wr_setup, void(Tuba this, entity actor, .entity weaponentity))
356{
357 actor.(weaponentity).tuba_instrument = 0;
358}
359
360METHOD(Tuba, wr_reload, void(Tuba this, entity actor, .entity weaponentity))
361{
362 // switch to alternate instruments :)
363 if (actor.(weaponentity).state != WS_READY)
364 return;
365
366 switch (actor.(weaponentity).tuba_instrument)
367 {
368 case 0:
369 actor.(weaponentity).tuba_instrument = 1;
370 actor.(weaponentity).weaponname = "akordeon";
371 break;
372 case 1:
373 actor.(weaponentity).tuba_instrument = 2;
374 actor.(weaponentity).weaponname = "kleinbottle";
375 break;
376 case 2:
377 actor.(weaponentity).tuba_instrument = 0;
378 actor.(weaponentity).weaponname = "tuba";
379 break;
380 }
381 int hittype = 0;
382 if (actor.(weaponentity).tuba_instrument & 1)
383 hittype |= HITTYPE_SECONDARY;
384 if (actor.(weaponentity).tuba_instrument & 2)
385 hittype |= HITTYPE_BOUNCE;
386 W_SetupShot(actor, weaponentity, false, 0, SND_Null, 0, 0, hittype | WEP_TUBA.m_id);
387 Send_Effect(EFFECT_TELEPORT, w_shotorg, '0 0 0', 1);
388 actor.(weaponentity).state = WS_INUSE;
389 weapon_thinkf(actor, weaponentity, WFRAME_RELOAD, 0.5, w_ready);
390}
391
392METHOD(Tuba, wr_checkammo1, bool(Tuba this, entity actor, .entity weaponentity))
393{
394 return true; // tuba has infinite ammo
395}
396METHOD(Tuba, wr_checkammo2, bool(Tuba this, entity actor, .entity weaponentity))
397{
398 return true; // tuba has infinite ammo
399}
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#endif // SVQC
421#ifdef CSQC
422
423METHOD(Tuba, wr_viewmodel, string(Tuba this, entity wep))
424{
425 return (wep.tuba_instrument == 0) ? "tuba" :
426 (wep.tuba_instrument == 1) ? "akordeon" :
427 "kleinbottle";
428}
429
430#define TUBA_STARTNOTE(i, n) _Sound_fixpath(W_Sound(strcat("tuba", (i ? ftos(i) : ""), "_loopnote", ftos(n))))
431
432const int TUBA_MIN = -18;
433const int TUBA_MAX = 27;
434const int TUBA_INSTRUMENTS = 3;
435
437
438void tubasound(entity e, bool restart)
439{
440 string snd1 = string_null;
441 if (Tuba_PitchStep)
442 {
443 string snd2 = string_null;
444 float vol1 = 1;
445 float speed1 = 1;
446 float vol2 = 0;
447 float speed2 = 1;
448
449 int m = pymod(e.note, Tuba_PitchStep);
450 if (m)
451 {
452 if (e.note - m < TUBA_MIN)
453 {
454 if (restart)
455 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
456 speed1 = 2.0 ** ((m - Tuba_PitchStep) / 12.0);
457 }
458 else if (e.note - m + Tuba_PitchStep > TUBA_MAX)
459 {
460 if (restart)
461 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
462 speed1 = 2.0 ** (m / 12.0);
463 }
464 else
465 {
466 if (restart)
467 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
468 vol1 = cos(M_PI_2 * m / Tuba_PitchStep);
469 speed1 = 2.0 ** (m / 12.0);
470 if (restart)
471 snd2 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
472 vol2 = sin(M_PI_2 * m / Tuba_PitchStep);
473 speed2 = 2.0 ** ((m - Tuba_PitchStep) / 12.0);
474 }
475 }
476 else if (restart)
477 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
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 {
485 if (restart)
486 snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
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 this.nextthink = time;
499 if (this.tuba_volume <= 0)
500 {
501 sound(this, CH_TUBA_SINGLE, SND_Null, 0, 0);
502 if (this.enemy)
503 {
504 sound(this.enemy, CH_TUBA_SINGLE, SND_Null, 0, 0);
505 delete(this.enemy);
506 }
507 delete(this);
508 }
509 else
510 tubasound(this, 0);
511}
512
514{
515 this.enemy.tuba_volume = bound(0, VOL_BASE * autocvar_cl_tuba_volume, 1);
516 this.enemy.tuba_volume_initial = this.enemy.tuba_volume;
517 this.enemy.note = this.note;
518 this.enemy.tuba_instrument = this.tuba_instrument;
519 tubasound(this.enemy, 1);
520}
521
523{
524 this.enemy.nextthink = time;
525 this.enemy = NULL;
526}
527
528NET_HANDLE(ENT_CLIENT_TUBANOTE, bool isNew)
529{
530 bool upd = false;
531 int f = ReadByte();
532 if (f & 1)
533 {
534 int n = ReadChar();
535 int i = ReadByte();
536 bool att = i & 1;
537 i >>= 1;
538
539 if (this.enemy)
540 {
541 if (n != this.note || i != this.tuba_instrument || isNew)
543 }
544 else
545 {
546 this.enemy = new(tuba_note);
547 if (Tuba_PitchStep)
548 this.enemy.enemy = new(tuba_note_2);
549 isNew = true;
550 }
551
552 this.enemy.tuba_attenuate = att;
553
554 if (isNew)
555 {
556 this.note = n;
557 this.tuba_instrument = i;
558 upd = true;
559 }
560 }
561
562 if (f & 2)
563 {
564 this.enemy.origin = ReadVector();
565 setorigin(this.enemy, this.enemy.origin);
566 if (this.enemy.enemy)
567 setorigin(this.enemy.enemy, this.enemy.origin);
568 }
569
571 this.entremove = Ent_TubaNote_StopSound;
573 this.enemy.nextthink = time + 10;
574
575 if (upd)
577 return true;
578}
579
581{
583 if (Tuba_PitchStep)
584 {
585 if (!checkextension("DP_SND_SOUND7_WIP2") && !checkextension("DP_SND_SOUND7"))
586 {
587 LOG_WARN("requested pitch shifting, but not supported by this engine build");
588 Tuba_PitchStep = 0;
589 }
590 }
591 for (int i, n = TUBA_MIN; n <= TUBA_MAX; ++n)
592 if (!Tuba_PitchStep || pymod(n, Tuba_PitchStep) == 0)
593 for (i = 0; i < TUBA_INSTRUMENTS; ++i)
595}
596
597#endif // CSQC
598#ifdef MENUQC
599
600METHOD(Tuba, describe, string(Tuba this))
601{
602 TC(Tuba, this);
604 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));
605 PAR(_("The secondary fire works the same way, playing a higher pitch."));
606 PAR(_("The only ammo it needs to operate is the breath from your lungs."));
607 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));
608 PAR(_("The pitch the %s plays depends on the movement keys pressed."), COLORED_NAME(this));
609 PAR(W_Guide_Keybinds(this));
611 return PAGE_TEXT;
612}
613
614#endif // MENUQC
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:189
float radius
Definition impulse.qh:11
#define PHYS_INPUT_BUTTON_CROUCH(s)
Definition player.qh:156
vector movement
Definition player.qh:228
#define PHYS_INPUT_BUTTON_JUMP(s)
Definition player.qh:153
float teleport_time
Definition player.qh:218
#define PHYS_INPUT_BUTTON_ATCK(s)
Definition player.qh:152
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition player.qh:154
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:943
float spawnshieldtime
Definition damage.qh:61
int state
int w_deathtype
const int HITTYPE_BOUNCE
set manually after projectile has bounced
Definition all.qh:33
const int HITTYPE_SECONDARY
Definition all.qh:31
const int HITTYPE_SOUND
cause bleeding from ears
Definition all.qh:35
#define tokenize_console
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:120
WriteByte(chan, ent.angles.y/DEC_FACTOR)
#define TC(T, sym)
Definition _all.inc:82
int SendFlags
Definition net.qh:159
#define NET_HANDLE(id, param)
Definition net.qh:15
const int MSG_ENTITY
Definition net.qh:156
#define ReadVector()
Definition net.qh:349
#define WriteHeader(to, id)
Definition net.qh:265
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
Definition net.qh:167
int ReadByte()
#define LOG_WARN(...)
Definition log.qh:58
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:189
const float M_PI_2
pi/2
Definition mathlib.qh:113
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)
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:85
#define METHOD(cname, name, prototype)
Definition oo.qh:274
#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:96
vector org
Definition self.qh:96
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:43
#define PAGE_TEXT
Definition string.qh:651
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
Definition string.qh:657
#define PAGE_TEXT_INIT()
Definition string.qh:650
entity enemy
Definition sv_ctf.qh:152
float speed2
monster run speed
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:136
void Ent_TubaNote_UpdateSound(entity this)
Definition tuba.qc:513
const int TUBA_MIN
Definition tuba.qc:432
void Ent_TubaNote_StopSound(entity this)
Definition tuba.qc:522
void Ent_TubaNote_Think(entity this)
Definition tuba.qc:491
void tubasound(entity e, bool restart)
Definition tuba.qc:438
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:433
const int TUBA_INSTRUMENTS
Definition tuba.qc:434
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:436
bool W_Tuba_NoteSendEntity(entity this, entity to, int sf)
Definition tuba.qc:205
void W_Tuba_NoteOn(entity actor,.entity weaponentity, float hittype)
Definition tuba.qc:262
void W_Tuba_NoteOff(entity this)
Definition tuba.qc:99
void W_Tuba_NoteThink(entity this)
Definition tuba.qc:226
#define TUBA_STARTNOTE(i, n)
Definition tuba.qc:430
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:75
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt().
Definition vector.qh:8
#define vec3(_x, _y, _z)
Definition vector.qh:100
string W_Guide_Keybinds(Weapon wep)
Definition all.qc:824
string W_Guide_DPS_onlyOne_unnamed(string name)
Definition all.qc:901
string weaponname
Definition all.qh:413
#define WEP_CVAR(wep, name)
Definition all.qh:337
const int WS_READY
idle frame
Definition weapon.qh:38
const int WS_INUSE
fire state
Definition weapon.qh:36
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