local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local actor = require("narrative.actor")
local checkpoint = require("level.checkpoint")
local CCEC = require("camera.camera_cineentercamera")
local thisObj, thisLevel, kraActor, sonActor, boatActor, ropeA, ropeB, kelp, driftWood, demigodReveal_Lights, boat_Start, boat_Start_Fwd, boat, boatPuppeteerHelper, DemiGodCine_Prepared, temp_DemiGodCine_Prepared, cineWad, cameraCineEnter_DemigodReveal
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  game.SubObject.Sleep(thisObj)
end
function OnStart(level, obj)
  HideLightsIfNeeded()
  if DemiGodCine_Prepared then
    Prepare()
  end
end
function OnFirstStart()
  GameObjects.DemiGodCollision:HideCollision()
end
function PrepareFromTrigger()
  if not DemiGodCine_Prepared then
    Prepare()
  end
end
function Prepare()
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 390 <= cineNumber and cineNumber < 400 then
    CreateActorsAndPositions()
    SetupPropsAndBoat()
    DemiGodCine_Prepared = true
    EnableInteractZone()
    GameObjects.DemiGodCollision:ShowCollision()
  end
end
function OnUpdate(level, obj)
  if cameraCineEnter_DemigodReveal ~= nil then
    cameraCineEnter_DemigodReveal:Update()
  end
end
function OnSaveCheckpoint(level, obj)
  return {temp_DemiGodCine_Prepared = DemiGodCine_Prepared}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  DemiGodCine_Prepared = savedInfo.temp_DemiGodCine_Prepared
end
function SetupPropsAndBoat()
  ropeA = GameObjects.boatRope10A.Child
  ropeB = GameObjects.boatRope10B.Child
  driftWood = GameObjects.driftWood00A.Child
  kelp = GameObjects.kelp00A.Child
  local seq = ND.CreateCineSequence(thisLevel, thisObj, "PropAnimSetup")
  seq:WaitForFunctionTrue(function()
    return game.FindLevel("Riv935_c400_DemigodReveal")
  end)
  seq:Do(BuildSpawnBoatSequence)
  seq:Do(SetupPropAnims)
  seq:StartSequence()
end
function SetupPropAnims()
  ropeA:StartAnim("narRivDemigodReveal000Cine")
  ropeB:StartAnim("narRivDemigodReveal000Cine1")
  driftWood:StartAnim("narRivDemigodReveal000Cine")
  kelp:StartAnim("narRivDemigodReveal000Cine")
  ropeA:JumpAnimToFrame(0)
  ropeB:JumpAnimToFrame(0)
  driftWood:JumpAnimToFrame(0)
  kelp:JumpAnimToFrame(0)
  ropeA:PauseAnim()
  ropeB:PauseAnim()
  driftWood:PauseAnim()
  kelp:PauseAnim()
  cineWad = game.FindLevel("Riv935_c400_DemigodReveal")
  demigodReveal_Lights = cineWad:GetGameObject("Cine_Start_400")
  HideCineLights()
end
function HideLightsIfNeeded()
  cineWad = game.FindLevel("Riv935_c400_DemigodReveal")
  if cineWad ~= nil then
    HideCineLights()
  end
end
function ShowCineLights()
  cineWad:CallScript("ShowLights")
end
function HideCineLights()
  cineWad:CallScript("HideLights")
end
function CreateActorsAndPositions()
  kraActor = actor.Actor.New("Kratos", game.Player.FindPlayer)
  sonActor = actor.Actor.New("Son", game.AI.FindSon)
  boatActor = actor.Actor.New("Boat")
  boat_Start = LD.GetWorldJointPosition("Cine_DemigodReveal", "Boat_Start")
  boat_Start_Fwd = LD.GetWorldJointForward("Cine_DemigodReveal", "Boat_Start")
