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 float isprimary, 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 ((isprimary) ? 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, up;
31 right = v_right;
32 up = v_up;
33
34 float fixed_spread_factor = (spread * autocvar_g_weaponspreadfactor) / spread_pattern_scale;
35 spread_pattern_bias = bound(0, spread_pattern_bias, 1);
36 for(int sc = 0; sc < bullets; ++sc)
37 {
38 vector s = W_CalculateSpreadPattern(spread_pattern, spread_pattern_bias, sc, bullets);
39 s = s * fixed_spread_factor;
40 fireBullet_falloff(actor, weaponentity,
41 w_shotorg, w_shotdir + right * s.y + up * s.z,
42 0, solidpenetration, damage,
43 falloff_halflife, falloff_mindist, falloff_maxdist,
44 0, force, falloff_forcehalflife,
45 thiswep.m_id, bullet_trail_effect, false);
46 }
47 }
48 else
49 for(int sc = 0; sc < bullets; ++sc)
50 fireBullet_falloff(actor, weaponentity,
52 spread, solidpenetration, damage,
53 falloff_halflife, falloff_mindist, falloff_maxdist,
54 0, force, falloff_forcehalflife,
55 thiswep.m_id, bullet_trail_effect, false);
56
57 if(lag && bullets > 0)
59
60 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
61
62 // casing code
63 if(autocvar_g_casings >= 1)
64 {
65 makevectors(actor.v_angle); // for some reason, this is lost
66 //for(int sc = 0; sc < WEP_CVAR_PRI(WEP_SHOTGUN, ammo); ++sc)
67 SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 30) * v_up), vectoangles(v_forward), 1, actor, weaponentity);
68 }
69}
70
74{
75 // declarations
76 float i, f, swing, swing_factor, swing_damage, meleetime, is_player;
77 entity target_victim;
78 vector targpos, melee_path;
79
80 if(!this.cnt) // set start time of melee
81 {
82 this.cnt = time;
84 }
85
86 makevectors(this.realowner.v_angle); // update values for v_* vectors
87
88 // calculate swing percentage based on time
89 meleetime = WEP_CVAR_SEC(WEP_SHOTGUN, melee_time) * W_WeaponRateFactor(this.realowner);
90 swing = bound(0, (this.cnt + meleetime - time) / meleetime, 10);
91 f = ((1 - swing) * WEP_CVAR_SEC(WEP_SHOTGUN, melee_traces));
92
93 // check to see if we can still continue, otherwise give up now
94 if(IS_DEAD(this.realowner) && WEP_CVAR_SEC(WEP_SHOTGUN, melee_no_doubleslap))
95 {
96 delete(this);
97 return;
98 }
99
100 melee_path = (v_up * WEP_CVAR_SEC(WEP_SHOTGUN, melee_swing_up))
101 + (v_right * WEP_CVAR_SEC(WEP_SHOTGUN, melee_swing_side));
102 // if okay, perform the traces needed for this frame
103 for(i=this.swing_prev; i < f; ++i)
104 {
105 swing_factor = ((1 - (i / WEP_CVAR_SEC(WEP_SHOTGUN, melee_traces))) * 2 - 1);
106
107 targpos = this.realowner.origin + this.realowner.view_ofs
108 + (melee_path * swing_factor)
109 + (v_forward * WEP_CVAR_SEC(WEP_SHOTGUN, melee_range));
110
111 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));
112
113 Send_Effect(EFFECT_SHOTGUN_WOOSH, trace_endpos, -melee_path, 1);
114
115 // draw lightning beams for debugging
116 #ifdef SHOTGUN_MELEEDEBUG
117 te_lightning2(NULL, targpos, this.realowner.origin + this.realowner.view_ofs + v_forward * 5 - v_up * 5);
118 te_customflash(targpos, 40, 2, '1 1 1');
119 #endif
120
121 is_player = (IS_PLAYER(trace_ent) || trace_ent.classname == "body" || IS_MONSTER(trace_ent));
122
123 if((trace_fraction < 1) // if trace is good, apply the damage and remove this
124 && (trace_ent.takedamage != DAMAGE_NO)
125 && (trace_ent != this.swing_alreadyhit)
126 && (is_player || WEP_CVAR_SEC(WEP_SHOTGUN, melee_nonplayerdamage)))
127 {
128 target_victim = trace_ent; // so it persists through other calls
129
130 if(is_player) // this allows us to be able to nerf the non-player damage done in e.g. assault or onslaught.
131 swing_damage = (WEP_CVAR_SEC(WEP_SHOTGUN, damage) * min(1, swing_factor + 1));
132 else
133 swing_damage = (WEP_CVAR_SEC(WEP_SHOTGUN, melee_nonplayerdamage) * min(1, swing_factor + 1));
134
135 //print(strcat(this.realowner.netname, " hitting ", target_victim.netname, " with ", strcat(ftos(swing_damage), " damage (factor: ", ftos(swing_factor), ") at "), ftos(time), " seconds.\n"));
136
137 Damage(target_victim, this.realowner, this.realowner,
138 swing_damage, WEP_SHOTGUN.m_id | HITTYPE_SECONDARY, this.weaponentity_fld,
139 this.realowner.origin + this.realowner.view_ofs,
140 v_forward * WEP_CVAR_SEC(WEP_SHOTGUN, force));
141
142 if(accuracy_isgooddamage(this.realowner, target_victim))
143 accuracy_add(this.realowner, WEP_SHOTGUN, 0, swing_damage, 0); // add to hit
144
145 // draw large red flash for debugging
146 #ifdef SHOTGUN_MELEEDEBUG
147 te_customflash(targpos, 200, 2, '15 0 0');
148 #endif
149
150 if(WEP_CVAR_SEC(WEP_SHOTGUN, melee_multihit)) // allow multiple hits with one swing, but not against the same player twice.
151 {
152 this.swing_alreadyhit = target_victim;
153 continue; // move along to next trace
154 }
155 else
156 {
157 delete(this);
158 return;
159 }
160 }
161 }
162
163 if(time >= this.cnt + meleetime)
164 {
165 // melee is finished
166 delete(this);
167 return;
168 }
169 else
170 {
171 // set up next frame
172 this.swing_prev = i;
173 this.nextthink = time;
174 }
175}
176
177void W_Shotgun_Attack2(Weapon thiswep, entity actor, .entity weaponentity, int fire)
178{
179 sound(actor, CH_WEAPON_A, SND_SHOTGUN_MELEE, VOL_BASE, ATTEN_NORM);
180 weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_SHOTGUN, animtime), w_ready);
181
182 entity meleetemp = new_pure(meleetemp);
183 meleetemp.realowner = actor;
185 meleetemp.nextthink = time + WEP_CVAR_SEC(WEP_SHOTGUN, melee_delay) * W_WeaponRateFactor(actor);
186 meleetemp.weaponentity_fld = weaponentity;
187 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);
188}
189
190// alternate secondary weapon frames
191void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor, .entity weaponentity, int fire)
192{
193 if (!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
194 if (!(actor.items & IT_UNLIMITED_AMMO))
195 {
196 W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
197 w_ready(thiswep, actor, weaponentity, fire);
198 return;
199 }
200
201 sound(actor, CH_WEAPON_SINGLE, SND_Null, VOL_BASE, ATTN_NORM); // kill previous sound
202 W_Shotgun_Attack(thiswep, actor, weaponentity, true,
203 WEP_CVAR_PRI(WEP_SHOTGUN, ammo),
204 WEP_CVAR_PRI(WEP_SHOTGUN, damage),
205 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_halflife),
206 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_mindist),
207 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_maxdist),
208 WEP_CVAR_PRI(WEP_SHOTGUN, bullets),
209 WEP_CVAR_PRI(WEP_SHOTGUN, spread),
210 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern),
211 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_scale),
212 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_bias),
213 WEP_CVAR_PRI(WEP_SHOTGUN, solidpenetration),
214 WEP_CVAR_PRI(WEP_SHOTGUN, force),
215 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_forcehalflife),
216 EFFECT_BULLET_WEAK); // actually is secondary, but we trick the last shot into playing full reload sound
217 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime), w_ready);
218}
219void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, .entity weaponentity, int fire)
220{
221 if (!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
222 if (!(actor.items & IT_UNLIMITED_AMMO))
223 {
224 W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
225 w_ready(thiswep, actor, weaponentity, fire);
226 return;
227 }
228
229 W_Shotgun_Attack(thiswep, actor, weaponentity, false,
230 WEP_CVAR_PRI(WEP_SHOTGUN, ammo),
231 WEP_CVAR_PRI(WEP_SHOTGUN, damage),
232 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_halflife),
233 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_mindist),
234 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_maxdist),
235 WEP_CVAR_PRI(WEP_SHOTGUN, bullets),
236 WEP_CVAR_PRI(WEP_SHOTGUN, spread),
237 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern),
238 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_scale),
239 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_bias),
240 WEP_CVAR_PRI(WEP_SHOTGUN, solidpenetration),
241 WEP_CVAR_PRI(WEP_SHOTGUN, force),
242 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_forcehalflife),
243 EFFECT_BULLET_WEAK);
244 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime), W_Shotgun_Attack3_Frame2);
245}
246
248
249METHOD(Shotgun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
250{
251 if(vdist(actor.origin - actor.enemy.origin, <=, WEP_CVAR_SEC(WEP_SHOTGUN, melee_range)))
252 PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false);
253 else
254 PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false, false);
255}
256
257METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
258{
259 // force reload weapon when clip is empty or insufficent
260 if(WEP_CVAR(WEP_SHOTGUN, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR_PRI(WEP_SHOTGUN, ammo))
261 {
262 if(actor.(weaponentity).clip_load >= 0 && (GetResource(actor, thiswep.ammo_type) > 0 || (actor.items & IT_UNLIMITED_AMMO)))
263 {
264 thiswep.wr_reload(thiswep, actor, weaponentity);
265 return;
266 }
267 }
268
269 if(actor.(weaponentity).clip_load >= 0) // we are not currently reloading
270 {
271 if(fire & 1)
272 {
273 if(time >= actor.(weaponentity).shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
274 {
275 if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(WEP_SHOTGUN, animtime)))
276 {
277 W_Shotgun_Attack(thiswep, actor, weaponentity, true,
278 WEP_CVAR_PRI(WEP_SHOTGUN, ammo),
279 WEP_CVAR_PRI(WEP_SHOTGUN, damage),
280 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_halflife),
281 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_mindist),
282 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_maxdist),
283 WEP_CVAR_PRI(WEP_SHOTGUN, bullets),
284 WEP_CVAR_PRI(WEP_SHOTGUN, spread),
285 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern),
286 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_scale),
287 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_bias),
288 WEP_CVAR_PRI(WEP_SHOTGUN, solidpenetration),
289 WEP_CVAR_PRI(WEP_SHOTGUN, force),
290 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_forcehalflife),
291 EFFECT_BULLET_WEAK);
292 actor.(weaponentity).shotgun_primarytime = time + WEP_CVAR_PRI(WEP_SHOTGUN, refire) * W_WeaponRateFactor(actor);
293 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(WEP_SHOTGUN, animtime), w_ready);
294 return;
295 }
296 }
297 }
298 else if((fire & 2) && WEP_CVAR(WEP_SHOTGUN, secondary) == 2)
299 {
300 if(time >= actor.(weaponentity).shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
301 {
302 if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime)))
303 {
304 W_Shotgun_Attack(thiswep, actor, weaponentity, false,
305 WEP_CVAR_PRI(WEP_SHOTGUN, ammo),
306 WEP_CVAR_PRI(WEP_SHOTGUN, damage),
307 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_halflife),
308 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_mindist),
309 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_maxdist),
310 WEP_CVAR_PRI(WEP_SHOTGUN, bullets),
311 WEP_CVAR_PRI(WEP_SHOTGUN, spread),
312 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern),
313 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_scale),
314 WEP_CVAR_PRI(WEP_SHOTGUN, spread_pattern_bias),
315 WEP_CVAR_PRI(WEP_SHOTGUN, solidpenetration),
316 WEP_CVAR_PRI(WEP_SHOTGUN, force),
317 WEP_CVAR_PRI(WEP_SHOTGUN, damagefalloff_forcehalflife),
318 EFFECT_BULLET_WEAK);
319 actor.(weaponentity).shotgun_primarytime = time + WEP_CVAR_SEC(WEP_SHOTGUN, alt_refire) * W_WeaponRateFactor(actor);
320 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(WEP_SHOTGUN, alt_animtime), W_Shotgun_Attack3_Frame1);
321 return;
322 }
323 }
324 }
325 }
326
327 if(actor.(weaponentity).clip_load >= 0) // we are not currently reloading
328 if(WEP_CVAR(WEP_SHOTGUN, secondary) == 1)
329 if(((fire & 1) && !IS_BOT_CLIENT(actor) && GetResource(actor, thiswep.ammo_type) <= 0 && actor.(weaponentity).clip_load == 0 && !(actor.items & IT_UNLIMITED_AMMO)) || (fire & 2))
330 if(!WEP_CVAR_SEC(WEP_SHOTGUN, melee_blockedbyfiring) || time >= actor.(weaponentity).shotgun_primarytime)
331 if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(WEP_SHOTGUN, refire)))
332 {
333 // melee attack
334 // attempt forcing playback of the anim by switching to another anim (that we never play) here...
335 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shotgun_Attack2);
336 }
337}
338
339METHOD(Shotgun, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
340{
341 float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo);
342 ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo);
343 return ammo_amount;
344}
345
346METHOD(Shotgun, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
347{
348 switch(WEP_CVAR(WEP_SHOTGUN, secondary))
349 {
350 case 1: return true; // melee does not use ammo
351 case 2: // secondary triple shot
352 {
353 float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo);
354 ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(WEP_SHOTGUN, ammo);
355 return ammo_amount;
356 }
357 default: return false; // secondary unavailable
358 }
359}
360
361METHOD(Shotgun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
362{
363 W_Reload(actor, weaponentity, WEP_CVAR_PRI(WEP_SHOTGUN, ammo), SND_RELOAD); // WEAPONTODO
364}
365
366METHOD(Shotgun, wr_suicidemessage, Notification(entity thiswep))
367{
368 return WEAPON_THINKING_WITH_PORTALS;
369}
370
371METHOD(Shotgun, wr_killmessage, Notification(entity thiswep))
372{
374 return WEAPON_SHOTGUN_MURDER_SLAP;
375 else
376 return WEAPON_SHOTGUN_MURDER;
377}
378
379#endif
380#ifdef CSQC
381.float prevric;
382
383METHOD(Shotgun, wr_impacteffect, void(entity thiswep, entity actor))
384{
385 vector org2 = w_org + w_backoff * 2;
386 pointparticles(EFFECT_SHOTGUN_IMPACT, org2, w_backoff * 1000, 1);
387 if(!w_issilent && time - actor.prevric > 0.25)
388 {
389 if(w_random < 0.05)
391 actor.prevric = time;
392 }
393}
394
395#endif
396#ifdef MENUQC
398
399METHOD(Shotgun, describe, string(Shotgun this))
400{
401 TC(Shotgun, this);
403 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));
404 PAR(_("The secondary fire swings the %s, slapping players close enough with the head of the weapon. "
405 "Since the slap takes a moment to land, timing this well is difficult."), COLORED_NAME(this));
406 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));
407 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));
408 PAR(W_Guide_Keybinds(this));
409 PAR(W_Guide_DPS_primaryMultishot(this.netname, "primary", "secondary", "primary_bullets", ""));
410 return PAGE_TEXT;
411}
412
413#endif
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:44
int m_id
Definition weapon.qh:45
virtual void wr_checkammo2()
(SERVER) checks ammo for weapon second
Definition weapon.qh:94
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:242
#define IS_DEAD(s)
Definition player.qh:245
#define IS_PLAYER(s)
Definition player.qh:243
#define PHYS_INPUT_BUTTON_ATCK(s)
Definition player.qh:150
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition player.qh:152
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:503
void W_SwitchWeapon_Force(Player this, Weapon w,.entity weaponentity)
Definition selection.qc:246
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:124
#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:109
#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:247
void W_Shotgun_Attack2(Weapon thiswep, entity actor,.entity weaponentity, int fire)
Definition shotgun.qc:177
float swing_prev
Definition shotgun.qc:71
void W_Shotgun_Attack(Weapon thiswep, entity actor,.entity weaponentity, float isprimary, 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:72
void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor,.entity weaponentity, int fire)
Definition shotgun.qc:219
void W_Shotgun_Melee_Think(entity this)
Definition shotgun.qc:73
void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor,.entity weaponentity, int fire)
Definition shotgun.qc:191
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:643
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
Definition string.qh:649
#define PAGE_TEXT_INIT()
Definition string.qh:642
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:364
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:21
#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:836
string W_Guide_DPS_primaryMultishot(string name, string pri, string sec, string shots, string refire2)
Definition all.qc:985
void W_MuzzleFlash(Weapon thiswep, entity actor,.entity weaponentity, vector shotorg, vector shotdir)
Definition all.qc:728
#define WEP_CVAR_PRI(wep, name)
Definition all.qh:322
#define WEP_CVAR(wep, name)
Definition all.qh:321
#define WEP_CVAR_SEC(wep, name)
Definition all.qh:323
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)]