1 // NOTE: also contains trigger_once at bottom
4 // the wait time has passed, so set back up for another activation
5 void multi_wait(entity this)
9 this.health = this.max_health;
10 this.takedamage = DAMAGE_YES;
11 this.solid = SOLID_BBOX;
16 // the trigger was just touched/killed/used
17 // this.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(entity this)
21 if (this.nextthink > time)
23 return; // allready been triggered
26 if(this.spawnflags & 16384)
27 if(!IS_PLAYER(this.enemy))
28 return; // only players
30 if (this.classname == "trigger_secret")
32 if (!IS_PLAYER(this.enemy))
34 found_secrets = found_secrets + 1;
35 WriteByte (MSG_ALL, SVC_FOUNDSECRET);
39 _sound (this.enemy, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
41 // don't trigger again until reset
42 this.takedamage = DAMAGE_NO;
44 SUB_UseTargets(this, this.enemy, this.goalentity);
48 setthink(this, multi_wait);
49 this.nextthink = time + this.wait;
51 else if (this.wait == 0)
53 multi_wait(this); // waiting finished
56 { // we can't just remove (this) here, because this is a touch function
57 // called wheil C code is looping through area links...
58 settouch(this, func_null);
62 void multi_use(entity this, entity actor, entity trigger)
64 this.goalentity = trigger;
69 void multi_touch(entity this, entity toucher)
71 if(!(this.spawnflags & 2))
72 if(!toucher.iscreature)
76 if(((this.spawnflags & 4) == 0) == (this.team != toucher.team))
79 // if the trigger has an angles field, check player's facing direction
80 if (this.movedir != '0 0 0')
82 makevectors (toucher.angles);
83 if (v_forward * this.movedir < 0)
84 return; // not facing the right way
87 // if the trigger has pressed keys, check that the player is pressing those keys
89 if(IS_PLAYER(toucher)) // only for players
90 if(!(toucher.pressedkeys & this.pressedkeys))
93 EXACTTRIGGER_TOUCH(this, toucher);
96 this.goalentity = toucher;
100 void multi_eventdamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
104 if(this.spawnflags & DOOR_NOSPLASH)
105 if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
107 this.health = this.health - damage;
108 if (this.health <= 0)
110 this.enemy = attacker;
111 this.goalentity = inflictor;
116 void multi_reset(entity this)
118 if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
119 settouch(this, multi_touch);
122 this.health = this.max_health;
123 this.takedamage = DAMAGE_YES;
124 this.solid = SOLID_BBOX;
126 setthink(this, func_null);
128 this.team = this.team_saved;
131 /*QUAKED spawnfunc_trigger_multiple (.5 .5 .5) ? notouch
132 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.
133 If "delay" is set, the trigger waits some time after activating before firing.
134 "wait" : Seconds between triggerings. (.2 default)
135 If notouch is set, the trigger is only fired by other entities, not by touching.
136 NOTOUCH has been obsoleted by spawnfunc_trigger_relay!
142 set "message" to text string
144 spawnfunc(trigger_multiple)
146 this.reset = multi_reset;
147 if (this.sounds == 1)
148 this.noise = "misc/secret.wav";
149 else if (this.sounds == 2)
150 this.noise = strzone(SND(TALK));
151 else if (this.sounds == 3)
152 this.noise = "misc/trigger1.wav";
155 precache_sound(this.noise);
159 else if(this.wait < -1)
161 this.use = multi_use;
165 this.team_saved = this.team;
169 if (this.spawnflags & SPAWNFLAG_NOTOUCH)
170 objerror (this, "health and notouch don't make sense\n");
171 this.max_health = this.health;
172 this.event_damage = multi_eventdamage;
173 this.takedamage = DAMAGE_YES;
174 this.solid = SOLID_BBOX;
175 setorigin(this, this.origin); // make sure it links into the world
179 if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
181 settouch(this, multi_touch);
182 setorigin(this, this.origin); // make sure it links into the world
188 /*QUAKED spawnfunc_trigger_once (.5 .5 .5) ? notouch
189 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
190 "targetname". If "health" is set, the trigger must be killed to activate.
191 If notouch is set, the trigger is only fired by other entities, not by touching.
192 if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
193 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.
199 set "message" to text string
201 spawnfunc(trigger_once)
204 spawnfunc_trigger_multiple(this);