local LD = require("design.LevelDesignLibrary")
local monitors = require("level.MonitorLibrary")
local thisLevel, thisObj, realmInfo, previousRealm, bridgeExterior, fx_Portal, fx_PortalEnd, lastDome, fx_BifrostInsertPulse, fx_MagicDust, fx_TreeCore, fx_GalaxySmall, fx_GalaxyLarge, fx_RootGlow, fx_TreeTop, fx_LeavesVortexLoop, fx_coalesceControl, fx_tableActive
local cineNumber_AlfheimComplete = 250
local cineNumber_HelheimReturnComplete = 498
local alfheimLightingUpdated = false
local helheimLightingUpdated = false
local firstActivated = false
local beam01_BifrostToCenterTable, beam02_CenterTableToCrystal, beam03_CrystalToPortal, beam04_MidgardTravelSkyBeam
local beam01_BifrostToCenterTable_Duration = 1.5
local beam02_to_beam03_delay = 0.2
local beam04_start_delay = 1.5
local skipFXIntro
function OnScriptLoaded(level, obj)
  thisLevel = level
  thisObj = obj
  bridgeExterior = level:FindSingleGameObject("bridgeSeq_exterior")
  fx_Portal = level:FindSingleGameObject("rtBridge_opening_part")
  fx_PortalEnd = GameObjects.endpulseFX
  beam01_BifrostToCenterTable = level:FindSingleGameObject("beamFX01")
  beam02_CenterTableToCrystal = level:FindSingleGameObject("beamFX02")
  beam04_MidgardTravelSkyBeam = level:FindSingleGameObject("beamFX_Midgard")
  beam03_CrystalToPortal = level:FindSingleGameObject("beamFX03")
  fx_MagicDust = level:FindSingleGameObject("MagicDustFX")
  fx_TreeCore = level:FindSingleGameObject("TreeFX_V2")
  fx_GalaxySmall = level:FindSingleGameObject("GalaxyAFX")
  fx_GalaxyLarge = level:FindSingleGameObject("GalaxyBFX")
  fx_RootGlow = GameObjects.wt_stump_fx
  fx_TreeTop = level:FindSingleGameObject("TreeTopFX")
  fx_LeavesVortexLoop = GameObjects.vortex_leaves_swirling_loop
  fx_coalesceControl = GameObjects.StumpFX
  fx_tableActive = GameObjects.rt_activetable
  fx_BifrostInsertPulse = GameObjects.rt_starttable
  realmInfo = LD.GetRealmInfo()
  SoundInit()
  skipFXIntro = engine.VFSBool.New("DEBUG: Skip RT Intro & Unlock All")
end
function OnStart(level, obj)
  local completedCineNum = game.Level.GetVariable("CompletedCineNumber")
  if not alfheimLightingUpdated and completedCineNum >= cineNumber_AlfheimComplete then
    alfheimLightingUpdated = true
    SetRoomState_AlfheimComplete()
  end
  if not helheimLightingUpdated and completedCineNum >= cineNumber_HelheimReturnComplete and completedCineNum < 499 then
    helheimLightingUpdated = true
    SetRoomState_HelheimReturnComplete()
  end
end
function OnFirstStart(level, obj)
  SetRoomState_Intro()
  PauseTorchIntro()
  InitBranchAnim_Intro()
end
function OnUpdate(level, obj)
  if skipFXIntro and skipFXIntro.value then
    skipFXIntro.value = false
    GameObjects.realm_controller_object.LuaObjectScript.UnlockRealm("Midgard")
    GameObjects.realm_controller_object.LuaObjectScript.UnlockRealm("Alfheim")
    GameObjects.realm_controller_object.LuaObjectScript.UnlockRealm("Muspelheim")
    GameObjects.realm_controller_object.LuaObjectScript.UnlockRealm("Niflheim")
    GameObjects.realm_controller_object.LuaObjectScript.UnlockRealm("Helheim")
    GameObjects.realm_controller_object.LuaObjectScript.UnlockRealm("Jotunheim")
    StartTreeAnim_Dissolve()
    LuaHook_Intro_Braziers_On()
    if game.Level.GetVariable("CompletedCineNumber") < 220 then
      game.Level.SetVariable("CompletedCineNumber", 220)
    end
  end
end
function Debug_DisplayCCVolumeAnimInfo()
  local objs = {}
  table.insert(objs, GameObjects.fxV_cal130_midgardTravel)
  table.insert(objs, GameObjects.fxV_cal130_jotunheim)
  table.insert(objs, GameObjects.fxV_cal130_muspelheim)
  table.insert(objs, GameObjects.fxV_cal130_niflheim)
  table.insert(objs, GameObjects.fxV_cal130_alfheimdark)
  table.insert(objs, GameObjects.fxV_cal130_alfheimlight)
  table.insert(objs, GameObjects.fxV_cal130_helheim)
  LD.DisplayAnimDebug(objs, {Y = 15})
end
function Event_RealmUnlocked(realm)
  PlayCrystalLight_Active(realm)
end
function Event_RealmLocked(realm)
  PlayCrystalLight_Init(realm)
end
function Event_OnInteractStart()
  previousRealm = LD.GetCurrentRealm()
end
function Callscript_StartIntroFx(level, obj)
  LD.ShowFX(fx_GalaxySmall)
end
function LuaHook_Intro_OnBifrostInsert()
  GameObjects.realmTravelFXTransitions:StartAnim("MidgardIntro_FX_Midgard")
  GameObjects.realmTravelFXTransitions:PlayAnimToFrame(150)
  GameObjects.rotateMainLightGroup:PlayAnimCycle()
  ShowTableActiveFX()
  LD.CallFunctionAfterDelay(function()
    LD.AddControllerRumble({EffectName = "FFB_SMALL", Duration = 20})
  end, 2)
end
function LuaHook_Intro_TableZoomStart()
  PlayCrystalLight_Active("Midgard")
  LD.AddControllerRumble({EffectName = "FFB_GIANT", Duration = 0.5})
end
function LuaHook_Intro_TableZoomEnd()
  game.FX.StopEffect({EffectName = "FFB_SMALL"})
  LD.AddControllerRumble({EffectName = "FFB_GIANT", Duration = 0.5})
