local LD = require("design.LevelDesignLibrary")
local timer = require("level.timer")
local monitors = require("level.MonitorLibrary")
local EC = require("design.Encounter")
local uiCalls = require("ui.uicalls")
local checkpoint = require("level.checkpoint")
local actor = require("narrative.actor")
local sonPup, syncPos, syncDir, switchParams
local latchUnlocked = false
local showerSparks = false
local selectedTarget, GnomePOS_1, GnomePOS_2, GnomePOS_3, runic_breakable_01, cageGnome
local gnomeValid = false
local inGnomeZone = false
local thisLevel
local player = game.Player.FindPlayer()
local kratosActor, sonActor
local pad = player.Pad
local buttonMaskingON
bottomTNFCompleted = false
crankLockFrame_MiddleReached = false
crankLockFrame_TopReached = false
local camBoatReleaseTimer = timer.StartLevelTimer(36)
local msg0 = false
local msg1 = false
local msg2 = false
local msg3 = false
local msg4 = false
local msg5 = false
local msg6 = false
camBoatReleaseTimer:Stop()
local drivenObjSail, camSyncedToSail
local skipIdle01 = false
local skipIdle02 = false
local skipIdle03 = false
local DidIdle01 = false
local DidIdle02 = false
local DidIdle03 = false
local bUsePushInCamera_Idle01 = false
local bUsePushInCamera_Idle02 = false
local bUsePushInCamera_Idle03 = false
function OnScriptLoaded(level, obj)
  thisLevel = level
  player = game.Player.FindPlayer()
  sonActor = game.AI.FindSon()
  player = game.Player.FindPlayer()
  GameObjects.LiftDoor_Tower_StaysOpen2.LuaObjectScript.ExcludeSon()
  GameObjects.sonHallucinationProp1:Hide()
  cageGnome = GameObjects.runic_breakable_03.Child
  GameObjects.WheelCrank_HelheimShip.LuaObjectScript.OverrideCameraInteractApproach("PLYR_Crank_HelBridgeBreak")
  GameObjects.WheelCrank_HelheimShip.LuaObjectScript.OverrideDefaultCameraRecenter(true, {YawRange = 360, PitchRange = 90})
  GameObjects.StraightCrank_AttachPoint.LuaObjectScript.OverrideCameraInteractApproach("ENV_Crank_Approach_HelR_Puzzle03")
  GameObjects.StraightCrank_AttachPoint.LuaObjectScript.OverrideDefaultCameraRecenter(true, {YawRange = 360, PitchRange = 90})
  GameObjects.StraightCrank_AttachPoint.LuaObjectScript.OverrideDefaultCameraYaw(true, 141)
  GameObjects.bgShip:PlayAnimToEnd(0.15)
  GameObjects.bgShip2:PlayAnimToEnd(0.15)
  SoundInit()
end
function OnFirstStart(level)
  GameObjects.T_PathDocksSecret:HideTraversePath()
  GameObjects.TraversePath_Cave:HideTraversePath()
  VisOffTLink()
  GameObjects.TraversePath16:HideTraversePath()
  GameObjects.Tower4_MoveSonForTNF:HideEntityVolume()
  GnomePOS_1 = GameObjects.GnomePOS_1
  GnomePOS_2 = GameObjects.GnomePOS_2
  GnomePOS_3 = GameObjects.GnomePOS_3
  runic_breakable_01 = GameObjects.runic_breakable_01
  selectedTarget = math.random(1, 3)
  print(selectedTarget)
  if selectedTarget == 1 then
    runic_breakable_01:SetWorldPosition(GnomePOS_1:GetWorldPosition())
    runic_breakable_01:SetWorldFacing(GnomePOS_1:GetWorldForward())
  elseif selectedTarget == 2 then
    runic_breakable_01:SetWorldPosition(GnomePOS_2:GetWorldPosition())
    runic_breakable_01:SetWorldFacing(GnomePOS_2:GetWorldForward())
  else
    runic_breakable_01:SetWorldPosition(GnomePOS_3:GetWorldPosition())
    runic_breakable_01:SetWorldFacing(GnomePOS_3:GetWorldForward())
  end
  cageGnome:HideCollision()
  cageGnome:HideBehaviors()
  GnomeValidZoneOFF()
  GameObjects.GnomeAxeTarget:HideCollision()
end
function InitializeVariables()
  kratosActor = actor.Actor.New("Kratos", game.Player.FindPlayer)
  sonActor = actor.Actor.New("Son", game.AI.FindSon)
end
function OnStart(level)
  if cageGnome ~= nil then
    GameObjects.GnomeAxeTarget.LuaObjectScript.RegisterOnWeaponEmbed(MakeCageGnomeValid)
    GameObjects.GnomeAxeTarget.LuaObjectScript.RegisterOnWeaponUnembed(MakeCageGnomeInvalidDelay)
  end
  OnStart_SpinnableElevator()
  LD.BreakObject(GameObjects.pillar_ice_sky_break)
  player:CallScript("EnableColdIdle")
  SoundOnStart()
  if gnomeValid == true then
    MakeCageGnomeValid()
  else
    MakeCageGnomeInvalid()
  end
  InitializeVariables()
  if buttonMaskingON == true then
    ButtonMasking()
  end
  if buttonMaskingON == false then
    ButtonMaskingOff()
  end
  GameObjects.LiftDoor_Tower_StaysOpen2.LuaObjectScript.ExcludeSon()
end
function OnUpdate(level)
  if engine.IsDebug() then
    local d = {}
    table.insert(d, {
      "Elevator Frame",
      tostring(GameObjects.Elevator.AnimFrame)
    })
    engine.DrawDebugTable(d)
  end
  if game.World.IsInsideCameraZone(player.WorldPosition, "CamZone_DoorLiftExit") == true and player:IsPlayingMove("MOV_LiftDoor") == true and player:GetActiveMovePercent() > 0.4 then
    game.Camera.SubmitCameraByName("PLYR_HelR100_DoorExit")
  end
  if bUsePushInCamera_Idle01 == true and game.World.IsInsideCameraZone(player.WorldPosition, "CamZone_T3_BaldurSequence_10") == true then
    game.Camera.SubmitCameraByName("PLYR_CrackClimb_Vista_Baldur_Cam1_PushIn")
  end
  if bUsePushInCamera_Idle02 == true and game.World.IsInsideCameraZone(player.WorldPosition, "CamZone_T3_BaldurSequence_40") == true then
    game.Camera.SubmitCameraByName("PLYR_CrackClimb_Vista_Baldur_Cam2_PushIn")
  end
  if bUsePushInCamera_Idle03 == true and game.World.IsInsideCameraZone(player.WorldPosition, "CamZone_T3_BaldurSequence_60") == true then
    game.Camera.SubmitCameraByName("PLYR_CrackClimb_Vista_Baldur_Cam3_PushIn")
  end
