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, .entity weaponentity, vector hitloc, vector force)
104 if(this.spawnflags & DOOR_NOSPLASH)
105 if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
108 if(((this.spawnflags & 4) == 0) == (this.team != attacker.team))
110 this.health = this.health - damage;
111 if (this.health <= 0)
113 this.enemy = attacker;
114 this.goalentity = inflictor;
119 void multi_reset(entity this)
121 if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
122 settouch(this, multi_touch);
125 this.health = this.max_health;
126 this.takedamage = DAMAGE_YES;
127 this.solid = SOLID_BBOX;
129 setthink(this, func_null);
131 this.team = this.team_saved;
134 /*QUAKED spawnfunc_trigger_multiple (.5 .5 .5) ? notouch
135 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.
136 If "delay" is set, the trigger waits some time after activating before firing.
137 "wait" : Seconds between triggerings. (.2 default)
138 If notouch is set, the trigger is only fired by other entities, not by touching.
139 NOTOUCH has been obsoleted by spawnfunc_trigger_relay!
145 set "message" to text string
147 spawnfunc(trigger_multiple)
149 this.reset = multi_reset;
150 if (this.sounds == 1)
151 this.noise = "misc/secret.wav";
152 else if (this.sounds == 2)
153 this.noise = strzone(SND(TALK));
154 else if (this.sounds == 3)
155 this.noise = "misc/trigger1.wav";
158 precache_sound(this.noise);
162 else if(this.wait < -1)
164 this.use = multi_use;
168 this.team_saved = this.team;
169 IL_PUSH(g_saved_team, this);
173 if (this.spawnflags & SPAWNFLAG_NOTOUCH)
174 objerror (this, "health and notouch don't make sense\n");
175 this.canteamdamage = true;
176 this.max_health = this.health;
177 this.event_damage = multi_eventdamage;
178 this.takedamage = DAMAGE_YES;
179 this.solid = SOLID_BBOX;
180 setorigin(this, this.origin); // make sure it links into the world
184 if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
186 settouch(this, multi_touch);
187 setorigin(this, this.origin); // make sure it links into the world
193 /*QUAKED spawnfunc_trigger_once (.5 .5 .5) ? notouch
194 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
195 "targetname". If "health" is set, the trigger must be killed to activate.
196 If notouch is set, the trigger is only fired by other entities, not by touching.
197 if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
198 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.
204 set "message" to text string
206 spawnfunc(trigger_once)
209 spawnfunc_trigger_multiple(this);