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:195
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
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:120
#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:350
#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: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:193
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:642
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
Definition string.qh:648
#define PAGE_TEXT_INIT()
Definition string.qh:641
entity enemy
Definition sv_ctf.qh:153
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:95
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