end
function OnUseWorld(level)
end
function HideFakeRunic()
  GameObjects.FakeRunic:Hide()
end
function KillLights()
  GameObjects.SmLight1:Hide()
  GameObjects.lightHighlightZone:HideEntityVolume()
end
function BreakIceBerg_HelR100()
  LD.BreakObject(GameObjects.HelIceSpikeBreak_spike_03_break)
  PlayShakes_IcebergCollapse()
end
function PlayShakes_IcebergCollapse()
  timer.StartLevelTimer(3.4, function()
    game.Blender.Trigger({
      Name = "FSE_SHAKE_GENERIC_GIANT",
      Duration = 0.8,
      TweenIn = {Time = 0.3},
      TweenOut = {Time = 0.3},
      Priority = 3
    })
    game.Blender.Trigger({
      Name = "FFB_LARGE",
      Duration = 0.8,
      TweenIn = {Time = 0.3},
      TweenOut = {Time = 0.3},
      Priority = 3
    })
  end)
  timer.StartLevelTimer(3.8, function()
    game.Blender.Trigger({
      Name = "FSE_SHAKE_TREMORS_LEVEL_0",
      Duration = 2.6,
      TweenIn = {Time = 0.2},
      TweenOut = {Time = 0.3},
      Priority = 5
    })
    game.Blender.Trigger({
      Name = "FFB_LOOP_SMALL",
      Duration = 2.6,
      TweenIn = {Time = 0.2},
      TweenOut = {Time = 0.3},
      Priority = 5
    })
  end)
  timer.StartLevelTimer(6.2, function()
    game.Blender.Trigger({
      Name = "FSE_SHAKE_GENERIC_SMALL",
      Duration = 0.6,
      TweenIn = {Time = 0.2},
      TweenOut = {Time = 1},
      Priority = 5
    })
    game.Blender.Trigger({
      Name = "FFB_GENERIC_RUMBLE_LOW",
      Duration = 0.6,
      TweenIn = {Time = 0.2},
      TweenOut = {Time = 1},
      Priority = 5
    })
  end)
  timer.StartLevelTimer(7.5, function()
    game.Blender.Trigger({
      Name = "FSE_SHAKE_GENERIC_SMALL",
      Duration = 0.6,
      TweenIn = {Time = 0.2},
      TweenOut = {Time = 0.5},
      Priority = 6
    })
    game.Blender.Trigger({
      Name = "FFB_GENERIC_RUMBLE_LOW",
      Duration = 0.6,
      TweenIn = {Time = 0.2},
      TweenOut = {Time = 0.5},
      Priority = 6
    })
  end)
end
function KidRescue()
  GameObjects.KidRescue:Hide()
  GameObjects.KidRubble:PlayAnimToEnd()
  AddScreenShake()
  SonMessage()
end
function HelBridgeDocks()
  LD.BreakObject(GameObjects.HelBridgeSmallBreak)
  GameObjects.sonHallucinationProp1:Show()
  LD.CallFunctionAfterDelay(function()
    GameObjects.sonHallucinationProp1:Hide()
  end, 0.1)
  PlayBridgeBreakSound()
  timer.StartLevelTimer(0, function()
    game.Blender.Trigger({
      Name = "FSE_SHAKE_GENERIC_MEDIUM",
      Duration = 2.2,
      TweenIn = {Time = 0.3},
      TweenOut = {Time = 0.8},
      Priority = 5
    })
  end)
  timer.StartLevelTimer(0, function()
    game.Blender.Trigger({
      Name = "FFB_GENERIC_RUMBLE_MEDIUM",
      Duration = 2.2,
      TweenIn = {Time = 0},
      TweenOut = {Time = 0.8},
      Priority = 1
    })
  end)
end
function ShowSecretTPath()
  GameObjects.T_PathDocksSecret:ShowTraversePath()
end
function T_PathShowSecretCave()
  GameObjects.TraversePath_Cave:ShowTraversePath()
end
function EnableCagePushBlock()
  GameObjects.StraightCrank_AttachPointCage.LuaObjectScript.Enable()
end
function IncrementSecret()
  LD.SetEntityVariable("HEL_Secret", LD.GetEntityVariable("HEL_Secret") + 1)
end
function BreakDrawBridge()
  LD.BreakObject(GameObjects.AnimBridge)
end
function VisOffTLink()
  GameObjects.T_LinkHiddenJump:Hide()
end
function VisOnTLink()
  GameObjects.T_LinkHiddenJump:Show()
end
function StartBaldurPath()
  timer.StartLevelTimer(40, SkipIdleOne)
  timer.StartLevelTimer(90, SkipIdleTwo)
  timer.StartLevelTimer(125, SkipIdleThree)
  ButtonMasking()
  game.Compass.SetDesignerForcedHide(true)
end
function SkipIdleOne()
  skipIdle01 = true
  print("idle NO 1")
  if DidIdle01 == false then
    GameObjects.CamZone_T3_BaldurSequence_10:HideCameraVolume()
    bUsePushInCamera_Idle01 = false
    print("hide camera zone10")
  end
end
function SkipIdleTwo()
  skipIdle02 = true
  print("idle NO 2")
  if DidIdle02 == false then
    GameObjects.CamZone_T3_BaldurSequence_40:HideCameraVolume()
    bUsePushInCamera_Idle02 = false
    print("hide camera zone40")
  end
end
function SkipIdleThree()
  skipIdle03 = true
  print("idle NO 3")
  if DidIdle03 == false then
    GameObjects.CamZone_T3_BaldurSequence_60:HideCameraVolume()
    bUsePushInCamera_Idle03 = false
    print("hide camera zone60")
  end
end
function Idle00()
  game.UI.Idle(true)
  uiCalls.UI_Event_DiscoverLocation("Helheim Docks")
  timer.StartLevelTimer(6, function()
    game.UI.Idle(false)
  end)
  LD.CallFunctionAfterDelay(function()
    game.Audio.PlayBanter("020_FromHel_02")
  end, 3)
