local c={}c.__index=c local K=Vector3.new local w=math.noise c.CameraShakeState={FadingIn=0;FadingOut=1;Sustained=2;Inactive=3}function c.new(w,Z,m,D)if m==nil then m=0 end if D==nil then D=0 end assert(type(w)=="\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(Z)=="\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(m)=="\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(D)=="\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 C=setmetatable({Magnitude=w,Roughness=Z,PositionInfluence=K();RotationInfluence=K();DeleteOnInactive=true,roughMod=1,magnMod=1;fadeOutDuration=D,fadeInDuration=m,sustain=m>0;currentFadeTime=m>0 and 0 or 1,tick=(Random.new()):NextNumber(-100,100),_camShakeInstance=true},c)return C end function c.UpdateShake(Z,c)local m=Z.tick local D=Z.currentFadeTime local C=K(w(m,0)*.5,w(0,m)*.5,w(m,m)*.5)if Z.fadeInDuration>0 and Z.sustain then if D<1 then D=D+c/Z.fadeInDuration elseif Z.fadeOutDuration>0 then Z.sustain=false end end if not Z.sustain then D=D-c/Z.fadeOutDuration end if Z.sustain then Z.tick=m+(c*Z.Roughness)*Z.roughMod else Z.tick=m+((c*Z.Roughness)*Z.roughMod)*D end Z.currentFadeTime=D return((C*Z.Magnitude)*Z.magnMod)*D end function c.StartFadeOut(K,c)if c==0 then K.currentFadeTime=0 end K.fadeOutDuration=c K.fadeInDuration=0 K.sustain=false end function c.StartFadeIn(K,c)if c==0 then K.currentFadeTime=1 end K.fadeInDuration=c or K.fadeInDuration K.fadeOutDuration=0 K.sustain=true end function c.GetScaleRoughness(c)return c.roughMod end function c.SetScaleRoughness(K,c)K.roughMod=c end function c.GetScaleMagnitude(c)return c.magnMod end function c.SetScaleMagnitude(K,c)K.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(K)if K:IsFadingIn()then return c.CameraShakeState.FadingIn elseif K:IsFadingOut()then return c.CameraShakeState.FadingOut elseif K: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