Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
tracing.qc File Reference
Include dependency graph for tracing.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void crosshair_trace (entity pl)
void crosshair_trace_plusvisibletriggers (entity pl)
void crosshair_trace_plusvisibletriggers__is_wz (entity pl, bool is_wz)
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)
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)
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)
void fireBullet_trace_callback (vector start, vector hit, vector end)
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)
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.
bool Headshot (entity targ, entity ent, vector start, vector end)
vector W_CalculateProjectileVelocity (entity actor, vector pvelocity, vector mvelocity, float forceAbsolute)
void W_SetupProjVelocity_Explicit (entity proj, vector dir, vector upDir, float pSpeed, float pUpSpeed, float pZSpeed, float spread, float forceAbsolute)
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, trueaim and antilag, and won't put w_shotorg inside a wall.
vector W_SetupShot_GetAlternatingOffset (int bullet_count)
void WarpZone_crosshair_trace (entity pl)
void WarpZone_crosshair_trace_plusvisibletriggers (entity pl)

Variables

entity FireRailgunBullet_cb_this
int WarpZone_findradius_hit

Function Documentation

◆ crosshair_trace()

void crosshair_trace ( entity pl)

Definition at line 565 of file tracing.qc.

566{
567 vector trace_start = CS(pl).cursor_trace_start;
568 traceline_antilag(pl, trace_start, trace_start + normalize(CS(pl).cursor_trace_endpos - trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
569}
void traceline_antilag(entity source, vector v1, vector v2, float nomonsters, entity forent, float lag)
Definition antilag.qc:203
#define ANTILAG_LATENCY(e)
Definition antilag.qh:21
const float MOVE_NORMAL
vector cursor_trace_endpos
vector normalize(vector v)
vector
Definition self.qh:96
ClientState CS(Client this)
Definition state.qh:47
int max_shot_distance
Definition weapon.qh:245

References ANTILAG_LATENCY, CS(), cursor_trace_endpos, entity(), max_shot_distance, MOVE_NORMAL, normalize(), traceline_antilag(), and vector.

Referenced by bumblebee_gunner_frame(), bumblebee_pilot_frame(), CheatCommand(), crosshair_trace_plusvisibletriggers__is_wz(), racer_frame(), raptor_frame(), spiderbot_frame(), spiderbot_guide_release(), spiderbot_rocket_do(), and spiderbot_rocket_guided().

◆ crosshair_trace_plusvisibletriggers()

void crosshair_trace_plusvisibletriggers ( entity pl)

Definition at line 571 of file tracing.qc.

572{
574}
void crosshair_trace_plusvisibletriggers__is_wz(entity pl, bool is_wz)
Definition tracing.qc:581

References crosshair_trace_plusvisibletriggers__is_wz(), and entity().

Referenced by Drag().

◆ crosshair_trace_plusvisibletriggers__is_wz()

void crosshair_trace_plusvisibletriggers__is_wz ( entity pl,
bool is_wz )

Definition at line 581 of file tracing.qc.

582{
584 {
585 if (it.model != "")
586 {
587 it.solid = SOLID_BSP;
589 }
590 });
591
592 if (is_wz)
594 else
595 crosshair_trace(pl);
596
597 IL_EACH(g_ctrace_changed, true, it.solid = SOLID_TRIGGER);
598
600}
const float SOLID_TRIGGER
float solid
const float SOLID_BSP
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
void crosshair_trace(entity pl)
Definition tracing.qc:565
void WarpZone_crosshair_trace(entity pl)
Definition tracing.qc:602
IntrusiveList g_ctrace_changed
Definition tracing.qh:117

References crosshair_trace(), entity(), FOREACH_ENTITY_FLOAT, g_ctrace_changed, IL_CLEAR, IL_EACH, IL_PUSH(), solid, SOLID_BSP, SOLID_TRIGGER, and WarpZone_crosshair_trace().

Referenced by crosshair_trace_plusvisibletriggers(), and WarpZone_crosshair_trace_plusvisibletriggers().

◆ fireBullet()

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 at line 560 of file tracing.qc.

561{
562 fireBullet_antilag(this, weaponentity, start, dir, spread, max_solid_penetration, damage, headshot_multiplier, force, dtype, tracer_effect, true);
563}
int dir
Definition impulse.qc:89
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:555

References dir, entity(), fireBullet_antilag(), and vector.

Referenced by spiderbot_frame(), and W_OverkillHeavyMachineGun_Attack_Auto().

◆ fireBullet_antilag()

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 at line 555 of file tracing.qc.

556{
557 fireBullet_falloff(this, weaponentity, start, dir, spread, max_solid_penetration, damage, 0, 0, 0, headshot_multiplier, force, 0, dtype, tracer_effect, do_antilag);
558}
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:379

References dir, entity(), fireBullet_falloff(), and vector.

Referenced by fireBullet().

◆ fireBullet_falloff()

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 at line 379 of file tracing.qc.

385{
387 vector end = start + dir * max_shot_distance;
388
390 fireBullet_trace_callback_eff = tracer_effect;
391
392 float solid_penetration_fraction = 1;
393 float damage_fraction = 1;
394 float total_damage = 0;
395
396 float lag = (do_antilag ? antilag_getlag(this) : 0);
397 if (lag)
398 antilag_takeback_all(this, lag);
399
400 // change shooter to SOLID_BBOX so the shot can hit corpses
401 int oldsolid = this.dphitcontentsmask;
402 if (this)
404
406
407 bool headshot = false; // indicates that one of the hit targets was a headshot
408 for (;;)
409 {
413 start = trace_endpos;
414 entity hit = trace_ent;
415
416 // traced up to max_shot_distance and didn't hit anything at all
417 if (trace_fraction == 1)
418 break;
419
420 // When hitting sky, stop.
422 break;
423
424 // can't use noimpact, as we need to pass through walls
425 //if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
426 //break;
427
428 // if we hit "weapclip", bail out
429 //
430 // rationale of this check:
431 //
432 // any shader that is solid, nodraw AND trans is meant to clip weapon
433 // shots and players, but has no other effect!
434 //
435 // if it is not trans, it is caulk and should not have this side effect
436 //
437 // matching shaders:
438 // common/weapclip (intended)
439 // common/noimpact (is supposed to eat projectiles, but is erased anyway)
440 bool is_weapclip = false;
444 is_weapclip = true;
445
446 if (!hit || hit.solid == SOLID_BSP || hit.solid == SOLID_SLIDEBOX)
447 Damage_DamageInfo(start, damage * damage_fraction, 0, 0, max(1, force) * dir * damage_fraction, dtype, hit.species, this);
448
449 // Avoid self-damage (except after going through a warp)
450 // avoid hitting the same entity twice (engine bug)
451 if (hit && hit != WarpZone_trace_forent && hit != fireBullet_last_hit)
452 {
454 yoda = 0;
455 MUTATOR_CALLHOOK(FireBullet_Hit, this, hit, start, end, damage, this.(weaponentity));
456 damage = M_ARGV(4, float);
457 if (headshot_multiplier && Headshot(hit, this, start, end))
458 {
459 damage *= headshot_multiplier;
460 headshot = true;
461 }
462 bool gooddamage = accuracy_isgooddamage(this, hit);
463
464 float dealt_damage = damage * damage_fraction;
465 vector dealt_force = force * dir * damage_fraction;
466
467 if (falloff_halflife || falloff_forcehalflife)
468 {
469 // start, end and trace_endpos seem unreliable for
470 // falloff calculations, using `entity.origin`s instead.
471 // dist is only used to measure distance between shooter
472 // and target entities and do math based on the distance
473 // target's location = hit.origin
474 // shooter's location = this.origin
475 float dist = vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, hit.origin) - this.origin);
476
477 if (falloff_halflife)
478 dealt_damage *= ExponentialFalloff(falloff_mindist, falloff_maxdist, falloff_halflife, dist);
479
480 if (falloff_forcehalflife)
481 dealt_force *= ExponentialFalloff(falloff_mindist, falloff_maxdist, falloff_forcehalflife, dist);
482 }
483
484 Damage(hit, this, this, dealt_damage, dtype, weaponentity, start, dealt_force);
485
486 // calculate hits for ballistic weapons
487 if (gooddamage)
488 {
489 // do not exceed 100%
490 float added_damage = min(damage - total_damage, damage * damage_fraction);
491 total_damage += damage * damage_fraction;
492 accuracy_add(this, this.(weaponentity).m_weapon, 0, added_damage, 0); // add to hit
493 }
494 }
495
496 if (is_weapclip && !autocvar_g_ballistics_penetrate_clips)
497 break;
498
499 // go through solid!
500 // outside the world? forget it
501 if (start.x > world.maxs.x || start.y > world.maxs.y || start.z > world.maxs.z
502 || start.x < world.mins.x || start.y < world.mins.y || start.z < world.mins.z)
503 break;
504
505 float maxdist;
506 entity hitstore = IS_PLAYER(hit) ? PS(hit) : hit;
507 if (max_solid_penetration < 0)
508 break;
509 else if (hitstore.ballistics_density < -1)
510 break; // -2: no solid penetration, ever
511 else if (hitstore.ballistics_density < 0)
512 maxdist = vlen(hit.maxs - hit.mins) + 1; // -1: infinite travel distance
513 else if (hitstore.ballistics_density == 0)
514 maxdist = max_solid_penetration * solid_penetration_fraction;
515 else
516 maxdist = max_solid_penetration * solid_penetration_fraction / hitstore.ballistics_density;
517
519 break;
520
521 // move the entity along its velocity until it's out of solid, then let it resume
522 // The previously hit entity is ignored here!
523 traceline_inverted (start, start + dir * maxdist, MOVE_NORMAL, WarpZone_trace_forent, true, hit);
524 if (trace_fraction == 1) // 1: we never got out of solid
525 break;
526
527 float dist_taken = max(autocvar_g_ballistics_mindistance, vlen(trace_endpos - start));
528 float fraction_used_of_what_is_left = dist_taken / maxdist;
529 solid_penetration_fraction -= solid_penetration_fraction * fraction_used_of_what_is_left;
530 solid_penetration_fraction = max(solid_penetration_fraction, 0);
531 damage_fraction = pow(solid_penetration_fraction, autocvar_g_ballistics_solidpenetration_exponent);
532
533 // Only show effect when going through a player (invisible otherwise)
534 if (hit && hit.solid != SOLID_BSP
535 && vdist(trace_endpos - start, >, 4))
537
538 start = trace_endpos;
539
540 if (hit.solid == SOLID_BSP)
541 Damage_DamageInfo(start, 0, 0, 0, max(1, force) * normalize(dir) * -damage_fraction, dtype, 0, this);
542 }
543
544 if (headshot)
545 Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_HEADSHOT);
546
547 if (lag)
549
550 // restore shooter solid type
551 if (this)
552 this.dphitcontentsmask = oldsolid;
553}
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:124
float antilag_getlag(entity e)
Definition antilag.qc:150
void antilag_restore_all(entity ignore)
Definition antilag.qc:137
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
vector W_CalculateSpread(vector dir, float spread, int spread_style, bool must_normalize)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define M_ARGV(x, type)
Definition events.qh:17
#define IS_PLAYER(s)
Definition player.qh:242
void traceline_inverted(vector v1, vector v2, float nomonsters, entity forent, float stopatentity, entity ignorestopatentity)
Definition util.qc:100
float Q3SURFACEFLAG_SKY
const float SOLID_SLIDEBOX
float trace_dphitcontents
float Q3SURFACEFLAG_NONSOLID
entity trace_ent
float DPCONTENTS_SOLID
float Q3SURFACEFLAG_NODRAW
float DPCONTENTS_CORPSE
float DPCONTENTS_BODY
float DPCONTENTS_OPAQUE
vector trace_endpos
float trace_dphitq3surfaceflags
float trace_fraction
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 trailparticles(e, effect, org, vel)
Definition effect.qh:8
#define pow(a, b)
Definition _all.inc:67
vector WarpZone_UnTransformOrigin(entity wz, vector org)
Transforms origin org backwards through warpzone wz, as the inverse of WarpZone_TransformOrigin.
Definition common.qc:526
vector WarpZone_TransformOrigin(entity wz, vector org)
Transforms origin org across warpzone wz.
Definition common.qc:489
vector WarpZone_TransformVelocity(entity wz, vector vel)
Transforms velocity v across warpzone wz.
Definition common.qc:495
#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
ERASEABLE float ExponentialFalloff(float mindist, float maxdist, float halflifedist, float d)
Definition math.qh:247
float vlen(vector v)
float min(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 PS(this)
Definition state.qh:18
bool Headshot(entity targ, entity ent, vector start, vector end)
Definition tracing.qc:223
void fireBullet_trace_callback(vector start, vector hit, vector end)
Definition tracing.qc:371
float autocvar_g_ballistics_mindistance
Definition tracing.qh:8
int autocvar_g_hitscan_spread_style
Definition tracing.qh:15
float autocvar_g_ballistics_solidpenetration_exponent
Definition tracing.qh:10
bool autocvar_g_ballistics_penetrate_clips
Definition tracing.qh:9
entity fireBullet_trace_callback_eff
Definition tracing.qh:101
entity fireBullet_last_hit
Definition tracing.qh:102
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt().
Definition vector.qh:8
Weapon m_weapon
Definition wepent.qh:26

References accuracy_add(), accuracy_isgooddamage(), antilag_getlag(), antilag_restore_all(), antilag_takeback_all(), autocvar_g_ballistics_mindistance, autocvar_g_ballistics_penetrate_clips, autocvar_g_ballistics_solidpenetration_exponent, autocvar_g_hitscan_spread_style, Damage(), Damage_DamageInfo(), dir, DPCONTENTS_BODY, DPCONTENTS_CORPSE, DPCONTENTS_OPAQUE, DPCONTENTS_SOLID, dphitcontentsmask, entity(), ExponentialFalloff(), fireBullet_last_hit, fireBullet_trace_callback(), fireBullet_trace_callback_eff, Headshot(), IS_PLAYER, M_ARGV, m_weapon, max(), max_shot_distance, min(), MOVE_NORMAL, MUTATOR_CALLHOOK, normalize(), NULL, pow, PS, Q3SURFACEFLAG_NODRAW, Q3SURFACEFLAG_NONSOLID, Q3SURFACEFLAG_SKY, Send_Notification(), SOLID_BSP, SOLID_SLIDEBOX, trace_dphitcontents, trace_dphitq3surfaceflags, trace_endpos, trace_ent, trace_fraction, traceline_inverted(), trailparticles, vdist, vector, vlen(), W_CalculateSpread(), WarpZone_trace_forent, WarpZone_trace_transform, WarpZone_TraceLine_ThroughZone, WarpZone_TransformOrigin(), WarpZone_TransformVelocity(), WarpZone_UnTransformOrigin(), world, and yoda.

Referenced by fireBullet_antilag(), W_MachineGun_Attack(), W_MachineGun_Attack_Auto(), W_MachineGun_Attack_Burst(), W_OverkillMachineGun_Attack_Auto(), W_Rifle_FireBullet(), and W_Shotgun_Attack().

◆ fireBullet_trace_callback()

void fireBullet_trace_callback ( vector start,
vector hit,
vector end )

Definition at line 371 of file tracing.qc.

372{
373 if (vdist(hit - start, >, 16))
377}

References fireBullet_last_hit, fireBullet_trace_callback_eff, NULL, trailparticles, vdist, vector, and WarpZone_trace_forent.

Referenced by fireBullet_falloff().

◆ FireRailgunBullet()

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 at line 261 of file tracing.qc.

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;
274 do
275 {
276 tracebox_antilag_force_wz(this, start, '0 0 0', '0 0 0', end, false, o,
277 (CS(this).antilag_debug ? CS(this).antilag_debug : ANTILAG_LATENCY(this)),
280 {
281 o = NULL;
282 continue;
283 }
284
285 // If it is NULL we can't hurt it so stop now
286 if (trace_ent == NULL || trace_fraction == 1)
287 break;
288
289 if (headshot_notify && !headshot && Headshot(trace_ent, this, start, end))
290 headshot = true;
291
292 // Make the entity non-solid so we can hit the next one
294 trace_ent.railgunhit = true;
295 trace_ent.railgunhitloc = trace_endpos;
296 trace_ent.railgunhitsolidbackup = trace_ent.solid;
299 if (trace_ent.solid == SOLID_BSP)
300 Damage_DamageInfo(trace_endpos, bdamage, 0, 0, trace_ent.railgunforce, deathtype, trace_ent.species, this);
301
302 if (trace_ent.solid == SOLID_BSP) // stop if this is a wall
303 break;
304 trace_ent.solid = SOLID_NOT; // make the entity non-solid
305 }
306 while (true);
307
308 vector endpoint = trace_endpos;
309 entity endent = trace_ent;
310 float endq3surfaceflags = trace_dphitq3surfaceflags;
311
312 // Find all the entities the railgun hit and restore their solid state
313 IL_EACH(g_railgunhit, it.railgunhit, it.solid = it.railgunhitsolidbackup);
314
315 // Play the sound for all players (even those hit)
316 entity pseudoprojectile = NULL;
317 FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != this && !(IS_SPEC(it) && it.enemy == this),
318 {
319 if (!pseudoprojectile)
320 pseudoprojectile = new(pseudoprojectile); // we need this so the sound uses the "entchannel4" volume
321
322 msg_entity = it;
323 // We want this to be very loud when close but fall off quickly -> using max base volume and high attenuation
324 soundtoat(MSG_ONE, pseudoprojectile, it.WarpZone_findradius_nearest, CH_SHOTS, SND(NEXWHOOSH_RANDOM()), VOL_BASEVOICE, ATTEN_IDLE, 0);
325 it.WarpZone_findradius_hit = 0; // reset the field we reused; no need to reset .WarpZone_findradius_nearest
326 });
327 if (pseudoprojectile)
328 delete(pseudoprojectile);
329
330 // Find all the entities the railgun hit and hurt them
331 float total_dmg = 0;
332 float foff, ffs;
333 IL_EACH(g_railgunhit, it.railgunhit,
334 {
335 foff = ExponentialFalloff(mindist, maxdist, halflifedist, it.railgundistance);
336 ffs = ExponentialFalloff(mindist, maxdist, forcehalflifedist, it.railgundistance);
337
338 if (accuracy_isgooddamage(this, it))
339 total_dmg += bdamage * foff;
340
341 if (it.takedamage)
342 {
343 // Apply the damage
344 Damage(it, this, this, bdamage * foff, deathtype, weaponentity, it.railgunhitloc, it.railgunforce * ffs);
345 if (it.solid == SOLID_SLIDEBOX)
346 Damage_DamageInfo(it.railgunhitloc, bdamage * foff, 0, 0,
347 bforce * ffs * normalize(it.railgunforce), deathtype, it.species, this);
348 }
349
350 // Reset fields before the list is cleared
351 it.railgunhit = false;
352 it.railgunhitloc = '0 0 0';
353 it.railgunhitsolidbackup = SOLID_NOT;
354 it.railgundistance = 0;
355 });
356
358
359 if (headshot)
360 Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_HEADSHOT);
361
362 // Calculate hits and fired shots for hitscan
363 if (this.(weaponentity))
364 accuracy_add(this, this.(weaponentity).m_weapon, 0, min(bdamage, total_dmg), 0); // add to hit
365
366 trace_endpos = endpoint;
367 trace_ent = endent;
368 trace_dphitq3surfaceflags = endq3surfaceflags;
369}
float antilag_debug
Definition antilag.qc:18
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
const float SOLID_NOT
entity WarpZone_trace_firstzone
First warpzone hit by a trace (can differ from the requested zone in case of _ThroughZone,...
Definition common.qh:41
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
entity FireRailgunBullet_cb_this
Definition tracing.qc:235
IntrusiveList g_railgunhit
Definition tracing.qh:91
#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

References antilag_debug, ANTILAG_LATENCY, CS(), Damage_DamageInfo(), dir, entity(), FireRailgunBullet_cb(), FireRailgunBullet_cb_this, FOREACH_CLIENT, g_railgunhit, Headshot(), IL_EACH, IL_PUSH(), IS_REAL_CLIENT, IS_SPEC, normalize(), NULL, SOLID_BSP, SOLID_NOT, trace_dphitq3surfaceflags, trace_endpos, trace_ent, trace_fraction, tracebox_antilag_force_wz(), vector, vlen(), WarpZone_trace_firstzone, WarpZone_trace_transform, WarpZone_TransformVelocity(), and WarpZone_UnTransformOrigin().

Referenced by W_OverkillNex_Attack(), W_Vaporizer_Attack(), and W_Vortex_Attack().

◆ FireRailgunBullet_cb()

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 at line 237 of file tracing.qc.

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}

