local A={}A.__index=A A.CameraShakeState={FadingIn=0;FadingOut=1;Sustained=2;Inactive=3}function A.new(g,r,i,Z)assert(type(g)=="\110\117\109\098\101\114","\077\097\103\110\105\116\117\100\101 \109\117\115\116 \098\101 \097 \110\117\109\098\101\114")assert(type(r)=="\110\117\109\098\101\114","\082\111\117\103\104\110\101\115\115 \109\117\115\116 \098\101 \097 \110\117\109\098\101\114")assert(type(i)=="\110\117\109\098\101\114","\070\097\100\101\073\110\084\105\109\101 \109\117\115\116 \098\101 \097 \110\117\109\098\101\114")assert(type(Z)=="\110\117\109\098\101\114","\070\097\100\101\079\117\116\084\105\109\101 \109\117\115\116 \098\101 \097 \110\117\109\098\101\114")local M=setmetatable({},A)M.Magnitude=g M.Roughness=r M.PositionInfluence=Vector3.new(.15,.15,.15)M.RotationInfluence=Vector3.new(1,1,1)M.DeleteOnInactive=true M.roughMod=1 M.magnMod=1 M.fadeOutDuration=Z M.fadeInDuration=i M.sustain=i>0 M.currentFadeTime=i>0 and 0 or 1 M.tick=(Random.new()):NextNumber(-100,100)M._camShakeInstance=true return M end function A.UpdateShake(g,A)local r=g.tick local i=g.currentFadeTime local Z=Vector3.new(math.noise(r,0)*.5,math.noise(0,r)*.5,math.noise(r,r)*.5)if g.fadeInDuration>0 and g.sustain then if i<1 then i=i+A/g.fadeInDuration elseif g.fadeOutDuration>0 then g.sustain=false end end if not g.sustain then i=i-A/g.fadeOutDuration end if g.sustain then g.tick=r+(A*g.Roughness)*g.roughMod else g.tick=r+((A*g.Roughness)*g.roughMod)*i end g.currentFadeTime=i return((Z*g.Magnitude)*g.magnMod)*i end function A.StartFadeOut(g,A)if A==0 then g.currentFadeTime=0 end g.fadeOutDuration=A g.fadeInDuration=0 g.sustain=false end function A.StartFadeIn(g,A)if A==0 then g.currentFadeTime=1 end g.fadeInDuration=A or g.fadeInDuration g.fadeOutDuration=0 g.sustain=true end function A.GetScaleRoughness(A)return A.roughMod end function A.SetScaleRoughness(g,A)g.roughMod=A end function A.GetScaleMagnitude(A)return A.magnMod end function A.SetScaleMagnitude(g,A)g.magnMod=A end function A.GetNormalizedFadeTime(A)return A.currentFadeTime end function A.IsShaking(A)return A.currentFadeTime>0 or A.sustain end function A.IsFadingOut(A)return not A.sustain and A.currentFadeTime>0 end function A.IsFadingIn(A)return A.currentFadeTime<1 and(A.sustain and A.fadeInDuration>0)end function A.GetState(g)if g:IsFadingIn()then return A.CameraShakeState.FadingIn elseif g:IsFadingOut()then return A.CameraShakeState.FadingOut elseif g:IsShaking()then return A.CameraShakeState.Sustained else return A.CameraShakeState.Inactive end end function A.destroy(A)A.Magnitude=nil A.Roughness=nil A.PositionInfluence=nil A.RotationInfluence=nil A.DeleteOnInactive=nil A.roughMod=nil A.magnMod=nil A.fadeOutDuration=nil A.fadeInDuration=nil A.sustain=nil A.currentFadeTime=nil A.tick=nil A._camShakeInstance=nil end return A
--[[
	cameraShakeInstance = CameraShakeInstance.new(magnitude, roughness, fadeInTime, fadeOutTime)
--]]

local CameraShakeInstance = {}
CameraShakeInstance.__index = CameraShakeInstance

CameraShakeInstance.CameraShakeState = {
	FadingIn = 0;
	FadingOut = 1;
	Sustained = 2;
	Inactive = 3;
}

