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 295 of file minelayer.qc.

296{
297 // scan how many mines we placed, and return if we reached our limit
298 if(WEP_CVAR(WEP_MINE_LAYER, limit))
299 {
300 int minecount = W_MineLayer_Count(actor, weaponentity);
301 if(minecount >= WEP_CVAR(WEP_MINE_LAYER, limit))
302 {
303 // the refire delay keeps this message from being spammed
304 Send_Notification(NOTIF_ONE, actor, MSG_MULTI, WEAPON_MINELAYER_LIMIT, WEP_CVAR(WEP_MINE_LAYER, limit));
305 play2(actor, SND(UNAVAILABLE));
306 return;
307 }
308 }
309
310 W_DecreaseAmmo(thiswep, actor, WEP_CVAR(WEP_MINE_LAYER, ammo), weaponentity);
311
312 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);
313 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
314
316 mine.weaponentity_fld = weaponentity;
317 IL_PUSH(g_mines, mine);
318 mine.owner = mine.realowner = actor;
319 if(WEP_CVAR(WEP_MINE_LAYER, detonatedelay) >= 0)
320 mine.spawnshieldtime = time + WEP_CVAR(WEP_MINE_LAYER, detonatedelay);
321 else
322 mine.spawnshieldtime = -1;
323 mine.classname = "mine";
324 mine.bot_dodge = true;
325 mine.bot_dodgerating = WEP_CVAR(WEP_MINE_LAYER, damage) * 2; // * 2 because it can detonate inflight which makes it even more dangerous
326
327 mine.takedamage = DAMAGE_YES;
328 mine.damageforcescale = WEP_CVAR(WEP_MINE_LAYER, damageforcescale);
329 SetResourceExplicit(mine, RES_HEALTH, WEP_CVAR(WEP_MINE_LAYER, health));
330 mine.event_damage = W_MineLayer_Damage;
331 mine.damagedbycontents = true;
333
336 mine.projectiledeathtype = thiswep.m_id;
337 mine.weaponentity_fld = weaponentity;
338 setsize(mine, '-4 -4 -4', '4 4 4'); // give it some size so it can be shot
339
340 setorigin(mine, w_shotorg - v_forward * 4); // move it back so it hits the wall at the right point
341 W_SetupProjVelocity_Basic(mine, WEP_CVAR(WEP_MINE_LAYER, speed), 0);
342 mine.angles = vectoangles(mine.velocity);
343
346 mine.nextthink = time;
347 mine.cnt = (WEP_CVAR(WEP_MINE_LAYER, lifetime) - WEP_CVAR(WEP_MINE_LAYER, lifetime_countdown));
348 mine.flags = FL_PROJECTILE;
349 IL_PUSH(g_projectiles, mine);
350 IL_PUSH(g_bot_dodge, mine);
351 mine.missile_flags = MIF_SPLASH | MIF_ARC | MIF_PROXY;
352
353 if(mine.cnt > 0) { mine.cnt += time; }
354
355 CSQCProjectile(mine, true, PROJECTILE_MINE, true);
356
357 // common properties
358
359 MUTATOR_CALLHOOK(EditProjectile, actor, mine);
360}
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:45
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:135
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:808
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:268
int W_MineLayer_Count(entity e,.entity weaponentity)
Definition minelayer.qc:167
void W_MineLayer_Think(entity this)
Definition minelayer.qc:178
void W_MineLayer_Touch(entity this, entity toucher)
Definition minelayer.qc:255
IntrusiveList g_mines
Definition minelayer.qh:83
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:728
#define WEP_CVAR(wep, name)
Definition all.qh:321
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 167 of file minelayer.qc.

168{
169 int minecount = 0;
170 IL_EACH(g_mines, it.realowner == e && it.weaponentity_fld == weaponentity,
171 {
172 minecount += 1;
173 });
174
175 return minecount;
176}
#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 268 of file minelayer.qc.

