Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
tuba.qc File Reference
#include "tuba.qh"
Include dependency graph for tuba.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MAX_TUBANOTES   32
#define TUBA_STARTNOTE(i, n)

Functions

void Ent_TubaNote_StopSound (entity this)
void Ent_TubaNote_Think (entity this)
void Ent_TubaNote_UpdateSound (entity this)
 NET_HANDLE (ENT_CLIENT_TUBANOTE, bool isNew)
 PRECACHE (Tuba)
void tubasound (entity e, bool restart)
int W_Tuba_GetNote (entity pl, int hittype)
bool W_Tuba_HasPlayed (entity pl,.entity weaponentity, string melody, int instrument, bool ignorepitch, float mintempo, float maxtempo)
void W_Tuba_NoteOff (entity this)
void W_Tuba_NoteOn (entity actor,.entity weaponentity, float hittype)
bool W_Tuba_NoteSendEntity (entity this, entity to, int sf)
void W_Tuba_NoteThink (entity this)

Variables

const int TUBA_INSTRUMENTS = 3
vector tuba_lastnotes [MAX_TUBANOTES]
float tuba_lastnotes_cnt
float tuba_lastnotes_last
const int TUBA_MAX = 27
const int TUBA_MIN = -18
entity tuba_note
int Tuba_PitchStep
float tuba_smoketime

Macro Definition Documentation

◆ MAX_TUBANOTES

#define MAX_TUBANOTES   32

Definition at line 8 of file tuba.qc.

Referenced by W_Tuba_HasPlayed(), and W_Tuba_NoteOff().

◆ TUBA_STARTNOTE

#define TUBA_STARTNOTE ( i,
n )
Value:
_Sound_fixpath(W_Sound(strcat("tuba", (i ? ftos(i) : ""), "_loopnote", ftos(n))))
string ftos(float f)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
string _Sound_fixpath(string base)
Definition sound.qh:94
string W_Sound(string w_snd)
Definition all.qc:226

Definition at line 430 of file tuba.qc.

Referenced by PRECACHE(), and tubasound().

Function Documentation

◆ Ent_TubaNote_StopSound()

void Ent_TubaNote_StopSound ( entity this)

Definition at line 522 of file tuba.qc.

523{
524 this.enemy.nextthink = time;
525 this.enemy = NULL;
526}
float time
#define NULL
Definition post.qh:14
entity enemy
Definition sv_ctf.qh:153

References enemy, entity(), NULL, and time.

Referenced by NET_HANDLE().

◆ Ent_TubaNote_Think()

void Ent_TubaNote_Think ( entity this)

Definition at line 491 of file tuba.qc.

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}
float frametime
float nextthink
const int CH_TUBA_SINGLE
Definition sound.qh:17
#define sound(e, c, s, v, a)
Definition sound.qh:52
void tubasound(entity e, bool restart)
Definition tuba.qc:438
float autocvar_cl_tuba_fadetime
Definition tuba.qh:15

References autocvar_cl_tuba_fadetime, CH_TUBA_SINGLE, enemy, entity(), frametime, nextthink, sound, time, and tubasound().

Referenced by NET_HANDLE().

◆ Ent_TubaNote_UpdateSound()

void Ent_TubaNote_UpdateSound ( entity this)

Definition at line 513 of file tuba.qc.

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}
float bound(float min, float value, float max)
const float VOL_BASE
Definition sound.qh:36
float autocvar_cl_tuba_volume
Definition tuba.qh:17
int tuba_instrument
Definition wepent.qh:10

References autocvar_cl_tuba_volume, bound(), enemy, entity(), tuba_instrument, tubasound(), and VOL_BASE.

Referenced by NET_HANDLE().

◆ NET_HANDLE()

NET_HANDLE ( ENT_CLIENT_TUBANOTE ,
bool isNew )

Definition at line 528 of file tuba.qc.

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}
#define ReadVector()
Definition net.qh:350
int ReadByte()
#define setthink(e, f)
void Ent_TubaNote_UpdateSound(entity this)
Definition tuba.qc:513
void Ent_TubaNote_StopSound(entity this)
Definition tuba.qc:522
void Ent_TubaNote_Think(entity this)
Definition tuba.qc:491
entity tuba_note
Definition tuba.qc:5
int Tuba_PitchStep
Definition tuba.qc:436

References enemy, Ent_TubaNote_StopSound(), Ent_TubaNote_Think(), Ent_TubaNote_UpdateSound(), ReadByte(), ReadVector, setthink, time, tuba_instrument, tuba_note, and Tuba_PitchStep.

◆ PRECACHE()

