local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local checkpoint = require("level.checkpoint")
local actor = require("narrative.actor")
local timer = require("level.timer")
local uiCalls = require("ui.uicalls")
local CCEC = require("camera.camera_cineentercamera")
local thisObj, thisLevel, player, kraActor, sonActor, darkOneEliteActor, darkOneActor, darkOne1Actor, DarkOne, DarkOne1, darkOneSpear, pillarProp
local sonGapCarry = false
sonFight = game.Level.SetVariable("SON_SoloMode")
local cine_lights_A, cine_lights_B, cine_lights_C
local bPartAStruggle = false
local bPartBStruggle = false
local bTriggerBanterOnce = false
local bTriggerBanterOnce2 = false
local bPostSonGapFight = false
myTimer = nil
local cameraCineEnter_SonGapCarryEnter, cameraCineEnter_EnterPillar
function OnScriptLoaded(level, go)
  thisObj = go
  thisLevel = level
  player = game.Player.FindPlayer()
  InitializeVariables()
  cine_lights_A = GameObjects.Cine_Start_230A
  cine_lights_B = GameObjects.Cine_Struggle_230B
  cine_lights_C = GameObjects.Cine_End_230C
  HideCineLights_A()
  HideCineLights_B()
  HideCineLights_C()
end
function OnStart(level, go)
  SetupPillar()
end
function OnUpdate(level, go)
  if player:IsPlayingMove("MOV_AlfSonGapCarryRageIdle") and bPartAStruggle == false and bTriggerBanterOnce == false then
    game.Audio.PlayBanter("SonGapSpearStruggle1")
    LD.CallFunctionAfterDelay(PartAStruggleBanterB, 10)
    bTriggerBanterOnce = true
  end
  if player:IsPlayingMove("MOV_AlfSonGapCarryPillarIdle") and bPartBStruggle == false and bTriggerBanterOnce2 == false then
    game.Audio.PlayBanter("SonGapWyrmSmashStruggle1")
    LD.CallFunctionAfterDelay(PartBStruggleBanterB, 10)
    bTriggerBanterOnce2 = true
  end
  if LD.GetEntityVariable("KidnapPostFightOver") == true and bPostSonGapFight == false then
    LD.CallFunctionAfterDelay(function()
      game.Audio.PlayBanter("PostSonGapFight")
    end, 1.2)
    bPostSonGapFight = true
    GameObjects.Btr_NoWayAcross:ShowEntityVolume()
    GameObjects.Btr_NoWayAcross_2:ShowEntityVolume()
  end
  if cameraCineEnter_SonGapCarryEnter ~= nil then
    cameraCineEnter_SonGapCarryEnter:Update()
  end
  if cameraCineEnter_EnterPillar ~= nil then
    cameraCineEnter_EnterPillar:Update()
  end
end
function OnUseWorld(level, obj)
end
function OnSaveCheckpoint(level, obj)
  local savedInfo = {sonGapCarry = sonGapCarry, bPostSonGapFight = bPostSonGapFight}
  savedInfo.LevelState = checkpoint.Save()
  return savedInfo
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  checkpoint.Restore(savedInfo.LevelState)
  sonGapCarry = savedInfo.sonGapCarry
  bPostSonGapFight = savedInfo.bPostSonGapFight
end
function InitializeVariables()
  if sonGapCarry == false then
    sonGapCarry = true
    CreateActors()
    SpawnCineDarkOnes()
    SpawnDarkOne()
    SpawnDarkOne1()
    SpawnDarkOneElite()
  end
end
function CreateActors()
  kraActor = actor.Actor.New("SON GAP CARRY PART 1: Kratos", game.Player.FindPlayer)
  sonActor = actor.Actor.New("SON GAP CARRY PART 1: Son", game.AI.FindSon)
  darkOneEliteActor = actor.Actor.New("SON GAP CARRY PART 1+2: Dark One Elite")
  darkOneActor = actor.Actor.New("SON GAP CARRY PART 2: Dark One")
  darkOne1Actor = actor.Actor.New("SON GAP CARRY PART 2: Dark One 1")
