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 remove (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
90 if(IS_PLAYER(toucher)) // only for players
91 if(!(toucher.pressedkeys & this.pressedkeys))
94 EXACTTRIGGER_TOUCH(this, toucher);
97 this.goalentity = toucher;
101 void multi_eventdamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
105 if(this.spawnflags & DOOR_NOSPLASH)
106 if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
108 this.health = this.health - damage;
109 if (this.health <= 0)
111 this.enemy = attacker;
112 this.goalentity = inflictor;
117 void multi_reset(entity this)
119 if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
120 settouch(this, multi_touch);
123 this.health = this.max_health;
124 this.takedamage = DAMAGE_YES;
125 this.solid = SOLID_BBOX;
127 setthink(this, func_null);
129 this.team = this.team_saved;
132 /*QUAKED spawnfunc_trigger_multiple (.5 .5 .5) ? notouch
133 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.
134 If "delay" is set, the trigger waits some time after activating before firing.
135 "wait" : Seconds between triggerings. (.2 default)
136 If notouch is set, the trigger is only fired by other entities, not by touching.
137 NOTOUCH has been obsoleted by spawnfunc_trigger_relay!
143 set "message" to text string
145 spawnfunc(trigger_multiple)
147 this.reset = multi_reset;
148 if (this.sounds == 1)
149 this.noise = "misc/secret.wav";
150 else if (this.sounds == 2)
151 this.noise = strzone(SND(TALK));
152 else if (this.sounds == 3)
153 this.noise = "misc/trigger1.wav";
156 precache_sound(this.noise);
160 else if(this.wait < -1)
162 this.use = multi_use;
166 this.team_saved = this.team;
167 IL_PUSH(g_saved_team, this);
171 if (this.spawnflags & SPAWNFLAG_NOTOUCH)
172 objerror (this, "health and notouch don't make sense\n");
173 this.max_health = this.health;
174 this.event_damage = multi_eventdamage;
175 this.takedamage = DAMAGE_YES;
176 this.solid = SOLID_BBOX;
177 setorigin(this, this.origin); // make sure it links into the world
181 if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
183 settouch(this, multi_touch);
184 setorigin(this, this.origin); // make sure it links into the world
190 /*QUAKED spawnfunc_trigger_once (.5 .5 .5) ? notouch
191 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
192 "targetname". If "health" is set, the trigger must be killed to activate.
193 If notouch is set, the trigger is only fired by other entities, not by touching.
194 if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
195 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.
201 set "message" to text string
203 spawnfunc(trigger_once)
206 spawnfunc_trigger_multiple(this);