local LD = require("design.LevelDesignLibrary")
local timer = require("level.timer")
local EC = require("design.Encounter")
local monitors = require("level.MonitorLibrary")
local checkpoint = require("level.checkpoint")
local LM = require("level.loadmonitor")
local player, thisLevel, TrapRoomEncounter, spikeTrapMonitor
local underElevatorCount = 0
local bFastCollapseRunning = false
local bEscapedTrapRoom = false
local beginRageGrab = false
local spinnableLocked = false
local SpikeTrapCC, btrVarFirst, btrVarUnlock, btrVarClose, btrVarSquashed, btrVarSinking, btrWaitWhat, tripleChestOpened, coffin_open, sonUnderTrap, exitOpen
local sonEscapedTrap = false
local kratosUnderTrap
local lastDoorHit = 0
local secondDoorHit = 0
local A2_EC_Monitor
local playTrapReaction = false
local gnome2Broken = false
Area_1_Encounter_1_Complete = false
Area_2_Encounter_1_Complete = false
Area_2_Encounter_1_Active = false
local Area_1_Encounter_1, Area_2_Encounter_1
local Area_2_EC_1_Started = false
local Stop_A2_EC_Monitor, Resume_A2_EC_Monitor, End_A2_EC_Monitor
function OnScriptLoaded(level)
  thisLevel = level
  player = game.Player.FindPlayer()
  SpikeTrapCC = GameObjects.SpikeCeiling:FindSingleGOByName("CombatCollision")
  SikeDraugrs_Area_2_Fight_1()
  GameObjects.EntZn_Area_2_Resume:HideEntityVolume()
  GameObjects.EntZn_Area_2_Stop:HideEntityVolume()
  SoundInit()
end
function OnUseWorld(level)
end
function OnFirstStart()
  GameObjects.TL_GapJump01:HideTraverseLink()
  GameObjects.runic_gnome_02.Child:HideCollision()
  GameObjects.TraverseLink1:HideTraverseLink()
end
function OnStart()
  spikeTrapMonitor = monitors.CreateAnimFrameMonitor(GameObjects.SpikeCeiling.Child)
  spikeTrapMonitor:OnFrameBackward(250, CeilingSlowdown01)
  spikeTrapMonitor:OnFrameBackward(220, CeilingSlowdown02)
  spikeTrapMonitor:OnFrameBackward(190, CeilingSlowdown03)
  spikeTrapMonitor:OnFrameBackward(170, CeilingSlowdown04)
  spikeTrapMonitor:OnFrameBackward(140, CeilingSlowdown04b)
  spikeTrapMonitor:OnFrameBackward(150, PlayFloorSpikeLoop)
  spikeTrapMonitor:OnFrameBackward(130, StopFloorSpikeLoop)
  spikeTrapMonitor:OnFrameBackward(135, CeilingSlowdown05)
  spikeTrapMonitor:OnFrameForward(130, PlayFloorSpikeLoop)
  spikeTrapMonitor:OnFrameForward(150, StopFloorSpikeLoop)
  spikeTrapMonitor:OnFrameForward(145, EnableGapJump)
  spikeTrapMonitor:OnFrameForward(4, DisableTripleChest)
  spikeTrapMonitor:OnFrameBackward(2, EnableTripleChest)
  spikeTrapMonitor:OnFrameBackward(146, function()
    GameObjects.CielingCollision:HideCollision()
  end)
  spikeTrapMonitor:OnFrameForward(146, function()
    GameObjects.CielingCollision:ShowCollision()
  end)
  GameObjects.SpinnableSystem.LuaObjectScript.RiverPassOverride(4.8, 6.325, 8.25)
  GameObjects.EntZn_Disable_TippyToesCA:HideEntityVolume()
  GameObjects.NavObstacle_AboveTrap:HideNavObstacle()
  GameObjects.TL_Upper1:ShowTraverseLink()
  if game.Level.GetVariable("CompletedCineNumber") > 180 then
    DisableCielingLTW()
  end
  LD.CallFunctionAfterDelay(function()
    if GameObjects.SpikeCeiling.Child.AnimFrame > 145 then
      GameObjects.TL_GapJump01:ShowTraverseLink()
    else
      GameObjects.TL_GapJump01:HideTraverseLink()
    end
  end, 0.1)
