--by pavetr.top/ds -- Define ConVars for tracer settings CreateClientConVar("tracer_hit_color", "0 255 0", true, false, "Tracer color on hit") CreateClientConVar("tracer_miss_color", "255 0 0", true, false, "Tracer color on miss") CreateClientConVar("tracer_thickness", "2", true, false, "Thickness of bullet tracers") CreateClientConVar("tracer_alpha", "255", true, false, "Transparency of bullet tracers (0-255)") CreateClientConVar("tracer_fade", "1", true, false, "Enable tracer fading (1 = Yes, 0 = No)") CreateClientConVar("tracer_fade_seconds", "1", true, false, "Time for tracers to fade out") CreateClientConVar("tracer_mat", "sprites/physbeam", true, false,"Material for the trail (some do not support color)") tracerTable = tracerTable or {} local function GetTracerColor(hit, alphaOverride) local colorConVar = hit and "tracer_hit_color" or "tracer_miss_color" local colorStr = GetConVar(colorConVar):GetString() local r, g, b = string.match(colorStr, "(%d+) (%d+) (%d+)") local alpha = alphaOverride or GetConVar("tracer_alpha"):GetInt() return Color(tonumber(r) or 255, tonumber(g) or 255, tonumber(b) or 255, alpha) end -- Bullet Tracer Hook hook.Add("PlayerTraceAttack", "BulletTracer", function(ent, dmg, dir, trace) if not IsFirstTimePredicted() then return end local vHitPos = trace.HitPos local vSrc = trace.StartPos if IsValid(ent) and ent:IsPlayer() then local initialHealth = ent:Health() timer.Simple(0.02, function() if not IsValid(ent) then return end local newHealth = ent:Health() local didHit = newHealth < initialHealth local fadeTime = GetConVar("tracer_fade_seconds"):GetFloat() table.insert(tracerTable, { startPos = vSrc, endPos = vHitPos, timeLeft = fadeTime, maxTime = fadeTime, color = GetTracerColor(didHit), thickness = GetConVar("tracer_thickness"):GetFloat(), didHit = didHit }) end) else local fadeTime = GetConVar("tracer_fade_seconds"):GetFloat() table.insert(tracerTable, { startPos = vSrc, endPos = vHitPos, timeLeft = fadeTime, maxTime = fadeTime, color = GetTracerColor(false), thickness = GetConVar("tracer_thickness"):GetFloat(), didHit = false }) end end) -- Draw Tracers hook.Add("PostDrawOpaqueRenderables", "DrawBulletTracers", function() if not tracerTable then return end local material = Material(GetConVar("tracer_mat"):GetString()) render.SetMaterial(material) local fadeEnabled = GetConVar("tracer_fade"):GetBool() for i = #tracerTable, 1, -1 do local tracer = tracerTable[i] local fadeFactor = fadeEnabled and (tracer.timeLeft / tracer.maxTime) or 1 local alpha = GetConVar("tracer_alpha"):GetInt() * fadeFactor local color = GetTracerColor(tracer.didHit, alpha) render.StartBeam(2) render.AddBeam(tracer.startPos, tracer.thickness, 0, color) render.AddBeam(tracer.endPos, tracer.thickness, 1, color) render.EndBeam() if fadeEnabled then tracer.timeLeft = tracer.timeLeft - FrameTime() if tracer.timeLeft <= 0 then table.remove(tracerTable, i) end end end end)