References dir, FireRailgunBullet_cb_this, FOREACH_CLIENT, IS_REAL_CLIENT, IS_SPEC, and vector.

Referenced by FireRailgunBullet().

◆ Headshot()

bool Headshot ( entity targ,
entity ent,
vector start,
vector end )

Definition at line 223 of file tracing.qc.

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}
#define IS_DEAD(s)
Definition player.qh:244
float trace_hits_box(vector start, vector end, vector thmi, vector thma)
Definition util.qc:2231
#define STAT(...)
Definition stats.qh:94
vector org
Definition self.qh:96

References entity(), IS_DEAD, IS_PLAYER, org, STAT, trace_hits_box(), and vector.

Referenced by fireBullet_falloff(), and FireRailgunBullet().

◆ W_CalculateProjectileVelocity()

vector W_CalculateProjectileVelocity ( entity actor,
vector pvelocity,
vector mvelocity,
float forceAbsolute )

Definition at line 177 of file tracing.qc.

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}
vector get_shotvelocity(vector myvel, vector mydir, float spd, float newton_style, float mi, float ma)
Definition util.qc:1308
float autocvar_g_projectiles_newton_style_2_maxfactor
Definition tracing.qh:12
int autocvar_g_projectiles_newton_style
Definition tracing.qh:11
float autocvar_g_projectiles_newton_style_2_minfactor
Definition tracing.qh:13
float W_WeaponSpeedFactor(entity this)