end
function SpawnCineDarkOnes()
  darkOneSpear = GameObjects.darkOneSpear00CineProp.Child
  darkOneSpear:SetCharacterConfig("spear")
  DarkOne = GameObjects.DarkOneCine.Child
  DarkOne1 = GameObjects.DarkOneCine1.Child
  HideDarkOnes()
end
function SetupPillar()
  pillarProp = GameObjects.pillarBreak00_Top.Child
  pillarProp:JumpAnimationToFrame(0, {
    Animation = "narAlfSonGapCarry040IntEnterPillar"
  })
  pillarProp:PauseAnimation()
  pillarProp:Hide()
end
function HidePillar()
  pillarProp:Hide()
end
function SpawnDarkOneElite()
  darkOneEliteActor:SetSpawnFunction(function()
    return ND.SpawnAIAtJoint(thisLevel, "Cine_SonGapCarryCine", "eliteOne_SonGapCarry_StartJoint", "CRT_DarkOneElite00", "BRA_AlfSonGapCarryEnter", "darkOneElite")
  end)
end
function SpawnDarkOne()
  darkOneActor:SetSpawnFunction(function()
    return ND.SpawnAIAtJoint(thisLevel, "Cine_SonGapCarryCine", "darkOne_SonGapCarry2_StartJoint", "CRT_DarkOne00", "BRA_AlfSonGapCarryEnterPillar", "darkOne1", {PowerLevel = "2", Variant = "QuickSpear"})
  end)
end
function SpawnDarkOne1()
  darkOne1Actor:SetSpawnFunction(function()
    return ND.SpawnAIAtJoint(thisLevel, "Cine_SonGapCarryCine", "darkOne1_SonGapCarry2_StartJoint", "CRT_DarkOne00", "BRA_AlfSonGapCarryEnterPillar1", "darkOne2", {PowerLevel = "2", Variant = "QuickSpear"})
  end)
end
function SonGapCarry_Part1_Sequence()
  if LD.GetEntityVariable("ALF_LightAcquired") == false then
    local cineSeq = ND.CreateCineSequence(thisLevel, thisObj, "Son Gap Carry Part 1")
    local sonGapCarryPart1_ActorTable = {
      {
        Actor = sonActor,
        Branch = "BRA_AlfSonGapCarryEnter"
      },
      {
        Actor = darkOneEliteActor,
        Branch = "BRA_AlfSonGapCarryEnter"
      },
      {
        Obj = DarkOne,
        Anim = "narAlfSonGapCarry000CineEnter"
      },
      {
        Obj = DarkOne1,
        Anim = "narAlfSonGapCarry000CineEnter1"
      },
      {
        Obj = darkOneSpear,
        Anim = "narAlfSonGapCarry000CineEnter"
      }
    }
    cineSeq:RequestCineModeAndWait(kraActor, thisObj)
    cineSeq:Do(StartCineEnter_SonGapCarry)
    cineSeq:ActorForceApproachAndWait(kraActor, {
      Branch = "BRA_AlfSonGapCarryEnter",
      ReferenceJoint = "sonGapCarry_Part1_SynchJoint",
      speed = ND.KraWalkSpeed,
      stop = false,
      radius = ND.InteractStopDistance,
      weapon_state = "bare_on_back"
    })
    cineSeq:SpawnActorAndWait(darkOneEliteActor)
    cineSeq:Do(ShowDarkOnes)
    cineSeq:Do(PlayCineLights_A)
    cineSeq:Do(HideCineLights_B)
    cineSeq:ActorSync(kraActor, {
      Slaves = sonGapCarryPart1_ActorTable,
      Branch = "BRA_AlfSonGapCarryEnter",
      ReferenceJoint = "sonGapCarry_Part1_SynchJoint"
    })
    cineSeq:WaitForAndCompleteCineMode(kraActor, thisObj)
    cineSeq:Do(HideCineLights_A)
    cineSeq:StopPuppetingActor(kraActor)
    cineSeq:Do(HideDarkOnes)
    cineSeq:Do(ShowSonGapCarryBlocker)
    cineSeq:Do(SonDefendingSoloIdle)
    cineSeq:DespawnActor(darkOneEliteActor)
    cineSeq:StartSequence()
  end
