local LD = require("design.LevelDesignLibrary")
local EC = require("design.Encounter")
local monitors = require("level.MonitorLibrary")
local checkpoint = require("level.checkpoint")
local timer = require("level.timer")
local CCEC = require("camera.camera_cineentercamera")
local CCOS = require("camera.camera_oneshot")
local TUT = require("game.GlobalTutorials")
local EliteDarkOne_BossEncounter = require("boss.statemachine")
local uiCalls = require("ui.uicalls")
local varRunesRevealed, varRuneDoorOpen, varRuneDoorSolved, runeTable, FlipperTable, player, darkOneKing, thisLevel, pad, carryObject
local varCrystalSocketed = false
local son
local shakeRumble = false
local pillarDestroyed = false
local pillarPushed = false
local rubbleCollapse = false
local whiteLight = false
local AlfheimTrenchRoof = false
local camShakeLarge = {
  EffectName = "FSE_shake_temp_Generic_Large",
  Duration = 1
}
local varPrisonHiveCleared = false
local varPrisonDoorTried = false
local TrenchEnc00, TrenchEnc01, TrenchEnc01_2, TrenchEnc01_3, TrenchEnc02, TrenchEnc03, TrenchEnc04, Trench_R_Encounter_1_1, Trench_R_Encounter_1_2, Trench_R_Encounter_Cell_1, Trench_R_Encounter_Cell_2, Trench_R_Encounter_3
local WreckedByBoss = false
local Count_WreckedByBoss
local Hint_EvadeUnblockables = false
local WitchAlertZoneMonitor, recallButtonMonitor, Trench1DespawnZoneMonitor, Trench2DespawnZoneMonitor, EliteDarkOne_HealthMonitor, TrenchEnc02Zone, CountDownMonitor, trenchClosed
local isResetting = false
local cameraTrenchClose, cameraADarkOneEliteAppears
local gateOpenSound = "SND_DOOR_Metal_Prison_Cell_Open_"
local gateMalfunctionSound = "SND_DOOR_Metal_Prison_Cell_Malfunction_"
local gateTendrilSound = "SND_DOOR_Metal_Prison_Cell_Tendril_01"
local ZoneMonitorAggroEnemy, ZoneTrigger
local EDO_Phase_1 = EliteDarkOne_BossEncounter:AddStage("EliteDarkOne_Intro_Phase_1", true)
local EDO_Phase_2 = EliteDarkOne_BossEncounter:AddStage("EliteDarkOne_Reinforcements_Phase_2", true)
local EDO_Phase_3 = EliteDarkOne_BossEncounter:AddStage("EliteDarkOne_Laststand_Phase_3", true)
function OnScriptLoaded(level)
  player = game.Player.FindPlayer()
  pad = player.Pad
  son = game.AI.FindSon()
  thisLevel = level
  Trench_Area_1_Repop()
  Trench_Area_1_Fight_1()
  Trench_Area_2_Fight_1()
  Trench_Area_1_Fight_3()
  Trench_Middle_ReturnFight_1()
  Trench_Middle_ReturnFight_2()
  Trench_Cell_ReturnFight_1()
  Trench_Cell_ReturnFight_2()
  Trench_Boss_ReturnFight()
  Trench_Area_2_KidnapFight()
  Trench_Area_2_KidnapFightPost()
  SoundInit()
  cameraTrenchClose = CCEC.CineEnterCamera.New("PLYR_Nar_LookAt_TrenchClose", 4.4, nil)
  cameraADarkOneEliteAppears = CCEC.CineEnterCamera.New("PLYR_Nar_LookAt_DarkOneElite", 4, nil)
  Count_WreckedByBoss = 0
  runeTable = {}
  runeTable[1] = 5
  runeTable[2] = 1
  runeTable[3] = 25
  runeTable[4] = 9
  FlipperTable = {}
  for i = 1, 4 do
    table.insert(FlipperTable, level:GetGameObject("SpearFlipper0" .. tostring(i)))
  end
  local floorSwitch_1 = level:FindGameObject("SwitchFloor_1")
  floorSwitch_1.LuaObjectScript.OverrideCameraInteractApproach("ENV_Interact_WallSwitch_Prison_Alf340_020")
  floorSwitch_1.LuaObjectScript.OverideInteractApproachYaw(true)
  floorSwitch_1.LuaObjectScript.OverrideCameraSubmissionTime(3)
  recallButtonMonitor = monitors.CreateTriangleButtonMonitor()
  recallButtonMonitor:OnButtonDown(DisableSecretMantle)
  local animFrameMonitorLibrary = require("level.animframemonitor")
  CountDownMonitor = animFrameMonitorLibrary.Add(GameObjects.Timers)
  CountDownMonitor:OnFrameBackward(0, TimeOutReset)
end
function OnStart(level)
  GameObjects.EntZn_MiddlePlatform:HideEntityVolume()
  if game.Level.GetVariable("CompletedCineNumber") < 230 then
    local Gnome01 = GameObjects.runic_breakable_01.Child:GetBreakable()
    local Gnome02 = GameObjects.runic_breakable_02.Child:GetBreakable()
    local Gnome03 = GameObjects.runic_breakable_03.Child:GetBreakable()
    if Gnome01.Broken or Gnome02.Broken or Gnome03.Broken then
      DisableNornirChestHint()
    end
  else
    DisableNornirChestHint()
  end
  if game.Level.GetVariable("CompletedCineNumber") < 245 then
    game.Compass.SetGatewayMarkerIsOpen("ALF_340_Helper_08", false)
  end
  carryObject = GameObjects.CarryBifrostLightTop.LuaObjectScript
  GameObjects.bifrost_crystal_temporal_pulse1:Hide()
  GameObjects.bifrost_crystal_temporal_pulse2:Hide()
  GameObjects.bifrost_crystal_temporal_pulse3:Hide()
  GameObjects.bifrost_crystal_temporal_pulse4:Hide()
  if varRuneDoorSolved == true then
    DisableFlippersRotations()
    GameObjects.DoorRunes:Hide()
  end
  GameObjects.entityZone_LTW345:HideEntityVolume()
  GameObjects.EliteFightCollision:HideCollision()
  Disable_LTW345()
  GameObjects.SnakeInteract.LuaObjectScript.GetInteractZone():ClearTags("NotInRageMode")
  GameObjects.SnakeInteract.LuaObjectScript.GetInteractZone():ClearTags("NotInCombat")
  GameObjects.WheelCrankPrison.LuaObjectScript.SetAnimSynchedCrank(GameObjects.WheelCrank)
  GameObjects.WheelCrank.LuaObjectScript.SetAnimSynchedCrank(GameObjects.WheelCrankPrison)
  if LD.GetEntityVariable("ALF_TrenchOpen") == true then
    GameObjects.AnimateTrenchGeoOpening:JumpAnimToPercent(1)
  end
  recallButtonMonitor:Stop()
  CountDownMonitor:Stop()
  GameObjects.Zone_DetectRecall:HideEntityVolume()
  if LD.GetEntityVariable("ALF_LightAcquired") == false then
    GameObjects.Trench01RetStartZone:HideEntityVolume()
    GameObjects.Trench01RetAlertZone:HideEntityVolume()
    GameObjects.Trench01RetCell1StartZone:HideEntityVolume()
    GameObjects.Trench01RetCell2StartZone:HideEntityVolume()
    GameObjects.Trench01RetCell3StartZone:HideEntityVolume()
    GameObjects.Checkpoint_Ret:HideEntityVolume()
    GameObjects.EZ_ToggleCA_SonOnPlatform:ShowEntityVolume()
    GameObjects.Toggle_LTW_ToEliteFight:HideEntityVolume()
    for _, x in pairs(GameObjects.CellDoors_after.Children) do
      x:Hide()
      x:HideCollision()
    end
  end
  if LD.GetEntityVariable("ALF_LightAcquired") == true then
    GameObjects.Trench01RetStartZone:ShowEntityVolume()
    GameObjects.Trench01RetAlertZone:ShowEntityVolume()
    GameObjects.CA_ForceIntoTrench.LuaObjectScript.Disable()
    GameObjects.CA_SonOnPlatform.LuaObjectScript.Disable()
    GameObjects.Trench01RetCell2StartZone:ShowEntityVolume()
    GameObjects.PrisDoor4Anim_L:PlayAnimToEnd()
    GameObjects.PrisDoor4Anim_R:PlayAnimToEnd()
    GameObjects.PrisDoor6Anim_L:PlayAnimToEnd()
    GameObjects.PrisDoor6Anim_R:PlayAnimToEnd()
    GameObjects.SwitchFloor_1.LuaObjectScript.Disable()
    varPrisonDoorTried = true
    for _, x in pairs(GameObjects.CellDoors_before.Children) do
      x:Hide()
      x:HideCollision()
    end
    DisableCA_SonOnPlatform()
    GameObjects.EZ_ToggleCA_SonOnPlatform:HideEntityVolume()
    GameObjects.AwarenessZone_EnemyCage.LuaObjectScript.DisableEventEmitter()
    GameObjects.EntZn_EnableCageAwareness:HideEntityVolume()
    GameObjects.EntZn_DisableCageAwareness:HideEntityVolume()
  end
  local eliteInteractZone = GameObjects.FakeSonInteract.LuaObjectScript.GetInteractZone()
  eliteInteractZone:SetXZRange(5)
  eliteInteractZone:SetYRange(1.5)
  eliteInteractZone:SetAngle(90)
  eliteInteractZone:SetHintXZRange(12)
  eliteInteractZone:SetHintAngle(360)
  if game.Level.GetVariable("CompletedCineNumber") >= 250 then
    GameObjects.IdleContext_Bored.LuaObjectScript.Disable()
  end
  SoundOnStart()
