Advertisement
Aoki1337

Freecam

Mar 20th, 2025 (edited)
179
0
29 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.59 KB | Software | 0 0
  1. local function getEyeAngles( ply )
  2.     return ply:InVehicle()
  3.         and select( 2, ply:GetVehicle():GetVehicleViewPosition() )
  4.          or ply:EyeAngles()
  5. end
  6.  
  7. local function isDown( cmd, key )
  8.     local isDown = cmd:KeyDown( key )
  9.  
  10.     if isDown then
  11.         cmd:RemoveKey( key )
  12.     end
  13.  
  14.     return isDown
  15. end
  16.  
  17. if FreeCam then
  18.     if FreeCam.enabled then
  19.         FreeCam:Toggle()
  20.  
  21.         if IsValid( FreeCam.panel ) then
  22.             FreeCam.panel:Remove()
  23.         end
  24.     end
  25. end
  26.  
  27. FreeCam = {
  28.     enabled = FreeCam and FreeCam.enabled or false,
  29.     movementEnabled = FreeCam and FreeCam.movementEnabled or false,
  30.     followingEnabled = FreeCam and FreeCam.followingEnabled or false,
  31.     pos = FreeCam and FreeCam.pos or nil,
  32.     ang = FreeCam and FreeCam.ang or nil,
  33.     speed = FreeCam and FreeCam.speed or 10,
  34.     physicalAngles = FreeCam and FreeCam.physicalAngles or Angle(),
  35.     m_yaw = 0,
  36.     m_pitch = 0,
  37.     panel = NULL,
  38. }
  39.  
  40. local function updateSensivity()
  41.     FreeCam.m_yaw = tonumber( GetConVar( 'm_yaw' ):GetString() ) or FreeCam.m_yaw
  42.     FreeCam.m_pitch = tonumber( GetConVar( 'm_pitch' ):GetString() ) or FreeCam.m_pitch
  43. end
  44.  
  45. updateSensivity()
  46. timer.Create( 'UpdateThirdPersonViewSensivity', 10, 0, updateSensivity )
  47.  
  48. function FreeCam:Toggle()
  49.     self.enabled = !self.enabled
  50.  
  51.     if self.enabled then
  52.         if !self.pos or !self.ang then
  53.             self:Reset()
  54.         end
  55.  
  56.         self:ShowGUI()
  57.  
  58.         hook.Add( 'CalcView', 'FreeCam', function( ... )
  59.             return self:CalcView( ... )
  60.         end )
  61.     else
  62.         self:HideGUI()
  63.         hook.Remove( 'CalcView', 'FreeCam' )
  64.     end
  65.  
  66.     if !self.movementEnabled then
  67.         self.physicalAngles = LocalPlayer():EyeAngles()
  68.     end
  69.  
  70.     return self.enabled
  71. end
  72.  
  73. function FreeCam:ToggleMovement()
  74.     self.movementEnabled = !self.movementEnabled
  75.  
  76.     if !self.movementEnabled then
  77.         self.physicalAngles = LocalPlayer():EyeAngles()
  78.     end
  79.  
  80.     return self.movementEnabled
  81. end
  82.  
  83. function FreeCam:ToggleFollowing()
  84.     self.followingEnabled = !self.followingEnabled
  85.  
  86.     if self.pos then
  87.         if self.followingEnabled then
  88.             self.pos = self.pos - LocalPlayer():GetPos()
  89.         else
  90.             self.pos = self.pos + LocalPlayer():GetPos()
  91.         end
  92.     end
  93.  
  94.     return self.followingEnabled
  95. end
  96.  
  97. function FreeCam:ToggleGUI()
  98.     if IsValid( self.panel ) then
  99.         self:HideGUI()
  100.     else
  101.         self:ShowGUI()
  102.     end
  103. end
  104.  
  105. function FreeCam:Reset()
  106.     self.pos = LocalPlayer():GetShootPos()
  107.  
  108.     if self.followingEnabled then
  109.         self.pos = self.pos - LocalPlayer():GetPos()
  110.     end
  111.  
  112.     self.ang = getEyeAngles( LocalPlayer() )
  113. end
  114.  
  115. function FreeCam:Init()
  116.     hook.Add( 'HUDPaint', 'FreeCam', function( ... )
  117.         return self:HUDPaint( ... )
  118.     end )
  119.  
  120.     hook.Add( 'HUDShouldDraw', 'FreeCam', function( ... )
  121.         return self:HUDShouldDraw( ... )
  122.     end )
  123.  
  124.     hook.Add( 'StartCommand', 'FreeCam', function( ... )
  125.         return self:StartCommand( ... )
  126.     end )
  127.  
  128.     concommand.Add( 'aoki_freecam_toggle', function()
  129.         local enabled = self:Toggle()
  130.         print( '[Freecam] Freecam ' .. ( enabled and 'enabled' or 'disabled' ) )
  131.     end )
  132.  
  133.     concommand.Add( 'aoki_freecam_toggle_movement', function()
  134.         local enabled = self:ToggleMovement()
  135.         print( '[Freecam] Movement ' .. ( enabled and 'enabled' or 'disabled' ) )
  136.     end )
  137.  
  138.     concommand.Add( 'aoki_freecam_toggle_following', function()
  139.         local enabled = self:ToggleFollowing()
  140.         print( '[Freecam] Following ' .. ( enabled and 'enabled' or 'disabled' ) )
  141.     end )
  142.  
  143.     concommand.Add( 'aoki_freecam_reset_camera', function()
  144.         self:Reset()
  145.         print( '[Freecam] Camera reset' )
  146.     end )
  147.  
  148.     concommand.Add( 'aoki_freecam_destroy', function()
  149.         self:Destroy()
  150.         print( '[Freecam] FreeCam destroyed' )
  151.     end )
  152. end
  153.  
  154. function FreeCam:Destroy()
  155.     hook.Remove( 'CalcView', 'FreeCam' )
  156.     hook.Remove( 'StartCommand', 'FreeCam' )
  157. end
  158.  
  159. function FreeCam:ShowGUI()
  160.     if IsValid( self.panel ) then return end
  161.  
  162.     local panel = vgui.Create( 'DPanel' )
  163.     self.panel = panel
  164.     panel.freecam = self
  165.     panel:SetSize( 1, 1 )
  166.     panel:SetRenderInScreenshots( false )
  167.     panel:SetPaintedManually( true )
  168.     panel:NoClipping( true )
  169.  
  170.     local font = 'Trebuchet24'
  171.  
  172.     function panel:Paint()
  173.         if !self.freecam.enabled then
  174.             return
  175.         end
  176.  
  177.         local text = string.format(
  178.             '[Freecam enabled]\nControlling: %s\nSpeed: %s',
  179.             self.freecam.movementEnabled and 'Player' or 'Camera',
  180.             self.freecam.speed
  181.         )
  182.  
  183.         local x, y = ScrW() / 2, 5
  184.  
  185.         draw.DrawText( text, font, x + 1, y + 1, Color( 50, 50, 50 ), TEXT_ALIGN_CENTER )
  186.         draw.DrawText( text, font, x, y, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
  187.  
  188.         render.DrawLine( LocalPlayer():GetShootPos(), LocalPlayer():GetEyeTrace().HitPos, color_white )
  189.     end
  190. end
  191.  
  192. function FreeCam:HideGUI()
  193.     if IsValid( self.panel ) then
  194.         self.panel:Remove()
  195.     end
  196. end
  197.  
  198. function FreeCam:HUDPaint()
  199.     if IsValid( self.panel ) then
  200.         self.panel:PaintManual( true )
  201.     end
  202. end
  203.  
  204. function FreeCam:CalcView( ply, pos, ang, fov )
  205.     if !self.enabled then
  206.         return
  207.     end
  208.  
  209.     local pos = self.pos
  210.     local ang = self.ang
  211.  
  212.     if self.followingEnabled then
  213.         pos = LocalPlayer():GetPos()
  214.         pos:Add( self.pos )
  215.     end
  216.  
  217.     local view = {
  218.         origin = pos,
  219.         angles = ang,
  220.         fov = fov,
  221.         drawviewer = true,
  222.     }
  223.  
  224.     return view
  225. end
  226.  
  227. function FreeCam:HUDShouldDraw( name )
  228.     if name == 'CHudWeaponSelection' and self.enabled and !self.movementEnabled then
  229.         return false
  230.     end
  231. end
  232.  
  233. function FreeCam:StartCommand( _, cmd )
  234.     if !self.enabled or self.movementEnabled then
  235.         return
  236.     end
  237.  
  238.     local wheel = cmd:GetMouseWheel()
  239.  
  240.     if wheel != 0 then
  241.         self.speed = math.Clamp( self.speed + wheel * math.abs( wheel ), 1, 100 )
  242.     end
  243.  
  244.     local w = isDown( cmd, IN_FORWARD ) and 1 or 0
  245.     local s = isDown( cmd, IN_BACK ) and 1 or 0
  246.     local a = isDown( cmd, IN_MOVELEFT ) and 1 or 0
  247.     local d = isDown( cmd, IN_MOVERIGHT ) and 1 or 0
  248.     local space = isDown( cmd, IN_JUMP ) and 1 or 0
  249.     local ctrl = isDown( cmd, IN_DUCK ) and 1 or 0
  250.     local shift = isDown( cmd, IN_SPEED )
  251.     local r = isDown( cmd, IN_RELOAD )
  252.  
  253.     if r and shift then
  254.         self:Reset()
  255.     end
  256.  
  257.     local coefficient = FrameTime() * self.speed * self.speed * ( shift and 2 or 1 )
  258.  
  259.     self.pos:Add( ( w - s ) * self.ang:Forward() * coefficient )
  260.     self.pos:Add( ( d - a ) * self.ang:Right() * coefficient )
  261.  
  262.     --- Moves the camera by Z axis relatively to the camera angles ---
  263.     --self.pos:Add( ( space - ctrl ) * self.ang:Up() * coefficient )
  264.  
  265.     --- Moves the camera by Z axis relatively to the world ---
  266.     self.pos.z = self.pos.z + ( space - ctrl ) * coefficient
  267.  
  268.     local mouseX = cmd:GetMouseX()
  269.     local mouseY = cmd:GetMouseY()
  270.  
  271.     self.ang.pitch = self.ang.pitch + mouseY * FreeCam.m_pitch
  272.     self.ang.yaw = self.ang.yaw + mouseX * -FreeCam.m_yaw
  273.  
  274.     cmd:ClearMovement()
  275.     cmd:ClearButtons()
  276.     cmd:SetViewAngles( self.physicalAngles )
  277.     cmd:SetMouseWheel( 0 )
  278. end
  279.  
  280. FreeCam:Init()
  281.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement