local N=require((game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")):WaitForChild("\078\101\118\101\114\109\111\114\101"))local C=N("\067\097\109\101\114\097\083\116\097\116\101")local F=N("\083\117\109\109\101\100\067\097\109\101\114\097")local h=N("\083\112\114\105\110\103")local d={}d.ClassName="\083\109\111\111\116\104\080\111\115\105\116\105\111\110\067\097\109\101\114\097"d._FocusCamera=nil d._OriginCamera=nil function d.new(N)local C=setmetatable({},d)C.Spring=h.new(Vector3.new())C.BaseCamera=N or error("\077\117\115\116 \104\097\118\101 \066\097\115\101\067\097\109\101\114\097")C.Speed=10 return C end function d.__add(C,N)return F.new(C,N)end function d.__newindex(F,N,C)if N=="\066\097\115\101\067\097\109\101\114\097"then rawset(F,"\095"..N,C)F.Spring.Target=F.BaseCamera.CameraState.Position F.Spring.Position=F.Spring.Target F.Spring.Velocity=Vector3.new(0,0,0)elseif N=="\076\097\115\116\085\112\100\097\116\101\084\105\109\101"or N=="\083\112\114\105\110\103"then rawset(F,N,C)elseif N=="\083\112\101\101\100"or N=="\068\097\109\112\101\114"or N=="\086\101\108\111\099\105\116\121"or N=="\080\111\115\105\116\105\111\110"then F:InternalUpdate()F.Spring[N]=C else error(N.." \105\115 \110\111\116 \097 \118\097\108\105\100 \109\101\109\098\101\114 \111\102 \083\109\111\111\116\104\080\111\115\105\116\105\111\110\067\097\109\101\114\097")end end function d.InternalUpdate(N)local C if N.LastUpdateTime then C=tick()-N.LastUpdateTime end N.LastUpdateTime=tick()N.Spring.Target=N.BaseCameraState.Position if C then N.Spring:TimeSkip(C)end end function d.__index(F,N)if N=="\083\116\097\116\101"or N=="\067\097\109\101\114\097\083\116\097\116\101"or N=="\067\097\109\101\114\097"then local N=F.BaseCameraState local h=C.new()h.FieldOfView=N.FieldOfView h.CFrame=N.CFrame h.Position=F.Position return h elseif N=="\080\111\115\105\116\105\111\110"then F:InternalUpdate()return F.Spring.Position elseif N=="\083\112\101\101\100"or N=="\068\097\109\112\101\114"or N=="\086\101\108\111\099\105\116\121"then return F.Spring[N]elseif N=="\084\097\114\103\101\116"then return F.BaseCameraState.Position elseif N=="\066\097\115\101\067\097\109\101\114\097\083\116\097\116\101"then return F.BaseCamera.CameraState or F.BaseCamera elseif N=="\066\097\115\101\067\097\109\101\114\097"then return rawget(F,"\095"..N)or error("\073\110\116\101\114\110\097\108 \101\114\114\111\114\058 \105\110\100\101\120 \100\111\101\115 \110\111\116 \101\120\105\115\116")else return d[N]end end return d
--- Lags the camera smoothly behind the position maintaining other components
-- @classmod SmoothPositionCamera

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Nevermore"))

local CameraState = require("CameraState")
local SummedCamera = require("SummedCamera")
local Spring = require("Spring")

local SmoothPositionCamera = {}
SmoothPositionCamera.ClassName = "SmoothPositionCamera"
SmoothPositionCamera._FocusCamera = nil
SmoothPositionCamera._OriginCamera = nil

function SmoothPositionCamera.new(baseCamera)
	local self = setmetatable({}, SmoothPositionCamera)

	self.Spring = Spring.new(Vector3.new())
	self.BaseCamera = baseCamera or error("Must have BaseCamera")
	self.Speed = 10

	return self
end

function SmoothPositionCamera:__add(other)
	return SummedCamera.new(self, other)
end

function SmoothPositionCamera:__newindex(index, value)
	if index == "BaseCamera" then
		rawset(self, "_" .. index, value)
		self.Spring.Target = self.BaseCamera.CameraState.Position
		self.Spring.Position = self.Spring.Target
		self.Spring.Velocity = Vector3.new(0, 0, 0)
	elseif index == "LastUpdateTime" or index == "Spring" then
		rawset(self, index, value)
	elseif index == "Speed" or index == "Damper" or index == "Velocity" or index == "Position" then
		self:InternalUpdate()
		self.Spring[index] = value
	else
		error(index .. " is not a valid member of SmoothPositionCamera")
	end
end

function SmoothPositionCamera:InternalUpdate()
	local Delta
	if self.LastUpdateTime then
		Delta = tick() - self.LastUpdateTime
	end

	self.LastUpdateTime = tick()
	self.Spring.Target = self.BaseCameraState.Position

	if Delta then
		self.Spring:TimeSkip(Delta)
	end
end

function SmoothPositionCamera:__index(index)
	if index == "State" or index == "CameraState" or index == "Camera" then
		local baseCameraState = self.BaseCameraState

		local state = CameraState.new()
		state.FieldOfView = baseCameraState.FieldOfView
		state.CFrame = baseCameraState.CFrame
		state.Position = self.Position

		return state
	elseif index == "Position" then
		self:InternalUpdate()
		return self.Spring.Position
	elseif index == "Speed" or index == "Damper" or index == "Velocity" then
		return self.Spring[index]
	elseif index == "Target" then
		return self.BaseCameraState.Position
	elseif index == "BaseCameraState" then
		return self.BaseCamera.CameraState or self.BaseCamera
	elseif index == "BaseCamera" then
		return rawget(self, "_" .. index) or error("Internal error: index does not exist")
	else
		return SmoothPositionCamera[index]
	end
end

return SmoothPositionCamera