end
function OnUpdate(level)
  if kratosUnderTrap == true then
    if player:HasMarker("InRageGrab") then
      beginRageGrab = true
      if not spinnableLocked then
        GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(0)
      end
    elseif beginRageGrab then
      beginRageGrab = false
      CeilingStartRewind()
    end
  end
  if engine.IsDebug() then
    local dt = {}
    table.insert(dt, {
      "underElevatorCount",
      underElevatorCount
    })
    table.insert(dt, {
      "sonUnderTrap",
      sonUnderTrap
    })
    table.insert(dt, {
      "CombatCollision enabled",
      SpikeTrapCC.LuaObjectScript.bEnabled
    })
    table.insert(dt, {
      "AnimFrame",
      GameObjects.SpikeCeiling.Child.AnimFrame
    })
    table.insert(dt, {
      "currentVelocity",
      GameObjects.SpinnableSystem.LuaObjectScript.currentVelocity
    })
    table.insert(dt, {
      "maxVelocity",
      GameObjects.SpinnableSystem.LuaObjectScript.maxVelocity
    })
    table.insert(dt, {
      "minVelocity",
      GameObjects.SpinnableSystem.LuaObjectScript.minVelocity
    })
    table.insert(dt, {
      "decayRate",
      GameObjects.SpinnableSystem.LuaObjectScript.decayRate
    })
    table.insert(dt, {
      "distanceToSpinnable",
      LD.GetDistanceBetweenTwoObjects(game.Player.FindPlayer(), GameObjects.SpinnableSystem)
    })
    dt.TitleColor = engine.Vector.New(33, 33, 128)
    dt.TitleAlpha = 220
    dt.Title = "Riv325 Debug"
    dt.X, dt.Y = -21, 2
    engine.DrawDebugTable(dt)
  end
end
function AxeEmbed()
  GameObjects.PanelTrapChunk07.LuaObjectScript:StopRotation()
end
function AxeRelease()
  GameObjects.PanelTrapChunk07.LuaObjectScript:BeginRewind()
end
function CeilingStartRewind()
  if GameObjects.SpikeCeiling.Child.AnimFrame == 0 then
    CeilingSpeedReset()
  elseif GameObjects.SpikeCeiling.Child.AnimFrame <= 135 then
    CeilingSlowdown05()
  elseif GameObjects.SpikeCeiling.Child.AnimFrame <= 170 then
    CeilingSlowdown04()
  elseif GameObjects.SpikeCeiling.Child.AnimFrame <= 190 then
    CeilingSlowdown03()
  elseif GameObjects.SpikeCeiling.Child.AnimFrame <= 220 then
    CeilingSlowdown02()
  elseif GameObjects.SpikeCeiling.Child.AnimFrame <= 250 then
    CeilingSlowdown01()
  end
end
function CeilingSlowdown01()
  if underElevatorCount == 0 then
    CeilingSpeedReset()
    return
  end
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-0.5)
end
function CeilingSlowdown02()
  if underElevatorCount == 0 then
    CeilingSpeedReset()
    return
  end
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-0.5)
end
function CeilingSlowdown03()
  if underElevatorCount == 0 then
    CeilingSpeedReset()
    return
  end
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-0.4)
end
function CeilingSlowdown04()
  if underElevatorCount == 0 then
    CeilingSpeedReset()
    return
  end
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-0.3)
  GameObjects.SpinnableSystem.LuaObjectScript.SetDecayRate(35)
end
function CeilingSlowdown04b()
  if kratosUnderTrap and sonUnderTrap then
    GameObjects.TL_GapJump01:HideTraverseLink()
    CeilingSpeedReset()
  end
end
function CeilingSlowdown05()
  if underElevatorCount == 0 and not sonUnderTrap then
    GameObjects.TL_GapJump01:HideTraverseLink()
    CeilingSpeedReset()
    return
  end
  if GameObjects.SpikeCeiling.Child.AnimFrame == 0 then
    return
  end
  bFastCollapseRunning = true
  if sonUnderTrap then
    GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-0.1)
    SpikeTrapCC.LuaObjectScript.Disable()
    if kratosUnderTrap then
      GameObjects.TL_GapJump01:HideTraverseLink()
      GameObjects.SpinnableSystem.LuaObjectScript.SetDecayRate(40)
      GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-50)
      LD.CallFunctionAfterDelay(function()
        SpikeTrapCC.LuaObjectScript.Enable()
      end, 0.2)
    end
  else
    GameObjects.TL_GapJump01:HideTraverseLink()
    if 0 < underElevatorCount then
      GameObjects.SpinnableSystem.LuaObjectScript.SetDecayRate(40)
      GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-50)
      LD.CallFunctionAfterDelay(function()
        SpikeTrapCC.LuaObjectScript.Enable()
      end, 0.2)
    end
  end
