if ( SERVER ) then return end // Clientside script, don't want the server to run it ever. local bShowNames = true // Start not showing, and showing names. local iSize = ( math.min( ScrW(), ScrH() ) * 0.8 ) / 2 // Make it small enough to fit comfortably on screen. local iSquareSize = 4 // How big the squares marking players are. local iMode, fMode, sMode = 1, function() end, "Off" local tModes = { { "Off", function( p ) return false end }, { "All Players ", function( p ) return true end }, { "Admins", function( p ) return p:IsAdmin() end }, { "Team Members", function( p, pL ) return p:Team() == pL:Team() end }, { "Other Teams", function( p, pL ) return p:Team() != pL:Team() end } } surface.CreateFont( "Default", 18, 700, true, false, "DefaultAA18B" ) local function HUDPaint() if ( iMode == 1 ) then return end local pLocal = LocalPlayer() // The player's object. local vLocal, vAim = pLocal:GetPos(), pLocal:GetAimVector() // The players position and the direction they're looking. local iCX, iCY = math.Round( ScrW() / 2 ), math.Round( ScrH() / 2 ) // The center of the screen. for _, pPlayer in pairs( player.GetAll() ) do // Loop through all the players on the server. if ( pPlayer != pLocal && fMode( pPlayer, pLocal ) == true ) then // There's no point in putting us on the compass. // Work out where we're drawing on the screen. local vOffset = vLocal - pPlayer:GetPos() local iPhi = math.Deg2Rad( math.Rad2Deg( math.atan2( vOffset.x, vOffset.y ) ) - math.Rad2Deg( math.atan2( vAim.x, vAim.y ) ) - 90 ) local iDX, iDY = math.cos( iPhi ) * -iSize, math.sin( iPhi ) * -iSize local iX, iY = iCX + iDX, iCY + iDY // Draw the squares background/border. local iSS = iSquareSize // Just for shorter code. :P surface.SetDrawColor( 0, 0, 0, 200 ) surface.DrawRect( iX - ( iSS + 1 ), iY - ( iSS + 1 ), ( iSS + 1 ) * 2, ( iSS + 1 ) * 2 ) // Now draw the inner square. local tTeamColor = team.GetColor( pPlayer:Team() ) // Get the player's team colour, so you can more easily pick out admins/enemies etc. surface.SetDrawColor( tTeamColor.r, tTeamColor.g, tTeamColor.b, 255 ) surface.DrawRect( iX - iSS, iY - iSS, iSS * 2, iSS * 2 ) if ( bShowNames ) then // The further away from the top center, the more transparent the name. local iDistance = math.sqrt( ( iDX ^ 2 ) + ( ( iDY + iSize ) ^ 2 ) ) local iAlpha = 255 - ( ( iDistance / ( iSize * 2 ) ) * 255 ) draw.SimpleTextOutlined( pPlayer:Name(), "DefaultAA18B", iX, iY + iSS + 1, Color( 255, 255, 255, iAlpha ), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM, 1, Color( 0, 0, 0, iAlpha ) ) end end end // Draw the mode name. draw.SimpleTextOutlined( sMode, "DefaultAA18B", iCX, iCY - iSize - iSquareSize - 24, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color( 0, 0, 0 ) ) end hook.Add( "HUDPaint", "PlayerCompass.HUDPaint", HUDPaint ) local function Toggle() iMode = iMode + 1 if ( iMode > #tModes ) then iMode = 1 end fMode = tModes[ iMode ][ 2 ] or function() end sMode = tModes[ iMode ][ 1 ] or "" Msg( "PlayerCompass: Mode " .. sMode .. "\n" ) end concommand.Add( "playercompass_toggle", Toggle ) local function SetSize( _, _, tArguments ) iSize = tonumber( tArguments[ 1 ] or iSize ) end concommand.Add( "playercompass_setsize", SetSize ) local function SetSquareSize( _, _, tArguments ) iSquareSize = tonumber( tArguments[ 1 ] or iSquareSize ) end concommand.Add( "playercompass_setsquaresize", SetSquareSize ) local function ToggleNames() bShowNames = !bShowNames end concommand.Add( "playercompass_togglenames", ToggleNames )