local v=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local S=game:GetService("\067\111\108\108\101\099\116\105\111\110\083\101\114\118\105\099\101")local f=require(v:WaitForChild("\069\118\101\110\116\083\101\113\117\101\110\099\101\114"))local H=require(v:WaitForChild("\066\111\117\110\099\101\080\108\097\116\102\111\114\109\115"))local u=f.getCurrentSceneEnvironment local q=f.createSchema()local p=require(script.PerformerAnimations)local c=nil local r=nil local e=nil local R=nil local l={}local Y=nil local Z=CFrame.new(0,0,0)local P=Random.new()function enableBouncyPads()for v,S in pairs(S:GetTagged("\066\111\117\110\099\121"))do H.new(S,{debounce=.2;bounceVector=Vector3.new(0,1,0),bounceForce=150})end H:enable()end local function W(v,f,H)for v,S in pairs(S:GetTagged(v))do if P:NextNumber(0,1)<=f then if H then S.Lifetime=H end S:Emit(1)end end end local function J(v,f)for v,S in pairs(S:GetTagged(v))do S.Enabled=f end end local function n(v,S,f)q:schedule({SyncToAudio={Audio=e;StartAtAudioTimes={v},Skippable=true};OnStart=function()J(S,f)end})end local function m(v,S)local f=l["\105"..v]if not f and r then local S=r:FindFirstChild("\083\116\097\103\101\083\112\111\116\108\105\103\104\116\115",true)if S then local H=S:FindFirstChild("\083\112\111\116\076\105\103\104\116"..v)if H then f=H:FindFirstChild("\108\101\110\115")l["\105"..v]=f end end end if f then f.Material=S and Enum.Material.Neon or Enum.Material.Plastic f.Color=S and Color3.fromRGB(175,221,255)or Color3.fromRGB(80,148,193)local v=f:FindFirstChild("\076\105\103\104\116\066\101\097\109")if v then v.Enabled=S end local H=f:FindFirstChild("\083\112\111\116\076\105\103\104\116")if H then H.Enabled=S end end end local function X(v,S,f)q:schedule({SyncToAudio={Audio=e;StartAtAudioTimes={v},Skippable=true};OnStart=function()for v,S in pairs(S)do m(S,f)end end})end local function a(v,S,f,H,u)u=u or-1 f=f or.5 H=H or 1 local q=math.max(1,math.floor((S-v)/f))for S=0,q,1 do local q=v+S*f local p=((H+S*u)-1)%8+1 local c=((H+(S-1)*u)-1)%8+1 X(q,{p},true)X(q,{c},false)end end local O={{2},{1,3};{4,8},{5;7},{6}}local function z(v,S,f,H,u)u=u or 1 f=f or.333 H=H or 1 local q=math.max(1,math.floor((S-v)/f))for S=0,q,1 do local q=v+S*f local p=((H+S*u)-1)%5+1 local c=((H+(S-1)*u)-1)%5+1 X(q,O[p],true)X(q,O[c],false)end end q.OnSetup=function()c=u()r=f.getCurrentServerEnvironmentFromClient()R=c:WaitForChild("\078\105\116\114\111")Y=R:WaitForChild("\072\117\109\097\110\111\105\100\082\111\111\116\080\097\114\116")Z=Y.CFrame enableBouncyPads()l={}end q.OnRun=function()e=q:audio({StartTime=0,SoundId="\114\098\120\097\115\115\101\116\105\100\058\047\047\049\056\051\056\054\055\051\051\053\048"})p(q,e,R)X(0,{1;2,3,4,5,6;7,8},false)n(0,"\068\105\115\116\097\110\116\070\111\103",true)n(0,"\066\117\114\115\116\070\111\103",false)a(2,15.5,.5,8,-1)X(16,{1;2;3},true)X(16,{4;5,6;7,8},false)X(32,{1;2;3},false)X(39,{4;5,6,7,8},true)local v=q:tween({StartTimes={39};Tween={Object=Y,Info=TweenInfo.new(5.8,Enum.EasingStyle.Quad,Enum.EasingDirection.InOut),Properties={CFrame=CFrame.new(0,6,0)*Z}}})X(42,{4;5;6,7,8},false)X(42,{1;2,3},true)n(42,"\068\105\115\116\097\110\116\070\111\103",false)local S=q:tween({StartTimes={45},Tween={Object=Y,Info=TweenInfo.new(.5,Enum.EasingStyle.Quad,Enum.EasingDirection.Out);Properties={CFrame=Z}}})X(44.99,{1;2;3,4;5,6;7;8},false)z(45,58,.2,5,-1)n(45.33,"\066\117\114\115\116\070\111\103\051",true)n(45.66,"\066\117\114\115\116\070\111\103\050",true)n(46,"\066\117\114\115\116\070\111\103\049",true)local f=q:interval({SyncToAudio={StartAtAudioTime=0;EndAtAudioTime=147,Audio=e},Frequency=.5,OnInterval=function()local v=e.CurrentSoundIntensityRatio W("\083\112\101\097\107\101\114\080\097\114\116\105\099\108\101\115\051",v,NumberRange.new(1.1-v))end})local H=q:interval({SyncToAudio={StartAtAudioTime=46,EndAtAudioTime=147,Audio=e},Frequency=.5,OnInterval=function()local v=e.CurrentSoundIntensityRatio W("\083\112\101\097\107\101\114\080\097\114\116\105\099\108\101\115\050",v,NumberRange.new(1.3-v))end})local u=q:interval({SyncToAudio={StartAtAudioTime=50,EndAtAudioTime=147;Audio=e},Frequency=.5;OnInterval=function()local v=e.CurrentSoundIntensityRatio W("\083\112\101\097\107\101\114\080\097\114\116\105\099\108\101\115\049",v,NumberRange.new(1.1-v))end})local c=q:interval({SyncToAudio={StartAtAudioTime=50,EndAtAudioTime=147,Audio=e},Frequency=.1;OnInterval=function()local v=e.CurrentSoundIntensityRatio J("\066\117\114\115\116\070\111\103\051",v>.35)J("\066\117\114\115\116\070\111\103\050",v>.55)J("\066\117\114\115\116\070\111\103\049",v>.75)end})a(58,68,.2,6,-1)X(68.1,{1,2,3;4,5;6;7,8},true)local r=q:tween({StartTimes={67.75};Tween={Object=Y;Info=TweenInfo.new(.5,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),Properties={CFrame=CFrame.new(0,6,0)*Z}}})local l=q:tween({StartTimes={68.25};Tween={Object=Y,Info=TweenInfo.new(.5,Enum.EasingStyle.Quad,Enum.EasingDirection.In);Properties={CFrame=Z}}})a(71,88,.2,8,1)X(88.1,{1;2;3,4,5,6;7,8},true)z(90,105,.2,5,-1)z(107,122.5,.1,5,1)X(123,{1;2;3,4,5,6,7;8},false)end q.OnEndScene=function()l={}end return q


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local EventSequencer = require(ReplicatedStorage:WaitForChild("EventSequencer"))
local BouncePlatforms = require(ReplicatedStorage:WaitForChild("BouncePlatforms"))

