Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
multi.qc
Go to the documentation of this file.
1#include "multi.qh"
2// NOTE: also contains trigger_once at bottom
3
4#ifdef SVQC
5// the wait time has passed, so set back up for another activation
6void multi_wait(entity this)
7{
8 if (this.max_health)
9 {
10 SetResourceExplicit(this, RES_HEALTH, this.max_health);
12 this.solid = SOLID_BBOX;
13 }
14}
15
16
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
21{
22 if (this.nextthink > time)
23 {
24 return; // allready been triggered
25 }
26
27 if((this.spawnflags & ONLY_PLAYERS) && !IS_PLAYER(this.enemy))
28 {
29 return; // only players
30 }
31
32 if (this.noise && this.noise != "")
33 {
35 }
36
37 // don't trigger again until reset
38 this.takedamage = DAMAGE_NO;
39
40 SUB_UseTargets(this, this.enemy, this.goalentity);
41
42 if (this.wait > 0)
43 {
44 setthink(this, multi_wait);
45 this.nextthink = time + this.wait;
46 }
47 else if (this.wait == 0)
48 {
49 multi_wait(this); // waiting finished
50 }
51 else
52 { // we can't just delete(this) here, because this is a touch function
53 // called while C code is looping through area links...
54 settouch(this, func_null);
55 this.use = func_null;
56 }
57}
58
59void multi_use(entity this, entity actor, entity trigger)
60{
61 this.goalentity = trigger;
62 this.enemy = actor;
63 multi_trigger(this);
64}
65
67{
68 if(!(this.spawnflags & ALL_ENTITIES) && !toucher.iscreature)
69 {
70 return;
71 }
72
73 if(this.team)
74 {
75 if(((this.spawnflags & INVERT_TEAMS) == 0) == (this.team != toucher.team))
76 {
77 return;
78 }
79 }
80
81 // if the trigger has an angles field, check player's facing direction
82 if (this.movedir != '0 0 0')
83 {
84 makevectors (toucher.angles);
85 if (v_forward * this.movedir < 0)
86 return; // not facing the right way
87 }
88
89 // if the trigger has pressed keys, check that the player is pressing those keys
90 if(this.pressedkeys && IS_PLAYER(toucher)) // only for players
91 {
92 if(!(CS(toucher).pressedkeys & this.pressedkeys))
93 {
94 return;
95 }
96 }
97
99
100 this.enemy = toucher;
101 this.goalentity = toucher;
102 multi_trigger(this);
103}
104
105void multi_eventdamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
106{
107 if(!this.takedamage)
108 return;
109 if(this.spawnflags & NOSPLASH)
110 if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
111 return;
112 if(this.team)
113 if(((this.spawnflags & INVERT_TEAMS) == 0) == (this.team != attacker.team))
114 return;
115 TakeResource(this, RES_HEALTH, damage);
116 if (GetResource(this, RES_HEALTH) <= 0)
117 {
118 this.enemy = attacker;
119 this.goalentity = inflictor;
120 multi_trigger(this);
121 }
122}
123
125{
126 if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
127 settouch(this, multi_touch);
128 if (this.max_health)
129 {
130 SetResourceExplicit(this, RES_HEALTH, this.max_health);
131 this.takedamage = DAMAGE_YES;
132 this.solid = SOLID_BBOX;
133 }
134 setthink(this, func_null);
135 this.nextthink = 0;
136 this.team = this.team_saved;
137 this.use = multi_use;
138}
139
140/*QUAKED spawnfunc_trigger_multiple (.5 .5 .5) ? notouch
141Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time.
142If "delay" is set, the trigger waits some time after activating before firing.
143"wait" : Seconds between triggerings. (.2 default)
144If notouch is set, the trigger is only fired by other entities, not by touching.
145NOTOUCH has been obsoleted by spawnfunc_trigger_relay!
146sounds
1471) secret
1482) beep beep
1493) large switch
1504)
151set "message" to text string
152*/
153spawnfunc(trigger_multiple)
154{
155 this.reset = multi_reset;
156 if (this.sounds == 1)
157 this.noise = "misc/secret.wav";
158 else if (this.sounds == 2)
159 this.noise = strzone(SND(TALK));
160 else if (this.sounds == 3)
161 this.noise = "misc/trigger1.wav";
162
163 if(this.noise && this.noise != "")
164 precache_sound(this.noise);
165
166 if (!this.wait)
167 this.wait = 0.2;
168 else if(this.wait < -1)
169 this.wait = 0;
170 this.use = multi_use;
171
172 if(this.wait == -1 && (q3compat & Q3COMPAT_DEFI))
173 this.wait = 0.1; // compatibility for q3df: "instant" return
174
176
177 this.team_saved = this.team;
178 IL_PUSH(g_saved_team, this);
179
180 if (GetResource(this, RES_HEALTH))
181 {
182 if (this.spawnflags & SPAWNFLAG_NOTOUCH)
183 objerror (this, "health and notouch don't make sense\n");
184 this.canteamdamage = true;
185 this.max_health = GetResource(this, RES_HEALTH);
186 this.event_damage = multi_eventdamage;
187 this.takedamage = DAMAGE_YES;
188 this.solid = SOLID_BBOX;
189 setorigin(this, this.origin); // make sure it links into the world
190 }
191 else
192 {
193 if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
194 {
195 settouch(this, multi_touch);
196 setorigin(this, this.origin); // make sure it links into the world
197 }
198 }
199}
200
201
202/*QUAKED spawnfunc_trigger_once (.5 .5 .5) ? notouch
203Variable 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
204"targetname". If "health" is set, the trigger must be killed to activate.
205If notouch is set, the trigger is only fired by other entities, not by touching.
206if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
207if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0.
208sounds
2091) secret
2102) beep beep
2113) large switch
2124)
213set "message" to text string
214*/
215spawnfunc(trigger_once)
216{
217 this.wait = -1;
218 spawnfunc_trigger_multiple(this);
219}
220#endif
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float max_health
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
float wait
Definition items.qc:17
int team
Definition main.qh:188
int spawnflags
Definition ammo.qh:15
#define IS_PLAYER(s)
Definition player.qh:243
const float SOLID_BBOX
float time
float nextthink
vector v_forward
vector origin
#define use
bool canteamdamage
Definition damage.qh:65
#define DEATH_ISSPECIAL(t)
Definition all.qh:39
const int HITTYPE_SPLASH
Definition all.qh:30
const int INVERT_TEAMS
Definition defs.qh:10
const int ALL_ENTITIES
Definition defs.qh:8
const int ONLY_PLAYERS
Definition defs.qh:13
const int NOSPLASH
Definition defs.qh:12
const int SPAWNFLAG_NOTOUCH
Definition defs.qh:17
solid
Definition ent_cs.qc:165
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
void SUB_UseTargets(entity this, entity actor, entity trigger)
Definition triggers.qc:344
#define EXACTTRIGGER_TOUCH(e, t)
Definition common.qh:115
#define EXACTTRIGGER_INIT
Definition common.qh:116
entity goalentity
Definition viewloc.qh:16
vector movedir
Definition viewloc.qh:18
string precache_sound(string sample)
string strzone(string s)
void multi_use(entity this, entity actor, entity trigger)
Definition multi.qc:59
void multi_trigger(entity this)
Definition multi.qc:20
void multi_reset(entity this)
Definition multi.qc:124
void multi_eventdamage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition multi.qc:105
void multi_touch(entity this, entity toucher)
Definition multi.qc:66
void multi_wait(entity this)
Definition multi.qc:6
var void func_null()
#define makevectors
Definition post.qh:21
#define objerror
Definition pre.qh:8
q3compat
Definition quake3.qc:59
#define Q3COMPAT_DEFI
Definition quake3.qh:5
#define setthink(e, f)
vector
Definition self.qh:92
entity entity toucher
Definition self.qh:72
#define settouch(e, f)
Definition self.qh:73
IntrusiveList g_saved_team
Definition vote.qh:79
int team_saved
Definition vote.qh:70
const int CH_TRIGGER
Definition sound.qh:12
const float VOL_BASE
Definition sound.qh:36
#define _sound(e, c, s, v, a)
Definition sound.qh:43
const float ATTEN_NORM
Definition sound.qh:30
#define SND(id)
Definition all.qh:35
#define spawnfunc(id)
Definition spawnfunc.qh:96
ClientState CS(Client this)
Definition state.qh:47
string noise
Definition subs.qh:83
const int DAMAGE_YES
Definition subs.qh:80
const int DAMAGE_NO
Definition subs.qh:79
float sounds
Definition subs.qh:42
float takedamage
Definition subs.qh:78
entity enemy
Definition sv_ctf.qh:153
int pressedkeys