end
local crystalRaiseDotsEffectDelay = 1.5
function DoorIntro(realm)
  RealmCrystalRaise(realm)
  LD.CallFunctionAfterDelay(function()
    PlayCrystalLight_Travel(realm)
    if realm == "Midgard" then
      realm = "Vanaheim"
    end
    local door = thisLevel:FindSingleGameObject("RealmTravelDoor_" .. realm)
    if door then
      door.LuaObjectScript.StartGlow(nil, true)
    end
  end, crystalRaiseDotsEffectDelay)
end
function LuaHook_Intro_Door_Jotunheim_On()
  DoorIntro("Jotunheim")
end
function LuaHook_Intro_Door_Vanaheim_On()
  DoorIntro("Vanaheim")
end
function LuaHook_Intro_Door_Muspelheim_On()
  DoorIntro("Muspelheim")
end
function LuaHook_Intro_Door_Niflheim_On()
  DoorIntro("Niflheim")
end
function LuaHook_Intro_Door_Asgard_On()
  DoorIntro("Asgard")
end
function LuaHook_Intro_Door_Svartalfheim_On()
  DoorIntro("Svartalfheim")
end
function LuaHook_Intro_Door_Helheim_On()
  DoorIntro("Helheim")
end
function LuaHook_Intro_Pool_Stars_On()
  LD.ShowFX(fx_MagicDust)
end
function LuaHook_Intro_Doors_Off()
  GameObjects.realm_controller_object.LuaObjectScript.ResetDoorGlow("Jotunheim", false)
  GameObjects.realm_controller_object.LuaObjectScript.ResetDoorGlow("Vanaheim", false)
  GameObjects.realm_controller_object.LuaObjectScript.ResetDoorGlow("Muspelheim", false)
  GameObjects.realm_controller_object.LuaObjectScript.ResetDoorGlow("Niflheim", false)
  GameObjects.realm_controller_object.LuaObjectScript.ResetDoorGlow("Asgard", false)
  GameObjects.realm_controller_object.LuaObjectScript.ResetDoorGlow("Svartalfheim", false)
  GameObjects.realm_controller_object.LuaObjectScript.ResetDoorGlow("Helheim", false)
  PlayCrystalLight_Init("Jotunheim")
  PlayCrystalLight_Init("Vanaheim")
  PlayCrystalLight_Init("Muspelheim")
  PlayCrystalLight_Init("Niflheim")
  PlayCrystalLight_Init("Asgard")
  PlayCrystalLight_Init("Svartalfheim")
  PlayCrystalLight_Init("Helheim")
  RealmCrystalLower("Jotunheim")
  RealmCrystalLower("Vanaheim")
  RealmCrystalLower("Muspelheim")
  RealmCrystalLower("Niflheim")
  RealmCrystalLower("Asgard")
  RealmCrystalLower("Svartalfheim")
  RealmCrystalLower("Helheim")
end
function LuaHook_Intro_MainLights_On()
  GameObjects.treeMidSpotlight:PlayAnimToEnd()
  GameObjects.realmTravelLightingTransitions:StartAnim("MidgardIntro_Spot_Midgard")
  GameObjects.realmTravelLightingTransitions:PlayAnimToEnd()
end
function LuaHook_Intro_Tree_Root_Energy_Tendrils()
  LD.ShowFX(fx_RootGlow)
  LD.ShowFX(fx_TreeCore)
  ResetCoalesceFX()
end
function LuaHook_Intro_Tree_Branch_Energy_Tendrils()
  StartBranchEnergyAnim_Intro()
end
function LuaHook_Intro_Tree_Top_Galaxy()
  LD.ShowFX(fx_GalaxyLarge)
  GameObjects.treePointLights:PlayAnimToEnd()
  GameObjects.exposureLights:PlayAnimToEnd()
end
function LuaHook_Intro_Tree_Branch_Growth()
  LD.ShowFX(fx_TreeTop)
  StartFallingLeaves()
  StartBranchAnim_Intro()
end
function LuaHook_Intro_Braziers_On()
  PlayTorchIntro()
  GameObjects.realmTravelFXTransitions:PlayAnimToEnd()
end
function LuaHook_Intro_Tree_Root_Flowers()
  StartFlowerGrowth("Midgard")
end
function Event_OnBifrostInserted()
  ShowTableActiveFX()
end
function Event_OnRealmSelectionChanged()
end
function Event_OnRealmSelectionConfirmed(realm)
  PlayTorchOutro()
  StartBranchAnim_Travel()
  PlayCrystalLight_Travel("Midgard")
  PlayConfirmBeam()
  StartFlowerDecay(previousRealm)
  Lighting_FX_Transition_In(0.5)
  StartDomeTransitionFX()
  ColorCorrection_Transition_In()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if cineNum < 470 or 490 < cineNum then
    if cineNum < 570 or 580 < cineNum then
      ActivateTravelPortal()
    end
    StopFallingLeaves()
    StartVortexLeaves()
  end
end
function Event_OnPlatformRotationStart()
end
function ActivateTravelPortal()
  if LD.GetCurrentRealm() ~= "Midgard" then
    bridgeExterior:Show()
    LD.ShowFX(fx_Portal:FindSingleGOByName("Fx"))
    LD.ShowFX(fx_Portal:FindSingleGOByName("Cards"))
  end
  local lightBridge = fx_Portal:FindSingleGOByName("bridgeExtend")
  lightBridge:Hide()
end
function PlayConfirmBeam()
  LD.ShowFX(beam01_BifrostToCenterTable)
  LD.CallFunctionAfterDelay(function()
    LD.HideFX(beam01_BifrostToCenterTable)
    StartCoalesceFX()
  end, beam01_BifrostToCenterTable_Duration)
end
function Event_OnDeviceAlignedToRealm()
  if LD.GetSelectedRealm() == "Midgard" then
    StartMidgardSequence()
  else
    PlayCrystalLight_TravelComplete("Midgard")
  end
end
function Event_RootCrystalLiftAnimDone()
  StopVortexLeaves()
  LD.CallFunctionAfterDelay(StartNonMidgardSequence, 0.35)
