Xonotic
all.qc
Go to the documentation of this file.
1 #include "all.qh"
2 
3 #ifdef SVQC
4 #include <server/utils.qh>
5 
6 bool autocvar_bot_sound_monopoly;
7 
8 .entity realowner;
9 bool sound_allowed(int to, entity e)
10 {
11  if(!e) return true; // save on a few checks
12  for ( ; ; )
13  {
14  if (e.classname == "body") e = e.enemy;
15  else if (e.realowner && e.realowner != e) e = e.realowner;
16  else if (e.owner && e.owner != e) e = e.owner;
17  else break;
18  }
19  // sounds to self may always pass
20  if (to == MSG_ONE && e == msg_entity) return true;
21  // sounds by players can be removed
22  if (autocvar_bot_sound_monopoly && IS_REAL_CLIENT(e)) return false;
23  // anything else may pass
24  return true;
25 }
26 
28 int precache_sound_index(string s) = #19;
29 
30 const int SVC_SOUND = 6;
31 const int SVC_STOPSOUND = 16;
32 
33 const int SND_VOLUME = BIT(0);
34 const int SND_ATTENUATION = BIT(1);
35 const int SND_LARGEENTITY = BIT(3);
36 const int SND_LARGESOUND = BIT(4);
37 const int SND_SPEEDUSHORT4000 = BIT(5);
38 
39 void soundtoat(int to, entity e, vector o, int chan, string samp, float vol, float attenu, float _pitch)
40 {
41  if (!sound_allowed(to, e)) return;
42  int entno = etof(e);
43  int idx = precache_sound_index(samp);
44  attenu = floor(attenu * 64);
45  vol = floor(vol * 255);
46  int sflags = 0;
47  int speed4000 = floor((_pitch * 0.01) * 4000 + 0.5);
48  if (vol != 255) sflags |= SND_VOLUME;
49  if (attenu != 64) sflags |= SND_ATTENUATION;
50  if (entno >= 8192 || chan < 0 || chan > 7) sflags |= SND_LARGEENTITY;
51  if (idx >= 256) sflags |= SND_LARGESOUND;
52  if (speed4000 && speed4000 != 4000) sflags |= SND_SPEEDUSHORT4000;
53  WriteByte(to, SVC_SOUND);
54  WriteByte(to, sflags);
55  if (sflags & SND_VOLUME) WriteByte(to, vol);
56  if (sflags & SND_ATTENUATION) WriteByte(to, attenu);
57  if (sflags & SND_SPEEDUSHORT4000) WriteShort(to, speed4000);
58  if (sflags & SND_LARGEENTITY)
59  {
60  WriteShort(to, entno);
61  WriteByte(to, chan);
62  }
63  else
64  {
65  WriteShort(to, (entno << 3) | chan);
66  }
67  if (sflags & SND_LARGESOUND) WriteShort(to, idx);
68  else WriteByte(to, idx);
69  WriteCoord(to, o.x);
70  WriteCoord(to, o.y);
71  WriteCoord(to, o.z);
72 }
73 
74 void soundto(int _dest, entity e, int chan, string samp, float vol, float _atten, float _pitch)
75 {
76  if (!sound_allowed(_dest, e)) return;
77  vector o = e.origin + 0.5 * (e.mins + e.maxs);
78  soundtoat(_dest, e, o, chan, samp, vol, _atten, _pitch);
79 }
80 void soundat(entity e, vector o, int chan, string samp, float vol, float _atten)
81 {
82  soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, _atten, 0);
83 }
84 void stopsoundto(int _dest, entity e, int chan)
85 {
86  if (!sound_allowed(_dest, e)) return;
87  int entno = etof(e);
88  if (entno >= 8192 || chan < 0 || chan > 7)
89  {
90  int idx = precache_sound_index(SND(Null));
91  int sflags = SND_LARGEENTITY;
92  if (idx >= 256) sflags |= SND_LARGESOUND;
93  WriteByte(_dest, SVC_SOUND);
94  WriteByte(_dest, sflags);
95  WriteShort(_dest, entno);
96  WriteByte(_dest, chan);
97  if (sflags & SND_LARGESOUND) WriteShort(_dest, idx);
98  else WriteByte(_dest, idx);
99  WriteCoord(_dest, e.origin.x);
100  WriteCoord(_dest, e.origin.y);
101  WriteCoord(_dest, e.origin.z);
102  }
103  else
104  {
105  WriteByte(_dest, SVC_STOPSOUND);
106  WriteShort(_dest, entno * 8 + chan);
107  }
108 }
109 void stopsound(entity e, int chan)
110 {
111  if (!sound_allowed(MSG_BROADCAST, e)) return;
112  stopsoundto(MSG_BROADCAST, e, chan); // unreliable, gets there fast
113  stopsoundto(MSG_ALL, e, chan); // in case of packet loss
114 }
115 
116 void play2(entity e, string filename)
117 {
118  msg_entity = e;
119  soundtoat(MSG_ONE, NULL, '0 0 0', CH_INFO, filename, VOL_BASE, ATTEN_NONE, 0);
120 }
121 
122 .float spamtime;
124 float spamsound(entity e, int chan, Sound samp, float vol, float _atten)
125 {
126  if (!sound_allowed(MSG_BROADCAST, e)) return false;
127  if (time > e.spamtime)
128  {
129  e.spamtime = time;
130  sound(e, chan, samp, vol, _atten);
131  return true;
132  }
133  return false;
134 }
135 
136 void play2team(float t, string filename)
137 {
138  if (autocvar_bot_sound_monopoly) return;
139  FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.team == t, play2(it, filename));
140 }
141 
142 void play2all(string samp)
143 {
144  if (autocvar_bot_sound_monopoly) return;
146 }
147 
148 #endif
#define SND(id)
Definition: all.qh:35
entity() spawn
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
const float ATTEN_NONE
Definition: sound.qh:27
entity to
Definition: self.qh:96
const int CH_INFO
Definition: sound.qh:6
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition: bits.qh:8
entity msg_entity
Definition: progsdefs.qc:63
#define NULL
Definition: post.qh:17
const float VOL_BASE
Definition: sound.qh:36
Definition: sound.qh:119
vector(float skel, float bonenum) _skel_get_boneabs_hidden
#define _sound(e, c, s, v, a)
Definition: sound.qh:50
entity realowner
Definition: common.qh:25
#define sound(e, c, s, v, a)
Definition: sound.qh:52
float time
Definition: csprogsdefs.qc:16
#define IS_PLAYER(v)
Definition: utils.qh:9