trace

Engine Trace Library, loaded by requiring "gamesense/trace"

Functions

trace.line

trace.line(from: vector, to: vector[, options: table]): table (trace info)

Argument

Type

Description

from

vector

Vector to start tracing from

to

vector

Vector to trace to

options

table

Optional table with values, indexed as skip, type & mask

Returns a table, structured as Trace

trace.hull

trace.hull(from: vector, to: vector, mins: vector, maxs: vector[, options: table]): table (trace info)

Argument

Type

Description

from

vector

Vector to start tracing from

to

vector

Vector to trace to

mins

vector

Bounding box mins

maxs

vector

Bounding box maxs

options

table

Optional table with values, indexed as skip, type & mask

Returns a table, structured as Trace

Trace

Description

  • This is simply the structure of the output table.

  • plane is a table that consists of values, indexed as normal, dist, type and sign_bits.

  • surface is a table that consists of values, indexed as name, props and flags.

Values

Index

Type

Description

start_pos

vector

Start position

end_pos

vector

Final position

plane

table

Surface normal at impact

fraction

number

Time completed, 1.0 = didn't hit anything

contents

number

Contents on the other side of the hit surface

disp_flags

number

Displacement flags for making surfaces with data

all_solid

boolean

If true, the plane is not valid

start_solid

boolean

If true, the initial point was in a solid area

fraction_left_solid

number

Time we left a solid, only valid if we started in solid

surface

table

Surface hit (impact surface)

hitgroup

number

0 == generic, non-zero is specific body part

physics_bone

number

Physics bone hit by trace in studio

world_surface_index

number

Index of the msurface2_t, if applicable

entindex

number

Entity index of the entity we hit

hitbox

number

Box hit by trace in studio

Mask

Description

  • Mask is an optional value in the "options" table.

  • The default mask is MASK_PLAYERSOLID.

  • You can pass either a string, a number or a table with strings or numbers.

  • If it's a table, all the masks will be combined by using the bitwise OR.

  • These enumerations are simply combinations of Contents which you can use just like the masks.

Values

Name

Value

Description

MASK_ALL

0xFFFFFFFF

Anything that is not empty space

MASK_SOLID

0x200400B

Anything that is (normally) solid

MASK_PLAYERSOLID

0x201400B

Anything that blocks player movement

MASK_NPCSOLID

0x202400B

Anything that blocks NPC movement

MASK_NPCFLUID

0x2024003

Anything that blocks fluid movement

MASK_WATER

0x4030

Anything that has water-like physics

MASK_OPAQUE

0x4081

Anything that blocks lighting

MASK_OPAQUE_AND_NPCS

0x2004081

Anything that blocks lighting, including NPCs

MASK_BLOCKLOS

0x4041

Anything that blocks line of sight for AI

MASK_BLOCKLOS_AND_NPCS

0x2004041

Anything that blocks line of sight for AI or NPCs

MASK_VISIBLE

0x6081

Anything that blocks line of sight for players

MASK_VISIBLE_AND_NPCS

0x2006081

Anything that blocks line of sight for players, including NPCs

MASK_SHOT

0x46004003

Anything that stops a bullet (including hitboxes)

MASK_FLOORTRACE

0x4004003

For finding floor height

MASK_WEAPONCLIPPING

0x6004003

Anything that is a CS:GO weapon

MASK_SHOT_BRUSHONLY

0x4004003

Anything that stops a bullet (excluding world + brush only)

MASK_SHOT_HULL

0x600400B

Anything that stops a bullet (excluding hitboxes)

MASK_SHOT_PORTAL

0x2004003

Solids except for grates

MASK_SOLID_BRUSHONLY

0x400B

World + Brushes

MASK_PLAYERSOLID_BRUSHONLY

0x1400B

World + Brushes + Player Clips

MASK_NPCSOLID_BRUSHONLY

0x2400B

Anything that blocks NPC movement, except other NPCs

MASK_NPCWORLDSTATIC

0x2000B

The world entity

MASK_NPCWORLDSTATIC_FLUID

0x20003

The world entity

MASK_SPLITAREAPORTAL

0x30

Things that split area portals

MASK_DEADSOLID

0x1000B

Anything that blocks corpse movement

Skip

Description

  • Skip is an optional value in the "options" table.

  • It can be either an entindex, a table with entindices or a function, like a "reverse" ShouldHitEntity callback.

  • If you're using it as a callback, entindex and contents_mask can be accessed by adding them to the arguments of a function.

Type

Description

  • Type is an optional value in the "options" table, indexed by "type".

  • The default trace type is TRACE_EVERYTHING.

  • You can pass either a string or a number.

Values

Name

Value

Description

TRACE_EVERYTHING

0

Self-explanatory

TRACE_WORLD_ONLY

1

NOTE: This does not test static props!!!

TRACE_ENTITIES_ONLY

2

NOTE: This version will not test static props

TRACE_EVERYTHING_FILTER_PROPS

3

NOTE: This version will pass the IHandleEntity for props through the filter

Contents

Description

  • This is what masks are combined with, meaning it can be used the same way.

  • This is mostly for rebuilding stuff when Valve doesn't use the masks that already exist.

Values

Name

Value

Description

CONTENTS_EMPTY