end
function StartBeamImpactVibration()
  LD.AddScreenShake({EffectName = "FFB_SLAM", Duration = 1.5})
  LD.CallFunctionAfterDelay(function()
    game.Blender.Trigger({
      Name = "FFB_GENERIC_RUMBLE_LOW",
      Duration = 500,
      TweenIn = {Time = 0},
      TweenOut = {Time = 0.25}
    })
  end, 0.25)
  LD.AddScreenShake({
    EffectName = "FSE_SWAY_REALMTRAVEL_CONFIRM_SHAKE",
    Duration = 500
  })
end
function StopBeamImpactVibration()
  game.FX.StopEffect({
    EffectName = "FFB_GENERIC_RUMBLE_LOW"
  })
  game.FX.StopEffect({
    EffectName = "FSE_SWAY_REALMTRAVEL_CONFIRM_SHAKE"
  })
end
function StartNonMidgardSequence()
  StartSharedSequenceLogic()
  LD.ShowFX(beam02_CenterTableToCrystal)
  PlaySoundActiveLoopOnTargetBeam("Main")
  LD.CallFunctionAfterDelay(function()
    LD.ShowFX(beam03_CrystalToPortal)
    local lightBridge = fx_Portal:FindSingleGOByName("bridgeExtend")
    lightBridge:Show()
  end, beam02_to_beam03_delay)
end
function StartMidgardSequence()
  LD.CallFunctionAfterDelay(function()
    StartSharedSequenceLogic()
    LD.ShowFX(beam04_MidgardTravelSkyBeam)
    PlaySoundActiveLoopOnTargetBeam("Sky")
  end, beam04_start_delay)
end
function StartSharedSequenceLogic()
  StartBeamImpactVibration()
  GameObjects.realm_controller_object.LuaObjectScript.Event_OnFXLoadSequenceStart()
  GameObjects.fxV_cal130_travelWind:PlayAnimToEnd()
  GameObjects.realm_controller_object.LuaObjectScript.PlaySoundTravelActivationLoop()
end
function RealmCrystalRaise(realm)
  local gem = thisLevel:FindSingleGameObject("cr_" .. string.lower(realm))
  if gem then
    gem:JumpAnimToFrame(200)
    gem:PlayAnimToFrame(360)
  end
end
function RealmCrystalLower(realm)
  local gem = thisLevel:FindSingleGameObject("cr_" .. string.lower(realm))
  if gem then
    gem:JumpAnimToFrame(600)
    gem:PlayAnimToFrame(720)
  end
end
function InitBranchAnim_Intro()
  thisLevel:PlayGlobalMaterialAnimation("wt_branches", "wt_branch_intro")
  thisLevel:PlayGlobalMaterialAnimation("wt_leaves_loose", "wt_branch_intro")
  thisLevel:PlayGlobalMaterialAnimation("wt_branches_energy", "wt_branch_energy_intro")
  thisLevel:PlayGlobalMaterialAnimation("wt_A", "wt_a_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_B", "wt_b_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_C", "wt_c_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_D", "wt_d_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_E", "wt_e_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_splinter_card_dissolve", "wt_splinter_card_dissolve", {Rate = 20})
  thisLevel:PlayGlobalMaterialAnimation("wt_splinters_A_dissolve", "wt_splinters_a_dissolve", {Rate = 20})
  thisLevel:PlayGlobalMaterialAnimation("wt_splinters_b_dissolve", "wt_splinters_b_dissolve", {Rate = 20})
  thisLevel:PlayGlobalMaterialAnimation("t_wt_root_a_dissolve", "wt_root_a_dissolve", {Rate = 20})
  thisLevel:PauseGlobalMaterialAnimation("wt_branches", "wt_branch_intro")
  thisLevel:PauseGlobalMaterialAnimation("wt_leaves_loose", "wt_branch_intro")
  thisLevel:PauseGlobalMaterialAnimation("wt_branches_energy", "wt_branch_energy_intro")
  thisLevel:PauseGlobalMaterialAnimation("wt_A", "wt_a_energy")
  thisLevel:PauseGlobalMaterialAnimation("wt_B", "wt_b_energy")
  thisLevel:PauseGlobalMaterialAnimation("wt_C", "wt_c_energy")
  thisLevel:PauseGlobalMaterialAnimation("wt_D", "wt_d_energy")
  thisLevel:PauseGlobalMaterialAnimation("wt_E", "wt_e_energy")
end
function StartBranchAnim_Intro()
  thisLevel:PlayGlobalMaterialAnimation("wt_branches", "wt_branch_intro", {Rate = 0.5})
  thisLevel:PlayGlobalMaterialAnimation("wt_leaves_loose", "wt_branch_intro", {Rate = 0.5})
end
function StartBranchEnergyAnim_Intro()
  thisLevel:PlayGlobalMaterialAnimation("wt_branches_energy", "wt_branch_energy_intro")
  LD.CallFunctionAfterDelay(function()
    StartBranchEnergyAnim_Idle()
  end, 7)
  thisLevel:PlayGlobalMaterialAnimation("wt_A", "wt_a_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_B", "wt_b_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_C", "wt_c_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_D", "wt_d_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_E", "wt_e_energy")
end
function StartBranchEnergyAnim_Idle()
  thisLevel:PlayGlobalMaterialAnimation("wt_branches_energy", "wt_branch_energy_idle", {Cycle = true})
