local LD = require("design.LevelDesignLibrary")
local timer = require("level.timer")
local CSL = require("camera.shakelibrary")
local thisLevel, Hammer
local camShakeLarge = {
  EffectName = "FSE_shake_temp_Generic_Large",
  Duration = 1
}
local PendulumVibrateCount = 1
local CameraZoneCutCamStrapLoose
local bPendulumSwinging = false
local bPendulumSolved = false
local bLootChestUnlocked = false
local bIllAdvised
local VIBRATE_MIN_FRAME = 75
local VIBRATE_MAX_FRAME = 150
local _HAMMER_ANIMS = {
  State01 = "hammerState01Idle1",
  State01Push = "hammerState01PendulumPush1",
  State01React = "hammerState01PendulumReact1",
  State01_02 = "hammerState01_02IceBlast1",
  State02 = "hammerState02Idle1",
  State02React = "hammerState02PendulumReact1",
  State02_03 = "hammerState02_03StrapBreakWin",
  State03 = "hammerState03Idle1",
  State03_04 = "hammerState03_04HammerPushWin1",
  State04 = "hammerState04Idle1"
}
_PENDULUM_STATES_IDLE = "_PENDULUM_STATES_IDLE"
_PENDULUM_STATES_HIT_BY_ARROW = "_PENDULUM_STATES_HIT_BY_ARROW"
_PENDULUM_STATES_PLAYING_HIT_REACT = "_PENDULUM_STATES_PLAYING_HIT_REACT"
_PENDULUM_STATES_PLAYER_APPROACH_STARTED = "_PENDULUM_STATES_PLAYER_APPROACH_STARTED"
_PENDULUM_STATES_PLAYER_INTERACTION_STARTED = "_PENDULUM_STATES_PLAYER_INTERACTION_STARTED"
_PENDULUM_STATES_PLAYER_INTERACTION_PAST_CANCEL = "_PENDULUM_STATES_PLAYER_INTERACTION_PAST_CANCEL"
_PENDULUM_STATES_TRANSITION_TO_COMPLETE = "_PENDULUM_STATES_TRANSITION_TO_COMPLETE"
_PENDULUM_STATES_COMPLETE = "_PENDULUM_STATES_COMPLETE"
local PendulumState = _PENDULUM_STATES_IDLE
SNDHammer = nil
SNDBuckle = nil
SNDStrap = nil
SNDCrystalOne = nil
SNDCrystalTwo = nil
function OnScriptLoaded(level)
  thisLevel = level
  Hammer = GameObjects.masonHammer00.Child
  CameraZoneCutCamStrapLoose = GameObjects.CamZone_StrapLoose
  SNDHammer = Hammer:FindSingleSoundEmitterByName("SNDHammer")
  SNDBuckle = Hammer:FindSingleSoundEmitterByName("SNDBuckle")
  SNDStrap = Hammer:FindSingleSoundEmitterByName("SNDStrap")
  SoundInit()
end
function OnFirstStart(level)
  GameObjects.TraversePath1_pendulum:HideTraversePath()
  GameObjects.TraversePath2_midway:HideTraversePath()
  GameObjects.TraversePath3_towardsStrap:HideTraversePath()
  GameObjects.SpawnZone:HideEntityVolume()
  Hammer:PlayAnimationCycle({
    Animation = _HAMMER_ANIMS.State01
  })
end
function OnStart(level)
  GameObjects.HammeStrap_Interactice_TNF_.LuaObjectScript.OverrideInteractZone({
    angle = 60,
    xzRange = 4,
    cameraAngle = 60,
    cameraAngleWeight = 0.5
  })
  OverrideInteractSounds()
  PendulumSetup()
  LD.HideFX(GameObjects.Ice_Snow_Explosion_A)
  LD.HideFX(GameObjects.Ice_Snow_Explosion_B)
  LD.HideFX(GameObjects.HammerPush_IceSnow)
  LD.HideFX(GameObjects.HammerFallFX)
  LD.HideFX(GameObjects.HammerCrashLakeFX)
  LD.HideFX(GameObjects.LandingConcussionFX)
  LD.HideFX(GameObjects.IceSlide_Anim:FindSingleGOByName("Lake_surface"))
  LD.HideFX(GameObjects.icicle_rm_02_break)
