local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local checkpoint = require("level.checkpoint")
local actor = require("narrative.actor")
local thisObj, thisLevel, kraActor, sonActor, balActor, freActor, boatActor, falcon
local cineNum = game.Level.GetVariable("CompletedCineNumber")
local cine_lights
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
end
function OnStart(level, obj)
  SetupProps()
  if game.Level.GetVariable("CompletedCineNumber") >= 540 then
    PositionSnake()
  end
  cine_lights = GameObjects.Cine_Start_540
  HideCineLights()
end
local cachedBoat
function SetCachedBoat()
  cachedBoat = game.Boat.GetPlayerBoat()
end
function DestroyCachedBoat()
  cachedBoat:FindSingleGOByName("puppeteerHelper"):CallScript("DestroyBoat")
end
function CreateActors()
  kraActor = actor.Actor.New("FINAL FIGHT INTRO: Kratos Actor", game.Player.FindPlayer)
  sonActor = actor.Actor.New("FINAL FIGHT INTRO: Son Actor", game.AI.FindSon)
  balActor = actor.Actor.New("FINAL FIGHT INTRO: Baldur Actor", ND.FindBaldur)
  freActor = actor.Actor.New("FINAL FIGHT INTRO: Freya Actor")
  boatActor = actor.Actor.New("FINAL FIGHT INTRO: Boat Actor", game.Boat.GetPlayerBoat)
  freActor:SetSpawnFunction(function()
    return ND.SpawnAIAtJoint(thisLevel, "Cine_FinalFightIntro_Group", "frey_FinalFightIntro_StartJoint", "CRT_Freya00", "BRA_FinalFightIntro", "freya")
  end)
end
function SetupProps()
  falcon = GameObjects.falcon00_Top.Child
end
function HideProps()
  falcon:Hide()
end
function FinalFightIntroSequence()
  SetCachedBoat()
  CreateActors()
  local snake = GameObjects.worldsnake00_Top.Child
  local cineSeq = LD.CreateCineSequence(thisLevel, thisObj, "FinalFightIntro")
  local finalFightIntro_ActorTable = {
    {
      Actor = sonActor,
      Branch = "BRA_FinalFightIntro"
    },
    {
      Actor = balActor,
      Branch = "BRA_FinalFightIntro"
    },
    {
      Actor = freActor,
      Branch = "BRA_FinalFightIntro"
    },
    {
      Obj = falcon,
      Anim = "narStnFinalFightIntroCineScene"
    },
    {
      Obj = snake,
      Anim = "narStnFinalFightIntroCineScene"
    },
    {
      Actor = kraActor,
      Branch = "BRA_FinalFightIntro"
    }
  }
  cineSeq:SetPostSkipMusic("SND_MX_STN_boss_master", "SND_MX_STN_start_master")
  cineSeq:MarkAbleToSkip({
    callbackOnSkip = StopMusicDelayTimer
  })
  cineSeq:WaitForLoadCheck("Stn910_c540_FinalFightIntro")
  cineSeq:Do(function()
    game.Compass.SetDesignerForcedHide(true)
  end)
  cineSeq:SpawnActorAndWait(freActor)
  cineSeq:SpawnActorAndWait(balActor)
  cineSeq:RequestCineModeAndWait(kraActor, thisObj)
  cineSeq:Do(PlayCineLights)
  cineSeq:Do(BreakLakeIce)
  cineSeq:ActorSync(boatActor, {
    Slaves = finalFightIntro_ActorTable,
    Branch = "BRA_FinalFightIntro",
    ReferenceJoint = "FinalFightIntro_SynchJoint"
  })
  cineSeq:Do(DisableBoat)
  cineSeq:Do(function()
    freActor:GetCreature():Hide()
  end)
  cineSeq:WaitUntilActorAnimPastFrame(kraActor, 1760)
  cineSeq:Do(function()
    freActor:GetCreature():Show()
  end)
  cineSeq:WaitUntilActorAnimPastPercentage(kraActor, 0.974)
  cineSeq:DespawnActor(freActor)
  cineSeq:Do(FalconFliesAway)
  cineSeq:WaitForAndCompleteCineMode(kraActor, thisObj)
  cineSeq:WaitForActorMoveComplete(kraActor)
  cineSeq:StopPuppetingActor(kraActor)
  cineSeq:StopPuppetingActor(sonActor)
  cineSeq:StopPuppetingActor(balActor)
  cineSeq:Do(DestroyCachedBoat)
  cineSeq:SetCompletedCineNumber(540)
  cineSeq:Do(HideCineLights)
  cineSeq:Do(CompleteCalObj850)
  cineSeq:Do(function()
    GameObjects.loadFinalBossFightZone:ShowEntityVolume()
    local bookmarks = require("design.Bookmarks")
    local tableEntry = bookmarks["BOOKMARK_" .. "34_StoneMason_010_FinalFight_Start"]
    game.World.StoreCheckpointAndBookmark(tableEntry)
  end)
  cineSeq:StartSequence()
