local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local timer = require("level.timer")
local monitors = require("level.MonitorLibrary")
local checkpoint = require("level.checkpoint")
local actor = require("narrative.actor")
local CCEC = require("camera.camera_cineentercamera")
local TUT = require("game.GlobalTutorials")
local thisObj, thisLevel, candlesA, candlesB, candlesC, tableA, flintA, bandage, body, mistletoeleaves, snowball, kratosActor, sonActor, logActor, mothersKnife_ActorTable, bLeadTheWay
local btrGateSlip = "030_GateSlip"
local cine_lights, cameraCineEnter
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  cameraCineEnter = CCEC.CineEnterCamera.New("ENV_CineEnter_For200_MothersKnife", 15.3, nil)
  cameraCineEnter:SetObjectToSleep(obj)
  HideCameraZones()
  game.SubObject.Sleep(obj)
end
function OnUpdate(level, obj)
  if cameraCineEnter ~= nil then
    cameraCineEnter:Update()
  end
end
function OnStart(level, obj)
  CreateActors()
  CreateProps()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if cineNum < 20 then
    AlignProps()
  end
  if 20 <= cineNum and cineNum < 72 then
    SetBodyOnPyre()
  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 CreateActors()
  kratosActor = actor.Actor.New("Kratos", game.Player.FindPlayer)
  sonActor = actor.Actor.New("Son", game.AI.FindSon)
  logActor = actor.Actor.New("Log", FindLog)
end
function FindLog()
  local logObjs = game.World.FindGameObjectsByMarker("log00")
  if logObjs then
    return logObjs[1]
  else
    return nil
  end
end
function CreateProps()
  candlesA = GameObjects.mothersCandles00A.Child
  candlesB = GameObjects.mothersCandles00B.Child
  candlesC = GameObjects.smallCandle00A.Child
  tableA = GameObjects.mothersTable00A.Child
  flintA = GameObjects.flint00A.Child
  bandage = GameObjects.sonBandage00A.Child
  body = GameObjects.motherBody00A.Child
  mistletoeleaves = GameObjects.mistletoeLeaves00A.Child
  snowball = GameObjects.snowball00A.Child
  HideProps()
  cine_lights = GameObjects.Cine_Start_20
  HideCineLights()
end
function AlignProps()
  candlesA:JumpAnimationToFrame(0, {
    Animation = "narProMothersKnife000CineScene"
  })
  candlesA:PauseAnimation()
  candlesB:JumpAnimationToFrame(0, {
    Animation = "narProMothersKnife000CineScene1"
  })
  candlesB:PauseAnimation()
  candlesC:JumpAnimationToFrame(0, {
    Animation = "narProMothersKnife000CineScene"
  })
  candlesC:PauseAnimation()
  tableA:JumpAnimationToFrame(0, {
    Animation = "narProMothersKnife000CineScene"
  })
  tableA:PauseAnimation()
  flintA:JumpAnimationToFrame(0, {
    Animation = "narProMothersKnife000CineScene"
  })
  flintA:PauseAnimation()
  bandage:JumpAnimationToFrame(0, {
    Animation = "narProMothersKnife000CineScene"
  })
  bandage:PauseAnimation()
  body:JumpAnimationToFrame(0, {
    Animation = "narProMothersKnife000CineScene"
  })
  body:PauseAnimation()
  mistletoeleaves:JumpAnimationToFrame(0, {
    Animation = "narProMothersKnife000CineScene"
  })
  mistletoeleaves:PauseAnimation()
  snowball:JumpAnimationToFrame(0, {
    Animation = "narProMothersKnife000CineScene"
  })
  snowball:PauseAnimation()
