local p=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 N=p("\067\097\109\101\114\097\083\116\097\116\101")local q=p("\083\117\109\109\101\100\067\097\109\101\114\097")local k=p("\083\112\114\105\110\103")local a={}a.ClassName="\076\097\103\080\111\105\110\116\067\097\109\101\114\097"a._FocusCamera=nil a._OriginCamera=nil function a.new(p,N)local q=setmetatable({},a)q.FocusSpring=k.new(Vector3.new())q.OriginCamera=p or error("\077\117\115\116 \104\097\118\101 \111\114\105\103\105\110\067\097\109\101\114\097")q.FocusCamera=N or error("\077\117\115\116 \104\097\118\101 \102\111\099\117\115\067\097\109\101\114\097")q.Speed=10 return q end function a.__add(N,p)return q.new(N,p)end function a.__newindex(q,p,N)if p=="\070\111\099\117\115\067\097\109\101\114\097"then rawset(q,"\095"..p,N)q.FocusSpring.Target=q.FocusCamera.CameraState.Position q.FocusSpring.Position=q.FocusSpring.Target q.FocusSpring.Velocity=Vector3.new(0,0,0)elseif p=="\079\114\105\103\105\110\067\097\109\101\114\097"then rawset(q,"\095"..p,N)elseif p=="\076\097\115\116\070\111\099\117\115\085\112\100\097\116\101"or p=="\070\111\099\117\115\083\112\114\105\110\103"then rawset(q,p,N)elseif p=="\083\112\101\101\100"or p=="\068\097\109\112\101\114"or p=="\086\101\108\111\099\105\116\121"then q.FocusSpring[p]=N else error(p.." \105\115 \110\111\116 \097 \118\097\108\105\100 \109\101\109\098\101\114 \111\102 \076\097\103\080\111\105\110\116\067\097\109\101\114\097")end end function a.__index(q,p)if p=="\083\116\097\116\101"or p=="\067\097\109\101\114\097\083\116\097\116\101"or p=="\067\097\109\101\114\097"then local p,k=q.Origin,q.FocusPosition local a=N.new()a.FieldOfView=p.FieldOfView+q.FocusCamera.CameraState.FieldOfView a.CFrame=CFrame.new(p.Position,k)return a elseif p=="\070\111\099\117\115\080\111\115\105\116\105\111\110"then local p if q.LastFocusUpdate then p=tick()-q.LastFocusUpdate end q.LastFocusUpdate=tick()q.FocusSpring.Target=q.FocusCamera.CameraState.Position if p then q.FocusSpring:TimeSkip(p)end return q.FocusSpring.Position elseif p=="\083\112\101\101\100"or p=="\068\097\109\112\101\114"or p=="\086\101\108\111\099\105\116\121"then return q.FocusSpring[p]elseif p=="\079\114\105\103\105\110"then return q.OriginCamera.CameraState elseif p=="\070\111\099\117\115\067\097\109\101\114\097"or p=="\079\114\105\103\105\110\067\097\109\101\114\097"then return rawget(q,"\095"..p)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 a[p]end end return a
--- Point a current element but lag behind for a smoother experience
-- @classmod LagPointCamera

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

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

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

---
-- @constructor
-- @param originCamera A camera to use
-- @param focusCamera The Camera to look at.
function LagPointCamera.new(originCamera, focusCamera)
	local self = setmetatable({}, LagPointCamera)

	self.FocusSpring = Spring.new(Vector3.new())
	self.OriginCamera = originCamera or error("Must have originCamera")
	self.FocusCamera = focusCamera or error("Must have focusCamera")
	self.Speed = 10

	return self
end

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

function LagPointCamera:__newindex(index, value)
	if index == "FocusCamera" then
		rawset(self, "_" .. index, value)
		self.FocusSpring.Target = self.FocusCamera.CameraState.Position
		self.FocusSpring.Position = self.FocusSpring.Target
		self.FocusSpring.Velocity = Vector3.new(0, 0, 0)
	elseif index == "OriginCamera" then
		rawset(self, "_" .. index, value)
	elseif index == "LastFocusUpdate" or index == "FocusSpring" then
		rawset(self, index, value)
	elseif index == "Speed" or index == "Damper" or index == "Velocity" then
		self.FocusSpring[index] = value
	else
		error(index .. " is not a valid member of LagPointCamera")
	end
end

function LagPointCamera:__index(index)
	if index == "State" or index == "CameraState" or index == "Camera" then
		local origin, focusPosition = self.Origin, self.FocusPosition

		local state = CameraState.new()
		state.FieldOfView = origin.FieldOfView + self.FocusCamera.CameraState.FieldOfView
		state.CFrame = CFrame.new(origin.Position, focusPosition)

		return state
	elseif index == "FocusPosition" then
		local delta
		if self.LastFocusUpdate then
			delta = tick() - self.LastFocusUpdate
		end

		self.LastFocusUpdate = tick()
		self.FocusSpring.Target = self.FocusCamera.CameraState.Position

		if delta then
			self.FocusSpring:TimeSkip(delta)
		end

		return self.FocusSpring.Position
	elseif index == "Speed" or index == "Damper" or index == "Velocity" then
		return self.FocusSpring[index]
	elseif index == "Origin" then
		return self.OriginCamera.CameraState
	elseif index == "FocusCamera" or index == "OriginCamera" then
		return rawget(self, "_" .. index) or error("Internal error: index does not exist")
	else
		return LagPointCamera[index]
	end
end

return LagPointCamera