]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/triggers/trigger/multi.qc
Use the sound list
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / trigger / multi.qc
1 // NOTE: also contains trigger_once at bottom
2
3 #ifdef SVQC
4 // the wait time has passed, so set back up for another activation
5 void multi_wait()
6 {SELFPARAM();
7         if (self.max_health)
8         {
9                 self.health = self.max_health;
10                 self.takedamage = DAMAGE_YES;
11                 self.solid = SOLID_BBOX;
12         }
13 }
14
15
16 // the trigger was just touched/killed/used
17 // self.enemy should be set to the activator so it can be held through a delay
18 // so wait for the delay time before firing
19 void multi_trigger()
20 {SELFPARAM();
21         if (self.nextthink > time)
22         {
23                 return;         // allready been triggered
24         }
25
26         if (self.classname == "trigger_secret")
27         {
28                 if (!IS_PLAYER(self.enemy))
29                         return;
30                 found_secrets = found_secrets + 1;
31                 WriteByte (MSG_ALL, SVC_FOUNDSECRET);
32         }
33
34         if (self.noise)
35                 _sound (self.enemy, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
36
37 // don't trigger again until reset
38         self.takedamage = DAMAGE_NO;
39
40         activator = self.enemy;
41         other = self.goalentity;
42         SUB_UseTargets();
43
44         if (self.wait > 0)
45         {
46                 self.think = multi_wait;
47                 self.nextthink = time + self.wait;
48         }
49         else if (self.wait == 0)
50         {
51                 multi_wait(); // waiting finished
52         }
53         else
54         {       // we can't just remove (self) here, because this is a touch function
55                 // called wheil C code is looping through area links...
56                 self.touch = func_null;
57         }
58 }
59
60 void multi_use()
61 {SELFPARAM();
62         self.goalentity = other;
63         self.enemy = activator;
64         multi_trigger();
65 }
66
67 void multi_touch()
68 {SELFPARAM();
69         if(!(self.spawnflags & 2))
70         if(!other.iscreature)
71                         return;
72
73         if(self.team)
74                 if(((self.spawnflags & 4) == 0) == (self.team != other.team))
75                         return;
76
77 // if the trigger has an angles field, check player's facing direction
78         if (self.movedir != '0 0 0')
79         {
80                 makevectors (other.angles);
81                 if (v_forward * self.movedir < 0)
82                         return;         // not facing the right way
83         }
84
85         // if the trigger has pressed keys, check that the player is pressing those keys
86         if(self.pressedkeys)
87         if(IS_PLAYER(other)) // only for players
88         if(!(other.pressedkeys & self.pressedkeys))
89                 return;
90
91         EXACTTRIGGER_TOUCH;
92
93         self.enemy = other;
94         self.goalentity = other;
95         multi_trigger ();
96 }
97
98 void multi_eventdamage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
99 {SELFPARAM();
100         if (!self.takedamage)
101                 return;
102         if(self.spawnflags & DOOR_NOSPLASH)
103                 if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
104                         return;
105         self.health = self.health - damage;
106         if (self.health <= 0)
107         {
108                 self.enemy = attacker;
109                 self.goalentity = inflictor;
110                 multi_trigger();
111         }
112 }
113
114 void multi_reset()
115 {SELFPARAM();
116         if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) )
117                 self.touch = multi_touch;
118         if (self.max_health)
119         {
120                 self.health = self.max_health;
121                 self.takedamage = DAMAGE_YES;
122                 self.solid = SOLID_BBOX;
123         }
124         self.think = func_null;
125         self.nextthink = 0;
126         self.team = self.team_saved;
127 }
128
129 /*QUAKED spawnfunc_trigger_multiple (.5 .5 .5) ? notouch
130 Variable sized repeatable trigger.  Must be targeted at one or more entities.  If "health" is set, the trigger must be killed to activate each time.
131 If "delay" is set, the trigger waits some time after activating before firing.
132 "wait" : Seconds between triggerings. (.2 default)
133 If notouch is set, the trigger is only fired by other entities, not by touching.
134 NOTOUCH has been obsoleted by spawnfunc_trigger_relay!
135 sounds
136 1)      secret
137 2)      beep beep
138 3)      large switch
139 4)
140 set "message" to text string
141 */
142 void spawnfunc_trigger_multiple()
143 {SELFPARAM();
144         self.reset = multi_reset;
145         if (self.sounds == 1)
146         {
147                 precache_sound ("misc/secret.wav");
148                 self.noise = "misc/secret.wav";
149         }
150         else if (self.sounds == 2)
151         {
152                 self.noise = SND(TALK);
153         }
154         else if (self.sounds == 3)
155         {
156                 precache_sound ("misc/trigger1.wav");
157                 self.noise = "misc/trigger1.wav";
158         }
159
160         if (!self.wait)
161                 self.wait = 0.2;
162         else if(self.wait < -1)
163                 self.wait = 0;
164         self.use = multi_use;
165
166         EXACTTRIGGER_INIT;
167
168         self.team_saved = self.team;
169
170         if (self.health)
171         {
172                 if (self.spawnflags & SPAWNFLAG_NOTOUCH)
173                         objerror ("health and notouch don't make sense\n");
174                 self.max_health = self.health;
175                 self.event_damage = multi_eventdamage;
176                 self.takedamage = DAMAGE_YES;
177                 self.solid = SOLID_BBOX;
178                 setorigin (self, self.origin);  // make sure it links into the world
179         }
180         else
181         {
182                 if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) )
183                 {
184                         self.touch = multi_touch;
185                         setorigin (self, self.origin);  // make sure it links into the world
186                 }
187         }
188 }
189
190
191 /*QUAKED spawnfunc_trigger_once (.5 .5 .5) ? notouch
192 Variable sized trigger. Triggers once, then removes itself.  You must set the key "target" to the name of another object in the level that has a matching
193 "targetname".  If "health" is set, the trigger must be killed to activate.
194 If notouch is set, the trigger is only fired by other entities, not by touching.
195 if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
196 if "angle" is set, the trigger will only fire when someone is facing the direction of the angle.  Use "360" for an angle of 0.
197 sounds
198 1)      secret
199 2)      beep beep
200 3)      large switch
201 4)
202 set "message" to text string
203 */
204 void spawnfunc_trigger_once()
205 {SELFPARAM();
206         self.wait = -1;
207         spawnfunc_trigger_multiple();
208 }
209 #endif