end
function CeilingSpeedReset()
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity()
  GameObjects.SpinnableSystem.LuaObjectScript.SetDecayRate()
  SpikeTrapCC.LuaObjectScript.Disable()
end
function InsideTrap(creature)
  if creature == player then
    kratosUnderTrap = true
    player:CallScript("LuaHook_DisableRevive", true)
    if sonEscapedTrap == false then
      GameObjects.CA_Riv_TouchSpikeTrap.LuaObjectScript.Disable()
      GameObjects.CA_Riv_TippyToesPeer.LuaObjectScript.Disable()
      GameObjects.ca_puzzled_01.LuaObjectScript.Disable()
      GameObjects.ca_puzzled_02.LuaObjectScript.Enable()
      SonStartRunningCheck()
    end
  end
  underElevatorCount = underElevatorCount + 1
  if underElevatorCount == 1 then
    CeilingStartRewind()
  end
end
function OutsideTrap(creature)
  if creature == player then
    kratosUnderTrap = false
    player:CallScript("LuaHook_DisableRevive", false)
  end
  underElevatorCount = underElevatorCount - 1
  if underElevatorCount < 0 then
    underElevatorCount = 0
  end
  if underElevatorCount == 0 and GameObjects.SpikeCeiling.Child.AnimFrame > 135 then
    CeilingSpeedReset()
  end
  if sonUnderTrap then
    GameObjects.TL_GapJump01:ShowTraverseLink()
  end
end
function Gnome2Break()
  gnome2Broken = true
end
function ChestOpened()
  tripleChestOpened = true
  GameObjects.LockedChest_TrapRoom.LuaObjectScript:Disable()
end
function EnableTripleChest()
  GameObjects.TL_Upper1:ShowTraverseLink()
  GameObjects.CielingCollision:HideCollision()
  GameObjects.NavObstacle_AboveTrap:HideNavObstacle()
  if player:IsInsideEntityZone("EntZn_SpinCollision") then
    Enable_SpinBlocker()
  end
  if game.Wallets.GetResourceValue("HERO", "MaxRage_Tracker1") < 1 then
    GameObjects.LockedChest_TrapRoom.LuaObjectScript.EnableInteractBehaviors()
  end
  if not gnome2Broken then
    GameObjects.runic_gnome_02.Child:HideCollision()
  end
end
function DisableTripleChest()
  GameObjects.LockedChest_TrapRoom.LuaObjectScript.DisableInteractBehaviors()
  GameObjects.NavObstacle_AboveTrap:ShowNavObstacle()
  if not gnome2Broken then
    GameObjects.runic_gnome_02.Child:ShowCollision()
  end
  GameObjects.TL_Upper1:HideTraverseLink()
end
function EnableGapJump()
  GameObjects.TL_GapJump01:ShowTraverseLink()
end
function DisableCielingJump()
  GameObjects.TL_Upper1:HideTraverseLink()
end
function TrapRoomCheckPointEnd()
  if playTrapReaction then
    GameObjects.Reaction_OutOfBreath.LuaObjectScript.Trigger()
  end
  game.World.StoreCheckpoint({
    OverrideObject = GameObjects.ChkOvr_TrapRoomExit.Child
  })
end
function EscapedTrapRoom()
  underElevatorCount = 0
  bEscapedTrapRoom = true
  sonEscapedTrap = true
  Area_2_Encounter_1:Stop()
  Area_2_Encounter_1:DespawnEnemies()
  Area_2_Encounter_1:SetComplete()
  GameObjects.ca_combat_turret_01.LuaObjectScript.Disable()
  GameObjects.IdleContext_Nervous.LuaObjectScript.Disable()
  if sonEscapedTrap then
    GameObjects.ca_combat_turret_02.LuaObjectScript.Disable()
    CeilingSpeedReset()
  end
  GameObjects.LookFar_Forward.LuaObjectScript.Enable()
  GameObjects.CA_Revisit_Start.LuaObjectScript.Disable()
  GameObjects.CA_Revisit_End.LuaObjectScript.Disable()
  GameObjects.TL_GapJump01:HideTraverseLink()
  game.AI.FindSon():RemoveAvailabilityRequest("LevelDesignScript")
  GameObjects.EntZn_NearTrapRevisit:ShowEntityVolume()
  GameObjects.EntZn_TrapRevisit:ShowEntityVolume()
  GameObjects.EntZn_LeaveTrapExit:ShowEntityVolume()
