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

Go to the source code of this file.

Functions

void W_MineLayer_Attack (Weapon thiswep, entity actor,.entity weaponentity)
int W_MineLayer_Count (entity e,.entity weaponentity)
void W_MineLayer_Damage (entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
void W_MineLayer_DoRemoteExplode (entity this)
void W_MineLayer_Explode (entity this, entity directhitentity)
void W_MineLayer_Explode_think (entity this)
bool W_MineLayer_PlacedMines (entity this,.entity weaponentity, bool detonate)
void W_MineLayer_ProximityExplode (entity this)
void W_MineLayer_RemoteExplode (entity this)
void W_MineLayer_Stick (entity this, entity to)
void W_MineLayer_Think (entity this)
void W_MineLayer_Touch (entity this, entity toucher)

Function Documentation

◆ W_MineLayer_Attack()

void W_MineLayer_Attack ( Weapon thiswep,
entity actor,
.entity weaponentity )

Definition at line 296 of file minelayer.qc.

297{
298 // scan how many mines we placed, and return if we reached our limit
299 if (WEP_CVAR(WEP_MINE_LAYER, limit) && W_MineLayer_Count(actor, weaponentity) >= WEP_CVAR(WEP_MINE_LAYER, limit))
300 {
301 // the refire delay keeps this message from being spammed
302 Send_Notification(NOTIF_ONE, actor, MSG_MULTI, WEAPON_MINELAYER_LIMIT, WEP_CVAR(WEP_MINE_LAYER, limit));
303 play2(actor, SND(UNAVAILABLE));
304 return;
305 }
306
307 W_DecreaseAmmo(thiswep, actor, WEP_CVAR(WEP_MINE_LAYER, ammo), weaponentity);
308
309 W_SetupShot_ProjectileSize(actor, weaponentity, '-4 -4 -4', '4 4 4', false, 5, SND_MINE_FIRE, CH_WEAPON_A, WEP_CVAR(WEP_MINE_LAYER, damage), thiswep.m_id);
310 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
311
313 mine.weaponentity_fld = weaponentity;
314 IL_PUSH(g_mines, mine);
315 mine.owner = mine.realowner = actor;
316 if (WEP_CVAR(WEP_MINE_LAYER, detonatedelay) >= 0)
317 mine.spawnshieldtime = time + WEP_CVAR(WEP_MINE_LAYER, detonatedelay);
318 else
319 mine.spawnshieldtime = -1;
320 mine.classname = "mine";
321 mine.bot_dodge = true;
322 mine.bot_dodgerating = WEP_CVAR(WEP_MINE_LAYER, damage) * 2; // * 2 because it can detonate inflight which makes it even more dangerous
323
324 mine.takedamage = DAMAGE_YES;
325 mine.damageforcescale = WEP_CVAR(WEP_MINE_LAYER, damageforcescale);
326 SetResourceExplicit(mine, RES_HEALTH, WEP_CVAR(WEP_MINE_LAYER, health));
327 mine.event_damage = W_MineLayer_Damage;
328 mine.damagedbycontents = true;
330
333 mine.projectiledeathtype = thiswep.m_id;
334 mine.weaponentity_fld = weaponentity;
335 setsize(mine, '-4 -4 -4', '4 4 4'); // give it some size so it can be shot
336
337 setorigin(mine, w_shotorg - v_forward * 4); // move it back so it hits the wall at the right point
338 W_SetupProjVelocity_Basic(mine, WEP_CVAR(WEP_MINE_LAYER, speed), 0);
339 mine.angles = vectoangles(mine.velocity);
340
343 mine.nextthink = time;
344 mine.cnt = (WEP_CVAR(WEP_MINE_LAYER, lifetime) - WEP_CVAR(WEP_MINE_LAYER, lifetime_countdown));
345 mine.flags = FL_PROJECTILE;
346 IL_PUSH(g_projectiles, mine);
347 IL_PUSH(g_bot_dodge, mine);
348 mine.missile_flags = MIF_SPLASH | MIF_ARC | MIF_PROXY;
349
350 if (mine.cnt > 0)
351 mine.cnt += time;
352
353 CSQCProjectile(mine, true, PROJECTILE_MINE, true);
354
355 // common properties
356
357 MUTATOR_CALLHOOK(EditProjectile, actor, mine);
358}
IntrusiveList g_bot_dodge
Definition api.qh:150
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
int m_id
Definition weapon.qh:43
float lifetime
Definition powerups.qc:23
const int FL_PROJECTILE
Definition constants.qh:85
float time
vector v_forward
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
IntrusiveList g_damagedbycontents
Definition damage.qh:143
float damageforcescale
float speed
Definition dynlight.qc:9
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
entity WarpZone_RefSys_SpawnSameRefSys(entity me)
Definition common.qc:806
vector vectoangles(vector v)
void W_MineLayer_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition minelayer.qc:269
int W_MineLayer_Count(entity e,.entity weaponentity)
Definition minelayer.qc:178
void W_MineLayer_Think(entity this)
Definition minelayer.qc:185
void W_MineLayer_Touch(entity this, entity toucher)
Definition minelayer.qc:255
IntrusiveList g_mines
Definition minelayer.qh:87
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_TOSS
Definition movetypes.qh:135
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1573
const int PROJECTILE_MINE
float health
Legacy fields for the resources. To be removed.
Definition resources.qh:9
#define setthink(e, f)
#define settouch(e, f)
Definition self.qh:73
const int MIF_SPLASH
Definition common.qh:46
IntrusiveList g_projectiles
Definition common.qh:58
const int MIF_PROXY
Definition common.qh:48
const int MIF_ARC
Definition common.qh:47
#define PROJECTILE_MAKETRIGGER(e)
Definition common.qh:34
const int CH_WEAPON_A
Definition sound.qh:7
void play2(entity e, string filename)
Definition all.qc:116
#define SND(id)
Definition all.qh:35
const int DAMAGE_YES
Definition subs.qh:80
float ammo
Definition sv_turrets.qh:43
vector w_shotdir
Definition tracing.qh:20
#define W_SetupShot_ProjectileSize(ent, wepent, mi, ma, antilag, recoil, snd, chan, maxdamage, deathtype)
Definition tracing.qh:30
vector w_shotorg
Definition tracing.qh:19
#define W_SetupProjVelocity_Basic(ent, pspeed, pspread)
Definition tracing.qh:49
void W_MuzzleFlash(Weapon thiswep, entity actor,.entity weaponentity, vector shotorg, vector shotdir)
Definition all.qc:715
#define WEP_CVAR(wep, name)
Definition all.qh:337
void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use,.entity weaponentity)

