```lua
local firstPersonMode = CreateClientConVar('qwb_firstperson', 0, true, false, 'FirstPerson Mode (from the hip)', 0, 2)
local firstPersonZNear = CreateClientConVar('qwb_firstperson_znear', 1.75, true, false, 'FirstPerson ZNear', 1, 5)

net.Receive('qwb.setIronsight', function()
	local b = net.ReadBool()

	qwb.ironsighted = b
end)

local angle_zero = Angle()
local firstPersonOffset1 = Vector()
local firstPersonOffset2 = Vector(-2, 0, 5)

local headDefaultScale = Vector(1, 1, 1)
local headScale = Vector(0.01, 0.01, 0.01)

local function hideHead(ply, boneID)
	if not IsValid(ply) then return false end

	boneID = boneID or ply:LookupBone('ValveBiped.Bip01_Head1')
	if not boneID then return end

	local curHeadScale = ply:GetManipulateBoneScale(boneID)
	if curHeadScale ~= headScale then
		ply:ManipulateBoneScale(boneID, headScale)
	end
end

local function showHead(ply, boneID)
	if not IsValid(ply) then return false end

	boneID = boneID or ply:LookupBone('ValveBiped.Bip01_Head1')
	if not boneID then return end

	local curHeadScale = ply:GetManipulateBoneScale(boneID)
	if curHeadScale ~= headDefaultScale then
		ply:ManipulateBoneScale(boneID, headDefaultScale)
	end
end

local function shouldChangeCalcView(ply)
	if not IsValid(ply) then return false end
	if GetViewEntity() ~= LocalPlayer() then return false end
	if not ply:Alive() then return false end

	local weap = ply:GetActiveWeapon()
	if not IsValid(weap) or not weap.IsQWB then return false end

	return true
end

local firstPersonModes = {
	[0] = function(ply, origin, angles)
		local att = ply:GetAttachment( ply:LookupAttachment('eyes') )
		if not att then return end

		local pos, ang = LocalToWorld(firstPersonOffset1, angle_zero, att.Pos, att.Ang)
		return pos, ang
	end,

	[1] = function(ply, origin, angles)
		local att = ply:GetAttachment( ply:LookupAttachment('anim_attachment_head') )
		if not att then return end

		local pos, ang = LocalToWorld(firstPersonOffset2, angle_zero, att.Pos, angles)
		return pos, ang
	end,
}

local function getSightPos(ply)
	local weap = ply:GetActiveWeapon()
	local att = ply:GetAttachment( ply:LookupAttachment('anim_attachment_rh') )
	if not att then return end

	local offset = weap.IronsightOffset
	local angOffset = weap.IronsightAngle

	if weap.Attachments and weap._attachments and weap._attachments.sights then
		local id = weap._attachments.sights.id
		local data = weap.Attachments.sights[id]
		if data then
			local camOffset = data.sightCameraOffset
			if camOffset then
				offset = offset + camOffset
			end

			local camAngOffset = data.sightCameraAngleOffset
			if camAngOffset then
				angOffset = angOffset + camAngOffset
			end
		end
	end

	return LocalToWorld(offset, angOffset or angle_zero, att.Pos, att.Ang)
end

local function nonSightCalcView(ply, origin, angles, fov, znear, zfar)
	if not shouldChangeCalcView(ply) then
		qwb.ironsightLerpProgress = nil
		return
	end

	qwb.ironsightLerpProgress = qwb.ironsightLerpProgress or 0
	qwb.ironsightLerpProgress = math.Clamp(qwb.ironsightLerpProgress - (FrameTime() * 4), 0, 1)

	local mode = firstPersonMode:GetInt()

	local getPosFunc = firstPersonModes[mode]
	if not getPosFunc then return end

	local pos, ang = getPosFunc(ply, origin, angles)
	if not pos then return end

	local sightPos = getSightPos(ply) or origin
	pos = LerpVector(qwb.ironsightLerpProgress, pos, sightPos)

	return {
		origin = pos,
		angles = ang,
		fov = fov,
		drawviewer = true,
		znear = firstPersonZNear:GetFloat() or 1.75,
	}
end

timer.Create('qwb.headCheck', 0.5, 0, function()
	if not shouldChangeCalcView(LocalPlayer()) or (firstPersonMode:GetInt() ~= 1 and not qwb.ironsighted) then
		showHead(LocalPlayer())
	elseif shouldChangeCalcView(LocalPlayer()) and (firstPersonMode:GetInt() == 1 or qwb.ironsighted) then
		hideHead(LocalPlayer())
	end
end)

hook.Add('InputMouseApply', 'qwb.firstPerson', function(cmd, x, y, ang)
	local mode = firstPersonMode:GetInt()
	if mode ~= 1 then return end

	if not shouldChangeCalcView(LocalPlayer()) then return end

	ang.p = math.Clamp(ang.p + y / 50, -65, 65)
	ang.y = ang.y - x / 50
	cmd:SetViewAngles(ang)

	return true
end)

hook.Add('CalcView', 'qwb.ironsight', function(ply, origin, angles, fov, znear, zfar)
	if not qwb.ironsighted then return nonSightCalcView(ply, origin, angles, fov, znear, zfar) end

	if not shouldChangeCalcView(ply) or qwb.isPlayerRunning(ply) then
		qwb.ironsighted = nil
		qwb.ironsightLerpProgress = nil
		return
	end

	local pos, ang = getSightPos(ply)

	qwb.ironsightLerpProgress = qwb.ironsightLerpProgress or 0
	qwb.ironsightLerpProgress = math.Clamp(qwb.ironsightLerpProgress + (FrameTime() * 3), 0, 1)

	local mode = firstPersonMode:GetInt()
	local getFunc = firstPersonModes[mode]
	local nonSightPos = getFunc and getFunc(ply, origin, angles) or origin

	pos = LerpVector(qwb.ironsightLerpProgress, nonSightPos, pos)

	local weap = ply:GetActiveWeapon()

	local view = {
		origin = pos,
		angles = ang,
		fov = fov,
		znear = weap.IronsightZNear or 2.35,
		drawviewer = true,
	}

	return view
end)

-- Thanks to octothorp team for this solution, which fixes camera shake
hook.Add('RenderScene', '_qwb', function(pos, angle, fov)
	local camData = hook.Run('CalcView', LocalPlayer(), pos, angle, fov)
	if not camData then return end

	render.Clear(0, 0, 0, 255, true, true, true)
	render.RenderView({
		angles = camData.angles,
		origin = camData.origin,
		drawhud = true,
		drawmonitors = true,
		dopostprocess = true,
	})

	return true
end)

function qwb.fullyClearStencil()
	render.SetStencilWriteMask( 0xFF )
	render.SetStencilTestMask( 0xFF )
	render.SetStencilReferenceValue( 0 )
	render.SetStencilCompareFunction( STENCIL_ALWAYS )
	render.SetStencilPassOperation( STENCIL_KEEP )
	render.SetStencilFailOperation( STENCIL_KEEP )
	render.SetStencilZFailOperation( STENCIL_KEEP )
	render.ClearStencil()
end
```
Оптимизируй код но сохрани логику