end
function Enable_SpinBlocker()
  if GameObjects.SpikeCeiling.Child.AnimFrame <= 10 then
    GameObjects.SpinnableDriver1:FindSingleGOByName("DeflectCollision"):ShowCollision()
    GameObjects.SpinnableDriver2:FindSingleGOByName("DeflectCollision"):ShowCollision()
  end
end
function Disable_SpinBlocker()
  GameObjects.SpinnableDriver1:FindSingleGOByName("DeflectCollision"):HideCollision()
  GameObjects.SpinnableDriver2:FindSingleGOByName("DeflectCollision"):HideCollision()
end
function SikeDraugrs_Area_2_Fight_1()
  Area_2_Encounter_1 = EC.NewEncounter(thisLevel, "[Area 2]EC:1 Intro Fight Riv325", {})
  Area_2_Encounter_1:AddWave({
    pointMarkerID = "Enemy",
    {
      spawners = "Draugr_P_SFG",
      spawnLocators = "A2_Loc_O_1",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.1
    },
    {
      spawners = "Draugr_P_SFG",
      spawnLocators = "A2_Loc_O_2",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1.5
    }
  })
  Area_2_Encounter_1:AddWave({
    pointMarkerID = "Enemy",
    timeBeforeNextWave = 0.1,
    {
      spawners = "Draugr_PT_SFG",
      spawnLocators = "A1_Loc_O_1",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.1
    }
  })
  Area_2_Encounter_1:AddWave({
    pointMarkerID = "Enemy",
    requireCompletionOfAllPriorWaves = true,
    {
      spawners = "Draugr_PT_SFG",
      spawnLocators = "A1_Loc_O_2",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 5
    },
    {
      spawners = "Draugr_P_SFG",
      spawnLocators = "A2_Loc_O_4",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.5
    }
  })
  Area_2_Encounter_1:AddWave({
    pointMarkerID = "Enemy",
    requireCompletionOfAllPriorWaves = true,
    {
      spawners = "H_Draugr_P_SFG",
      spawnLocators = "A2_Loc_O_1",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1
    }
  })
  Area_2_Encounter_1:OnStart(function()
    A2_EC_Monitor = monitors.CreateEntityZoneMonitor(player, GameObjects.Trap_Fight_Space)
    A2_EC_Monitor:OnEnter(Area_2_Encounter_1_Start)
    A2_EC_Monitor:OnExit(Area_2_Encounter_1_Stop)
    GameObjects.EntZn_Area_2_Resume:HideEntityVolume()
    GameObjects.EntZn_Area_2_Stop:ShowEntityVolume()
    GameObjects.ca_combat_turret_01.LuaObjectScript.Enable()
    Area_2_Encounter_1_Active = true
  end)
  Area_2_Encounter_1:OnCombatStart(function()
    game.Audio.StartCheckpointedMusic("SND_MX_RIV_fight_trap_in")
  end)
  Area_2_Encounter_1:OnComplete(function()
    A2_EC_Monitor:Stop()
    A2_EC_Monitor = nil
    LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Draugr_2H")
    Area_2_Encounter_1_Complete = true
    Area_2_Encounter_1_Active = false
    game.Audio.StartMusic("SND_MX_RIV_fight_trap_out")
    if bEscapedTrapRoom == false then
      game.World.StoreCheckpoint({
        OverrideObject = GameObjects.ChkOvr_TrapRoomStart.Child
      })
    end
  end)
  Area_2_Encounter_1:OnEnemyDeath(function(enemy)
    if enemy:InsideZone(GameObjects.EntZn_InsideTrap) then
      OutsideTrap()
      enemy:RemoveMarker("Enemy")
      if GameObjects.SpikeCeiling.Child.AnimFrame <= 136 and kratosUnderTrap == false then
        BtrSquashed()
      end
    end
  end, {markerID = "Enemy"})
end
function Area_2_Encounter_1_Stop()
  if Area_2_Encounter_1:IsRunning() then
    Area_2_Encounter_1:Stop()
  end
end
function Area_2_Encounter_1_Start()
  Area_2_Encounter_1:Start()
