Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
mortar.qc
Go to the documentation of this file.
1#include "mortar.qh"
2
3#ifdef SVQC
4
5void W_Mortar_Grenade_Explode(entity this, entity directhitentity)
6{
7 if (directhitentity.takedamage == DAMAGE_AIM
8 && IS_PLAYER(directhitentity) && DIFF_TEAM(this.realowner, directhitentity) && !IS_DEAD(directhitentity)
9 && IsFlying(directhitentity))
10 Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
11
12 this.event_damage = func_null;
13 this.takedamage = DAMAGE_NO;
14
15 if (this.move_movetype == MOVETYPE_NONE)
16 this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work
17
18 RadiusDamage(this, this.realowner,
19 WEP_CVAR_PRI(WEP_MORTAR, damage),
20 WEP_CVAR_PRI(WEP_MORTAR, edgedamage),
21 WEP_CVAR_PRI(WEP_MORTAR, radius),
22 NULL,
23 NULL,
24 WEP_CVAR_PRI(WEP_MORTAR, force),
27 directhitentity
28 );
29
30 delete(this);
31}
32
34{
35 W_Mortar_Grenade_Explode(this, trigger);
36}
37
38void W_Mortar_Grenade_Explode2(entity this, entity directhitentity)
39{
40 if (directhitentity.takedamage == DAMAGE_AIM
41 && IS_PLAYER(directhitentity) && DIFF_TEAM(this.realowner, directhitentity) && !IS_DEAD(directhitentity)
42 && IsFlying(directhitentity))
43 Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
44
45 this.event_damage = func_null;
46 this.takedamage = DAMAGE_NO;
47
48 if (this.move_movetype == MOVETYPE_NONE)
49 this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work
50
51 RadiusDamage(this, this.realowner,
52 WEP_CVAR_SEC(WEP_MORTAR, damage),
53 WEP_CVAR_SEC(WEP_MORTAR, edgedamage),
54 WEP_CVAR_SEC(WEP_MORTAR, radius),
55 NULL,
56 NULL,
57 WEP_CVAR_SEC(WEP_MORTAR, force),
60 directhitentity
61 );
62
63 delete(this);
64}
65
67{
68 W_Mortar_Grenade_Explode2(this, trigger);
69}
70
71void W_Mortar_Grenade_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
72{
73 if (GetResource(this, RES_HEALTH) <= 0)
74 return;
75 if (!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions
76 return; // g_projectiles_damage says to halt
77
78 TakeResource(this, RES_HEALTH, damage);
79 if (GetResource(this, RES_HEALTH) <= 0)
80 W_PrepareExplosionByDamage(this, attacker, adaptor_think2use);
81}
82
84{
85 this.nextthink = time;
86 if (time > this.cnt)
87 {
90 return;
91 }
92 if (this.gl_detonate_later && this.gl_bouncecnt >= WEP_CVAR_PRI(WEP_MORTAR, remote_minbouncecnt))
94}
95
97{
99 if (toucher.takedamage == DAMAGE_AIM || WEP_CVAR_PRI(WEP_MORTAR, type) == 0) // always explode when hitting a player, or if normal mortar projectile
100 this.use(this, NULL, toucher);
101 else if (WEP_CVAR_PRI(WEP_MORTAR, type) == 1) // bounce
102 {
104 Send_Effect(EFFECT_HAGAR_BOUNCE, this.origin, this.velocity, 1);
106 ++this.gl_bouncecnt;
107 }
108 else if (WEP_CVAR_PRI(WEP_MORTAR, type) == 2
109 && (!toucher || (toucher.takedamage != DAMAGE_AIM && toucher.move_movetype == MOVETYPE_NONE))) // stick
110 {
111 spamsound(this, CH_SHOTS, SND_MORTAR_STICK, VOL_BASE, ATTN_NORM);
112
113 // let it stick whereever it is
114 this.movedir = this.velocity; // save to this temporary field, will be restored on explosion
115 this.velocity = '0 0 0';
116 set_movetype(this, MOVETYPE_NONE); // also disables gravity
117 this.gravity = 0; // nope, it does NOT! maybe a bug in CSQC code? TODO
119
120 // do not respond to any more touches
121 this.solid = SOLID_NOT;
122
123 this.nextthink = min(this.nextthink, time + WEP_CVAR_PRI(WEP_MORTAR, lifetime_stick));
124 }
125}
126
128{
130 if (toucher.takedamage == DAMAGE_AIM || WEP_CVAR_SEC(WEP_MORTAR, type) == 0) // always explode when hitting a player, or if normal mortar projectile
131 this.use(this, NULL, toucher);
132 else if (WEP_CVAR_SEC(WEP_MORTAR, type) == 1) // bounce
133 {
135 Send_Effect(EFFECT_HAGAR_BOUNCE, this.origin, this.velocity, 1);
137 ++this.gl_bouncecnt;
138
139 if (WEP_CVAR_SEC(WEP_MORTAR, lifetime_bounce) && this.gl_bouncecnt == 1)
140 this.nextthink = time + WEP_CVAR_SEC(WEP_MORTAR, lifetime_bounce);
141 }
142 else if (WEP_CVAR_SEC(WEP_MORTAR, type) == 2
143 && (!toucher || (toucher.takedamage != DAMAGE_AIM && toucher.move_movetype == MOVETYPE_NONE))) // stick
144 {
145 spamsound(this, CH_SHOTS, SND_MORTAR_STICK, VOL_BASE, ATTN_NORM);
146
147 // let it stick whereever it is
148 this.movedir = this.velocity; // save to this temporary field, will be restored on explosion
149 this.velocity = '0 0 0';
150 set_movetype(this, MOVETYPE_NONE); // also disables gravity
151 this.gravity = 0; // nope, it does NOT! maybe a bug in CSQC code? TODO
153
154 // do not respond to any more touches
155 this.solid = SOLID_NOT;
156
157 this.nextthink = min(this.nextthink, time + WEP_CVAR_SEC(WEP_MORTAR, lifetime_stick));
158 }
159}
160
161void W_Mortar_Attack(Weapon thiswep, entity actor, .entity weaponentity)
162{
163 W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(WEP_MORTAR, ammo), weaponentity);
164
165 W_SetupShot_ProjectileSize(actor, weaponentity, '-3 -3 -3', '3 3 3', false, 4, SND_MORTAR_FIRE, CH_WEAPON_A, WEP_CVAR_PRI(WEP_MORTAR, damage), thiswep.m_id);
166 w_shotdir = v_forward; // no TrueAim for grenades please
167
168 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
169
170 entity gren = new(grenade);
171 gren.owner = gren.realowner = actor;
172 gren.bot_dodge = true;
173 gren.bot_dodgerating = WEP_CVAR_PRI(WEP_MORTAR, damage);
175 gren.bouncefactor = WEP_CVAR(WEP_MORTAR, bouncefactor);
176 gren.bouncestop = WEP_CVAR(WEP_MORTAR, bouncestop);
178 gren.projectiledeathtype = thiswep.m_id;
179 gren.weaponentity_fld = weaponentity;
180 setorigin(gren, w_shotorg);
181 setsize(gren, '-3 -3 -3', '3 3 3');
182
183 gren.cnt = time + WEP_CVAR_PRI(WEP_MORTAR, lifetime);
184 gren.nextthink = time;
188
189 gren.takedamage = DAMAGE_YES;
190 SetResourceExplicit(gren, RES_HEALTH, WEP_CVAR_PRI(WEP_MORTAR, health));
191 gren.damageforcescale = WEP_CVAR_PRI(WEP_MORTAR, damageforcescale);
192 gren.event_damage = W_Mortar_Grenade_Damage;
193 gren.damagedbycontents = true;
195 gren.missile_flags = MIF_SPLASH | MIF_ARC;
196 W_SetupProjVelocity_UP_PRI(gren, WEP_MORTAR);
197
198 gren.angles = vectoangles(gren.velocity);
199 gren.flags = FL_PROJECTILE;
200 IL_PUSH(g_projectiles, gren);
201 IL_PUSH(g_bot_dodge, gren);
202
203 if (WEP_CVAR_PRI(WEP_MORTAR, type) == 0
204 || WEP_CVAR_PRI(WEP_MORTAR, type) == 2)
205 CSQCProjectile(gren, true, PROJECTILE_GRENADE, true);
206 else
208
209 MUTATOR_CALLHOOK(EditProjectile, actor, gren);
210}
211
212void W_Mortar_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
213{
214 W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(WEP_MORTAR, ammo), weaponentity);
215
216 W_SetupShot_ProjectileSize(actor, weaponentity, '-3 -3 -3', '3 3 3', false, 4, SND_MORTAR_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(WEP_MORTAR, damage), thiswep.m_id | HITTYPE_SECONDARY);
217 w_shotdir = v_forward; // no TrueAim for grenades please
218
219 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
220
221 entity gren = new(grenade);
222 gren.owner = gren.realowner = actor;
223 gren.bot_dodge = true;
224 gren.bot_dodgerating = WEP_CVAR_SEC(WEP_MORTAR, damage);
226 gren.bouncefactor = WEP_CVAR(WEP_MORTAR, bouncefactor);
227 gren.bouncestop = WEP_CVAR(WEP_MORTAR, bouncestop);
229 gren.projectiledeathtype = thiswep.m_id | HITTYPE_SECONDARY;
230 gren.weaponentity_fld = weaponentity;
231 setorigin(gren, w_shotorg);
232 setsize(gren, '-3 -3 -3', '3 3 3');
233
234 gren.nextthink = time + WEP_CVAR_SEC(WEP_MORTAR, lifetime);
238
239 gren.takedamage = DAMAGE_YES;
240 SetResourceExplicit(gren, RES_HEALTH, WEP_CVAR_SEC(WEP_MORTAR, health));
241 gren.damageforcescale = WEP_CVAR_SEC(WEP_MORTAR, damageforcescale);
242 gren.event_damage = W_Mortar_Grenade_Damage;
243 gren.damagedbycontents = true;
245 gren.missile_flags = MIF_SPLASH | MIF_ARC;
246 W_SetupProjVelocity_UP_SEC(gren, WEP_MORTAR);
247
248 gren.angles = vectoangles(gren.velocity);
249 gren.flags = FL_PROJECTILE;
250 IL_PUSH(g_projectiles, gren);
251 IL_PUSH(g_bot_dodge, gren);
252
253 if (WEP_CVAR_SEC(WEP_MORTAR, type) == 0 || WEP_CVAR_SEC(WEP_MORTAR, type) == 2)
254 CSQCProjectile(gren, true, PROJECTILE_GRENADE, true);
255 else
257
258 MUTATOR_CALLHOOK(EditProjectile, actor, gren);
259}
260
261.bool bot_secondary_grenademooth; // whatever a mooth is
262
263METHOD(Mortar, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
264{
265 PHYS_INPUT_BUTTON_ATCK(actor) = false;
266 PHYS_INPUT_BUTTON_ATCK2(actor) = false;
267 if (!actor.bot_secondary_grenademooth) // WEAPONTODO: merge this into using WEP_CVAR_BOTH
268 {
269 if (bot_aim(actor, weaponentity, WEP_CVAR_PRI(WEP_MORTAR, speed), WEP_CVAR_PRI(WEP_MORTAR, speed_up), WEP_CVAR_PRI(WEP_MORTAR, lifetime), true, true))
270 {
271 PHYS_INPUT_BUTTON_ATCK(actor) = true;
272 if (random() < 0.01)
273 actor.bot_secondary_grenademooth = true;
274 }
275 }
276 else
277 {
278 if (bot_aim(actor, weaponentity, WEP_CVAR_SEC(WEP_MORTAR, speed), WEP_CVAR_SEC(WEP_MORTAR, speed_up), WEP_CVAR_SEC(WEP_MORTAR, lifetime), true, true))
279 {
280 PHYS_INPUT_BUTTON_ATCK2(actor) = true;
281 if (random() < 0.02)
282 actor.bot_secondary_grenademooth = false;
283 }
284 }
285}
286
287/*case WR_CALCINFO:
288{
289 wepinfo_pri_refire = max3(sys_frametime, WEP_CVAR_PRI(WEP_MORTAR, refire), WEP_CVAR_PRI(WEP_MORTAR, animtime));
290 wepinfo_pri_dps = (WEP_CVAR_PRI(WEP_MORTAR, damage) * (1 / wepinfo_pri_refire));
291 wepinfo_pri_speed = (1 / max(1, (10000 / max(1, WEP_CVAR_PRI(WEP_MORTAR, speed)))));
292
293 // for the range calculation, closer to 1 is better
294 wepinfo_pri_range_max = 2000 * wepinfo_pri_speed;
295 wepinfo_pri_range = wepinfo_pri_speed * WEP_CVAR_PRI(WEP_MORTAR,
296
297 wepinfo_sec_refire = max3(sys_frametime, WEP_CVAR_SEC(WEP_MORTAR, refire), WEP_CVAR_SEC(WEP_MORTAR, animtime));
298 wepinfo_sec_dps = (WEP_CVAR_SEC(WEP_MORTAR, damage) * (1 / wepinfo_sec_refire));
299
300 wepinfo_sec_dps = (WEP_CVAR_SEC(WEP_MORTAR, damage) * (1 / max3(sys_frametime, WEP_CVAR_SEC(WEP_MORTAR, refire), WEP_CVAR_SEC(WEP_MORTAR, animtime))));
301 wepinfo_ter_dps = 0;
302 */
303
304METHOD(Mortar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
305{
306 if (autocvar_g_balance_mortar_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(WEP_MORTAR, ammo), WEP_CVAR_SEC(WEP_MORTAR, ammo)))
307 { // forced reload
308 thiswep.wr_reload(thiswep, actor, weaponentity);
309 return;
310 }
311
312 if (fire & 1)
313 {
314 if (weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_MORTAR, refire)))
315 {
316 W_Mortar_Attack(thiswep, actor, weaponentity);
317 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_MORTAR, animtime), w_ready);
318 }
319 }
320 else if (fire & 2)
321 {
322 if (WEP_CVAR_SEC(WEP_MORTAR, remote_detonateprimary))
323 {
324 bool nade_found = false;
325 IL_EACH(g_projectiles, it.realowner == actor && it.classname == "grenade",
326 {
327 if (!it.gl_detonate_later)
328 {
329 it.gl_detonate_later = true;
330 nade_found = true;
331 }
332 });
333 if (nade_found)
334 sound(actor, CH_WEAPON_B, SND_MORTAR_DET, VOL_BASE, ATTN_NORM);
335 }
336 else if (weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_MORTAR, refire)))
337 {
338 W_Mortar_Attack2(thiswep, actor, weaponentity);
339 weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_MORTAR, animtime), w_ready);
340 }
341 }
342}
343
344METHOD(Mortar, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
345{
346 float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_MORTAR, ammo);
347 ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_MORTAR, ammo);
348 return ammo_amount;
349}
350
351METHOD(Mortar, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
352{
353 float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(WEP_MORTAR, ammo);
354 ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(WEP_MORTAR, ammo);
355 return ammo_amount;
356}
357
358METHOD(Mortar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
359{
360 W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(WEP_MORTAR, ammo), WEP_CVAR_SEC(WEP_MORTAR, ammo)), SND_RELOAD); // WEAPONTODO
361}
362
363METHOD(Mortar, wr_suicidemessage, Notification(entity thiswep))
364{
366 return WEAPON_MORTAR_SUICIDE_BOUNCE;
367 else
368 return WEAPON_MORTAR_SUICIDE_EXPLODE;
369}
370
371METHOD(Mortar, wr_killmessage, Notification(entity thiswep))
372{
374 return WEAPON_MORTAR_MURDER_BOUNCE;
375 else
376 return WEAPON_MORTAR_MURDER_EXPLODE;
377}
378
379#endif // SVQC
380#ifdef CSQC
381
382METHOD(Mortar, wr_impacteffect, void(entity thiswep, entity actor))
383{
384 vector org2 = w_org + w_backoff * 2;
385 pointparticles(EFFECT_GRENADE_EXPLODE, org2, '0 0 0', 1);
386 if (!w_issilent)
387 sound(actor, CH_SHOTS, SND_MORTAR_IMPACT, VOL_BASE, ATTN_NORM);
388}
389
390#endif // CSQC
391#ifdef MENUQC
393
394METHOD(Mortar, describe, string(Mortar this))
395{
396 TC(Mortar, this);
398 PAR(_("The %s launches a grenade that explodes immediately on impact, dealing a medium amount of splash damage."), COLORED_NAME(this));
399 PAR(_("The secondary fire shoots a similar grenade that explodes shortly after bouncing."));
400 PAR(_("It consumes %s ammo for every grenade launched."), COLORED_NAME(ITEM_Rockets));
401 PAR(_("The %s works best at close to medium ranges, but it's quite tricky to hit an enemy if they're airborne. "
402 "Since the secondary fire grenade bounces before exploding, it can be bounced against walls to damage enemies lurking around a corner."), COLORED_NAME(this));
403 PAR(W_Guide_Keybinds(this));
404 PAR(W_Guide_DPS(this.netname, "primary", "secondary"));
405 return PAGE_TEXT;
406}
407
408#endif // MENUQC
bool bot_aim(entity this,.entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, float applygravity, bool shot_accurate)
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
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.
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:42
int m_id
Definition weapon.qh:43
string netname
Definition powerups.qc:20
float lifetime
Definition powerups.qc:23
float cnt
Definition powerups.qc:24
float gravity
Definition items.qh:17
#define COLORED_NAME(this)
Definition color.qh:195
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
#define PHYS_INPUT_BUTTON_ATCK(s)
Definition player.qh:152
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition player.qh:154
const int FL_PROJECTILE
Definition constants.qh:85
vector velocity
const float SOLID_NOT
float time
float nextthink
vector v_forward
vector origin
const float ATTN_NORM
#define use
void UpdateCSQCProjectile(entity e)
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
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
IntrusiveList g_damagedbycontents
Definition damage.qh:143
vector w_org
int w_deathtype
float damageforcescale
vector w_backoff
float w_issilent
const int HITTYPE_BOUNCE
Definition all.qh:31
const int HITTYPE_SECONDARY
Definition all.qh:29
float speed
Definition dynlight.qc:9
#define pointparticles(effect, org, vel, howmany)
Definition effect.qh:7
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:120
solid
Definition ent_cs.qc:165
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define IL_EACH(this, cond, body)
#define TC(T, sym)
Definition _all.inc:82
vector movedir
Definition viewloc.qh:18
float random(void)
vector vectoangles(vector v)
float min(float f,...)
void W_Mortar_Attack2(Weapon thiswep, entity actor,.entity weaponentity)
Definition mortar.qc:212
void W_Mortar_Grenade_Explode2(entity this, entity directhitentity)
Definition mortar.qc:38
void W_Mortar_Grenade_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition mortar.qc:71
void W_Mortar_Grenade_Explode_use(entity this, entity actor, entity trigger)
Definition mortar.qc:33
void W_Mortar_Grenade_Think1(entity this)
Definition mortar.qc:83
void W_Mortar_Grenade_Touch2(entity this, entity toucher)
Definition mortar.qc:127
void W_Mortar_Grenade_Explode(entity this, entity directhitentity)
Definition mortar.qc:5
void W_Mortar_Grenade_Explode2_use(entity this, entity actor, entity trigger)
Definition mortar.qc:66
void W_Mortar_Attack(Weapon thiswep, entity actor,.entity weaponentity)
Definition mortar.qc:161
bool bot_secondary_grenademooth
Definition mortar.qc:261
void W_Mortar_Grenade_Touch1(entity this, entity toucher)
Definition mortar.qc:96
float gl_bouncecnt
Definition mortar.qh:81
float gl_detonate_later
Definition mortar.qh:80
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_NONE
Definition movetypes.qh:129
float bouncefactor
Definition movetypes.qh:47
float move_movetype
Definition movetypes.qh:76
float bouncestop
Definition movetypes.qh:46
const int MOVETYPE_BOUNCE
Definition movetypes.qh:139
var void func_null()
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1573
entity Notification
always last
Definition all.qh:81
#define METHOD(cname, name, prototype)
Definition oo.qh:269
#define NULL
Definition post.qh:14
const int PROJECTILE_GRENADE_BOUNCING
Definition projectiles.qh:9
const int PROJECTILE_GRENADE
Definition projectiles.qh:8
float health
Legacy fields for the resources. To be removed.
Definition resources.qh:9
#define setthink(e, f)
vector
Definition self.qh:92
entity entity toucher
Definition self.qh:72
#define settouch(e, f)
Definition self.qh:73
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
void adaptor_think2use_hittype_splash(entity this)
Definition common.qc:106
const int MIF_SPLASH
Definition common.qh:46
int projectiledeathtype
Definition common.qh:21
#define PROJECTILE_TOUCH(e, t)
Definition common.qh:28
IntrusiveList g_projectiles
Definition common.qh:58
const int MIF_ARC
Definition common.qh:47
#define PROJECTILE_MAKETRIGGER(e)
Definition common.qh:34
const float VOL_BASE
Definition sound.qh:36
const int CH_SHOTS
Definition sound.qh:14
const int CH_WEAPON_A
Definition sound.qh:7
#define sound(e, c, s, v, a)
Definition sound.qh:52
const int CH_WEAPON_B
Definition sound.qh:8
Sound SND_GRENADE_BOUNCE_RANDOM()
Definition all.inc:17
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
#define PAGE_TEXT
Definition string.qh:642
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
Definition string.qh:648
#define PAGE_TEXT_INIT()
Definition string.qh:641
const int DAMAGE_YES
Definition subs.qh:80
const int DAMAGE_NO
Definition subs.qh:79
const int DAMAGE_AIM
Definition subs.qh:81
float takedamage
Definition subs.qh:78
float ammo
Definition sv_turrets.qh:43
#define DIFF_TEAM(a, b)
Definition teams.qh:242
entity realowner
#define W_SetupProjVelocity_UP_PRI(ent, wep)
Definition tracing.qh:54
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_UP_SEC(ent, wep)
Definition tracing.qh:56
string W_Guide_Keybinds(Weapon wep)
Definition all.qc:824
string W_Guide_DPS(string name, string pri, string sec)
Definition all.qc:918
void W_MuzzleFlash(Weapon thiswep, entity actor,.entity weaponentity, vector shotorg, vector shotdir)
Definition all.qc:715
#define WEP_CVAR_PRI(wep, name)
Definition all.qh:338
#define WEP_CVAR(wep, name)
Definition all.qh:337
#define WEP_CVAR_SEC(wep, name)
Definition all.qh:339
void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use,.entity weaponentity)
void W_Reload(entity actor,.entity weaponentity, float sent_ammo_min, Sound sent_sound)
void weapon_thinkf(entity actor,.entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor,.entity weaponentity, int fire) func)
bool weapon_prepareattack(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
void w_ready(Weapon thiswep, entity actor,.entity weaponentity, int fire)
entity weaponentity_fld
float weapon_load[REGISTRY_MAX(Weapons)]