end
function OnUpdate(level)
  if AlfheimTrenchRoof == false and LD.GetEntityVariable("ALF_LightAcquired") == true and LD.GetEntityVariable("ALF_TrenchOpen") == true and LD.GetEntityVariable("ALF_TrenchClosing") == true and LD.GetEntityVariable("ALF_TrenchClosed") == false then
    AlfheimTrenchRoof = true
    GameObjects.AnimateTrenchGeoOpening:JumpAnimToFrame(560)
    GameObjects.AnimateTrenchGeoOpening:PlayAnimToFrame(0, -1)
    GameObjects.WheelCrankFightZone:HideEntityVolume()
    GameObjects.Trench01KidnapZone:HideEntityVolume()
    GameObjects.Trench01KidnapZonePost:HideEntityVolume()
    GameObjects.EntZn_Area_1_Attack:HideEntityVolume()
    GameObjects.EntZn_Area_2_Attack:HideEntityVolume()
    PlayTrenchCloseSound()
    game.Audio.StartMusic("SND_MX_ALF_trench_return_entrance")
    timer.StartLevelTimer(4, function()
      game.Level.SetVariable("ALF_TrenchClosed", true)
      game.Level.SetVariable("ALF_TrenchOpen", false)
    end)
    timer.StartLevelTimer(1, CameraTrenchClosing)
    LD.CallFunctionAfterDelay(function()
      game.Audio.PlayBanter("TrenchReturnDark_Right")
    end, 3)
    local alf320 = game.FindLevel("Alf320_TrenchADark")
    if alf320 ~= nil then
      alf320:CallScript("DeactivateTrenchRunes")
      alf320:CallScript("DisableSandbowlEntZone")
    end
    local alf075 = game.FindLevel("Alf075_Lighting")
    if alf075 ~= nil then
      alf075:CallScript("TrenchLightsOFF")
    end
    local alf000 = game.FindLevel("Alf000_SkyDark")
    if alf000 ~= nil then
      alf000:CallScript("CloseTrenchRoof")
    end
    GameObjects.Trench01RetStartZone:ShowEntityVolume()
    GameObjects.Trench01RetAlertZone:ShowEntityVolume()
    GameObjects.Trench01RetCell2StartZone:ShowEntityVolume()
    GameObjects.light_door_L.Child.LuaObjectScript:Enable()
    GameObjects.light_door_M.Child.LuaObjectScript:Enable()
    GameObjects.light_door_R.Child.LuaObjectScript:Enable()
  end
  if cameraTrenchClose ~= nil then
    cameraTrenchClose:Update()
  end
  if cameraADarkOneEliteAppears ~= nil then
    cameraADarkOneEliteAppears:Update()
  end
  if LD.GetEntityVariable("ShakeRumble") == true and shakeRumble == false then
    shakeRumble = true
    ShakeRumble()
  end
  if LD.GetEntityVariable("KidnapFightOver") == true and pillarDestroyed == false then
    pillarDestroyed = true
    GameObjects.SnakeInteract.LuaObjectScript.Enable()
  end
  if LD.GetEntityVariable("PillarPushed") == true and pillarPushed == false then
    pillarPushed = true
    GameObjects.Dragon_head_fall_break.Child:PlayAnimToEnd()
  end
  if LD.GetEntityVariable("AmbushCollisionZone") == true and rubbleCollapse == false then
    rubbleCollapse = true
  end
  if LD.GetEntityVariable("TrenchFight02Started") == false and player:InsideZone(GameObjects.EntZn_Area_2_Attack) then
    LD.SetEntityVariable("TrenchFight02Started", true)
    LD.SetEntityVariable("TrenchFightBanter", false)
  end
  if Trench_R_Encounter_3:IsRunning() and (player:IsPlayingMove("MOV_DefBlockCrush") or player:IsPlayingMove("MOV_DefBlockCrushKneel")) and WreckedByBoss == false and Hint_EvadeUnblockables == false then
    WreckedByBoss = true
    Count_WreckedByBoss = Count_WreckedByBoss + 1
    timer.StartLevelTimer(1.5, function()
      WreckedByBoss = false
    end)
    if Count_WreckedByBoss == 3 then
      uiCalls.SendSidebarDesignerMessage({
        Text = 41045,
        DisplayTime = 7.5,
        MessageVariant = uiCalls.msgParam.SIDEBAR_MEDIUM
      })
      Count_WreckedByBoss = 0
      Hint_EvadeUnblockables = true
    end
  end
end
function OnFirstStart(level)
  HideTraversePaths()
  HideRunes()
  GameObjects.SpreadDoor_RuneLocked.LuaObjectScript.Lock()
  GameObjects.SpreadDoor_Fake:Hide()
  GameObjects.Anim_SwayIdle:PlayAnimCycle(0.6)
  GameObjects.AmbushBackCollision:HideCollision()
  GameObjects.FakeSnakeHead:Hide()
  GameObjects.FakeSnakeHead:HideCollision()
  GameObjects.TemporalBridge_LG:Hide()
  GameObjects.TemporalBridge_LG:HideCollision()
  GameObjects.TemporalBridge_RG:Hide()
  GameObjects.TemporalBridge_RG:HideCollision()
  GameObjects.EliteFightCollision:HideCollision()
  GameObjects.Trench01KidnapZone:HideEntityVolume()
  GameObjects.Trench01RetStartZone:HideEntityVolume()
  GameObjects.Trench01RetAlertZone:HideEntityVolume()
  GameObjects.Trench01RetCell1StartZone:HideEntityVolume()
  GameObjects.Trench01RetCell2StartZone:HideEntityVolume()
  GameObjects.Trench01RetCell3StartZone:HideEntityVolume()
  GameObjects.Checkpoint_Ret:HideEntityVolume()
  GameObjects.CristalCovered:ShowLights()
  GameObjects.CristalOpened:HideLights()
  local alf000 = game.FindLevel("Alf000_SkyDark")
  if alf000 ~= nil then
    alf000:CallScript("TurnOnTemple")
  end
end
function DisableNornirChestHint()
  GameObjects.BtrZone_NornirChest:HideEntityVolume()
end
function OpenDoorSideA()
  GameObjects.CA_Exit_Outside.LuaObjectScript.Interrupt()
  GameObjects.CA_Exit_Outside.LuaObjectScript.Disable()
  GameObjects.CA_Exit_TrenchClosing.LuaObjectScript.Disable()
  GameObjects.CA_Exit_Inside.LuaObjectScript.Enable()
end
function OpenDoorSideB()
  GameObjects.CA_Exit_Inside.LuaObjectScript.Interrupt()
  GameObjects.CA_Exit_Inside.LuaObjectScript.Disable()
  if game.Level.GetVariable("CompletedCineNumber") == 245 and not trenchClosed then
    trenchClosed = true
    GameObjects.CA_Exit_TrenchClosing.LuaObjectScript.Enable()
    GameObjects.CA_observe_down_EA.LuaObjectScript.Disable()
  else
    GameObjects.CA_Exit_Outside.LuaObjectScript.Enable()
  end
end
function CLeanUpCAExitInside()
  GameObjects.CA_Exit_Inside.LuaObjectScript.Disable()
end
function CheckTraversePaths()
  GameObjects.Zone_DetectRecall:ShowEntityVolume()
  if GameObjects.liftingBlock.AnimFrame == 36 then
    GameObjects.UpperTraverseLinks:ShowTraverseLink()
  elseif GameObjects.liftingBlock.AnimFrame == 108 then
    GameObjects.TopTraverseLinks:ShowTraverseLink()
  elseif GameObjects.liftingBlock.AnimFrame == 144 then
    GameObjects.LowerTraverseLinks:ShowTraverseLink()
    GameObjects.coffin_tier1_alf340_4.LuaObjectScript.Enable()
  elseif GameObjects.liftingBlock.AnimFrame == 180 then
    GameObjects.TraverseMantleSecret:ShowTraverseLink()
    if LD.GetEntityVariable("ALF_LightAcquired") == false then
      GameObjects.entityZone_LTW345:ShowEntityVolume()
      GameObjects.CA_ForceIntoTrench.LuaObjectScript.Enable()
      GameObjects.CA_SonOnPlatform.LuaObjectScript.Interrupt()
      GameObjects.CA_SonOnPlatform.LuaObjectScript.Disable()
      Enable_LTW345()
    end
  else
    GameObjects.LowerTraverseLinks:HideTraverseLink()
    GameObjects.UpperTraverseLinks:HideTraverseLink()
    GameObjects.TraverseMantleSecret:HideTraverseLink()
    GameObjects.coffin_tier1_alf340_4.LuaObjectScript.Disable()
  end
end
function Enable_LTW345()
  GameObjects.LeadTheWay345.LuaObjectScript.Enable()
end
function Disable_LTW345()
  GameObjects.LeadTheWay345.LuaObjectScript.Disable()
end
function Enable_LTWEA()
  GameObjects.LeadTheWay_ExitArea.LuaObjectScript.Enable()
end
function Disable_LTWEA()
  GameObjects.LeadTheWay_ExitArea.LuaObjectScript.Disable()
end
function Enable_LTW_EliteFight()
  if LD.GetEntityVariable("ALF_LightAcquired") == true then
    GameObjects.LeadTheWay_ToEliteFight.LuaObjectScript.Enable()
    son:CallScript("EnterBehaviorContext", "LEAD_THE_WAY_BEHAVIOR_CONTEXT_CONFIG")
    GameObjects.entityZone_LTW345:HideEntityVolume()
    Disable_LTW345()
    GameObjects.CA_ForceIntoTrench.LuaObjectScript.Disable()
    GameObjects.CA_SonOnPlatform.LuaObjectScript.Disable()
  end
end
function Disable_LTW_EliteFight()
  if LD.GetEntityVariable("ALF_LightAcquired") == true then
    GameObjects.LeadTheWay_ToEliteFight.LuaObjectScript.Disable()
    son:CallScript("ClearBehaviorContext")
  end
end
function HideTraversePaths()
  GameObjects.Zone_DetectRecall:HideEntityVolume()
  GameObjects.LowerTraverseLinks:HideTraverseLink()
  GameObjects.UpperTraverseLinks:HideTraverseLink()
  GameObjects.TraverseMantleSecret:HideTraverseLink()
  GameObjects.coffin_tier1_alf340_4.LuaObjectScript.Disable()
end
function TurnOnRecallMonitor()
  recallButtonMonitor:Start()
end
function TurnOffRecallMonitor()
  recallButtonMonitor:Stop()
end
function DisableSecretMantle()
  GameObjects.TraverseMantleSecret:HideTraverseLink()
end
function OpenCell_R1()
  GameObjects.CellDoor_R1:PlayAnimToEnd()
end
function OpenCell_R2()
  GameObjects.CellDoor_R2:PlayAnimToEnd()
end
function DetachCarryCrystal()
  GameObjects.Anim_BreakAndFall:PlayAnimToEnd()
  GameObjects.Anim_SwayIdle:PlayAnimToEnd(2)
  LD.PlaySoundOnFrame(GameObjects.CarryBifrostMainDoor.Child.SoundEmitters[1], GameObjects.Anim_BreakAndFall, "SND_AMB_EMIT_Bifrost_Crystal_Hanging_Fall_Impact", 25, "forward")
  LD.CallFunctionAfterDelay(function()
    GameObjects.CarryBifrostMainDoor.LuaObjectScript.EnableInteract()
  end, 2)
  LD.CallFunctionAfterDelay(function()
    GameObjects.light_door_L.Child.LuaObjectScript.FlickerOff(flickerOffCallback_L)
    GameObjects.light_door_M.Child.LuaObjectScript.FlickerOff(flickerOffCallback_M)
    GameObjects.light_door_R.Child.LuaObjectScript.FlickerOff(flickerOffCallback_R)
    PlaySoundOnTemporalCellDoorDeactivation()
  end, 1)
  GameObjects.Trench01RetCell1StartZone:ShowEntityVolume()
  GameObjects.Btr_TrenchReturn_Base:HideEntityVolume()
  GameObjects.CA_HintBridge.LuaObjectScript.Enable()
end
function flickerOffCallback_L()
  GameObjects.CollidableBox_L:HideCollision()
end
function flickerOffCallback_M()
  GameObjects.CollidableBox_M:HideCollision()
end
function flickerOffCallback_R()
  GameObjects.CollidableBox_R:HideCollision()