end
function SetSpawnFunctions()
  boatActor:SetSpawnFunction(function()
    local cineBoatRef = FindBoat()
    if cineBoatRef == nil then
      local boatWad = game.FindLevel("BoatGlobal")
      cineBoatRef = game.AI.Spawn(boatWad, boat_Start, boat_Start_Fwd, "CRT_Boat00", "BRA_Spawn")
      cineBoatRef:AddMarker("DemigodBoat")
    end
    return cineBoatRef
  end)
end
function FindBoat()
  local objArray = game.World.FindGameObjectsByMarker("DemigodBoat")
  for _, obj in ipairs(objArray) do
    if obj:GetCreature() ~= nil then
      return obj:GetCreature()
    end
  end
  return nil
end
function BuildSpawnBoatSequence()
  local seq = ND.CreateCineSequence(thisLevel, thisObj, "spawn_demigodReveal_boat")
  seq:WaitFrames(1)
  seq:WaitForFunctionTrue(WaitForBoatWad)
  seq:Do(SetSpawnFunctions)
  seq:SpawnActorAndWait(boatActor)
  seq:Do(function()
    boat = boatActor:GetCreature()
    boatPuppeteerHelper = boat:FindSingleGOByName("puppeteerHelper")
    boatPuppeteerHelper:CallScript("DisableInteractZone")
  end)
  seq:ActorSync(boatActor, {
    Branch = "BRA_DemigodReveal_Idle",
    ReferenceJoint = "DemigodReveal_SyncJoint"
  })
  seq:StartSequence()
end
function WaitForBoatWad()
  return game.FindLevel("BoatGlobal") ~= nil
end
function EnableInteractZone()
  GameObjects.BoatInteractZone.LuaObjectScript:Enable()
end
function BuildDemigodRevealSequence()
  local demigodRevealSeq = ND.CreateCineSequence(thisLevel, thisObj, "demigodReveal")
  local demigodReveal_ActorTable = {
    {
      Actor = sonActor,
      Branch = "BRA_DemigodReveal"
    },
    {
      Actor = kraActor,
      Branch = "BRA_DemigodReveal"
    },
    {
      Obj = ropeA,
      Anim = "narRivDemigodReveal000Cine"
    },
    {
      Obj = ropeB,
      Anim = "narRivDemigodReveal000Cine1"
    },
    {
      Obj = driftWood,
      Anim = "narRivDemigodReveal000Cine"
    },
    {
      Obj = kelp,
      Anim = "narRivDemigodReveal000Cine"
    },
    {Obj = demigodReveal_Lights, Anim = "default"}
  }
  demigodRevealSeq:SetPostSkipMusic("SND_MX_RIV_start_master", "SND_MX_SonSick_master", "SND_MX_CAL_start_master", "SND_MX_CAL_snake_belly_master")
  demigodRevealSeq:MarkAbleToSkip()
  demigodRevealSeq:RequestCineModeAndWait(kraActor, thisObj)
  demigodRevealSeq:Do(StartCineEnter_DemigodReveal)
  demigodRevealSeq:Do(function()
    game.Audio.PlayBanter("RIV_WashedAshore_02_Disembodied")
  end)
  demigodRevealSeq:ActorForceApproachAndWait(kraActor, {
    Branch = "BRA_DemigodReveal",
    ReferenceJoint = "DemigodReveal_SyncJoint",
    speed = ND.KraWalkSpeed,
    stop = true,
    prevent_path_eval = true,
    radius = ND.StopTurnRadius,
    weapon_state = "bare"
  })
  demigodRevealSeq:Do(ShowCineLights)
  demigodRevealSeq:Do(UpdateDockingSystemOnBoatEnter)
  demigodRevealSeq:Do(SetCorrectRopeMesh)
  demigodRevealSeq:ActorSync(boatActor, {
    Slaves = demigodReveal_ActorTable,
    Branch = "BRA_DemigodReveal",
    ReferenceJoint = "DemigodReveal_SyncJoint"
  })
  demigodRevealSeq:Do(function()
    game.Compass.SetDesignerForcedHide(true)
  end)
  demigodRevealSeq:WaitForAndCompleteCineMode(kraActor, thisObj)
  demigodRevealSeq:SetCompletedCineNumber(400)
  demigodRevealSeq:StopPuppetingActor(sonActor)
  demigodRevealSeq:StopPuppetingActor(kraActor)
  demigodRevealSeq:StopPuppetingActor(boatActor)
  demigodRevealSeq:Do(function()
    GameObjects.NoGoZone_DemigodReveal:Hide()
  end)
  demigodRevealSeq:Do(function()
    GameObjects.SadContext.LuaObjectScript.Disable()
    GameObjects.CA_Exit_DemiGod.LuaObjectScript.Disable()
  end)
  demigodRevealSeq:Do(function()
    GameObjects.EntZn_Playtest_DemiGodEnd:ShowEntityVolume()
  end)
  demigodRevealSeq:Do(function()
    DemiGodCine_Prepared = false
  end)
  demigodRevealSeq:Do(function()
    GameObjects.DemiGodCollision:HideCollision()
  end)
  demigodRevealSeq:Do(function()
    LD.EnableContextBehaviorBanter()
  end)
  demigodRevealSeq:Do(Enable_ClearBoatSpeedZone)
  demigodRevealSeq:Do(HideCineLights)
  demigodRevealSeq:Do(SetPreventNoTowerBanterFact)
  demigodRevealSeq:Do(function()
    game.AI.FindSon():CallScript("ClearBehaviorContext")
  end)
  demigodRevealSeq:Do(function()
    game.Audio.PlayBanter("RIV_RevealFollowUp")
    boat = boatActor:GetCreature()
    boatPuppeteerHelper = boat:FindSingleGOByName("puppeteerHelper")
    boatPuppeteerHelper:CallScript("EnableInteractZone")
    GameObjects.FreyaCaveBoat_02.LuaObjectScript.Enable()
    local boat = game.Boat.GetPlayerBoat()
    boat:FindSingleGOByName("puppeteerHelper"):CallScript("NotifyDockSystem_PlayerEnteringBoat", boat)
  end)
  demigodRevealSeq:Do(function()
    SetBoatSpeed()
    LD.SetEntityVariable("NAR_RoadLoreAllowed", true)
    _G.StartLevelTimer(2, function()
      Complete_Caldera_Objective360()
      BOOKMARK_21_RiverPass_030_ToTheVault()
    end)
  end)
  demigodRevealSeq:StartSequence()