References ammo, CH_WEAPON_A, CSQCProjectile(), DAMAGE_YES, damageforcescale, entity(), FL_PROJECTILE, g_bot_dodge, g_damagedbycontents, g_mines, g_projectiles, health, IL_PUSH(), lifetime, Weapon::m_id, MIF_ARC, MIF_PROXY, MIF_SPLASH, MOVETYPE_TOSS, MUTATOR_CALLHOOK, play2(), PROJECTILE_MAKETRIGGER, PROJECTILE_MINE, Send_Notification(), set_movetype(), SetResourceExplicit(), setthink, settouch, SND, speed, time, v_forward, vectoangles(), W_DecreaseAmmo(), W_MineLayer_Count(), W_MineLayer_Damage(), W_MineLayer_Think(), W_MineLayer_Touch(), W_MuzzleFlash(), W_SetupProjVelocity_Basic, W_SetupShot_ProjectileSize, w_shotdir, w_shotorg, WarpZone_RefSys_SpawnSameRefSys(), and WEP_CVAR.

◆ W_MineLayer_Count()

int W_MineLayer_Count ( entity e,
.entity weaponentity )

Definition at line 178 of file minelayer.qc.

179{
180 int minecount = 0;
181 IL_EACH(g_mines, it.realowner == e && it.weaponentity_fld == weaponentity, ++minecount);
182 return minecount;
183}
#define IL_EACH(this, cond, body)

References entity(), g_mines, and IL_EACH.

Referenced by W_MineLayer_Attack().

◆ W_MineLayer_Damage()

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

