CreateClientConVar( "onscreenbb", 0 ) CreateClientConVar( "onscreenbb_ff", 0 ) CreateClientConVar( "onscreenbb_fadelength", ScrW() / 4 ) CreateClientConVar( "onscreenbb_size", 5 ) CreateClientConVar( "onscreenbb_npcs", 1 ) CreateClientConVar( "onscreenbb_weapons", 1 ) CreateClientConVar( "onscreenbb_items", 1 ) CreateClientConVar( "onscreenbb_showdead", 1 ) CreateClientConVar( "onscreenbb_maxshow", 3 ) local function IsGamemode( name ) if ( string.find( GAMEMODE.Name, name ) ) then return true end return false end local function GetCoordinates( ent ) local min, max = ent:OBBMins(), ent:OBBMaxs() local corners = { Vector( min.x, min.y, min.z ), Vector( min.x, min.y, max.z ), Vector( min.x, max.y, min.z ), Vector( min.x, max.y, max.z ), Vector( max.x, min.y, min.z ), Vector( max.x, min.y, max.z ), Vector( max.x, max.y, min.z ), Vector( max.x, max.y, max.z ) } local minX, minY, maxX, maxY = ScrW() * 2, ScrH() * 2, 0, 0 for _, corner in pairs( corners ) do local onScreen = ent:LocalToWorld( corner ):ToScreen() minX, minY = math.min( minX, onScreen.x ), math.min( minY, onScreen.y ) maxX, maxY = math.max( maxX, onScreen.x ), math.max( maxY, onScreen.y ) end return minX, minY, maxX, maxY end local deathSequences = { [ "models/barnacle.mdl" ] = { 4, 15 }, [ "models/antlion_guard.mdl" ] = { 44 }, [ "models/hunter.mdl" ] = { 124, 125, 126, 127, 128 } } local function FilterTargets( e ) local ply = LocalPlayer() local class = e:GetClass() local showdead = GetConVarNumber( "onscreenbb_showdead" ) > 0 if ( e:IsNPC() ) then if ( GetConVarNumber( "onscreenbb_npcs" ) <= 0 ) then return end if ( !showdead && e:GetMoveType() == 0 ) then return end local model = string.lower( e:GetModel() or "" ) if ( table.HasValue( deathSequences[ model ] or {}, e:GetSequence() ) ) then return false end // They're dead. return true end if ( e:IsPlayer() ) then if ( e == ply ) then return end if ( !showdead && !e:Alive() ) then return end if ( GetConVarNumber( "onscreenbb_ff" ) <= 0 && e:Team() == ply:Team() ) then return end local isalien if ( string.find( GAMEMODE.Name, "Parasite" ) ) then if ( e:GetNWString( "type" ) == "alien" ) then isalien = "Alien" end end return true, { e:Name(), e:Health(), isalien }, team.GetColor( e:Team() ) end if ( e:IsWeapon() ) then if ( GetConVarNumber( "onscreenbb_weapons" ) <= 0 ) then return end if ( ValidEntity( e:GetOwner() ) ) then return end return true end if ( class == "item_healthcharger" ) then local bone = e:LookupBone( "roundcap" ) if ( bone ) then local pos = e:GetBonePosition( bone ) pos = e:WorldToLocal( pos ) local full, empty = 5.87, 2.1 local percent = math.floor( ( ( pos.x - empty ) / ( full - empty ) ) * 100 ) percent = math.Clamp( percent, 0, 100 ) return true, { class, percent .. "%" } end end if ( string.find( class, "item" ) ) then if ( GetConVarNumber( "onscreenbb_items" ) <= 0 ) then return end return true end if ( ( IsGamemode( "FortWars" ) || IsGamemode( "GeoForts" ) ) && string.find( string.lower( e:GetModel() or "" ), "roller" ) ) then return true, "Flag", Color( e:GetColor() ) end end local targets = {} local function FindTargets() if ( GetConVarNumber( "onscreenbb" ) <= 0 ) then return end targets = {} for _, e in pairs( ents.GetAll() ) do local valid, name, colour = FilterTargets( e ) if ( valid == true ) then if ( type( name ) != "table" ) then name = { name or e:GetClass() } end targets[ #targets + 1 ] = { Entity = e, Name = name, Colour = colour or Color( 255, 255, 255 ) } end end end timer.Create( "OnScreenBB", 0.25, 0, FindTargets ) local function GetTargets() return targets end local function HUDPaint() if ( GetConVarNumber( "onscreenbb" ) <= 0 ) then return end local cx, cy = ScrW() / 2, ScrH() / 2 local ff = GetConVarNumber( "onscreenbb_ff" ) > 0 local fadeLength = GetConVarNumber( "onscreenbb_fadelength" ) local size = GetConVarNumber( "onscreenbb_size" ) local maxShow = GetConVarNumber( "onscreenbb_maxshow" ) local ply = LocalPlayer() local myTeam = ply:Team() local targets = {} for _, info in pairs( GetTargets() ) do local target = info.Entity if ( ValidEntity( target ) ) then local x1, y1, x2, y2 = GetCoordinates( target ) targets[ #targets + 1 ] = { Entity = target, Coord = { x1, y1, x2, y2 }, Length = ( Vector( ( x1 + x2 ) / 2, y1, 0 ) - Vector( cx, cy, 0 ) ):Length(), Name = info.Name, Colour = info.Colour } end end table.sort( targets, function( a, b ) return a.Length < b.Length end ) local targNum = 0 for _, info in pairs( targets ) do local ent = info.Entity local x1, y1, x2, y2 = unpack( info.Coord ) local col = info.Colour surface.SetDrawColor( col.r, col.g, col.b, 255 ) // Top left. surface.DrawLine( x1, y1, math.min( x1 + size, x2 ), y1 ) surface.DrawLine( x1, y1, x1, math.min( y1 + size, y2 ) ) // Top right. surface.DrawLine( x2, y1, math.max( x2 - size, x1 ), y1 ) surface.DrawLine( x2, y1, x2, math.min( y1 + size, y2 ) ) // Bottom left. surface.DrawLine( x1, y2, math.min( x1 + size, x2 ), y2 ) surface.DrawLine( x1, y2, x1, math.max( y2 - size, y1 ) ) // Bottom right. surface.DrawLine( x2, y2, math.max( x2 - size, x1 ), y2 ) surface.DrawLine( x2, y2, x2, math.max( y2 - size, y1 ) ) local mx, my = ( x1 + x2 ) / 2, ( y1 + y2 ) / 2 local a = ( 1 - math.Clamp( info.Length / fadeLength, 0, 1 ) ) * 255 if ( a > 0 && ( targNum < maxShow || maxShow == -1 ) ) then local y = y1 - ( #info.Name * 13 ) - 2 for _, line in ipairs( info.Name ) do draw.SimpleTextOutlined( line, "Default", mx, y, Color( 255, 255, 255, a ), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM, 1, Color( 0, 0, 0, a ) ) y = y + 13 end end targNum = targNum + 1 end end hook.Add( "HUDPaint", "onScreenBB", HUDPaint ) local function Menu( panel ) panel:CheckBox( "Enabled", "onscreenbb" ) panel:Help( "" ) panel:CheckBox( "Show teammates", "onscreenbb_ff" ) panel:CheckBox( "Show NPCs", "onscreenbb_npcs" ) panel:CheckBox( "Show weapons", "onscreenbb_weapons" ) panel:CheckBox( "Show items", "onscreenbb_items" ) panel:CheckBox( "Show dead players/NPCs", "onscreenbb_showdead" ) panel:Help( "" ) panel:NumSlider( "Fade length", "onscreenbb_fadelength", 50, 500, 0 ) panel:NumSlider( "Max names shown", "onscreenbb_maxshow", -1, 9, 0 ) panel:Help( "" ) panel:NumSlider( "Corner size", "onscreenbb_size", 1, 10, 0 ) end local function PopulateToolMenu() spawnmenu.AddToolMenuOption( "Options", "Hacks", "onScreenBB", "onScreenBB", "", "", Menu ) end hook.Add( "PopulateToolMenu", "onScreenBB", PopulateToolMenu )