local LD = require("design.LevelDesignLibrary")
local checkpoint = require("level.checkpoint")
local ND = require("design.NarrativeDesignLibrary")
local actor = require("narrative.actor")
local CCEC = require("camera.camera_cineentercamera")
local thisLevel, thisObj, kratosActor, athenaActor, freyaBoat, deer0, deer1, deer2, deer3, deer4, deer5, deer7
local deerTable = {
  deer0,
  deer1,
  deer2,
  deer3,
  deer4,
  deer5,
  deer7
}
local bigDeerTable = {
  deer0,
  deer1,
  deer2,
  deer3,
  deer4,
  deer5
}
local cineLights, cineLightsB, cineEnterCamera_AthenaBoat
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  game.SubObject.Sleep(obj)
end
function OnStart(level, obj)
  CreateActorsAndPositions()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if cineNum < 375 then
    BoatAppearanceSeq()
  end
  if game.Boat.FindAndCacheAthenaBoat then
    game.Boat.FindAndCacheAthenaBoat()
  end
end
function CreateActorsAndPositions()
  kratosActor = actor.Actor.New("Kratos", game.Player.FindPlayer)
  athenaActor = actor.Actor.New("Athena")
  SetSpawnFunctions()
  SetupProps()
end
function SetupProps()
  freyaBoat = GameObjects.BoatFreyaProp.Child
  deer0 = GameObjects.Deer00_0.Child
  deer1 = GameObjects.Deer00_1.Child
  deer2 = GameObjects.Deer00_2.Child
  deer3 = GameObjects.Deer00_3.Child
  deer4 = GameObjects.Deer00_4.Child
  deer5 = GameObjects.Deer00_5.Child
  deer7 = GameObjects.Deer00_7.Child
  cineLights = GameObjects.Cine_Start_375
  cineLightsB = GameObjects.Cine_Start_375B
  HideCineLights()
  deer0:SetCharacterConfig("Deer_00")
  deer1:SetCharacterConfig("Deer_10")
  deer2:SetCharacterConfig("Deer_10")
  deer3:SetCharacterConfig("Deer_10")
  deer4:SetCharacterConfig("Deer_00")
  deer5:SetCharacterConfig("Deer_00")
  deer7:SetCharacterConfig("Deer_10")
  HideDeer()
  freyaBoat:StartAnim("narRivAthenaBoat000Cine_propBoatIdle")
  freyaBoat:JumpAnimToFrame(0)
  freyaBoat:PauseAnim()
  freyaBoat:Hide()
end
function HideDeer()
  RunFunctionOnObjectsInTable(deerTable, "Hide")
end
function ShowDeer()
  RunFunctionOnObjectsInTable(deerTable, "Show")
end
function OnUpdate()
  if cineEnterCamera_AthenaBoat ~= nil then
    cineEnterCamera_AthenaBoat:Update()
  end
end
function OnSaveCheckpoint(level, obj)
  local savedInfo = {}
  savedInfo.LevelState = checkpoint.Save()
  return savedInfo
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  checkpoint.Restore(savedInfo.LevelState)
end
function RunFunctionOnObjectsInTable(obj_table, func_name, ...)
  for _, each_obj in ipairs(obj_table) do
    each_obj[func_name](each_obj, ...)
  end
end
function BuildAthenaBoatSequence()
  local availabilityState = {
    AvailableForSync = false,
    AvailableForBanter = false,
    AvailableInLevel = false,
    AvailableForCombat = false
  }
  game.AI.FindSon():SetNewAvailabilityRequest("SonUnavailable", availabilityState)
  LD.SetEntityVariable("FOR_ReturnForBlades", true)
  local seq = ND.CreateCineSequence(thisLevel, thisObj, "athenaBoatSeq")
  local actorTable = {
    {Actor = athenaActor},
    {
      Obj = freyaBoat,
      Anim = "narRivAthenaBoat000Cine"
    },
    {
      Obj = deer0,
      Anim = "narRivAthenaBoat000Cine"
    },
    {
      Obj = deer1,
      Anim = "narRivAthenaBoat000Cine1"
    },
    {
      Obj = deer2,
      Anim = "narRivAthenaBoat000Cine2"
    },
    {
      Obj = deer3,
      Anim = "narRivAthenaBoat000Cine3"
    },
    {
      Obj = deer4,
      Anim = "narRivAthenaBoat000Cine4"
    },
    {
      Obj = deer5,
      Anim = "narRivAthenaBoat000Cine5"
    },
    {
      Obj = deer7,
      Anim = "narRivAthenaBoat000Cine7"
    },
    {Obj = cineLights, Anim = "default"},
    {Obj = cineLightsB, Anim = "default"}
  }
  seq:SetPostSkipMusic("SND_MX_RIV_start_master", "SND_MX_PRO_start_master")
  seq:MarkAbleToSkip()
  seq:RequestCineModeAndWait(kratosActor, thisObj)
  seq:Do(StartCineEnter_AthenaBoat)
  seq:SpawnActorAndWait(athenaActor)
  seq:ActorForceApproachAndWait(kratosActor, {
    Branch = "BRA_AthenaBoat",
    ReferenceJoint = "AthenaBoat_SynchJoint",
    speed = ND.KraWalkSpeed,
    stop = false,
    radius = ND.StopTurnRadius,
    weapon_state = "bare"
  })
  seq:Do(TurnOffMovementWind)
  seq:Do(ShowDeer)
  seq:Do(PlayCineLights)
  seq:Do(PlayCineLightsB)
  seq:ActorSync(kratosActor, {
    Slaves = actorTable,
    Branch = "BRA_AthenaBoat",
    ReferenceJoint = "AthenaBoat_SynchJoint"
  })
  seq:WaitUntilActorAnimPastFrame(kratosActor, 150)
  seq:ParentObject(cineLights, kratosActor:GetCreature(), "zeroJoint")
  seq:WaitUntilActorAnimPastPercentage(kratosActor, 0.3)
  seq:WaitForLoadCheck("For100_River")
  seq:Do(function()
    seq:SetMaxSkipSpeedup(20)
  end)
  seq:WaitUntilActorAnimPastPercentage(kratosActor, 0.468)
  seq:WaitUntilActorAnimPastPercentage(kratosActor, 0.95)
  seq:Do(function()
    if not seq.skipping then
      seq.ableToSkip = false
      game.SetAbleToSkip(false)
    end
  end)
  seq:WaitForLoadCheck("For101_RiverToHouse")
  seq:WaitForAndCompleteCineMode(kratosActor, thisObj)
  seq:WaitForLoadCheck("For200_House")
  seq:WaitForLoadCheck("For200_c380_RetrieveBlades")
  seq:DespawnActor(athenaActor)
  seq:SetCompletedCineNumber(375)
  seq:StopPuppetingActor(kratosActor)
  seq:StopPuppetingActor(athenaActor)
  seq:DespawnActor(athenaActor)
  seq:Do(TurnOnMovementWind)
  seq:Do(HideDeer)
  seq:Do(HideCineLights)
  seq:StartSequence()