end
function SetCorrectRopeMesh()
  ropeA:HideJoint(ropeA:GetJointIndex("ropeMesh"))
  ropeA:HideJoint(ropeA:GetJointIndex("ropeBMesh"))
  ropeA:HideJoint(ropeA:GetJointIndex("ropeCMesh"))
  ropeA:HideJoint(ropeA:GetJointIndex("ropeDMesh"))
  ropeA:HideJoint(ropeA:GetJointIndex("ropeEMesh"))
  local currentArmor = game.Player.FindPlayer():PickupGetPickupNameInSlot("ArmorChest")
  local origMeshArmors = {
    "KratosArmorChest_Starter_Tier00",
    "KratosArmorChest_TankSet_Tier01",
    "KratosArmorChest_TankSet_Tier02",
    "KratosArmorChest_TankSet_Tier03",
    "KratosArmorChest_DamageSet_Tier01",
    "KratosArmorChest_DamageSet_Tier02",
    "KratosArmorChest_DamageSet_Tier03"
  }
  local meshBArmors = {
    "KratosArmorChest_TankSet_Tier04",
    "KratosArmorChest_TankSet_Tier05",
    "KratosArmorChest_TankSet_Tier06",
    "KratosArmorChest_MspTankSet_Tier06",
    "KratosArmorChest_NifTankSet_Tier06",
    "KratosArmorChest_TyrSet_Tier06"
  }
  local meshCArmors = {
    "KratosArmorChest_ValkyrieSet_Tier06",
    "KratosArmorChest_ElementalSet_Tier06",
    "KratosArmorChest_HuldraBrokSet_Tier06",
    "KratosArmorChest_HuldraSindriSet_Tier06"
  }
  local meshDArmors = {
    "KratosArmorChest_DamageSet_Tier04",
    "KratosArmorChest_DamageSet_Tier05",
    "KratosArmorChest_DamageSet_Tier06",
    "KratosArmorChest_MspDamageSet_Tier06",
    "KratosArmorChest_NifDamageSet_Tier06",
    "KratosArmorChest_SpeedSet_Tier03",
    "KratosArmorChest_SpeedSet_Tier04",
    "KratosArmorChest_SpeedSet_Tier05",
    "KratosArmorChest_SpeedSet_Tier06",
    "KratosArmorChest_MspSpeedSet_Tier06",
    "KratosArmorChest_NifSpeedSet_Tier06",
    "KratosArmorChest_TravelerSet_Tier06",
    "KratosArmorChest_SpeedSet_Tier02"
  }
  local meshEArmors = {
    "KratosArmorChest_SpeedSet_Tier01"
  }
  local mysteryArmors = {}
  for _, name in ipairs(origMeshArmors) do
    if name == currentArmor then
      ropeA:ShowJoint(ropeA:GetJointIndex("ropeMesh"))
      return
    end
  end
  for _, name in ipairs(meshDArmors) do
    if name == currentArmor then
      ropeA:ShowJoint(ropeA:GetJointIndex("ropeDMesh"))
      return
    end
  end
  for _, name in ipairs(meshBArmors) do
    if name == currentArmor then
      ropeA:ShowJoint(ropeA:GetJointIndex("ropeBMesh"))
      return
    end
  end
  for _, name in ipairs(meshCArmors) do
    if name == currentArmor then
      ropeA:ShowJoint(ropeA:GetJointIndex("ropeCMesh"))
      return
    end
  end
  for _, name in ipairs(meshEArmors) do
    if name == currentArmor then
      ropeA:ShowJoint(ropeA:GetJointIndex("ropeEMesh"))
      return
    end
  end
  ropeA:ShowJoint(ropeA:GetJointIndex("ropeMesh"))