end
function InitTreeAnim_Dissolve()
  thisLevel:PlayGlobalMaterialAnimation("wt_A", "wt_a_dissolve")
  thisLevel:PlayGlobalMaterialAnimation("wt_B", "wt_b_dissolve")
  thisLevel:PlayGlobalMaterialAnimation("wt_C", "wt_c_dissolve")
  thisLevel:PlayGlobalMaterialAnimation("wt_D", "wt_d_dissolve")
  thisLevel:PlayGlobalMaterialAnimation("wt_E", "wt_e_dissolve")
  thisLevel:PauseGlobalMaterialAnimation("wt_A", "wt_a_dissolve")
  thisLevel:PauseGlobalMaterialAnimation("wt_B", "wt_b_dissolve")
  thisLevel:PauseGlobalMaterialAnimation("wt_C", "wt_c_dissolve")
  thisLevel:PauseGlobalMaterialAnimation("wt_D", "wt_d_dissolve")
  thisLevel:PauseGlobalMaterialAnimation("wt_E", "wt_e_dissolve")
  thisLevel:PlayGlobalMaterialAnimation("wt_branches_energy", "wt_branch_energy_intro")
  thisLevel:PauseGlobalMaterialAnimation("wt_branches_energy", "wt_branch_energy_intro")
  thisLevel:PlayGlobalMaterialAnimation("wt_branches", "wt_branch_dissolve", {Rate = 20})
  thisLevel:PlayGlobalMaterialAnimation("wt_leaves_loose", "wt_branch_dissolve", {Rate = 20})
  thisLevel:PlayGlobalMaterialAnimation("wt_splinter_card_dissolve", "wt_splinter_card_dissolve", {Rate = -20})
  thisLevel:PlayGlobalMaterialAnimation("wt_splinters_A_dissolve", "wt_splinters_a_dissolve", {Rate = -20})
  thisLevel:PlayGlobalMaterialAnimation("wt_splinters_b_dissolve", "wt_splinters_b_dissolve", {Rate = -20})
  thisLevel:PlayGlobalMaterialAnimation("t_wt_root_a_dissolve", "wt_root_a_dissolve", {Rate = -20})
end
function StartTreeAnim_Dissolve(newspeed)
  local speed = newspeed or 1
  GameObjects.treeMidSpotlight:Show()
  thisLevel:PlayGlobalMaterialAnimation("wt_splinter_card_dissolve", "wt_splinter_card_dissolve", {Rate = speed})
  thisLevel:PlayGlobalMaterialAnimation("wt_splinters_A_dissolve", "wt_splinters_a_dissolve", {Rate = speed})
  thisLevel:PlayGlobalMaterialAnimation("wt_splinters_b_dissolve", "wt_splinters_b_dissolve", {Rate = speed})
  thisLevel:PlayGlobalMaterialAnimation("t_wt_root_a_dissolve", "wt_root_a_dissolve", {Rate = speed})
  thisLevel:PlayGlobalMaterialAnimation("wt_A", "wt_a_dissolve", {Rate = speed})
  thisLevel:PlayGlobalMaterialAnimation("wt_B", "wt_b_dissolve", {Rate = speed})
  thisLevel:PlayGlobalMaterialAnimation("wt_C", "wt_c_dissolve", {Rate = speed})
  thisLevel:PlayGlobalMaterialAnimation("wt_D", "wt_d_dissolve", {Rate = speed})
  thisLevel:PlayGlobalMaterialAnimation("wt_E", "wt_e_dissolve", {Rate = speed})
  GameObjects.realmTravelFXTransitions:PlayAnimationToEnd({Rate = speed})
  LuaHook_Intro_Tree_Root_Flowers()
  GameObjects.realmTravelFXTransitions:StartAnim("MidgardIntro_FX_Midgard")
  GameObjects.realmTravelFXTransitions:PlayAnimToEnd(2 * speed)
  FinishTalismanTreeRestoreSequence()
end
function FinishTalismanTreeRestoreSequence()
  LD.CallFunctionAfterDelay(function()
    LuaHook_Intro_Tree_Top_Galaxy()
    LuaHook_Intro_Tree_Root_Energy_Tendrils()
    LuaHook_Intro_MainLights_On()
    GameObjects.rotateMainLightGroup:PlayAnimCycle()
    StartBranchAnim_Intro()
    StartBranchEnergyAnim_Idle()
    StartFallingLeaves()
  end, 24)
  thisLevel:OnGlobalMaterialAnimationDone("wt_A", "RestoreTreeEnergy", {
    Animation = "wt_a_dissolve",
    Repeat = false,
    Force = true
  })
end
function RestoreTreeEnergy()
  thisLevel:PlayGlobalMaterialAnimation("wt_A", "wt_a_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_B", "wt_b_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_C", "wt_c_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_D", "wt_d_energy")
  thisLevel:PlayGlobalMaterialAnimation("wt_E", "wt_e_energy")
end
function StartBranchAnim_Travel()
  thisLevel:PlayGlobalMaterialAnimation("wt_branches", "wt_branch_dissolve")
  thisLevel:PlayGlobalMaterialAnimation("wt_leaves_loose", "wt_branch_dissolve")
end
function StartBranchAnim_TravelComplete(realm)
  if realm == "Niflheim" then
    realm = "Nidavellir"
  end
  local animName
  if realm == "Midgard" then
    animName = "wt_branch_intro"
  else
    animName = "wt_branch_" .. string.lower(realm)
    if realm == "Alfheim" then
      local completedCineNum = game.Level.GetVariable("CompletedCineNumber")
      if completedCineNum < cineNumber_AlfheimComplete then
        animName = animName .. "Dark"
      end
    end
  end
  thisLevel:PlayGlobalMaterialAnimation("wt_branches", animName)
  thisLevel:PlayGlobalMaterialAnimation("wt_leaves_loose", animName)
end
function StartFlowerGrowth(realm)
  if realm == "Niflheim" then
    realm = "nifleheim"
  end
  local materialAnimName = "rtflower_a_anim_" .. string.lower(realm)
  if realm == "Alfheim" then
    local completedCineNum = game.Level.GetVariable("CompletedCineNumber")
    if completedCineNum < cineNumber_AlfheimComplete then
      materialAnimName = materialAnimName .. "Dark"
    end
  end
  thisLevel:PlayGlobalMaterialAnimation("rtFlower_A_anim", materialAnimName)
  local flowerGroupsGrowthOffset = 0.5
  local meshAnim = "rtFlower_grp_"
  if realm == "Helheim" then
    meshAnim = meshAnim .. "helheim"
  else
    meshAnim = meshAnim .. "midgard"
  end
  meshAnim = meshAnim .. "_grow"
  for i = 1, 6 do
    local delay = i * flowerGroupsGrowthOffset
    LD.CallFunctionAfterDelay(function()
      local group = thisLevel:FindSingleGameObject("flowers_0" .. tostring(i))
      for j = 1, #group.Children do
        group.Children[j].Child:StartAnim(meshAnim)
        group.Children[j].Child:JumpAnimToFrame(0)
        group.Children[j].Child:PlayAnimToEnd()
      end
      group:Show()
    end, delay)
  end