function CameraShakeInstance.new(magnitude, roughness, fadeInTime, fadeOutTime)	
	assert(type(magnitude) == "number", "Magnitude must be a number")
	assert(type(roughness) == "number", "Roughness must be a number")
	assert(type(fadeInTime) == "number", "FadeInTime must be a number")
	assert(type(fadeOutTime) == "number", "FadeOutTime must be a number")
	
	local self = setmetatable({}, CameraShakeInstance)
	
	self.Magnitude = magnitude
	self.Roughness = roughness
	self.PositionInfluence = Vector3.new(0.15, 0.15, 0.15)
	self.RotationInfluence = Vector3.new(1, 1, 1)
	self.DeleteOnInactive = true
	self.roughMod = 1
	self.magnMod = 1
	self.fadeOutDuration = fadeOutTime
	self.fadeInDuration = fadeInTime
	self.sustain = (fadeInTime > 0)
	self.currentFadeTime = (fadeInTime > 0 and 0 or 1)
	self.tick = Random.new():NextNumber(-100, 100)
	self._camShakeInstance = true
	
	return self
	
end

function CameraShakeInstance:UpdateShake(deltaTime)
	local _tick = self.tick
	local currentFadeTime = self.currentFadeTime

	local offset = Vector3.new(
		math.noise(_tick, 0) * 0.5,
		math.noise(0, _tick) * 0.5,
		math.noise(_tick, _tick) * 0.5
	)

	if self.fadeInDuration > 0 and self.sustain then
		if currentFadeTime < 1 then
			currentFadeTime = currentFadeTime + (deltaTime / self.fadeInDuration)
		elseif self.fadeOutDuration > 0 then
			self.sustain = false
		end
	end

	if not self.sustain then
		currentFadeTime = currentFadeTime - (deltaTime / self.fadeOutDuration)
	end

	if self.sustain then
		self.tick = _tick + (deltaTime * self.Roughness * self.roughMod)
	else
		self.tick = _tick + (deltaTime * self.Roughness * self.roughMod * currentFadeTime)
	end

	self.currentFadeTime = currentFadeTime

	return offset * self.Magnitude * self.magnMod * currentFadeTime
end

function CameraShakeInstance:StartFadeOut(fadeOutTime)
	if fadeOutTime == 0 then
		self.currentFadeTime = 0
	end
	self.fadeOutDuration = fadeOutTime
	self.fadeInDuration = 0
	self.sustain = false
end

function CameraShakeInstance:StartFadeIn(fadeInTime)
	if fadeInTime == 0 then
		self.currentFadeTime = 1
	end
	self.fadeInDuration = fadeInTime or self.fadeInDuration
	self.fadeOutDuration = 0
	self.sustain = true
end

function CameraShakeInstance:GetScaleRoughness()
	return self.roughMod
end

function CameraShakeInstance:SetScaleRoughness(scale)
	self.roughMod = scale
end

function CameraShakeInstance:GetScaleMagnitude()
	return self.magnMod
end

function CameraShakeInstance:SetScaleMagnitude(scale)
	self.magnMod = scale
end

function CameraShakeInstance:GetNormalizedFadeTime()
	return self.currentFadeTime
end

function CameraShakeInstance:IsShaking()
	return self.currentFadeTime > 0 or self.sustain
end

function CameraShakeInstance:IsFadingOut()
	return not self.sustain and self.currentFadeTime > 0
end

function CameraShakeInstance:IsFadingIn()
	return self.currentFadeTime < 1 and self.sustain and self.fadeInDuration > 0
end

function CameraShakeInstance:GetState()
	if self:IsFadingIn() then
		return CameraShakeInstance.CameraShakeState.FadingIn
	elseif self:IsFadingOut() then
		return CameraShakeInstance.CameraShakeState.FadingOut
	elseif self:IsShaking() then
		return CameraShakeInstance.CameraShakeState.Sustained
	else
		return CameraShakeInstance.CameraShakeState.Inactive
	end
end

function CameraShakeInstance:destroy()
	-- Set all properties to nil or default values
	self.Magnitude = nil
	self.Roughness = nil
	self.PositionInfluence = nil
	self.RotationInfluence = nil
	self.DeleteOnInactive = nil
	self.roughMod = nil
	self.magnMod = nil
	self.fadeOutDuration = nil
	self.fadeInDuration = nil
	self.sustain = nil
	self.currentFadeTime = nil
	self.tick = nil
	self._camShakeInstance = nil
end

return CameraShakeInstance