end
function SonTrapWin()
  if Area_2_Encounter_1:IsComplete() then
    GameObjects.Reaction_OutOfBreath.LuaObjectScript.Trigger()
  else
    playTrapReaction = true
  end
end
function Riv325_Bookmark_OpenPanels()
  GameObjects.SecondPanel.Child:PlayAnimToEnd()
  GameObjects.FirstPanel.LuaObjectScript:HackAnimToEnd()
end
function OnEvaluateLoadGroup_Cinematic()
  if game.Level.GetVariable("CompletedCineNumber") <= 135 then
    return "CanyonOverlookConfig"
  elseif game.Level.GetVariable("CompletedCineNumber") > 135 and game.Level.GetVariable("CompletedCineNumber") < 400 then
    return "AI_Visit01"
  else
    return "AI_Visit02"
  end
end
function LoadCheck_Riv350()
  game.UI.LoadCheck("Riv350_CalderaVista")
end
local convertDistanceToFX = function(dist)
  if dist < 22 then
    return {
      EffectName = "FSE_shake_temp_Generic_Medium",
      Duration = 0.4
    }, {EffectName = "FFB_LARGE", Duration = 0.4}
  elseif dist < 30 then
    return {
      EffectName = "FSE_shake_temp_Generic_Small",
      Duration = 0.3
    }, {EffectName = "FFB_MEDIUM", Duration = 0.3}
  else
    return nil, nil
  end
end
function OnSpinnableUnlock(direction, atStart)
  spinnableLocked = false
  if not atStart then
    BtrUnlock()
  end
end
function OnSpinnableLock()
  spinnableLocked = true
  BtrCloseCall()
  SoundOnSpinnableStop()
end
function OnSpinnableReachedLockFrame()
  SoundOnSpinnableStop()
end
function OnSpinnableAddImpulse(direction, atEnd)
  bFastCollapseRunning = false
  if not atEnd then
    SoundOnAddImpulseSpinnable()
  end
  SonStartRunningCheck()
end
function OnSpinnableRewind()
  BtrSinking()
  SoundOnRewindSpinnable()
end
function OnSpinnableReachStart()
  if bFastCollapseRunning then
    local camShake, conRumble = convertDistanceToFX(LD.GetDistanceBetweenTwoObjects(game.Player.FindPlayer(), GameObjects.SpinnableSystem))
    if camShake then
      game.FX.SubmitEffect(camShake)
    end
    if conRumble then
      game.FX.SubmitEffect(conRumble)
    end
    bFastCollapseRunning = false
  end
  SoundOnSpinnableReachStart()
end
function OnSpinnableReachEnd()
  SoundOnSpinnableReachEnd()
end
function BtrFirstHit()
  if not btrVarFirst then
    btrVarFirst = true
    LD.CallFunctionAfterDelay(function()
      GameObjects.Riv325_HintBanter.LuaObjectScript.SinkingCeiling2_Banter()
    end, 0.75)
  end
end
function BtrUnlock()
  if not btrVarUnlock then
    btrVarUnlock = true
    StartLevelTimer(1, function()
      GameObjects.Riv325_HintBanter.LuaObjectScript.SinkingCeiling5_Banter()
    end)
  end
end
function BtrSinking()
  if GameObjects.SpikeCeiling.Child.AnimFrame > 320 and player:InsideZone(GameObjects.EntZn_InsideTrap) and not btrVarSinking then
    btrVarSinking = true
    StartLevelTimer(1, function()
      GameObjects.Riv325_HintBanter.LuaObjectScript.SinkingCeiling4_Banter()
    end)
  end
end
function BtrCloseCall()
  if GameObjects.SpikeCeiling.Child.AnimFrame <= 170 and player:InsideZone(GameObjects.EntZn_InsideTrap) and not btrVarClose then
    btrVarClose = true
    GameObjects.Riv325_HintBanter.LuaObjectScript.SinkingCeiling6_Banter()
  end
end
function BtrSquashed()
  if not btrVarSquashed then
    btrVarSquashed = true
    StartLevelTimer(1, function()
      GameObjects.Riv325_HintBanter.LuaObjectScript.SinkingCeiling6b_Banter()
    end)
  end
end
function LowerCieling()
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinFrame(0)
end
function FirstDoorHit()
  EnableFollowSpline()
end
function EnableFollowSpline()
  GameObjects.LTW_Intro_Follow.LuaObjectScript.Enable()