end
function StartFlowerDecay(realm)
  local flowerGroupsDecayOffset = 0.2
  local meshAnim = "rtFlower_grp_"
  if realm == "Helheim" then
    meshAnim = meshAnim .. "helheim"
  else
    meshAnim = meshAnim .. "midgard"
  end
  meshAnim = meshAnim .. "_contract"
  for i = 1, 6 do
    local delay = i * flowerGroupsDecayOffset
    LD.CallFunctionAfterDelay(function()
      local group = thisLevel:FindSingleGameObject("flowers_0" .. tostring(i))
      for j = 1, #group.Children do
        group.Children[j].Child:StartAnim(meshAnim)
        group.Children[j].Child:JumpAnimToFrame(0)
        group.Children[j].Child:PlayAnimToEnd()
      end
      LD.CallFunctionAfterDelay(function()
        group:Hide()
      end, delay + 5)
    end, delay)
  end
end
function HideFlowers()
  for i = 1, 6 do
    local group = thisLevel:FindSingleGameObject("flowers_0" .. tostring(i))
    group:Hide()
  end
end
function StartFallingLeaves()
  StopFallingLeaves()
  local currentRealm = LD.GetCurrentRealm()
  local objectName = "wt_leaves_falling"
  if currentRealm ~= "Midgard" then
    if currentRealm == "Alfheim" then
      local completedCineNum = game.Level.GetVariable("CompletedCineNumber")
      if completedCineNum < cineNumber_AlfheimComplete then
        objectName = objectName .. "_alfdark"
      else
        objectName = objectName .. "_alflight"
      end
    else
      objectName = objectName .. "_" .. string.lower(currentRealm)
    end
  end
  local leavesObj = thisLevel:FindSingleGameObject(objectName)
  if leavesObj then
    LD.ShowFX(leavesObj, {cycle = true})
  end
end
function StopFallingLeaves()
  LD.HideFX(GameObjects.wt_leaves_falling)
  LD.HideFX(GameObjects.wt_leaves_falling_alfdark)
  LD.HideFX(GameObjects.wt_leaves_falling_alflight)
  LD.HideFX(GameObjects.wt_leaves_falling_jotunheim)
  LD.HideFX(GameObjects.wt_leaves_falling_muspelheim)
end
function StartVortexLeaves()
  ShowCustomFX(fx_LeavesVortexLoop, 0, 300)
  fx_LeavesVortexLoop.Child:OnAnimationDone(thisObj, "StartVortexLeaves", {Force = true})
end
function StopVortexLeaves()
  fx_LeavesVortexLoop.Child:ClearAllAnimCallbacks()
  fx_LeavesVortexLoop.Child:JumpAnimToFrame(301)
  for _, d in pairs(fx_LeavesVortexLoop.Descendants) do
    d:JumpAnimToFrame(301)
  end
end
function PlayTorchIdle(monitor)
  if monitor ~= nil then
    monitor:Stop()
    monitor:Terminate()
    monitor = nil
  end
  GameObjects.torchLights:StartAnim("MidgardTorchIdle_Spot")
  GameObjects.torchLights:PlayAnimCycle()
end
function PauseTorchIntro()
  LD.HideFX(GameObjects.brazier_torch_refn)
  GameObjects.torchLights:StartAnim("MidgardTorchIntro_Spot_MidgardTorch")
  GameObjects.torchLights:JumpAnimToFrame(0)
  GameObjects.torchLights:PauseAnim()
end
function PlayTorchIntro()
  GameObjects.torchLights:StartAnim("MidgardTorchIntro_Spot_MidgardTorch")
  GameObjects.torchLights:JumpAnimToFrame(0)
  GameObjects.torchLights:PlayAnimToEnd()
  local animMonitor = monitors.CreateAnimFrameMonitor(GameObjects.torchLights)
  animMonitor:OnFrame(GameObjects.torchLights.AnimLengthFrames, function()
    PlayTorchIdle(animMonitor)
  end)
  LD.ShowFX(GameObjects.brazier_torch_refn)
end
function PlayTorchOutro()
  GameObjects.torchLights:StartAnim("MidgardTorchIntro_Spot_MidgardTorch")
  GameObjects.torchLights:JumpAnimToFrame(GameObjects.torchLights.AnimLengthFrames)
  GameObjects.torchLights:PlayAnimToEnd(-1)
  LD.HideFX(GameObjects.brazier_torch_refn)
end
function PlayCrystalLight_Init(realm)
  local crystal = thisLevel:FindSingleGameObject("c_" .. string.lower(realm))
  if crystal then
    crystal.LuaObjectScript.PlayAnim_Init(realm)
  end
  local tidePool = thisLevel:FindSingleGameObject("tidePool_" .. realm)
  if tidePool then
    LD.HideFX(tidePool:FindSingleGOByName("FX_State0_Unpowered"))
    LD.HideFX(tidePool:FindSingleGOByName("FX_State1_Powered"))
    LD.HideFX(tidePool:FindSingleGOByName("FX_State2_CrystalActive"))
  end
end
function PlayCrystalLight_Active(realm)
  local crystal = thisLevel:FindSingleGameObject("c_" .. string.lower(realm))
  if crystal then
    crystal.LuaObjectScript.PlayAnim_ActiveLoop(realm)
  end
  local tidePool = thisLevel:FindSingleGameObject("tidePool_" .. realm)
  if tidePool then
    LD.ShowFX(GameObjects["tidePool_" .. realm]:FindSingleGOByName("FX_State1_Powered"))
  end
end
function PlayCrystalLight_Travel(realm)
  local crystal = thisLevel:FindSingleGameObject("c_" .. string.lower(realm))
  if crystal then
    crystal.LuaObjectScript.PlayAnim_Travel(realm)
  end
  local tidePool = thisLevel:FindSingleGameObject("tidePool_" .. realm)
  if tidePool then
    LD.HideFX(GameObjects["tidePool_" .. realm]:FindSingleGOByName("FX_State1_Powered"))
    LD.ShowFX(GameObjects["tidePool_" .. realm]:FindSingleGOByName("FX_State2_CrystalActive"))
  end
