local f={}f.__index=f local G=game:GetService("\084\119\101\101\110\083\101\114\118\105\099\101")local m=game:GetService("\082\117\110\083\101\114\118\105\099\101")local q={}local r=false if not r then for f,G in pairs(workspace.Cutscenes:GetDescendants())do if G:IsA("\066\097\115\101\080\097\114\116")then G.Transparency=1 end end end local c={NIL_DATA="\067\117\116\115\099\101\110\101 \100\097\116\097 \099\097\110\'\116 \098\101 \110\105\108",INVALID_DATA="\067\117\116\115\099\101\110\101 \100\097\116\097 \099\097\110\'\116 \098\101 \105\110\118\097\108\105\100";NO_CAMERA="\067\117\116\115\099\101\110\101 \099\097\109\101\114\097 \110\111\116 \115\101\116"}local function R(f,G)return pcall(function()local m=f[G]end)end local function S(f,G)if f and R(f,G)then if typeof(f[G])=="\073\110\115\116\097\110\099\101"then return f[G].Value else return f[G]end end end function f.new(G,m,r,c,R)local S={}S.Camera=G S.Data=R or{}S.Looped=m or false S.Speed=r or 1 S.Instruction=0 S.Playing=false S.Paused=false S.CurrentTween=nil S.CurrentFOVTween=nil S.ID=#q+1 S.Loaded=false S.FreezeControls=c or false S.ENextKeyframe=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")S.ELoaded=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")S.EPlay=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")S.EPause=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")S.EStop=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")S.EResume=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")S.DidLoop=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")S.Counter=0 S.Elapsed=0 S.NextInstruction=0 f[S.ID]=S return setmetatable(S,f)end function f.parse(f,G)local q={}q[1]={}q[2]={}local r=f:FindFirstChild("\067\097\109\101\114\097\115")local R=f:FindFirstChild("\080\114\111\103\114\097\109")if r and R then for f=1,#r:GetChildren(),1 do if G then m.RenderStepped:wait()end local c=r:FindFirstChild(tostring(f))if c then q[1][f]={}q[1][f][1]=S(c,"\067\070\114\097\109\101")or CFrame.new()q[1][f][2]=S(c,"\070\079\086")or 70 q[1][f][3]=Enum.EasingStyle[S(c,"\084\114\097\110\115\105\116\105\111\110\084\121\112\101")or 1]q[1][f][4]=S(c,"\084\114\097\110\115\105\116\105\111\110\068\117\114\097\116\105\111\110")or 1 q[1][f][5]=S(c,"\084\114\097\110\115\105\116\105\111\110\068\105\114\101\099\116\105\111\110")or 1 q[1][f][6]=S(c,"\084\114\097\110\115\105\116\105\111\110\068\101\108\097\121")or 0 end end else warn(c.INVALID_DATA)end return q end function f.Load(R,G,m,q,r)if G then if type(G)=="\116\097\098\108\101"then R.Data=G elseif G:IsA("\070\111\108\100\101\114")then if q then spawn(function()R.Data=f.parse(G,r)if m then G:Destroy()end R.Loaded=true R.ELoaded:Fire()end)else R.Data=f.parse(G,r)if m then G:Destroy()end R.Loaded=true R.ELoaded:Fire()end else warn(c.INVALID_DATA)end else warn(c.NIL_DATA)end end function f.Play(q,f,G,m)q.Speed=f or q.Speed if type(G)=="\098\111\111\108\101\097\110"then q.Looped=G end q.Camera=q.Camera or m if q.Camera and q.Playing==false then if q.FreezeControls then local f=(require((game:GetService("\080\108\097\121\101\114\115")).LocalPlayer.PlayerScripts.PlayerModule)):GetControls()f:Disable()end q.Camera.CameraType=Enum.CameraType.Scriptable q.Playing=true q.EPlay:Fire()else warn(c.NO_CAMERA)end end function f.Resume(f)if f.Playing and f.Paused then f.Camera.CameraType=Enum.CameraType.Scriptable f.CurrentTween:Play()f.CurrentFOVTween:Play()f.Paused=false f.EResume:Fire()end end function f.Pause(f)if f.Playing==true and f.Paused==false then f.CurrentTween:Pause()f.CurrentFOVTween:Pause()f.Paused=true f.EPause:Fire()end end function f.Stop(f)if f.Playing==true then f.Playing=false f.Paused=false f.Instruction=0 if f.CurrentTween then f.CurrentTween:Cancel()end f.CurrentTween=nil if f.CurrentFOVTween then f.CurrentFOVTween:Cancel()end f.CurrentFOVTween=nil f.NextInstruction=0 f.Elapsed=0 f.Camera.CameraType=Enum.CameraType.Custom local G=(require((game:GetService("\080\108\097\121\101\114\115")).LocalPlayer.PlayerScripts.PlayerModule)):GetControls()G:Enable()local m=(game:GetService("\080\108\097\121\101\114\115")).LocalPlayer local q=m.Character if q then local G=q:FindFirstChild("\072\117\109\097\110\111\105\100")if G then f.Camera.CameraSubject=G end end f.EStop:Fire()end end function f.GetDuration(G,f)f=f or 1 local m=0 for f,G in pairs(G.Data[1])do m=(m+G[4])+G[6]end return m/f end function f.Update(m,f)if m.Playing==true and(m.Paused==false and m.Camera)then m.Camera.CameraType=Enum.CameraType.Scriptable if m.Counter>=m.NextInstruction then m.Instruction=m.Instruction+1 local f=m.Data[1][m.Instruction]if f then if f[4]==0 then m.Camera.FieldOfView=f[2]m.Camera.CFrame=f[1]end local q=TweenInfo.new(f[4]/m.Speed,f[3],f[5],0,false,f[6]/m.Speed)local r=TweenInfo.new(f[4]/m.Speed,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut,0,false,f[6]/m.Speed)local c={CFrame=f[1]}m.CurrentTween=G:Create(m.Camera,q,c)m.CurrentFOVTween=G:Create(m.Camera,r,{FieldOfView=f[2]})m.CurrentTween:Play()m.CurrentFOVTween:Play()m.Counter=0 m.NextInstruction=(f[4]+f[6])/m.Speed m.ENextKeyframe:Fire(m.Instruction,m.NextInstruction,f)else if m.Looped then m.Instruction=0 m.Counter=0 m.Elapsed=0 m.NextInstruction=0 m.DidLoop:Fire()else m:Stop()end end end m.Counter=m.Counter+f m.Elapsed=m.Elapsed+f end end function f.Toggle(f)if f.Playing then if f.Paused then f:Resume()else f:Pause()end end end function f.Destroy(f)if f.Playing then f:Stop()end f.CurrentTween:Destroy()f.CurrentFOVTween:Destroy()f.EPlay:Destroy()f.EPause:Destroy()f.EStop:Destroy()f.EResume:Destroy()f.ELoaded:Destroy()q[f.ID]=nil f=nil end return f
-- Generated By Codes Otaku Plugin