Definition at line 269 of file minelayer.qc.

270{
271 if (GetResource(this, RES_HEALTH) <= 0)
272 return;
273
274 // Reading the cvar here because this.damageforcescale is overridden in blaster.qc
275 // this way the blaster can hit mines midair but can only detach them when enabled by this cvar.
276 if (WEP_CVAR(WEP_MINE_LAYER, damageforcescale) && inflictor.classname != "mine")
277 {
278 set_movetype(this, MOVETYPE_BOUNCE); // not TOSS: so a direct perpendicular hit can move the mine
279 this.wait = time + 0.0625; // after this time it will reattach instead of bouncing
281 this.avelocity += force * -WEP_CVAR(WEP_MINE_LAYER, damageforcescale);
282 }
283
284 float is_from_enemy = (inflictor.realowner != this.realowner);
285
286 if (!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, (is_from_enemy ? 1 : -1)))
287 return; // g_projectiles_damage says to halt
288
289 TakeResource(this, RES_HEALTH, damage);
290 this.angles = vectoangles(this.velocity);
291
292 if (GetResource(this, RES_HEALTH) <= 0)
294}
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.
float wait
Definition items.qc:17
vector avelocity
vector velocity
ent angles
Definition ent_cs.qc:121
void W_MineLayer_Explode_think(entity this)
Definition minelayer.qc:96
const int MOVETYPE_BOUNCE
Definition movetypes.qh:139
float W_CheckProjectileDamage(entity inflictor, entity projowner, int deathtype, float exception)
Definition common.qc:45
void W_PrepareExplosionByDamage(entity this, entity attacker, void(entity this) explode)
Definition common.qc:87
entity realowner

References angles, avelocity, damageforcescale, entity(), GetResource(), MOVETYPE_BOUNCE, realowner, set_movetype(), settouch, TakeResource(), time, vectoangles(), vector, velocity, W_CheckProjectileDamage(), W_MineLayer_Explode_think(), W_MineLayer_Touch(), W_PrepareExplosionByDamage(), wait, and WEP_CVAR.

Referenced by W_MineLayer_Attack().

◆ W_MineLayer_DoRemoteExplode()

void W_MineLayer_DoRemoteExplode ( entity this)

Definition at line 101 of file minelayer.qc.