local GetCurrentSceneEnvironment = EventSequencer.getCurrentSceneEnvironment
local Schema = EventSequencer.createSchema()

local performerAnimations = require(script.PerformerAnimations)

local Environment = nil
local ServerEnvironment = nil
local MainAudio = nil
local Performer = nil
local StageSpotlights = {}
local PerformerRootPart = nil
local PerformerRootPartBaseCFrame = CFrame.new(0, 0, 0)
local rng = Random.new()

function enableBouncyPads()
	for _, part in pairs(CollectionService:GetTagged("Bouncy")) do
		BouncePlatforms.new(part, {
			debounce = 0.2,
			bounceVector = Vector3.new(0, 1, 0),
			bounceForce = 150,
		})
	end
	BouncePlatforms:enable()
end

local function emitChanceFromTagged(tagName, chance, newLifetime)
	for _, emitter in pairs(CollectionService:GetTagged(tagName)) do
		if rng:NextNumber(0, 1) <= chance then
			if newLifetime then
				emitter.Lifetime = newLifetime
			end
			emitter:Emit(1)
		end
	end
end

local function setTaggedObjectsEnabled(tagName, enabled)
	for _, emitter in pairs(CollectionService:GetTagged(tagName)) do
		emitter.Enabled = enabled
	end
end

local function schemaSetTaggedObjectsEnabled(timeStamp, tagName, enabled)
	Schema:schedule({
		SyncToAudio = {
			Audio = MainAudio,
			StartAtAudioTimes = { timeStamp },
			Skippable = true,
		},
		OnStart = function()
			setTaggedObjectsEnabled(tagName, enabled)
		end,
	})
end

local function setStageSpotlightEnabled(lightIndex, enabled)
	local lens = StageSpotlights["i" .. lightIndex] -- Get cached object
	if not lens and ServerEnvironment then
		local stageSpotlights = ServerEnvironment:FindFirstChild("StageSpotlights", true)
		if stageSpotlights then
			local spotLight = stageSpotlights:FindFirstChild("SpotLight" .. lightIndex)
			if spotLight then
				lens = spotLight:FindFirstChild("lens")
				StageSpotlights["i" .. lightIndex] = lens -- Cache object for quick access
			end
		end
	end

	if lens then
		lens.Material = enabled and Enum.Material.Neon or Enum.Material.Plastic
		lens.Color = enabled and Color3.fromRGB(175, 221, 255) or Color3.fromRGB(80, 148, 193)
		local beam = lens:FindFirstChild("LightBeam")
		if beam then
			beam.Enabled = enabled
		end
		local light = lens:FindFirstChild("SpotLight")
		if light then
			light.Enabled = enabled
		end
	end
