Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
tracing.qc
Go to the documentation of this file.
1#include "tracing.qh"
2
3#include <common/constants.qh>
7#include <common/state.qh>
8#include <common/util.qh>
10#include <common/wepent.qh>
12#include <server/antilag.qh>
13#include <server/damage.qh>
14#include <server/main.qh>
20
24void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vector s_forward, vector mi, vector ma, float antilag, float recoil, Sound snd, float chan, float maxdamage, float range, int deathtype)
25{
26 TC(Sound, snd);
27 float nudge = 1; // added to traceline target and subtracted from result TOOD(divVerent): do we still need this? Doesn't the engine do this now for us?
28 float oldsolid = ent.dphitcontentsmask;
29 Weapon wep = DEATH_WEAPONOF(deathtype);
30 if (!IS_CLIENT(ent))
31 antilag = false; // no antilag for non-clients!
33 {
34 // This is the reason rifle, MG, OKMG and other fireBullet weapons don't hit the crosshair when shooting at walls.
35 // This is intentional, otherwise if you stand too close to a (glass) wall and attempt to shoot an enemy through it,
36 // trueaim will cause the shot to hit the wall exactly but then miss the enemy (unless shooting from eye/center).
37 // TODO for fireBullet, find how far the shot will penetrate and aim at that
38 // for fireRailgunbullet, find the farthest target and aim at that
39 // this will avoid issues when another player is passing in front of you when you shoot
40 // (currently such a shot will hit them but then miss the original target)
41 ent.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE;
42 }
43 else
44 ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
45 vector view_org = ent.origin + ent.view_ofs;
46 if (antilag)
47 WarpZone_traceline_antilag(NULL, view_org, view_org + s_forward * range, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
48 // passing NULL, because we do NOT want it to touch dphitcontentsmask
49 else
50 WarpZone_TraceLine(view_org, view_org + s_forward * range, MOVE_NOMONSTERS, ent);
51 ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
52
53 vector forward = v_forward;
54 vector right = v_right;
55 vector up = v_up;
57 v_forward = forward;
58 v_right = right;
59 v_up = up;
60
61 // un-adjust trueaim if shotend is too close
63 w_shotend = view_org + s_forward * autocvar_g_trueaim_minrange;
64
65 // track max damage
66 if (IS_PLAYER(ent) && accuracy_canbegooddamage(ent))
67 accuracy_add(ent, wep, maxdamage, 0, 0); // add to fired
68
69 if (IS_PLAYER(ent))
70 W_HitPlotAnalysis(ent, wep, forward, right, up);
71
72 // read shot origin offset, like g_shootfromcenter
73 // set in CL_WeaponEntity_SetModel (not a CSQC exclusive function...)
74 vector md = ent.(weaponentity).movedir;
75 //print(sprintf("offset of %s: %v\n", ent.(weaponentity).m_weapon.netname, md));
76 vector dv = right * -md.y + up * md.z;
77
78 w_shotorg = view_org;
79
80 // FIXME: account for warpzones
81 // move the shotorg sideways and vertically as much as requested if possible
82 if (antilag)
83 tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + dv, MOVE_NORMAL, ent, (CS(ent).antilag_debug ? CS(ent).antilag_debug : ANTILAG_LATENCY(ent)));
84 else
85 tracebox(w_shotorg, mi, ma, w_shotorg + dv, MOVE_NORMAL, ent);
87
88 // now move the shotorg forward as much as requested if possible
89 if (antilag)
90 tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + forward * (md.x + nudge), MOVE_NORMAL, ent, (CS(ent).antilag_debug ? CS(ent).antilag_debug : ANTILAG_LATENCY(ent)));
91 else
92 tracebox(w_shotorg, mi, ma, w_shotorg + forward * (md.x + nudge), MOVE_NORMAL, ent);
93 w_shotorg = trace_endpos - forward * nudge;
94
95 //print(sprintf("w_shotorg %v\n\n", w_shotorg - view_org));
96
97 // calculate the shotdir from the chosen shotorg
98 if (W_DualWielding(ent))
99 w_shotdir = s_forward;
100 else
102
103 //vector prevdir = w_shotdir;
104 //vector prevorg = w_shotorg;
105 //vector prevend = w_shotend;
106
107 if (antilag && !CS_CVAR(ent).cvar_cl_noantilag)
108 {
109 if (autocvar_g_antilag == 1) // switch to "ghost" if not hitting original
110 {
111 traceline(w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent);
112 if (!trace_ent.takedamage)
113 {
115 if (trace_ent.takedamage && IS_PLAYER(trace_ent))
116 {
117 entity e = trace_ent;
118 traceline(w_shotorg, e.origin, MOVE_NORMAL, ent);
119 if (trace_ent == e)
121 }
122 }
123 }
124 else if (autocvar_g_antilag == 3) // client side hitscan
125 {
126 // this part MUST use prydon cursor
127 if (CS(ent).cursor_trace_ent // client was aiming at someone
128 && CS(ent).cursor_trace_ent != ent // just to make sure
129 && CS(ent).cursor_trace_ent.takedamage // and that person is killable
130 && IS_PLAYER(CS(ent).cursor_trace_ent)) // and actually a player
131 {
132 // verify that the shot would miss without antilag
133 // (avoids an issue where guns would always shoot at their origin)
134 traceline(w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent);
135 if (!trace_ent.takedamage)
136 {
137 // verify that the shot would hit if altered
138 traceline(w_shotorg, CS(ent).cursor_trace_ent.origin, MOVE_NORMAL, ent);
139 if (trace_ent == CS(ent).cursor_trace_ent)
141 else
142 LOG_INFO("antilag fail");
143 }
144 }
145 }
146 }
147
148 ent.dphitcontentsmask = oldsolid; // restore solid type (generally SOLID_SLIDEBOX)
149
151 ent.punchangle_x = -recoil;
152
153 if (snd != SND_Null)
154 {
155 sound(ent, chan, snd, (W_DualWielding(ent) ? VOL_BASE * 0.7 : VOL_BASE), ATTN_NORM);
157 }
158
159 // nudge w_shotend so a trace to w_shotend hits
161 //if (w_shotend != prevend) printf("SERVER: shotEND differs: %s - %s\n", vtos(w_shotend), vtos(prevend));
162 //if (w_shotorg != prevorg) printf("SERVER: shotORG differs: %s - %s\n", vtos(w_shotorg), vtos(prevorg));
163 //if (w_shotdir != prevdir) printf("SERVER: shotDIR differs: %s - %s\n", vtos(w_shotdir), vtos(prevdir));
164}
165
167{
168 // Cycle of 4
169 vector offset = '0 37.5 -12.5';
170 if (bullet_count & 2)
171 offset.y = -offset.y;
172 if (bullet_count & 1)
173 offset.z = -offset.z;
174 return offset;
175}
176
177vector W_CalculateProjectileVelocity(entity actor, vector pvelocity, vector mvelocity, float forceAbsolute)
178{
179 mvelocity *= W_WeaponSpeedFactor(actor);
180
181 vector mdirection = normalize(mvelocity);
182 float mspeed = vlen(mvelocity);
183
184 return get_shotvelocity(pvelocity, mdirection, mspeed, (forceAbsolute ? 0 : autocvar_g_projectiles_newton_style),
186}
187
188void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float pSpeed, float pUpSpeed, float pZSpeed, float spread, float forceAbsolute)
189{
190 if (proj.owner == NULL)
191 error("Unowned missile");
192
193 dir += upDir * (pUpSpeed / pSpeed);
194 dir.z += pZSpeed / pSpeed;
195 pSpeed *= vlen(dir);
196 dir = normalize(dir);
197
198 #if 0
199 if (autocvar_g_projectiles_spread_style != mspercallsstyle)
200 {
201 mspercallsum = mspercallcount = 0;
202 mspercallsstyle = autocvar_g_projectiles_spread_style;
203 }
204 mspercallsum -= gettime(GETTIME_HIRES);
205 #endif
206
208
209 #if 0
210 mspercallsum += gettime(GETTIME_HIRES);
211 ++mspercallcount;
212 LOG_INFO("avg: ", ftos(mspercallcount / mspercallsum), " per sec");
213 #endif
214
215 proj.velocity = W_CalculateProjectileVelocity(proj.owner, proj.owner.velocity, pSpeed * dir, forceAbsolute);
216}
217
218
219// ====================
220// Ballistics Tracing
221// ====================
222
223bool Headshot(entity targ, entity ent, vector start, vector end)
224{
225 if (!IS_PLAYER(targ) || IS_DEAD(targ) || STAT(FROZEN, targ) || !targ.takedamage)
226 return false;
227 vector org = targ.origin; // antilag is already taken into consideration //antilag_takebackorigin(targ, CS(targ), time - ANTILAG_LATENCY(ent));
228 vector headmins = org + '0.6 0 0' * targ.mins_x + '0 0.6 0' * targ.mins_y + '0 0 1' * (1.3 * targ.view_ofs_z - 0.3 * targ.maxs_z);
229 vector headmaxs = org + '0.6 0 0' * targ.maxs_x + '0 0.6 0' * targ.maxs_y + '0 0 1' * targ.maxs_z;
230
231 return trace_hits_box(start, end, headmins, headmaxs);
232}
233
238{
239 vector dir, nearest;
240 float length2;
242 && !(IS_SPEC(it) && it.enemy == FireRailgunBullet_cb_this), // not when spectating the shooter
243 {
244 dir = hit - start;
245 length2 = vlen2(dir);
246 nearest = (length2)
247 ? start + dir * bound(0, ((it.origin - start) * dir) / length2, 1)
248 : start;
249 // Above is equivalent to the standard closest approach method `start + dir * bound(0, (it.origin - start) * dir, length)`,
250 // but avoids the sqrt needed to calculate `length`
251 if (!it.WarpZone_findradius_hit || vlen2(it.origin - nearest) < vlen2(it.origin - it.WarpZone_findradius_nearest)) // this segment went closer to the player
252 {
253 // Here we reuse .WarpZone_findradius_nearest as the beam's nearest point to the player, and .WarpZone_findradius_hit for whether it's been set yet
254 // They're safe to reuse since WarpZone_TraceBox_ThroughZone (called by the tracebox_antilag_force_wz below) doesn't set them
255 // Just need to remember to clear .WarpZone_findradius_hit later
256 it.WarpZone_findradius_nearest = nearest;
257 it.WarpZone_findradius_hit = 1;
258 }
259 });
260}
261void FireRailgunBullet(entity this, .entity weaponentity, vector start, vector end, float bdamage, bool headshot_notify, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype)
262{
263 vector dir = normalize(end - start);
264 vector force = dir * bforce;
265 end += dir; // go a little bit into the wall because we need to hit this wall later
266
267 bool headshot = false; // indicates that one of the targets hit was a headshot
268
269 // Trace multiple times until we hit a wall, each obstacle will be made
270 // non-solid so we can hit the next, while doing this we spawn effects and
271 // note down which entities were hit so we can damage them later
272 entity o = this;
273 vector trans_force;
275 do
276 {
277 tracebox_antilag_force_wz(this, start, '0 0 0', '0 0 0', end, false, o,
278 (CS(this).antilag_debug ? CS(this).antilag_debug : ANTILAG_LATENCY(this)),
281 {
282 o = NULL;
283 continue;
284 }
285
287 if (trace_ent.solid == SOLID_BSP)
288 Damage_DamageInfo(trace_endpos, bdamage, 0, 0, trans_force, deathtype, trace_ent.species, this);
289
290 // If it is NULL we can't hurt it so stop now
291 if (trace_ent == NULL || trace_fraction == 1)
292 break;
293
294 if (headshot_notify && !headshot && Headshot(trace_ent, this, start, end))
295 headshot = true;
296
297 // Make the entity non-solid so we can hit the next one
299 trace_ent.railgunhit = true;
300 trace_ent.railgunhitloc = trace_endpos;
301 trace_ent.railgunhitsolidbackup = trace_ent.solid;
303 trace_ent.railgunforce = trans_force;
304
305 if (trace_ent.solid == SOLID_BSP) // stop if this is a wall
306 break;
307 trace_ent.solid = SOLID_NOT; // make the entity non-solid
308 }
309 while (true);
310
311 vector endpoint = trace_endpos;
312 entity endent = trace_ent;
313 float endq3surfaceflags = trace_dphitq3surfaceflags;
314
315 // Find all the entities the railgun hit and restore their solid state
316 IL_EACH(g_railgunhit, it.railgunhit, it.solid = it.railgunhitsolidbackup);
317
318 // Play the sound for all players (even those hit)
319 entity pseudoprojectile = NULL;
320 FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != this && !(IS_SPEC(it) && it.enemy == this),
321 {
322 if (!pseudoprojectile)
323 pseudoprojectile = new(pseudoprojectile); // we need this so the sound uses the "entchannel4" volume
324
325 msg_entity = it;
326 // We want this to be very loud when close but fall off quickly -> using max base volume and high attenuation
327 soundtoat(MSG_ONE, pseudoprojectile, it.WarpZone_findradius_nearest, CH_SHOTS, SND(NEXWHOOSH_RANDOM()), VOL_BASEVOICE, ATTEN_IDLE, 0);
328 it.WarpZone_findradius_hit = 0; // reset the field we reused; no need to reset .WarpZone_findradius_nearest
329 });
330 if (pseudoprojectile)
331 delete(pseudoprojectile);
332
333 // Find all the entities the railgun hit and hurt them
334 float total_dmg = 0;
335 float foff, ffs;
336 IL_EACH(g_railgunhit, it.railgunhit,
337 {
338 foff = ExponentialFalloff(mindist, maxdist, halflifedist, it.railgundistance);
339 ffs = ExponentialFalloff(mindist, maxdist, forcehalflifedist, it.railgundistance);
340
341 if (accuracy_isgooddamage(this, it))
342 total_dmg += bdamage * foff;
343
344 if (it.takedamage)
345 {
346 // Apply the damage
347 Damage(it, this, this, bdamage * foff, deathtype, weaponentity, it.railgunhitloc, it.railgunforce * ffs);
348 if (it.solid == SOLID_SLIDEBOX)
349 Damage_DamageInfo(it.railgunhitloc, bdamage * foff, 0, 0,
350 bforce * ffs * normalize(it.railgunforce), deathtype, it.species, this);
351 }
352
353 // Reset fields before the list is cleared
354 it.railgunhit = false;
355 it.railgunhitloc = '0 0 0';
356 it.railgunhitsolidbackup = SOLID_NOT;
357 it.railgundistance = 0;
358 });
359
361
362 if (headshot)
363 Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_HEADSHOT);
364
365 // Calculate hits and fired shots for hitscan
366 if (this.(weaponentity))
367 accuracy_add(this, this.(weaponentity).m_weapon, 0, min(bdamage, total_dmg), 0); // add to hit
368
369 trace_endpos = endpoint;
370 trace_ent = endent;
371 trace_dphitq3surfaceflags = endq3surfaceflags;
372}
373
375{
376 if (vdist(hit - start, >, 16))
380}
381
382void fireBullet_falloff(entity this, .entity weaponentity, vector start, vector dir,
383 float spread, float max_solid_penetration, float damage,
384 float falloff_halflife, float falloff_mindist,
385 float falloff_maxdist, float headshot_multiplier,
386 float force, float falloff_forcehalflife,
387 float dtype, entity tracer_effect, bool do_antilag)
388{
390 vector end = start + dir * max_shot_distance;
391
393 fireBullet_trace_callback_eff = tracer_effect;
394
395 float solid_penetration_fraction = 1;
396 float damage_fraction = 1;
397 float total_damage = 0;
398
399 float lag = (do_antilag ? antilag_getlag(this) : 0);
400 if (lag)
401 antilag_takeback_all(this, lag);
402
403 // change shooter to SOLID_BBOX so the shot can hit corpses
404 int oldsolid = this.dphitcontentsmask;
405 if (this)
407
409
410 bool headshot = false; // indicates that one of the hit targets was a headshot
411 for (;;)
412 {
416 start = trace_endpos;
417 entity hit = trace_ent;
418
419 // traced up to max_shot_distance and didn't hit anything at all
420 if (trace_fraction == 1)
421 break;
422
423 // When hitting sky, stop.
425 break;
426
427 // can't use noimpact, as we need to pass through walls
428 //if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
429 //break;
430
431 // if we hit "weapclip", bail out
432 //
433 // rationale of this check:
434 //
435 // any shader that is solid, nodraw AND trans is meant to clip weapon
436 // shots and players, but has no other effect!
437 //
438 // if it is not trans, it is caulk and should not have this side effect
439 //
440 // matching shaders:
441 // common/weapclip (intended)
442 // common/noimpact (is supposed to eat projectiles, but is erased anyway)
443 bool is_weapclip = false;
447 is_weapclip = true;
448
449 if (!hit || hit.solid == SOLID_BSP || hit.solid == SOLID_SLIDEBOX)
450 Damage_DamageInfo(start, damage * damage_fraction, 0, 0, max(1, force) * dir * damage_fraction, dtype, hit.species, this);
451
452 // Avoid self-damage (except after going through a warp)
453 // avoid hitting the same entity twice (engine bug)
454 if (hit && hit != WarpZone_trace_forent && hit != fireBullet_last_hit)
455 {
457 yoda = 0;
458 MUTATOR_CALLHOOK(FireBullet_Hit, this, hit, start, end, damage, this.(weaponentity));
459 damage = M_ARGV(4, float);
460 if (headshot_multiplier && Headshot(hit, this, start, end))
461 {
462 damage *= headshot_multiplier;
463 headshot = true;
464 }
465 bool gooddamage = accuracy_isgooddamage(this, hit);
466
467 float dealt_damage = damage * damage_fraction;
468 vector dealt_force = force * dir * damage_fraction;
469
470 if (falloff_halflife || falloff_forcehalflife)
471 {
472 // start, end and trace_endpos seem unreliable for
473 // falloff calculations, using `entity.origin`s instead.
474 // dist is only used to measure distance between shooter
475 // and target entities and do math based on the distance
476 // target's location = hit.origin
477 // shooter's location = this.origin
478 float dist = vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, hit.origin) - this.origin);
479
480 if (falloff_halflife)
481 dealt_damage *= ExponentialFalloff(falloff_mindist, falloff_maxdist, falloff_halflife, dist);
482
483 if (falloff_forcehalflife)
484 dealt_force *= ExponentialFalloff(falloff_mindist, falloff_maxdist, falloff_forcehalflife, dist);
485 }
486
487 Damage(hit, this, this, dealt_damage, dtype, weaponentity, start, dealt_force);
488
489 // calculate hits for ballistic weapons
490 if (gooddamage)
491 {
492 // do not exceed 100%
493 float added_damage = min(damage - total_damage, damage * damage_fraction);
494 total_damage += damage * damage_fraction;
495 accuracy_add(this, this.(weaponentity).m_weapon, 0, added_damage, 0); // add to hit
496 }
497 }
498
499 if (is_weapclip && !autocvar_g_ballistics_penetrate_clips)
500 break;
501
502 // go through solid!
503 // outside the world? forget it
504 if (start.x > world.maxs.x || start.y > world.maxs.y || start.z > world.maxs.z
505 || start.x < world.mins.x || start.y < world.mins.y || start.z < world.mins.z)
506 break;
507
508 float maxdist;
509 entity hitstore = IS_PLAYER(hit) ? PS(hit) : hit;
510 if (max_solid_penetration < 0)
511 break;
512 else if (hitstore.ballistics_density < -1)
513 break; // -2: no solid penetration, ever
514 else if (hitstore.ballistics_density < 0)
515 maxdist = vlen(hit.maxs - hit.mins) + 1; // -1: infinite travel distance
516 else if (hitstore.ballistics_density == 0)
517 maxdist = max_solid_penetration * solid_penetration_fraction;
518 else
519 maxdist = max_solid_penetration * solid_penetration_fraction / hitstore.ballistics_density;
520
522 break;
523
524 // move the entity along its velocity until it's out of solid, then let it resume
525 // The previously hit entity is ignored here!
526 traceline_inverted (start, start + dir * maxdist, MOVE_NORMAL, WarpZone_trace_forent, true, hit);
527 if (trace_fraction == 1) // 1: we never got out of solid
528 break;
529
530 float dist_taken = max(autocvar_g_ballistics_mindistance, vlen(trace_endpos - start));
531 float fraction_used_of_what_is_left = dist_taken / maxdist;
532 solid_penetration_fraction -= solid_penetration_fraction * fraction_used_of_what_is_left;
533 solid_penetration_fraction = max(solid_penetration_fraction, 0);
534 damage_fraction = pow(solid_penetration_fraction, autocvar_g_ballistics_solidpenetration_exponent);
535
536 // Only show effect when going through a player (invisible otherwise)
537 if (hit && hit.solid != SOLID_BSP
538 && vdist(trace_endpos - start, >, 4))
540
541 start = trace_endpos;
542
543 if (hit.solid == SOLID_BSP)
544 Damage_DamageInfo(start, 0, 0, 0, max(1, force) * normalize(dir) * -damage_fraction, dtype, 0, this);
545 }
546
547 if (headshot)
548 Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_HEADSHOT);
549
550 if (lag)
552
553 // restore shooter solid type
554 if (this)
555 this.dphitcontentsmask = oldsolid;
556}
557
558void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect, bool do_antilag)
559{
560 fireBullet_falloff(this, weaponentity, start, dir, spread, max_solid_penetration, damage, 0, 0, 0, headshot_multiplier, force, 0, dtype, tracer_effect, do_antilag);
561}
562
563void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect)
564{
565 fireBullet_antilag(this, weaponentity, start, dir, spread, max_solid_penetration, damage, headshot_multiplier, force, dtype, tracer_effect, true);
566}
567
569{
570 vector trace_start = CS(pl).cursor_trace_start;
571 traceline_antilag(pl, trace_start, trace_start + normalize(CS(pl).cursor_trace_endpos - trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
572}
573
578
583
585{
587 {
588 if (it.model != "")
589 {
590 it.solid = SOLID_BSP;
592 }
593 });
594
595 if (is_wz)
597 else
598 crosshair_trace(pl);
599
600 IL_EACH(g_ctrace_changed, true, it.solid = SOLID_TRIGGER);
601
603}
604
606{
607 vector trace_start = CS(pl).cursor_trace_start;
608 WarpZone_traceline_antilag(pl, trace_start, trace_start + normalize(CS(pl).cursor_trace_endpos - trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
609}
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
bool accuracy_canbegooddamage(entity attacker)
if damage were to occur, would accuracy_isgooddamage be able to return true?
Definition accuracy.qc:154
void tracebox_antilag(entity source, vector v1, vector mi, vector ma, vector v2, float nomonsters, entity forent, float lag)
Definition antilag.qc:216
float antilag_debug
Definition antilag.qc:18
void antilag_takeback_all(entity ignore, float lag)
Definition antilag.qc:124
void WarpZone_traceline_antilag(entity source, vector v1, vector v2, float nomonsters, entity forent, float lag)
Definition antilag.qc:209
void traceline_antilag(entity source, vector v1, vector v2, float nomonsters, entity forent, float lag)
Definition antilag.qc:203
void tracebox_antilag_force_wz(entity source, vector v1, vector mi, vector ma, vector v2, float nomonsters, entity forent, float lag, bool wz, WarpZone_trace_callback_t cb)
A version of traceline that must be used by SOLID_SLIDEBOX things that want to hit SOLID_CORPSE thing...
Definition antilag.qc:168
float antilag_getlag(entity e)
Definition antilag.qc:150
void antilag_restore_all(entity ignore)
Definition antilag.qc:137
#define traceline_antilag_force(source, v1, v2, nomonsters, forent, lag)
Definition antilag.qh:31
#define ANTILAG_LATENCY(e)
Definition antilag.qh:21
int autocvar_g_antilag
Definition antilag.qh:5
#define MUTATOR_CALLHOOK(name,...)
Definition base.qh:186
#define M_ARGV(idx, type)
Definition base.qh:153
vector W_CalculateSpread(vector dir, float spread, int spread_style, bool must_normalize)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:37
int spawnflags
M: flags : WEPSPAWNFLAG_... combined.
Definition weapon.qh:55
#define IS_CLIENT(s)
Definition player.qh:241
#define IS_DEAD(s)
Definition player.qh:244
#define IS_PLAYER(s)
Definition player.qh:242
vector get_shotvelocity(vector myvel, vector mydir, float spd, float newton_style, float mi, float ma)
Definition util.qc:1298
float trace_hits_box(vector start, vector end, vector thmi, vector thma)
Definition util.qc:2221
void traceline_inverted(vector v1, vector v2, float nomonsters, entity forent, float stopatentity, entity ignorestopatentity)
Definition util.qc:100
vector v_up
float Q3SURFACEFLAG_SKY
const float MOVE_NOMONSTERS
const float SOLID_SLIDEBOX
float trace_dphitcontents
float Q3SURFACEFLAG_NONSOLID
entity trace_ent
const float SOLID_TRIGGER
float GETTIME_HIRES
float DPCONTENTS_SOLID
float Q3SURFACEFLAG_NODRAW
const float MOVE_NORMAL
float DPCONTENTS_CORPSE
float DPCONTENTS_BODY
const float SOLID_NOT
float DPCONTENTS_OPAQUE
vector v_right
vector trace_endpos
float trace_dphitq3surfaceflags
vector v_forward
float trace_fraction
float solid
const float ATTN_NORM
const float SOLID_BSP
float dphitcontentsmask
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition damage.qc:484
float yoda
Definition damage.qh:48
void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner)
#define DEATH_WEAPONOF(t)
Definition all.qh:47
entity cursor_trace_ent
vector cursor_trace_endpos
#define trailparticles(e, effect, org, vel)
Definition effect.qh:8
void W_HitPlotAnalysis(entity player, entity wep, vector screenforward, vector screenright, vector screenup)
Definition hitplot.qc:58
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define IL_EACH(this, cond, body)
#define IL_CLEAR(this)
Remove all elements.
#define FOREACH_ENTITY_FLOAT(fld, match, body)
Definition iter.qh:174
#define pow(a, b)
Definition _all.inc:67
#define TC(T, sym)
Definition _all.inc:82
#define STAT(...)
Definition stats.qh:94
vector WarpZone_UnTransformOrigin(entity wz, vector org)
Transforms origin org backwards through warpzone wz, as the inverse of WarpZone_TransformOrigin.
Definition common.qc:530
vector WarpZone_TransformOrigin(entity wz, vector org)
Transforms origin org across warpzone wz.
Definition common.qc:493
int WarpZone_findradius_hit
Definition common.qc:567
vector WarpZone_TransformVelocity(entity wz, vector vel)
Transforms velocity v across warpzone wz.
Definition common.qc:499
entity WarpZone_trace_firstzone
First warpzone hit by a trace (can differ from the requested zone in case of _ThroughZone,...
Definition common.qh:41
#define WarpZone_TraceLine(org, end, nomonsters, forent)
Definition common.qh:51
#define WarpZone_TraceLine_ThroughZone(org, end, nomonsters, forent, zone, cb)
Definition common.qh:47
entity WarpZone_trace_transform
Transform accumulator during a trace.
Definition common.qh:40
entity WarpZone_trace_forent
Temp, callback is allowed to change it.
Definition common.qh:36
#define LOG_INFO(...)
Definition log.qh:62
vector movedir
Definition viewloc.qh:18
ERASEABLE float ExponentialFalloff(float mindist, float maxdist, float halflifedist, float d)
Definition math.qh:247
float gettime(void)
float vlen(vector v)
float min(float f,...)
vector normalize(vector v)
string ftos(float f)
float max(float f,...)
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1500
#define NULL
Definition post.qh:14
#define world
Definition post.qh:15
#define error
Definition pre.qh:6
vector
Definition self.qh:96
vector org
Definition self.qh:96
int dir
Definition impulse.qc:89
void W_PlayStrengthSound(entity player)
Definition common.qc:40
bool W_DualWielding(entity player)
Definition common.qc:20
const float VOL_BASE
Definition sound.qh:36
#define sound(e, c, s, v, a)
Definition sound.qh:52
#define CS_CVAR(this)
Definition state.qh:51
#define PS(this)
Definition state.qh:18
ClientState CS(Client this)
Definition state.qh:47
vector W_CalculateProjectileVelocity(entity actor, vector pvelocity, vector mvelocity, float forceAbsolute)
Definition tracing.qc:177
void FireRailgunBullet_cb(vector start, vector hit, vector end)
Updates the nearest point of the beam to each player, with the new segment from start to hit.
Definition tracing.qc:237
bool Headshot(entity targ, entity ent, vector start, vector end)
Definition tracing.qc:223
void fireBullet(entity this,.entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect)
Definition tracing.qc:563
entity FireRailgunBullet_cb_this
Definition tracing.qc:235
void W_SetupShot_Dir_ProjectileSize_Range(entity ent,.entity weaponentity, vector s_forward, vector mi, vector ma, float antilag, float recoil, Sound snd, float chan, float maxdamage, float range, int deathtype)
This function calculates w_shotorg and w_shotdir based on the weapon model offset,...
Definition tracing.qc:24
void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float pSpeed, float pUpSpeed, float pZSpeed, float spread, float forceAbsolute)
Definition tracing.qc:188
void fireBullet_trace_callback(vector start, vector hit, vector end)
Definition tracing.qc:374
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:382
void crosshair_trace(entity pl)
Definition tracing.qc:568
void crosshair_trace_plusvisibletriggers(entity pl)
Definition tracing.qc:574
void WarpZone_crosshair_trace_plusvisibletriggers(entity pl)
Definition tracing.qc:579
void crosshair_trace_plusvisibletriggers__is_wz(entity pl, bool is_wz)
Definition tracing.qc:584
void fireBullet_antilag(entity this,.entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect, bool do_antilag)
Definition tracing.qc:558
void FireRailgunBullet(entity this,.entity weaponentity, vector start, vector end, float bdamage, bool headshot_notify, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype)
Definition tracing.qc:261
vector W_SetupShot_GetAlternatingOffset(int bullet_count)
Definition tracing.qc:166
void WarpZone_crosshair_trace(entity pl)
Definition tracing.qc:605
int autocvar_g_projectiles_spread_style
Definition tracing.qh:14
IntrusiveList g_railgunhit
Definition tracing.qh:91
float autocvar_g_projectiles_newton_style_2_maxfactor
Definition tracing.qh:12
float autocvar_g_trueaim_minrange
Definition tracing.qh:17
bool autocvar_g_norecoil
Definition tracing.qh:16
float autocvar_g_ballistics_mindistance
Definition tracing.qh:8
vector w_shotdir
Definition tracing.qh:20
IntrusiveList g_ctrace_changed
Definition tracing.qh:117
int autocvar_g_hitscan_spread_style
Definition tracing.qh:15
int autocvar_g_projectiles_newton_style
Definition tracing.qh:11
float autocvar_g_projectiles_newton_style_2_minfactor
Definition tracing.qh:13
float autocvar_g_ballistics_solidpenetration_exponent
Definition tracing.qh:10
bool autocvar_g_ballistics_penetrate_clips
Definition tracing.qh:9
vector w_shotorg
Definition tracing.qh:19
entity fireBullet_trace_callback_eff
Definition tracing.qh:101
entity fireBullet_last_hit
Definition tracing.qh:102
vector w_shotend
Definition tracing.qh:21
#define IS_SPEC(v)
Definition utils.qh:10
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt().
Definition vector.qh:8
int max_shot_distance
Definition weapon.qh:240
const int WEP_FLAG_PENETRATEWALLS
weapon has high calibur bullets that can penetrate thick walls (WEAPONTODO)
Definition weapon.qh:261
float W_WeaponSpeedFactor(entity this)
Weapon m_weapon
Definition wepent.qh:26