end
function PlayCrystalLight_TravelComplete(realm)
  local crystal = thisLevel:FindSingleGameObject("c_" .. string.lower(realm))
  if crystal then
    crystal.LuaObjectScript.PlayAnim_TravelReverse(realm)
  end
  local tidePool = thisLevel:FindSingleGameObject("tidePool_" .. realm)
  if tidePool then
    LD.ShowFX(GameObjects["tidePool_" .. realm]:FindSingleGOByName("FX_State1_Powered"))
    LD.HideFX(GameObjects["tidePool_" .. realm]:FindSingleGOByName("FX_State2_CrystalActive"))
  end
end
function Lighting_FX_Transition_In(speed)
  speed = speed or 1
  local completedCineNum = game.Level.GetVariable("CompletedCineNumber")
  local lightAnimName = ""
  local fxAnimName = ""
  if previousRealm ~= nil then
    local prevRealm = previousRealm
    if prevRealm == "Niflheim" then
      prevRealm = "Nidavellir"
    end
    lightAnimName = prevRealm
    fxAnimName = prevRealm
    if prevRealm == "Alfheim" then
      if completedCineNum < cineNumber_AlfheimComplete then
        lightAnimName = lightAnimName .. "Dark"
        fxAnimName = fxAnimName .. "Dark"
      else
        lightAnimName = lightAnimName .. "Light"
        fxAnimName = fxAnimName .. "Light"
      end
    end
    lightAnimName = lightAnimName .. "_Spot_MidgardTravel"
    fxAnimName = fxAnimName .. "_FX_MidgardTravel"
  end
  GameObjects.realmTravelLightingTransitions:StartAnim(lightAnimName)
  GameObjects.realmTravelLightingTransitions:PlayAnimToEnd(speed)
  GameObjects.realmTravelLightingTransitions:ShowLights()
  GameObjects.realmTravelFXTransitions:StartAnim(fxAnimName)
  GameObjects.realmTravelFXTransitions:PlayAnimToEnd(speed)
end
function Lighting_FX_Transition_Out(speed)
  speed = speed or 1
  local destinationRealm = LD.GetCurrentRealm()
  local completedCineNum = game.Level.GetVariable("CompletedCineNumber")
  local lightAnimName = ""
  local fxAnimName = ""
  if destinationRealm ~= nil then
    if destinationRealm == "Niflheim" then
      destinationRealm = "Nidavellir"
    end
    lightAnimName = "MidgardTravel_Spot_" .. destinationRealm
    fxAnimName = "MidgardTravel_FX_" .. destinationRealm
    if destinationRealm == "Alfheim" then
      if completedCineNum < cineNumber_AlfheimComplete then
        lightAnimName = lightAnimName .. "Dark"
        fxAnimName = fxAnimName .. "Dark"
      else
        lightAnimName = lightAnimName .. "Light"
        fxAnimName = fxAnimName .. "Light"
      end
    end
  end
  GameObjects.realmTravelLightingTransitions:StartAnim(lightAnimName)
  GameObjects.realmTravelLightingTransitions:PlayAnimToEnd(speed)
  GameObjects.realmTravelLightingTransitions:ShowLights()
  GameObjects.realmTravelFXTransitions:StartAnim(fxAnimName)
  GameObjects.realmTravelFXTransitions:PlayAnimToEnd(speed)
end
function ColorCorrection_Transition_Out()
  local currRealm = LD.GetCurrentRealm()
  local transitionVolume = "fxV_cal130_" .. string.lower(currRealm)
  if currRealm == "Alfheim" then
    if game.Level.GetVariable("CompletedCineNumber") < cineNumber_AlfheimComplete then
      transitionVolume = transitionVolume .. "dark"
    else
      transitionVolume = transitionVolume .. "light"
    end
  end
  transitionVolume = thisLevel:FindSingleGameObject(transitionVolume)
  if transitionVolume then
    transitionVolume:PlayAnimToEnd(1)
  end
  GameObjects.fxV_cal130_midgardTravel:PlayAnimToEnd(-1)
end
function ColorCorrection_Transition_In()
  local transitionVolume = "fxV_cal130_" .. string.lower(previousRealm)
  if previousRealm == "Alfheim" then
    if game.Level.GetVariable("CompletedCineNumber") < cineNumber_AlfheimComplete then
      transitionVolume = transitionVolume .. "dark"
    else
      transitionVolume = transitionVolume .. "light"
    end
  end
  transitionVolume = thisLevel:FindSingleGameObject(transitionVolume)
  if transitionVolume then
    transitionVolume:PlayAnimToEnd(-1)
  end
  GameObjects.fxV_cal130_midgardTravel:PlayAnimToEnd(1)
end
function Event_OnLoadComplete()
  LD.ShowFX(fx_PortalEnd)
  StopCoalesceFX()
  GameObjects.fxV_cal130_travelWind:PlayAnimToEnd(-1)
  local blastCleanupFxDelay = 1
  LD.CallFunctionAfterDelay(function()
    local currRealm = LD.GetCurrentRealm()
    if currRealm == "Midgard" then
      PlayCrystalLight_TravelComplete("Midgard")
      StopVortexLeaves()
    end
    StartFlowerGrowth(currRealm)
    Lighting_FX_Transition_Out(0.5)
    ColorCorrection_Transition_Out()
    StartBranchAnim_TravelComplete(currRealm)
    PlayTorchIntro()
    LD.HideFX(beam03_CrystalToPortal)
    LD.HideFX(beam02_CenterTableToCrystal)
    LD.HideFX(beam04_MidgardTravelSkyBeam)
    StopSoundActiveLoopOnBeams()
    bridgeExterior:Hide()
    fx_Portal:FindSingleGOByName("Cards"):Hide()
    LD.HideFX(fx_Portal:FindSingleGOByName("Fx"))
    LD.HideFX(fx_Portal:FindSingleGOByName("Cards"))
    StartFallingLeaves()
    LD.AddScreenShake({
      EffectName = "FSE_SHAKE_VIBRATE_CRYSTAL_INTACT",
      Duration = 2
    })
    LD.AddScreenShake({EffectName = "FFB_SLAM", Duration = 1.5})
    game.FX.StopEffect({EffectName = "FFB_SMALL"})
    StopBeamImpactVibration()
    FinishDomeTransitionFX()
    previousRealm = nil
    GameObjects.realm_controller_object.LuaObjectScript.StopSoundTravelActivationLoop()
    Event_FXSequenceEnd()
  end, blastCleanupFxDelay)