end
function SecondPanelHit()
  secondDoorHit = secondDoorHit + 1
  if secondDoorHit == 2 then
    GameObjects.ca_puzzled_01.LuaObjectScript.Enable()
  elseif secondDoorHit == 3 then
    GameObjects.CA_Riv_TouchSpikeTrap.LuaObjectScript.Disable()
    GameObjects.Scripted_SecondPanel:HideCollision()
  end
  if lastDoorHit == 0 and 3 <= secondDoorHit then
    GameObjects.CA_Riv_TippyToesPeer.LuaObjectScript.Enable()
  end
end
function CheckSecretPanel()
  if lastDoorHit == 0 and secondDoorHit < 3 then
    GameObjects.CA_Riv_TouchSpikeTrap.LuaObjectScript.Enable()
    GameObjects.CA_Riv_TippyToesPeer.LuaObjectScript.Enable()
    GameObjects.ca_puzzled_01.LuaObjectScript.Disable()
    GameObjects.ca_puzzled_02.LuaObjectScript.Enable()
  end
end
function CheckSecretChest()
  if lastDoorHit == 0 and secondDoorHit < 3 then
    GameObjects.CA_Riv_TippyToesPeer.LuaObjectScript.Enable()
  end
end
function ChestFound()
  GameObjects.EntZn_Disable_TippyToesCA:ShowEntityVolume()
end
function LastDoorOpening()
  GameObjects.CA_Riv_TippyToesPeer.LuaObjectScript.Disable()
  GameObjects.CA_Riv_TouchSpikeTrap.LuaObjectScript.Disable()
  lastDoorHit = lastDoorHit + 1
  if 3 <= lastDoorHit then
    exitOpen = true
    GameObjects.TraverseLink1:ShowTraverseLink()
    if Area_2_Encounter_1_Active then
      StartLevelTimer(0.25, function()
        GameObjects.Riv325_HintBanter.LuaObjectScript.SinkingCeiling10_Combat_Banter()
      end)
    else
      StartLevelTimer(0.25, function()
        GameObjects.Riv325_HintBanter.LuaObjectScript.SinkingCeiling10_Banter()
      end)
    end
    SonStartRunningCheck()
  end
end
function SonStartRunningCheck()
  if 3 <= lastDoorHit and sonEscapedTrap == false and GameObjects.SpikeCeiling.Child.AnimFrame > 80 then
    sonUnderTrap = true
    GameObjects.ca_combat_turret_02.LuaObjectScript.Enable()
    GameObjects.ca_combat_turret_01.LuaObjectScript.Interrupt()
    GameObjects.ca_combat_turret_01.LuaObjectScript.Disable()
    GameObjects.ca_puzzled_01.LuaObjectScript.Interrupt()
    GameObjects.ca_puzzled_01.LuaObjectScript.Disable()
    GameObjects.ca_puzzled_02.LuaObjectScript.Interrupt()
    GameObjects.ca_puzzled_02.LuaObjectScript.Disable()
    local availabilityState = {AvailableForCombat = false, Unoccupied = false}
    game.AI.FindSon():SetNewAvailabilityRequest("LevelDesignScript", availabilityState)
  end
end
function SonRunningUnderTrap()
  sonUnderTrap = true
  if GameObjects.SpikeCeiling.Child.AnimFrame <= 135 then
    GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-0.1)
    if kratosUnderTrap then
      GameObjects.TL_GapJump01:HideTraverseLink()
    end
  end
  GameObjects.CA_Riv_TouchSpikeTrap.LuaObjectScript.Disable()
  GameObjects.CA_Riv_TippyToesPeer.LuaObjectScript.Disable()
end
function SonExitTrap()
  sonUnderTrap = false
  if GameObjects.SpikeCeiling.Child.AnimFrame <= 140 then
    GameObjects.TL_GapJump01:HideTraverseLink()
  end
  CeilingStartRewind()
end
function SonFinishedTrapRun()
  sonEscapedTrap = true
  CeilingStartRewind()
  GameObjects.EntZn_SonClearedTrap:HideEntityVolume()
end
function EnableCielingLTW()
  GameObjects.LTW_Cieling_Lead.LuaObjectScript.Enable()
  GameObjects.LookFar_Forward.LuaObjectScript.Disable()
end
function DisableCielingLTW()
  GameObjects.LTW_Cieling_Lead.LuaObjectScript.Disable()
  GameObjects.LookFar_Forward.LuaObjectScript.Disable()
  GameObjects.ca_combat_turret_02.LuaObjectScript.Disable()
  GameObjects.ca_combat_turret_01.LuaObjectScript.Disable()
  GameObjects.ca_puzzled_01.LuaObjectScript.Disable()
