2 void() SUB_UseTargets;
\r
6 activator = self.enemy;
\r
12 ==============================
\r
15 the global "activator" should be set to the entity that initiated the firing.
\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
20 Centerprints any self.message to the activator.
\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
25 Search for (string)targetname in all entities that
\r
26 match (string)self.target and call their .use function
\r
28 ==============================
\r
30 /*void() SUB_UseTargets =
\r
32 local entity t, stemp, otemp, act;
\r
35 // check for a delay
\r
39 // create a temp object to fire at a later time
\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
53 // print the message
\r
55 if (activator.classname == "player" && self.message != "")
\r
57 centerprint (activator, self.message);
\r
59 sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
\r
63 // kill the killtagets
\r
65 if (self.killtarget)
\r
70 t = find (t, targetname, self.killtarget);
\r
86 t = find (t, targetname, self.target);
\r
108 void() trigger_reactivate =
\r
110 self.solid = SOLID_TRIGGER;
\r
113 //=============================================================================
\r
115 float SPAWNFLAG_NOMESSAGE = 1;
\r
116 float SPAWNFLAG_NOTOUCH = 1;
\r
118 // the wait time has passed, so set back up for another activation
\r
119 void() multi_wait =
\r
121 if (self.max_health)
\r
123 self.health = self.max_health;
\r
124 self.takedamage = DAMAGE_YES;
\r
125 self.solid = SOLID_BBOX;
\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
135 if (self.nextthink > time)
\r
137 return; // allready been triggered
\r
140 if (self.classname == "trigger_secret")
\r
142 if (self.enemy.classname != "player")
\r
144 found_secrets = found_secrets + 1;
\r
145 WriteByte (MSG_ALL, SVC_FOUNDSECRET);
\r
149 sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
\r
151 // don't trigger again until reset
\r
152 self.takedamage = DAMAGE_NO;
\r
154 activator = self.enemy;
\r
160 self.think = multi_wait;
\r
161 self.nextthink = time + self.wait;
\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
168 self.nextthink = time + 0.1;
\r
169 self.think = SUB_Remove;
\r
173 void() multi_trigger =
\r
175 if (self.nextthink > time)
\r
179 if (self.classname == "trigger_secret")
\r
181 if (self.enemy.classname != "player")
\r
185 found_secrets = found_secrets + TF_FLARE_OFF;
\r
190 sound(self, 2, self.noise, TF_FLARE_OFF, TF_FLARE_OFF);
\r
192 self.takedamage = TF_FLARE_LIT;
\r
193 activator = self.enemy;
\r
195 if (self.wait > TF_FLARE_LIT)
\r
197 self.think = multi_wait;
\r
198 self.nextthink = time + self.wait;
\r
202 self.touch = SUB_Null;
\r
203 self.nextthink = time + 0.1;
\r
204 self.think = SUB_Remove;
\r
210 self.enemy = activator;
\r
214 void() multi_touch =
\r
216 if (other.classname != "player")
\r
219 // if the trigger has an angles field, check player's facing direction
\r
220 if (self.movedir != '0 0 0')
\r
222 makevectors (other.angles);
\r
223 if (v_forward * self.movedir < 0)
\r
224 return; // not facing the right way
\r
227 self.enemy = other;
\r
231 void multi_eventdamage (vector hitloc, float damage, entity inflictor, entity attacker, float deathtype)
\r
233 if (!self.takedamage)
\r
235 self.health = self.health - damage;
\r
236 if (self.health <= 0)
\r
238 self.enemy = attacker;
\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
254 set "message" to text string
\r
256 void (float tno) ConvertToGoal;
\r
257 void () CheckIfQ3FTrigger;
\r
258 void() trigger_multiple =
\r
260 /* if (CheckIfQ3FTrigger() == 1)
\r
265 if (CheckIfQ3FTrigger() == 2)
\r
270 CheckIfQ3FTrigger ();
\r
272 if (self.sounds == 1)
\r
274 precache_sound ("misc/secret.wav");
\r
275 self.noise = "misc/secret.wav";
\r
277 else if (self.sounds == 2)
\r
279 precache_sound ("misc/talk.wav");
\r
280 self.noise = "misc/talk.wav";
\r
282 else if (self.sounds == 3)
\r
284 precache_sound ("misc/trigger1.wav");
\r
285 self.noise = "misc/trigger1.wav";
\r
290 self.use = multi_use;
\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
306 if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) )
\r
308 self.touch = multi_touch;
\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
325 set "message" to text string
\r
327 /*void() trigger_once =
\r
330 trigger_multiple();
\r
333 //=============================================================================
\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
338 void() trigger_relay =
\r
340 self.use = SUB_UseTargets;
\r
344 //=============================================================================
\r
347 void() counter_use =
\r
349 self.count = self.count - 1;
\r
350 if (self.count < 0)
\r
353 if (self.count != 0)
\r
355 if (activator.classname == "player"
\r
356 && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
\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
365 centerprint (activator, "Only 1 more to go...");
\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
377 /*QUAKED trigger_counter (.5 .5 .5) ? nomessage
\r
378 Acts as an intermediary for an action that takes multiple inputs.
\r
380 If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished.
\r
382 After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
\r
384 void() trigger_counter =
\r
390 self.use = counter_use;
\r
393 .float triggerhurttime;
\r
394 /*void() hurt_touch =
\r
396 if (other.takedamage)
\r
397 if (other.triggerhurttime < time)
\r
399 other.triggerhurttime = time + 1;
\r
400 Damage (other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
\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
411 /*void() trigger_hurt =
\r
414 self.touch = hurt_touch;
\r
418 self.message = "was in the wrong place.";
\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
424 void() target_speaker =
\r
427 precache_sound (self.noise);
\r
428 ambientsound (self.origin, self.noise, 1, ATTN_STATIC);
\r
435 void() sparksthink =
\r
437 self.nextthink = time + 0.1;
\r
439 if(random() < self.wait) {
\r
440 te_spark(self.origin,'0 0 -1',self.cnt);
\r
445 void() func_sparks =
\r
447 self.think = sparksthink;
\r
448 self.nextthink = time + 0.2;
\r
450 // self.cnt is the amount of sparks that one burst will spawn
\r
452 self.cnt = 25.0; // nice default value
\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
463 precache_sound (self.noise);
\r
464 ambientsound (self.origin, self.noise, 1, ATTN_STATIC);
\r
471 =============================================================================
\r
475 =============================================================================
\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
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
493 void () fd_secret_use =
\r
497 self.health = 10000;
\r
498 //self.havocattack = TRUE;
\r
500 // exit if still moving around...
\r
501 if (self.origin != self.oldorigin)
\r
504 self.message = ""; // no more message
\r
506 SUB_UseTargets(); // fire all targets / killtargets
\r
508 self.velocity = '0 0 0';
\r
510 // Make a sound, wait a little...
\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
516 temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
\r
517 makevectors(self.mangle);
\r
521 if (self.spawnflags & SECRET_1ST_DOWN)
\r
522 self.t_width = fabs(v_up * self.size);
\r
524 self.t_width = fabs(v_right * self.size);
\r
527 if (!self.t_length)
\r
528 self.t_length = fabs(v_forward * self.size);
\r
530 if (self.spawnflags & SECRET_1ST_DOWN)
\r
531 self.dest1 = self.origin - v_up * self.t_width;
\r
533 self.dest1 = self.origin + v_right * (self.t_width * temp);
\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
541 // Wait after first movement...
\r
542 void () fd_secret_move1 =
\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
550 // Start moving sideways w/sound...
\r
551 void () fd_secret_move2 =
\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
558 // Wait here until time to go back...
\r
559 void () fd_secret_move3 =
\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
565 self.nextthink = self.ltime + self.wait;
\r
566 self.think = fd_secret_move4;
\r
570 // Move backward...
\r
571 void () fd_secret_move4 =
\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
578 // Wait 1 second...
\r
579 void () fd_secret_move5 =
\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
587 void () fd_secret_move6 =
\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
594 void () fd_secret_done =
\r
596 if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT)
\r
598 self.health = 10000;
\r
599 self.takedamage = DAMAGE_YES;
\r
600 //self.th_pain = fd_secret_use;
\r
602 if (self.noise3 != "")
\r
603 sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
\r
606 void () secret_blocked =
\r
608 if (time < self.attack_finished)
\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
621 void() secret_touch =
\r
623 if (activator.classname != "player")
\r
625 if (self.attack_finished > time)
\r
628 self.attack_finished = time + 2;
\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
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
649 If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
\r
656 void () func_door_secret =
\r
658 /*if (!self.deathtype) // map makers can override this
\r
659 self.deathtype = " got in the way";*/
\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
673 self.touch = secret_touch;
\r
674 self.blocked = secret_blocked;
\r
676 self.use = fd_secret_use;
\r
677 if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT)
\r
679 self.health = 10000;
\r
680 self.takedamage = DAMAGE_YES;
\r
681 self.event_damage = fd_secret_use;
\r
683 self.oldorigin = self.origin;
\r
685 self.wait = 5; // 5 seconds before closing
\r
689 // TF DOORS // SHOULD MOVE THIS TO SEPERATE TF DOORS FILE
\r
690 void() door_go_down;
\r
692 float() DoorShouldOpen;
\r
694 void() fd_secret_move1;
\r
695 void() fd_secret_move2;
\r
696 void() fd_secret_move3;
\r
697 void() fd_secret_move4;
\r
698 void() fd_secret_move5;
\r
699 void() fd_secret_move6;
\r
700 void() fd_secret_done;
\r
703 void() door_blocked =
\r
705 T_Damage(other, self, self, self.dmg);
\r
706 if (self.wait >= TF_FLARE_LIT)
\r
708 if (self.state == 3)
\r
719 void() door_hit_top =
\r
721 sound(self, 2, self.noise1, TF_FLARE_OFF, TF_FLARE_OFF);
\r
722 self.state = TF_FLARE_LIT;
\r
723 if (self.spawnflags & 32)
\r
727 self.think = door_go_down;
\r
728 self.nextthink = self.ltime + self.wait;
\r
731 void() door_hit_bottom =
\r
733 self.goal_state = 2;
\r
734 sound(self, 2, self.noise1, TF_FLARE_OFF, TF_FLARE_OFF);
\r
735 self.state = TF_FLARE_OFF;
\r
738 void() door_go_down =
\r
740 sound(self, 2, self.noise2, TF_FLARE_OFF, TF_FLARE_OFF);
\r
741 if (self.max_health)
\r
743 self.takedamage = TF_FLARE_OFF;
\r
744 self.health = self.max_health;
\r
747 SUB_CalcMove(self.pos1, self.speed, door_hit_bottom);
\r
750 void() door_go_up =
\r
752 if (self.state == 2)
\r
756 if (self.state == TF_FLARE_LIT)
\r
758 self.nextthink = self.ltime + self.wait;
\r
761 sound(self, 2, self.noise2, TF_FLARE_OFF, TF_FLARE_OFF);
\r
763 SUB_CalcMove(self.pos2, self.speed, door_hit_top);
\r
767 void() door_fire =
\r
769 local entity oself;
\r
770 local entity starte;
\r
771 if (self.owner != self)
\r
773 objerror("door_fire: self.owner != self");
\r
777 sound(self, 2, self.noise4, TF_FLARE_OFF, TF_FLARE_OFF);
\r
779 self.message = string_null;
\r
781 if (self.spawnflags & 32)
\r
783 if (self.state == 2 || self.state == TF_FLARE_LIT)
\r
790 } while (self != starte && self != world);
\r
800 } while (self != starte && self != world);
\r
806 if (other.classname == "info_tfgoal") // Doors by item_tfgoals in q3f maps werent working right
\r
807 { //so I added this as a temp fix.
\r
808 return; // Note: doors by info_tfgoals will react slower`
\r
810 local entity oself;
\r
812 self.owner.message = "";
\r
813 self.enemy.message = "";
\r
820 void() door_trigger_touch =
\r
823 if (other.health <= TF_FLARE_LIT)
\r
827 if (!Activated(self, other))
\r
829 if (self.else_goal != TF_FLARE_LIT)
\r
831 te = Findgoal(self.else_goal);
\r
834 DoResults(te, other, self.goal_result & 2);
\r
839 if (time < self.attack_finished)
\r
843 self.attack_finished = time + TF_FLARE_OFF;
\r
849 void() door_killed =
\r
851 local entity oself;
\r
854 self.health = self.max_health;
\r
855 self.takedamage = TF_FLARE_LIT;
\r
860 void() door_touch =
\r
863 if (other.classname != "player")
\r
867 if (self.owner.attack_finished > time)
\r
871 if (!Activated(self, other))
\r
873 if (self.else_goal != TF_FLARE_LIT)
\r
875 te = Findgoal(self.else_goal);
\r
878 DoResults(te, other, self.goal_result & 2);
\r
883 self.owner.attack_finished = time + 2;
\r
884 if (self.owner.message != "")
\r
886 CenterPrint(other, self.owner.message);
\r
887 sound(other, 2, "misc/talk.wav", TF_FLARE_OFF, TF_FLARE_OFF);
\r
893 if ((self.items & other.items) != self.items)
\r
895 if (self.owner.items == 131072)
\r
897 if (world.worldtype == 2)
\r
899 CenterPrint(other, "You need the silver keycard");
\r
900 sound(self, 2, self.noise3, TF_FLARE_OFF, TF_FLARE_OFF);
\r
904 if (world.worldtype == TF_FLARE_OFF)
\r
906 CenterPrint(other, "You need the silver runekey");
\r
907 sound(self, 2, self.noise3, TF_FLARE_OFF, TF_FLARE_OFF);
\r
911 if (world.worldtype == TF_FLARE_LIT)
\r
913 CenterPrint(other, "You need the silver key");
\r
914 sound(self, 2, self.noise3, TF_FLARE_OFF, TF_FLARE_OFF);
\r
921 if (world.worldtype == 2)
\r
923 CenterPrint(other, "You need the gold keycard\n");
\r
924 sound(self, 2, self.noise3, TF_FLARE_OFF, TF_FLARE_OFF);
\r
928 if (world.worldtype == TF_FLARE_OFF)
\r
930 CenterPrint(other, "You need the gold runekey");
\r
931 sound(self, 2, self.noise3, TF_FLARE_OFF, TF_FLARE_OFF);
\r
935 if (world.worldtype == TF_FLARE_LIT)
\r
937 CenterPrint(other, "You need the gold key");
\r
938 sound(self, 2, self.noise3, TF_FLARE_OFF, TF_FLARE_OFF);
\r
945 other.items = other.items - self.items;
\r
946 other.tf_items = other.tf_items | self.items;
\r
947 if (DoorShouldOpen())
\r
949 self.touch = SUB_Null;
\r
952 self.enemy.touch = SUB_Null;
\r
958 entity(vector fmins, vector fmaxs) spawn_field =
\r
960 local entity trigger;
\r
964 trigger.movetype = TF_FLARE_LIT;
\r
965 trigger.solid = TF_FLARE_OFF;
\r
966 trigger.owner = self;
\r
967 trigger.touch = door_trigger_touch;
\r
968 trigger.team_no = self.team_no;
\r
969 trigger.playerclass = self.playerclass;
\r
970 trigger.items_allowed = self.items_allowed;
\r
971 trigger.activate_goal_no = self.activate_goal_no;
\r
972 trigger.inactivate_goal_no = self.inactivate_goal_no;
\r
973 trigger.remove_goal_no = self.remove_goal_no;
\r
974 trigger.restore_goal_no = self.restore_goal_no;
\r
975 trigger.activate_group_no = self.activate_group_no;
\r
976 trigger.inactivate_group_no = self.inactivate_group_no;
\r
977 trigger.remove_group_no = self.remove_group_no;
\r
978 trigger.restore_group_no = self.restore_group_no;
\r
979 trigger.goal_activation = self.goal_activation;
\r
980 trigger.goal_effects = self.goal_effects;
\r
981 trigger.goal_result = self.goal_result;
\r
982 trigger.goal_group = self.goal_group;
\r
985 setsize(trigger, t1 - '60 60 8', t2 + '60 60 8');
\r
989 float(entity e1, entity e2) EntitiesTouching =
\r
991 if (e1.mins_x > e2.maxs_x)
\r
993 return TF_FLARE_LIT;
\r
995 if (e1.mins_y > e2.maxs_y)
\r
997 return TF_FLARE_LIT;
\r
999 if (e1.mins_z > e2.maxs_z)
\r
1001 return TF_FLARE_LIT;
\r
1003 if (e1.maxs_x < e2.mins_x)
\r
1005 return TF_FLARE_LIT;
\r
1007 if (e1.maxs_y < e2.mins_y)
\r
1009 return TF_FLARE_LIT;
\r
1011 if (e1.maxs_z < e2.mins_z)
\r
1013 return TF_FLARE_LIT;
\r
1015 return TF_FLARE_OFF;
\r
1018 void() LinkDoors =
\r
1021 local entity starte;
\r
1022 local vector cmins;
\r
1023 local vector cmaxs;
\r
1028 if (self.spawnflags & 4)
\r
1030 self.enemy = self;
\r
1031 self.owner = self;
\r
1034 cmins = self.mins;
\r
1035 cmaxs = self.maxs;
\r
1040 self.owner = starte;
\r
1043 starte.health = self.health;
\r
1045 if (self.targetname)
\r
1047 starte.targetname = self.targetname;
\r
1049 if (self.message != "")
\r
1051 starte.message = self.message;
\r
1053 t = find(t, classname, self.classname);
\r
1056 self.enemy = starte;
\r
1057 self = self.owner;
\r
1062 if (self.targetname)
\r
1070 self.owner.trigger_field = spawn_field(cmins, cmaxs);
\r
1073 if (EntitiesTouching(self, t))
\r
1077 objerror("cross connected doors");
\r
1081 if (t.mins_x < cmins_x)
\r
1083 cmins_x = t.mins_x;
\r
1085 if (t.mins_y < cmins_y)
\r
1087 cmins_y = t.mins_y;
\r
1089 if (t.mins_z < cmins_z)
\r
1091 cmins_z = t.mins_z;
\r
1093 if (t.maxs_x > cmaxs_x)
\r
1095 cmaxs_x = t.maxs_x;
\r
1097 if (t.maxs_y > cmaxs_y)
\r
1099 cmaxs_y = t.maxs_y;
\r
1101 if (t.maxs_z > cmaxs_z)
\r
1103 cmaxs_z = t.maxs_z;
\r
1106 } while (TF_FLARE_OFF);
\r
1109 void() func_door =
\r
1111 if (CheckExistence() == TF_FLARE_LIT)
\r
1117 // Q3F/ETF Map Support
\r
1118 if (self.allowteams == "red")
\r
1122 if (self.allowteams == "blue")
\r
1127 if (world.worldtype == TF_FLARE_LIT)
\r
1129 precache_sound("doors/medtry.wav");
\r
1130 precache_sound("doors/meduse.wav");
\r
1131 self.noise3 = "doors/medtry.wav";
\r
1132 self.noise4 = "doors/meduse.wav";
\r
1136 if (world.worldtype == TF_FLARE_OFF)
\r
1138 precache_sound("doors/runetry.wav");
\r
1139 precache_sound("doors/runeuse.wav");
\r
1140 self.noise3 = "doors/runetry.wav";
\r
1141 self.noise4 = "doors/runeuse.wav";
\r
1145 if (world.worldtype == 2)
\r
1147 precache_sound("doors/basetry.wav");
\r
1148 precache_sound("doors/baseuse.wav");
\r
1149 self.noise3 = "doors/basetry.wav";
\r
1150 self.noise4 = "doors/baseuse.wav";
\r
1154 dprint("no worldtype set!\n");
\r
1158 if (self.sounds == TF_FLARE_LIT)
\r
1160 precache_sound("misc/null.wav");
\r
1161 precache_sound("misc/null.wav");
\r
1162 self.noise1 = "misc/null.wav";
\r
1163 self.noise2 = "misc/null.wav";
\r
1165 if (self.sounds == TF_FLARE_OFF)
\r
1167 precache_sound("doors/drclos4.wav");
\r
1168 precache_sound("doors/doormv1.wav");
\r
1169 self.noise1 = "doors/drclos4.wav";
\r
1170 self.noise2 = "doors/doormv1.wav";
\r
1172 if (self.sounds == 2)
\r
1174 precache_sound("doors/hydro1.wav");
\r
1175 precache_sound("doors/hydro2.wav");
\r
1176 self.noise2 = "doors/hydro1.wav";
\r
1177 self.noise1 = "doors/hydro2.wav";
\r
1179 if (self.sounds == 3)
\r
1181 precache_sound("doors/stndr1.wav");
\r
1182 precache_sound("doors/stndr2.wav");
\r
1183 self.noise2 = "doors/stndr1.wav";
\r
1184 self.noise1 = "doors/stndr2.wav";
\r
1186 if (self.sounds == 4)
\r
1188 precache_sound("doors/ddoor1.wav");
\r
1189 precache_sound("doors/ddoor2.wav");
\r
1190 self.noise1 = "doors/ddoor2.wav";
\r
1191 self.noise2 = "doors/ddoor1.wav";
\r
1193 if (self.armorclass == TF_FLARE_OFF)
\r
1195 precache_sound("doors/creekdr1.wav");
\r
1196 precache_sound("doors/creekdr2.wav");
\r
1197 self.noise2 = "doors/creekdr1.wav";
\r
1198 self.noise1 = "doors/creekdr2.wav";
\r
1200 if (self.armorclass == 2)
\r
1202 precache_sound("doors/metaldr1.wav");
\r
1203 precache_sound("doors/metaldr2.wav");
\r
1204 self.noise2 = "doors/metaldr1.wav";
\r
1205 self.noise1 = "doors/metaldr2.wav";
\r
1207 if (self.armorclass == 3)
\r
1209 precache_sound("doors/electdr1.wav");
\r
1210 precache_sound("doors/electdr2.wav");
\r
1211 self.noise2 = "doors/electdr1.wav";
\r
1212 self.noise1 = "doors/electdr2.wav";
\r
1214 if (self.armorclass == 4)
\r
1216 precache_sound("doors/track_st.wav");
\r
1217 precache_sound("doors/track_e.wav");
\r
1218 self.noise2 = "doors/track_st.wav";
\r
1219 self.noise1 = "doors/track_e.wav";
\r
1222 self.max_health = self.health;
\r
1224 self.movetype = 7;
\r
1225 setorigin(self, self.origin);
\r
1226 setmodel(self, self.model);
\r
1227 self.classname = "door";
\r
1228 self.blocked = door_blocked;
\r
1229 self.use = door_use;
\r
1230 if (self.spawnflags & 16)
\r
1232 self.items = 131072;
\r
1234 if (self.spawnflags & 8)
\r
1236 self.items = 262144;
\r
1238 if (!(self.speed))
\r
1254 self.pos1 = self.origin;
\r
1255 self.pos2 = self.pos1 + self.movedir * (fabs(self.movedir * self.size) - self.lip);
\r
1256 if (self.spawnflags & TF_FLARE_OFF)
\r
1258 setorigin(self, self.pos2);
\r
1259 self.pos2 = self.pos1;
\r
1260 self.pos1 = self.origin;
\r
1262 self.state = TF_FLARE_OFF;
\r
1265 self.takedamage = TF_FLARE_OFF;
\r
1266 self.th_die = door_killed;
\r
1272 self.touch = door_touch;
\r
1273 self.think = LinkDoors;
\r
1274 self.nextthink = self.ltime + 0.1;
\r
1277 // MOVE TO TFTRIGGERS
\r
1278 void() trigger_once =
\r
1280 if (CheckExistence() == TF_FLARE_LIT)
\r
1286 trigger_multiple();
\r
1291 self.solid = TF_FLARE_OFF;
\r
1292 self.nextthink = -1;
\r
1295 void() hurt_touch =
\r
1298 if (other.is_dead != 0) // added by xavior to stop killing of dead bodies
\r
1300 if (other.takedamage)
\r
1302 if (!Activated(self, other))
\r
1304 if (self.else_goal != TF_FLARE_LIT)
\r
1306 te = Findgoal(self.else_goal);
\r
1309 DoResults(te, other, self.goal_result & 2);
\r
1314 self.solid = TF_FLARE_LIT;
\r
1316 TF_T_Damage(other, self, self, self.dmg, TF_FLARE_OFF, TF_FLARE_LIT);
\r
1317 self.think = hurt_on;
\r
1318 self.nextthink = time + TF_FLARE_OFF;
\r
1322 void() trigger_hurt =
\r
1324 if (self.allowteams == "red") // Converted to work with q3f/ETF entities
\r
1327 self.owned_by = 2;
\r
1329 if (self.allowteams == "blue")
\r
1331 self.owned_by = 1;
\r
1335 if (CheckExistence() == TF_FLARE_LIT)
\r
1341 self.touch = hurt_touch;
\r
1350 void () SUB_UseTargets =
\r
1353 local entity stemp;
\r
1354 local entity otemp;
\r
1357 if (self.dont_do_triggerwork)
\r
1359 self.dont_do_triggerwork = 0;
\r
1365 t.classname = "DelayedUse";
\r
1366 t.nextthink = (time + self.delay);
\r
1367 t.think = DelayThink;
\r
1368 t.enemy = activator;
\r
1369 t.message = self.message;
\r
1370 t.killtarget = self.killtarget;
\r
1371 t.target = self.target;
\r
1374 if (((activator.classname == "player") && (self.message != "")))
\r
1376 CenterPrint (activator, self.message);
\r
1379 sound (activator, 2, "misc/talk.wav", 1, 1);
\r
1382 if ((activator.classname == "player"))
\r
1384 DoGroupWork (self, activator);
\r
1385 DoGoalWork (self, activator);
\r
1387 if (self.killtarget)
\r
1392 t = find (t, targetname, self.killtarget);
\r
1407 t = find (t, targetname, self.target);
\r
1416 if ((self.use != SUB_Null))
\r