References autocvar_g_projectiles_newton_style, autocvar_g_projectiles_newton_style_2_maxfactor, autocvar_g_projectiles_newton_style_2_minfactor, entity(), get_shotvelocity(), normalize(), vector, vlen(), and W_WeaponSpeedFactor().

Referenced by ctf_Handle_Throw(), IMPULSE(), kh_Key_DropAll(), kh_Key_DropOne(), powerups_DropItem(), toss_nade(), W_Nexball_Attack(), W_RocketMinsta_Attack(), and W_SetupProjVelocity_Explicit().

◆ W_SetupProjVelocity_Explicit()

void W_SetupProjVelocity_Explicit ( entity proj,
vector dir,
vector upDir,
float pSpeed,
float pUpSpeed,
float pZSpeed,
float spread,
float forceAbsolute )

Definition at line 188 of file tracing.qc.

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}
float GETTIME_HIRES
#define LOG_INFO(...)
Definition log.qh:62
float gettime(void)
string ftos(float f)
#define error
Definition pre.qh:6
vector W_CalculateProjectileVelocity(entity actor, vector pvelocity, vector mvelocity, float forceAbsolute)
Definition tracing.qc:177
int autocvar_g_projectiles_spread_style
Definition tracing.qh:14

References autocvar_g_projectiles_spread_style, dir, entity(), error, ftos(), gettime(), GETTIME_HIRES, LOG_INFO, normalize(), NULL, vector, vlen(), W_CalculateProjectileVelocity(), and W_CalculateSpread().

