local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local actor = require("narrative.actor")
local timers = require("level.timer")
local checkpoint = require("level.checkpoint")
local CCEC = require("camera.camera_cineentercamera")
local thisObj, thisLevel, son, kraActor, sonActor, debrisProp, cineSeq, idleSeq, hardLandingTimer, cine_lights_492, cameraCineEnter_OutOfControl
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  son = game.AI.FindSon()
end
function OnStart(level, obj)
  cine_lights_492 = GameObjects.Cine_Start_492
  HideCineLights()
  if game.Level.GetVariable("CompletedCineNumber") < 492 then
    SetupActors()
    SetupSonIdle()
  else
    GameObjects.InteractZone_OutOfControl:Hide()
  end
end
function OnUpdate(level, obj)
  if cameraCineEnter_OutOfControl ~= nil then
    cameraCineEnter_OutOfControl:Update()
  end
end
function OnSaveCheckpoint(level, obj)
  return {
    levelState = checkpoint.Save()
  }
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  checkpoint.Restore(savedInfo.LevelState)
end
function SetupActors()
  kraActor = actor.Actor.New("OUT OF CONTROL: Kratos Actor", game.Player.FindPlayer)
  sonActor = actor.Actor.New("OUT OF CONTROL: Son Actor", game.AI.FindSon)
  debrisProp = thisObj:FindSingleGOByName("stoneDebrisProp").Child
end
function SetupSonIdle()
  idleSeq = LD.CreateCineSequence(thisLevel, thisObj, "SonIdle")
  local slaveTab = {
    {
      Obj = debrisProp,
      Anim = "narHelROutOfControl000IntIdle"
    }
  }
  idleSeq:WaitSeconds(0.2)
  idleSeq:WaitForFunctionTrue(function()
    return not son:IsPlayingMove("MOV_BaldurSkyEnter") or son.AnimFrame / son.AnimLengthFrames >= 0.98
  end)
  idleSeq:ActorSync(sonActor, {
    Slaves = slaveTab,
    Branch = "BRA_OutOfControlIdle",
    ReferenceJoint = "OutOfControl_SynchJoint"
  })
  idleSeq:StartSequence()
end
function SetupCineSequence()
  cineSeq = LD.CreateCineSequence(thisLevel, thisObj, "Out Of Control Sequence")
  local slaveTab = {
    {Actor = sonActor},
    {
      Obj = debrisProp,
      Anim = "narHelROutOfControl010CineScene"
    }
  }
  if hardLandingTimer ~= nil then
    hardLandingTimer:Stop()
    hardLandingTimer = nil
  end
  cineSeq:SetPostSkipMusic("SND_MX_HEL_start_master", nil, nil, nil, nil, "SND_MX_HEL_tower1_climb")
  cineSeq:MarkAbleToSkip()
  cineSeq:CancelSequence(idleSeq)
  cineSeq:RequestCineModeAndWait(kraActor, thisObj)
  cineSeq:Do(function()
    thisObj:FindSingleGOByName("CDHull"):Hide()
  end)
  cineSeq:Do(StartCineEnter_OutOfControl)
  cineSeq:ActorForceApproachAndWait(kraActor, {
    Branch = "BRA_OutOfControl",
    ReferenceJoint = "OutOfControl_SynchJoint",
    speed = ND.KraWalkSpeed,
    stop = true,
    prevent_path_eval = true,
    radius = ND.StopTurnRadius,
    foot = game.Creature.Foot.kLeft,
    weapon_state = "bare_on_back"
  })
  cineSeq:Do(PlayCineLights)
  cineSeq:ActorSync(kraActor, {
    Slaves = slaveTab,
    Branch = "BRA_OutOfControl",
    ReferenceJoint = "OutOfControl_SynchJoint"
  })
  cineSeq:WaitForAndCompleteCineMode(kraActor, thisObj)
  cineSeq:StopPuppetingActor(kraActor)
  cineSeq:StopPuppetingActor(sonActor)
  cineSeq:Do(function()
    debrisProp:Hide()
  end)
  cineSeq:Do(HideCineLights)
  cineSeq:Do(function()
    local availabilityState = {AvailableForCombat = true}
    game.AI.FindSon():SetNewAvailabilityRequest("LevelDesignScript", availabilityState)
  end)
  cineSeq:Do(function()
    game.Audio.StartCheckpointedMusic("SND_MX_HEL_tower1_climb")
  end)
  cineSeq:SetCompletedCineNumber(492)
  cineSeq:Do(AwardTrophy)
  cineSeq:Do(Quest_Helheim_Parent_Start)
  cineSeq:Do(function()
    game.World.StoreCheckpoint()
  end)
  cineSeq:StartSequence()
end
function AwardTrophy()
  print("Trophy Awarded: Round Two")
  game.UnlockTrophy(8)
end
function CanSeqFire()
  return game.Level.GetVariable("CompletedCineNumber") < 492
end
function PlayCineLights()
  cine_lights_492:Show()
  cine_lights_492:JumpAnimToFrame(0)
  cine_lights_492:PlayAnimToEnd()
end
function HideCineLights()
  cine_lights_492:Hide()
end
function StartHardLandingTimer()
  if cineSeq == nil then
    hardLandingTimer = timers.StartLevelTimer(7, PlayHardLandingHint)
  end
end
function PlayHardLandingHint()
  game.Audio.PlayBanter("010_HardLanding_02")
  hardLandingTimer = timers.StartLevelTimer(20, PlayHardLandingHintAlt)
end
function PlayHardLandingHintAlt()
  game.Audio.PlayBanter("010_HardLanding_02Alt1")
  hardLandingTimer = timers.StartLevelTimer(20, PlayHardLandingHintAlt2)
end
function PlayHardLandingHintAlt2()
  game.Audio.PlayBanter("010_HardLanding_02Alt2")
  hardLandingTimer = timers.StartLevelTimer(20, PlayHardLandingHint)
end
function Quest_Helheim_Parent_Start()
  game.QuestManager.ProposeQuestState("Quest_PeaksPass_Objective830", "Complete")
  LD.ActivateQuest("Quest_Helheim_Parent")
  game.Compass.SetDesignerForcedHide(false)
end
function StartCineEnter_OutOfControl()
  cameraCineEnter_OutOfControl = CCEC.CineEnterCamera.New("ENV_CineEnter_OutOfControl", 7)
  cameraCineEnter_OutOfControl:SetCallback(DestroyCineEnter_OutOfControl)
  cameraCineEnter_OutOfControl:Start()
end
function DestroyCineEnter_OutOfControl()
  cameraCineEnter_OutOfControl = nil
  game.SubObject.Sleep(thisObj)
end