end
function Idle01()
  if skipIdle01 == false then
    local fPushInCameraDelay_Idle01 = 3.2
    timer.StartLevelTimer(fPushInCameraDelay_Idle01, function()
      bUsePushInCamera_Idle01 = true
    end)
    game.UI.Idle(true)
    timer.StartLevelTimer(25, function()
      game.UI.Idle(false)
      GameObjects.CamZone_T3_BaldurSequence_10:HideCameraVolume()
      bUsePushInCamera_Idle01 = false
    end)
    DidIdle01 = true
  end
end
function ClimbWallPeekOverEnter02()
  local cineSeq = LD.CreateCineSequence(thisLevel, GameObjects.idleZone_2, "ClimbWallPeekOverEnter02")
  local cineSeq_ActorTable = {
    {
      Actor = sonActor,
      Branch = "BRA_Peak740_ClimbWallPeekOverEnter"
    }
  }
  cineSeq:WaitForFunctionTrue(function()
    return player:IsPlayingMove("MOV_Crack_Climb_H_Right_Start_Forward") or player:IsPlayingMove("MOV_Crack_Climb_H_Right_Forward")
  end)
  cineSeq:ActorSync(kratosActor, {
    Slaves = cineSeq_ActorTable,
    Branch = "BRA_Peak740_ClimbWallPeekOverEnter",
    ReferenceJoint = "idle02_Sync"
  })
  cineSeq:WaitForActorFinishMove(kratosActor, "MOV_Peak740_ClimbWallPeekOverEnter")
  cineSeq:StopPuppetingActor(kratosActor)
  cineSeq:StopPuppetingActor(sonActor)
  cineSeq:StartSequence()
end
function ClimbWallPeekOverExit02()
  local cineSeq = LD.CreateCineSequence(thisLevel, GameObjects.idleZone_2, "ClimbWallPeekOverExit02")
  local cineSeq_ActorTable = {
    {
      Actor = sonActor,
      Branch = "BRA_Peak740_ClimbWallPeekOverExit"
    }
  }
  cineSeq:WaitForFunctionTrue(function()
    return player:IsPlayingMove("MOV_Peak740_ClimbWallPeekOverIdle") or player:IsPlayingMove("MOV_Peak740_ClimbWallPeekOverIdle")
  end)
  cineSeq:ActorSync(kratosActor, {
    Slaves = cineSeq_ActorTable,
    Branch = "BRA_Peak740_ClimbWallPeekOverExit",
    ReferenceJoint = "idle02_Sync"
  })
  cineSeq:WaitForActorFinishMove(kratosActor, "MOV_Peak740_ClimbWallPeekOverExit")
  cineSeq:StopPuppetingActor(kratosActor)
  cineSeq:StopPuppetingActor(sonActor)
  cineSeq:StartSequence()
end
function Idle02()
  if skipIdle02 == false then
    local fPushInCameraDelay_Idle02 = 3.2
    timer.StartLevelTimer(fPushInCameraDelay_Idle02, function()
      bUsePushInCamera_Idle02 = true
    end)
    game.UI.Idle(true)
    ClimbWallPeekOverEnter02()
    timer.StartLevelTimer(35, function()
      game.UI.Idle(false)
      GameObjects.CamZone_T3_BaldurSequence_40:HideCameraVolume()
      ClimbWallPeekOverExit02()
      bUsePushInCamera_Idle02 = false
    end)
    DidIdle02 = true
  end
end
function ClimbWallPeekOverEnter03()
  local cineSeq = LD.CreateCineSequence(thisLevel, GameObjects.idleZone_3, "ClimbWallPeekOverEnter03")
  local cineSeq_ActorTable = {
    {
      Actor = sonActor,
      Branch = "BRA_Peak740_ClimbWallPeekOverEnter"
    }
  }
  cineSeq:WaitForFunctionTrue(function()
    return player:IsPlayingMove("MOV_Crack_Climb_H_Right_Start_Forward") or player:IsPlayingMove("MOV_Crack_Climb_H_Right_Forward")
  end)
  cineSeq:ActorSync(kratosActor, {
    Slaves = cineSeq_ActorTable,
    Branch = "BRA_Peak740_ClimbWallPeekOverEnter",
    ReferenceJoint = "idle03_Sync"
  })
  cineSeq:WaitForActorFinishMove(kratosActor, "MOV_Peak740_ClimbWallPeekOverEnter")
  cineSeq:StopPuppetingActor(kratosActor)
  cineSeq:StopPuppetingActor(sonActor)
  cineSeq:StartSequence()
end
function ClimbWallPeekOverExit03()
  local cineSeq = LD.CreateCineSequence(thisLevel, GameObjects.idleZone_3, "ClimbWallPeekOverExit03")
  local cineSeq_ActorTable = {
    {
      Actor = sonActor,
      Branch = "BRA_Peak740_ClimbWallPeekOverExit"
    }
  }
  cineSeq:WaitForFunctionTrue(function()
    return player:IsPlayingMove("MOV_Peak740_ClimbWallPeekOverIdle") or player:IsPlayingMove("MOV_Peak740_ClimbWallPeekOverIdle")
  end)
  cineSeq:ActorSync(kratosActor, {
    Slaves = cineSeq_ActorTable,
    Branch = "BRA_Peak740_ClimbWallPeekOverExit",
    ReferenceJoint = "idle03_Sync"
  })
  cineSeq:WaitForActorFinishMove(kratosActor, "MOV_Peak740_ClimbWallPeekOverExit")
  cineSeq:StopPuppetingActor(kratosActor)
  cineSeq:StopPuppetingActor(sonActor)
  cineSeq:StartSequence()
end
function Idle03()
  if skipIdle03 == false then
    local fPushInCameraDelay_Idle03 = 3.6
    timer.StartLevelTimer(fPushInCameraDelay_Idle03, function()
      bUsePushInCamera_Idle03 = true
    end)
    game.UI.Idle(true)
    ClimbWallPeekOverEnter03()
    timer.StartLevelTimer(30, function()
      game.UI.Idle(false)
      GameObjects.CamZone_T3_BaldurSequence_60:HideCameraVolume()
      ClimbWallPeekOverExit03()
      bUsePushInCamera_Idle03 = false
    end)
    DidIdle03 = true
  end
end
function ButtonMasking()
  print("button masking")
  buttonMaskingON = true
  pad:DisableGameButton(tweaks.ePad.kPadCircle)
end
function ButtonMaskingOff()
  print("button masking off")
  buttonMaskingON = false
  pad:EnableGameButton(tweaks.ePad.kPadCircle)