end
function turnOffElite_Callback()
end
function SpawnSurprise()
  LD.SetEntityVariable("TrenchFight01_2Started", true)
  timer.StartLevelTimer(0.1, function()
    TrenchEnc01_3:Start()
  end)
  local alf340c = game.FindLevel("Alf340_c_Prisoners")
  if alf340c ~= nil then
    alf340c:CallScript("HidePrisoner")
  end
end
function OpenLeftCellDoors()
  if varPrisonHiveCleared == false then
    varPrisonDoorTried = true
    timer.StartLevelTimer(1, function()
      GameObjects.PrisDoor4Anim_L:PlayAnimToEnd()
      PlaySoundOnGate(GameObjects.PrisDoor4Anim_L, gateOpenSound .. "L")
    end)
    timer.StartLevelTimer(1, function()
      GameObjects.PrisDoor4Anim_R:PlayAnimToEnd()
      PlaySoundOnGate(GameObjects.PrisDoor4Anim_L, gateOpenSound .. "R")
    end)
    timer.StartLevelTimer(1, function()
      GameObjects.PrisDoor5Anim_L:PlayAnimToFrame(60, 2)
      PlaySoundOnGate(GameObjects.PrisDoor4Anim_L, gateMalfunctionSound .. "L")
      PlaySoundOnGate(GameObjects.PrisDoor4Anim_L, gateTendrilSound)
    end)
    timer.StartLevelTimer(1, function()
      GameObjects.PrisDoor5Anim_R:PlayAnimToFrame(60, 2)
      PlaySoundOnGate(GameObjects.PrisDoor4Anim_L, gateMalfunctionSound .. "R")
    end)
    timer.StartLevelTimer(1, function()
      GameObjects.PrisDoor6Anim_L:PlayAnimToEnd()
      PlaySoundOnGate(GameObjects.PrisDoor4Anim_L, gateOpenSound .. "L")
    end)
    timer.StartLevelTimer(1, function()
      GameObjects.PrisDoor6Anim_R:PlayAnimToEnd()
      PlaySoundOnGate(GameObjects.PrisDoor4Anim_L, gateOpenSound .. "R")
    end)
  end
end
function CoffinTendrilBreak()
  GameObjects.HiveDeadBodyGeo:HideCollision()
  for _, x in pairs(GameObjects.HiveDeadBodyGeo.Children) do
    x.Child.LuaObjectScript.StartDecay()
  end
  GameObjects.SecretLightOneIC:HideCollision()
  GameObjects.coffin_tier1_alf340_3.LuaObjectScript.Enable()
end
function PrisonTendrilBreak()
  GameObjects.PrisonHiveGeo:HideCollision()
  for _, x in pairs(GameObjects.PrisonHiveGeo.Children) do
    x.Child.LuaObjectScript.StartDecay()
  end
  varPrisonHiveCleared = true
  ShakeRumble()
  GameObjects.CA_LookAtLoot.LuaObjectScript.Disable()
  if varPrisonDoorTried == true then
    GameObjects.PrisDoor5Anim_L:JumpAnimToFrame(60)
    GameObjects.PrisDoor5Anim_R:JumpAnimToFrame(60)
    GameObjects.SwitchFloor_1.LuaObjectScript.Disable()
  end
end
function HideDeathIC()
  GameObjects.DeathPlains:HideCollision()
end
function ShowDeathIC()
  GameObjects.DeathPlains:ShowCollision()
end
function ActivateTrenchRoof()
  if LD.GetEntityVariable("ALF_LightAcquired") == false then
    GameObjects.AnimateTrenchGeoOpening:PlayAnimToEnd()
    PlayTrenchOpenSound()
  end
end
function AmbushWallOn()
  GameObjects.AmbushBackCollision:ShowCollision()
end
function TrenchSnakePillar()
  game.Level.SetVariable("ALF_TrenchPillar", true)
  local alf340 = game.FindLevel("Alf340_TrenchBDark")
  local cineObj
  if alf340 ~= nil then
    cineObj = alf340:FindSingleGameObject("Cine_SonGapCarryCine")
    cineObj:CallScript("SonGapCarry_Part2_Sequence")
  end
end
function TrenchBLoopDone()
  game.Level.SetVariable("TrenchBLoop", true)
end
function TrenchBridgeL()
  LD.CallFunctionAfterDelay(function()
    GameObjects.NavObstacle_bridge_LG:HideNavObstacle()
    GameObjects.TemporalBridge_L:HideCollision()
  end, 1)
end
function TrenchBridgeR()
  LD.CallFunctionAfterDelay(function()
    GameObjects.NavObstacle_bridge_RG:HideNavObstacle()
    GameObjects.TemporalBridge_R:HideCollision()
  end, 1)
end
function TrenchBridgeRM()
  if LD.GetEntityVariable("ALF_LightAcquired") == true then
    LD.CallFunctionAfterDelay(function()
      GameObjects.TemporalBridge_M:HideCollision()
      LD.SetEntityVariable("ALF_TrenchLightBridgeSolved", true)
      GameObjects.CA_HintBridge.LuaObjectScript.Disable()
      GameObjects.Toggle_LTW_ExitArea:HideEntityVolume()
      GameObjects.LeadTheWay_ExitArea.LuaObjectScript.Disable()
      GameObjects.Toggle_LTW_ToEliteFight:ShowEntityVolume()
      GameObjects.NavObstacle_bridge_M:HideNavObstacle()
    end, 1)
  end
end
function RemoveTrenchBridgeRM()
  varCrystalSocketed = false
  if LD.GetEntityVariable("ALF_LightAcquired") == true then
    LD.CallFunctionAfterDelay(function()
      GameObjects.NavObstacle_bridge_M:ShowNavObstacle()
      GameObjects.TemporalBridge_M:ShowCollision()
      GameObjects.CA_HintBridge.LuaObjectScript.Enable()
      GameObjects.Toggle_LTW_ExitArea:ShowEntityVolume()
      GameObjects.LeadTheWay_ExitArea.LuaObjectScript.Enable()
      GameObjects.Toggle_LTW_ToEliteFight:HideEntityVolume()
      GameObjects.LeadTheWay_ToEliteFight.LuaObjectScript.Disable()
      son:CallScript("ClearBehaviorContext")
    end, 1)
  end
end
function NextTo_CrystalBase()
  if LD.GetEntityVariable("ALF_LightAcquired") == true then
    GameObjects.CA_SonAvoidBridge.LuaObjectScript.Enable()
  end
end
function AwayFrom_CrystalBase()
  if LD.GetEntityVariable("ALF_LightAcquired") == true then
    GameObjects.CA_SonAvoidBridge.LuaObjectScript.Disable()
  end
end
function CrystalSocketed()
  varCrystalSocketed = true
end
function SonOnLightBridge()
  if varCrystalSocketed then
    carryObject.SetCarryDisallowedTags()
  end
end
function SonOffLightBridge()
  if varCrystalSocketed then
    carryObject.ClearCarryDisallowedTags()
  end
end
function RuneCrankStart()
  game.Level.SetVariable("RuneCrank", true)
end
function KratosNearCrank()
  GameObjects.EntZn_MiddlePlatform:ShowEntityVolume()
  if son:InsideZone(GameObjects.EntZn_MiddlePlatform) then
    GameObjects.CA_SonOnPlatform.LuaObjectScript.Enable()
  end
end
function KratosAwayFromCrank()
  GameObjects.EntZn_MiddlePlatform:HideEntityVolume()
  GameObjects.CA_SonOnPlatform.LuaObjectScript.Disable()
end
function SonOnPlatform()
  GameObjects.CA_SonOnPlatform.LuaObjectScript.Enable()
end
function SonOffPlatform()
  GameObjects.CA_SonOnPlatform.LuaObjectScript.Disable()
end
function ReturnElevatorGlyph()
  local alf320 = game.FindLevel("Alf320_TrenchADark")
  if alf320 ~= nil then
    alf320:CallScript("EnableSandbowlEntZone")
  end
end
function ShakeRumble()
  game.FX.SubmitEffect(camShakeLarge)
end
function Trench1EncounterComplete()
  LD.SetEntityVariable("TrenchFight01", true)
  if LD.GetEntityVariable("TrenchFight02Started") == false and LD.GetEntityVariable("TrenchFight01_2Started") == false then
    LD.SetEntityVariable("TrenchFightBanter", true)
  end
  LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_DarkOne_Base")
end
function Trench1_2EncounterComplete()
  LD.SetEntityVariable("PrisonDraugrFight", true)
  LD.SetEntityVariable("TrenchFight01_2Started", false)
  if LD.GetEntityVariable("TrenchFight02Started") == false and LD.GetEntityVariable("TrenchFight01") == true then
    LD.SetEntityVariable("TrenchFightBanter", true)
  end
end
function WheelCrankEncounterComplete()
  LD.SetEntityVariable("WheelCrankFight", true)
end
function Trench2EncounterComplete()
  LD.SetEntityVariable("TrenchFight02Started", false)
  LD.SetEntityVariable("TrenchFight02", true)
  if LD.GetEntityVariable("TrenchFight01_2Started") == false and LD.GetEntityVariable("TrenchFight01") == true then
    LD.SetEntityVariable("TrenchFightBanter", true)
  end
  BOOKMARK_06_Alfheim_032_TrenchPuzzle()
end
function Trench3EncounterComplete()
  LD.SetEntityVariable("TrenchFight03", true)
  LD.SetEntityVariable("KidnapFightOver", true)
end
function Trench4EncounterComplete()
  LD.SetEntityVariable("KidnapPostFightOver", true)
  timer.StartLevelTimer(5, function()
    TUT.SkillPointReminder_Tutorial()
  end)
  LD.StopCombatMusic()
  LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_DarkOne_Warrior")
  BOOKMARK_06_Alfheim_035_AfterPillarCollapse()
  print("stop combat music")
end
function TrenchRetMidZoneOn()
  GameObjects.Trench01RetCell3StartZone:ShowEntityVolume()
end
function TrenchRet1EncounterComplete()
  LD.SetEntityVariable("TrenchFight01Ret", true)
  LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Revenant_Poison")
end
function EnableCageAwareness()
  GameObjects.AwarenessZone_EnemyCage.LuaObjectScript.EnableEventEmitter()
end
function DisableCageAwareness()
  GameObjects.AwarenessZone_EnemyCage.LuaObjectScript.DisableEventEmitter()
end
function TrenchRet3EncounterComplete()
  carryObject.EnableInteract()
  GameObjects.EliteFightCollision:HideCollision()
  GameObjects.light_door_D1.Child.LuaObjectScript:Disable()
  GameObjects.light_door_D2.Child.LuaObjectScript:Disable()
  GameObjects.light_door_D3.Child.LuaObjectScript:Disable()
  GameObjects.light_door_D4.Child.LuaObjectScript:Disable()
  GameObjects.light_door_D5.Child.LuaObjectScript:Disable()
  timer.StartLevelTimer(15, function()
    ReturnElevatorGlyph()
  end)
  LD.SetEntityVariable("TrenchFight03Ret", true)
  LD.SetEntityVariable("CompletedCineNumber", 247)
  game.Compass.SetDesignerForcedHide(false)
  if darkOneKing ~= nil then
    darkOneKing:CallScript("HideHealthBar")
  end
  LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Svart\195\161lj\199\171furr")