end
function BuildCineSequence()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  local cloth = GameObjects.retrieveBladesCloth
  cloth:JumpAnimToFrame(0)
  cloth:PauseAnim()
  if 15 <= cineNum and cineNum < 20 then
    local mothersKnifeSeq = ND.CreateCineSequence(thisLevel, thisObj, "mothersKnife")
    local mothersKnife_ActorTable = {
      {
        Actor = sonActor,
        Branch = "BRA_MothersKnife"
      },
      {
        Obj = candlesA,
        Anim = "narProMothersKnife000CineScene"
      },
      {
        Obj = candlesB,
        Anim = "narProMothersKnife000CineScene1"
      },
      {
        Obj = candlesC,
        Anim = "narProMothersKnife000CineScene"
      },
      {
        Obj = tableA,
        Anim = "narProMothersKnife000CineScene"
      },
      {
        Obj = flintA,
        Anim = "narProMothersKnife000CineScene"
      },
      {
        Obj = bandage,
        Anim = "narProMothersKnife000CineScene"
      },
      {
        Obj = body,
        Anim = "narProMothersKnife000CineScene"
      },
      {
        Obj = mistletoeleaves,
        Anim = "narProMothersKnife000CineScene"
      },
      {
        Obj = snowball,
        Anim = "narProMothersKnife000CineScene"
      }
    }
    if logActor:GetCreature() ~= nil then
      print("MothersKnife cinematic - log is present")
      table.insert(mothersKnife_ActorTable, {
        Actor = logActor,
        Branch = "BRA_MothersKnife"
      })
    else
      print("MothersKnife cinematic - log is not present")
    end
    mothersKnifeSeq:SetPostSkipMusic("SND_MX_PRO_start_master")
    mothersKnifeSeq:WaitForLoadCheck("For200_c020_MothersKnife")
    local doorObj = GameObjects.KratosHouseDoorA.Child
    mothersKnifeSeq:RequestCineModeAndWait(kratosActor, thisObj)
    mothersKnifeSeq:Do(StartPreCineCamera)
    mothersKnifeSeq:Do(IncreaseKratosDeceleration)
    mothersKnifeSeq:ActorForceApproachAndWait(kratosActor, {
      Branch = "BRA_MothersKnife",
      ReferenceJoint = "MothersKnife_SyncJoint",
      speed = 0.9,
      stop = false,
      radius = 0.1
    })
    mothersKnifeSeq:Do(ClearKratosDeceleration)
    mothersKnifeSeq:Do(PlayCineBLights)
    mothersKnifeSeq:Do(PlayProps)
    mothersKnifeSeq:Do(function()
      game.World.DisablePlayerStateSoftSave()
    end)
    mothersKnifeSeq:Do(DisableFaceSwapping)
    mothersKnifeSeq:ActorSync(kratosActor, {
      Slaves = mothersKnife_ActorTable,
      Branch = "BRA_MothersKnife",
      ReferenceJoint = "MothersKnife_SyncJoint"
    })
    mothersKnifeSeq:Do(function()
      doorObj:StartAnim("narProMothersKnife000CineScene")
    end)
    mothersKnifeSeq:Do(UpdatePyreGeo)
    mothersKnifeSeq:WaitUntilActorAnimPastPercentage(kratosActor, 0.075)
    mothersKnifeSeq:Do(function()
      mothersKnifeSeq:MarkAbleToSkip()
    end)
    mothersKnifeSeq:WaitUntilActorAnimPastPercentage(kratosActor, 0.1)
    mothersKnifeSeq:Do(function()
      game.Wallets.AddResource("HERO", "KratosArmorWrist_Starter_Tier00", 1, "NO_TELEMETRY")
      game.UI.ClearNotification("Resource", "KratosArmorWrist_Starter_Tier00")
    end)
    mothersKnifeSeq:Do(ActivateBracersNGPlus)
    mothersKnifeSeq:WaitUntilActorAnimPastPercentage(kratosActor, 0.87)
    mothersKnifeSeq:Do(function()
      bandage:Hide()
    end)
    mothersKnifeSeq:WaitUntilActorAnimPastPercentage(kratosActor, 0.95)
    mothersKnifeSeq:Do(DisableDoor)
    mothersKnifeSeq:Do(DisablePreviousLeadTheWay)
    mothersKnifeSeq:Do(EnableLeadTheWay)
    mothersKnifeSeq:Do(CameraHideForcedSplineVolumes)
    mothersKnifeSeq:Do(function()
      mothersKnifeSeq:SetMaxSkipSpeedup(3)
    end)
    mothersKnifeSeq:WaitForFunctionTrue(function()
      return not sonActor:GetCreature():IsPlayingMove("MOV_MothersKnife")
    end)
    mothersKnifeSeq:DespawnActor(logActor)
    mothersKnifeSeq:StopPuppetingActor(sonActor)
    mothersKnifeSeq:Do(SetIdleContext_LeadTheWay)
    mothersKnifeSeq:WaitSeconds(4)
    mothersKnifeSeq:Do(StartQuest_BeginHunt)
    mothersKnifeSeq:Do(function()
      LD.EnableContextBehaviorBanter()
    end)
    mothersKnifeSeq:WaitForAndCompleteCineMode(kratosActor, thisObj)
    mothersKnifeSeq:StopPuppetingActor(kratosActor)
    mothersKnifeSeq:Do(EnableFaceSwapping)
    mothersKnifeSeq:Do(SpawnInGameFireFX)
    mothersKnifeSeq:Do(HideCineLights)
    mothersKnifeSeq:Do(HideTableAndProps)
    mothersKnifeSeq:Do(ShowCameraZones)
    mothersKnifeSeq:SetCompletedCineNumber(20)
    mothersKnifeSeq:Do(function()
      game.AI.FindSon():CallScript("LuaHook_ToggleSlowdownStops", false)
    end)
    mothersKnifeSeq:Do(function()
      LD.CallFunctionAfterDelay(function()
        TUT.BasicMove_Tutorial()
      end, 0.25)
    end)
    mothersKnifeSeq:Do(function()
      game.World.EnablePlayerStateSoftSave()
    end)
    mothersKnifeSeq:Do(function()
      local bookmarks = require("design.Bookmarks")
      local tableEntry = bookmarks["BOOKMARK_" .. "01_Forest_010_HuntStarts"]
      game.World.StoreCheckpointAndBookmark(tableEntry)
    end)
    mothersKnifeSeq:Do(function()
      LD.CallFunctionAfterDelay(function()
        game.Audio.PlayBanter(btrGateSlip)
      end, 1.6)
    end)
    mothersKnifeSeq:StartSequence()
  end