end
function Event_FXSequenceEnd()
  GameObjects.realm_controller_object.LuaObjectScript.Event_FXSequenceEnd()
end
function Event_OnCrystalRaise(realm)
  PlayCrystalLight_Travel(realm)
end
function Event_OnCrystalLower(realm)
  PlayCrystalLight_TravelComplete(realm)
end
function LuaHook_OnBifrostRemove()
  HideTableActiveFX()
end
function HideTableActiveFX()
  LD.HideFX(fx_tableActive)
  fx_tableActive:FindSingleGOByName("pool_ripples"):PlayAnimToEnd(-1)
end
function ShowTableActiveFX()
  LD.ShowFX(fx_tableActive)
  LD.ShowFX(fx_BifrostInsertPulse)
  fx_tableActive:FindSingleGOByName("pool_ripples"):PlayAnimToEnd()
end
function StartDomeTransitionFX()
  if lastDome ~= nil then
    lastDome.Child:JumpAnimToFrame(360)
    lastDome:Show()
    lastDome.Child:PlayAnimToEnd()
  end
end
function FinishDomeTransitionFX()
  local currRealm = LD.GetCurrentRealm()
  if lastDome ~= nil then
    lastDome:Hide()
  end
  if LD.GetSelectedRealm() == "Alfheim" then
    if game.Level.GetVariable("CompletedCineNumber") < cineNumber_AlfheimComplete then
      lastDome = GameObjects.dome_Alfheim_A
    else
      lastDome = GameObjects.dome_Alfheim_B
    end
  else
    lastDome = thisLevel:FindSingleGameObject("dome_" .. LD.GetSelectedRealm())
  end
  if currRealm ~= "Midgard" and lastDome ~= nil then
    lastDome.Child:JumpAnimToFrame(100)
    lastDome:Show()
    lastDome.Child:PlayAnimToFrame(360)
    lastDome.Child:OnAnimDone(thisObj, "ExcessivePauseTest")
  end
  GameObjects.AnimTest:JumpAnimToFrame(0)
  GameObjects.AnimTest:PlayAnimToFrame(50)
end
function ExcessivePauseTest()
  lastDome.Child:ClearAllAnimCallbacks()
  lastDome.Child:PauseAnim()
end
function StartCoalesceFX()
  LD.ShowFX(fx_coalesceControl)
  LD.ShowFX(fx_TreeCore)
end
function StopCoalesceFX()
  fx_coalesceControl:PlayAnimToEnd(-3)
  fx_TreeCore:PlayAnimToEnd(-3)
end
function ResetCoalesceFX()
  fx_coalesceControl:JumpAnimToFrame(0)
  fx_coalesceControl:PauseAnim()
  fx_TreeCore:JumpAnimToFrame(0)
  fx_TreeCore:PauseAnim()
end
function ShowCustomFX(fx, jumpToFrame, playToFrame)
  jumpToFrame = jumpToFrame or 0
  playToFrame = playToFrame or nil
  if fx ~= nil then
    fx:JumpAnimToFrame(jumpToFrame)
    fx:Show()
    fx:ShowParticleEmitter()
    fx:ShowLights()
    if playToFrame == nil then
      fx:PlayAnimToEnd()
    else
      fx:PlayAnimToFrame(playToFrame)
    end
    for _, d in pairs(fx.Descendants) do
      d:JumpAnimToFrame(jumpToFrame)
      d:Show()
      d:ShowParticleEmitter()
      d:ShowLights()
      if playToFrame == nil then
        d:PlayAnimToEnd()
      else
        d:PlayAnimToFrame(playToFrame)
      end
    end
  end
end
function SetRoomState_Intro()
  fx_Portal:Hide()
  bridgeExterior:Hide()
  LD.HideFX(fx_Portal)
  LD.HideFX(fx_PortalEnd)
  LD.HideFX(fx_BifrostInsertPulse)
  HideTableActiveFX()
  LD.HideFX(fx_MagicDust)
  LD.HideFX(fx_TreeCore)
  LD.HideFX(fx_GalaxySmall)
  LD.HideFX(fx_GalaxyLarge)
  LD.HideFX(fx_TreeTop)
  LD.HideFX(fx_RootGlow)
  ResetCoalesceFX()
  StopFallingLeaves()
  LD.HideFX(fx_LeavesVortexLoop)
  for _, realm in pairs(realmInfo.names) do
    HideFlowers(realm)
    PlayCrystalLight_Init(realm)
  end
  PlayCrystalLight_Init("Midgard")
  HideFlowers("Midgard")
  for _, child in pairs(GameObjects.realmDomes.Children) do
    child:Hide()
    child.Child:JumpAnimToPercent(0)
    child.Child:PauseAnim()
  end
  GameObjects.Cal130_LOWER_Level:Hide()
  GameObjects.realmTravelLightingTransitions:StartAnim("MidgardIntro_Spot_Midgard")
  GameObjects.realmTravelLightingTransitions:JumpAnimToFrame(0)
  GameObjects.realmTravelLightingTransitions:PauseAnim()
  GameObjects.realmTravelFXTransitions:StartAnim("MidgardIntro_FX_Midgard")
  GameObjects.realmTravelFXTransitions:JumpAnimToFrame(0)
  GameObjects.realmTravelFXTransitions:PauseAnim()
  GameObjects.rotateMainLightGroup:PauseAnim()
  GameObjects.treeMidSpotlight:JumpAnimToFrame(0)
  GameObjects.treeMidSpotlight:PauseAnim()
  GameObjects.treePointLights:PauseAnim()
  GameObjects.exposureLights:PauseAnim()