end
function ButtonMaskingDisable()
  print("button masking off")
  buttonMaskingON = false
  pad:EnableGameButton(tweaks.ePad.kPadCircle)
  GameObjects.buttonMaskingOn:HideEntityVolume()
  GameObjects.buttonMaskingOff:HideEntityVolume()
  game.Compass.SetDesignerForcedHide(false)
end
function Objective100_Quest()
  print("Helheim Parent no longer exists")
end
function Objective300_Quest()
  LD.CompleteQuest("Quest_Helheim_Objective100")
end
function TNF_BreakMastPlatform()
  GameObjects.LockGroup:PlayAnimToEnd()
  GameObjects.breakableCubes:JumpAnimToFrame(440)
  GameObjects.breakableCubes:PlayAnimToEnd()
end
function UnlockBoatChain()
  GameObjects.boat:PlayAnimToEnd(0.25)
  GameObjects.lock4Chain:Hide()
  GameObjects.VolumetricFog1:PlayAnimToEnd()
end
function TryClamp()
  GameObjects.SailsAnim:JumpAnimToFrame(50)
  GameObjects.SailsAnim:PlayAnimToFrame(55)
  LD.CallFunctionAfterDelay(function()
    GameObjects.SailsAnim:PlayAnimToFrame(0, -2)
  end, 1)
end
function MastBladeInteract()
  GameObjects.WheelCrank1.LuaObjectScript.Unlock()
  GameObjects.mastBlocker:Hide()
  GameObjects.clamp:Hide()
  GameObjects.SailsAnim:PlayAnimToFrame(160, 1)
  GameObjects.boat:PlayAnimToFrame(70, 0.5)
  LD.CallFunctionAfterDelay(function()
    GameObjects.boat:PlayAnimToFrame(60, -2)
    GameObjects.SailsAnim:PlayAnimToFrame(155, -1)
  end, 1)
  bottomTNFCompleted = true
end
function UnlockLatch()
  GameObjects.WheelCrank1.LuaObjectScript.Unlock()
end
function DelayedCrankLogic()
  game.Level.SetVariable("showerSparks", false)
  GameObjects.boat:PlayAnimToFrame(120, 0.25)
end
function CollisionWallsON()
  GameObjects.Cart:FindSingleGOByName("CDS"):PlayAnimToEnd()
end
function LiftGateMemory1()
  Memory2Message()
  game.Level.SetVariable("Memory2Go", true)
  game.Compass.SetDesignerForcedHide(true)
end
function LiftGateMemory2()
  Memory2Message()
  game.Level.SetVariable("MemoryBGo", true)
end
function Memory2Message()
  if msg2 == false then
    GameObjects.POI_PastHauntsSon.LuaObjectScript.SetupPOISequence()
    msg2 = true
  end
end
function EndDemoMessage()
  if msg5 == false then
    uiCalls.UI_Event_SendDesignerMessage("The Son and Kratos fly away on the boat. THIS CONCLUDES THE PLAYTEST!!! You are a winner.", 20)
    msg5 = true
  end
end
function CheckPoint()
  game.World.StoreCheckpoint()
end
function Trigger_Tower2PuzzleBottom()
  GameObjects.ContextAction_Son_UnderDocks.LuaObjectScript.Disable()
  GameObjects.ContextAction_Son_Idle_Bored.LuaObjectScript.Enable()
  GameObjects.CA_SyncExitHelperTower2.LuaObjectScript.Enable()
end
function Trigger_SonPuzzle_Tower2()
  GameObjects.ContextAction_Son_Idle_Bored.LuaObjectScript.Enable()
  GameObjects.ContextAction_Son_UnderDocks.LuaObjectScript.Disable()
end
function TriggerLeadTheWay_Tower2()
  GameObjects.CA_Point_Forward.LuaObjectScript.Enable()
  GameObjects.CA_Observe_Forward_Tower2Back.LuaObjectScript.Disable()
  GameObjects.ContextAction_Son_Idle_Bored.LuaObjectScript.Disable()
  GameObjects.ContextAction_Son_Idle_AfterTraveler.LuaObjectScript.Disable()
  GameObjects.CA_SyncExitHelper.LuaObjectScript.Enable()
  GameObjects.LeadTheWay2.LuaObjectScript.Enable()
  GameObjects.LeadTheWay3.LuaObjectScript.Enable()
  GameObjects.StraightCrank_AttachPoint.LuaObjectScript.Disable()
end
function TriggerLeadTheWay_Tower2OFF()
  GameObjects.CA_Point_Forward.LuaObjectScript.Disable()
  GameObjects.CA_Observe_Forward_Tower2Back.LuaObjectScript.Enable()
  GameObjects.StraightCrank_AttachPoint.LuaObjectScript.Enable()
end
function EnterBaldurClimb()
  GameObjects.ContextAction_Son_Idle_AfterTraveler.LuaObjectScript.Disable()
  GameObjects.LeadTheWay2.LuaObjectScript.Disable()
  GameObjects.LeadTheWay3.LuaObjectScript.Disable()
end
function AvoidClimbOn()
  GameObjects.CA_Tower1_AvoidClimb.LuaObjectScript.Enable()
  GameObjects.ContextAction_Son_ObserveForward_Tower1.LuaObjectScript.Disable()
end
function AvoidClimbOff()
  GameObjects.CA_Tower1_AvoidClimb.LuaObjectScript.Disable()
  GameObjects.ContextAction_Son_ObserveForward_Tower1.LuaObjectScript.Enable()
end
function MakeSonUnavailabe()
  local availabilityState = {AvailableForSync = false}
  game.AI.FindSon():SetNewAvailabilityRequest("LevelDesignScript", availabilityState)
end
function MakeSonAvailable()
  game.AI.FindSon():RemoveAvailabilityRequest("LevelDesignScript")
end
function Trigger_ContextTower1()
  GameObjects.ContextAction_Son_ObserveForward_Tower1.LuaObjectScript.Enable()
end
function Trigger_ContextTower2()
  GameObjects.contextaction_son_inspect_observe_down_Tower2.LuaObjectScript.Enable()
end
function Trigger_ContextTower3()
  GameObjects.ContextAction_Son_ObserveForward_Tower3.LuaObjectScript.Enable()
end
function Trigger_ContextTowerTripChest()
  GameObjects.ContextAction_Son_ObserveForward_TripChest.LuaObjectScript.Enable()
end
function Trigger_ObserveFWD_Tower2Back()
  GameObjects.CA_Observe_Forward_Tower2Back.LuaObjectScript.Enable()