end
function StopMusicDelayTimer()
  _G.OnSkipFinalFightIntro()
end
function CompleteCalObj850()
  game.QuestManager.ProposeQuestState("Quest_Caldera_Objective850", "Complete")
end
function DisableBoat()
  local boat = boatActor:GetCreature()
  boat:FindSingleGOByName("puppeteerHelper"):CallScript("DisableInteractZone")
end
function BreakLakeIce()
  local cineWad = game.FindLevel("Stn910_c540_FinalFightIntro")
  if cineWad ~= nil then
    cineWad:CallScript("PlayLakeIceBreakAnim")
  end
end
function PositionSnake()
  local snake = GameObjects.worldsnake00_Top.Child
  snake:StartAnim("envStnSnakeHeadIdleKO")
  snake:PlayAnimToEnd()
  HideProps()
end
function FalconFliesAway()
  local freExitActor = actor.Actor.New("FINAL FIGHT INTRO EXIT: Freya Actor", ND.FindFreya)
  local finalFightIntroExit_ActorTable = {
    {
      Obj = falcon,
      Anim = "narStnFinalFightIntroCineExit"
    }
  }
  local playFalconSeq = LD.CreateCineSequence(thisLevel, thisObj, "FinalFightIntroHideFalcon")
  playFalconSeq:Do(AlignFalconExit)
  playFalconSeq:WaitUntilActorAnimPastPercentage(kraActor, 0.985)
  playFalconSeq:Do(SpawnBossFreya)
  playFalconSeq:WaitForFunctionTrue(ND.FindFreya)
  playFalconSeq:ActorSync(freExitActor, {
    Slaves = finalFightIntroExit_ActorTable,
    Branch = "BRA_FinalFightIntroExit",
    ReferenceJoint = "FinalFightIntroExit_SynchJoint"
  })
  playFalconSeq:WaitUntilActorAnimPastPercentage(freExitActor, 0.97402596)
  playFalconSeq:Do(HideProps)
  playFalconSeq:StopPuppetingActor(freExitActor)
  playFalconSeq:Do(EndFalconFliesAway)
  playFalconSeq:StartSequence()
end
function SpawnBossFreya()
  game.FindLevel("Stn980_BossShoulder"):CallScript("SpawnFreyaAfterFinalFightIntro")
end
function EndFalconFliesAway()
  game.FindLevel("Stn980_BossShoulder"):CallScript("FreyaFinishFinalFightIntroTransition")
end
function AlignFalconExit()
  local jointIndex = thisObj:GetJointIndex("FinalFightIntroExit_SynchJoint")
  local newFalconLoc = thisObj:GetWorldJointPosition(jointIndex)
  local newFalconRot = thisObj:GetWorldJointForward(jointIndex)
  falcon:SetWorldPosition(newFalconLoc)
  falcon:SetWorldFacing(newFalconRot)
end
function HideFreya()
  ND.FindFreya():GetCreature():CallScript("Hide")
end
function ShowFreya()
  ND.FindFreya():GetCreature():CallScript("Show")
end
function PlayCineLights()
  cine_lights:Show()
  cine_lights:JumpAnimToFrame(0)
  cine_lights:PlayAnimToEnd()
end
function HideCineLights()
  cine_lights:Hide()
end
