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 568 of file tracing.qc.

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}
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:240

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 574 of file tracing.qc.

575{
577}
void crosshair_trace_plusvisibletriggers__is_wz(entity pl, bool is_wz)
Definition tracing.qc:584

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 584 of file tracing.qc.

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}
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:568
void WarpZone_crosshair_trace(entity pl)
Definition tracing.qc:605
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 563 of file tracing.qc.

564{
565 fireBullet_antilag(this, weaponentity, start, dir, spread, max_solid_penetration, damage, headshot_multiplier, force, dtype, tracer_effect, true);
566}
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:558

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 558 of file tracing.qc.

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}
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

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 382 of file tracing.qc.

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}
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(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
#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:530
vector WarpZone_TransformOrigin(entity wz, vector org)
Transforms origin org across warpzone wz.
Definition common.qc:493
vector WarpZone_TransformVelocity(entity wz, vector vel)
Transforms velocity v across warpzone wz.
Definition common.qc:499
#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:374
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 374 of file tracing.qc.

375{
376 if (vdist(hit - start, >, 16))
380}

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;
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}
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 MUTATOR_HOOKFUNCTION(), 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:2221
#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:1298
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:37
int spawnflags
M: flags : WEPSPAWNFLAG_... combined.
Definition weapon.qh:55
#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
weapon has high calibur bullets that can penetrate thick walls (WEAPONTODO)
Definition weapon.qh:261

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.