end
function Trigger_ContextAfterTraveler()
  GameObjects.ContextAction_Son_Idle_AfterTraveler.LuaObjectScript.Enable()
end
function TriggerObserveFWD_Docks()
  GameObjects.CA_Observe_ForwardDock.LuaObjectScript.Enable()
  GameObjects.LeadTheWayStayNear.LuaObjectScript.Enable()
  GameObjects.LeadTheWay.LuaObjectScript.Disable()
  GameObjects.ContextAction_Son_NoCave.LuaObjectScript.Disable()
end
function LeadTheWayTower1_On()
  GameObjects.LeadTheWay.LuaObjectScript.Enable()
end
function TriggerBuddyDrop()
  GameObjects.ContextAction_Son_NoCave.LuaObjectScript.Enable()
end
function Trigger_ContextTowerTripChestOFF()
  GameObjects.ContextAction_Son_ObserveForward_TripChest.LuaObjectScript.Disable()
end
function Trigger_ContextTowerOneOFF()
  GameObjects.ContextAction_Son_ObserveForward_Tower1.LuaObjectScript.Disable()
end
function Trigger_ObserveFWD_Tower2BackOFF()
  GameObjects.CA_Observe_Forward_Tower2Back.LuaObjectScript.Disable()
end
function TriggerObserveFWD_DocksOFF()
  GameObjects.CA_Observe_ForwardDock.LuaObjectScript.Disable()
end
function TriggerBuddyDropOFF()
  GameObjects.ContextAction_Son_NoCave.LuaObjectScript.Disable()
end
function TurnOffTriggerTower3()
  GameObjects.TriggerTower3_SonObserveFWD1:HideEntityVolume()
end
function HideAllDocksCA()
  GameObjects.LeadTheWayStayNear.LuaObjectScript.Disable()
  GameObjects.LeadTheWay.LuaObjectScript.Disable()
end
function MoveSonForTNF_Hel100()
  local helR300 = game.FindLevel("HelR300_HelShip")
  if helR300 ~= nil then
    local shipScript = helR300:FindSingleGameObject("HelheimShipScript")
    if shipScript ~= nil then
      shipScript:CallScript("MoveSonForTNF")
    end
  end
end
function MakeCageGnomeValid()
  if cageGnome == nil then
    return
  end
  cageGnome:ShowCollision()
  cageGnome:ShowBehaviors()
  gnomeValid = true
end
function MakeCageGnomeInvalid()
  if cageGnome == nil then
    return
  end
  if inGnomeZone == false then
    cageGnome:HideCollision()
    cageGnome:HideBehaviors()
    gnomeValid = false
  end
end
function MakeCageGnomeInvalidDelay()
  if cageGnome == nil then
    return
  end
  LD.CallFunctionAfterDelay(function()
    MakeCageGnomeInvalid()
  end, 0.5)
end
function GnomeValidZoneON()
  print("gnome zones on")
  GameObjects.GnomeAxeTarget:ShowCollision()
  GameObjects.GnomeCollisionNoEmbed:HideCollision()
  GameObjects.GnomeValidZone:Show()
end
function GnomeValidZoneOFF()
  print("gnome zones off")
  GameObjects.GnomeAxeTarget:HideCollision()
  GameObjects.GnomeCollisionNoEmbed:ShowCollision()
  GameObjects.GnomeValidZone:Hide()
end
function InGnomeZone()
  inGnomeZone = true
end
function OutGnomeZone()
  inGnomeZone = false
end
function CheckPoint()
  game.World.StoreCheckpoint()
end
function SonMessage()
  if msg6 == false then
    msg6 = true
  end
end
function EnableReturnTower3()
  GameObjects.Tower3_ReturnPath:ShowTraversePath()
end
function HideReturnClimb()
  GameObjects.Tower3_ReturnPath:HideTraversePath()
end
function AddScreenShake()
  local shakeParams = {
    EffectName = "FSE_shake_temp_Generic_Large",
    Duration = 0.1
  }
  game.FX.SubmitEffect(shakeParams)
end
function AxeTargetActivateFront()
  game.Level.SetVariable("AxeTarget_Front", true)
end
function AxeTargetActivateBack()
  game.Level.SetVariable("AxeTarget_Back", true)
end
function AxeTargetActivateSecret()
  game.Level.SetVariable("AxeTarget_Secret", true)
end
function AxeTargetActivateR()
  game.Level.SetVariable("AxeTarget_R", true)
end
function AxeTargetActivateL()
  game.Level.SetVariable("AxeTarget_L", true)
end
local spikeTrapMonitor, elevatorCombatCollisionScript
local underElevatorCount = 0
function OnStart_SpinnableElevator()
  elevatorCombatCollisionScript = GameObjects.Elevator:FindSingleGOByName("CombatCollision")
  local elevatorMonitor = monitors.CreateAnimFrameMonitor(GameObjects.Elevator)
  elevatorMonitor:OnFrameForward(160, function()
    GameObjects.TraverseLink1m:HideTraverseLink()
    GameObjects.TraverseLink2m:HideTraverseLink()
  end)
  elevatorMonitor:OnFrameForward(180, function()
    GameObjects.TraverseLink1m:ShowTraverseLink()
    GameObjects.TraverseLink2m:HideTraverseLink()
  end)
  elevatorMonitor:OnFrameForward(200, function()
    GameObjects.TraverseLink1m:HideTraverseLink()
    GameObjects.TraverseLink2m:HideTraverseLink()
  end)
  elevatorMonitor:OnFrameBackward(200, function()
    GameObjects.TraverseLink1m:ShowTraverseLink()
    GameObjects.TraverseLink2m:HideTraverseLink()
  end)
  elevatorMonitor:OnFrameBackward(180, function()
    GameObjects.TraverseLink1m:HideTraverseLink()
    GameObjects.TraverseLink2m:ShowTraverseLink()
  end)
  elevatorMonitor:OnFrameBackward(160, function()
    GameObjects.TraverseLink1m:HideTraverseLink()
    GameObjects.TraverseLink2m:HideTraverseLink()
  end)
  spikeTrapMonitor = monitors.CreateAnimFrameMonitor(GameObjects.Elevator)
  spikeTrapMonitor:OnFrameBackward(110, CeilingSlowdown01)
  spikeTrapMonitor:OnFrameBackward(100, CeilingSlowdown02)
  spikeTrapMonitor:OnFrameBackward(90, CeilingSlowdown03)
  spikeTrapMonitor:OnFrameBackward(85, CeilingSlowdown04)
  spikeTrapMonitor:OnFrameBackward(70, CeilingDead)
  spikeTrapMonitor:OnFrameBackward(30, function()
    elevatorCombatCollisionScript.LuaObjectScript.Enable()
  end)
  spikeTrapMonitor:OnFrameBackward(1, function()
    elevatorCombatCollisionScript.LuaObjectScript.Disable()
  end)
  spikeTrapMonitor:Stop()