end
function OnSaveCheckpoint(level)
  return {
    PendulumVibrateCount = PendulumVibrateCount,
    bPendulumSwinging = bPendulumSwinging,
    bPendulumSolved = bPendulumSolved,
    bLootChestUnlocked = bLootChestUnlocked,
    PendulumState = PendulumState
  }
end
function OnRestoreCheckpoint(level, savedInfo)
  PendulumVibrateCount = savedInfo.PendulumVibrateCount
  bPendulumSwinging = savedInfo.bPendulumSwinging
  bPendulumSolved = savedInfo.bPendulumSolved
  bLootChestUnlocked = savedInfo.bLootChestUnlocked
  PendulumState = savedInfo.PendulumState
end
function PendulumSetup()
  Hammer.LuaObjectScript.ExcludeSon()
  Hammer.LuaObjectScript.OverrideCameraInteractApproach("ENV_InteractApproach_MasonPendulumPush")
  Hammer.LuaObjectScript.OverideInteractApproachYaw(true)
  Hammer.LuaObjectScript.OverrideCameraSubmissionTime(2)
  Hammer.LuaObjectScript.OverrideInteractZone({xzRange = 1.8, hintXZRange = 4})
  if PendulumVibrateCount == 3 then
    CameraZoneCutCamStrapLoose:HideCameraVolume()
  end
end
function HammerStrapPush_Interaction()
  bPendulumSwinging = true
  PendulumState = _PENDULUM_STATES_PLAYER_APPROACH_STARTED
  GameObjects.BifrostVibrate_Intact_sm.LuaObjectScript.Disable()
end
function HammerStrapPush_InteractionStart()
  PendulumState = _PENDULUM_STATES_PLAYER_INTERACTION_STARTED
end
function HammerStrapPush_InteractionFinish()
  PendulumState = _PENDULUM_STATES_PLAYER_INTERACTION_PAST_CANCEL
  Hammer:OnAnimationDone(thisLevel, "HammerStrapPush_OnComplete", {Force = true})
  GameObjects.BifrostVibrate_Intact_sm.LuaObjectScript.Enable()
end
function HammerStrapPush_OnComplete()
  bPendulumSwinging = false
  Hammer:ClearAllAnimCallbacks()
  if bPendulumSolved == false then
    Hammer.LuaObjectScript.Enable()
    PlayHammerIdle()
  end
end
function Pendlum_VibrateCrystal_SuccessCheck()
  return PendulumState == _PENDULUM_STATES_PLAYER_INTERACTION_PAST_CANCEL and Hammer.AnimFrame >= VIBRATE_MIN_FRAME and Hammer.AnimFrame <= VIBRATE_MAX_FRAME
end
function Pendulum_VibrateCrystal_InitialHit()
  if PendulumState ~= _PENDULUM_STATES_IDLE then
    return
  end
  PendulumState = _PENDULUM_STATES_HIT_BY_ARROW
  Hammer.LuaObjectScript.Disable()
end
function Pendulum_VibrateCrystal_Hit()
  Pendulum_VibrateCrystal_PlayReact()
  if bLootChestUnlocked == false and PendulumState == _PENDULUM_STATES_COMPLETE then
    UnlockLootChest()
  end
  if Pendlum_VibrateCrystal_SuccessCheck() then
    PendulumVibrateCount = PendulumVibrateCount + 1
    if PendulumVibrateCount == 3 then
      local recenterToLock = {
        TimeStart = 0,
        TimeDuration = 3,
        LockRecenter = 1,
        YawRange = -1,
        TriggerLeft = 0,
        TriggerRight = 0,
        ReturnLeft = 180,
        ReturnRight = -180,
        PitchRange = -1,
        ReturnDown = -90,
        ReturnUp = 90
      }
      game.Camera.Recenter(recenterToLock)
    end
    PendulumVibrateCountCheck()
  end
end
function Pendulum_VibrateCrystal_CooldownComplete()
  if PendulumState == _PENDULUM_STATES_PLAYING_HIT_REACT then
    HammerStrapReact_OnComplete()
  end
