--by pavetr.top/ds local cameraEnabled = false local headCameraEnabled = false local ChestCameraEnabled = false local cameraMode = "head" local headCamOffset = Vector(10, 2, 8) local chestCamOffset = Vector(2, 5, -8) local headCamFOV = 0 local ChestCamFOV = 0 local offsetLimits = { min = Vector(-20, -20, -20), max = Vector(20, 20, 20) } local function ClampOffset(offset) return Vector( math.Clamp(offset.x, offsetLimits.min.x, offsetLimits.max.x), math.Clamp(offset.y, offsetLimits.min.y, offsetLimits.max.y), math.Clamp(offset.z, offsetLimits.min.z, offsetLimits.max.z) ) end hook.Add("CalcView", "ChestCamera_AttachToPlayer", function(ply, pos, angles, fov) if cameraEnabled then local view = {} local attachmentPoint = cameraMode == "head" and "eyes" or "chest" local offset = cameraMode == "head" and headCamOffset or chestCamOffset local attachmentID = ply:LookupAttachment(attachmentPoint) if attachmentID then local attachPos = ply:GetAttachment(attachmentID).Pos local desiredCamPos = attachPos + angles:Forward() * -offset.z + angles:Right() * offset.x + angles:Up() * offset.y angles:RotateAroundAxis(angles:Right(), headCamFOV) angles:RotateAroundAxis(angles:Right(), ChestCamFOV) local trace = util.TraceLine({ start = attachPos, endpos = desiredCamPos, filter = ply }) if trace.Hit then view.origin = trace.HitPos + trace.HitNormal * 5 else view.origin = desiredCamPos end view.angles = angles view.fov = fov view.drawviewer = true return view end end end) if exechack_api then exechack_api.CalcViewOverlayHook = function(ply, pos, angles, fov) if cameraEnabled then local view = {} local attachmentPoint = cameraMode == "head" and "eyes" or "chest" local offset = cameraMode == "head" and headCamOffset or chestCamOffset local attachmentID = ply:LookupAttachment(attachmentPoint) if attachmentID then local attachPos = ply:GetAttachment(attachmentID).Pos local desiredCamPos = attachPos + angles:Forward() * -offset.z + angles:Right() * offset.x + angles:Up() * offset.y angles:RotateAroundAxis(angles:Right(), headCamFOV) angles:RotateAroundAxis(angles:Right(), ChestCamFOV) local trace = util.TraceLine({ start = attachPos, endpos = desiredCamPos, filter = ply }) if trace.Hit then view.origin = trace.HitPos + trace.HitNormal * 5 else view.origin = desiredCamPos end view.angles = angles view.fov = fov view.drawviewer = true return view end end end end local function CreateHeadCameraSettings(panel) panel:ClearControls() panel:Help("Head Camera Settings") panel:CheckBox("Enable Head Camera", "headcamera_enabled") local offsetX = panel:NumSlider("Offset X", "headcamera_offset_x", -20, 20, 2) local offsetY = panel:NumSlider("Offset Y", "headcamera_offset_y", -20, 20, 2) local offsetZ = panel:NumSlider("Offset Z", "headcamera_offset_z", 0, 50, 2) local verticalAngle = panel:NumSlider("Vertical Angle (FOV)", "headcamera_fov", -30, 30, 2) verticalAngle:SetValue(headCamFOV) local resetButton = panel:Button("Reset to Default", "headcamera_reset") offsetX:SetValue(headCamOffset.x) offsetY:SetValue(headCamOffset.y) offsetZ:SetValue(headCamOffset.z) resetButton.DoClick = function() headCamOffset = Vector(10, 2, 8) headCamFOV = 0 offsetX:SetValue(headCamOffset.x) offsetY:SetValue(headCamOffset.y) offsetZ:SetValue(headCamOffset.z) verticalAngle:SetValue(headCamFOV) end end local function CreateChestCameraSettings(panel) panel:ClearControls() panel:Help("Chest Camera Settings") panel:CheckBox("Enable Chest Camera", "Chestcamera_enabled") local offsetX = panel:NumSlider("Offset X", "chestcamera_offset_x", -20, 20, 2) local offsetY = panel:NumSlider("Offset Y", "chestcamera_offset_y", -20, 20, 2) local offsetZ = panel:NumSlider("Offset Z", "chestcamera_offset_z", -50, 50, 2) local verticalAngle = panel:NumSlider("Vertical Angle (FOV)", "chestcamera_fov", -30, 30, 2) verticalAngle:SetValue(ChestCamFOV) local resetButton = panel:Button("Reset to Default", "chestcamera_reset") offsetX:SetValue(chestCamOffset.x) offsetY:SetValue(chestCamOffset.y) offsetZ:SetValue(chestCamOffset.z) resetButton.DoClick = function() chestCamOffset = Vector(2, 5, -8) ChestCamFOV = 0 offsetX:SetValue(chestCamOffset.x) offsetY:SetValue(chestCamOffset.y) offsetZ:SetValue(chestCamOffset.z) verticalAngle:SetValue(ChestCamFOV) end end local function UpdateCameraSettings() cameraEnabled = headCameraEnabled or ChestCameraEnabled if headCameraEnabled then cameraMode = "head" headCamOffset.x = ClampOffset(Vector(GetConVar("headcamera_offset_x"):GetFloat(), 0, 0)).x headCamOffset.y = ClampOffset(Vector(0, GetConVar("headcamera_offset_y"):GetFloat(), 0)).y headCamOffset.z = ClampOffset(Vector(0, 0, GetConVar("headcamera_offset_z"):GetFloat())).z headCamFOV = GetConVar("headcamera_fov"):GetFloat() elseif ChestCameraEnabled then cameraMode = "chest" chestCamOffset.x = ClampOffset(Vector(GetConVar("chestcamera_offset_x"):GetFloat(), 0, 0)).x chestCamOffset.y = ClampOffset(Vector(0, GetConVar("chestcamera_offset_y"):GetFloat(), 0)).y chestCamOffset.z = ClampOffset(Vector(0, 0, GetConVar("chestcamera_offset_z"):GetFloat())).z ChestCamFOV = GetConVar("chestcamera_fov"):GetFloat() end end CreateConVar("Chestcamera_enabled", "0", FCVAR_ARCHIVE, "Enable or disable Chest camera") CreateConVar("headcamera_enabled", "0", FCVAR_ARCHIVE, "Enable or disable head camera") CreateConVar("headcamera_offset_x", "10", FCVAR_ARCHIVE, "Head camera offset on X axis") CreateConVar("headcamera_offset_y", "2", FCVAR_ARCHIVE, "Head camera offset on Y axis") CreateConVar("headcamera_offset_z", "8", FCVAR_ARCHIVE, "Head camera offset on Z axis") CreateConVar("chestcamera_offset_x", "2", FCVAR_ARCHIVE, "Chest camera offset on X axis") CreateConVar("chestcamera_offset_y", "5", FCVAR_ARCHIVE, "Chest camera offset on Y axis") CreateConVar("chestcamera_offset_z", "-8", FCVAR_ARCHIVE, "Chest camera offset on Z axis") CreateConVar("headcamera_fov", "0", FCVAR_ARCHIVE, "Vertical angle adjustment for head camera") CreateConVar("chestcamera_fov", "0", FCVAR_ARCHIVE, "Vertical angle adjustment for Chest camera") cvars.AddChangeCallback("headcamera_enabled", function(convar, oldValue, newValue) headCameraEnabled = tobool(newValue) UpdateCameraSettings() end) cvars.AddChangeCallback("Chestcamera_enabled", function(convar, oldValue, newValue) ChestCameraEnabled = tobool(newValue) UpdateCameraSettings() end) cvars.AddChangeCallback("headcamera_offset_x", function(convar, oldValue, newValue) headCamOffset.x = ClampOffset(Vector(newValue, 0, 0)).x end) cvars.AddChangeCallback("headcamera_offset_y", function(convar, oldValue, newValue) headCamOffset.y = ClampOffset(Vector(0, newValue, 0)).y end) cvars.AddChangeCallback("headcamera_offset_z", function(convar, oldValue, newValue) headCamOffset.z = ClampOffset(Vector(0, 0, newValue)).z end) cvars.AddChangeCallback("chestcamera_offset_x", function(convar, oldValue, newValue) chestCamOffset.x = ClampOffset(Vector(newValue, 0, 0)).x end) cvars.AddChangeCallback("chestcamera_offset_y", function(convar, oldValue, newValue) chestCamOffset.y = ClampOffset(Vector(0, newValue, 0)).y end) cvars.AddChangeCallback("chestcamera_offset_z", function(convar, oldValue, newValue) chestCamOffset.z = ClampOffset(Vector(0, 0, newValue)).z end) hook.Add("PopulateToolMenu", "ChestCamera_PopulateToolMenu", function() spawnmenu.AddToolMenuOption("Options", "Camera", "HeadCamera", "Head Camera", "", "", CreateHeadCameraSettings) spawnmenu.AddToolMenuOption("Options", "Camera", "ChestCamera", "Chest Camera", "", "", CreateChestCameraSettings) end) RunConsoleCommand("spawnmenu_reload")