local Cutscene = {}
Cutscene.__index = Cutscene
local TS = game:GetService("TweenService")
local RuS = game:GetService("RunService")
local Cutscenes = {}

local DEBUG_MODE = false

if not DEBUG_MODE then
	for i, v in pairs(workspace.Cutscenes:GetDescendants()) do
		if v:IsA("BasePart") then
			v.Transparency = 1
		end
	end
end

local ERROR = {
	NIL_DATA = "Cutscene data can't be nil",
	INVALID_DATA = "Cutscene data can't be invalid",
	NO_CAMERA = "Cutscene camera not set",
}

local function hasProperty(object, prop)
	return pcall(function()
		local t = object[prop]
	end)
end

local function GetValue(Parent, Name)
	if Parent and hasProperty(Parent, Name) then
		if typeof(Parent[Name]) == "Instance" then
			return Parent[Name].Value
		else
			return Parent[Name]
		end
	end
end

function Cutscene.new(Camera, Looped, Speed, FreezeControls, Data)
	local Self = {}

	Self.Camera = Camera
	Self.Data = Data or {}
	Self.Looped = Looped or false
	Self.Speed = Speed or 1
	Self.Instruction = 0
	Self.Playing = false
	Self.Paused = false
	Self.CurrentTween = nil
	Self.CurrentFOVTween = nil
	Self.ID = #Cutscenes + 1
	Self.Loaded = false
	Self.FreezeControls = FreezeControls or false

	Self.ENextKeyframe = Instance.new("BindableEvent")
	Self.ELoaded = Instance.new("BindableEvent")
	Self.EPlay = Instance.new("BindableEvent")
	Self.EPause = Instance.new("BindableEvent")
	Self.EStop = Instance.new("BindableEvent")
	Self.EResume = Instance.new("BindableEvent")
	Self.DidLoop = Instance.new("BindableEvent")

	Self.Counter = 0
	Self.Elapsed = 0

	Self.NextInstruction = 0

	Cutscene[Self.ID] = Self

	return setmetatable(Self, Cutscene)