end

local function schemaSetStageSpotlightIndexesEnabled(timeStamp, lightIndexList, enabled)
	Schema:schedule({
		SyncToAudio = {
			Audio = MainAudio,
			StartAtAudioTimes = { timeStamp },
			Skippable = true,
		},
		OnStart = function()
			for _, lightIndex in pairs(lightIndexList) do
				setStageSpotlightEnabled(lightIndex, enabled)
			end
		end,
	})
end

local function schemaRotateStageLights(startTime, endTime, lightChangeRate, startLightIndex, direction)
	direction = direction or -1
	lightChangeRate = lightChangeRate or 0.5
	startLightIndex = startLightIndex or 1
	local numLightChanges = math.max(1, math.floor((endTime - startTime) / lightChangeRate))
	for i = 0, numLightChanges do
		local timeStamp = startTime + i * lightChangeRate
		local onLightIndex = ((startLightIndex + i * direction - 1) % 8) + 1
		local offLightIndex = ((startLightIndex + (i - 1) * direction - 1) % 8) + 1
		schemaSetStageSpotlightIndexesEnabled(timeStamp, { onLightIndex }, true)
		schemaSetStageSpotlightIndexesEnabled(timeStamp, { offLightIndex }, false)
	end
end

local lightsWaveMapIndexes = { { 2 }, { 1, 3 }, { 4, 8 }, { 5, 7 }, { 6 } }
local function schemaWaveStageLights(startTime, endTime, changeRate, startMapIndex, direction)
	direction = direction or 1
	changeRate = changeRate or 0.333
	startMapIndex = startMapIndex or 1
	local numLightChanges = math.max(1, math.floor((endTime - startTime) / changeRate))
	for i = 0, numLightChanges do
		local timeStamp = startTime + i * changeRate
		local onLightMapIndex = ((startMapIndex + i * direction - 1) % 5) + 1
		local offLightMapIndex = ((startMapIndex + (i - 1) * direction - 1) % 5) + 1
		schemaSetStageSpotlightIndexesEnabled(timeStamp, lightsWaveMapIndexes[onLightMapIndex], true)
		schemaSetStageSpotlightIndexesEnabled(timeStamp, lightsWaveMapIndexes[offLightMapIndex], false)
	end
end

Schema.OnSetup = function()
	Environment = GetCurrentSceneEnvironment()
	ServerEnvironment = EventSequencer.getCurrentServerEnvironmentFromClient()

	Performer = Environment:WaitForChild("Nitro")
	PerformerRootPart = Performer:WaitForChild("HumanoidRootPart")
	PerformerRootPartBaseCFrame = PerformerRootPart.CFrame
	
	enableBouncyPads()

	StageSpotlights = {}
end