0

No contents

CONTENTS_SOLID

0x1

An eye is never valid in a solid

CONTENTS_WINDOW

0x2

Translucent, but not watery (glass)

CONTENTS_AUX

0x4

CONTENTS_GRATE

0x8

Alpha-tested "grate" textures. Bullets/sight pass through, but solids don't

CONTENTS_SLIME

0x10

CONTENTS_WATER

0x20

CONTENTS_BLOCKLOS

0x40

Block AI line of sight

CONTENTS_OPAQUE

0x80

Things that cannot be seen through (may be non-solid though)

LAST_VISIBLE_CONTENTS

0x80

ALL_VISIBLE_CONTENTS

0xFF

CONTENTS_TESTFOGVOLUME

0x100

CONTENTS_UNUSED

0x200

CONTENTS_BLOCKLIGHT

0x400

CONTENTS_TEAM1

0x800

Per team contents used to differentiate collisions

CONTENTS_TEAM2

0x1000

Between players and objects on different teams

CONTENTS_IGNORE_NODRAW_OPAQUE

0x2000

CONTENTS_MOVEABLE

0x4000

CONTENTS_AREAPORTAL

0x8000

CONTENTS_PLAYERCLIP

0x10000

CONTENTS_MONSTERCLIP

0x20000

CONTENTS_BRUSH_PAINT

0x40000

CONTENTS_GRENADECLIP

0x80000

CONTENTS_UNUSED2

0x100000

CONTENTS_UNUSED3

0x200000

CONTENTS_UNUSED4

0x400000

CONTENTS_UNUSED5

0x800000

CONTENTS_ORIGIN

0x1000000

Removed before bsping an entity

CONTENTS_MONSTER

0x2000000

Should never be on a brush, only in game

CONTENTS_DEBRIS

0x4000000

CONTENTS_DETAIL

0x8000000

Brushes to be added after vis leafs

CONTENTS_TRANSLUCENT

0x10000000

Auto set if any surface has trans

CONTENTS_LADDER

0x20000000

CONTENTS_HITBOX

0x40000000

Use accurate hitboxes on trace

Examples

Plane visualizer

  • A demonstration how you can create a crosshair used in many other cheat providers, if you ever found it cool-looking of course.

  • I'm not entirely good at math so I'm sure there's a better way to make it!

local vector = require "vector"
local trace = require "gamesense/trace"

client.set_event_callback("paint", function()
	local local_player = entity.get_local_player()

	local src = vector(client.eye_position())
	local dest = src + vector():init_from_angles(client.camera_angles()) * 4096

	local tr = trace.line(src, dest, { skip = local_player, mask = "MASK_SHOT" })

	local end_pos = tr.end_pos
	local right, up = tr.plane.normal:vectors()

	local size = 8

	local upper_left = end_pos + up * size + right * size
	local upper_right = end_pos + up * size - right * size
	local bottom_right = end_pos - up * size - right * size
	local bottom_left = end_pos - up * size + right * size

	local x1, y1 = renderer.world_to_screen(upper_left:unpack())
	local x2, y2 = renderer.world_to_screen(upper_right:unpack())
	local x3, y3 = renderer.world_to_screen(bottom_right:unpack())
	local x4, y4 = renderer.world_to_screen(bottom_left:unpack())

	renderer.line(x1, y1, x2, y2, 255, 255, 255, 255)
	renderer.line(x2, y2, x3, y3, 255, 255, 255, 255)
	renderer.line(x3, y3, x4, y4, 255, 255, 255, 255)
	renderer.line(x4, y4, x1, y1, 255, 255, 255, 255)

	renderer.triangle(x1, y1, x2, y2, x3, y3, 255, 255, 255, 100)
	renderer.triangle(x1, y1, x3, y3, x4, y4, 255, 255, 255, 100)
end)

Skip & mask capabilities

  • This example shows what skip & mask values are capable of.

local vector = require "vector"
local trace = require "gamesense/trace"

client.set_event_callback("setup_command", function()
    local from = vector(client.eye_position())
    local to = from + vector():init_from_angles(client.camera_angles()) * 1024
    
    -- number example
    -- skip the specified entindex
    local local_player = entity.get_local_player()
    
    local tr_n = trace.line(from, to, {
        skip = local_player,
        
        -- mask as a number
        mask = 0xFFFFFFFF
    }
    
    -- table example
    -- skip every teammate
    local teammates = {}
    
    local players = entity.get_players()
    for i, entindex in ipairs(players) do
        if not entity.is_enemy(entindex) then
            table.insert(teammates, entindex)
        end
    end
    
    local tr_t = trace.line(from, to, {
        skip = teammates,
        
        -- mask as a string
        mask = "MASK_PLAYERSOLID"
    }
    
    -- function example
    -- skip every "CCSPlayer" entity
    local skip_classname = "CCSPlayer"
    
    local tr_f = trace.line(from, to, {
        skip = function(entindex, contents_mask)
            return entity.get_classname(entindex) == skip_classname
        end,
        
        -- mask as a table with strings and numbers
        -- a combination that results in "MASK_BLOCKLOS"
        mask = {"CONTENTS_SOLID", "CONTENTS_MOVEABLE", 0x40}
    })
end)

Last updated