local C={}C.__index=C local p=Vector3.new local d=math.noise C.CameraShakeState={FadingIn=0;FadingOut=1;Sustained=2;Inactive=3}function C.new(d,x,I,X)if I==nil then I=0 end if X==nil then X=0 end assert(type(d)=="\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(x)=="\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(X)=="\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 g=setmetatable({Magnitude=d,Roughness=x;PositionInfluence=p(),RotationInfluence=p();DeleteOnInactive=true;roughMod=1;magnMod=1,fadeOutDuration=X,fadeInDuration=I,sustain=I>0;currentFadeTime=I>0 and 0 or 1;tick=(Random.new()):NextNumber(-100,100);_camShakeInstance=true},C)return g end function C.UpdateShake(x,C)local I=x.tick local X=x.currentFadeTime local g=p(d(I,0)*.5,d(0,I)*.5,d(I,I)*.5)if x.fadeInDuration>0 and x.sustain then if X<1 then X=X+C/x.fadeInDuration elseif x.fadeOutDuration>0 then x.sustain=false end end if not x.sustain then X=X-C/x.fadeOutDuration end if x.sustain then x.tick=I+(C*x.Roughness)*x.roughMod else x.tick=I+((C*x.Roughness)*x.roughMod)*X end x.currentFadeTime=X return((g*x.Magnitude)*x.magnMod)*X end function C.StartFadeOut(p,C)if C==0 then p.currentFadeTime=0 end p.fadeOutDuration=C p.fadeInDuration=0 p.sustain=false end function C.StartFadeIn(p,C)if C==0 then p.currentFadeTime=1 end p.fadeInDuration=C or p.fadeInDuration p.fadeOutDuration=0 p.sustain=true end function C.GetScaleRoughness(C)return C.roughMod end function C.SetScaleRoughness(p,C)p.roughMod=C end function C.GetScaleMagnitude(C)return C.magnMod end function C.SetScaleMagnitude(p,C)p.magnMod=C end function C.GetNormalizedFadeTime(C)return C.currentFadeTime end function C.IsShaking(C)return C.currentFadeTime>0 or C.sustain end function C.IsFadingOut(C)return not C.sustain and C.currentFadeTime>0 end function C.IsFadingIn(C)return C.currentFadeTime<1 and(C.sustain and C.fadeInDuration>0)end function C.GetState(p)if p:IsFadingIn()then return C.CameraShakeState.FadingIn elseif p:IsFadingOut()then return C.CameraShakeState.FadingOut elseif p:IsShaking()then return C.CameraShakeState.Sustained else return C.CameraShakeState.Inactive end end return C
-- Camera Shake Instance
-- Crazyman32
-- February 26, 2018

--[[
	
	cameraShakeInstance = CameraShakeInstance.new(magnitude, roughness, fadeInTime, fadeOutTime)
	
--]]



local CameraShakeInstance = {}
CameraShakeInstance.__index = CameraShakeInstance

local V3 = Vector3.new
local NOISE = math.noise


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


function CameraShakeInstance.new(magnitude, roughness, fadeInTime, fadeOutTime)
	
	if (fadeInTime == nil) then fadeInTime = 0 end
	if (fadeOutTime == nil) then fadeOutTime = 0 end
	
	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({
		Magnitude = magnitude;
		Roughness = roughness;
		PositionInfluence = V3();
		RotationInfluence = V3();
		DeleteOnInactive = true;
		roughMod = 1;
		magnMod = 1;
		fadeOutDuration = fadeOutTime;
		fadeInDuration = fadeInTime;
		sustain = (fadeInTime > 0);
		currentFadeTime = (fadeInTime > 0 and 0 or 1);
		tick = Random.new():NextNumber(-100, 100);
		_camShakeInstance = true;
	}, CameraShakeInstance)
	
	return self
	
end


function CameraShakeInstance:UpdateShake(dt)
	
	local _tick = self.tick
	local currentFadeTime = self.currentFadeTime
	
	local offset = V3(
		NOISE(_tick, 0) * 0.5,
		NOISE(0, _tick) * 0.5,
		NOISE(_tick, _tick) * 0.5
	)
	
	if (self.fadeInDuration > 0 and self.sustain) then
		if (currentFadeTime < 1) then
			currentFadeTime = currentFadeTime + (dt / self.fadeInDuration)
		elseif (self.fadeOutDuration > 0) then
			self.sustain = false
		end
	end
	
	if (not self.sustain) then
		currentFadeTime = currentFadeTime - (dt / self.fadeOutDuration)
	end
	
	if (self.sustain) then
		self.tick = _tick + (dt * self.Roughness * self.roughMod)
	else
		self.tick = _tick + (dt * 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(v)
	self.roughMod = v
end


function CameraShakeInstance:GetScaleMagnitude()
	return self.magnMod
end


function CameraShakeInstance:SetScaleMagnitude(v)
	self.magnMod = v
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


return CameraShakeInstance