end
function ShowSonGapCarryBlocker()
  GameObjects.SonGapCarryBlocker:JumpAnimToPercent(1)
  GameObjects.LeadTheWay345.LuaObjectScript.Disable()
end
function SonDefendingSoloIdle()
  local sonDefendingSeq = ND.CreateCineSequence(thisLevel, thisObj, "Son Defending Solo")
  local sonDefending_ActorTable = {
    {
      Actor = darkOneActor,
      Branch = "BRA_AlfSonGapCarrySoloIdle"
    },
    {
      Actor = darkOne1Actor,
      Branch = "BRA_AlfSonGapCarrySoloIdle1"
    }
  }
  sonDefendingSeq:SpawnActorAndWait(darkOneActor)
  sonDefendingSeq:SpawnActorAndWait(darkOne1Actor)
  sonDefendingSeq:ActorSync(sonActor, {
    Slaves = sonDefending_ActorTable,
    Branch = "BRA_AlfSonGapCarrySoloIdle",
    ReferenceJoint = "sonGapCarry_Part2_SynchJoint"
  })
  sonDefendingSeq:StartSequence()
end
function LuaHook_ShowRageModeUIMessage()
  uiCalls.EnableMechanicRage()
end
function SonGapTimerToFail(thisLevel, thisObj)
  myTimer = timer.StartLevelTimer(40, SonGapCarryFail)
end
function SonGapCarryFail()
  local sonGapFailSeq = ND.CreateCineSequence(thisLevel, thisObj, "Son Gap Carry Fail")
  local sonGapFail_ActorTable = {
    {
      Obj = DarkOne,
      Anim = "narAlfSonGapCarry020IntRageFail"
    },
    {
      Obj = DarkOne1,
      Anim = "narAlfSonGapCarry020IntRageFail1"
    },
    {
      Obj = darkOneSpear,
      Anim = "narAlfSonGapCarry020IntRageFail"
    }
  }
  sonGapFailSeq:ActorSync(kraActor, {
    Slaves = sonGapFail_ActorTable,
    Branch = "BRA_AlfSonGapCarryFail",
    ReferenceJoint = "sonGapCarry_Part1_SynchJoint"
  })
  sonGapFailSeq:WaitForActorPuppeteerComplete(kraActor)
  sonGapFailSeq:StopPuppetingActor(kraActor)
  sonGapFailSeq:StartSequence()
  uiCalls.DisableMechanicRage()
end
function PartAStruggleBanterB()
  if bPartAStruggle == false then
    game.Audio.PlayBanter("SonGapSpearStruggle2")
    LD.CallFunctionAfterDelay(PartAStruggleBanterC, 10)
  end
end
function PartAStruggleBanterC()
  if bPartAStruggle == false then
    game.Audio.PlayBanter("SonGapSpearStruggle3")
  end
end
function SonGapCarrySuccess(thisLevel, thisObj)
  myTimer:Stop()
  player:CallScript("LuaHook_AlfheimRageMomentEnter")
  bPartAStruggle = true
  DarkOne1:StartAnim("narAlfSonGapCarry030CineRageScene1")
  GameObjects.Trench01KidnapZone:ShowEntityVolume()
  uiCalls.UI_Event_TurnOffDesignerMessage()
end
function HideDarkOnes()
  DarkOne:Hide()
  DarkOne1:Hide()
  darkOneSpear:Hide()
