local function q()local q=PlayersService.LocalPlayer if q and(game.Workspace.CurrentCamera and game.Workspace.CurrentCamera.CameraType==Enum.CameraType.Custom)then return true end return false end local function n()if EnabledCamera then EnabledCamera:Update()end if EnabledOcclusion and not VRService.VREnabled then EnabledOcclusion:Update(EnabledCamera)end if shouldUsePlayerScriptsCamera()then TransparencyController:Update()end end local function g(q)if EnabledCamera~=q then if EnabledCamera then EnabledCamera:SetEnabled(false)end EnabledCamera=q if EnabledCamera then EnabledCamera:SetEnabled(true)end end end local function M(n)if n==Enum.DevComputerMovementMode.ClickToMove.Name then if FFlagUserNoCameraClickToMove then return end ClickToMove:Start()g(nil)TransparencyController:SetEnabled(true)else local q=workspace.CurrentCamera and workspace.CurrentCamera.CameraType if VRService.VREnabled and q~=Enum.CameraType.Scriptable then g(VRCamera)TransparencyController:SetEnabled(false)elseif(q==Enum.CameraType.Custom or not AllCamerasInLua)and n==Enum.ComputerCameraMovementMode.Classic.Name then g(ClassicCamera)TransparencyController:SetEnabled(true)elseif(q==Enum.CameraType.Custom or not AllCamerasInLua)and n==Enum.ComputerCameraMovementMode.Follow.Name then g(FollowCamera)TransparencyController:SetEnabled(true)elseif(q==Enum.CameraType.Custom or not AllCamerasInLua)and(isOrbitalCameraEnabled and n==Enum.ComputerCameraMovementMode.Orbital.Name)then g(OrbitalCamera)TransparencyController:SetEnabled(true)elseif AllCamerasInLua and CameraTypeEnumMap[q]then g(CameraTypeEnumMap[q])TransparencyController:SetEnabled(false)else g(nil)TransparencyController:SetEnabled(false)end ClickToMove:Stop()end local M=q()local N=getCameraOcclusionMode()if EnabledOcclusion==Invisicam and(N~=Enum.DevCameraOcclusionMode.Invisicam or not M)then Invisicam:Cleanup()end if M then if N==Enum.DevCameraOcclusionMode.Zoom and(isOrbitalCameraEnabled and n~=Enum.ComputerCameraMovementMode.Orbital.Name)then EnabledOcclusion=PopperCam elseif N==Enum.DevCameraOcclusionMode.Invisicam then EnabledOcclusion=Invisicam else EnabledOcclusion=nil end else EnabledOcclusion=nil end end local function N(q)if q==Enum.CameraType.Scriptable then UserInputService.MouseBehavior=Enum.MouseBehavior.Default end end local function d(q)TransparencyController:SetSubject(q)end local function x()M(getCurrentCameraMode())local q=workspace.CurrentCamera if q then if cameraSubjectChangedConn then cameraSubjectChangedConn:disconnect()end if cameraTypeChangedConn then cameraTypeChangedConn:disconnect()end cameraSubjectChangedConn=(q:GetPropertyChangedSignal("\067\097\109\101\114\097\083\117\098\106\101\099\116")):connect(function()d(q.CameraSubject)end)cameraTypeChangedConn=(q:GetPropertyChangedSignal("\067\097\109\101\114\097\084\121\112\101")):connect(function()M(getCurrentCameraMode())N(q.CameraType)end)d(q.CameraSubject)N(q.CameraType)end end local function v(q)workspace.Changed:connect(function(q)if q=="\067\117\114\114\101\110\116\067\097\109\101\114\097"then x()end end)q.Changed:connect(function(q)M(getCurrentCameraMode())end)GameSettings.Changed:connect(function(q)M(getCurrentCameraMode())end)RunService:BindToRenderStep("\099\097\109\101\114\097\082\101\110\100\101\114\085\112\100\097\116\101",Enum.RenderPriority.Camera.Value,n)x()M(getCurrentCameraMode())end do while PlayersService.LocalPlayer==nil do PlayersService.PlayerAdded:wait()end hasLastInput=pcall(function()lastInputType=UserInputService:GetLastInputType()UserInputService.LastInputTypeChanged:connect(function(q)lastInputType=q end)end)v(PlayersService.LocalPlayer)end local function P()M(getCurrentCameraMode())end;(VRService:GetPropertyChangedSignal("\086\082\069\110\097\098\108\101\100")):connect(P)

local function shouldUseOcclusionModule()
	local player = PlayersService.LocalPlayer
	if player and game.Workspace.CurrentCamera and game.Workspace.CurrentCamera.CameraType == Enum.CameraType.Custom then
		return true
	end
	return false
end

local function Update()
	if EnabledCamera then
		EnabledCamera:Update()
	end
	if EnabledOcclusion and not VRService.VREnabled then
		EnabledOcclusion:Update(EnabledCamera)
	end
	if shouldUsePlayerScriptsCamera() then
		TransparencyController:Update()
	end
end

local function SetEnabledCamera(newCamera)
	if EnabledCamera ~= newCamera then
		if EnabledCamera then
			EnabledCamera:SetEnabled(false)
		end
		EnabledCamera = newCamera
		if EnabledCamera then
			EnabledCamera:SetEnabled(true)
		end
	end
end