end
function TnF_Rip_Prison()
  LD.SetEntityVariable("ALF_PrisonTnF", true)
end
function WhiteLight()
  if LD.GetEntityVariable("ALF_TrenchEndTnF") == true and whiteLight == false then
    whiteLight = true
    game.Level.SetVariable("ALF_TrenchEndTnF", false)
    game.Level.SetVariable("ALF_TrenchEndTnF", true)
    GameObjects.CristalCovered:HideLights()
    GameObjects.CristalOpened:ShowLights()
  end
end
function OpenSpreadDoor345()
  if LD.GetEntityVariable("ALF_TrenchEndTnF") == true and whiteLight == false then
    whiteLight = true
    game.Level.SetVariable("ALF_TrenchEndTnF", false)
    game.Level.SetVariable("ALF_TrenchEndTnF", true)
    GameObjects.CristalCovered:HideLights()
    GameObjects.CristalOpened:ShowLights()
  end
  if LD.GetEntityVariable("CompletedCineNumber") == 245 then
    game.Level.SetVariable("ALF_TrenchClosing", true)
    GameObjects.Checkpoint_Ret:ShowEntityVolume()
  end
end
function EZE_AmbushInputMask_On()
  LD.SetEntityVariable("ALF_InputMaskStage", 340)
  pad:DisableGameButton(tweaks.ePad.kPadSquare)
  pad:DisableGameButton(tweaks.ePad.kPadL2)
  pad:DisableGameButton(tweaks.ePad.kPadTriangle)
  pad:DisableGameButton(tweaks.ePad.kPadRight)
  pad:DisableGameButton(tweaks.ePad.kPadUp)
end
function EZE_AmbushInputMask_Off()
  LD.SetEntityVariable("ALF_InputMaskStage", 0)
  pad:ClearAllDisabledGameButtons()
end
function KidnapText()
end
function Trench_Area_1_Repop()
  TrenchEnc00 = EC.NewEncounter(thisLevel, "[Area 1]EC:1 Alf340 Repop Dark Ones", {
    CheckpointOnComplete = false,
    RepopulationEncounter = true,
    MustHaveCompletedList = {
      "[Area 1]EC:2 Return Level Boss Fight"
    }
  })
  TrenchEnc00:AddWave({
    {
      spawners = "DarkOne_6_SFBF",
      spawnLocators = "A1_A_Loc_*",
      spawnWad = "Alf340_AI_TrenchPost",
      useSpawnLocatorsOnly = true,
      prioritizeSpawnersInRange = {5, 60},
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "DarkOne_6_SFBF",
      spawnLocators = "A1_A_Loc_*",
      spawnWad = "Alf340_AI_TrenchPost",
      useSpawnLocatorsOnly = true,
      prioritizeSpawnersInRange = {5, 60},
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2.5
    },
    {
      spawners = "DarkOne_7_SFBF",
      spawnLocators = "A1_A_Loc_*",
      spawnWad = "Alf340_AI_TrenchPost",
      useSpawnLocatorsOnly = true,
      prioritizeSpawnersInRange = {5, 60},
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 5
    }
  })
  TrenchEnc00:SetStartZone(thisLevel:GetGameObject("EntZn_Area_1_Repop"), {
    cineRequirement = {339, 950}
  })
end
function Trench_Area_1_Fight_1()
  TrenchEnc01 = EC.NewEncounter(thisLevel, "[Area 1]EC:1 Alf340 first fight at start of trench", {
    CheckpointOnComplete = true,
    StartMusic = "SND_MX_ALF_trench_combat_in",
    StopMusic = "SND_MX_ALF_trench_combat_out"
  })
  TrenchEnc01:AddWave({
    {
      spawners = "DarkOne_SFBF",
      spawnLocators = "A1_A_Loc_*",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      prioritizeSpawnersInRange = {0, 40},
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 3
    },
    {
      spawners = "DarkOne_SFBL",
      spawnLocators = "A1_A_L_Loc_1",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      prioritizeSpawnersInRange = {0, 40},
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "DarkOne_SFBR",
      spawnLocators = "A1_A_R_Loc_1",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      prioritizeSpawnersInRange = {0, 40},
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1.5
    }
  })
  TrenchEnc01:AddWave({
    requireCompletionOfAllPriorWaves = true,
    {
      spawners = "DarkOne_SFBF",
      spawnLocators = "A1_A_Loc_*",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      prioritizeSpawnersInRange = {0, 40},
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1
    },
    {
      spawners = "DarkOne_SFBR",
      spawnLocators = "A1_A_R_Loc_1",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      prioritizeSpawnersInRange = {0, 40},
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2
    }
  })
  TrenchEnc01:OnEnemyDeath(function()
    TrenchEnc01:StartWave(2)
  end, {count = 1})
  TrenchEnc01:SetStartZone(GameObjects.EntZn_Area_1_Attack)
  TrenchEnc01:OnComplete(Quest_Alfheim_Objective300_Complete)
  TrenchEnc01:OnComplete(Trench1EncounterComplete)
end
function Trench_Area_2_Fight_1()
  TrenchEnc02 = EC.NewEncounter(thisLevel, "[Area 2]EC:1 Alf340 second fight after start of trench", {
    CheckpointOnComplete = true,
    StartMusic = "SND_MX_ALF_trench_combat_in",
    StopMusic = "SND_MX_ALF_trench_combat_out"
  })
  TrenchEnc02:AddWave({
    prioritizeOnScreenSpawners = true,
    {
      spawners = "DarkOne_SFL8",
      spawnLocators = "A2_B_FL_Loc_1",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = {0.1, 0.2}
    },
    {
      spawners = "Draugr_L1_H_SA",
      spawnLocators = "A2_D_Loc_1",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = {0.1, 0.2}
    },
    {
      spawners = "DarkOne_SFBF",
      spawnLocators = "A2_B_Loc_*",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      prioritizeSpawnersInRange = {0, 40},
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = {2, 3}
    }
  })
  TrenchEnc02:AddWave({
    prioritizeOnScreenSpawners = true,
    requireCompletionOfAllPriorWaves = true,
    {
      spawners = "DarkOne_SFBF",
      spawnLocators = "A2_B_Loc_*",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      prioritizeSpawnersInRange = {0, 40},
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = {1, 2}
    }
  })
  TrenchEnc02:OnEnemyDeath(function()
    TrenchEnc02:StartWave(2)
  end, {count = 1})
  TrenchEnc02:OnComplete(Trench2EncounterComplete)
  TrenchEnc02:SetStartZone(GameObjects.EntZn_Area_2_Attack)
  TrenchEnc02Zone = monitors.CreateEntityZoneMonitor(player, thisLevel:GetGameObject("EntZn_Area_2_Attack"))
  TrenchEnc02Zone:SetTriggerCountLimit(1)