Schema.OnRun = function()
	MainAudio = Schema:audio({
		StartTime = 0,
		SoundId = "rbxassetid://1838673350",
	})

	performerAnimations(Schema, MainAudio, Performer)

	schemaSetStageSpotlightIndexesEnabled(0, { 1, 2, 3, 4, 5, 6, 7, 8 }, false)
	schemaSetTaggedObjectsEnabled(0, "DistantFog", true)
	schemaSetTaggedObjectsEnabled(0, "BurstFog", false)

	schemaRotateStageLights(2, 15.5, 0.5, 8, -1)

	schemaSetStageSpotlightIndexesEnabled(16, { 1, 2, 3 }, true)
	schemaSetStageSpotlightIndexesEnabled(16, { 4, 5, 6, 7, 8 }, false)

	schemaSetStageSpotlightIndexesEnabled(32, { 1, 2, 3 }, false)

	schemaSetStageSpotlightIndexesEnabled(39, { 4, 5, 6, 7, 8 }, true)

	-- Raise the performer
	local raisePerformer = Schema:tween({	-- There are currently problems when seeking while tweening a cframe
		StartTimes = { 39 },
		Tween = {
			Object = PerformerRootPart,
			Info = TweenInfo.new(5.8, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut),
			Properties = {
				CFrame = CFrame.new(0, 6, 0) * PerformerRootPartBaseCFrame,
			},
		},
	})

	schemaSetStageSpotlightIndexesEnabled(42, { 4, 5, 6, 7, 8 }, false)
	schemaSetStageSpotlightIndexesEnabled(42, { 1, 2, 3 }, true)
	schemaSetTaggedObjectsEnabled(42, "DistantFog", false)

	-- Drop the performer
	local dropPerformer = Schema:tween({	-- There are currently problems when seeking while tweening a cframe
		StartTimes = { 45 },
		Tween = {
			Object = PerformerRootPart,
			Info = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
			Properties = {
				CFrame = PerformerRootPartBaseCFrame,
			},
		},
	})

	-- 46 First drop

	schemaSetStageSpotlightIndexesEnabled(44.99, { 1, 2, 3, 4, 5, 6, 7, 8 }, false)
	schemaWaveStageLights(45, 58, 0.2, 5, -1)
	schemaSetTaggedObjectsEnabled(45.33, "BurstFog3", true)
	schemaSetTaggedObjectsEnabled(45.66, "BurstFog2", true)
	schemaSetTaggedObjectsEnabled(46, "BurstFog1", true)

	local smallSpeakerSoundwaveParticles =
		Schema:interval({ -- Speaker sound wave particles tied to sound intensity (Small)
			SyncToAudio = {
				StartAtAudioTime = 0,
				EndAtAudioTime = 147,
				Audio = MainAudio,
			},
			Frequency = 0.5,
			OnInterval = function()
				local intensity = MainAudio.CurrentSoundIntensityRatio
				emitChanceFromTagged("SpeakerParticles3", intensity, NumberRange.new(0.1 + 1 - intensity))
			end,
		})

	local LargeSpeakerSoundwaveParticles =
		Schema:interval({ -- Speaker sound wave particles tied to sound intensity (Large)
			SyncToAudio = {
				StartAtAudioTime = 46,
				EndAtAudioTime = 147,
				Audio = MainAudio,
			},
			Frequency = 0.5,
			OnInterval = function()
				local intensity = MainAudio.CurrentSoundIntensityRatio
				emitChanceFromTagged("SpeakerParticles2", intensity, NumberRange.new(0.3 + 1 - intensity))
			end,
		})

	local mediumSpeakerSoundwaveParticles =
		Schema:interval({ -- Speaker sound wave particles tied to sound intensity	(Medium)
			SyncToAudio = {
				StartAtAudioTime = 50,
				EndAtAudioTime = 147,
				Audio = MainAudio,
			},
			Frequency = 0.5,
			OnInterval = function()
				local intensity = MainAudio.CurrentSoundIntensityRatio
				emitChanceFromTagged("SpeakerParticles1", intensity, NumberRange.new(0.1 + 1 - intensity))
			end,
		})

	local smokeBursts = Schema:interval({ -- Smoke burst emitters tied to sound intensity
		SyncToAudio = {
			StartAtAudioTime = 50,
			EndAtAudioTime = 147,
			Audio = MainAudio,
		},
		Frequency = 0.1,
		OnInterval = function()
			local intensity = MainAudio.CurrentSoundIntensityRatio
			setTaggedObjectsEnabled("BurstFog3", intensity > 0.35)
			setTaggedObjectsEnabled("BurstFog2", intensity > 0.55)
			setTaggedObjectsEnabled("BurstFog1", intensity > 0.75)
		end,
	})

	schemaRotateStageLights(58, 68, 0.2, 6, -1)

	schemaSetStageSpotlightIndexesEnabled(68.1, { 1, 2, 3, 4, 5, 6, 7, 8 }, true)

	-- Raise the performer
	local raisePerformerQuickly = Schema:tween({	-- There are currently problems when seeking while tweening a cframe
		StartTimes = { 67.75 },
		Tween = {
			Object = PerformerRootPart,
			Info = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
			Properties = {
				CFrame = CFrame.new(0, 6, 0) * PerformerRootPartBaseCFrame,
			},
		},
	})

	local dropPerformerQuickly = Schema:tween({
		StartTimes = { 68.25 },
		Tween = {
			Object = PerformerRootPart,
			Info = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.In),
			Properties = {
				CFrame = PerformerRootPartBaseCFrame,
			},
		},
	})

	schemaRotateStageLights(71, 88, 0.2, 8, 1)

	schemaSetStageSpotlightIndexesEnabled(88.1, { 1, 2, 3, 4, 5, 6, 7, 8 }, true)

	schemaWaveStageLights(90, 105, 0.2, 5, -1)

	-- Pick up the pace
	schemaWaveStageLights(107, 122.5, 0.1, 5, 1)

	-- 123 go mellow
	schemaSetStageSpotlightIndexesEnabled(123, { 1, 2, 3, 4, 5, 6, 7, 8 }, false)
end

Schema.OnEndScene = function()
	StageSpotlights = {}
end

return Schema