end
function EnableTrapRevisit()
  GameObjects.LTW_Intro_Follow.LuaObjectScript.Disable()
  GameObjects.ca_puzzled_01.LuaObjectScript.Disable()
  GameObjects.ca_combat_turret_01.LuaObjectScript.Disable()
  GameObjects.ca_combat_turret_02.LuaObjectScript.Disable()
  GameObjects.LookFar_Forward.LuaObjectScript.Disable()
  GameObjects.LTW_Revisit.LuaObjectScript.Enable()
  GameObjects.CA_Revisit_End.LuaObjectScript.Enable()
  GameObjects.CA_Revisit_Start.LuaObjectScript.Enable()
  GameObjects.CA_Revisit_Done.LuaObjectScript.Enable()
  GameObjects.IdleContext_Nervous.LuaObjectScript.Enable()
  local monitor = LM.CreateLoadMonitor()
  monitor:AddCallback({
    Wads = {
      "Riv350_CalderaVista"
    },
    Functions = {
      TravPath_EnableRevisit
    }
  })
end
function PlayerNearTrapExit()
  GameObjects.LTW_Revisit.LuaObjectScript.Enable()
  GameObjects.CA_Revisit_End.LuaObjectScript.Enable()
  GameObjects.CA_Revisit_Start.LuaObjectScript.Enable()
  GameObjects.CA_Revisit_Done.LuaObjectScript.Enable()
end
function PlayerLeaveTrapExit()
  GameObjects.CA_Revisit_End.LuaObjectScript.Interrupt()
  GameObjects.CA_Revisit_End.LuaObjectScript.Disable()
  GameObjects.LTW_Revisit.LuaObjectScript.Disable()
end
function TravPath_EnableRevisit()
  local riv350 = game.FindLevel("Riv350_CalderaVista")
  riv350:CallScript("TravPath_EnableRevisit")
end
local SNDSpikeMain, SNDSpikeFloor, SNDSpikeGear
local sparkEmitters = {}
local debrisEmitters = {}
local trapEvents = {
  Sparks = "SND_MECH_Spike_Ceiling_Trap_Scrape_Sparks_LP",
  Debris = "SND_MECH_Spike_Ceiling_Trap_Debris_Individual_LP",
  LowerMain = "SND_MECH_Spike_Ceiling_Trap_Lower_Main_Movement_LP",
  RaiseMain = "SND_MECH_Spike_Ceiling_Trap_Raise_Main_Movement_LP",
  LowerGear = "SND_MECH_Spike_Ceiling_Trap_Lower_Gear_LP",
  RaiseGear = "SND_MECH_Spike_Ceiling_Trap_Raise_Gear_LP",
  FloorSpikes = "SND_MECH_Spike_Ceiling_Trap_Floor_Spikes_Raise_LP",
  HitRoof = "SND_MECH_Spike_Ceiling_Trap_Hit_Roof",
  HitGround = "SND_MECH_Spike_Ceiling_Trap_Hit_Ground"
}
local ceilingLowerSoundDelay = 1.8
function SoundInit()
  SNDSpikeMain = GameObjects.SNDGrpTrapMain:FindSingleSoundEmitterByName("SNDSpikeCieling01")
  SNDSpikeFloor = GameObjects.SNDGrpSpikeFloor:FindSingleSoundEmitterByName("SNDSpikeFloor")
  SNDSpikeGear = GameObjects.SNDGrpTrapGear:FindSingleSoundEmitterByName("SNDSpikeTrapGear")
  sparkEmitters = GameObjects.SNDSparkGroup.SoundEmitters
  debrisEmitters = GameObjects.SNDDebrisGroup.SoundEmitters
end
function SoundOnRewindSpinnable()
  GameObjects.SpinnableGears1.LuaObjectScript.StopOnCWRotateSound()
  GameObjects.SpinnableGears2.LuaObjectScript.StopOnCWRotateSound()
  GameObjects.SpinnableGears1.LuaObjectScript.PlayOnCCWRotateSound()
  GameObjects.SpinnableGears2.LuaObjectScript.PlayOnCCWRotateSound()
  LD.StopSound(SNDSpikeMain, trapEvents.RaiseMain, true)
  LD.StopSound(SNDSpikeGear, trapEvents.RaiseGear, true)
  LD.PlaySound(SNDSpikeMain, trapEvents.LowerMain, true)
  LD.PlaySound(SNDSpikeGear, trapEvents.LowerGear, true)
  PlaySoundSparksDebris()
