Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
multi.qc File Reference
#include "multi.qh"
Include dependency graph for multi.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void multi_eventdamage (entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
void multi_reset (entity this)
void multi_touch (entity this, entity toucher)
void multi_trigger (entity this, bool exacttrigger)
void multi_use (entity this, entity actor, entity trigger)
void multi_wait (entity this)
 spawnfunc (trigger_multiple)
 spawnfunc (trigger_once)

Variables

int triggertimes

Function Documentation

◆ multi_eventdamage()

void multi_eventdamage ( entity this,
entity inflictor,
entity attacker,
float damage,
int deathtype,
.entity weaponentity,
vector hitloc,
vector force )

Definition at line 148 of file multi.qc.

149{
150 if(!this.takedamage)
151 return;
152 if(this.spawnflags & NOSPLASH)
153 if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
154 return;
155 if(this.team)
156 if(((this.spawnflags & INVERT_TEAMS) == 0) == (this.team != attacker.team))
157 return;
158 TakeResource(this, RES_HEALTH, damage);
159 if (GetResource(this, RES_HEALTH) <= 0)
160 {
161 this.enemy = attacker;
162 this.goalentity = inflictor;
163 multi_trigger(this, false);
164 }
165}
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.
int team
Definition main.qh:188
int spawnflags
Definition ammo.qh:15
#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 NOSPLASH
Definition defs.qh:12
entity goalentity
Definition viewloc.qh:16
void multi_trigger(entity this, bool exacttrigger)
Definition multi.qc:22
float takedamage
Definition subs.qh:78
entity enemy
Definition sv_ctf.qh:153

References DEATH_ISSPECIAL, enemy, entity(), GetResource(), goalentity, HITTYPE_SPLASH, INVERT_TEAMS, multi_trigger(), NOSPLASH, spawnflags, takedamage, TakeResource(), team, and vector.

Referenced by spawnfunc().

◆ multi_reset()

void multi_reset ( entity this)

Definition at line 167 of file multi.qc.

168{
169 if (q3compat || !(this.spawnflags & SPAWNFLAG_NOTOUCH))
170 settouch(this, multi_touch);
171 if (this.max_health)
172 {
173 SetResourceExplicit(this, RES_HEALTH, this.max_health);
174 this.takedamage = DAMAGE_YES;
175 this.solid = SOLID_BBOX;
176 }
177 setthink(this, func_null);
178 this.nextthink = 0;
179 this.team = this.team_saved;
180 this.use = multi_use;
181}
float max_health
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
const float SOLID_BBOX
float nextthink
#define use
const int SPAWNFLAG_NOTOUCH
Definition defs.qh:17
solid
Definition ent_cs.qc:165
void multi_use(entity this, entity actor, entity trigger)
Definition multi.qc:96
void multi_touch(entity this, entity toucher)
Definition multi.qc:103
var void func_null()
q3compat
Definition quake3.qc:59
#define setthink(e, f)
#define settouch(e, f)
Definition self.qh:73
int team_saved
Definition vote.qh:70
const int DAMAGE_YES
Definition subs.qh:80

References DAMAGE_YES, entity(), func_null(), max_health, multi_touch(), multi_use(), nextthink, q3compat, SetResourceExplicit(), setthink, settouch, solid, SOLID_BBOX, SPAWNFLAG_NOTOUCH, spawnflags, takedamage, team, team_saved, and use.

Referenced by spawnfunc().

◆ multi_touch()

void multi_touch ( entity this,
entity toucher )

Definition at line 103 of file multi.qc.

104{
105 if(!q3compat && !(this.spawnflags & ALL_ENTITIES) && !toucher.iscreature)
106 {
107 return;
108 }
109
110 if (q3compat && AVAILABLE_TEAMS == 2)
111 {
112 // This feature isn't mentioned in entities.def but it's in the source.
113 // Xonotic has given these spawnflags other meanings.
114 if(((this.spawnflags & 1) && toucher.team != NUM_TEAM_1) // not on red
115 || ((this.spawnflags & 2) && toucher.team != NUM_TEAM_2)) // not on blue
116 return;
117 }
118 else if (this.team)
119 {
120 if(((this.spawnflags & INVERT_TEAMS) == 0) == (this.team != toucher.team))
121 {
122 return;
123 }
124 }
125
126 // if the trigger has an angles field, check player's facing direction
127 if (this.movedir != '0 0 0')
128 {
129 makevectors (toucher.angles);
130 if (v_forward * this.movedir < 0)
131 return; // not facing the right way
132 }
133
134 // if the trigger has pressed keys, check that the player is pressing those keys
135 if(this.pressedkeys && IS_PLAYER(toucher)) // only for players
136 {
137 if(!(CS(toucher).pressedkeys & this.pressedkeys))
138 {
139 return;
140 }
141 }
142
143 this.enemy = toucher;
144 this.goalentity = toucher;
145 multi_trigger(this, true);
146}
#define IS_PLAYER(s)
Definition player.qh:242
vector v_forward
const int ALL_ENTITIES
Definition defs.qh:8
vector movedir
Definition viewloc.qh:18
#define makevectors
Definition post.qh:21
#define AVAILABLE_TEAMS
entity entity toucher
Definition self.qh:72
ClientState CS(Client this)
Definition state.qh:47
int pressedkeys
const int NUM_TEAM_2
Definition teams.qh:14
const int NUM_TEAM_1
Definition teams.qh:13

References ALL_ENTITIES, AVAILABLE_TEAMS, CS(), enemy, entity(), goalentity, INVERT_TEAMS, IS_PLAYER, makevectors, movedir, multi_trigger(), NUM_TEAM_1, NUM_TEAM_2, pressedkeys, q3compat, spawnflags, team, toucher, and v_forward.

Referenced by multi_reset(), and spawnfunc().

◆ multi_trigger()

void multi_trigger ( entity this,
bool exacttrigger )

Definition at line 22 of file multi.qc.

23{
24 if((this.spawnflags & ONLY_PLAYERS) && !IS_PLAYER(this.enemy))
25 {
26 return; // only players
27 }
28
29 // In Q3 .wait <= 0 is forever,
30 // in Xonotic .wait == -1 means forever and == -2 means don't wait at all.
31 if (IS_GAMETYPE(CTS) && IS_CLIENT(this.enemy))
32 {
33 // check the client-specific trigger time
34 int cnum = etof(this.enemy);
35 if (buf_getsize(this.triggertimes) >= cnum) // buffer slot exists
36 {
37 float triggertime = stof(bufstr_get(this.triggertimes, cnum - 1));
38 if (this.enemy.spawn_time <= triggertime) // havn't respawned since triggering
39 {
40 if ((this.wait <= 0 && (q3compat || this.wait >= -1)) // wait forever (until respawn in CTS)
41 || triggertime + this.wait > time) // too soon
42 return;
43 }
44 }
45 }
46 else if (this.nextthink > time)
47 return; // allready been triggered
48
49 if (exacttrigger)
50 EXACTTRIGGER_TOUCH(this, this.enemy);
51
52 if (this.noise && this.noise != "")
53 {
55 }
56
57 // don't trigger again until reset
58 this.takedamage = DAMAGE_NO;
59
60 SUB_UseTargets(this, this.enemy, this.goalentity);
61
62 if (IS_GAMETYPE(CTS) && IS_CLIENT(this.enemy))
63 {
64 // store the client-specific trigger time
65 string triggertime = sprintf("%15.14g", time); // 16b, perfect precision until timelimit_max @ <= 512hz (32768 sec)
66 int cnum = etof(this.enemy);
67 int bsize = buf_getsize(this.triggertimes);
68 if (bsize >= cnum) // already got a slot
69 bufstr_set(this.triggertimes, cnum - 1, triggertime);
70 else while (bsize < cnum) // create any lower numbered slots too
71 bufstr_add(this.triggertimes, (++bsize == cnum ? triggertime : "0"), true);
72 }
73 else if (this.wait > 0)
74 {
75 setthink(this, multi_wait);
76 this.nextthink = time + this.wait;
77 }
78 else if (this.wait < -1 && !q3compat) // xon maps only: no waiting
79 {
80 multi_wait(this); // waiting finished
81 }
82 else
83 {
84 if (IS_GAMETYPE(CTS)) // client-specific .wait timers
85 this.nextthink = stof("inf"); // clients can trigger again after respawning, disabled for other touchers
86 else
87 {
88 // we can't just delete(this) here, because this is a touch function
89 // called while C code is looping through area links...
90 settouch(this, func_null);
91 this.use = func_null;
92 }
93 }
94}
float wait
Definition items.qc:17
#define IS_CLIENT(s)
Definition player.qh:241
float time
const int ONLY_PLAYERS
Definition defs.qh:13
void SUB_UseTargets(entity this, entity actor, entity trigger)
Definition triggers.qc:344
#define EXACTTRIGGER_TOUCH(e, t)
Definition common.qh:115
float stof(string val,...)
#define etof(e)
Definition misc.qh:25
int triggertimes
Definition multi.qc:5
void multi_wait(entity this)
Definition multi.qc:8
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
string noise
Definition subs.qh:83
const int DAMAGE_NO
Definition subs.qh:79

References _sound, ATTEN_NORM, CH_TRIGGER, DAMAGE_NO, enemy, entity(), etof, EXACTTRIGGER_TOUCH, func_null(), goalentity, IS_CLIENT, IS_PLAYER, multi_wait(), nextthink, noise, ONLY_PLAYERS, q3compat, setthink, settouch, spawnflags, stof(), SUB_UseTargets(), takedamage, time, triggertimes, use, VOL_BASE, and wait.

Referenced by multi_eventdamage(), multi_touch(), and multi_use().

◆ multi_use()

void multi_use ( entity this,
entity actor,
entity trigger )

Definition at line 96 of file multi.qc.

97{
98 this.goalentity = trigger;
99 this.enemy = actor;
100 multi_trigger(this, false);
101}

References enemy, entity(), goalentity, and multi_trigger().

Referenced by multi_reset(), and spawnfunc().

◆ multi_wait()

void multi_wait ( entity this)

Definition at line 8 of file multi.qc.

9{
10 if (this.max_health)
11 {
12 SetResourceExplicit(this, RES_HEALTH, this.max_health);
14 this.solid = SOLID_BBOX;
15 }
16}

References DAMAGE_YES, entity(), max_health, SetResourceExplicit(), solid, SOLID_BBOX, and takedamage.

Referenced by multi_trigger().

◆ spawnfunc() [1/2]

spawnfunc ( trigger_multiple )

Definition at line 196 of file multi.qc.

197{
198 this.reset = multi_reset;
199 if (this.sounds == 1)
200 this.noise = "misc/secret.wav";
201 else if (this.sounds == 2)
202 this.noise = strzone(SND(TALK));
203 else if (this.sounds == 3)
204 this.noise = "misc/trigger1.wav";
205
206 if(this.noise && this.noise != "")
207 precache_sound(this.noise);
208
209 if (q3compat)
210 {
211 if (!this.wait)
212 {
213 string s = GetField_fullspawndata(this, "wait", false);
214 if (!s || s == "") // it's really not set ("0" or "foo" waits forever)
215 this.wait = 0.5;
216 }
217 }
218 else if (!this.wait)
219 this.wait = 0.2;
220
221 this.use = multi_use;
222
224
225 // TEAMNUMBERS_THAT_ARENT_STUPID TODO: need to convert this.team to index, maybe add .teamindex
226 this.team_saved = this.team;
227 IL_PUSH(g_saved_team, this);
228
229 // health/damage mode isn't supported in Q3 or with CTS client-specific .wait timers
230 if (GetResource(this, RES_HEALTH) && !q3compat && !IS_GAMETYPE(CTS))
231 {
232 if (this.spawnflags & SPAWNFLAG_NOTOUCH)
233 objerror (this, "health and notouch don't make sense\n");
234 this.canteamdamage = true;
235 this.max_health = GetResource(this, RES_HEALTH);
236 this.event_damage = multi_eventdamage;
237 this.takedamage = DAMAGE_YES;
238 this.solid = SOLID_BBOX;
239 setorigin(this, this.origin); // make sure it links into the world
240 }
241 else
242 {
243 if (q3compat || !(this.spawnflags & SPAWNFLAG_NOTOUCH))
244 settouch(this, multi_touch);
245
246 if (IS_GAMETYPE(CTS)) // client-specific .wait timers
247 if ((this.triggertimes = buf_create()) < 0)
248 LOG_FATAL("trigger_multiple: wait timer buffer creation failed somehow!\n");
249 }
250}
vector origin
bool canteamdamage
Definition damage.qh:65
#define buf_create
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define EXACTTRIGGER_INIT
Definition common.qh:116
#define LOG_FATAL(...)
Definition log.qh:53
string precache_sound(string sample)
string strzone(string s)
void multi_reset(entity this)
Definition multi.qc:167
void multi_eventdamage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition multi.qc:148
#define objerror
Definition pre.qh:8
IntrusiveList g_saved_team
Definition vote.qh:79
string GetField_fullspawndata(entity e, string fieldname, bool vfspath)
Retrieves the value of a map entity field from fullspawndata.
Definition main.qc:451
#define SND(id)
Definition all.qh:35
float sounds
Definition subs.qh:42

References buf_create, canteamdamage, DAMAGE_YES, EXACTTRIGGER_INIT, g_saved_team, GetField_fullspawndata(), GetResource(), IL_PUSH(), LOG_FATAL, max_health, multi_eventdamage(), multi_reset(), multi_touch(), multi_use(), noise, objerror, origin, precache_sound(), q3compat, settouch, SND, solid, SOLID_BBOX, sounds, SPAWNFLAG_NOTOUCH, spawnflags, strzone(), takedamage, team, team_saved, triggertimes, use, and wait.

◆ spawnfunc() [2/2]

spawnfunc ( trigger_once )

Definition at line 266 of file multi.qc.

267{
268 this.wait = -1;
269 spawnfunc_trigger_multiple(this);
270}

References wait.

Variable Documentation

◆ triggertimes

int triggertimes

Definition at line 5 of file multi.qc.

Referenced by multi_trigger(), and spawnfunc().