end
function Trench_Area_1_Fight_3()
  TrenchEnc01_3 = EC.NewEncounter(thisLevel, "TrenchEnc01_3", {CheckpointOnComplete = false})
  TrenchEnc01_3:AddWave({
    {
      spawners = "Draugr_PB_PATH_3",
      spawnWad = "Alf340_AI_TrenchPre",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  TrenchEnc01_3:OnComplete(Trench1_2EncounterComplete)
end
function Trench_Area_2_KidnapFight()
  TrenchEnc03 = EC.NewEncounter(thisLevel, "TrenchEnc03", {CheckpointOnComplete = false})
  TrenchEnc03:AddWave({
    {
      spawners = "DarkOne_SFA",
      spawnLocators = "A1_C_Loc_Fly",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 5.5
    },
    {
      spawners = "DarkOne_Hive_SFBF",
      spawnLocators = "A1_C_Loc_2",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 6.5
    },
    {
      spawners = "DarkOne_Hive_SFBF",
      spawnLocators = "A1_C_Loc_3",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 9
    },
    {
      spawners = "DarkOne_Hive_SFBF",
      spawnLocators = "A1_C_Loc_4",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 11
    }
  })
  TrenchEnc03:AddWave({
    requireCompletionOfAllPriorWaves = true,
    {
      spawners = "DarkOne_SFA",
      spawnLocators = "A1_C_Loc_Fly",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "DarkOne_Hive_SFBF",
      spawnLocators = "A1_C_Loc_2",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1
    },
    {
      spawners = "DarkOne_Hive_SFBF",
      spawnLocators = "A1_C_Loc_4",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2
    }
  })
  TrenchEnc03:AddWave({
    requireCompletionOfAllPriorWaves = true,
    {
      spawners = "DarkOne_SnakePillar",
      spawnLocators = "A1_C_Loc_Tur",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  TrenchEnc03:OnEnemyDeath(function()
    TrenchEnc03:StartWave(2)
  end, {count = 3})
  TrenchEnc03:OnEnemyDeath(function()
    TrenchEnc03:StartWave(3)
  end, {count = 7})
  TrenchEnc03:OnComplete(Trench3EncounterComplete)
  TrenchEnc03:SetStartZone(thisLevel:GetGameObject("Trench01KidnapZone"))
  TrenchEnc03:OnStart(function()
    game.Compass.SetDesignerForcedHide(true)
  end)
end
function Trench_Area_2_KidnapFightPost()
  TrenchEnc04 = EC.NewEncounter(thisLevel, "TrenchEnc04", {CheckpointOnComplete = true})
  TrenchEnc04:AddWave({
    {
      spawners = "H_DarkOne_SFA",
      spawnLocators = "A4_CR_Loc_1",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 6
    },
    {
      spawners = "DarkOne_H_SFA",
      spawnLocators = "A4_CR_Loc_2",
      spawnWad = "Alf340_AI_TrenchPre",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 7.5
    }
  })
  TrenchEnc04:OnComplete(Trench4EncounterComplete)
  TrenchEnc04:SetStartZone(thisLevel:GetGameObject("Trench01KidnapZonePost"))
  TrenchEnc04:OnStart(function()
    game.Compass.SetDesignerForcedHide(false)
  end)
end
function Trench_Middle_ReturnFight_1()
  Trench_R_Encounter_1_1 = EC.NewEncounter(thisLevel, "[Area 4]EC:1 Return to Trench Mid 2 Witch Fight", {
    CheckpointOnComplete = true,
    LeashZone = "LeashZone340",
    StartMusic = "SND_MX_ALF_trench_return_fight1_in",
    StopMusic = "SND_MX_ALF_trench_return_fight1_out"
  })
  Trench_R_Encounter_1_1:AddWave({
    prioritizeOffScreenSpawners = true,
    {
      spawners = "Witch00_Stealth",
      spawnLocators = "A4_O_Loc_1",
      spawnWad = "Alf340_AI_TrenchPost",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.1
    },
    {
      spawners = "Witch00_Stealth",
      spawnLocators = "A4_O_Loc_2",
      spawnWad = "Alf340_AI_TrenchPost",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Trench_R_Encounter_1_1:SetStartZone(GameObjects.Trench01RetStartZone)
  Trench_R_Encounter_1_1:OnComplete(TrenchRet1EncounterComplete)
end
function Trench_Middle_ReturnFight_2()
  Trench_R_Encounter_1_2 = EC.NewEncounter(thisLevel, "[Area 4]EC:1 Return to Trench Mid Draugr Fight", {
    CheckpointOnComplete = false,
    LeashZone = "LeashZone340"
  })
  Trench_R_Encounter_1_2:AddWave({
    {
      spawners = "Draugr_L2_H_SFG",
      spawnLocators = "A4_E_Loc_*",
      spawnWad = "Alf340_AI_TrenchPost",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Trench_R_Encounter_1_2:SetStartZone(GameObjects.Trench01RetCell3StartZone)
end
function Trench_Cell_ReturnFight_1()
  Trench_R_Encounter_Cell_1 = EC.NewEncounter(thisLevel, "[Area 4]EC:1 Prison Cell Draugr Fight", {
    CheckpointOnComplete = false,
    LeashZone = "LeashZone340"
  })
  Trench_R_Encounter_Cell_1:AddWave({
    {
      spawners = "Draugr_PL_SSA",
      spawnLocators = "A4_C_Loc_0",
      spawnWad = "Alf340_AI_TrenchPost",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "Draugr_PL_SSA",
      spawnLocators = "A4_C_Loc_1",
      spawnWad = "Alf340_AI_TrenchPost",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.2
    },
    {
      spawners = "Draugr_PL_SSA",
      spawnLocators = "A4_C_Loc_2",
      spawnWad = "Alf340_AI_TrenchPost",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.4
    }
  })
  Trench_R_Encounter_Cell_1:SetStartZone(GameObjects.Trench01RetCell1StartZone)
end
function Trench_Cell_ReturnFight_2()
  Trench_R_Encounter_Cell_2 = EC.NewEncounter(thisLevel, "[Area 4]EC:1 Return to Trench End Draugr Fight", {
    CheckpointOnComplete = false,
    LeashZone = "LeashZone340"
  })
  Trench_R_Encounter_Cell_2:AddWave({
    {
      spawners = "Draugr_N_SFG",
      spawnLocators = "A4_C_Loc_3",
      spawnWad = "Alf340_AI_TrenchPost",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Trench_R_Encounter_Cell_2:SetStartZone(GameObjects.Trench01RetCell2StartZone)
end
function Trench_Boss_ReturnFight()
  Trench_R_Encounter_3 = EC.NewEncounter(thisLevel, "[Area 1]EC:2 Return Level Boss Fight", {CheckpointOnComplete = true})
  Trench_R_Encounter_3:AddWave({
    {
      spawners = "E_DarkOne_S",
      spawnLocators = "A1_O_Loc_2",
      spawnWad = "Alf340_AI_TrenchPost",
      markerID = "E_DarkOne",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Trench_R_Encounter_3:OnStart(TrenchRet3EncounterStart)
  Trench_R_Encounter_3:OnComplete(TrenchRet3EncounterComplete)
end
function DisableBowlEliteFight()
  if LD.GetEntityVariable("ALF_LightAcquired") == true and LD.GetEntityVariable("TrenchFight03Ret") == false then
    GameObjects.FakeSonInteract.LuaObjectScript.Enable()
    local alf320 = game.FindLevel("Alf320_TrenchADark")
    if alf320 ~= nil then
      print("DISABLING SANDBOWL TRENCH")
      alf320:CallScript("DisableSandbowlEntZone")
    end
    GameObjects.DeactivateRuneForBoss:HideEntityVolume()
  end
end
function TrenchRet3EncounterStart()
  game.Compass.SetDesignerForcedHide(true)
  son:CallScript("ClearBehaviorContext")
  game.Audio.StartMusic("SND_MX_ALF_dark_elf_leader_in")
  GameObjects.EliteFightCollision:ShowCollision()
  GameObjects.light_door_D1.Child.LuaObjectScript:Enable()
  GameObjects.light_door_D2.Child.LuaObjectScript:Enable()
  GameObjects.light_door_D3.Child.LuaObjectScript:Enable()
  GameObjects.light_door_D4.Child.LuaObjectScript:Enable()
  GameObjects.light_door_D5.Child.LuaObjectScript:Enable()
  carryObject.DisableInteract()
  local nearbyCreatures = player:FindEnemies(100)
  for _, creature in ipairs(nearbyCreatures) do
    if creature ~= player and creature:GetHitPoints() > 0 and creature:GetName() == "darkoneelite00" then
      darkOneKing = creature
      if darkOneKing ~= nil then
        darkOneKing:CallScript("ShowHealthBar")
      end
    end
  end
end
function DebugTrenchRoofOpen()
  GameObjects.AnimateTrenchGeoOpening:PlayAnimToEnd()
  local alf320 = game.FindLevel("Alf320_TrenchADark")
  if alf320 ~= nil then
    alf320:CallScript("ActivateTrenchRunes")
    alf320:CallScript("RuneBowlTrenchON")
  end
  local alf000 = game.FindLevel("Alf000_SkyDark")
  if alf000 ~= nil then
    alf000:CallScript("ActivateTrenchRoof")
  end
end
function CameraTrenchClosing()
  cameraTrenchClose:Start()
end
function CameraDarkOneIntroCamera()
  cameraADarkOneEliteAppears:Start()
end
function EDO_Phase_1:OnEnter(level)
end
function EDO_Phase_2:OnEnter(level)
end
function EDO_Phase_3:OnEnter(level)
end
local EliteDarkOne_A1EC2_Next = function()
  Trench_R_Encounter_3:StartWave()
end
function StartEliteFight()
  Trench_R_Encounter_3:Start()
  GameObjects.FakeSonInteract.LuaObjectScript.Disable()
end
function OnSaveCheckpoint(level)
  return {
    pillarDestroyed = pillarDestroyed,
    varRuneDoorSolved = varRuneDoorSolved,
    trenchClosed = trenchClosed,
    levelstate = checkpoint.Save()
  }
end
function OnRestoreCheckpoint(level, savedInfo)
  pillarDestroyed = savedInfo.pillarDestroyed
  varRuneDoorSolved = savedInfo.varRuneDoorSolved
  trenchClosed = savedInfo.trenchClosed
  checkpoint.Restore(savedInfo.levelstate)
end
function BOOKMARK_06_Alfheim_032_TrenchPuzzle()
  local bookmarks = require("design.Bookmarks")
  local tableEntry = bookmarks["BOOKMARK_" .. "06_Alfheim_032_TrenchPuzzle"]
  tableEntry.OverrideObject = GameObjects.CO_TrenchPuzzle
  game.World.StoreCheckpointAndBookmark(tableEntry)
end
function BOOKMARK_06_Alfheim_035_AfterPillarCollapse()
  local bookmarks = require("design.Bookmarks")
  local tableEntry = bookmarks["BOOKMARK_" .. "06_Alfheim_035_AfterPillarCollapse"]
  tableEntry.OverrideObject = GameObjects.CO_AfterPillarCollapse
  game.World.StoreCheckpointAndBookmark(tableEntry)
end
local liftingBlockGO
local isRewinding = false
local middleBlockState = "Rest"
local rightBlockState = "Rest"
local soundEmitterGearsTable = {}
local soundGearsLP = "SND_MECH_Lift_Trench_Crank_Platform_Gear_Cog_Click_LP"
local soundEmitterTemporalCrystalChain, SNDTrenchOpen_Center, SNDTrenchOpen_Left, SNDTrenchOpen_Right, SNDWaterfallTrickleLt, SNDWaterfallTrickleHvy, SNDDripsCaveHard, SNDDripsCaveTonal, trenchCrankScript, prisonCrankScript, liftingBlockAnimMonitor_Middle, liftingBlockAnimMonitor_Right
local liftingBlockLastPauseCycle = 0
local liftingBlockMiddleSound = {
  SoundEmitter = nil,
  LoopEvent = "SND_MECH_Lift_Trench_Middle_Platorm_LP_Alf340",
  PeakEvent = "SND_MECH_Lift_Trench_Middle_Platorm_Hit_Peak_Alf340",
  PeakFrame = 0,
  BottomFrame = 72
}
local liftingBlockRightSound = {
  SoundEmitter = nil,
  LoopEvent = "SND_MECH_Lift_Trench_Crank_Platform_LP_Alf340",
  PeakEvent = "SND_MECH_Lift_Trench_Crank_Platform_Hit_Peak_Alf340",
  PeakFrame = 72,
  BottomFrame = 180
}
local spreadDoorSound = {
  SoundEmitter_Center = nil,
  OnInteractForward_Center = "",
  OnInteractForward_Left = "SND_DOOR_Alfheim_Double_Door_Open_L",
  OnInteractForward_Right = "SND_DOOR_Alfheim_Double_Door_Open_R",
  OnInteractBackward_Center = "",
  OnInteractBackward_Right = "SND_DOOR_Alfheim_Double_Door_Open_R",
  OnInteractBackward_Left = "SND_DOOR_Alfheim_Double_Door_Open_L",
  OnInteractClose_Center = "",
  OnInteractClose_Left = "SND_DOOR_Alfheim_Double_Door_Close_L",
  OnInteractClose_Right = "SND_DOOR_Alfheim_Double_Door_Close_R"
}
local puzzleDoorSound = {
  OnInteractForward_Left = "SND_MECH_Alfheim_Puzzle_Door_Open_L",
  OnInteractForward_Right = "SND_MECH_Alfheim_Puzzle_Door_Open_R"
}
local liftingBlockStopFrames = {
  0,
  36,
  72,
  108,
  144,
  180
}
function SoundInit()
  SNDTrenchOpen_Center = GameObjects.AnimateTrenchGeoOpening:FindSingleSoundEmitterByName("SNDTrenchOpen_Center")
  SNDTrenchOpen_Left = GameObjects.AnimateTrenchGeoOpening:FindSingleSoundEmitterByName("SNDTrenchOpen_Left")
  SNDTrenchOpen_Right = GameObjects.AnimateTrenchGeoOpening:FindSingleSoundEmitterByName("SNDTrenchOpen_Right")
  SNDWaterfallTrickleLt = GameObjects.SNDTrenchCloseEvents:FindSingleSoundEmitterByName("SNDWaterfallTrickleLt")
  SNDWaterfallTrickleHvy = GameObjects.SNDTrenchCloseEvents:FindSingleSoundEmitterByName("SNDWaterfallTrickleHvy")
  SNDDripsCaveHard = GameObjects.SNDTrenchCloseEvents:FindSingleSoundEmitterByName("SNDDripsCaveHard")
  SNDDripsCaveTonal = GameObjects.SNDTrenchCloseEvents:FindSingleSoundEmitterByName("SNDDripsCaveTonal")
  soundEmitterTemporalCrystalChain = GameObjects.SNDGrpHangingTemporalCrystal.SoundEmitters[1]
  liftingBlockGO = GameObjects.liftingBlock
  if liftingBlockGO ~= nil then
    local soundEmitterGearsGOs = liftingBlockGO:FindGOsByName("WallGears_Trench*")
    if soundEmitterGearsGOs ~= nil then
      for i = 1, #soundEmitterGearsGOs do
        soundEmitterGearsTable[#soundEmitterGearsTable + 1] = soundEmitterGearsGOs[i].Child:FindSingleSoundEmitterByName("SNDWallGears")
      end
    end
  end
  local liftingBlockMiddleEmitter = liftingBlockGO:FindSingleSoundEmitterByName("SNDliftingBlockMiddle")
  if liftingBlockMiddleEmitter ~= nil then
    liftingBlockMiddleSound.SoundEmitter = liftingBlockMiddleEmitter
  end
  local liftingBlockRightEmitter = liftingBlockGO:FindSingleSoundEmitterByName("SNDliftingBlockRight")
  if liftingBlockRightEmitter ~= nil then
    liftingBlockRightSound.SoundEmitter = liftingBlockRightEmitter
  end
  trenchCrankScript = liftingBlockGO:FindSingleGOByName("WheelCrank").LuaObjectScript
  prisonCrankScript = GameObjects.WheelCrankPrison.LuaObjectScript
  SoundSetupLiftingBlockMonitor()
end
function SoundOnStart()
  GameObjects.SpreadDoor_Alfheim.LuaObjectScript.SoundSetup(spreadDoorSound)
  GameObjects.SpreadDoor_RuneLocked.LuaObjectScript.SoundSetup(puzzleDoorSound)
  if GameObjects.Anim_BreakAndFall.AnimFrame < 1 then
    LD.PlayRestartableSoundLoop(soundEmitterTemporalCrystalChain, "SND_AMB_EMIT_Bifrost_Crystal_Hanging_Chain_LP")
  end
end
function PlayTrenchOpenSound()
  LD.PlaySoundOnFrame(SNDTrenchOpen_Center, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf300_Trench_Start", 0, "forward")
  LD.PlaySoundOnFrame(SNDTrenchOpen_Center, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf300_Trench_Glyphs_Rise", 45, "forward")
  LD.PlaySoundOnFrame(SNDTrenchOpen_Left, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf300_Trench_Door_L_LP", 180, "forward")
  LD.PlaySoundOnFrame(SNDTrenchOpen_Right, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf300_Trench_Door_R_LP", 180, "forward")
  LD.PlaySoundOnFrame(SNDTrenchOpen_Center, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf300_Trench_Doors_Open", 180, "forward")
  LD.PlaySoundOnFrame(SNDTrenchOpen_Center, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf300_Trench_Doors_Creak", 650, "forward")
  LD.StopSoundOnFrame(SNDTrenchOpen_Left, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf300_Trench_Door_L_LP", 840, "forward")
  LD.StopSoundOnFrame(SNDTrenchOpen_Right, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf300_Trench_Door_R_LP", 840, "forward")
  LD.PlaySoundOnFrame(SNDTrenchOpen_Center, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf300_Trench_Doors_Stop", 840, "forward")
end
function PlayTrenchCloseSound()
  LD.PlaySoundOnFrame(SNDTrenchOpen_Left, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf340_Trench_Door_L_LP", 450, "backward")
  LD.PlaySoundOnFrame(SNDTrenchOpen_Right, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf340_Trench_Door_R_LP", 450, "backward")
  LD.PlaySoundOnFrame(SNDTrenchOpen_Center, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf340_TrenchClose_LP", 450, "backward")
  LD.PlaySoundOnFrame(SNDTrenchOpen_Center, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf340_TrenchClose_Creak", 450, "backward")
  LD.StopSoundOnFrame(SNDTrenchOpen_Left, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf340_Trench_Door_L_LP", 180, "backward")
  LD.StopSoundOnFrame(SNDTrenchOpen_Right, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf340_Trench_Door_R_LP", 180, "backward")
  LD.StopSoundOnFrame(SNDTrenchOpen_Center, GameObjects.AnimateTrenchGeoOpening, "SND_CINE_Alf340_TrenchClose_LP", 196, "backward")
  LD.PlaySoundOnFrame(SNDWaterfallTrickleLt, GameObjects.AnimateTrenchGeoOpening, "SND_WTR_Waterfall_Trickle_Lt_Alf340_Seq_LP", 450, "backward")
  LD.PlaySoundOnFrame(SNDWaterfallTrickleHvy, GameObjects.AnimateTrenchGeoOpening, "SND_WTR_Waterfall_Trickle_Hvy_Alf340_Seq_LP", 450, "backward")
  LD.PlaySoundOnFrame(SNDDripsCaveHard, GameObjects.AnimateTrenchGeoOpening, "SND_WTR_Drips_Cave_Hard_Splats_Alf340_Seq_LP", 450, "backward")
  LD.PlaySoundOnFrame(SNDDripsCaveTonal, GameObjects.AnimateTrenchGeoOpening, "SND_WTR_Drips_Cave_Tonal_Alf340_Seq_LP", 450, "backward")
  LD.StopSoundOnFrame(SNDWaterfallTrickleLt, GameObjects.AnimateTrenchGeoOpening, "SND_WTR_Waterfall_Trickle_Lt_Alf340_Seq_LP", 196, "backward")
  LD.StopSoundOnFrame(SNDWaterfallTrickleHvy, GameObjects.AnimateTrenchGeoOpening, "SND_WTR_Waterfall_Trickle_Hvy_Alf340_Seq_LP", 196, "backward")
  LD.StopSoundOnFrame(SNDDripsCaveHard, GameObjects.AnimateTrenchGeoOpening, "SND_WTR_Drips_Cave_Hard_Splats_Alf340_Seq_LP", 196, "backward")
  LD.StopSoundOnFrame(SNDDripsCaveTonal, GameObjects.AnimateTrenchGeoOpening, "SND_WTR_Drips_Cave_Tonal_Alf340_Seq_LP", 196, "backward")
end
function PlaySoundOnGate(obj, snd)
  LD.PlaySound(obj:FindSingleSoundEmitterByName("SNDPrisonDoor*"), snd)
end
function PlaySoundOnTemporalCellDoorDeactivation()
  local temporalDoorEmitters = GameObjects.SNDGrpTemporalCellDoors.SoundEmitters
  if temporalDoorEmitters ~= nil and 0 < #temporalDoorEmitters then
    for i = 1, #temporalDoorEmitters do
      LD.PlaySound(temporalDoorEmitters[i], "SND_MAG_Temporal_CellDoor_Deactivate")
    end
  end
  LD.StopRestartableSoundLoop(soundEmitterTemporalCrystalChain, "SND_AMB_EMIT_Bifrost_Crystal_Hanging_Chain_LP")
end
function SoundSetupLiftingBlockMonitor()
  liftingBlockAnimMonitor_Middle = monitors.CreateAnimFrameMonitor(liftingBlockGO)
  liftingBlockAnimMonitor_Middle:OnFrame(liftingBlockMiddleSound.BottomFrame, HandleSoundLiftingBlockMiddleBottom)
  liftingBlockAnimMonitor_Right = monitors.CreateAnimFrameMonitor(liftingBlockGO)
  liftingBlockAnimMonitor_Right:OnFrameForward(liftingBlockRightSound.PeakFrame, PlaySoundLiftingBlockRightPeak_Forward)
  liftingBlockAnimMonitor_Right:OnFrameBackward(liftingBlockRightSound.PeakFrame, PlaySoundLiftingBlockRightPeak_Backward)
end
function OnLiftingBlockForwardEvent()
  OnGearsForwardEvent()
  if liftingBlockGO.AnimFrame >= liftingBlockMiddleSound.PeakFrame and liftingBlockGO.AnimFrame < liftingBlockMiddleSound.BottomFrame and middleBlockState == "Rest" then
    PlaySoundLiftingBlockMiddleLoop(true)
    middleBlockState = "Cranking"
  end
  if liftingBlockGO.AnimFrame >= liftingBlockRightSound.PeakFrame and liftingBlockGO.AnimFrame < liftingBlockRightSound.BottomFrame and rightBlockState == "Rest" then
    PlaySoundLiftingBlockRightLoop(true)
    rightBlockState = "Cranking"
  end
end
function OnLiftingBlockBackwardEvent()
  OnGearsForwardEvent()
  if liftingBlockGO.AnimFrame <= liftingBlockMiddleSound.BottomFrame and liftingBlockGO.AnimFrame > liftingBlockMiddleSound.PeakFrame and middleBlockState == "Rest" then
    PlaySoundLiftingBlockMiddleLoop(true)
    middleBlockState = "Cranking"
  end
  if liftingBlockGO.AnimFrame <= liftingBlockRightSound.BottomFrame and liftingBlockGO.AnimFrame > liftingBlockRightSound.PeakFrame and rightBlockState == "Rest" then
    PlaySoundLiftingBlockRightLoop(true)
    rightBlockState = "Cranking"
  end
end
function OnLiftingBlockRewindEvent()
  OnGearsForwardEvent()
  if liftingBlockGO.AnimFrame <= liftingBlockMiddleSound.BottomFrame and liftingBlockGO.AnimFrame > liftingBlockMiddleSound.PeakFrame and middleBlockState == "Rest" then
    PlaySoundLiftingBlockMiddleLoop(true)
  end
  middleBlockState = "Rewinding"
  if liftingBlockGO.AnimFrame <= liftingBlockRightSound.BottomFrame and liftingBlockGO.AnimFrame > liftingBlockRightSound.PeakFrame and rightBlockState == "Rest" then
    PlaySoundLiftingBlockRightLoop(true)
    rightBlockState = "Rewinding"
  end
end
function OnLiftingBlockPauseEvent()
  OnGearsPauseEvent()
  if middleBlockState ~= "Rest" then
    StopSoundLiftingBlockMiddleLoop()
    middleBlockState = "Rest"
  end
  if rightBlockState ~= "Rest" then
    if trenchCrankScript.GetCurrentCycle() == 2 or prisonCrankScript.GetCurrentCycle == 2 then
      LD.PlaySound(liftingBlockRightSound.SoundEmitter, liftingBlockRightSound.PeakEvent)
    else
      StopSoundLiftingBlockRightLoop()
    end
    rightBlockState = "Rest"
  end
  UpdateLiftingBlockLastPauseCycle()
end
function AtLiftingBlockBeginningEvent()
  if middleBlockState ~= "Rest" then
    LD.PlaySound(liftingBlockMiddleSound.SoundEmitter, liftingBlockMiddleSound.PeakEvent)
    if middleBlockState == "Rewinding" then
      prisonCrankScript.StopRewindSound()
    end
    middleBlockState = "Rest"
  end
  OnGearsPauseEvent()
  UpdateLiftingBlockLastPauseCycle()
end
function AtLiftingBlockEndEvent()
  if rightBlockState ~= "Rest" then
    StopSoundLiftingBlockRightLoop()
    rightBlockState = "Rest"
  end
end
function OnLiftingBlockAttachedEvent()
  if middleBlockState == "Rewinding" or rightBlockState == "Rewinding" then
    local nextStopFrameIndex = GetLiftingBlockNextStopFrameIndex()
    if middleBlockState == "Rewinding" then
      if nextStopFrameIndex == 1 then
        LD.PlaySoundOnFrame(liftingBlockMiddleSound.SoundEmitter, liftingBlockGO, liftingBlockMiddleSound.PeakEvent, 1, "backward")
      else
        LD.StopSoundOnFrame(liftingBlockMiddleSound.SoundEmitter, liftingBlockGO, liftingBlockMiddleSound.LoopEvent, liftingBlockStopFrames[nextStopFrameIndex], "backward")
      end
      middleBlockState = "Rest"
    end
    if rightBlockState == "Rewinding" then
      if nextStopFrameIndex == 3 then
        LD.PlaySoundOnFrame(liftingBlockRightSound.SoundEmitter, liftingBlockGO, liftingBlockRightSound.PeakEvent, liftingBlockStopFrames[nextStopFrameIndex], "backward", true)
      else
        LD.StopSoundOnFrame(liftingBlockRightSound.SoundEmitter, liftingBlockGO, liftingBlockRightSound.LoopEvent, liftingBlockStopFrames[nextStopFrameIndex], "backward")
      end
      rightBlockState = "Rest"
    end
  end
  OnGearsPauseEvent()
end
function OnTrenchGearsEmbedEvent()
  if middleBlockState == "Rewinding" or rightBlockState == "Rewinding" then
    prisonCrankScript.StopRewindSound()
  end
  OnLiftingBlockAttachedEvent()
end
function GetLiftingBlockNextStopFrameIndex()
  local nextStopFrameIndex = 0
  local currentliftingBlockFrame = liftingBlockGO.AnimFrame
  for targetIndex = 1, #liftingBlockStopFrames do
    if targetIndex == #liftingBlockStopFrames then
      nextStopFrameIndex = targetIndex
      break
    elseif currentliftingBlockFrame >= liftingBlockStopFrames[targetIndex] and currentliftingBlockFrame < liftingBlockStopFrames[targetIndex + 1] then
      nextStopFrameIndex = targetIndex
      break
    end
  end
  return nextStopFrameIndex
end
function PlaySoundLiftingBlockRightPeak_Backward()
  if rightBlockState ~= "Rest" then
    LD.PlaySound(liftingBlockRightSound.SoundEmitter, liftingBlockRightSound.PeakEvent)
    rightBlockState = "Rest"
  end
end
function PlaySoundLiftingBlockRightPeak_Forward()
  if rightBlockState ~= "Cranking" and GetLiftingBlockCurrentCycle() > liftingBlockLastPauseCycle then
    PlaySoundLiftingBlockRightLoop(true)
    rightBlockState = "Cranking"
  end
end
function HandleSoundLiftingBlockMiddleBottom()
  if middleBlockState == "Cranking" and middleBlockState ~= "Rewinding" then
    StopSoundLiftingBlockMiddleLoop()
    middleBlockState = "Rest"
  end
  HandleSoundLiftingBlockMiddleRewind()
end
function HandleSoundLiftingBlockMiddleRewind()
  if middleBlockState == "Rewinding" then
    PlaySoundLiftingBlockMiddleLoop(true)
  end
end
function UpdateLiftingBlockLastPauseCycle()
  liftingBlockLastPauseCycle = GetLiftingBlockCurrentCycle()
end
function GetLiftingBlockCurrentCycle()
  local currentCycle = 0
  if trenchCrankScript.GetCurrentCycle() >= prisonCrankScript.GetCurrentCycle() then
    currentCycle = trenchCrankScript.GetCurrentCycle()
  else
    currentCycle = prisonCrankScript.GetCurrentCycle()
  end
  return currentCycle
end
function PlaySoundLiftingBlockMiddleLoop(ignoreLoopCheck)
  LD.PlaySound(liftingBlockMiddleSound.SoundEmitter, liftingBlockMiddleSound.LoopEvent, ignoreLoopCheck)
end
function StopSoundLiftingBlockMiddleLoop()
  LD.StopSound(liftingBlockMiddleSound.SoundEmitter, liftingBlockMiddleSound.LoopEvent)
end
function PlaySoundLiftingBlockRightLoop(ignoreLoopCheck)
  LD.PlaySound(liftingBlockRightSound.SoundEmitter, liftingBlockRightSound.LoopEvent, ignoreLoopCheck)
end
function StopSoundLiftingBlockRightLoop()
  LD.StopSound(liftingBlockRightSound.SoundEmitter, liftingBlockRightSound.LoopEvent)
end
function OnGearsForwardEvent()
  for i = 1, #soundEmitterGearsTable do
    LD.PlaySound(soundEmitterGearsTable[i], soundGearsLP)
  end
end
function OnGearsPauseEvent()
  for i = 1, #soundEmitterGearsTable do
    LD.StopSound(soundEmitterGearsTable[i], soundGearsLP)
  end
end
local flipperPuzzleOverallEmitter
local timerGemLoopIsOn = false
local timerGemEmitters = {}
local timerGemSoundMonitor
local allowTimerTickSound = true
local timedFlipperPuzzleSoundEvents = {
  TimerGemOn = "SND_MECH_Alfheim_Door_Puzzle_Reset_Gear_Oneshot",
  TimerGemOnLoop = "SND_MECH_Alfheim_Door_Puzzle_Grind_LP",
  TimerGemOff = "SND_MECH_Alfheim_Door_Puzzle_Door_Gem_Countdown",
  TimerTickingLoop = "SND_MECH_Puzzle_Timer_01_LP",
  TimerTickingSpeedUp = "SND_MECH_Puzzle_Timer_Speed_x2",
  FlipperOverrideTable = {
    OnHit = "SND_MECH_Alfheim_Door_Puzzle_Axe_Hit_Metal_Circle_Layer",
    OnRotateStop = "SND_MECH_Alfheim_Door_Puzzle_Turn_Stop"
  },
  FlipperOnReset = "SND_MECH_Alfheim_Door_Puzzle_Reset_Spin",
  FlipperMagicPulse = "SND_MECH_Alfheim_Door_Puzzle_Success_Door_Open_Magic",
  AlignRune = "SND_MECH_Alfheim_Door_Puzzle_Success_Align_Single_Rune",
  PuzzleSolved = "SND_MECH_Alfheim_Door_Puzzle_Door_Success_Gear_Hit",
  DoorOpenL = "SND_MECH_Alfheim_Puzzle_Door_Open_L",
  DoorOpenR = "SND_MECH_Alfheim_Puzzle_Door_Open_R"
}
function SoundInit_FlipperPuzzleRoomSound()
  if not varRuneDoorSolved == true and timerGemSoundMonitor == nil then
    flipperPuzzleOverallEmitter = GameObjects.SNDGrpFlipperRoomCeiling.SoundEmitters[1]
    for _ = 1, 5 do
      table.insert(timerGemEmitters, {})
    end
    local tempTimerGemEmitters = GameObjects.Timers.SoundEmitters
    for currentTimerGemIndex = 1, #tempTimerGemEmitters do
      for currentRow = 1, 5 do
        if string.find(tempTimerGemEmitters[currentTimerGemIndex].Name, tostring(currentRow)) ~= nil then
          table.insert(timerGemEmitters[currentRow], tempTimerGemEmitters[currentTimerGemIndex])
          break
        end
      end
    end
    GameObjects.SpearFlipper01.LuaObjectScript.SoundSetup(timedFlipperPuzzleSoundEvents.FlipperOverrideTable)
    GameObjects.SpearFlipper02.LuaObjectScript.SoundSetup(timedFlipperPuzzleSoundEvents.FlipperOverrideTable)
    GameObjects.SpearFlipper03.LuaObjectScript.SoundSetup(timedFlipperPuzzleSoundEvents.FlipperOverrideTable)
    GameObjects.SpearFlipper04.LuaObjectScript.SoundSetup(timedFlipperPuzzleSoundEvents.FlipperOverrideTable)
    timerGemSoundMonitor = monitors.CreateAnimFrameMonitor(GameObjects.Timers)
    timerGemSoundMonitor:OnFrameForward(1, function()
      PlaySoundOnTimerGemRow(1, timedFlipperPuzzleSoundEvents.TimerGemOn)
    end)
    timerGemSoundMonitor:OnFrameForward(150, function()
      PlaySoundOnTimerGemRow(2, timedFlipperPuzzleSoundEvents.TimerGemOn)
    end)
    timerGemSoundMonitor:OnFrameForward(300, function()
      PlaySoundOnTimerGemRow(3, timedFlipperPuzzleSoundEvents.TimerGemOn)
    end)
    timerGemSoundMonitor:OnFrameForward(450, function()
      PlaySoundOnTimerGemRow(4, timedFlipperPuzzleSoundEvents.TimerGemOn)
    end)
    timerGemSoundMonitor:OnFrameForward(600, function()
      PlaySoundOnTimerGemRow(5, timedFlipperPuzzleSoundEvents.TimerGemOn)
    end)
    timerGemSoundMonitor:OnFrameBackward(30, function()
      PlaySoundOnTimerGemRow(1, timedFlipperPuzzleSoundEvents.TimerGemOff)
    end)
    timerGemSoundMonitor:OnFrameBackward(180, function()
      PlaySoundOnTimerGemRow(2, timedFlipperPuzzleSoundEvents.TimerGemOff)
      LD.PlaySound(flipperPuzzleOverallEmitter, timedFlipperPuzzleSoundEvents.TimerTickingSpeedUp)
    end)
    timerGemSoundMonitor:OnFrameBackward(330, function()
      PlaySoundOnTimerGemRow(3, timedFlipperPuzzleSoundEvents.TimerGemOff)
    end)
    timerGemSoundMonitor:OnFrameBackward(480, function()
      PlaySoundOnTimerGemRow(4, timedFlipperPuzzleSoundEvents.TimerGemOff)
    end)
    timerGemSoundMonitor:OnFrameBackward(629, function()
      PlaySoundOnTimerGemRow(5, timedFlipperPuzzleSoundEvents.TimerGemOff)
    end)
  end
end
function PlaySoundOnTimerGemRow(rowNumber, soundEvent)
  for currentGemInRow = 1, #timerGemEmitters[rowNumber] do
    LD.PlaySound(timerGemEmitters[rowNumber][currentGemInRow], soundEvent)
  end
end
function StopSoundOnTimerGemRow(rowNumber, soundEvent)
  for currentGemInRow = 1, #timerGemEmitters[rowNumber] do
    LD.StopSound(timerGemEmitters[rowNumber][currentGemInRow], soundEvent)
  end
end
function StopSoundOnLoopOnTimerGems()
  timerGemLoopIsOn = false
  StopSoundOnTimerGemRow(3, timedFlipperPuzzleSoundEvents.TimerGemOnLoop)
end
function PlaySoundOnAlignRune()
  LD.PlaySound(flipperPuzzleOverallEmitter, timedFlipperPuzzleSoundEvents.AlignRune)
end
function PlaySoundOnPuzzleSolved()
  LD.StopSound(flipperPuzzleOverallEmitter, timedFlipperPuzzleSoundEvents.TimerTickingLoop)
  LD.PlaySound(flipperPuzzleOverallEmitter, timedFlipperPuzzleSoundEvents.PuzzleSolved)
  LD.PlaySoundAfterDelay(GameObjects.SpreadDoor_Fake:FindSingleSoundEmitterByName("SNDFlipperPuzzleDoorL"), timedFlipperPuzzleSoundEvents.DoorOpenL, 0.2)
  LD.PlaySoundAfterDelay(GameObjects.SpreadDoor_Fake:FindSingleSoundEmitterByName("SNDFlipperPuzzleDoorR"), timedFlipperPuzzleSoundEvents.DoorOpenR, 0.2)
end
function FlipperPuzzle_OnCrystalFullyLit()
  allowTimerTickSound = false
  RevealRunes()
  TurnOnTimers()
  allowTimerTickSound = true
end
function TurnOnTimers()
  if varRuneDoorSolved ~= true then
    SoundInit_FlipperPuzzleRoomSound()
    LD.StopSound(flipperPuzzleOverallEmitter, timedFlipperPuzzleSoundEvents.TimerTickingLoop)
    GameObjects.Timers:JumpAnimToFrame(0)
    LD.CallFunctionAfterDelay(function()
      GameObjects.Timers:PlayAnimToFrame(630, 21)
      PlaySoundOnTimerGemRow(3, timedFlipperPuzzleSoundEvents.TimerGemOnLoop)
      timerGemLoopIsOn = true
      GameObjects.Timers:OnAnimationDone(thisLevel, "StopSoundOnLoopOnTimerGems")
    end, 0.1)
  end
end
function TurnOffTimers()
  if varRuneDoorSolved ~= true then
    LD.StopSound(flipperPuzzleOverallEmitter, timedFlipperPuzzleSoundEvents.TimerTickingLoop)
    GameObjects.Timers:PlayAnimToFrame(0, -21)
    CountDownMonitor:Stop()
  end
end
function StartCountDown()
  carryObject.Lock()
  if varRuneDoorSolved ~= true then
    GameObjects.Timers:PlayAnimToFrame(0, -1)
    CountDownMonitor:Start()
    if allowTimerTickSound then
      LD.PlaySound(flipperPuzzleOverallEmitter, timedFlipperPuzzleSoundEvents.TimerTickingLoop)
      if GameObjects.Timers.AnimFrame <= 180 then
        LD.PlaySound(flipperPuzzleOverallEmitter, timedFlipperPuzzleSoundEvents.TimerTickingSpeedUp)
      end
    end
    if timerGemLoopIsOn then
      StopSoundOnLoopOnTimerGems()
    end
  end
end
function TimeOutReset()
  isResetting = true
  LD.StopSound(flipperPuzzleOverallEmitter, timedFlipperPuzzleSoundEvents.TimerTickingLoop)
  CountDownMonitor:Stop()
  ResetFlippers()
  HideRunes()
  timer.StartLevelTimer(2, function()
    allowTimerTickSound = false
    TurnOnTimers()
    RevealRunes()
    OnRotateCallback()
    allowTimerTickSound = true
    isResetting = false
    carryObject.Unlock()
  end)
end
function RevealRunes()
  if varRuneDoorSolved ~= true then
    varRunesRevealed = true
    GameObjects.DoorRunes:Show()
    GameObjects.SpearFlipper01.LuaObjectScript.ShowRunes()
    GameObjects.SpearFlipper02.LuaObjectScript.ShowRunes()
    GameObjects.SpearFlipper03.LuaObjectScript.ShowRunes()
    GameObjects.SpearFlipper04.LuaObjectScript.ShowRunes()
    EnableFlippersRotations()
  end
end
function HideRunes()
  if varRuneDoorSolved ~= true then
    DisableFlippersRotations()
    varRunesRevealed = false
    GameObjects.DoorRunes:Hide()
    GameObjects.SpearFlipper01.LuaObjectScript.HideRunes()
    GameObjects.SpearFlipper02.LuaObjectScript.HideRunes()
    GameObjects.SpearFlipper03.LuaObjectScript.HideRunes()
    GameObjects.SpearFlipper04.LuaObjectScript.HideRunes()
  end
end
function EnableFlippersRotations()
  GameObjects.SpearFlipper01.LuaObjectScript.EnableRotation()
  GameObjects.SpearFlipper02.LuaObjectScript.EnableRotation()
  GameObjects.SpearFlipper03.LuaObjectScript.EnableRotation()
  GameObjects.SpearFlipper04.LuaObjectScript.EnableRotation()
end
function DisableFlippersRotations()
  GameObjects.SpearFlipper01.LuaObjectScript.DisableRotation()
  GameObjects.SpearFlipper02.LuaObjectScript.DisableRotation()
  GameObjects.SpearFlipper03.LuaObjectScript.DisableRotation()
  GameObjects.SpearFlipper04.LuaObjectScript.DisableRotation()
end
function ResetFlippers()
  GameObjects.AnimFlipper_01:JumpAnimToFrame(30)
  GameObjects.AnimFlipper_02:JumpAnimToFrame(30)
  GameObjects.AnimFlipper_03:JumpAnimToFrame(30)
  GameObjects.AnimFlipper_04:JumpAnimToFrame(30)
  GameObjects.SpearFlipper01.LuaObjectScript.ResetRotateCW()
  GameObjects.SpearFlipper02.LuaObjectScript.ResetRotateCW()
  GameObjects.SpearFlipper03.LuaObjectScript.ResetRotateCCW()
  GameObjects.SpearFlipper04.LuaObjectScript.ResetRotateCCW()
  GameObjects.SpearFlipper01.LuaObjectScript.PlaySoundOnFlipper_Remote(timedFlipperPuzzleSoundEvents.FlipperOnReset)
  GameObjects.SpearFlipper02.LuaObjectScript.PlaySoundOnFlipper_Remote(timedFlipperPuzzleSoundEvents.FlipperOnReset)
  GameObjects.SpearFlipper03.LuaObjectScript.PlaySoundOnFlipper_Remote(timedFlipperPuzzleSoundEvents.FlipperOnReset)
  GameObjects.SpearFlipper04.LuaObjectScript.PlaySoundOnFlipper_Remote(timedFlipperPuzzleSoundEvents.FlipperOnReset)
end
function OnRotateCallback()
  if isResetting == true then
    return
  end
  if varRunesRevealed == true and varRuneDoorOpen ~= true and varRuneDoorSolved ~= true then
    StartCountDown()
    local DoRunesMatch = {}
    DoRunesMatch[1] = false
    DoRunesMatch[2] = false
    DoRunesMatch[3] = false
    DoRunesMatch[4] = false
    for i = 1, 4 do
      DoRunesMatch[i] = runeTable[i] == FlipperTable[i].LuaObjectScript.GetCurrentRune()
    end
    if DoRunesMatch[1] and DoRunesMatch[2] and DoRunesMatch[3] and DoRunesMatch[4] then
      RuneDoorUnlock()
    else
      RuneDoorLock()
    end
    if DoRunesMatch[1] then
      if GameObjects.Rune_N1:IsModelShown() then
        PlaySoundOnAlignRune()
      end
      GameObjects.Rune_N1:Hide()
    else
      GameObjects.Rune_N1:Show()
    end
    if DoRunesMatch[2] then
      if GameObjects.Rune_R1:IsModelShown() then
        PlaySoundOnAlignRune()
      end
      GameObjects.Rune_R1:Hide()
    else
      GameObjects.Rune_R1:Show()
    end
    if DoRunesMatch[3] then
      if GameObjects.Rune_T1:IsModelShown() then
        PlaySoundOnAlignRune()
      end
      GameObjects.Rune_T1:Hide()
    else
      GameObjects.Rune_T1:Show()
    end
    if DoRunesMatch[4] then
      if GameObjects.Rune_A1:IsModelShown() then
        PlaySoundOnAlignRune()
      end
      GameObjects.Rune_A1:Hide()
    else
      GameObjects.Rune_A1:Show()
    end
  end
end
function RuneDoorUnlock()
  carryObject.Unlock()
  PlaySoundOnPuzzleSolved()
  CountDownMonitor:Stop()
  TurnOffTimers()
  GameObjects.SpreadDoor_RuneLocked.LuaObjectScript.Disable()
  GameObjects.SpreadDoor_RuneLocked:Hide()
  GameObjects.SpreadDoor_Fake:Show()
  GameObjects.SpreadDoor_Fake:PlayAnimToEnd()
  LD.CallFunctionAfterDelay(function()
    GameObjects.bifrost_crystal_temporal_pulse1:Show()
    GameObjects.SpearFlipper01.LuaObjectScript.PlaySoundOnFlipper_Remote(timedFlipperPuzzleSoundEvents.FlipperMagicPulse)
    GameObjects.bifrost_crystal_temporal_pulse2:Show()
    GameObjects.SpearFlipper02.LuaObjectScript.PlaySoundOnFlipper_Remote(timedFlipperPuzzleSoundEvents.FlipperMagicPulse)
    GameObjects.bifrost_crystal_temporal_pulse3:Show()
    GameObjects.SpearFlipper03.LuaObjectScript.PlaySoundOnFlipper_Remote(timedFlipperPuzzleSoundEvents.FlipperMagicPulse)
    GameObjects.bifrost_crystal_temporal_pulse4:Show()
    GameObjects.SpearFlipper04.LuaObjectScript.PlaySoundOnFlipper_Remote(timedFlipperPuzzleSoundEvents.FlipperMagicPulse)
  end, 0.628)
  DisableFlippersRotations()
  varRuneDoorSolved = true
  GameObjects.Timers:PlayAnimToFrame(0, -21)
end
function RuneDoorLock()
  GameObjects.SpreadDoor_RuneLocked.LuaObjectScript.Lock()
  varRuneDoorSolved = false
end
function RuneDoorOpened()
  varRuneDoorOpen = true
end
function EnableCA_Room1()
  GameObjects.CA_Wait_Room_1.LuaObjectScript.Enable()
end
function DisableCA_Room1()
  GameObjects.CA_Wait_Room_1.LuaObjectScript.Disable()
end
function EnableCA_Room2()
  GameObjects.CA_Wait_Room_2.LuaObjectScript.Enable()
end
function DisableCA_Room2()
  GameObjects.CA_Wait_Room_2.LuaObjectScript.Disable()
end
function EnableCA_Lift()
  if LD.GetEntityVariable("ALF_LightAcquired") then
    GameObjects.CA_WaitByLift.LuaObjectScript.Enable()
  end
end
function DisableCA_Lift()
  GameObjects.CA_WaitByLift.LuaObjectScript.Disable()
end
function EnableCA_SonOnPlatform()
  GameObjects.CA_SonOnPlatform.LuaObjectScript.Enable()
end
function DisableCA_SonOnPlatform()
  GameObjects.CA_SonOnPlatform.LuaObjectScript.Disable()
end
function Quest_Alfheim_Objective300_Complete()
  game.Compass.SetDesignerForcedHide(false)
  LD.CompleteQuest("Quest_Alfheim_Objective300")
  game.Compass.SetGatewayMarkerIsOpen("ALF_300_Helper_Dock", false)
  game.Compass.SetGatewayMarkerIsOpen("ALF_340_Helper_08", false)
end
function OnEvaluateLoadGroup_Lighting()
  if game.Level.GetVariable("ALF_LightAcquired") == false then
    return "LightingTrenchOpen"
  elseif game.Level.GetVariable("ALF_LightAcquired") == true then
    return "LightingTrenchClosed"
  end
end
function Alf340_Bookmark_TrenchOpened()
end