end
function CeilingStartRewind()
  PlayShakes_Spinnables_Rewind()
  if GameObjects.Elevator.AnimFrame <= 70 then
    CeilingDead()
    spikeTrapMonitor:Start()
  elseif GameObjects.Elevator.AnimFrame <= 85 then
    CeilingSlowdown04()
    spikeTrapMonitor:Start()
  elseif GameObjects.Elevator.AnimFrame <= 90 then
    CeilingSlowdown03()
    spikeTrapMonitor:Start()
  elseif GameObjects.Elevator.AnimFrame <= 100 then
    CeilingSlowdown02()
    spikeTrapMonitor:Start()
  elseif GameObjects.Elevator.AnimFrame <= 110 then
    CeilingSlowdown01()
    spikeTrapMonitor:Start()
  else
    spikeTrapMonitor:Start()
  end
  SoundOnRewindElevator()
end
function CeilingSlowdown01()
  if underElevatorCount == 0 then
    return
  end
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-0.4)
end
function CeilingSlowdown02()
  if underElevatorCount == 0 then
    return
  end
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-0.25)
end
function CeilingSlowdown03()
  if underElevatorCount == 0 then
    return
  end
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-0.175)
end
function CeilingSlowdown04()
  if underElevatorCount == 0 then
    return
  end
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-0.1)
end
function CeilingDead()
  if underElevatorCount == 0 then
    return
  end
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinFrame(22)
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity(-30.5)
  GameObjects.SpinnableSystem.LuaObjectScript.SetDecayRate(10)
  elevatorCombatCollisionScript.LuaObjectScript.Enable()
end
function CeilingSpeedReset_ZoneExit()
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinFrame()
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity()
  GameObjects.SpinnableSystem.LuaObjectScript.SetDecayRate()
  elevatorCombatCollisionScript.LuaObjectScript.Disable()
end
function CeilingSpeedReset()
  spikeTrapMonitor:Stop()
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinFrame()
  GameObjects.SpinnableSystem.LuaObjectScript.SetMinVelocity()
  GameObjects.SpinnableSystem.LuaObjectScript.SetDecayRate()
  elevatorCombatCollisionScript.LuaObjectScript.Disable()
end
function PlayShakes_Settled()
  game.Blender.Trigger({
    Name = "FSE_SHAKE_SWITCH_CLUNK_LIGHT",
    Duration = 1.4,
    TweenIn = {Time = 0.3},
    TweenOut = {Time = 0.2},
    Priority = 5000
  })
  game.Blender.Trigger({
    Name = "FFB_SMALLER",
    Duration = 0.8,
    TweenIn = {Time = 0},
    TweenOut = {Time = 0.6},
    Priority = 5000
  })
end
function PlayShakes_Spinnables()
  game.Blender.Trigger({
    Name = "FSE_SWAY_BOUYANT_ZIPLINE_NORMAL",
    Duration = 3,
    TweenIn = {Time = 0.3},
    TweenOut = {Time = 5},
    Priority = 3000,
    Weight = 0.7
  })
  game.Blender.Trigger({
    Name = "FFB_GENERIC_RUMBLE_LOW",
    Duration = 1.2,
    TweenIn = {Time = 0},
    TweenOut = {Time = 6},
    Priority = 3000,
    Weight = 1
  })
end
function PlayShakes_Spinnables_Rewind()
  game.Blender.Trigger({
    Name = "FSE_SWAY_BOUYANT_ZIPLINE_NORMAL",
    Duration = 5,
    TweenIn = {Time = 0.3},
    TweenOut = {Time = 9},
    Priority = 3000,
    Weight = 0.3
  })
  game.Blender.Trigger({
    Name = "FFB_GENERIC_RUMBLE_LOW",
    Duration = 8,
    TweenIn = {Time = 0},
    TweenOut = {Time = 6},
    Priority = 3000,
    Weight = 1
  })
end
function StopShakes_Spinnables()
  game.Blender.Stop({
    Name = "FSE_SWAY_BOUYANT_ZIPLINE_NORMAL",
    Time = 0
  })
  game.Blender.Stop({
    Name = "FFB_GENERIC_RUMBLE_LOW",
    Time = 0
  })
end
function SpinnableOnReachedLockFrame()
  CeilingSpeedReset()
  SoundOnElevatorStop()
  StopShakes_Spinnables()
end
function SpinnableOnAddImpulse()
  CeilingSpeedReset()
  PlayShakes_Spinnables()
  if GameObjects.SpinnableSystem.LuaObjectScript.currentVelocity <= 0 then
    SoundOnElevatorStop()
  end
  SoundOnLiftElevator()
end
function SpinnableOnReachStart()
  SoundOnElevatorStop()
  SoundOnElevatorReachStart()
  StopShakes_Spinnables()
  PlayShakes_Settled()
end
function SpinnableOnReachEnd()
  SoundOnElevatorStop()
  SoundOnElevatorReachEnd()
  StopShakes_Spinnables()
  PlayShakes_Settled()
end
function SpinnableOnUnlock()
  if GameObjects.Elevator.AnimFrame > 0 then
    SoundOnRewindElevator()
  end
end
function SpinnableOnLock()
  StopShakes_Spinnables()
  if GameObjects.Elevator.AnimFrame > 0 and GameObjects.Elevator.AnimFrame < GameObjects.Elevator.AnimLengthFrames then
    PlaySoundElevatorGearsLocked()
  end
  SoundOnElevatorStop()
end
function OnZoneEnter()
  underElevatorCount = underElevatorCount + 1
end
function OnZoneExit()
  underElevatorCount = underElevatorCount - 1
  if underElevatorCount < 0 then
    underElevatorCount = 0
  end
  if underElevatorCount == 0 and GameObjects.Elevator.AnimFrame > 70 then
    CeilingSpeedReset_ZoneExit()
  end