PRECACHE ( Tuba )

Definition at line 580 of file tuba.qc.

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}
#define LOG_WARN(...)
Definition log.qh:61
float pymod(float e, float f)
Pythonic mod: TODO: %% operator?
Definition mathlib.qc:193
string precache_sound(string sample)
float checkextension(string ext)
const int TUBA_MIN
Definition tuba.qc:432
const int TUBA_MAX
Definition tuba.qc:433
const int TUBA_INSTRUMENTS
Definition tuba.qc:434
#define TUBA_STARTNOTE(i, n)
Definition tuba.qc:430
float autocvar_cl_tuba_pitchstep
Definition tuba.qh:16

References autocvar_cl_tuba_pitchstep, checkextension(), LOG_WARN, precache_sound(), pymod(), TUBA_INSTRUMENTS, TUBA_MAX, TUBA_MIN, Tuba_PitchStep, and TUBA_STARTNOTE.

◆ tubasound()

void tubasound ( entity e,
bool restart )

Definition at line 438 of file tuba.qc.

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}
const float M_PI_2
Definition mathlib.qh:109
float cos(float f)
float sin(float f)
string string_null
Definition nil.qh:9
#define _sound(e, c, s, v, a)
Definition sound.qh:43
float speed2
monster run speed
float autocvar_cl_tuba_attenuation
Definition tuba.qh:14

References _sound, autocvar_cl_tuba_attenuation, CH_TUBA_SINGLE, cos(), entity(), M_PI_2, pymod(), sin(), speed2, string_null, TUBA_MAX, TUBA_MIN, Tuba_PitchStep, and TUBA_STARTNOTE.

Referenced by Ent_TubaNote_Think(), and Ent_TubaNote_UpdateSound().

◆ W_Tuba_GetNote()

int W_Tuba_GetNote ( entity pl,
int hittype )

Definition at line 136 of file tuba.qc.

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}
#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
const int HITTYPE_SECONDARY
Definition all.qh:29
ClientState CS(Client this)
Definition state.qh:47
const int NUM_TEAM_2
Definition teams.qh:14
const int NUM_TEAM_4
Definition teams.qh:16
bool teamplay
Definition teams.qh:59

References CS(), entity(), HITTYPE_SECONDARY, movement, NUM_TEAM_2, NUM_TEAM_4, PHYS_INPUT_BUTTON_CROUCH, PHYS_INPUT_BUTTON_JUMP, and teamplay.

Referenced by W_Tuba_NoteOn().

◆ W_Tuba_HasPlayed()

bool W_Tuba_HasPlayed ( entity pl,
.entity weaponentity,
string melody,
int instrument,
bool ignorepitch,
float mintempo,
float maxtempo )

Definition at line 13 of file tuba.qc.

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}
#define tokenize_console
float stof(string val,...)
float min(float f,...)
float floor(float f)
string argv(float n)
float max(float f,...)
vector
Definition self.qh:92
vector tuba_lastnotes[MAX_TUBANOTES]
Definition tuba.qc:11
float tuba_lastnotes_cnt
Definition tuba.qc:10
#define MAX_TUBANOTES
Definition tuba.qc:8

References argv(), entity(), floor(), max(), MAX_TUBANOTES, min(), stof(), tokenize_console, tuba_lastnotes, tuba_lastnotes_cnt, and vector.

Referenced by trigger_magicear_processmessage().

◆ W_Tuba_NoteOff()

void W_Tuba_NoteOff ( entity this)

Definition at line 99 of file tuba.qc.

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}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float cnt
Definition powerups.qc:24
entity owner
Definition main.qh:87
float spawnshieldtime
Definition damage.qh:61
string trigger_magicear_processmessage_forallears(entity source, float teamsay, entity privatesay, string msgin)
Definition magicear.qc:149
void bprint(string text,...)
float tuba_lastnotes_last
Definition tuba.qc:9
#define vec3(_x, _y, _z)
Definition vector.qh:95
entity weaponentity_fld

References bound(), bprint(), cnt, entity(), MAX_TUBANOTES, NULL, owner, spawnshieldtime, strcat(), string_null, time, trigger_magicear_processmessage_forallears(), tuba_instrument, tuba_lastnotes, tuba_lastnotes_cnt, tuba_lastnotes_last, tuba_note, vec3, and weaponentity_fld.

Referenced by W_Tuba_NoteOn(), and W_Tuba_NoteThink().

◆ W_Tuba_NoteOn()

void W_Tuba_NoteOn ( entity actor,
.entity weaponentity,
float hittype )