269{
270 if(GetResource(this, RES_HEALTH) <= 0)
271 return;
272
273 // Reading the cvar here because this.damageforcescale is overridden in blaster.qc
274 // this way the blaster can hit mines midair but can only detach them when enabled by this cvar.
275 if (WEP_CVAR(WEP_MINE_LAYER, damageforcescale) && inflictor.classname != "mine")
276 {
277 set_movetype(this, MOVETYPE_BOUNCE); // not TOSS: so a direct perpendicular hit can move the mine
278 this.wait = time + 0.0625; // after this time it will reattach instead of bouncing
280 this.avelocity += force * -WEP_CVAR(WEP_MINE_LAYER, damageforcescale);
281 }
282
283 float is_from_enemy = (inflictor.realowner != this.realowner);
284
285 if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, (is_from_enemy ? 1 : -1)))
286 return; // g_projectiles_damage says to halt
287
288 TakeResource(this, RES_HEALTH, damage);
289 this.angles = vectoangles(this.velocity);
290
291 if(GetResource(this, RES_HEALTH) <= 0)
293}
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:88
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 93 of file minelayer.qc.

94{
95 this.event_damage = func_null;
96 this.takedamage = DAMAGE_NO;
97
99 this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work
100
101 RadiusDamage(this, this.realowner, WEP_CVAR(WEP_MINE_LAYER, remote_damage), WEP_CVAR(WEP_MINE_LAYER, remote_edgedamage), WEP_CVAR(WEP_MINE_LAYER, remote_radius),
102 NULL, NULL, WEP_CVAR(WEP_MINE_LAYER, remote_force), this.projectiledeathtype | HITTYPE_BOUNCE, this.weaponentity_fld, NULL);
103
104 .entity weaponentity = this.weaponentity_fld;
105 Weapon thiswep = WEP_MINE_LAYER;
106 if(this.realowner.(weaponentity).m_weapon == thiswep)
107 {
108 entity own = this.realowner;
109 if(!thiswep.wr_checkammo1(thiswep, own, weaponentity))
110 if(!(own.items & IT_UNLIMITED_AMMO))
111 {
112 own.cnt = thiswep.m_id;
113 ATTACK_FINISHED(own, weaponentity) = time;
114 own.(weaponentity).m_switchweapon = w_getbestweapon(own, weaponentity);
115 }
116 }
117 delete(this);
118}
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:44
virtual void wr_checkammo1()
(SERVER) checks ammo for weapon primary
Definition weapon.qh:92
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:981
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 if(IS_PLAYER(directhitentity))
62 if(DIFF_TEAM(this.realowner, directhitentity))
63 if(!IS_DEAD(directhitentity))
64 if(IsFlying(directhitentity))
65 Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
66
67 this.event_damage = func_null;
68 this.takedamage = DAMAGE_NO;
69
70 RadiusDamage(this, this.realowner, WEP_CVAR(WEP_MINE_LAYER, damage), WEP_CVAR(WEP_MINE_LAYER, edgedamage), WEP_CVAR(WEP_MINE_LAYER, radius), NULL, NULL, WEP_CVAR(WEP_MINE_LAYER, force), this.projectiledeathtype, this.weaponentity_fld, directhitentity);
71
72 .entity weaponentity = this.weaponentity_fld;
73 Weapon thiswep = WEP_MINE_LAYER;
74 if(this.realowner.(weaponentity).m_weapon == thiswep)
75 {
76 entity own = this.realowner;
77 if(!thiswep.wr_checkammo1(thiswep, own, weaponentity))
78 if(!(own.items & IT_UNLIMITED_AMMO))
79 {
80 own.cnt = thiswep.m_id;
81 ATTACK_FINISHED(own, weaponentity) = time;
82 own.(weaponentity).m_switchweapon = w_getbestweapon(own, weaponentity);
83 }
84 }
85 delete(this);
86}
float radius
Definition impulse.qh:11
bool IsFlying(entity this)
Definition player.qc:836
#define IS_DEAD(s)
Definition player.qh:245
#define IS_PLAYER(s)
Definition player.qh:243
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 88 of file minelayer.qc.

89{
91}
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 362 of file minelayer.qc.

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

References entity(), g_mines, and IL_EACH.

◆ W_MineLayer_ProximityExplode()

void W_MineLayer_ProximityExplode ( entity this)

Definition at line 149 of file minelayer.qc.

150{
151 // make sure no friend is in the mine's radius. If there is any, explosion is delayed until they're at a safe distance
152 if(WEP_CVAR(WEP_MINE_LAYER, protection) && this.mine_explodeanyway == 0)
153 {
154 entity head = WarpZone_FindRadius(this.origin, WEP_CVAR(WEP_MINE_LAYER, radius), false);
155 while(head)
156 {
157 if(SAME_TEAM(head, this.realowner))
158 return;
159 head = head.chain;
160 }
161 }
162
163 this.mine_time = 0;
165}
vector origin
entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
Definition common.qc:686
float mine_explodeanyway
Definition minelayer.qh:80
float mine_time
Definition minelayer.qh:81
#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 120 of file minelayer.qc.