end
function ShowDarkOnes()
  DarkOne:Show()
  DarkOne1:Show()
  darkOneSpear:Show()
end
function PlayCineLights_A()
  cine_lights_A:Show()
  cine_lights_A:JumpAnimToFrame(0)
  cine_lights_A:PlayAnimToEnd()
end
function SonGapCarry_Part2_Sequence()
  local cineSeq2 = ND.CreateCineSequence(thisLevel, thisObj, "Son Gap Carry Part 2")
  local sonGapCarryPart2_ActorTable = {
    {
      Actor = sonActor,
      Branch = "BRA_AlfSonGapCarryEnterPillar"
    },
    {
      Actor = darkOneEliteActor,
      Branch = "BRA_AlfSonGapCarryEnterPillar"
    },
    {
      Actor = darkOneActor,
      Branch = "BRA_AlfSonGapCarryEnterPillar"
    },
    {
      Actor = darkOne1Actor,
      Branch = "BRA_AlfSonGapCarryEnterPillar1"
    },
    {
      Obj = GameObjects.Dragon_head_fall_punchin.Child,
      Anim = "Default"
    }
  }
  cineSeq2:SpawnActorAndWait(darkOneActor)
  cineSeq2:SpawnActorAndWait(darkOne1Actor)
  cineSeq2:SpawnActorAndWait(darkOneEliteActor)
  cineSeq2:RequestCineModeAndWait(kraActor, thisObj, true)
  cineSeq2:Do(EnableManualCineMode)
  cineSeq2:Do(StartCineEnter_EnterPillar)
  cineSeq2:ActorForceApproachAndWait(kraActor, {
    Branch = "BRA_AlfSonGapCarryEnterPillar",
    ReferenceJoint = "sonGapCarry_Part2_SynchJoint",
    speed = ND.KraRunSpeed,
    stop = false,
    radius = ND.InteractStopDistance,
    strafe_distance = 1.5
  })
  cineSeq2:ActorSync(kraActor, {
    Slaves = sonGapCarryPart2_ActorTable,
    Branch = "BRA_AlfSonGapCarryEnterPillar",
    ReferenceJoint = "sonGapCarry_Part2_SynchJoint"
  })
  cineSeq2:WaitForActorPlayingMove(kraActor, "MOV_AlfSonGapCarryPillarScene")
  cineSeq2:SetPostSkipMusic("SND_MX_ALF_start_master", nil, nil, nil, "SND_MX_ALF_trench_pillar_fight_in")
  cineSeq2:Do(function()
    cineSeq2:MarkAbleToSkip()
  end)
  cineSeq2:Do(function()
    darkOne1Actor:GetCreature():TriggerMoveEvent("LE_AlfSonGapCarryPillarScene1")
  end)
  cineSeq2:Do(function()
    darkOneActor:GetCreature():TriggerMoveEvent("LE_AlfSonGapCarryPillarScene")
  end)
  cineSeq2:WaitUntilActorAnimPastPercentage(kraActor, 0.4)
  cineSeq2:Do(function()
    player:CallScript("LuaHook_AlfheimRageMomentExit")
  end)
  cineSeq2:WaitForAndCompleteCineMode(kraActor, thisObj)
  cineSeq2:StopPuppetingActor(kraActor)
  cineSeq2:StopPuppetingActor(sonActor)
  cineSeq2:Do(SwapDragonHead)
  cineSeq2:DespawnActor(darkOneActor)
  cineSeq2:DespawnActor(darkOne1Actor)
  cineSeq2:DespawnActor(darkOneEliteActor)
  cineSeq2:Do(HideCineLights_B)
  cineSeq2:Do(HideCineLights_A)
  cineSeq2:Do(HideCineLights_C)
  cineSeq2:SetCompletedCineNumber(230)
  cineSeq2:StartSequence()