end
function TurnOnMovementWind()
  game.FX.SetEnableCounterWind(true)
end
function TurnOffMovementWind()
  game.FX.SetEnableCounterWind(false)
end
function PlayCineLights()
  cineLights:Show()
  cineLights:JumpAnimToFrame(0)
  PlaySoundCineLights()
end
function PlayCineLightsB()
  cineLightsB:Show()
  cineLightsB:JumpAnimToFrame(0)
end
function HideCineLights()
  cineLights:Hide()
  if cineLights.Parent ~= nil and cineLights.Parent == game.Player.FindPlayer() then
    cineLights:Unparent()
  end
  cineLightsB:Hide()
end
function BoatAppearanceSeq()
  freyaBoat:Show()
  freyaBoat:PlayAnimationCycle({
    Animation = "narRivAthenaBoat000Cine_propBoatIdle"
  })
end
function SetSpawnFunctions()
  athenaActor:SetSpawnFunction(function()
    return ND.SpawnAIAtJoint(thisLevel, "Cine_AthenaBoat", "AthenaSpawn_Joint", "CRT_Athena00", "BRA_Spawn", "Athena")
  end)
end
function StartCineEnter_AthenaBoat()
  game.SubObject.Wake(thisObj)
  cineEnterCamera_AthenaBoat = CCEC.CineEnterCamera.New("ENV_CineEnter_AthenaBoat", 7)
  cineEnterCamera_AthenaBoat:SetCallback(DestroyCineEnter_AthenaBoat)
  cineEnterCamera_AthenaBoat:Start()
end
function DestroyCineEnter_AthenaBoat()
  cineEnterCamera_AthenaBoat = nil
  game.SubObject.Sleep(thisObj)
end
function PlaySoundCineLights()
  local kratosEmitter = game.Player.FindPlayer():FindSingleSoundEmitterByName("SNDKratos")
  LD.PlaySoundOnFrame(kratosEmitter, cineLights, "SND_AMB_EMIT_Red_Storm_Lightning_Close", 130, "forward")
  LD.PlaySoundOnFrame(kratosEmitter, cineLights, "SND_AMB_EMIT_Red_Storm_Lightning_Close", 138, "forward")
  LD.PlaySoundOnFrame(kratosEmitter, cineLights, "SND_AMB_EMIT_Red_Storm_Lightning_Close", 148, "forward")
  LD.PlaySoundOnFrame(kratosEmitter, cineLights, "SND_AMB_EMIT_Red_Storm_Lightning_Close", 299, "forward")
  LD.PlaySoundOnFrame(kratosEmitter, cineLights, "SND_AMB_EMIT_Red_Storm_Lightning_Close", 1137, "forward")
  LD.PlaySoundOnFrame(kratosEmitter, cineLights, "SND_AMB_EMIT_Red_Storm_Lightning_Close", 1160, "forward")
  LD.PlaySoundOnFrame(kratosEmitter, cineLights, "SND_AMB_EMIT_Red_Storm_Lightning_Close", 1168, "forward")
  LD.PlaySoundOnFrame(kratosEmitter, cineLights, "SND_AMB_EMIT_Red_Storm_Lightning_Close", 1793, "forward")
  LD.PlaySoundOnFrame(kratosEmitter, cineLights, "SND_AMB_EMIT_Red_Storm_Lightning_Close", 2629, "forward")
  LD.PlaySoundOnFrame(kratosEmitter, cineLights, "SND_AMB_EMIT_Red_Storm_Lightning_Close", 2649, "forward")
end