end
function Pendulum_VibrateCrystal_PlayReact()
  if PendulumState == _PENDULUM_STATES_PLAYER_APPROACH_STARTED or PendulumState == _PENDULUM_STATES_PLAYER_INTERACTION_STARTED then
    return
  end
  ShakeRumble()
  if not bPendulumSwinging then
    if PendulumVibrateCount == 1 or PendulumVibrateCount == 2 then
      PendulumState = _PENDULUM_STATES_PLAYING_HIT_REACT
      Hammer:StartAnimation({
        Animation = _HAMMER_ANIMS.State01React,
        Tween = 0.1
      })
      Hammer:PlayAnimationToEnd()
      PlayNoShoveBtr()
      AudioBuckleWobble()
    elseif PendulumVibrateCount == 3 then
      Hammer:ClearAllAnimCallbacks()
      Hammer:ClearAllAnimationCallbacks()
      Hammer:StartAnimation({
        Animation = _HAMMER_ANIMS.State02React,
        Tween = 0.1
      })
      Hammer:PlayAnimationToEnd()
      Hammer:OnAnimationDone(thisLevel, "HammerStrapReact_OnComplete", {
        Animation = "hammerState02PendulumReact1",
        Force = true
      })
      if not bLootChestUnlocked then
        AudioBuckleWobble()
      end
    end
  end
end
function HammerStrapReact_OnComplete()
  Hammer:ClearAllAnimCallbacks()
  PlayHammerIdle()
end
function PlayHammerIdle()
  if PendulumState ~= _PENDULUM_STATES_COMPLETE then
    PendulumState = _PENDULUM_STATES_IDLE
  end
  bPendulumSwinging = false
  if PendulumState ~= _PENDULUM_STATES_COMPLETE then
    Hammer:StartAnimation({
      Animation = _HAMMER_ANIMS.State01,
      Tween = 0.5
    })
    Hammer:PlayAnimationCycle()
    Hammer.LuaObjectScript.Enable()
  else
    Hammer:StartAnimation({
      Animation = _HAMMER_ANIMS.State02
    })
    Hammer:PlayAnimationCycle()
  end
end
function SetDriversForHammerWarp()
  local player = game.Player.FindPlayer()
  local rotationDriver = player:GetAnimDriver("hammerwarpRotationDriver")
  local translationDriver = player:GetAnimDriver("hammerwarpTranslationDriver")
  local kraHammer_Start_Fwd = GameObjects.Marker_BrokenStrap_WarpPoint:GetWorldForward()
  local kraHammer_Start_Position = GameObjects.Marker_BrokenStrap_WarpPoint:GetWorldPosition()
  rotationDriver.ValueVec = kraHammer_Start_Fwd
  translationDriver.ValueVec = kraHammer_Start_Position
  player:TriggerMoveEvent("LE_HammerStrap_01")
end
function PendulumVibrateCountCheck()
  AudioIceBreaks(PendulumVibrateCount)
  if PendulumVibrateCount == 2 then
    PlayShakes_PendulumVibrateCount_02()
    GameObjects.Icicle_Hammer_break_1A.Child:JumpAnimToFrame(72)
    timer.StartLevelTimer(0.25, function()
      GameObjects.Icicle_Hammer_break_1B.Child:JumpAnimToFrame(72)
    end)
    LD.ShowFX(GameObjects.Ice_Snow_Explosion_A)
    GameObjects.Ice_Snow_Explosion_A.Child:JumpAnimToFrame(72)
    PlayFirstShootBtr()
    GameObjects.EEE_PendulumFirst.LuaObjectScript.Trigger()
  elseif PendulumVibrateCount == 3 then
    PendulumState = _PENDULUM_STATES_TRANSITION_TO_COMPLETE
    AudioHammer()
    AudioHammerFallStuck()
    HammerTipMusic()
    GameObjects.Icicle_Hammer_break_2A.Child:JumpAnimToFrame(72)
    timer.StartLevelTimer(0.15, function()
      GameObjects.Icicle_Hammer_break_2B.Child:JumpAnimToFrame(72)
    end)
    timer.StartLevelTimer(0.2, function()
      GameObjects.Icicle_Hammer_break_2C.Child:JumpAnimToFrame(72)
    end)
    LD.ShowFX(GameObjects.Ice_Snow_Explosion_B)
    GameObjects.Ice_Snow_Explosion_B.Child:JumpAnimToFrame(72)
    Hammer:ClearAllAnimCallbacks()
    Hammer:ClearAllAnimationCallbacks()
    Hammer:StartAnimation({
      Animation = _HAMMER_ANIMS.State01_02,
      Tween = 0.3
    })
    Hammer:PlayAnimationToEnd()
    Hammer:OnAnimationDone(thisLevel, "HammerPause_State02", {
      Animation = "hammerState01_02IceBlast1",
      Force = true
    })
    timer.StartLevelTimer(2.3, ShakeRumble)
    GameObjects.BifrostVibrate_Intact_sm.LuaObjectScript.cooldownTimer:Stop()
    timer.StartLevelTimer(12, function()
      GameObjects.BifrostVibrate_Intact_sm.LuaObjectScript.cooldownTimer:Restart()
    end)
    CameraZoneCutCamStrapLoose:ShowCameraVolume()
    local camseqlength = 12.89
    timer.StartLevelTimer(camseqlength, function()
      CameraZoneCutCamStrapLoose:HideCameraVolume()
    end)
    SetDriversForHammerWarp()
    bPendulumSolved = true
    PlaySecondShootBtr()
    GameObjects.EEE_PendulumLast.LuaObjectScript.Trigger()
    PlayShakes_PendulumVibrateCount_03()
    timer.StartLevelTimer(6, function()
      GameObjects.Icicle_Hammer_break_2A.Child:Hide()
      GameObjects.Icicle_Hammer_break_2B.Child:Hide()
      GameObjects.Icicle_Hammer_break_2C.Child:Hide()
    end)
  end