end
function DetatchFromFriendsCrank()
  local friendsCrankHandle = GameObjects.StraightCrank_AttachPointCage.LuaObjectScript
  if friendsCrankHandle.GetCurrentCycle() > 6 then
    GameObjects.TraverseLink11:HideTraverseLink()
    GameObjects.TraverseLink2:HideTraverseLink()
    GameObjects.TraverseLink21:HideTraverseLink()
  else
    GameObjects.TraverseLink11:ShowTraverseLink()
    GameObjects.TraverseLink2:ShowTraverseLink()
    GameObjects.TraverseLink21:ShowTraverseLink()
  end
end
function ShipFreedLowerDeck()
  GameObjects.AnimBridge:PlayAnimToEnd()
  GameObjects.WheelCrank_HelheimShip.LuaObjectScript.DisablePlayerInput()
  GameObjects.Tower4_MoveSonForTNF:ShowEntityVolume()
  game.AI.FindSon():AddMarker("DisableSummon")
  GameObjects.TraverseLink23:HideTraverseLink()
  GameObjects.TraverseLink3:HideTraverseLink()
  LD.CallFunctionAfterDelay(function()
    LD.PlayMove(game.Player.FindPlayer(), GameObjects.BreakableBridge, "MOV_BridgeFailKnockback")
    GameObjects.WheelCrank_HelheimShip.LuaObjectScript.EnablePlayerInput()
  end, 1.25)
  local helR300 = game.FindLevel("HelR300_HelShip")
  if helR300 ~= nil then
    local shipScript = helR300:FindSingleGameObject("HelheimShipScript")
    if shipScript ~= nil then
      shipScript:CallScript("TriggerUpwardDeckMovement")
      shipScript:CallScript("EnableUpperDeckTNF")
    end
  end
  GameObjects.Btr_HelR100.LuaObjectScript.ShipFreedLowerDeck()
  PlaySound_Platform01Break()
end
function AnimateUpperBridgeOnShipCrankComplete(level)
  LD.CallFunctionAfterDelay(function()
    GameObjects.BridgeTop:PlayAnimToEnd()
  end, 10)
end
local towerState
local STATE_CAUGHT_ON_CRANK_PLATFORM = 1
local STATE_CAUGHT_ON_TNF_PLATFORM = 2
local HingeDoorOverrideSoundEvents = {
  SoundEmitter_Center = nil,
  SoundEmitter_Left = nil,
  SoundEmitter_Right = nil,
  OnInteractForward_Center = "SND_DOOR_HelR100_Drain_Push_Open_01",
  OnInteractForward_Left = "SND_DOOR_HelR100_Drain_Push_Open_01",
  OnInteractForward_Right = "SND_DOOR_HelR100_Drain_Push_Open_01"
}
local HingeDoorLocksOverrideSoundEvents = {
  LockLeftOpen = "SND_DOOR_HelR100_Drain_Latch_01",
  LockLeftClose = "SND_DOOR_HelR100_Drain_Latch_01",
  LockRightOpen = "SND_DOOR_HelR100_Drain_Latch_02",
  LockRightClose = "SND_DOOR_HelR100_Drain_Latch_02"
}
local LiftGateOverrideSoundEvents = {
  OnInteract_Start = "SND_MECH_HelR_Gate_Metal",
  OnInteract_Scrape_LP = "",
  OnInteract_Gears_LP = "",
  OnInteract_Push = ""
}
local SpinnableElevatorDriverOverrideSoundEvents = {
  SoundEmitter = nil,
  OnSpinForward = "SND_MECH_Elevator_HelShip_Up_LP",
  OnSpinBackward = "SND_MECH_Elevator_HelShip_Down_LP",
  OnReachStart = "SND_MECH_Elevator_HelShip_Bottom_Hit",
  OnReachEnd = "SND_MECH_Elevator_HelShip_Top_Hit",
  OnEmbed = "SND_MECH_Elevator_HelShip_Spinnable"
}
local SpinnableElevatorGearsOverrideSoundEvents = {
  OnWeaponEmbed = "SND_MECH_Elevator_HelShip_Axe_Jam",
  OnWeaponUnembed = "",
  OnCWRotate = "",
  OnCCWRotate = ""
}
local Push_CrankSoundOverrides = {
  OnStart = "",
  OnReturnToStart = "",
  OnForward = "SND_MECH_Block_Push_Stone_Large_LP",
  OnForwardLoop = "",
  OnFirstForward = "",
  OnBackward = "SND_MECH_Block_Push_Stone_Large_LP",
  OnBackwardLoop = "",
  OnFirstBackward = "",
  OnFastForward = "SND_MECH_Block_Push_Stone_Large_LP",
  OnRewind = "SND_MECH_Block_Push_Stone_Large_LP",
  OnEnd = "",
  OnStuckAtEnd = "",
  OnStuckAtStart = ""
}
local platform01SoundTable = {
  SoundEmitter = nil,
  LoopEvent = "SND_CINE_HelShip_Platform_Creak_01_LP",
  BreakEvent = "SND_BRK_HelShip_Platform_01",
  ImpactEvent = "SND_CINE_HeShip_Hit_Platform_01"
}
local platform02SoundTable = {
  SoundEmitter = nil,
  LoopEvent = "SND_CINE_HelShip_Platform_Creak_02_LP",
  ImpactEvent = "SND_CINE_HeShip_Hit_Platform_02"
}
local pushOffBlockEmitter
function SoundInit()
  platform01SoundTable.SoundEmitter = GameObjects.BreakableBridge:FindSingleGOByName("DrawBridge").SoundEmitters[1]
  platform02SoundTable.SoundEmitter = GameObjects.BridgeTop:FindSingleGOByName("DrawBridge").SoundEmitters[1]
end
function SoundOnStart()
  GameObjects.HingeDoor_Hel200Entrance:FindSingleGOByName("hel200EntranceScript").LuaObjectScript.SoundSetup(HingeDoorLocksOverrideSoundEvents)
  GameObjects.HingeDoor_Hel200Entrance.LuaObjectScript.SoundSetup(HingeDoorOverrideSoundEvents)
  GameObjects.SpinnableDriver_HelR100.Child.LuaObjectScript.SoundSetup(SpinnableElevatorDriverOverrideSoundEvents)
  GameObjects.SpinnableGears_HelR100.Child.LuaObjectScript.SoundSetup(SpinnableElevatorGearsOverrideSoundEvents)
  GameObjects.FriendsForEver.Child.LuaObjectScript.CrankSoundSetup(Push_CrankSoundOverrides)
  GameObjects.FriendsForEver1.Child.LuaObjectScript.CrankSoundSetup(Push_CrankSoundOverrides)
  SetupSoundBasedOnTowerState()
  SetupSoundDockPushBlock()