end

function Cutscene.parse(DataFolder, SafeMode)
	local Data = {}
	Data[1] = {} -- Cameras
	Data[2] = {} -- Program
	local Cameras = DataFolder:FindFirstChild("Cameras")
	local Program = DataFolder:FindFirstChild("Program")
	if Cameras and Program then
		for i = 1, #Cameras:GetChildren(), 1 do
			if SafeMode then
				RuS.RenderStepped:wait()
			end
			local Camera = Cameras:FindFirstChild(tostring(i))
			if Camera then
				Data[1][i] = {}
				Data[1][i][1] = GetValue(Camera, "CFrame") or CFrame.new()
				Data[1][i][2] = GetValue(Camera, "FOV") or 70
				Data[1][i][3] = Enum.EasingStyle[GetValue(Camera, "TransitionType") or 1]
				Data[1][i][4] = GetValue(Camera, "TransitionDuration") or 1
				Data[1][i][5] = GetValue(Camera, "TransitionDirection") or 1
				Data[1][i][6] = GetValue(Camera, "TransitionDelay") or 0
			end
		end
	else
		warn(ERROR.INVALID_DATA)
	end
	return Data
end

function Cutscene:Load(Data, Destroy, NoYield, SafeMode)
	if Data then
		if type(Data) == "table" then
			self.Data = Data
		elseif Data:IsA("Folder") then
			if NoYield then
				spawn(function()
					self.Data = Cutscene.parse(Data, SafeMode)
					if Destroy then
						Data:Destroy()
					end
					self.Loaded = true
					self.ELoaded:Fire()
				end)
			else
				self.Data = Cutscene.parse(Data, SafeMode)
				if Destroy then
					Data:Destroy()
				end
				self.Loaded = true
				self.ELoaded:Fire()
			end
		else
			warn(ERROR.INVALID_DATA)
		end
	else
		warn(ERROR.NIL_DATA)
	end
end

function Cutscene:Play(Speed, Looped, Camera)
	self.Speed = Speed or self.Speed
	if type(Looped) == "boolean" then
		self.Looped = Looped
	end
	self.Camera = self.Camera or Camera
	if self.Camera and self.Playing == false then
		if self.FreezeControls then
			local controls = require(game:GetService("Players").LocalPlayer.PlayerScripts.PlayerModule):GetControls()
			controls:Disable()
		end
		self.Camera.CameraType = Enum.CameraType.Scriptable
		self.Playing = true
		self.EPlay:Fire()
	else
		warn(ERROR.NO_CAMERA)
	end