end
function PlayShakes_PendulumVibrateCount_02()
  timer.StartLevelTimer(0, function()
    CSL.PlayDefaultShake("ShakeRumbleGiant", 1, 0, 1.2)
  end)
  timer.StartLevelTimer(0.5, function()
    CSL.PlayDefaultShake("CrumbleMedium", 1.6, 0.3, 0.5)
  end)
  timer.StartLevelTimer(2.3, function()
    CSL.PlayDefaultShake("CrumbleLower", 1, 0.3, 0.8)
  end)
end
function PlayShakes_PendulumVibrateCount_03()
  timer.StartLevelTimer(0, function()
    CSL.PlayDefaultShake("ShakeRumbleGiant", 1, 0.2, 0.5)
  end)
  timer.StartLevelTimer(1.45, function()
    CSL.PlayDefaultShake("ShakeRumbleMedium", 0.5, 0, 0)
  end)
  timer.StartLevelTimer(2, function()
    CSL.PlayDefaultShake("ShakeRumbleMedium", 0.5, 0, 0)
  end)
  timer.StartLevelTimer(2.8, function()
    CSL.PlayDefaultShake("ShakeRumbleMedium", 0.5, 0, 0)
  end)
  timer.StartLevelTimer(3.2, function()
    CSL.PlayDefaultShake("ShakeRumbleMedium", 0.5, 0, 0.3)
  end)
  timer.StartLevelTimer(3.8, function()
    CSL.PlayDefaultShake("CrumbleLower", 4.6, 0.5, 5.5)
  end)
end
function HammerPause_State02()
  LD.CompleteQuest("Quest_StoneMason_Objective275")
  PendulumState = _PENDULUM_STATES_COMPLETE
  Hammer:ClearAllAnimCallbacks()
  PlayHammerIdle()
  GameObjects.TraversePath1_pendulum:ShowTraversePath()
  EnableDetachStrapSound()
  local bookmarks = require("design.Bookmarks")
  local tableEntry = bookmarks["BOOKMARK_" .. "14_Stonemason_041_PendulumComplete"]
  game.World.StoreCheckpointAndBookmark(tableEntry)
end
function DetachHammerStrapRing()
  timer.StartLevelTimer(1, function()
    AudioStrap()
    Hammer:OnAnimationDone(thisLevel, "DetachStrapComplete", {Force = true})
  end)
end
function BTR_PlayIllAdvised()
  if not bIllAdvised then
    bIllAdvised = true
    game.Audio.PlayBanter("stn_HammerStrap_Slash")
  end
end
function DetachStrapComplete()
  Hammer:ClearAllAnimationCallbacks()
  game.QuestManager.ProposeQuestState("Quest_StoneMason_Objective325", "Complete")
  game.Compass.SetDesignerForcedHide(false)
  game.World.StoreCheckpoint()