121{
122 if(IS_DEAD(this.realowner))
123 return;
124
125 if(this.spawnshieldtime >= 0)
126 {
127 if(time < this.spawnshieldtime) // timer
128 return;
129 }
130 else
131 {
132 /* make sure no friend is in the mine's radius.
133 * WEAPONTODO: modify protection cvar to allow disabling remote detonation protection.
134 * disabling it currently allows Mine Layer-flying, even more powerful than rocket-flying
135 * ... even without Rocket Flying mutator enabled
136 */
137 entity head = WarpZone_FindRadius(this.origin, WEP_CVAR(WEP_MINE_LAYER, remote_radius), false);
138 while(head)
139 {
140 if(SAME_TEAM(head, this.realowner))
141 return;
142 head = head.chain;
143 }
144 }
145
147}
float spawnshieldtime
Definition damage.qh:61
void W_MineLayer_DoRemoteExplode(entity this)
Definition minelayer.qc:93

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:2033
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 178 of file minelayer.qc.

179{
180 entity head;
181
182 this.nextthink = time;
183
185 {
186 if(LostMovetypeFollow(this))
187 {
190 }
191 }
192
193 // our lifetime has expired, it's time to die - mine_time just allows us to play a sound for this
194 // TODO: replace this mine_trigger.wav sound with a real countdown
195 if((time > this.cnt) && (!this.mine_time) && (this.cnt > 0))
196 {
197 if(WEP_CVAR(WEP_MINE_LAYER, lifetime_countdown) > 0)
198 spamsound(this, CH_SHOTS, SND_MINE_TRIGGER, VOL_BASE, ATTN_NORM);
199 this.mine_time = time + WEP_CVAR(WEP_MINE_LAYER, lifetime_countdown);
200 this.mine_explodeanyway = 1; // make the mine super aggressive -- Samual: Rather, make it not care if a teammate is near.
201 }
202
203 // a player's mines shall explode if they disconnect or die
204 if(!IS_PLAYER(this.realowner) || IS_DEAD(this.realowner) || STAT(FROZEN, this.realowner))
205 {
208 return;
209 }
210
211 // set the mine for detonation when a foe gets close enough
212 float time_core = WEP_CVAR(WEP_MINE_LAYER, proximity_time_core);
213 float time_edge = WEP_CVAR(WEP_MINE_LAYER, proximity_time_edge);
214 float proxrad = WEP_CVAR(WEP_MINE_LAYER, proximity_radius);
215 head = WarpZone_FindRadius(this.origin, proxrad, false);
216 while(head)
217 {
218 if(IS_PLAYER(head) && !IS_DEAD(head) && !STAT(FROZEN, head) && !IS_INDEPENDENT_PLAYER(head))
219 if(DIFF_TEAM(head, this.realowner)) // don't trigger for teammates
220 {
221 if(!this.mine_time) // don't repeat the sound
222 spamsound(this, CH_SHOTS, SND_MINE_TRIGGER, VOL_BASE, ATTN_NORM);
223 // scale from time_edge to time_core based on how close the player is to the mine
224 float new_mine_time = time + time_core;
225 if(time_edge != time_core)
226 new_mine_time += (time_edge - time_core) * vlen(head.WarpZone_findradius_dist) / proxrad;
227 if((!this.mine_time) || this.mine_time > new_mine_time) // choose the earliest explosion time
228 this.mine_time = new_mine_time;
229 }
230 head = head.chain;
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 if(!IS_DEAD(this.realowner))
244 if(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:2053
int LostMovetypeFollow(entity ent)
Definition util.qc:2063
float nextthink
#define STAT(...)
Definition stats.qh:82
float vlen(vector v)
void W_MineLayer_ProximityExplode(entity this)
Definition minelayer.qc:149
void W_MineLayer_RemoteExplode(entity this)
Definition minelayer.qc:120
float minelayer_detonate
Definition minelayer.qh:80
#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{
258 return; // we're already a stuck mine, why do we get called? TODO does this even happen?
259 if(time <= this.wait)
260 return; // don't reattach yet
261
263
264 if (toucher.solid == SOLID_BSP)
266}
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().