end
function ShipPassiveSpawned(level, passive)
  GameObjects.BreakableBridge:FindSingleGOByName("DrawBridge").LuaObjectScript.ShipPassiveSpawned(nil, nil, passive)
  GameObjects.BridgeTop:FindSingleGOByName("DrawBridge").LuaObjectScript.ShipPassiveSpawned(nil, nil, passive)
end
function PlayBridgeBreakSound()
  local emitter = GameObjects.HelBridgeSmallBreak.Child:FindSingleSoundEmitterByName("SNDIceBreak")
  LD.PlaySound(emitter, "SND_BRK_Stone_Bridge_HelR100")
end
function SoundOnRewindElevator()
end
function SoundOnLiftElevator()
end
function SoundOnElevatorStop()
end
function SoundOnElevatorReachEnd()
end
function SoundOnElevatorReachStart()
end
function PlaySoundElevatorGearsLocked()
  GameObjects.SpinnableGears_HelR100.Child.LuaObjectScript.PlayOnWeaponEmbedSound()
end
local bDocksBlockPushedOffLedge = false
local pushOffBlockAnimMonitor, pushOffBlockCrankScript
function SetupSoundDockPushBlock()
  if not bDocksBlockPushedOffLedge then
    pushOffBlockEmitter = GameObjects.FriendsForEver2.Child.Child:FindSingleSoundEmitterByName("SNDPushBlockHelR100")
    pushOffBlockCrankScript = GameObjects.FriendsForEver2.Child.LuaObjectScript
    if pushOffBlockAnimMonitor == nil then
      pushOffBlockAnimMonitor = monitors.CreateAnimFrameMonitor(GameObjects.FriendsForEver2)
      pushOffBlockAnimMonitor:OnFrameBackward(0, AttemptStopSoundPushBlockLoop)
      pushOffBlockAnimMonitor:OnFrame(24, AttemptStopSoundPushBlockLoop)
      pushOffBlockAnimMonitor:OnFrameForward(47, AttemptStopSoundPushBlockLoop)
    end
  end
end
function PlaySoundPushBlockLoop()
  LD.PlaySound(pushOffBlockEmitter, Push_CrankSoundOverrides.OnForward)
end
function StopSoundPushBlockLoop()
  LD.StopSound(pushOffBlockEmitter, Push_CrankSoundOverrides.OnForward)
end
function AttemptStopSoundPushBlockLoop()
  if not pushOffBlockCrankScript.PlayerIsAttached() then
    StopSoundPushBlockLoop()
  end
end
function PlaySoundPushBlockAtEnd()
  bDocksBlockPushedOffLedge = true
  StopSoundPushBlockLoop()
  LD.CallFunctionAfterDelay(function()
    LD.PlaySound(pushOffBlockEmitter, "SND_PUSH_Block_Push_Fall_HelR100")
  end, 0.834)
  if pushOffBlockAnimMonitor ~= nil then
    pushOffBlockAnimMonitor:Stop()
    pushOffBlockAnimMonitor:Terminate()
    pushOffBlockAnimMonitor = nil
  end
end
function SetupSoundBasedOnTowerState()
  if towerState ~= nil then
    if towerState == STATE_CAUGHT_ON_CRANK_PLATFORM then
      LD.PlaySound(platform01SoundTable.SoundEmitter, platform01SoundTable.LoopEvent)
    elseif towerState == STATE_CAUGHT_ON_TNF_PLATFORM then
      LD.PlaySound(platform02SoundTable.SoundEmitter, platform02SoundTable.LoopEvent)
    end
  end
end
function PlaySound_ShipHitPlatform01()
  LD.PlaySound(platform01SoundTable.SoundEmitter, platform01SoundTable.LoopEvent)
  LD.PlaySound(platform01SoundTable.SoundEmitter, platform01SoundTable.ImpactEvent)
  towerState = STATE_CAUGHT_ON_CRANK_PLATFORM
end
function PlaySound_Platform01Break()
  LD.StopSound(platform01SoundTable.SoundEmitter, platform01SoundTable.LoopEvent)
  LD.PlaySound(platform01SoundTable.SoundEmitter, platform01SoundTable.BreakEvent)
  towerState = STATE_CAUGHT_ON_TNF_PLATFORM
end
function PlaySound_ShipHitPlatform02()
  LD.PlaySound(platform02SoundTable.SoundEmitter, platform02SoundTable.LoopEvent)
  LD.PlaySound(platform02SoundTable.SoundEmitter, platform02SoundTable.ImpactEvent)
  towerState = STATE_CAUGHT_ON_TNF_PLATFORM
end
function musicOnSlippedMyMind()
  game.Audio.StartMusic("SND_MX_HEL_past_haunts_baldur_out")
end
function AnimBGShip()
  GameObjects.bgShip:PlayAnimToEnd(0.15)
end
function AddScreenShake()
  local shakeParams = {
    EffectName = "FSE_shake_temp_Generic_Large",
    Duration = 0.5
  }
  game.FX.SubmitEffect(shakeParams)
end
function AnimateBackgroundShip()
  GameObjects.bgShip2:JumpAnimToFrame(575)
  GameObjects.bgShip2:PlayAnimToEnd(0.15)
end
function HelR100_TripleChest_Callback(level, obj)
  local HelR100_Area4B_TripleChestFight_Call = game.FindLevel("HelR100_Docks")
  GameObjects.Cbt_HelR100_Script.LuaObjectScript:Area_4B_TripleChest_Enc_Start()
end
function HelR100_TravelerDoor_Callback(level, obj)
  local HelR100_Area4B_TripleChestFight_Call = game.FindLevel("HelR100_Docks")
  GameObjects.Cbt_HelR100_Script.LuaObjectScript:A3TraverlerDoorShowAlert()
end
function OnSaveCheckpoint(level)
  return {
    levelState = checkpoint.Save(),
    towerState = towerState,
    buttonMaskingON = buttonMaskingON,
    gnomeValid = gnomeValid,
    bDocksBlockPushedOffLedge = bDocksBlockPushedOffLedge
  }
end
function OnRestoreCheckpoint(level, savedInfo)
  checkpoint.Restore(savedInfo.levelState)
  towerState = savedInfo.towerState
  buttonMaskingON = savedInfo.savebuttonMaskingON
  gnomeValid = savedInfo.gnomeValid
  bDocksBlockPushedOffLedge = savedInfo.bDocksBlockPushedOffLedge
end