end
function SetupHammerPush()
  Hammer:PlayAnimationCycle({
    Animation = _HAMMER_ANIMS.State03
  })
end
function HammerFalls()
  LD.ShowFX(GameObjects.HammerPush_IceSnow)
  LD.ShowFX(GameObjects.HammerFallFX)
  LD.ShowFX(GameObjects.HammerCrashLakeFX)
  LD.ShowFX(GameObjects.LandingConcussionFX)
  LD.ShowFX(GameObjects.IceSlide_Anim:FindSingleGOByName("Lake_surface"))
end
function ShakeRumble()
  game.FX.SubmitEffect(camShakeLarge)
end
function Enable_CA_Squat_Stn400_ElevatorEntry()
  GameObjects.CA_TakeOutJournal_ElevatorEntry.LuaObjectScript.Enable()
end
function Disable_CA_Squat_Stn400_ElevatorEntry()
  GameObjects.CA_Squat_Stn400_ElevatorEntry.LuaObjectScript.Disable()
  GameObjects.CA_TakeOutJournal_ElevatorEntry.LuaObjectScript.Disable()
  GameObjects.CA_Observe_Forward_Stn400_HammerHitChiselDoor.LuaObjectScript.Disable()
end
function RemoveSindriShop_1()
  LD.SetMarkerState("SM_300_VendorLocation", 0)
end
function PushCrystal01()
  LD.PlaySingleSynchMove_KratosObject(GameObjects.HammerCrystal_Group01, "synchJoint", "Stn430_WindowKick", "BRA_Stn430_WindowKick", "")
  GameObjects.CA_Observe_Down_Stn400_KickCockpit.LuaObjectScript.Enable()
  GameObjects.TraversePath2_midway:ShowTraversePath()
  LD.CallFunctionAfterDelay(AudioCrystalOne, 0.525)
  timer.StartLevelTimer(5, function()
    GameObjects.HammerCrystal_Group01:Hide()
  end)
end
function WindowVibrateCrystalHit()
  GameObjects.HammerCrystal_Group02:PlayAnimToEnd()
  GameObjects.ice_cockpit.Child:PlayAnimToEnd()
  ShakeRumble()
  GameObjects.TraversePath3_towardsStrap:ShowTraversePath()
  GameObjects.CA_Observe_Down_Stn400_VibrateCockpit.LuaObjectScript.Enable()
end
function WindowVibrateCrystalInitialHit()
  AudioCrystalTwo()
end
function UnlockLootChest()
  bLootChestUnlocked = true
  LD.ShowFX(GameObjects.icicle_rm_02_break)
  GameObjects.Blocker:HideCollision()
end
function HideHammerCollision()
  GameObjects.HammerIC:HideCollision()
  GameObjects.Hammer_block2:HideCollision()
  GameObjects.Hammer_block3:HideCollision()
  GameObjects.Hammer_block4:HideCollision()
  GameObjects.Hammer_block5:HideCollision()
  GameObjects.Hammer_block7:HideCollision()
  GameObjects.Hammer_block8:HideCollision()
  GameObjects.Hammer_block9:HideCollision()
  GameObjects.Hammer_block10:HideCollision()
end
function OnExitCrackClimbOntoPlatform()
  GameObjects.LTW_Stn400_GoTurret_1.LuaObjectScript.Enable()
end
function OnExitCrackClimbOntoStrap()
  LD.CompleteQuest("Quest_StoneMason_Objective300")
  GameObjects.CA_Idle_Stn400_TnFStrap.LuaObjectScript.Enable()
end
function CompassOff()
  game.Compass.SetDesignerForcedHide(true)
  StartApproachCameraRecenter()
end
function Recenter_TNF_Approach(d)
  local duration = d
  local approach = {
    TimeStart = 0,
    TimeDuration = duration,
    LockRecenter = 1,
    YawRange = -1,
    TriggerLeft = -98,
    ReturnLeft = -98,
    ReturnRight = -98,
    TriggerRight = -98,
    PitchRange = -1,
    TriggerUp = -18.9,
    ReturnUp = -18.9,
    ReturnDown = -18.9,
    TriggerDown = -18.9,
    RotationSpace = 1
  }
  game.Camera.Recenter(approach)
end
function StartApproachCameraRecenter()
  Recenter_TNF_Approach(1)
  timer.StartLevelTimer(1, function()
    Recenter_TNF_Approach(1)
  end)