Referenced by FireGrapplingHook(), M_Golem_Attack_Lightning(), M_Spider_Attack_Web(), W_Blaster_Attack(), W_Crylink_Attack(), W_Crylink_Attack2(), and W_Hagar_Attack2_Load_Release().

◆ W_SetupShot_Dir_ProjectileSize_Range()

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, trueaim and antilag, and won't put w_shotorg inside a wall.

make sure you call makevectors first (FIXME?)

Definition at line 24 of file tracing.qc.

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}
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
void WarpZone_traceline_antilag(entity source, vector v1, vector v2, float nomonsters, entity forent, float lag)
Definition antilag.qc:209
#define traceline_antilag_force(source, v1, v2, nomonsters, forent, lag)
Definition antilag.qh:31
int autocvar_g_antilag
Definition antilag.qh:5
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:42
int spawnflags
M: flags : WEPSPAWNFLAG_... combined.
Definition weapon.qh:60
#define IS_CLIENT(s)
Definition player.qh:241
vector v_up
const float MOVE_NOMONSTERS
vector v_right
vector v_forward
const float ATTN_NORM
#define DEATH_WEAPONOF(t)
Definition all.qh:47
entity cursor_trace_ent
void W_HitPlotAnalysis(entity player, entity wep, vector screenforward, vector screenright, vector screenup)
Definition hitplot.qc:58
#define TC(T, sym)
Definition _all.inc:82
#define WarpZone_TraceLine(org, end, nomonsters, forent)
Definition common.qh:51
vector movedir
Definition viewloc.qh:18
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
float autocvar_g_trueaim_minrange
Definition tracing.qh:17
bool autocvar_g_norecoil
Definition tracing.qh:16
vector w_shotdir
Definition tracing.qh:20
vector w_shotorg
Definition tracing.qh:19
vector w_shotend
Definition tracing.qh:21
const int WEP_FLAG_PENETRATEWALLS
Definition weapon.qh:266