end
function DisableFaceSwapping()
  if game.PhotoMode.SetFaceChangeEnabled then
    game.PhotoMode.SetFaceChangeEnabled(false)
  end
end
function EnableFaceSwapping()
  if game.PhotoMode.SetFaceChangeEnabled then
    game.PhotoMode.SetFaceChangeEnabled(true)
  end
end
function StartQuest_BeginHunt()
  LD.CompleteQuest("Quest_Forest_Objective100")
  if game.InitEntitlementsResources then
    game.InitEntitlementsResources()
  end
  local tutorialRunes = game.Wallets.GetRunesWithFlags("HERO", {
    "RuneCreator_Unique_T2Starter"
  })
  if tutorialRunes ~= nil and #tutorialRunes == 0 then
    game.Wallets.GenerateRune("HERO", "RuneCreator_Unique_T2Starter")
  end
end
function SetIdleContext_LeadTheWay()
  game.AI.FindSon():CallScript("EnterBehaviorContext", "LEAD_THE_WAY_BEHAVIOR_CONTEXT_CONFIG")
end
function UpdatePyreGeo()
  local cineWad = game.FindLevel("For200_c020_MothersKnife")
  if cineWad ~= nil then
    cineWad:CallScript("ShowCompletedPyre")
  end
end
function SpawnInGameFireFX()
  local cineWad = game.FindLevel("For200_c020_MothersKnife")
  if cineWad ~= nil then
    cineWad:CallScript("ShowCheapPyreFX")
  end
end
function DisablePreviousLeadTheWay()
  local for101 = game.FindLevel("For101_RiverToHouse")
  if for101 ~= nil then
    for101:GetGameObject("LogCarry_PlayerNavCurve").Child:CallScript("Disable")
    for101:GetGameObject("Cine_LogBoatExit"):CallScript("DisableBoatToHouseLTW")
  end
end
function EnableLeadTheWay()
  local for000_sky = game.FindLevel("For000_Sky")
  for000_sky:CallScript("EnableLeadTheWay")
end
function DisableDoor()
  local kratosHouseDoor = GameObjects.KratosHouseDoorA.Child
  kratosHouseDoor.LuaObjectScript.Disable()
end
function SetBodyOnPyre()
  body:Show()
  body:JumpAnimationToFrame(body.AnimLengthFrames)
end
function PlayProps()
  candlesA:Show()
  candlesB:Show()
  candlesC:Show()
  tableA:Show()
  mistletoeleaves:Show()
  body:Show()
  bandage:Show()
  _G.ShowTrapDoorRug()
end
function HideProps()
  candlesA:Hide()
  candlesB:Hide()
  candlesC:Hide()
  tableA:Hide()
  mistletoeleaves:Hide()
  bandage:Hide()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if 72 <= cineNum then
    body:Hide()
  end
end
function HideTableAndProps()
  candlesA:Hide()
  candlesB:Hide()
  candlesC:Hide()
  tableA:Hide()
  mistletoeleaves:Hide()
  GameObjects.SCRIPT_OFF_Mothersknife_CINE:Hide()
  _G.HideTrapDoorRug()
end
function ActivateBracersNGPlus()
  local player = game.Player.FindPlayer()
  if player:PickupIsAcquired("Blades") then
    local currentWrist = player:PickupGetPickupNameInSlot("ArmorWrist")
    if currentWrist ~= "" then
      player:PickupActivate(currentWrist)
    end
  end
end
function PlayCineBLights()
  cine_lights:Show()
  cine_lights:JumpAnimToFrame(0)
  cine_lights:PlayAnimToEnd()
end
function HideCineLights()
  cine_lights:Hide()
end
function StartPreCineCamera()
  cameraCineEnter:Start()
end
function CameraHideForcedSplineVolumes()
  GameObjects.CamZone_LogCarry_Forced_020:HideCameraVolume()
  GameObjects.CamZone_LogCarry_Forced_030:HideCameraVolume()
end
function IncreaseKratosDeceleration()
  game.Player.FindPlayer():SetDecelerationOverride(1.2)
  game.Player.FindPlayer():SetAccelerationOverride(1.2)
end
function ClearKratosDeceleration()
  game.Player.FindPlayer():ClearDecelerationOverride()
  game.Player.FindPlayer():ClearAccelerationOverride()
end
function SetCameraZoneVisibility(zonename, bVisible)
  local camzone = thisLevel:GetGameObject(zonename)
  if bVisible == true then
    camzone:ShowCameraVolume()
  else
    camzone:HideCameraVolume()
  end
end
function HideCameraZones()
  SetCameraZoneVisibility("IndoorBaseNav_UnderneathShed", false)
  SetCameraZoneVisibility("OutDoorWideNav_BackOfHouse", false)
end
function ShowCameraZones()
  SetCameraZoneVisibility("IndoorBaseNav_UnderneathShed", true)
  SetCameraZoneVisibility("OutDoorWideNav_BackOfHouse", true)
end