end
function SoundOnAddImpulseSpinnable()
  if GameObjects.SpikeCeiling.Child.AnimFrame < GameObjects.SpikeCeiling.Child.AnimLengthFrames then
    GameObjects.SpinnableGears1.LuaObjectScript.StopOnCCWRotateSound()
    GameObjects.SpinnableGears2.LuaObjectScript.StopOnCCWRotateSound()
    GameObjects.SpinnableGears1.LuaObjectScript.PlayOnCWRotateSound()
    GameObjects.SpinnableGears2.LuaObjectScript.PlayOnCWRotateSound()
    LD.StopSound(SNDSpikeMain, trapEvents.LowerMain, true)
    LD.StopSound(SNDSpikeGear, trapEvents.LowerGear, true)
    LD.PlaySound(SNDSpikeMain, trapEvents.RaiseMain, true)
    LD.PlaySound(SNDSpikeGear, trapEvents.RaiseGear, true)
    StopSoundSparksDebris()
    PlaySoundSparksDebris()
    LD.CallFunctionAfterDelay(StopSoundSparksDebris, 1.3)
  end
end
function SoundOnSpinnableStop()
  GameObjects.SpinnableGears1.LuaObjectScript.StopOnCWRotateSound()
  GameObjects.SpinnableGears2.LuaObjectScript.StopOnCWRotateSound()
  GameObjects.SpinnableGears1.LuaObjectScript.StopOnCCWRotateSound()
  GameObjects.SpinnableGears2.LuaObjectScript.StopOnCCWRotateSound()
  LD.StopSound(SNDSpikeMain, trapEvents.LowerMain, true)
  LD.StopSound(SNDSpikeGear, trapEvents.LowerGear, true)
  LD.StopSound(SNDSpikeMain, trapEvents.RaiseMain, true)
  LD.StopSound(SNDSpikeGear, trapEvents.RaiseGear, true)
  StopFloorSpikeLoop()
  StopSoundSparksDebris()
end
function SoundOnSpinnableReachEnd()
  SoundOnSpinnableStop()
  LD.PlaySound(SNDSpikeMain, trapEvents.HitRoof, true)
end
function SoundOnSpinnableReachStart()
  SoundOnSpinnableStop()
  LD.PlaySound(SNDSpikeMain, trapEvents.HitGround, true)
end
function PlaySoundSparksDebris()
  for i = 1, #sparkEmitters do
    LD.PlaySound(sparkEmitters[i], trapEvents.Sparks, true)
  end
  for i = 1, #debrisEmitters do
    LD.PlaySound(debrisEmitters[i], trapEvents.Debris, true)
  end
end
function StopSoundSparksDebris()
  for i = 1, #sparkEmitters do
    LD.StopSound(sparkEmitters[i], trapEvents.Sparks, true)
  end
  for i = 1, #debrisEmitters do
    LD.StopSound(debrisEmitters[i], trapEvents.Debris, true)
  end
end
function PlayFloorSpikeLoop()
  LD.PlaySound(SNDSpikeFloor, trapEvents.FloorSpikes, true)
end
function StopFloorSpikeLoop()
  LD.StopSound(SNDSpikeFloor, trapEvents.FloorSpikes, true)
end
function OnSaveCheckpoint(level)
  return {
    levelstate = checkpoint.Save(),
    tripleChestOpened = tripleChestOpened,
    exitOpen = exitOpen,
    bEscapedTrapRoom = bEscapedTrapRoom,
    lastDoorHit = lastDoorHit,
    gnome2Broken = gnome2Broken,
    sonEscapedTrap = sonEscapedTrap,
    secondDoorHit = secondDoorHit
  }
end
function OnRestoreCheckpoint(level, savedInfo)
  checkpoint.Restore(savedInfo.levelstate)
  tripleChestOpened = savedInfo.tripleChestOpened
  exitOpen = savedInfo.exitOpen
  bEscapedTrapRoom = savedInfo.bEscapedTrapRoom
  gnome2Broken = savedInfo.gnome2Broken
  sonEscapedTrap = savedInfo.sonEscapedTrap
  lastDoorHit = savedInfo.lastDoorHit or 0
  secondDoorHit = savedInfo.secondDoorHit
end