end
function UpdateDockingSystemOnBoatEnter()
  boatPuppeteerHelper:CallScript("NotifyDockSystem_PlayerEnteringBoat", boat)
end
function Complete_Caldera_Objective360()
  game.QuestManager.ProposeQuestState("Quest_Caldera_Objective370", "Complete")
  game.Compass.SetDesignerForcedHide(false)
end
function BOOKMARK_21_RiverPass_030_ToTheVault()
  local bookmarks = require("design.Bookmarks")
  local tableEntry = bookmarks["BOOKMARK_" .. "21_RiverPass_030_ToTheVault"]
  game.World.StoreCheckpointAndBookmark(tableEntry)
end
function StartCineEnter_DemigodReveal()
  game.SubObject.Wake(thisObj)
  cameraCineEnter_DemigodReveal = CCEC.CineEnterCamera.New("ENV_CineEnter_DemigodReveal", 8)
  cameraCineEnter_DemigodReveal:SetCallback(DestroyCineEnter_DemigodReveal)
  cameraCineEnter_DemigodReveal:Start()
end
function DestroyCineEnter_DemigodReveal()
  cameraCineEnter_DemigodReveal = nil
  game.SubObject.Sleep(thisObj)
end
function SetBoatSpeed()
  local data = {}
  data.TargetMaxSpeed = 8
  data.TargetMaxRotationSpeed = 80
  data.TargetAcceleration = 12.5
  data.TargetAngularAcceleration = 160
  data.MaxSpeedChangeRate = 6
  data.MaxRotationSpeedChangeRate = 100
  data.AccelerationChangeRate = 6
  data.AngularAccelerationChangeRate = 100
  game.Boat.SetGlobalSpeedControlData(data)
end
function Enable_ClearBoatSpeedZone()
  if game.FindLevel("Cal225_RiverPassLH") ~= nil then
    game.FindLevel("Cal225_RiverPassLH"):CallScript("EnableBoatSpeedClearZone")
  end
end
function SetPreventNoTowerBanterFact()
  game.Audio.SetBanterFact("preventNoTower", true, "Forever")
end
