2 // NOTE: also contains trigger_once at bottom
5 // the wait time has passed, so set back up for another activation
6 void multi_wait(entity this)
10 this.health = this.max_health;
11 this.takedamage = DAMAGE_YES;
12 this.solid = SOLID_BBOX;
17 // the trigger was just touched/killed/used
18 // this.enemy should be set to the activator so it can be held through a delay
19 // so wait for the delay time before firing
20 void multi_trigger(entity this)
22 if (this.nextthink > time)
24 return; // allready been triggered
27 if(this.spawnflags & 16384)
28 if(!IS_PLAYER(this.enemy))
29 return; // only players
31 if (this.classname == "trigger_secret")
33 if (!IS_PLAYER(this.enemy))
35 found_secrets = found_secrets + 1;
36 WriteByte (MSG_ALL, SVC_FOUNDSECRET);
40 _sound (this.enemy, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
42 // don't trigger again until reset
43 this.takedamage = DAMAGE_NO;
45 SUB_UseTargets(this, this.enemy, this.goalentity);
49 setthink(this, multi_wait);
50 this.nextthink = time + this.wait;
52 else if (this.wait == 0)
54 multi_wait(this); // waiting finished
57 { // we can't just delete(this) here, because this is a touch function
58 // called while C code is looping through area links...
59 settouch(this, func_null);
63 void multi_use(entity this, entity actor, entity trigger)
65 this.goalentity = trigger;
70 void multi_touch(entity this, entity toucher)
72 if(!(this.spawnflags & 2))
73 if(!toucher.iscreature)
77 if(((this.spawnflags & 4) == 0) == (this.team != toucher.team))
80 // if the trigger has an angles field, check player's facing direction
81 if (this.movedir != '0 0 0')
83 makevectors (toucher.angles);
84 if (v_forward * this.movedir < 0)
85 return; // not facing the right way
88 // if the trigger has pressed keys, check that the player is pressing those keys
89 if(this.pressedkeys && IS_PLAYER(toucher)) // only for players
90 if(!(CS(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;
166 IL_PUSH(g_saved_team, this);
170 if (this.spawnflags & SPAWNFLAG_NOTOUCH)
171 objerror (this, "health and notouch don't make sense\n");
172 this.max_health = this.health;
173 this.event_damage = multi_eventdamage;
174 this.takedamage = DAMAGE_YES;
175 this.solid = SOLID_BBOX;
176 setorigin(this, this.origin); // make sure it links into the world
180 if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
182 settouch(this, multi_touch);
183 setorigin(this, this.origin); // make sure it links into the world
189 /*QUAKED spawnfunc_trigger_once (.5 .5 .5) ? notouch
190 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
191 "targetname". If "health" is set, the trigger must be killed to activate.
192 If notouch is set, the trigger is only fired by other entities, not by touching.
193 if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
194 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.
200 set "message" to text string
202 spawnfunc(trigger_once)
205 spawnfunc_trigger_multiple(this);