]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/mapobjects/target/speaker.qc
Merge branch 'terencehill/minigame_flood_control' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mapobjects / target / speaker.qc
1 #include "speaker.qh"
2 #ifdef SVQC
3 // TODO add a way to do looped sounds with sound(); then complete this entity
4 void target_speaker_use_off(entity this, entity actor, entity trigger);
5 void target_speaker_use_activator(entity this, entity actor, entity trigger)
6 {
7         if (!IS_REAL_CLIENT(actor))
8                 return;
9         string snd;
10         if(substring(this.noise, 0, 1) == "*")
11         {
12                 var .string sample = GetVoiceMessageSampleField(substring(this.noise, 1, -1));
13                 if(GetPlayerSoundSampleField_notFound)
14                         snd = SND(Null);
15                 else if(actor.(sample) == "")
16                         snd = SND(Null);
17                 else
18                 {
19                         tokenize_console(actor.(sample));
20                         float n;
21                         n = stof(argv(1));
22                         if(n > 0)
23                                 snd = strcat(argv(0), ftos(floor(random() * n + 1)), ".wav"); // randomization
24                         else
25                                 snd = strcat(argv(0), ".wav"); // randomization
26                 }
27         }
28         else
29                 snd = this.noise;
30         msg_entity = actor;
31         soundto(MSG_ONE, this, CH_TRIGGER, snd, VOL_BASE * this.volume, this.atten, 0);
32 }
33 void target_speaker_use_on(entity this, entity actor, entity trigger)
34 {
35         string snd;
36         if(substring(this.noise, 0, 1) == "*")
37         {
38                 var .string sample = GetVoiceMessageSampleField(substring(this.noise, 1, -1));
39                 if(GetPlayerSoundSampleField_notFound)
40                         snd = SND(Null);
41                 else if(actor.(sample) == "")
42                         snd = SND(Null);
43                 else
44                 {
45                         tokenize_console(actor.(sample));
46                         float n;
47                         n = stof(argv(1));
48                         if(n > 0)
49                                 snd = strcat(argv(0), ftos(floor(random() * n + 1)), ".wav"); // randomization
50                         else
51                                 snd = strcat(argv(0), ".wav"); // randomization
52                 }
53         }
54         else
55                 snd = this.noise;
56         _sound(this, CH_TRIGGER_SINGLE, snd, VOL_BASE * this.volume, this.atten);
57         if(this.spawnflags & (SPEAKER_LOOPED_ON + SPEAKER_LOOPED_OFF))
58                 this.use = target_speaker_use_off;
59 }
60 void target_speaker_use_off(entity this, entity actor, entity trigger)
61 {
62         sound(this, CH_TRIGGER_SINGLE, SND_Null, VOL_BASE * this.volume, this.atten);
63         this.use = target_speaker_use_on;
64 }
65 void target_speaker_reset(entity this)
66 {
67         if(this.spawnflags & SPEAKER_LOOPED_ON)
68         {
69                 if(this.use == target_speaker_use_on)
70                         target_speaker_use_on(this, NULL, NULL);
71         }
72         else if(this.spawnflags & SPEAKER_LOOPED_OFF)
73         {
74                 if(this.use == target_speaker_use_off)
75                         target_speaker_use_off(this, NULL, NULL);
76         }
77 }
78
79 spawnfunc(target_speaker)
80 {
81         // TODO: "*" prefix to sound file name
82         // TODO: wait and random (just, HOW? random is not a field)
83         if(this.noise)
84                 precache_sound (this.noise);
85
86         if(!this.atten && (this.spawnflags & SPEAKER_GLOBAL) && !(this.spawnflags & 3)) // special check for quake 3: looped sounds are never global
87         {
88                 if (!Q3COMPAT_COMMON)
89                         LOG_WARN("target_speaker uses legacy spawnflag GLOBAL (BIT(2)), please set atten to -1 instead");
90                 this.atten = -1;
91         }
92
93         if(!this.atten)
94         {
95                 if(this.targetname && this.targetname != "")
96                         this.atten = ATTEN_NORM;
97                 else
98                         this.atten = ATTEN_STATIC;
99         }
100         else if(this.atten < 0)
101                 this.atten = 0;
102
103         if(!this.volume)
104                 this.volume = 1;
105
106         if(this.targetname && this.targetname != "")
107         {
108                 if(this.spawnflags & SPEAKER_ACTIVATOR)
109                         this.use = target_speaker_use_activator;
110                 else if(this.spawnflags & SPEAKER_LOOPED_ON)
111                 {
112                         target_speaker_use_on(this, NULL, NULL);
113                         this.reset = target_speaker_reset;
114                 }
115                 else if(this.spawnflags & SPEAKER_LOOPED_OFF)
116                 {
117                         this.use = target_speaker_use_on;
118                         this.reset = target_speaker_reset;
119                 }
120                 else
121                         this.use = target_speaker_use_on;
122         }
123         else if(this.spawnflags & SPEAKER_LOOPED_ON)
124         {
125                 ambientsound (this.origin, this.noise, VOL_BASE * this.volume, this.atten);
126                 delete(this);
127         }
128         else if(this.spawnflags & SPEAKER_LOOPED_OFF)
129         {
130                 objerror(this, "This sound entity can never be activated");
131         }
132         else
133         {
134                 // Quake/Nexuiz fallback
135                 ambientsound (this.origin, this.noise, VOL_BASE * this.volume, this.atten);
136                 delete(this);
137         }
138 }
139 #endif