end
function EnableManualCineMode()
  game.Cinematics.EnableCinematicMode()
  local pad = game.Player.FindPlayer().Pad
  pad:DisableGameButton(tweaks.ePad.kPadUp)
end
function SwapDragonHead()
  GameObjects.Col_DragonHead:HideCollision()
  GameObjects.Dragon_head_fall_break:Hide()
  GameObjects.FakeSnakeHead:Show()
  GameObjects.FakeSnakeHead:ShowCollision()
end
function PlayCineLights_B()
  cine_lights_B:Show()
  cine_lights_B:JumpAnimToFrame(0)
  cine_lights_B:PlayAnimToEnd()
end
function HideCineLights_A()
  cine_lights_A:Hide()
end
function HideCineLights_B()
  cine_lights_B:Hide()
end
function PlayCineLights_C()
  cine_lights_C:Show()
  cine_lights_C:JumpAnimToFrame(0)
  cine_lights_C:PlayAnimToEnd()
end
function HideCineLights_C()
  cine_lights_C:Hide()
end
function PartBStruggleBanterB()
  if bPartBStruggle == false then
    game.Audio.PlayBanter("SonGapWyrmSmashStruggle2")
    LD.CallFunctionAfterDelay(PartBStruggleBanterC, 10)
  end
end
function PartBStruggleBanterC()
  if bPartBStruggle == false then
    game.Audio.PlayBanter("SonGapWyrmSmashStruggle3")
  end
end
function PillarEnterPillar(thisLevel, thisObj)
  pillarProp:Show()
  timer.StartLevelTimer(5.1, function()
    GameObjects.Dragon_head_fall_break:Hide()
  end)
  pillarProp:PlayAnimationToEnd({
    Animation = "narAlfSonGapCarry040IntEnterPillar"
  })
  PlayCineLights_B()
  HideCineLights_A()
end
function PillarKratosPillarIdle(thisLevel, thisObj)
  pillarProp:StartAnim("narAlfSonGapCarry050IntKratosPillarIdle")
end
function PillarEnterPillarPush(thisLevel, thisObj)
  pillarProp:StartAnim("narAlfSonGapCarry065IntEnterPillarPush")
end
function PillarPillarPush(thisLevel, thisObj)
  pillarProp:StartAnim("narAlfSonGapCarry070IntPillarPush")
end
function PillarPillarFail(thisLevel, thisObj)
  pillarProp:StartAnim("narAlfSonGapCarry080IntPillarFail")
end
function PillarPillarScene(thisLevel, thisObj)
  pillarProp:Hide()
  bPartBStruggle = true
  GameObjects.Dragon_head_fall_break:Show()
  HideCineLights_B()
  PlayCineLights_C()
end
function NoWayAcrossBanter()
  return game.Level.GetVariable("KidnapPostFightOver") and game.Level.GetVariable("CompletedCineNumber") < 242
end
function HideNoWayAcrossBanterZones()
  GameObjects.Btr_NoWayAcross:Hide()
  GameObjects.Btr_NoWayAcross_2:Hide()
end
function StartCineEnter_SonGapCarry()
  cameraCineEnter_SonGapCarryEnter = CCEC.CineEnterCamera.New("ENV_CineEnter_SonGapCarry", 8)
  cameraCineEnter_SonGapCarryEnter:SetCallback(DestroyCineEnter_SonGapCarry)
  cameraCineEnter_SonGapCarryEnter:Start()
end
function DestroyCineEnter_SonGapCarry()
  cameraCineEnter_SonGapCarryEnter = nil
end
function StartCineEnter_EnterPillar()
  cameraCineEnter_EnterPillar = CCEC.CineEnterCamera.New("ENV_CineEnter_EnterPillar", 8)
  cameraCineEnter_EnterPillar:SetCallback(DestroyCineEnter_EnterPillar)
  cameraCineEnter_EnterPillar:Start()
end
function DestroyCineEnter_EnterPillar()
  cameraCineEnter_EnterPillar = nil
end