end

function Cutscene:Resume()
	if self.Playing and self.Paused then
		self.Camera.CameraType = Enum.CameraType.Scriptable
		self.CurrentTween:Play()
		self.CurrentFOVTween:Play()
		self.Paused = false
		self.EResume:Fire()
	end
end

function Cutscene:Pause()
	if self.Playing == true and self.Paused == false then
		self.CurrentTween:Pause()
		self.CurrentFOVTween:Pause()
		self.Paused = true
		self.EPause:Fire()
	end
end

function Cutscene:Stop()
	if self.Playing == true then
		self.Playing = false
		self.Paused = false
		self.Instruction = 0
		if self.CurrentTween then
			self.CurrentTween:Cancel()
		end
		self.CurrentTween = nil
		if self.CurrentFOVTween then
			self.CurrentFOVTween:Cancel()
		end
		self.CurrentFOVTween = nil
		self.NextInstruction = 0
		self.Elapsed = 0
		self.Camera.CameraType = Enum.CameraType.Custom
		local controls = require(game:GetService("Players").LocalPlayer.PlayerScripts.PlayerModule):GetControls()
		controls:Enable()
		local Player = game:GetService("Players").LocalPlayer
		local Character = Player.Character
		if Character then
			local Humanoid = Character:FindFirstChild("Humanoid")
			if Humanoid then
				self.Camera.CameraSubject = Humanoid
			end
		end
		self.EStop:Fire()
	end
end

function Cutscene:GetDuration(Speed)
	Speed = Speed or 1
	local count = 0
	for i, X in pairs(self.Data[1]) do
		count = count + X[4] + X[6]
	end
	return count / Speed
end

function Cutscene:Update(delta)
	if self.Playing == true and self.Paused == false and self.Camera then
		self.Camera.CameraType = Enum.CameraType.Scriptable
		if self.Counter >= self.NextInstruction then
			self.Instruction = self.Instruction + 1
			local X = self.Data[1][self.Instruction]
			if X then
				if X[4] == 0 then
					self.Camera.FieldOfView = X[2]
					self.Camera.CFrame = X[1]
				end
				local TI = TweenInfo.new(X[4] / self.Speed, X[3], X[5], 0, false, X[6] / self.Speed)
				local TI2 = TweenInfo.new(
					X[4] / self.Speed,
					Enum.EasingStyle.Sine,
					Enum.EasingDirection.InOut,
					0,
					false,
					X[6] / self.Speed
				)
				local Properties = {
					["CFrame"] = X[1],
				}
				self.CurrentTween = TS:Create(self.Camera, TI, Properties)
				self.CurrentFOVTween = TS:Create(self.Camera, TI2, { FieldOfView = X[2] })
				self.CurrentTween:Play()
				self.CurrentFOVTween:Play()
				self.Counter = 0
				self.NextInstruction = (X[4] + X[6]) / self.Speed
				self.ENextKeyframe:Fire(self.Instruction, self.NextInstruction, X)
			else
				if self.Looped then
					self.Instruction = 0
					self.Counter = 0
					self.Elapsed = 0
					self.NextInstruction = 0
					self.DidLoop:Fire()
				else
					self:Stop()
				end
			end
		end
		self.Counter = self.Counter + delta
		self.Elapsed = self.Elapsed + delta
	end
end

function Cutscene:Toggle()
	if self.Playing then
		if self.Paused then
			self:Resume()
		else
			self:Pause()
		end
	end
end

function Cutscene:Destroy()
	if self.Playing then
		self:Stop()
	end
	self.CurrentTween:Destroy()
	self.CurrentFOVTween:Destroy()
	self.EPlay:Destroy()
	self.EPause:Destroy()
	self.EStop:Destroy()
	self.EResume:Destroy()
	self.ELoaded:Destroy()
	Cutscenes[self.ID] = nil
	self = nil
end

return Cutscene
