What is traceline?
Quake-c defines it in defs.qc:
void (vector v1, vector v2, float nomonsters, entity forent) traceline = #16;
This is a builtin function run by engine c code.
I'll post the manual definition in a comment for reference.
When it is called by quake-c code, it does the following:
Trace a line between vector points v1 and v2 and set various variables.
Most quake-c code that uses traceline manipulates or derives action from one of those variables.
v1 - vector source point in map space
v2 - vector end point in map space
nomonsters - if true monster entities will be ignored - we accept this as (ent.flags & FL_MONSTER)
forent - ignore this entity, and owner or owned entities, if world, ignore no entity
Notes: Traces are blocked by bounding boxes and exact bsp entities
- bounding boxes can be much bigger than visible models - setting FL_ITEM in flags gives a much bigger box, and monsters tend to have bigger boxes
- try this in the console: r_showbboxes is "1" ["0"] shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)
Globals from defs.qc (frequency of use in v1.06 quake-c by line count and manual notes):
entity trace_ent; // (22) entity hit by trace or world if none
float trace_allsolid; // (0) manual says "never used"
float trace_fraction; // (13) fraction of distance covered when entity was hit - 1 for no hits
float trace_inopen; // (7) true - line goes through CONTENT_EMPTY
float trace_inwater; // (7) true - line goes through CONTENT_WATER
float trace_plane_dist; // (0) distance to impact along direction vector
float trace_startsolid; // (0) manual says "never used"
vector trace_endpos; // (15) end of trace - v2, entity hit, or map surface
vector trace_plane_normal; // (11) tricky vector math - by the manual: "direction vector of trace"
Used in these functions of v1.06 quake-c:
How does it really work in practice?
Traceline only seems to set trace_ent to players or monsters if nomonsters is false.
It may be that it can target any entity with health and takedamage set. But in my experience it does NOT target non players and non monsters.
If you want to see most other entites a findradius of traceline length could be used:
findradius(v1, vlen(trace_endpos - v1));
and then check how close all the entity origins / box dimensions are to the traceline.
(I'll leave this vector math to you - just find the vlen from the entity origin to v1 and then trace that distance along the traceline vector (v1 - v2) - do another vlen compare between those two points and decide how close is close enough...)
If this is less than 1, the line stopped before the end point v2 was reached. There is no way to be sure if it is an accurate fraction - actual distance should be measured with vlen(org - end).
This is where the line stops in map coordinates. A great place for weapon effects (gunshot sparks or marks), portals, reticles, etc.
This is the tricky one!
Normal vector: "often simply called the "normal," to a surface is a vector perpendicular to it."
A vector perpendicular to the surface the traceline hit.
Say you wanted to place a portal or reticle in front of that surface:
// norm is a vector, e is the spawned entity to hold the mark or portal
// self is the firing entity, but the angles of the traceline could be used
norm = trace_plane_normal;
norm_x = 0 - norm_x;
norm_y = 0 - norm_y;
e.angles = vectoangles( norm );
setorigin( e, pos - ( v_forward * 0.2 ) ); // subtract v_forward to move the mark away from the surface a short distance
vectoangles turns the normal into a vector pointing perpendicular away from the surface into open map space in front of the surface.
The other trace_* globals seem to work as indicated.
I have one caveat for the "never used" vars from frikbot source:
frikbot/bot_move.qc: if (trace_allsolid || trace_startsolid)
It seems like if these are true, the trace is either all in CONTENT_SOLID or just starts there.
I have not used these so I cannot verify this, but it would be easy to test out.
By use in the original code, traceline is mostly for weapon strike and damage.
The original lightning gun could potentially damage 3 targets. It ran 3 tracelines to find them along the beam strike.
A little imagination and traceline can (and has been) used for:
- targeting reticles
- placing portals and sprites (gunshot marks) on walls
- grapple hook operation
- bot and monster AI tracking
I hope this clears up the confusion around traceline.
Please ask any questions you have in the comments here, or on the forum: Moddb.com