102{
103 this.event_damage = func_null;
104 this.takedamage = DAMAGE_NO;
105
106 if (this.move_movetype == MOVETYPE_NONE
108 this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work
109
110 RadiusDamage(this, this.realowner,
111 WEP_CVAR(WEP_MINE_LAYER, remote_damage),
112 WEP_CVAR(WEP_MINE_LAYER, remote_edgedamage),
113 WEP_CVAR(WEP_MINE_LAYER, remote_radius),
114 NULL,
115 NULL,
116 WEP_CVAR(WEP_MINE_LAYER, remote_force),
118 this.weaponentity_fld,
119 NULL
120 );
121
122 .entity weaponentity = this.weaponentity_fld;
123 Weapon thiswep = WEP_MINE_LAYER;
124 if (this.realowner.(weaponentity).m_weapon == thiswep)
125 {
126 entity own = this.realowner;
127 if (!thiswep.wr_checkammo1(thiswep, own, weaponentity)
128 && !(own.items & IT_UNLIMITED_AMMO))
129 {
130 own.cnt = thiswep.m_id;
131 ATTACK_FINISHED(own, weaponentity) = time;
132 own.(weaponentity).m_switchweapon = w_getbestweapon(own, weaponentity);
133 }
134 }
135 delete(this);
136}
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:42
virtual void wr_checkammo1()
(SERVER) checks ammo for weapon primary
Definition weapon.qh:100
const int IT_UNLIMITED_AMMO
Definition item.qh:23
float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
Definition damage.qc:943
const int HITTYPE_BOUNCE
Definition all.qh:31
vector movedir
Definition viewloc.qh:18
const int MOVETYPE_NONE
Definition movetypes.qh:129
const int MOVETYPE_FOLLOW
Definition movetypes.qh:141
float move_movetype
Definition movetypes.qh:76
var void func_null()
#define NULL
Definition post.qh:14
#define w_getbestweapon(ent, wepent)
Definition selection.qh:23
int projectiledeathtype
Definition common.qh:21
const int DAMAGE_NO
Definition subs.qh:79
float takedamage
Definition subs.qh:78
#define ATTACK_FINISHED(ent, w)
entity weaponentity_fld
Weapon m_switchweapon
Definition wepent.qh:25

References ATTACK_FINISHED, DAMAGE_NO, entity(), func_null(), HITTYPE_BOUNCE, IT_UNLIMITED_AMMO, Weapon::m_id, m_switchweapon, move_movetype, movedir, MOVETYPE_FOLLOW, MOVETYPE_NONE, NULL, projectiledeathtype, RadiusDamage(), realowner, takedamage, time, velocity, w_getbestweapon, weaponentity_fld, WEP_CVAR, and Weapon::wr_checkammo1().

Referenced by W_MineLayer_RemoteExplode().

◆ W_MineLayer_Explode()

void W_MineLayer_Explode ( entity this,
entity directhitentity )

Definition at line 58 of file minelayer.qc.

59{
60 if (directhitentity.takedamage == DAMAGE_AIM
61 && IS_PLAYER(directhitentity) && DIFF_TEAM(this.realowner, directhitentity) && !IS_DEAD(directhitentity)
62 && IsFlying(directhitentity))
63 Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
64
65 this.event_damage = func_null;
66 this.takedamage = DAMAGE_NO;
67
68 RadiusDamage(this, this.realowner,
69 WEP_CVAR(WEP_MINE_LAYER, damage),
70 WEP_CVAR(WEP_MINE_LAYER, edgedamage),
71 WEP_CVAR(WEP_MINE_LAYER, radius),
72 NULL,
73 NULL,
74 WEP_CVAR(WEP_MINE_LAYER, force),
77 directhitentity
78 );
79
80 .entity weaponentity = this.weaponentity_fld;
81 Weapon thiswep = WEP_MINE_LAYER;
82 if (this.realowner.(weaponentity).m_weapon == thiswep)
83 {
84 entity own = this.realowner;
85 if (!thiswep.wr_checkammo1(thiswep, own, weaponentity)
86 && !(own.items & IT_UNLIMITED_AMMO))
87 {
88 own.cnt = thiswep.m_id;
89 ATTACK_FINISHED(own, weaponentity) = time;
90 own.(weaponentity).m_switchweapon = w_getbestweapon(own, weaponentity);
91 }
92 }
93 delete(this);
94}
float radius
Definition impulse.qh:11
bool IsFlying(entity this)
Definition player.qc:843
#define IS_DEAD(s)
Definition player.qh:244
#define IS_PLAYER(s)
Definition player.qh:242
const int DAMAGE_AIM
Definition subs.qh:81
#define DIFF_TEAM(a, b)
Definition teams.qh:242

References ATTACK_FINISHED, DAMAGE_AIM, DAMAGE_NO, DIFF_TEAM, entity(), func_null(), IS_DEAD, IS_PLAYER, IsFlying(), IT_UNLIMITED_AMMO, Weapon::m_id, m_switchweapon, NULL, projectiledeathtype, radius, RadiusDamage(), realowner, Send_Notification(), takedamage, time, w_getbestweapon, weaponentity_fld, WEP_CVAR, and Weapon::wr_checkammo1().

Referenced by W_MineLayer_Explode_think(), W_MineLayer_ProximityExplode(), and W_MineLayer_Think().

◆ W_MineLayer_Explode_think()

void W_MineLayer_Explode_think ( entity this)

Definition at line 96 of file minelayer.qc.

97{
99}
void W_MineLayer_Explode(entity this, entity directhitentity)
Definition minelayer.qc:58

References entity(), NULL, and W_MineLayer_Explode().

Referenced by W_MineLayer_Damage().

◆ W_MineLayer_PlacedMines()

bool W_MineLayer_PlacedMines ( entity this,
.entity weaponentity,
bool detonate )

Definition at line 360 of file minelayer.qc.

361{
362 bool minfound = false;
363 IL_EACH(g_mines, it.realowner == this && it.weaponentity_fld == weaponentity,
364 {
365 if (detonate)
366 {
367 if (!it.minelayer_detonate)
368 {
369 it.minelayer_detonate = true;
370 minfound = true;
371 }
372 }
373 else
374 minfound = true;
375 });
376 return minfound;
377}

References entity(), g_mines, and IL_EACH.

◆ W_MineLayer_ProximityExplode()

void W_MineLayer_ProximityExplode ( entity this)

Definition at line 163 of file minelayer.qc.

164{
165 // make sure no friend is in the mine's radius. If there is any, explosion is delayed until they're at a safe distance
166 if (WEP_CVAR(WEP_MINE_LAYER, protection) && this.mine_explodeanyway == 0)
167 {
168 entity head = WarpZone_FindRadius(this.origin, WEP_CVAR(WEP_MINE_LAYER, radius), false);
169 for (; head; head = head.chain)
170 if (SAME_TEAM(head, this.realowner))
171 return;
172 }
173
174 this.mine_time = 0;
176}
vector origin
entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
Definition common.qc:684
float mine_explodeanyway
Definition minelayer.qh:84
float mine_time
Definition minelayer.qh:85
#define SAME_TEAM(a, b)
Definition teams.qh:241

References entity(), mine_explodeanyway, mine_time, NULL, origin, radius, realowner, SAME_TEAM, W_MineLayer_Explode(), WarpZone_FindRadius(), and WEP_CVAR.

Referenced by W_MineLayer_Think().

◆ W_MineLayer_RemoteExplode()

void W_MineLayer_RemoteExplode ( entity this)

Definition at line 138 of file minelayer.qc.

139{
140 if (IS_DEAD(this.realowner))
141 return;
142 if (this.spawnshieldtime >= 0)
143 {
144 if (time < this.spawnshieldtime) // timer
145 return;
146 }
147 else
148 {
149 /* make sure no friend is in the mine's radius.
150 * WEAPONTODO: modify protection cvar to allow disabling remote detonation protection.
151 * disabling it currently allows Mine Layer-flying, even more powerful than rocket-flying
152 * ... even without Rocket Flying mutator enabled
153 */
154 entity head = WarpZone_FindRadius(this.origin, WEP_CVAR(WEP_MINE_LAYER, remote_radius), false);
155 for (; head; head = head.chain)
156 if (SAME_TEAM(head, this.realowner))
157 return;
158 }
159
161}
float spawnshieldtime
Definition damage.qh:61
void W_MineLayer_DoRemoteExplode(entity this)
Definition minelayer.qc:101

References entity(), IS_DEAD, origin, realowner, SAME_TEAM, spawnshieldtime, time, W_MineLayer_DoRemoteExplode(), WarpZone_FindRadius(), and WEP_CVAR.

Referenced by W_MineLayer_Think().

◆ W_MineLayer_Stick()

void W_MineLayer_Stick ( entity this,
entity to )

Definition at line 5 of file minelayer.qc.

6{
7 spamsound(this, CH_SHOTS, SND_MINE_STICK, VOL_BASE, ATTN_NORM);
8
9 // in order for mines to face properly when sticking to the ground, they must be a server side entity rather than a csqc projectile
10
11 entity newmine = spawn();
12 IL_PUSH(g_mines, newmine);
13 newmine.weaponentity_fld = this.weaponentity_fld;
14 newmine.classname = this.classname;
15
16 newmine.bot_dodge = this.bot_dodge;
17 newmine.bot_dodgerating = this.bot_dodgerating;
18
19 newmine.owner = this.owner;
20 newmine.realowner = this.realowner;
21 newmine.glowmod = colormapPaletteColor(this.realowner.clientcolors & 0x0F, true);
22
24 setorigin(newmine, this.origin);
25 setmodel(newmine, MDL_MINELAYER_MINE);
26 setsize(newmine, '-4 -4 -4', '4 4 4');
27 newmine.angles = vectoangles(-trace_plane_normal); // face against the surface
28
29 newmine.movedir = -trace_plane_normal;
30
31 newmine.takedamage = this.takedamage;
32 newmine.damageforcescale = this.damageforcescale;
33 SetResourceExplicit(newmine, RES_HEALTH, GetResource(this, RES_HEALTH));
34 newmine.event_damage = this.event_damage;
35 newmine.spawnshieldtime = this.spawnshieldtime;
36 newmine.damagedbycontents = true;
38
39 set_movetype(newmine, MOVETYPE_NONE); // lock the mine in place
40 newmine.projectiledeathtype = this.projectiledeathtype;
41
42 newmine.mine_time = this.mine_time;
43
44 settouch(newmine, func_null);
46 newmine.nextthink = time;
47 newmine.cnt = this.cnt;
48 newmine.flags = this.flags;
49 IL_PUSH(g_projectiles, newmine);
50 IL_PUSH(g_bot_dodge, newmine);
51
52 delete(this);
53
54 if (to)
55 SetMovetypeFollow(newmine, to);
56}
float bot_dodge
Definition api.qh:40
float bot_dodgerating
Definition api.qh:39
float cnt
Definition powerups.qc:24
entity owner
Definition main.qh:87
#define colormapPaletteColor(c, isPants)
Definition color.qh:5
#define setmodel(this, m)
Definition model.qh:26
void SetMovetypeFollow(entity ent, entity e)
Definition util.qc:2129
string classname
float flags
const float ATTN_NORM
vector trace_plane_normal
#define spawn
const float VOL_BASE
Definition sound.qh:36
const int CH_SHOTS
Definition sound.qh:14
float spamsound(entity e, int chan, Sound samp, float vol, float _atten)
use this one if you might be causing spam (e.g.
Definition all.qc:124

References ATTN_NORM, bot_dodge, bot_dodgerating, CH_SHOTS, classname, cnt, colormapPaletteColor, damageforcescale, entity(), flags, func_null(), g_bot_dodge, g_damagedbycontents, g_mines, g_projectiles, GetResource(), IL_PUSH(), mine_time, MOVETYPE_NONE, origin, owner, PROJECTILE_MAKETRIGGER, projectiledeathtype, realowner, set_movetype(), setmodel, SetMovetypeFollow(), SetResourceExplicit(), setthink, settouch, spamsound(), spawn, spawnshieldtime, takedamage, time, trace_plane_normal, vectoangles(), VOL_BASE, W_MineLayer_Think(), and weaponentity_fld.

Referenced by W_MineLayer_Touch().

◆ W_MineLayer_Think()

void W_MineLayer_Think ( entity this)

Definition at line 185 of file minelayer.qc.

186{
187 this.nextthink = time;
188
190 {
193 }
194
195 // our lifetime has expired, it's time to die - mine_time just allows us to play a sound for this
196 // WEAPONTODO: replace this mine_trigger.wav sound with a real countdown
197 if (time > this.cnt && !this.mine_time && this.cnt > 0)
198 {
199 if (WEP_CVAR(WEP_MINE_LAYER, lifetime_countdown) > 0)
200 spamsound(this, CH_SHOTS, SND_MINE_TRIGGER, VOL_BASE, ATTN_NORM);
201 this.mine_time = time + WEP_CVAR(WEP_MINE_LAYER, lifetime_countdown);
202 this.mine_explodeanyway = 1; // make the mine super aggressive -- Samual: Rather, make it not care if a teammate is near.
203 }
204
205 // a player's mines shall explode if they disconnect or die
206 if (!IS_PLAYER(this.realowner) || IS_DEAD(this.realowner) || STAT(FROZEN, this.realowner))
207 {
210 return;
211 }
212
213 // set the mine for detonation when a foe gets close enough
214 float time_core = WEP_CVAR(WEP_MINE_LAYER, proximity_time_core);
215 float time_edge = WEP_CVAR(WEP_MINE_LAYER, proximity_time_edge);
216 float proxrad = WEP_CVAR(WEP_MINE_LAYER, proximity_radius);
217 float new_mine_time;
218 entity head = WarpZone_FindRadius(this.origin, proxrad, false);
219 for (; head; head = head.chain)
220 if (IS_PLAYER(head) && !IS_DEAD(head) && !STAT(FROZEN, head) && !IS_INDEPENDENT_PLAYER(head)
221 && DIFF_TEAM(head, this.realowner)) // don't trigger for team mates
222 {
223 if (!this.mine_time) // don't repeat the sound
224 spamsound(this, CH_SHOTS, SND_MINE_TRIGGER, VOL_BASE, ATTN_NORM);
225 // scale from time_edge to time_core based on how close the player is to the mine
226 new_mine_time = time + time_core;
227 if (time_edge != time_core)
228 new_mine_time += (time_edge - time_core) * vlen(head.WarpZone_findradius_dist) / proxrad;
229 if (!this.mine_time || this.mine_time > new_mine_time) // choose the earliest explosion time
230 this.mine_time = new_mine_time;
231 }
232
233 // explode if it's time to
234 if (this.mine_time && time >= this.mine_time)
235 {
237 return;
238 }
239
240 // remote detonation
241 .entity weaponentity = this.weaponentity_fld;
242 if (this.realowner.(weaponentity).m_weapon == WEP_MINE_LAYER
243 && !IS_DEAD(this.realowner)
244 && this.minelayer_detonate)
245 {
247 return;
248 }
249
250 // if it was detached by damage but landed during the bounce time, reenable gravity so it will touch and reattach
251 if (this.move_movetype == MOVETYPE_BOUNCE && IS_ONGROUND(this))
252 UNSET_ONGROUND(this);
253}
void UnsetMovetypeFollow(entity ent)
Definition util.qc:2149
int LostMovetypeFollow(entity ent)
Definition util.qc:2159
float nextthink
#define STAT(...)
Definition stats.qh:82
float vlen(vector v)
void W_MineLayer_ProximityExplode(entity this)
Definition minelayer.qc:163
void W_MineLayer_RemoteExplode(entity this)
Definition minelayer.qc:138
float minelayer_detonate
Definition minelayer.qh:84
#define UNSET_ONGROUND(s)
Definition movetypes.qh:18
#define IS_ONGROUND(s)
Definition movetypes.qh:16
#define IS_INDEPENDENT_PLAYER(e)
Definition client.qh:312

References ATTN_NORM, CH_SHOTS, cnt, DIFF_TEAM, entity(), HITTYPE_BOUNCE, IS_DEAD, IS_INDEPENDENT_PLAYER, IS_ONGROUND, IS_PLAYER, LostMovetypeFollow(), mine_explodeanyway, mine_time, minelayer_detonate, move_movetype, MOVETYPE_BOUNCE, MOVETYPE_FOLLOW, MOVETYPE_NONE, nextthink, NULL, origin, projectiledeathtype, realowner, set_movetype(), spamsound(), STAT, time, UNSET_ONGROUND, UnsetMovetypeFollow(), vlen(), VOL_BASE, W_MineLayer_Explode(), W_MineLayer_ProximityExplode(), W_MineLayer_RemoteExplode(), WarpZone_FindRadius(), weaponentity_fld, and WEP_CVAR.

Referenced by W_MineLayer_Attack(), and W_MineLayer_Stick().

◆ W_MineLayer_Touch()

void W_MineLayer_Touch ( entity this,
entity toucher )

Definition at line 255 of file minelayer.qc.

256{
257 if (this.move_movetype == MOVETYPE_NONE
259 return; // we're already a stuck mine, why do we get called? TODO does this even happen?
260 if (time <= this.wait)
261 return; // don't reattach yet
262
264
265 if (toucher.solid == SOLID_BSP)
267}
const float SOLID_BSP
void W_MineLayer_Stick(entity this, entity to)
Definition minelayer.qc:5
entity entity toucher
Definition self.qh:72
#define PROJECTILE_TOUCH(e, t)
Definition common.qh:28

References entity(), move_movetype, MOVETYPE_FOLLOW, MOVETYPE_NONE, PROJECTILE_TOUCH, SOLID_BSP, time, toucher, W_MineLayer_Stick(), and wait.

Referenced by W_MineLayer_Attack(), and W_MineLayer_Damage().