References accuracy_add(), accuracy_canbegooddamage(), antilag_debug, ANTILAG_LATENCY, ATTN_NORM, autocvar_g_antilag, autocvar_g_norecoil, autocvar_g_trueaim_minrange, CS(), CS_CVAR, cursor_trace_ent, DEATH_WEAPONOF, DPCONTENTS_BODY, DPCONTENTS_CORPSE, DPCONTENTS_SOLID, entity(), IS_CLIENT, IS_PLAYER, LOG_INFO, MOVE_NOMONSTERS, MOVE_NORMAL, movedir, normalize(), NULL, sound, Weapon::spawnflags, TC, trace_endpos, trace_ent, tracebox_antilag(), traceline_antilag_force, v_forward, v_right, v_up, vdist, vector, VOL_BASE, W_DualWielding(), W_HitPlotAnalysis(), W_PlayStrengthSound(), w_shotdir, w_shotend, w_shotorg, WarpZone_trace_transform, WarpZone_TraceLine, WarpZone_traceline_antilag(), WarpZone_UnTransformOrigin(), and WEP_FLAG_PENETRATEWALLS.

◆ W_SetupShot_GetAlternatingOffset()

vector W_SetupShot_GetAlternatingOffset ( int bullet_count)

Definition at line 166 of file tracing.qc.

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}

References vector.

Referenced by W_Fireball_Attack2(), W_Fireball_AttackEffect(), W_Seeker_Fire_Flac(), and W_Seeker_Fire_Missile().

◆ WarpZone_crosshair_trace()

void WarpZone_crosshair_trace ( entity pl)

◆ WarpZone_crosshair_trace_plusvisibletriggers()

void WarpZone_crosshair_trace_plusvisibletriggers ( entity pl)

Variable Documentation

◆ FireRailgunBullet_cb_this

entity FireRailgunBullet_cb_this

Definition at line 235 of file tracing.qc.

Referenced by FireRailgunBullet(), and FireRailgunBullet_cb().

◆ WarpZone_findradius_hit

int WarpZone_findradius_hit

Definition at line 234 of file tracing.qc.