Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
shotgun.qc
Go to the documentation of this file.
1#include "shotgun.qh"
2
3#ifdef SVQC
4
5// enable to debug melee range
6//#define SHOTGUN_MELEEDEBUG
7
8void W_Shotgun_Attack(Weapon thiswep, entity actor, .entity weaponentity,
9 bool is_primary, float ammocount, float damage,
10 float falloff_halflife, float falloff_mindist, float falloff_maxdist,
11 float bullets, float spread,
12 float spread_pattern, float spread_pattern_scale, float spread_pattern_bias,
13 float solidpenetration,
14 float force, float falloff_forcehalflife,
15 entity bullet_trail_effect)
16{
17 W_DecreaseAmmo(thiswep, actor, ammocount, weaponentity);
18
19 W_SetupShot(actor, weaponentity, true, 5, SND_SHOTGUN_FIRE,
20 (is_primary ? CH_WEAPON_A : CH_WEAPON_SINGLE), damage * bullets, thiswep.m_id);
21
22 // TRICK: do the antilag outside the regular fireBullet function,
23 // so it isn't performed unnecessarily on every single bullet!
24 float lag = antilag_getlag(actor);
25 if (lag && bullets > 0)
26 antilag_takeback_all(actor, lag);
27
28 if (spread_pattern && spread_pattern_scale > 0)
29 {
30 vector right = v_right;
31 vector up = v_up;
32
33 float fixed_spread_factor = (spread * autocvar_g_weaponspreadfactor) / spread_pattern_scale;
34 spread_pattern_bias = bound(0, spread_pattern_bias, 1);
35 for (int sc = 0; sc < bullets; ++sc)
36 {
37 vector s = W_CalculateSpreadPattern(spread_pattern, spread_pattern_bias, sc, bullets);
38 s *= fixed_spread_factor;
39 fireBullet_falloff(actor, weaponentity, w_shotorg, w_shotdir + right * s.y + up * s.z,
40 0,
41 solidpenetration,
42 damage,
43 falloff_halflife,
44 falloff_mindist,
45 falloff_maxdist,
46 0,
47 force,
48 falloff_forcehalflife,
49 thiswep.m_id,
50 bullet_trail_effect,
51 false
52 );
53 }
54 }
55 else
56 for (int sc = 0; sc < bullets; ++sc)
57 fireBullet_falloff(actor, weaponentity, w_shotorg, w_shotdir,
58 spread,
59 solidpenetration,
60 damage,
61 falloff_halflife,
62 falloff_mindist,
63 falloff_maxdist,
64 0,
65 force,
66 falloff_forcehalflife,
67 thiswep.m_id,
68 bullet_trail_effect,
69 false
70 );
71
72 if (lag && bullets > 0)
74
75 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
76
77 // casing code
78 if (autocvar_g_casings >= 1)
79 {
80 makevectors(actor.v_angle); // for some reason, this is lost
81 //for (int sc = 0; sc < WEP_CVAR_PRI(WEP_SHOTGUN, ammo); ++sc)
82 SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 30) * v_up), vectoangles(v_forward), 1, actor, weaponentity);
83 }
84}
85
89{
90 if (!this.cnt) // set start time of melee
91 {
92 this.cnt = time;
94 }
95
96 makevectors(this.realowner.v_angle); // update values for v_* vectors
97
98 // calculate swing percentage based on time
99 float meleetime = WEP_CVAR_SEC(WEP_SHOTGUN, melee_time) * W_WeaponRateFactor(this.realowner);
100 float swing = bound(0, (this.cnt + meleetime - time) / meleetime, 10);
101 float f = ((1 - swing) * WEP_CVAR_SEC(WEP_SHOTGUN, melee_traces));
102
103 // check to see if we can still continue, otherwise give up now
104 if (IS_DEAD(this.realowner) && WEP_CVAR_SEC(WEP_SHOTGUN, melee_no_doubleslap))
105 {
106 delete(this);
107 return;
108 }
109
110 vector melee_path = (v_up * WEP_CVAR_SEC(WEP_SHOTGUN, melee_swing_up))
111 + (v_right * WEP_CVAR_SEC(WEP_SHOTGUN, melee_swing_side));
112 // if okay, perform the traces needed for this frame
113 entity target_victim;
114 vector targpos;
115 float swing_factor, swing_damage, i;
116 for (i = this.swing_prev; i < f; ++i)
117 {
118 swing_factor = (1 - (i / WEP_CVAR_SEC(WEP_SHOTGUN, melee_traces))) * 2 - 1;
119
120 targpos = this.realowner.origin + this.realowner.view_ofs
121 + (melee_path * swing_factor)
122 + (v_forward * WEP_CVAR_SEC(WEP_SHOTGUN, melee_range));
123
124 WarpZone_traceline_antilag(this.realowner, this.realowner.origin + this.realowner.view_ofs, targpos, false, this.realowner, ((IS_CLIENT(this.realowner)) ? ANTILAG_LATENCY(this.realowner) : 0));
125
126 Send_Effect(EFFECT_SHOTGUN_WOOSH, trace_endpos, -melee_path, 1);
127
128 // draw lightning beams for debugging
129 #ifdef SHOTGUN_MELEEDEBUG
130 te_lightning2(NULL, targpos, this.realowner.origin + this.realowner.view_ofs + v_forward * 5 - v_up * 5);
131 te_customflash(targpos, 40, 2, '1 1 1');
132 #endif
133
134 bool is_player = (IS_PLAYER(trace_ent) || trace_ent.classname == "body" || IS_MONSTER(trace_ent));
135
136 if (trace_fraction < 1 // if trace is good, apply the damage and remove this
137 && trace_ent.takedamage != DAMAGE_NO
138 && trace_ent != this.swing_alreadyhit
139 && (is_player || WEP_CVAR_SEC(WEP_SHOTGUN, melee_nonplayerdamage)))
140 {
141 target_victim = trace_ent; // so it persists through other calls
142
143 if (is_player) // this allows us to be able to nerf the non-player damage done in e.g. assault or onslaught.
144 swing_damage = (WEP_CVAR_SEC(WEP_SHOTGUN, damage) * min(1, swing_factor + 1));
145 else
146 swing_damage = (WEP_CVAR_SEC(WEP_SHOTGUN, melee_nonplayerdamage) * min(1, swing_factor + 1));
147
148 //print(strcat(this.realowner.netname, " hitting ", target_victim.netname, " with ", strcat(ftos(swing_damage), " damage (factor: ", ftos(swing_factor), ") at "), ftos(time), " seconds.\n"));
149
150 Damage(target_victim, this.realowner, this.realowner,
151 swing_damage,
152 WEP_SHOTGUN.m_id | HITTYPE_SECONDARY,
153 this.weaponentity_fld,
154 this.realowner.origin + this.realowner.view_ofs,
155 v_forward * WEP_CVAR_SEC(WEP_SHOTGUN, force)
156 );
157
158 if (accuracy_isgooddamage(this.realowner, target_victim))
159 accuracy_add(this.realowner, WEP_SHOTGUN, 0, swing_damage, 0); // add to hit
160
161 // draw large red flash for debugging
162 #ifdef SHOTGUN_MELEEDEBUG
163 te_customflash(targpos, 200, 2, '15 0 0');
164 #endif
165
166 if (WEP_CVAR_SEC(WEP_SHOTGUN, melee_multihit)) // allow multiple hits with one swing, but not against the same player twice.
167 {
168 this.swing_alreadyhit = target_victim;
169 continue; // move along to next trace
170 }
171 else
172 {
173 delete(this);
174 return;
175 }
176 }
177 }
178
179 if (time >= this.cnt + meleetime)
180 {
181 // melee is finished
182 delete(this);
183 return;
184 }
185 else
186 {
187 // set up next frame
188 this.swing_prev = i;
189 this.nextthink = time;
190 }
191}
192
193void W_Shotgun_Attack2(Weapon thiswep, entity actor, .entity weaponentity, int fire)
194{
195 sound(actor, CH_WEAPON_A, SND_SHOTGUN_MELEE, VOL_BASE, ATTEN_NORM);
196 weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_SHOTGUN, animtime), w_ready);
197
198 entity meleetemp = new_pure(meleetemp);
199 meleetemp.realowner = actor;
201 meleetemp.nextthink = time + WEP_CVAR_SEC(WEP_SHOTGUN, melee_delay) * W_WeaponRateFactor(actor);
202 meleetemp.weaponentity_fld = weaponentity;
203 W_SetupShot_Range(actor, weaponentity, true, 0, SND_Null, 0, WEP_CVAR_SEC(WEP_SHOTGUN, damage), WEP_CVAR_SEC(WEP_SHOTGUN, melee_range), WEP_SHOTGUN.m_id | HITTYPE_SECONDARY);
204}
205
206// alternate secondary weapon frames
207void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor, .entity weaponentity, int fire)
208{
209 if (!thiswep.wr_checkammo2(thiswep, actor, weaponentity)
210 && !(actor.items & IT_UNLIMITED_AMMO))
211 {
212 W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
213 w_ready(thiswep, actor, weaponentity, fire);
214 return;
215 }
216
217 sound(actor, CH_WEAPON_SINGLE, SND_Null, VOL_BASE, ATTN_NORM); // kill previous sound
218 W_Shotgun_Attack(thiswep, actor, weaponentity, true,
219 WEP_CVAR_PRI(WEP_SHOTGUN, ammo),
220 WEP_CVAR_PRI(WEP_SHOTGUN, damage),
221 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_halflife),
222 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_mindist),
223 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_maxdist),
224 WEP_CVAR_PRI(WEP_SHOTGUN, bullets),
225 WEP_CVAR_PRI(WEP_SHOTGUN, spread),
226 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern),
227 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_scale),
228 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_bias),
229 WEP_CVAR_PRI(WEP_SHOTGUN, solidpenetration),
230 WEP_CVAR_PRI(WEP_SHOTGUN, force),
231 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_forcehalflife),
232 EFFECT_BULLET_WEAK
233 ); // actually is secondary, but we trick the last shot into playing full reload sound
234 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime), w_ready);
235}
236void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, .entity weaponentity, int fire)
237{
238 if (!thiswep.wr_checkammo2(thiswep, actor, weaponentity)
239 && !(actor.items & IT_UNLIMITED_AMMO))
240 {
241 W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
242 w_ready(thiswep, actor, weaponentity, fire);
243 return;
244 }
245
246 W_Shotgun_Attack(thiswep, actor, weaponentity, false,
247 WEP_CVAR_PRI(WEP_SHOTGUN, ammo),
248 WEP_CVAR_PRI(WEP_SHOTGUN, damage),
249 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_halflife),
250 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_mindist),
251 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_maxdist),
252 WEP_CVAR_PRI(WEP_SHOTGUN, bullets),
253 WEP_CVAR_PRI(WEP_SHOTGUN, spread),
254 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern),
255 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_scale),
256 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_bias),
257 WEP_CVAR_PRI(WEP_SHOTGUN, solidpenetration),
258 WEP_CVAR_PRI(WEP_SHOTGUN, force),
259 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_forcehalflife),
260 EFFECT_BULLET_WEAK
261 );
262 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime), W_Shotgun_Attack3_Frame2);
263}
264
266
267METHOD(Shotgun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
268{
269 if (vdist(actor.origin - actor.enemy.origin, <=, WEP_CVAR_SEC(WEP_SHOTGUN, melee_range)))
270 PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false);
271 else
272 PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false);
273}
274
275METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
276{
277 // force reload weapon when clip is empty or insufficent
278 if (WEP_CVAR(WEP_SHOTGUN, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR_PRI(WEP_SHOTGUN, ammo)
279 && actor.(weaponentity).clip_load >= 0 && (GetResource(actor, thiswep.ammo_type) > 0 || (actor.items & IT_UNLIMITED_AMMO)))
280 {
281 thiswep.wr_reload(thiswep, actor, weaponentity);
282 return;
283 }
284
285 if (actor.(weaponentity).clip_load >= 0) // we are not currently reloading
286 {
287 if (fire & 1)
288 {
289 if (time >= actor.(weaponentity).shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
290 if (weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_SHOTGUN, animtime)))
291 {
292 W_Shotgun_Attack(thiswep, actor, weaponentity, true,
293 WEP_CVAR_PRI(WEP_SHOTGUN, ammo),
294 WEP_CVAR_PRI(WEP_SHOTGUN, damage),
295 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_halflife),
296 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_mindist),
297 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_maxdist),
298 WEP_CVAR_PRI(WEP_SHOTGUN, bullets),
299 WEP_CVAR_PRI(WEP_SHOTGUN, spread),
300 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern),
301 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_scale),
302 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_bias),
303 WEP_CVAR_PRI(WEP_SHOTGUN, solidpenetration),
304 WEP_CVAR_PRI(WEP_SHOTGUN, force),
305 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_forcehalflife),
306 EFFECT_BULLET_WEAK
307 );
308 actor.(weaponentity).shotgun_primarytime = time + WEP_CVAR_PRI(WEP_SHOTGUN, refire) * W_WeaponRateFactor(actor);
309 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_SHOTGUN, animtime), w_ready);
310 return;
311 }
312 }
313 else if ((fire & 2) && WEP_CVAR(WEP_SHOTGUN, secondary) == 2)
314 {
315 if (time >= actor.(weaponentity).shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
316 if (weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime)))
317 {
318 W_Shotgun_Attack(thiswep, actor, weaponentity, false,
319 WEP_CVAR_PRI(WEP_SHOTGUN, ammo),
320 WEP_CVAR_PRI(WEP_SHOTGUN, damage),
321 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_halflife),
322 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_mindist),
323 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_maxdist),
324 WEP_CVAR_PRI(WEP_SHOTGUN, bullets),
325 WEP_CVAR_PRI(WEP_SHOTGUN, spread),
326 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern),
327 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_scale),
328 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_bias),
329 WEP_CVAR_PRI(WEP_SHOTGUN, solidpenetration),
330 WEP_CVAR_PRI(WEP_SHOTGUN, force),
331 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_forcehalflife),
332 EFFECT_BULLET_WEAK
333 );
334 actor.(weaponentity).shotgun_primarytime = time + WEP_CVAR_SEC(WEP_SHOTGUN, alt_refire) * W_WeaponRateFactor(actor);
335 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime), W_Shotgun_Attack3_Frame1);
336 return;
337 }
338 }
339 }
340
341 if (actor.(weaponentity).clip_load >= 0 // we are not currently reloading
342 && WEP_CVAR(WEP_SHOTGUN, secondary) == 1
343 && (((fire & 1) && !IS_BOT_CLIENT(actor) && GetResource(actor, thiswep.ammo_type) <= 0 && actor.(weaponentity).clip_load == 0 && !(actor.items & IT_UNLIMITED_AMMO))
344 || (fire & 2))
345 && (!WEP_CVAR_SEC(WEP_SHOTGUN, melee_blockedbyfiring) || time >= actor.(weaponentity).shotgun_primarytime)
346 && weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_SHOTGUN, refire)))
347 {
348 // melee attack
349 // attempt forcing playback of the anim by switching to another anim (that we never play) here...
350 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shotgun_Attack2);
351 }
352}
353
354METHOD(Shotgun, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
355{
356 float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo);
357 ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo);
358 return ammo_amount;
359}
360
361METHOD(Shotgun, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
362{
363 switch (WEP_CVAR(WEP_SHOTGUN, secondary))
364 {
365 case 1:
366 return true; // melee does not use ammo
367 case 2: // secondary triple shot
368 {
369 float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo);
370 ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo);
371 return ammo_amount;
372 }
373 default:
374 return false; // secondary unavailable
375 }
376}
377
378METHOD(Shotgun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
379{
380 W_Reload(actor, weaponentity, WEP_CVAR_PRI(WEP_SHOTGUN, ammo), SND_RELOAD); // WEAPONTODO
381}
382
383METHOD(Shotgun, wr_suicidemessage, Notification(entity thiswep))
384{
385 return WEAPON_THINKING_WITH_PORTALS;
386}
387
388METHOD(Shotgun, wr_killmessage, Notification(entity thiswep))
389{
391 return WEAPON_SHOTGUN_MURDER_SLAP;
392 else
393 return WEAPON_SHOTGUN_MURDER;
394}
395
396#endif // SVQC
397#ifdef CSQC
398.float prevric;
399
400METHOD(Shotgun, wr_impacteffect, void(entity thiswep, entity actor))
401{
402 vector org2 = w_org + w_backoff * 2;
403 pointparticles(EFFECT_SHOTGUN_IMPACT, org2, w_backoff * 1000, 1);
404 if (!w_issilent && time - actor.prevric > 0.25)
405 {
406 if (w_random < 0.05)
408 actor.prevric = time;
409 }
410}
411
412#endif // CSQC
413#ifdef MENUQC
415
416METHOD(Shotgun, describe, string(Shotgun this))
417{
418 TC(Shotgun, this);
420 PAR(_("The %s is one of the two main default weapons, firing a single shotgun round which spreads into multiple pellets upon exiting the barrel."), COLORED_NAME(this));
421 PAR(_("The secondary fire swings the %s, slapping players close enough with the head of the weapon. "
422 "Since the slap takes a moment to land, timing this well is difficult."), COLORED_NAME(this));
423 PAR(_("The primary fire consumes %s ammo, although if you spawn in with the %s you will already have some."), COLORED_NAME(ITEM_Shells), COLORED_NAME(this));
424 PAR(_("The %s damage drops off quickly as the range increases, so it is only useful for close combat or sometimes medium range combat."), COLORED_NAME(this));
425 PAR(W_Guide_Keybinds(this));
426 PAR(W_Guide_DPS_primaryMultishot(this.netname, "primary", "secondary", "primary_bullets", ""));
427 return PAGE_TEXT;
428}
429
430#endif // MENUQC
void accuracy_add(entity this, Weapon w, float fired, float hit, float real)
update accuracy stats
Definition accuracy.qc:102
bool accuracy_isgooddamage(entity attacker, entity targ)
does this damage count towards accuracy stats?
Definition accuracy.qc:133
void antilag_takeback_all(entity ignore, float lag)
Definition antilag.qc:125
void WarpZone_traceline_antilag(entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
Definition antilag.qc:221
float antilag_getlag(entity e)
Definition antilag.qc:151
void antilag_restore_all(entity ignore)
Definition antilag.qc:138
#define ANTILAG_LATENCY(e)
Definition antilag.qh:19
bool bot_aim(entity this,.entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, float applygravity, bool shot_accurate)
vector W_CalculateSpreadPattern(int pattern, float bias, int counter, int total)
float autocvar_g_weaponspreadfactor
void SpawnCasing(vector vel, vector ang, int casingtype, entity casingowner,.entity weaponentity)
Definition casings.qc:17
int autocvar_g_casings
Definition casings.qh:17
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.
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
virtual void wr_checkammo2()
(SERVER) checks ammo for weapon second
Definition weapon.qh:105
string netname
Definition powerups.qc:20
float cnt
Definition powerups.qc:24
#define COLORED_NAME(this)
Definition color.qh:195
const int IT_UNLIMITED_AMMO
Definition item.qh:23
#define IS_CLIENT(s)
Definition player.qh:241
#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
float W_WeaponRateFactor(entity this)
vector v_up
entity trace_ent
float time
vector v_right
vector trace_endpos
float nextthink
vector v_forward
float trace_fraction
const float ATTN_NORM
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition damage.qc:493
void W_SwitchWeapon_Force(Player this, Weapon w,.entity weaponentity)
Definition selection.qc:237
vector w_org
int w_deathtype
float w_random
vector w_backoff
float w_issilent
const int HITTYPE_SECONDARY
Definition all.qh:29
#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
#define TC(T, sym)
Definition _all.inc:82
float bound(float min, float value, float max)
float random(void)
vector vectoangles(vector v)
float min(float f,...)
entity Notification
always last
Definition all.qh:81
float prevric
Definition okshotgun.qc:101
#define new_pure(class)
purely logical entities (not linked to the area grid)
Definition oo.qh:67
#define METHOD(cname, name, prototype)
Definition oo.qh:269
#define NULL
Definition post.qh:14
#define makevectors
Definition post.qh:21
#define w_getbestweapon(ent, wepent)
Definition selection.qh:23
#define setthink(e, f)
vector
Definition self.qh:92
void W_PlayStrengthSound(entity player)
Definition common.qc:40
float shotgun_primarytime
Definition shotgun.qc:265
void W_Shotgun_Attack2(Weapon thiswep, entity actor,.entity weaponentity, int fire)
Definition shotgun.qc:193
float swing_prev
Definition shotgun.qc:86
void W_Shotgun_Attack(Weapon thiswep, entity actor,.entity weaponentity, bool is_primary, float ammocount, float damage, float falloff_halflife, float falloff_mindist, float falloff_maxdist, float bullets, float spread, float spread_pattern, float spread_pattern_scale, float spread_pattern_bias, float solidpenetration, float force, float falloff_forcehalflife, entity bullet_trail_effect)
Definition shotgun.qc:8
entity swing_alreadyhit
Definition shotgun.qc:87
void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor,.entity weaponentity, int fire)
Definition shotgun.qc:236
void W_Shotgun_Melee_Think(entity this)
Definition shotgun.qc:88
void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor,.entity weaponentity, int fire)
Definition shotgun.qc:207
const int CH_WEAPON_SINGLE
Definition sound.qh:9
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
const float ATTEN_NORM
Definition sound.qh:30
#define sound(e, c, s, v, a)
Definition sound.qh:52
Sound SND_RIC_RANDOM()
Definition all.inc:33
#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_NO
Definition subs.qh:79
float ammo
Definition sv_turrets.qh:43
entity realowner
void fireBullet_falloff(entity this,.entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float falloff_halflife, float falloff_mindist, float falloff_maxdist, float headshot_multiplier, float force, float falloff_forcehalflife, float dtype, entity tracer_effect, bool do_antilag)
Definition tracing.qc:356
vector w_shotdir
Definition tracing.qh:20
vector w_shotorg
Definition tracing.qh:19
#define W_SetupShot_Range(ent, wepent, antilag, recoil, snd, chan, maxdamage, range, deathtype)
Definition tracing.qh:36
#define W_SetupShot(ent, wepent, antilag, recoil, snd, chan, maxdamage, deathtype)
Definition tracing.qh:34
#define IS_MONSTER(v)
Definition utils.qh:23
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition utils.qh:15
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8
string W_Guide_Keybinds(Weapon wep)
Definition all.qc:824
string W_Guide_DPS_primaryMultishot(string name, string pri, string sec, string shots, string refire2)
Definition all.qc:973
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)
float weapon_load[REGISTRY_MAX(Weapons)]