end
function SetRoomState_AlfheimComplete()
  GameObjects.dome_Alfheim_A.Child:JumpAnimToFrame(GameObjects.dome_Alfheim_A.Child.AnimLengthFrames)
  GameObjects.dome_Alfheim_A:Hide()
  GameObjects.dome_Alfheim_B:Show()
  GameObjects.dome_Alfheim_B.Child:JumpAnimToFrame(360)
  GameObjects.dome_Alfheim_B.Child:PauseAnim()
  lastDome = GameObjects.dome_Alfheim_B
  GameObjects.fxV_cal130_alfheimdark:JumpAnimToFrame(0)
  GameObjects.fxV_cal130_alfheimdark:PauseAnim()
  GameObjects.fxV_cal130_alfheimdark:Hide()
  GameObjects.fxV_cal130_alfheimlight:JumpAnimToFrame(GameObjects.fxV_cal130_alfheimlight.AnimLengthFrames)
  GameObjects.fxV_cal130_alfheimlight:Show()
  GameObjects.realmTravelLightingTransitions:StartAnim("MidgardTravel_Spot_AlfheimLight")
  GameObjects.realmTravelLightingTransitions:JumpAnimToFrame(GameObjects.realmTravelLightingTransitions.AnimLengthFrames)
  GameObjects.realmTravelFXTransitions:StartAnim("MidgardTravel_FX_AlfheimLight")
  GameObjects.realmTravelFXTransitions:JumpAnimToFrame(GameObjects.realmTravelFXTransitions.AnimLengthFrames)
  StartBranchAnim_TravelComplete("Alfheim")
  StartFlowerGrowth("Alfheim")
  StartFallingLeaves()
end
function SetRoomState_HelheimReturnComplete()
  if lastDome then
    lastDome.Child:JumpAnimToFrame(GameObjects.dome_Alfheim_A.Child.AnimLengthFrames)
    lastDome:Hide()
  end
  lastDome = GameObjects.dome_Helheim
  lastDome:Show()
  lastDome.Child:JumpAnimToFrame(360)
  lastDome.Child:PauseAnim()
  GameObjects.fxV_cal130_helheim:JumpAnimToFrame(GameObjects.fxV_cal130_alfheimlight.AnimLengthFrames)
  GameObjects.fxV_cal130_helheim:Show()
  GameObjects.realmTravelLightingTransitions:StartAnim("MidgardTravel_Spot_Helheim")
  GameObjects.realmTravelLightingTransitions:JumpAnimToFrame(GameObjects.realmTravelLightingTransitions.AnimLengthFrames)
  GameObjects.realmTravelFXTransitions:StartAnim("MidgardTravel_FX_Helheim")
  GameObjects.realmTravelFXTransitions:JumpAnimToFrame(GameObjects.realmTravelFXTransitions.AnimLengthFrames)
  StartBranchAnim_TravelComplete("Helheim")
  StartFlowerGrowth("Helheim")
  StartFallingLeaves()
  GameObjects.realm_controller_object.LuaObjectScript.ResetPressurePlatesAndRootBridgeToRealmDirection("Helheim")
  GameObjects.worldTreeBridge00_P.LuaObjectScript.Extend()
end
function SetRoomState_TempleFlipped()
  SetRoomState_Intro()
  GameObjects.treeMidSpotlight:Hide()
  InitTreeAnim_Dissolve()
end
function SetRoomState_TalismanAcquired()
  StartTreeAnim_Dissolve(0.25)
end
function SetRoomState_HengeDisruptStart()
  previousRealm = "Midgard"
  LD.SetSelectedRealm("Helheim")
  LD.SetCurrentRealm("Helheim")
  Event_OnRealmSelectionConfirmed("Helheim")
  StopFallingLeaves()
  StartVortexLeaves()
  PlayCrystalLight_TravelComplete("Midgard")
  GameObjects.realm_controller_object.LuaObjectScript.AnimateTempleRise()
  GameObjects.realm_controller_object.LuaObjectScript.DisableTable()
end
function SetRoomState_HengeDisruptFXTransition_Helheim()
  Event_OnLoadComplete()
  StopVortexLeaves()
  StartFallingLeaves()
  GameObjects.realm_controller_object.LuaObjectScript.AnimateTempleFall()
end
local tableToCrystalBeamEmitter, skyBeamEmitter
local beamSoundEvents = {
  ActiveLoop = "SND_MAG_Realm_Room_Travel_Beam_LP",
  OnStop = "SND_MAG_Realm_Room_Travel_Beam_Stop"
}
function SoundInit()
  tableToCrystalBeamEmitter = beam02_CenterTableToCrystal:FindSingleGOByName("SNDGrpRealmBeam").SoundEmitters[1]
  skyBeamEmitter = beam04_MidgardTravelSkyBeam:FindSingleGOByName("SNDGrpSkyBeam").SoundEmitters[1]
end
function PlaySoundActiveLoopOnTargetBeam(targetBeam)
  if targetBeam == "Main" then
    LD.PlaySound(tableToCrystalBeamEmitter, beamSoundEvents.ActiveLoop)
  elseif targetBeam == "Sky" then
    LD.PlaySound(skyBeamEmitter, beamSoundEvents.ActiveLoop)
  end
end
function StopSoundActiveLoopOnBeams()
  if tableToCrystalBeamEmitter ~= nil and tableToCrystalBeamEmitter.PlayingAnything then
    LD.PlaySound(tableToCrystalBeamEmitter, beamSoundEvents.OnStop)
    LD.StopSound(tableToCrystalBeamEmitter, beamSoundEvents.ActiveLoop)
  end
  if skyBeamEmitter ~= nil and skyBeamEmitter.PlayingAnything then
    LD.PlaySound(skyBeamEmitter, beamSoundEvents.OnStop)
    LD.StopSound(skyBeamEmitter, beamSoundEvents.ActiveLoop)
  end
end
function PlaySoundJotunheimFail()
  LD.PlaySound(tableToCrystalBeamEmitter, "SND_MAG_Realm_Room_Travel_Jotunheim_Travel_Fail")
end
function OnSaveCheckpoint(level, obj)
  return {
    lastDome = lastDome,
    firstActivated = firstActivated,
    alfheimLightingUpdated = alfheimLightingUpdated,
    helheimLightingUpdated = helheimLightingUpdated
  }
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  lastDome = savedInfo.lastDome
  firstActivated = savedInfo.firstActivated
  alfheimLightingUpdated = savedInfo.alfheimLightingUpdated
  helheimLightingUpdated = savedInfo.helheimLightingUpdated
end
