]> icculus.org git repositories - divverent/nexuiz.git/blob - TeamNexuiz/game/gamec/g_triggers.c
- Spring cleaning! Cleaned up a lot of FTE warnings regarding unused locals
[divverent/nexuiz.git] / TeamNexuiz / game / gamec / g_triggers.c
1 \r
2 void() SUB_UseTargets;\r
3 \r
4 void() DelayThink =\r
5 {\r
6         activator = self.enemy;\r
7         SUB_UseTargets ();\r
8         remove(self);\r
9 };\r
10 \r
11 /*\r
12 ==============================\r
13 SUB_UseTargets\r
14 \r
15 the global "activator" should be set to the entity that initiated the firing.\r
16 \r
17 If self.delay is set, a DelayedUse entity will be created that will actually\r
18 do the SUB_UseTargets after that many seconds have passed.\r
19 \r
20 Centerprints any self.message to the activator.\r
21 \r
22 Removes all entities with a targetname that match self.killtarget,\r
23 and removes them, so some events can remove other triggers.\r
24 \r
25 Search for (string)targetname in all entities that\r
26 match (string)self.target and call their .use function\r
27 \r
28 ==============================\r
29 */\r
30 /*void() SUB_UseTargets =\r
31 {\r
32         local entity t, stemp, otemp, act;\r
33 \r
34 //\r
35 // check for a delay\r
36 //\r
37         if (self.delay)\r
38         {\r
39         // create a temp object to fire at a later time\r
40                 t = spawn();\r
41                 t.classname = "DelayedUse";\r
42                 t.nextthink = time + self.delay;\r
43                 t.think = DelayThink;\r
44                 t.enemy = activator;\r
45                 t.message = self.message;\r
46                 t.killtarget = self.killtarget;\r
47                 t.target = self.target;\r
48                 return;\r
49         }\r
50 \r
51 \r
52 //\r
53 // print the message\r
54 //\r
55         if (activator.classname == "player" && self.message != "")\r
56         {\r
57                 centerprint (activator, self.message);\r
58                 if (!self.noise)\r
59                         sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);\r
60         }\r
61 \r
62 //\r
63 // kill the killtagets\r
64 //\r
65         if (self.killtarget)\r
66         {\r
67                 t = world;\r
68                 do\r
69                 {\r
70                         t = find (t, targetname, self.killtarget);\r
71                         if (!t)\r
72                                 return;\r
73                         remove (t);\r
74                 } while ( 1 );\r
75         }\r
76 \r
77 //\r
78 // fire targets\r
79 //\r
80         if (self.target)\r
81         {\r
82                 act = activator;\r
83                 t = world;\r
84                 do\r
85                 {\r
86                         t = find (t, targetname, self.target);\r
87                         if (!t)\r
88                         {\r
89                                 return;\r
90                         }\r
91                         stemp = self;\r
92                         otemp = other;\r
93                         self = t;\r
94                         other = stemp;\r
95                         if (self.use)\r
96                                 self.use ();\r
97                         self = stemp;\r
98                         other = otemp;\r
99                         activator = act;\r
100                 } while ( 1 );\r
101         }\r
102 \r
103 \r
104 };*/\r
105 \r
106 \r
107 \r
108 void() trigger_reactivate =\r
109 {\r
110         self.solid = SOLID_TRIGGER;\r
111 };\r
112 \r
113 //=============================================================================\r
114 \r
115 float   SPAWNFLAG_NOMESSAGE = 1;\r
116 float   SPAWNFLAG_NOTOUCH = 1;\r
117 \r
118 // the wait time has passed, so set back up for another activation\r
119 void() multi_wait =\r
120 {\r
121         if (self.max_health)\r
122         {\r
123                 self.health = self.max_health;\r
124                 self.takedamage = DAMAGE_YES;\r
125                 self.solid = SOLID_BBOX;\r
126         }\r
127 };\r
128 \r
129 \r
130 // the trigger was just touched/killed/used\r
131 // self.enemy should be set to the activator so it can be held through a delay\r
132 // so wait for the delay time before firing\r
133 /*void() multi_trigger =\r
134 {\r
135         if (self.nextthink > time)\r
136         {\r
137                 return;         // allready been triggered\r
138         }\r
139 \r
140         if (self.classname == "trigger_secret")\r
141         {\r
142                 if (self.enemy.classname != "player")\r
143                         return;\r
144                 found_secrets = found_secrets + 1;\r
145                 WriteByte (MSG_ALL, SVC_FOUNDSECRET);\r
146         }\r
147 \r
148         if (self.noise)\r
149                 sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);\r
150 \r
151 // don't trigger again until reset\r
152         self.takedamage = DAMAGE_NO;\r
153 \r
154         activator = self.enemy;\r
155 \r
156         SUB_UseTargets();\r
157 \r
158         if (self.wait > 0)\r
159         {\r
160                 self.think = multi_wait;\r
161                 self.nextthink = time + self.wait;\r
162         }\r
163         else\r
164         {       // we can't just remove (self) here, because this is a touch function\r
165                 // called wheil C code is looping through area links...\r
166                 self.touch = SUB_Null;\r
167 \r
168                 self.nextthink = time + 0.1;\r
169                 self.think = SUB_Remove;\r
170         }\r
171 };*/\r
172 \r
173 void() multi_trigger = \r
174 {\r
175         if (self.nextthink > time)\r
176         {\r
177                 return;\r
178         }\r
179         if (self.classname == "trigger_secret")\r
180         {\r
181                 if (self.enemy.classname != "player")\r
182                 {\r
183                         return;\r
184                 }\r
185                 found_secrets = found_secrets + TF_FLARE_OFF;\r
186                 WriteByte(2, 28);\r
187         }\r
188         if (self.noise)\r
189         {\r
190                 sound(self, 2, self.noise, TF_FLARE_OFF, TF_FLARE_OFF);\r
191         }\r
192         self.takedamage = TF_FLARE_LIT;\r
193         activator = self.enemy;\r
194         SUB_UseTargets();\r
195         if (self.wait > TF_FLARE_LIT)\r
196         {\r
197                 self.think = multi_wait;\r
198                 self.nextthink = time + self.wait;\r
199         }\r
200         else\r
201         {\r
202                 self.touch = SUB_Null;\r
203                 self.nextthink = time + 0.1;\r
204                 self.think = SUB_Remove;\r
205         }\r
206 };\r
207 \r
208 void() multi_use =\r
209 {\r
210         self.enemy = activator;\r
211         multi_trigger();\r
212 };\r
213 \r
214 void() multi_touch =\r
215 {\r
216         if (other.classname != "player")\r
217                 return;\r
218 \r
219 // if the trigger has an angles field, check player's facing direction\r
220         if (self.movedir != '0 0 0')\r
221         {\r
222                 makevectors (other.angles);\r
223                 if (v_forward * self.movedir < 0)\r
224                         return;         // not facing the right way\r
225         }\r
226 \r
227         self.enemy = other;\r
228         multi_trigger ();\r
229 };\r
230 \r
231 void multi_eventdamage (vector hitloc, float damage, entity inflictor, entity attacker, float deathtype)\r
232 {\r
233         if (!self.takedamage)\r
234                 return;\r
235         self.health = self.health - damage;\r
236         if (self.health <= 0)\r
237         {\r
238                 self.enemy = attacker;\r
239                 multi_trigger();\r
240         }\r
241 }\r
242 \r
243 /*QUAKED trigger_multiple (.5 .5 .5) ? notouch\r
244 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.\r
245 If "delay" is set, the trigger waits some time after activating before firing.\r
246 "wait" : Seconds between triggerings. (.2 default)\r
247 If notouch is set, the trigger is only fired by other entities, not by touching.\r
248 NOTOUCH has been obsoleted by trigger_relay!\r
249 sounds\r
250 1)      secret\r
251 2)      beep beep\r
252 3)      large switch\r
253 4)\r
254 set "message" to text string\r
255 */\r
256 void (float tno) ConvertToGoal;\r
257 void () CheckIfQ3FTrigger;\r
258 void() trigger_multiple =\r
259 {\r
260 /*      if (CheckIfQ3FTrigger() == 1)\r
261         {\r
262                 ConvertToGoal (1);\r
263                 return;\r
264         }\r
265         if (CheckIfQ3FTrigger() == 2)\r
266         {\r
267                 ConvertToGoal (2);\r
268                 return;\r
269         }*/\r
270         CheckIfQ3FTrigger ();\r
271 \r
272         if (self.sounds == 1)\r
273         {\r
274                 precache_sound ("misc/secret.wav");\r
275                 self.noise = "misc/secret.wav";\r
276         }\r
277         else if (self.sounds == 2)\r
278         {\r
279                 precache_sound ("misc/talk.wav");\r
280                 self.noise = "misc/talk.wav";\r
281         }\r
282         else if (self.sounds == 3)\r
283         {\r
284                 precache_sound ("misc/trigger1.wav");\r
285                 self.noise = "misc/trigger1.wav";\r
286         }\r
287 \r
288         if (!self.wait)\r
289                 self.wait = 0.2;\r
290         self.use = multi_use;\r
291 \r
292         InitTrigger ();\r
293 \r
294         if (self.health)\r
295         {\r
296                 if (self.spawnflags & SPAWNFLAG_NOTOUCH)\r
297                         objerror ("health and notouch don't make sense\n");\r
298                 self.max_health = self.health;\r
299                 self.event_damage = multi_eventdamage;\r
300                 self.takedamage = DAMAGE_YES;\r
301                 self.solid = SOLID_BBOX;\r
302                 setorigin (self, self.origin);  // make sure it links into the world\r
303         }\r
304         else\r
305         {\r
306                 if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) )\r
307                 {\r
308                         self.touch = multi_touch;\r
309                 }\r
310         }\r
311 };\r
312 \r
313 \r
314 /*QUAKED trigger_once (.5 .5 .5) ? notouch\r
315 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\r
316 "targetname".  If "health" is set, the trigger must be killed to activate.\r
317 If notouch is set, the trigger is only fired by other entities, not by touching.\r
318 if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.\r
319 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.\r
320 sounds\r
321 1)      secret\r
322 2)      beep beep\r
323 3)      large switch\r
324 4)\r
325 set "message" to text string\r
326 */\r
327 /*void() trigger_once =\r
328 {\r
329         self.wait = -1;\r
330         trigger_multiple();\r
331 };*/\r
332 \r
333 //=============================================================================\r
334 \r
335 /*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)\r
336 This fixed size trigger cannot be touched, it can only be fired by other events.  It can contain killtargets, targets, delays, and messages.\r
337 */\r
338 void() trigger_relay =\r
339 {\r
340         self.use = SUB_UseTargets;\r
341 };\r
342 \r
343 \r
344 //=============================================================================\r
345 \r
346 \r
347 void() counter_use =\r
348 {\r
349         self.count = self.count - 1;\r
350         if (self.count < 0)\r
351                 return;\r
352 \r
353         if (self.count != 0)\r
354         {\r
355                 if (activator.classname == "player"\r
356                 && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)\r
357                 {\r
358                         if (self.count >= 4)\r
359                                 centerprint (activator, "There are more to go...");\r
360                         else if (self.count == 3)\r
361                                 centerprint (activator, "Only 3 more to go...");\r
362                         else if (self.count == 2)\r
363                                 centerprint (activator, "Only 2 more to go...");\r
364                         else\r
365                                 centerprint (activator, "Only 1 more to go...");\r
366                 }\r
367                 return;\r
368         }\r
369 \r
370         if (activator.classname == "player"\r
371         && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)\r
372                 centerprint(activator, "Sequence completed!");\r
373         self.enemy = activator;\r
374         multi_trigger ();\r
375 };\r
376 \r
377 /*QUAKED trigger_counter (.5 .5 .5) ? nomessage\r
378 Acts as an intermediary for an action that takes multiple inputs.\r
379 \r
380 If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished.\r
381 \r
382 After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.\r
383 */\r
384 void() trigger_counter =\r
385 {\r
386         self.wait = -1;\r
387         if (!self.count)\r
388                 self.count = 2;\r
389 \r
390         self.use = counter_use;\r
391 };\r
392 \r
393 /*.float triggerhurttime;\r
394 void() hurt_touch =\r
395 {\r
396         if (other.takedamage)\r
397         if (other.triggerhurttime < time)\r
398         {\r
399                 other.triggerhurttime = time + 1;\r
400                 Damage (other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');\r
401         }\r
402 \r
403         return;\r
404 };*/\r
405 \r
406 /*QUAKED trigger_hurt (.5 .5 .5) ?\r
407 Any object touching this will be hurt\r
408 set dmg to damage amount\r
409 defalt dmg = 5\r
410 */\r
411 /*void() trigger_hurt =\r
412 {\r
413         InitTrigger ();\r
414         self.touch = hurt_touch;\r
415         if (!self.dmg)\r
416                 self.dmg = 1000;\r
417         if (!self.message)\r
418                 self.message = "was in the wrong place.";\r
419 };*/\r
420 \r
421 //void() target_speaker_use = {sound(self, CHAN_VOICE, self.noise, 1, 1);}\r
422 //void() target_speaker = {self.use = target_speaker_use;}\r
423 \r
424 void() target_speaker =\r
425 {\r
426 if(self.noise) {\r
427  precache_sound (self.noise);\r
428  ambientsound (self.origin, self.noise, 1, ATTN_STATIC);\r
429 }\r
430 //remove(self);\r
431 };\r
432 \r
433 \r
434 /*\r
435 void() sparksthink =\r
436 {\r
437   self.nextthink = time + 0.1;\r
438 \r
439   if(random() < self.wait) {\r
440     te_spark(self.origin,'0 0 -1',self.cnt);\r
441   }\r
442 }\r
443 \r
444 \r
445 void() func_sparks =\r
446 {\r
447   self.think = sparksthink;\r
448   self.nextthink = time + 0.2;\r
449 \r
450   // self.cnt is the amount of sparks that one burst will spawn\r
451   if(self.cnt < 1) {\r
452     self.cnt = 25.0; // nice default value\r
453   }\r
454 \r
455   // self.wait is the probability that a sparkthink will spawn a spark shower\r
456   // range: 0 - 1, but 0 makes little sense, so...\r
457   if(self.wait < 0.05) {\r
458     self.wait = 0.25; // nice default value\r
459   }\r
460 \r
461   // sound\r
462   if(self.noise) {\r
463     precache_sound (self.noise);\r
464     ambientsound (self.origin, self.noise, 1, ATTN_STATIC);\r
465   }\r
466 }\r
467 */\r
468 \r
469 \r
470 /*\r
471 =============================================================================\r
472 \r
473 SECRET DOORS\r
474 \r
475 =============================================================================\r
476 */\r
477 // Doors are in TFDOORS.C\r
478 /*void() fd_secret_move1;\r
479 void() fd_secret_move2;\r
480 void() fd_secret_move3;\r
481 void() fd_secret_move4;\r
482 void() fd_secret_move5;\r
483 void() fd_secret_move6;\r
484 void() fd_secret_done;\r
485 \r
486 float SECRET_OPEN_ONCE = 1;             // stays open\r
487 float SECRET_1ST_LEFT = 2;              // 1st move is left of arrow\r
488 float SECRET_1ST_DOWN = 4;              // 1st move is down from arrow\r
489 float SECRET_NO_SHOOT = 8;              // only opened by trigger\r
490 float SECRET_YES_SHOOT = 16;    // shootable even if targeted\r
491 \r
492 \r
493 void () fd_secret_use =\r
494 {\r
495         local float temp;\r
496 \r
497         self.health = 10000;\r
498         //self.havocattack = TRUE;\r
499 \r
500         // exit if still moving around...\r
501         if (self.origin != self.oldorigin)\r
502                 return;\r
503 \r
504         self.message = ""; // no more message\r
505 \r
506         SUB_UseTargets();                               // fire all targets / killtargets\r
507 \r
508         self.velocity = '0 0 0';\r
509 \r
510         // Make a sound, wait a little...\r
511 \r
512         if (self.noise1 != "")\r
513                 sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);\r
514         self.nextthink = self.ltime + 0.1;\r
515 \r
516         temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1\r
517         makevectors(self.mangle);\r
518 \r
519         if (!self.t_width)\r
520         {\r
521                 if (self.spawnflags & SECRET_1ST_DOWN)\r
522                         self.t_width = fabs(v_up * self.size);\r
523                 else\r
524                         self.t_width = fabs(v_right * self.size);\r
525         }\r
526 \r
527         if (!self.t_length)\r
528                 self.t_length = fabs(v_forward * self.size);\r
529 \r
530         if (self.spawnflags & SECRET_1ST_DOWN)\r
531                 self.dest1 = self.origin - v_up * self.t_width;\r
532         else\r
533                 self.dest1 = self.origin + v_right * (self.t_width * temp);\r
534 \r
535         self.dest2 = self.dest1 + v_forward * self.t_length;\r
536         SUB_CalcMove(self.dest1, self.speed, fd_secret_move1);\r
537         if (self.noise2 != "")\r
538                 sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);\r
539 };\r
540 \r
541 // Wait after first movement...\r
542 void () fd_secret_move1 =\r
543 {\r
544         self.nextthink = self.ltime + 1.0;\r
545         self.think = fd_secret_move2;\r
546         if (self.noise3 != "")\r
547                 sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);\r
548 };\r
549 \r
550 // Start moving sideways w/sound...\r
551 void () fd_secret_move2 =\r
552 {\r
553         if (self.noise2 != "")\r
554                 sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);\r
555         SUB_CalcMove(self.dest2, self.speed, fd_secret_move3);\r
556 };\r
557 \r
558 // Wait here until time to go back...\r
559 void () fd_secret_move3 =\r
560 {\r
561         if (self.noise3 != "")\r
562                 sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);\r
563         if (!(self.spawnflags & SECRET_OPEN_ONCE))\r
564         {\r
565                 self.nextthink = self.ltime + self.wait;\r
566                 self.think = fd_secret_move4;\r
567         }\r
568 };\r
569 \r
570 // Move backward...\r
571 void () fd_secret_move4 =\r
572 {\r
573         if (self.noise2 != "")\r
574                 sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);\r
575         SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);\r
576 };\r
577 \r
578 // Wait 1 second...\r
579 void () fd_secret_move5 =\r
580 {\r
581         self.nextthink = self.ltime + 1.0;\r
582         self.think = fd_secret_move6;\r
583         if (self.noise3 != "")\r
584                 sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);\r
585 };\r
586 \r
587 void () fd_secret_move6 =\r
588 {\r
589         if (self.noise2 != "")\r
590                 sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);\r
591         SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done);\r
592 };\r
593 \r
594 void () fd_secret_done =\r
595 {\r
596         if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT)\r
597         {\r
598                 self.health = 10000;\r
599                 self.takedamage = DAMAGE_YES;\r
600                 //self.th_pain = fd_secret_use;\r
601         }\r
602         if (self.noise3 != "")\r
603                 sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);\r
604 };\r
605 \r
606 void () secret_blocked =\r
607 {\r
608         if (time < self.attack_finished)\r
609                 return;\r
610         self.attack_finished = time + 0.5;\r
611         //T_Damage (other, self, self, self.dmg, self.dmg, self.deathtype, DT_IMPACT, (self.absmin + self.absmax) * 0.5, '0 0 0', Obituary_Generic);\r
612 };*/\r
613 \r
614 /*\r
615 ==============\r
616 secret_touch\r
617 \r
618 Prints messages\r
619 ================\r
620 */ // now in TFDOORS.C\r
621 /*void() secret_touch =\r
622 {\r
623         if (activator.classname != "player")\r
624                 return;\r
625         if (self.attack_finished > time)\r
626                 return;\r
627 \r
628         self.attack_finished = time + 2;\r
629 \r
630         if (self.message)\r
631         {\r
632                 if (other.flags & FL_CLIENT)\r
633                         centerprint (other, self.message);\r
634                 sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);\r
635         }\r
636 };*/\r
637 \r
638 \r
639 /*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot\r
640 Basic secret door. Slides back, then to the side. Angle determines direction.\r
641 wait  = # of seconds before coming back\r
642 1st_left = 1st move is left of arrow\r
643 1st_down = 1st move is down from arrow\r
644 always_shoot = even if targeted, keep shootable\r
645 t_width = override WIDTH to move back (or height if going down)\r
646 t_length = override LENGTH to move sideways\r
647 "dmg"           damage to inflict when blocked (2 default)\r
648 \r
649 If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.\r
650 "sounds"\r
651 1) medieval\r
652 2) metal\r
653 3) base\r
654 */\r
655 \r
656 /*void () func_door_secret =\r
657 {\r
658         /*if (!self.deathtype) // map makers can override this\r
659                 self.deathtype = " got in the way";*/\r
660 /*\r
661         if (!self.dmg)\r
662                 self.dmg = 2;\r
663 \r
664         // Magic formula...\r
665         self.mangle = self.angles;\r
666         self.angles = '0 0 0';\r
667         self.solid = SOLID_BSP;\r
668         self.movetype = MOVETYPE_PUSH;\r
669         self.classname = "door";\r
670         setmodel (self, self.model);\r
671         setorigin (self, self.origin);\r
672 \r
673         self.touch = secret_touch;\r
674         self.blocked = secret_blocked;\r
675         self.speed = 50;\r
676         self.use = fd_secret_use;\r
677         if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT)\r
678         {\r
679                 self.health = 10000;\r
680                 self.takedamage = DAMAGE_YES;\r
681                 self.event_damage = fd_secret_use;\r
682         }\r
683         self.oldorigin = self.origin;\r
684         if (!self.wait)\r
685                 self.wait = 5;          // 5 seconds before closing\r
686 };*/\r
687 \r
688 \r
689 // TF DOORS                     // MOVED THIS TO SEPERATE TF DOORS FILE\r
690 \r
691 // MOVE TO TFTRIGGERS\r
692 void() trigger_once = \r
693 {\r
694         if (CheckExistence() == TF_FLARE_LIT)\r
695         {\r
696                 dremove(self);\r
697                 return;\r
698         }\r
699         self.wait = -1;\r
700         trigger_multiple();\r
701 };\r
702 \r
703 void() hurt_on = \r
704 {\r
705         self.solid = TF_FLARE_OFF;\r
706         self.nextthink = -1;\r
707 };\r
708 \r
709 void() hurt_touch = \r
710 {\r
711         local entity te;\r
712         if (other.is_dead != 0)         // added by xavior to stop killing of dead bodies\r
713                 return;                                         ////\r
714         if (other.takedamage)\r
715         {\r
716                 if (!Activated(self, other))\r
717                 {\r
718                         if (self.else_goal != TF_FLARE_LIT)\r
719                         {\r
720                                 te = Findgoal(self.else_goal);\r
721                                 if (te)\r
722                                 {\r
723                                         DoResults(te, other, self.goal_result & 2);\r
724                                 }\r
725                         }\r
726                         return;\r
727                 }\r
728                 self.solid = TF_FLARE_LIT;\r
729                 deathmsg = 36;\r
730                 TF_T_Damage(other, self, self, self.dmg, TF_FLARE_OFF, TF_FLARE_LIT);\r
731                 self.think = hurt_on;\r
732                 self.nextthink = time + TF_FLARE_OFF;\r
733         }\r
734 };\r
735 \r
736 void() trigger_hurt = \r
737 {\r
738         if (self.allowteams == "red")           // Converted to work with q3f/ETF entities\r
739         {\r
740                 self.team_no = 2;\r
741                 self.owned_by = 2;\r
742         }\r
743         if (self.allowteams == "blue")\r
744         {\r
745                 self.owned_by = 1;\r
746                 self.team_no = 1;\r
747         }\r
748 \r
749         if (CheckExistence() == TF_FLARE_LIT)\r
750         {\r
751                 dremove(self);\r
752                 return;\r
753         }\r
754         InitTrigger();\r
755         self.touch = hurt_touch;\r
756         if (!(self.dmg))\r
757         {\r
758                 self.dmg = 5;\r
759         }\r
760 };\r
761 \r
762 \r
763 // TF SUBS\r
764 void () SUB_UseTargets =\r
765 {\r
766         local entity t;\r
767         local entity stemp;\r
768         local entity otemp;\r
769         local entity act;\r
770 \r
771         if (self.dont_do_triggerwork)\r
772         {\r
773                 self.dont_do_triggerwork = 0;\r
774                 return;\r
775         }\r
776         if (self.delay)\r
777         {\r
778                 t = spawn ();\r
779                 t.classname = "DelayedUse";\r
780                 t.nextthink = (time + self.delay);\r
781                 t.think = DelayThink;\r
782                 t.enemy = activator;\r
783                 t.message = self.message;\r
784                 t.killtarget = self.killtarget;\r
785                 t.target = self.target;\r
786                 return;\r
787         }\r
788         if (((activator.classname == "player") && (self.message != "")))\r
789         {\r
790                 CenterPrint (activator, self.message);\r
791                 if (!self.noise)\r
792                 {\r
793                         sound (activator, 2, "misc/talk.wav", 1, 1);\r
794                 }\r
795         }\r
796         if ((activator.classname == "player"))\r
797         {\r
798                 DoGroupWork (self, activator);\r
799                 DoGoalWork (self, activator);\r
800         }\r
801         if (self.killtarget)\r
802         {\r
803                 t = world;\r
804                 do\r
805                 {\r
806                         t = find (t, targetname, self.killtarget);\r
807                         if (!t)\r
808                         {\r
809                                 return;\r
810                         }\r
811                         remove (t);\r
812 \r
813                 } while (1);\r
814         }\r
815         if (self.target)\r
816         {\r
817                 act = activator;\r
818                 t = world;\r
819                 do\r
820                 {\r
821                         t = find (t, targetname, self.target);\r
822                         if (!t)\r
823                         {\r
824                                 return;\r
825                         }\r
826                         stemp = self;\r
827                         otemp = other;\r
828                         self = t;\r
829                         other = stemp;\r
830                         if ((self.use != SUB_Null))\r
831                         {\r
832                                 if (self.use)\r
833                                 {\r
834                                         self.use ();\r
835                                 }\r
836                         }\r
837                         self = stemp;\r
838                         other = otemp;\r
839                         activator = act;\r
840 \r
841                 } while (1);\r
842         }\r
843 };\r
844 \r