end
function PlayNoShoveBtr()
  local btrObj = GameObjects.Btr_HammerRibbon_Group
  if btrObj ~= nil then
    btrObj.LuaObjectScript:PlayNoShoveBtr()
  end
end
function PlayFirstShootBtr()
  local btrObj = GameObjects.Btr_HammerRibbon_Group
  if btrObj ~= nil then
    btrObj.LuaObjectScript:PlayFirstShootBtr()
  end
end
function PlaySecondShootBtr()
  local btrObj = GameObjects.Btr_HammerRibbon_Group
  if btrObj ~= nil then
    btrObj.LuaObjectScript:PlaySecondShootBtr()
  end
end
local SoundLevel
local attemptsToFindSoundLevel = 0
local soundOverrides = {
  explicitSoundEmitter = "TNFEmitter",
  activeIdleLoopSound = "SND_MECH_TNF_HammerStrap_Idle_LP",
  struggleToActiveIdleSound = "SND_MECH_TNF_HammerStrap_Struggle_Stop"
}
function SoundInit()
  FindSoundLevel()
  AudioBuckleLoop()
  SNDCrystalOne = GameObjects.SNDCrystals:FindSingleSoundEmitterByName("SNDCrystalOne")
  SNDCrystalTwo = GameObjects.SNDCrystals:FindSingleSoundEmitterByName("SNDCrystalTwo")
  soundOverrides.explicitSoundEmitter = game.Player.FindPlayer():FindSingleSoundEmitterByName("SNDLeftHand")
end
function FindSoundLevel()
  SoundLevel = game.FindLevel("Stn050_Sound")
  if SoundLevel == nil and attemptsToFindSoundLevel < 30 then
    attemptsToFindSoundLevel = attemptsToFindSoundLevel + 1
    StartLevelTimer(1, FindSoundLevel)
  end
end
function EnableDetachStrapSound()
  if SoundLevel ~= nil then
    SoundLevel:CallScript("OnHammerStateHookFall")
  end
end
function AudioHammer()
  LD.PlaySound(SNDHammer, "SND_EVNT_Stone_Mason_Buckle_Fall_Start")
end
function AudioHammerFallStuck()
  LD.PlaySoundOnFrame(SNDHammer, Hammer, "SND_EVNT_Stone_Mason_Buckle_Fall_Impact", 90, "forward")
end
function AudioIceBreaks(pstate)
  if pstate == 2 then
    LD.PlaySound(SNDHammer, "SND_EVNT_Stone_Mason_Buckle_Explo2")
  elseif pstate == 3 then
    LD.PlaySound(SNDHammer, "SND_EVNT_Stone_Mason_Buckle_Collapse")
  end
end
function LuaHook_BuckleStrapHitSwing(ai, data)
  HammerStrapPush_InteractionStart()
  LD.PlaySound(SNDBuckle, "SND_EVNT_Stone_Mason_Buckle_Strap_Hit_Swing")
end
function AudioStrap()
  LD.PlaySound(SNDStrap, "SND_EVNT_Stone_Mason_Hammer_Strap_Break")
end
function AudioBuckleWobble()
  LD.PlaySound(SNDBuckle, "SND_MECH_Stone_Mason_Buckle_Explo_Rattle")
end
function AudioBuckleLoop()
  LD.PlaySound(SNDBuckle, "SND_MECH_Metal_Buckle_Idle_LP")
end
function AudioCrystalOne()
  LD.PlaySound(SNDCrystalOne, "SND_BRK_Hammer_Climb_Window_Kick")
end
function AudioCrystalTwo()
  LD.PlaySound(SNDCrystalTwo, "SND_BRK_Hammer_Climb_Window_Shoot")
end
function AudioTNFStart()
  print("Sending callback to InteractiveObject_TNF")
  GameObjects.HammeStrap_Interactice_TNF_.LuaObjectScript.PlayTNFInteractStart()
end
function OverrideInteractSounds()
  print("Overriding hammer strap TNF sound events")
  GameObjects.HammeStrap_Interactice_TNF_.LuaObjectScript.SoundSetup(soundOverrides)
end
function HammerTipMusic()
  game.Audio.StartCheckpointedMusic("SND_MX_STN_hammer_base_tip")
end