local function OnCameraMovementModeChange(newCameraMode)
	if newCameraMode == Enum.DevComputerMovementMode.ClickToMove.Name then
		if FFlagUserNoCameraClickToMove then
			--No longer responding to ClickToMove here!
			return
		end
		ClickToMove:Start()
		SetEnabledCamera(nil)
		TransparencyController:SetEnabled(true)
	else
		local currentCameraType = workspace.CurrentCamera and workspace.CurrentCamera.CameraType
		if VRService.VREnabled and currentCameraType ~= Enum.CameraType.Scriptable then
			SetEnabledCamera(VRCamera)
			TransparencyController:SetEnabled(false)		
		elseif (currentCameraType == Enum.CameraType.Custom or not AllCamerasInLua) and newCameraMode == Enum.ComputerCameraMovementMode.Classic.Name then
			SetEnabledCamera(ClassicCamera)			
			TransparencyController:SetEnabled(true)
		elseif (currentCameraType == Enum.CameraType.Custom or not AllCamerasInLua) and newCameraMode == Enum.ComputerCameraMovementMode.Follow.Name then
			SetEnabledCamera(FollowCamera)
			TransparencyController:SetEnabled(true)
		elseif (currentCameraType == Enum.CameraType.Custom or not AllCamerasInLua) and (isOrbitalCameraEnabled and (newCameraMode == Enum.ComputerCameraMovementMode.Orbital.Name)) then
			SetEnabledCamera(OrbitalCamera)
			TransparencyController:SetEnabled(true)
		elseif AllCamerasInLua and CameraTypeEnumMap[currentCameraType] then
			SetEnabledCamera(CameraTypeEnumMap[currentCameraType])
			TransparencyController:SetEnabled(false)
		else -- Our camera movement code was disabled by the developer
			SetEnabledCamera(nil)
			TransparencyController:SetEnabled(false)
		end
		ClickToMove:Stop()
	end
	
	local useOcclusion = shouldUseOcclusionModule()
	local newOcclusionMode = getCameraOcclusionMode()
	if EnabledOcclusion == Invisicam and (newOcclusionMode ~= Enum.DevCameraOcclusionMode.Invisicam or (not useOcclusion)) then
		Invisicam:Cleanup()
	end
	
	-- PopperCam does not work with OrbitalCamera, as OrbitalCamera's distance can be fixed.
	if useOcclusion then	
		if newOcclusionMode == Enum.DevCameraOcclusionMode.Zoom and ( isOrbitalCameraEnabled and newCameraMode ~= Enum.ComputerCameraMovementMode.Orbital.Name ) then
			EnabledOcclusion = PopperCam
		elseif newOcclusionMode == Enum.DevCameraOcclusionMode.Invisicam then
			EnabledOcclusion = Invisicam
		else
			EnabledOcclusion = nil
		end
	else
		EnabledOcclusion = nil
	end
end

local function OnCameraTypeChanged(newCameraType)
	if newCameraType == Enum.CameraType.Scriptable then
		UserInputService.MouseBehavior = Enum.MouseBehavior.Default
	end
end


local function OnCameraSubjectChanged(newSubject)
	TransparencyController:SetSubject(newSubject)
end

local function OnNewCamera()
	OnCameraMovementModeChange(getCurrentCameraMode())

	local currentCamera = workspace.CurrentCamera
	if currentCamera then
		if cameraSubjectChangedConn then
			cameraSubjectChangedConn:disconnect()
  		end

		if cameraTypeChangedConn then
			cameraTypeChangedConn:disconnect()
		end

		cameraSubjectChangedConn = currentCamera:GetPropertyChangedSignal("CameraSubject"):connect(function()
			OnCameraSubjectChanged(currentCamera.CameraSubject)
		end)
	
		cameraTypeChangedConn = currentCamera:GetPropertyChangedSignal("CameraType"):connect(function()
			OnCameraMovementModeChange(getCurrentCameraMode())
			OnCameraTypeChanged(currentCamera.CameraType)
  		end)

		OnCameraSubjectChanged(currentCamera.CameraSubject)
		OnCameraTypeChanged(currentCamera.CameraType)
	end
end


local function OnPlayerAdded(player)
	workspace.Changed:connect(function(prop)
		if prop == 'CurrentCamera' then
			OnNewCamera()
		end
	end)

	player.Changed:connect(function(prop)
		OnCameraMovementModeChange(getCurrentCameraMode())
	end)

	GameSettings.Changed:connect(function(prop)
		OnCameraMovementModeChange(getCurrentCameraMode())
	end)

	RunService:BindToRenderStep("cameraRenderUpdate", Enum.RenderPriority.Camera.Value, Update)

	OnNewCamera()
	OnCameraMovementModeChange(getCurrentCameraMode())
end

do
	while PlayersService.LocalPlayer == nil do PlayersService.PlayerAdded:wait() end
	hasLastInput = pcall(function()
		lastInputType = UserInputService:GetLastInputType()
		UserInputService.LastInputTypeChanged:connect(function(newLastInputType) 
			lastInputType = newLastInputType
		end)
	end)
	OnPlayerAdded(PlayersService.LocalPlayer)
end

local function OnVREnabled()
	OnCameraMovementModeChange(getCurrentCameraMode())
end

VRService:GetPropertyChangedSignal("VREnabled"):connect(OnVREnabled)