Definition at line 262 of file tuba.qc.

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}
float radius
Definition impulse.qh:11
float W_WeaponRateFactor(entity this)
vector v_up
vector v_right
vector v_forward
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
const int HITTYPE_BOUNCE
Definition all.qh:31
const int HITTYPE_SOUND
Definition all.qh:33
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:120
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
Definition net.qh:167
#define gettaginfo
Definition post.qh:32
vector org
Definition self.qh:92
#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
float tuba_smoketime
Definition tuba.qc:6
bool W_Tuba_NoteSendEntity(entity this, entity to, int sf)
Definition tuba.qc:205
void W_Tuba_NoteOff(entity this)
Definition tuba.qc:99
void W_Tuba_NoteThink(entity this)
Definition tuba.qc:226
#define WEP_CVAR(wep, name)
Definition all.qh:337

References entity(), gettaginfo, HITTYPE_BOUNCE, HITTYPE_SECONDARY, HITTYPE_SOUND, Net_LinkEntity(), NULL, org, radius, RadiusDamage(), Send_Effect(), setthink, time, tuba_instrument, tuba_note, tuba_smoketime, v_forward, v_right, v_up, vector, W_SetupShot, W_Tuba_GetNote(), W_Tuba_NoteOff(), W_Tuba_NoteSendEntity(), W_Tuba_NoteThink(), W_WeaponRateFactor(), and WEP_CVAR.

◆ W_Tuba_NoteSendEntity()

bool W_Tuba_NoteSendEntity ( entity this,
entity to,
int sf )

Definition at line 205 of file tuba.qc.

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}
vector origin
const int MSG_ENTITY
Definition net.qh:156
#define WriteHeader(to, id)
Definition net.qh:265
float MSG_ONE
Definition menudefs.qc:56
void WriteChar(float data, float dest, float desto)
void WriteByte(float data, float dest, float desto)
entity msg_entity
Definition progsdefs.qc:63
bool sound_allowed(int to, entity e)
Definition all.qc:9
entity realowner

References cnt, entity(), MSG_ENTITY, msg_entity, MSG_ONE, origin, realowner, sound_allowed(), tuba_instrument, WriteByte(), WriteChar(), and WriteHeader.

Referenced by W_Tuba_NoteOn().

◆ W_Tuba_NoteThink()

void W_Tuba_NoteThink ( entity this)

Definition at line 226 of file tuba.qc.

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}
float teleport_time
Definition player.qh:218
int SendFlags
Definition net.qh:159
float vlen(vector v)
vector normalize(vector v)
float fabs(float f)
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

References autocvar_snd_soundradius, entity(), fabs(), FOREACH_CLIENT, IS_REAL_CLIENT, max(), nextthink, normalize(), origin, realowner, SendFlags, teleport_time, time, vector, vlen(), W_Tuba_NoteOff(), and WEP_CVAR.

Referenced by W_Tuba_NoteOn().

Variable Documentation

◆ TUBA_INSTRUMENTS

const int TUBA_INSTRUMENTS = 3

Definition at line 434 of file tuba.qc.

Referenced by PRECACHE().

◆ tuba_lastnotes

vector tuba_lastnotes[MAX_TUBANOTES]

Definition at line 11 of file tuba.qc.

Referenced by W_Tuba_HasPlayed(), and W_Tuba_NoteOff().

◆ tuba_lastnotes_cnt

float tuba_lastnotes_cnt

Definition at line 10 of file tuba.qc.

Referenced by W_Tuba_HasPlayed(), and W_Tuba_NoteOff().

◆ tuba_lastnotes_last

float tuba_lastnotes_last

Definition at line 9 of file tuba.qc.

Referenced by W_Tuba_NoteOff().

◆ TUBA_MAX

const int TUBA_MAX = 27

Definition at line 433 of file tuba.qc.

Referenced by PRECACHE(), and tubasound().

◆ TUBA_MIN

const int TUBA_MIN = -18

Definition at line 432 of file tuba.qc.

Referenced by PRECACHE(), and tubasound().

◆ tuba_note

entity tuba_note

Definition at line 5 of file tuba.qc.

Referenced by bot_cmd_debug_assert_canfire(), NET_HANDLE(), W_Tuba_NoteOff(), and W_Tuba_NoteOn().

◆ Tuba_PitchStep

int Tuba_PitchStep

Definition at line 436 of file tuba.qc.

Referenced by NET_HANDLE(), PRECACHE(), and tubasound().

◆ tuba_smoketime

float tuba_smoketime

Definition at line 6 of file tuba.qc.

Referenced by W_Tuba_NoteOn().