local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local timers = require("level.timer")
local monitors = require("level.MonitorLibrary")
local actor = require("narrative.actor")
local thisObj, thisLevel, player
local bFirstHeimili = false
local sonActor, freyaActor, turtle, firstHeimili_actorTable, deer2Actor, deer3Actor, deer4Actor, boar1, boar2, crow1, crow2, crow3, heimili_start
local turtle_standing = false
local turtleFrameMonitor, SNDBoar, SNDElk
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  player = game.Player.FindPlayer()
  game.SubObject.Sleep(obj)
end
function OnStart()
  if game.Level.GetVariable("CompletedCineNumber") >= 160 then
    HideWildlife()
  end
end
function OnUpdate(level, obj)
end
function OnSaveCheckpoint(level, obj)
  local savedInfo = {}
  savedInfo.bFirstHeimili = bFirstHeimili
  return savedInfo
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  bFirstHeimili = savedInfo.bFirstHeimili
end
function CreateActors()
  sonActor = actor.Actor.New("Son", game.AI.FindSon)
  freyaActor = actor.Actor.New("Freya", LD.FindFreya)
  turtle = game.FindLevel("Riv480_FreyaHouse"):GetGameObject("freyaCreature").Child
  firstHeimili_actorTable = {
    {Actor = freyaActor},
    {
      Obj = turtle,
      Anim = "poiRivFirstHeimili020Scene"
    }
  }
end
function CreateWildlifeActors()
  deer2Actor = actor.Actor.New("deer2")
  deer3Actor = actor.Actor.New("deer3")
  deer4Actor = actor.Actor.New("deer4")
  SetupWildlifeProps()
  SetSpawnFunctions()
end
function SetupWildlifeProps()
  boar1 = GameObjects.boar1.Child
  boar2 = GameObjects.boar2.Child
  crow1 = GameObjects.Animatedcrow1.Child
  crow2 = GameObjects.Animatedcrow2.Child
  crow3 = GameObjects.Animatedcrow3.Child
end
function SetSpawnFunctions()
  local cineWad = game.FindLevel("Riv480_c160_WitchHouseA")
  deer2Actor:SetSpawnFunction(function()
    return ND.SpawnAIAtJoint(cineWad, "POI_FirstHeimili", "Freya_Start", "CRT_Deer00", "BRA_DeerWildlife2_Idle", "deer2")
  end)
  deer3Actor:SetSpawnFunction(function()
    return ND.SpawnAIAtJoint(cineWad, "POI_FirstHeimili", "Freya_Start", "CRT_Deer00", "BRA_DeerWildlife3_Idle", "deer3")
  end)
  deer4Actor:SetSpawnFunction(function()
    return ND.SpawnAIAtJoint(cineWad, "POI_FirstHeimili", "Freya_Start", "CRT_Deer00", "BRA_DeerWildlife4_Idle", "deer4")
  end)
end
function TEMPORARILY_UNHOOKED()
  print("----------------------------------actor in zone, play banter---------------------------------------")
  game.Audio.PlayBanter("RIV_FirstHeimili_A", function()
    print("----------------------------------banter A finished---------------------------------------")
    local riv480 = game.FindLevel("Riv480_FreyaHouse")
    if riv480 ~= nil then
      riv480:CallScript("CreatureStandImmediate_FirstHeimili")
      game.Audio.PlayBanter("RIV_FirstHeimili_B")
    else
      engine.Warning("Warning: attempting to get reference to Riv480, reference returned nil.")
    end
  end)
end
function BuildFirstHeimiliSeq()
  local seq = LD.CreateCineSequence(thisLevel, thisObj, "firstHeimili")
  local freyaSeq = ND.CreateCineSequence(thisLevel, thisObj, "firstHeimili_freyaApproach")
  local turtleSeq = LD.CreateCineSequence(thisLevel, thisObj, "sonPetTurtle")
  local turtle = game.FindLevel("Riv480_FreyaHouse"):GetGameObject("freyaCreature").Child
  local petTurtle_actor_table = {
    {
      Obj = turtle,
      Anim = "poiRivSonPetTurtle",
      TweenTime = 3
    }
  }
  CreateActors()
  seq:WaitForFunctionTrue(function()
    return LD.FindFreya()
  end)
  seq:WaitForActorInZone(freyaActor, GameObjects.POITriggerZone_FirstHeimili)
  seq:WaitForLoadCheck("Riv475_FreyaHouseExt")
  seq:BranchSequence(freyaSeq)
  freyaSeq:ActorForceApproachAndWait(freyaActor, {
    Branch = "BRA_FirstHeimiliIdle",
    ReferenceJoint = "FirstHeimili_SyncJoint",
    speed = 1.5,
    stop = false,
    foot = game.Creature.Foot.kRight,
    radius = 0.975
  })
  freyaSeq:ActorSync(freyaActor, {
    Branch = "BRA_FirstHeimiliIdle",
    ReferenceJoint = "FirstHeimili_SyncJoint"
  })
  seq:WaitForActorInZone(sonActor, thisObj)
  seq:ActorForceApproachAndWait(sonActor, {
    Branch = "BRA_FirstHeimili",
    ReferenceJoint = "FirstHeimili_SyncJoint",
    speed = 1.5,
    stop = false,
    radius = ND.ArrivalRadius,
    foot = game.Creature.Foot.kRight
  })
  seq:ActorSync(sonActor, {
    Slaves = firstHeimili_actorTable,
    Branch = "BRA_FirstHeimili",
    ReferenceJoint = "FirstHeimili_SyncJoint"
  })
  seq:WaitSeconds(0.6)
  seq:Do(Riv480_EndOfHeimili_TurtleMonitor)
  seq:Do(function()
    game.Audio.PlayBanter("RIV_FirstHeimili_A")
  end)
  seq:Do(game.AI.FindSon():CallScript("ClearBehaviorContext"))
  seq:WaitUntilActorAnimPastFrame(freyaActor, 193)
  seq:Do(function()
    game.Audio.PlayBanter("RIV_FirstHeimili_B")
  end)
  seq:Do(Heimili_Started)
  seq:Do(LTW_Update_FreyaPath)
  seq:WaitForFunctionTrue(function()
    return freyaActor:GetCreature():IsPlayingMove("MOV_FirstHeimili")
  end)
  seq:Do(StartTurtleShakeFrameMonitor)
  seq:BranchSequence(turtleSeq)
  turtleSeq:WaitForActorInZone(sonActor, GameObjects.POI_SonPetTurtle)
  turtleSeq:Do(function()
    timers.StartLevelTimer(0.1, function()
      game.Audio.PlayBanter("RIV_FirstHeimili_B2")
    end)
  end)
  turtleSeq:Do(function()
    GameObjects.Son_Riv475_LeadTheWay.Child.LuaObjectScript.Disable()
  end)
  turtleSeq:Do(LTW_Update_FreyaDontStop)
  turtleSeq:Do(function()
    game.AI.FindSon():SetAccelerationOverride(1.8)
  end)
  turtleSeq:ActorForceApproachAndWait(sonActor, {
    Branch = "BRA_SonPetTurtle",
    ReferenceJoint = "SonPetTurtle_SyncJoint",
    speed = ND.SonRunSpeed,
    stop = false,
    radius = ND.RunArrivalRadius,
    foot = game.Creature.Foot.kRight,
    ignore_navmesh = true
  })
  turtleSeq:Do(function()
    timers.StartLevelTimer(0.01, function()
      game.Audio.PlayBanter("RIV_FirstHeimili_B3")
    end)
  end)
  turtleSeq:Do(function()
    timers.StartLevelTimer(13.75, function()
      game.Audio.PlayBanter("RIV_FirstHeimili_B4")
    end)
  end)
  turtleSeq:ActorSync(sonActor, {
    Slaves = petTurtle_actor_table,
    Branch = "BRA_SonPetTurtle",
    ReferenceJoint = "SonPetTurtle_SyncJoint"
  })
  turtleSeq:Do(_G.DisableBoarCarryAwarenessZones)
  turtleSeq:WaitForSyncStart(game.AI.FindSon())
  turtleSeq:StopPuppetingActor(sonActor)
  seq:StopPuppetingActor(freyaActor)
  seq:Do(function()
    bFirstHeimili = true
  end)
  seq:StartSequence()
end
function LTW_Update_FreyaPath()
  local LTW_Params = {}
  LTW_Params = {LeaderDistance_Wait = 15, LeaderDistance_Continue = 8}
  GameObjects.Freya_Riv475_LeadTheWay.Child.LuaObjectScript.UpdateLeadTheWayParams(LTW_Params)
  local Son_LTW_Params = {}
  Son_LTW_Params = {
    Speed = 1.5,
    FollowerDistance_CaughtUp = 0.3,
    FollowerDistance_Continue = 0.5
  }
  GameObjects.Son_Riv475_LeadTheWay.Child.LuaObjectScript.UpdateLeadTheWayParams(Son_LTW_Params)
end
function LTW_Update_FreyaDontStop()
  local LTW_Params = {
    Speed = 1.25,
    LeaderDistance_Wait = 1000,
    LeaderDistance_Continue = 9999
  }
  GameObjects.Freya_Riv475_LeadTheWay.Child.LuaObjectScript.UpdateLeadTheWayParams(LTW_Params)
end
function Riv480_EndOfHeimili_TurtleMonitor()
  local riv480 = game.FindLevel("Riv480_FreyaHouse")
  if riv480 ~= nil then
    riv480:CallScript("EndOfHeimili_CreatureMonitor")
  else
    error("riv480 is not loaded but needs to be in order for the creature stand idle to work")
  end
end
function PlayCameraShake(nameofeffect, duration, tweenin, tweenout)
  local effect = {
    EffectName = nameofeffect,
    Duration = duration,
    TweenInTime = tweenin,
    TweenOutTime = tweenout
  }
  game.FX.SubmitEffect(effect)
end
function PlayCameraShake_FootStomp(length)
  game.Blender.Trigger({
    Name = "FSE_SHAKE_DRAGON_STEPS",
    Duration = 0.6,
    TweenIn = {Time = 0},
    TweenOut = {Time = 0.2},
    Priority = 5000
  })
  game.Blender.Trigger({
    Name = "FFB_MEDIUM",
    Duration = 0.5,
    TweenIn = {Time = 0},
    TweenOut = {Time = 0.3},
    Priority = 5000
  })
end
function PlayCameraShake_Rising()
  game.Blender.Trigger({
    Name = "FFB_GENERIC_RUMBLE_STRONG",
    Duration = 2.69,
    TweenIn = {Time = 0.2},
    TweenOut = {Time = 1.2},
    Priority = 5000,
    Weight = 0.5
  })
end
function StartTurtleShakeFrameMonitor()
  turtleFrameMonitor = monitors.CreateAnimFrameMonitor(turtle)
  assert(turtleFrameMonitor, "Couldn't create turtle frame monitor")
  turtleFrameMonitor:OnFrameForward(346, function()
    PlayCameraShake_FootStomp(1.2)
  end)
  turtleFrameMonitor:OnFrameForward(431, function()
    PlayCameraShake_FootStomp(1.2)
  end)
  turtleFrameMonitor:OnFrameForward(459, function()
    PlayCameraShake_Rising()
  end)
  turtleFrameMonitor:OnFrameForward(477, function()
    PlayCameraShake_FootStomp(1.2)
  end)
  assert(turtle.AnimLengthFrames >= 478, "Trying to destroy frame monitor after last frame check, but not enough frames in anim")
  turtleFrameMonitor:OnFrameForward(478, DestroyTurtleFrameMonitor)
end
function DestroyTurtleFrameMonitor()
  if turtleFrameMonitor ~= nil then
    turtleFrameMonitor:Stop()
    turtleFrameMonitor:Terminate()
    turtleFrameMonitor = nil
  end
end
function FreyaPathWildlifeSeq()
  if deer2Actor == nil then
    CreateWildlifeActors()
    local seq = LD.CreateCineSequence(thisLevel, thisObj, "freyaPath Wildlife")
    local idleActors = {
      {
        Actor = deer3Actor,
        Branch = "BRA_DeerWildlife3_Idle"
      },
      {
        Actor = deer4Actor,
        Branch = "BRA_DeerWildlife4_Idle"
      },
      {
        Obj = boar1,
        Anim = "FreyaHouseIntro_Boar00_0_idle01"
      },
      {
        Obj = boar2,
        Anim = "FreyaHouseIntro_Boar00_1_idle01"
      },
      {
        Obj = crow1,
        Anim = "FreyaHouseIntro_Crow00_0_idle"
      },
      {
        Obj = crow2,
        Anim = "FreyaHouseIntro_Crow00_1_idle1"
      },
      {
        Obj = crow3,
        Anim = "FreyaHouseIntro_Crow00_2_idle2"
      }
    }
    local deerRun_actors = {
      {
        Actor = deer3Actor,
        Branch = "BRA_DeerWildlife3_Cine"
      },
      {
        Actor = deer4Actor,
        Branch = "BRA_DeerWildlife4_Cine"
      }
    }
    seq:SpawnActorAndWait(deer2Actor)
    seq:SpawnActorAndWait(deer3Actor)
    seq:SpawnActorAndWait(deer4Actor)
    seq:WaitForLoadCheck("Riv480_c160_WitchHouseA")
    seq:ActorSync(deer2Actor, {
      Slaves = idleActors,
      Branch = "BRA_DeerWildlife2_Idle",
      ReferenceJoint = "WildLife_SyncJoint"
    })
    seq:Do(SetDeerSizes)
    seq:WaitSeconds(2)
    seq:Do(LoopWildlifeObjects)
    seq:WaitForFunctionTrue(function()
      return heimili_start == true
    end)
    seq:Do(CrowsFlyAway)
    seq:ActorSync(deer2Actor, {
      Slaves = deerRun_actors,
      Branch = "BRA_DeerWildlife2_Cine",
      ReferenceJoint = "WildLife_SyncJoint"
    })
    seq:WaitSeconds(13.95)
    seq:Do(SND_TriggerElkSounds)
    seq:WaitForActorPuppeteerComplete(deer2Actor)
    seq:DespawnActor(deer2Actor)
    seq:DespawnActor(deer3Actor)
    seq:DespawnActor(deer4Actor)
    seq:Do(HideWildlife)
    seq:StartSequence()
  end
end
function SetDeerSizes()
  deer2Actor:GetCreature():SetCharacterConfig("Deer_10")
  deer3Actor:GetCreature():SetCharacterConfig("Deer_10")
  deer4Actor:GetCreature():SetCharacterConfig("Deer_00")
end
function LoopWildlifeObjects()
  boar1:JumpAnimToFrame(0)
  boar1:PlayAnimCycle()
  boar2:JumpAnimToFrame(0)
  boar2:PlayAnimCycle()
  crow1:JumpAnimToFrame(0)
  crow1:PlayAnimCycle()
  crow2:JumpAnimToFrame(0)
  crow2:PlayAnimCycle()
  crow3:JumpAnimToFrame(0)
  crow3:PlayAnimCycle()
end
function IsPlayerNearBoars()
  return game.AIUtil.Distance(player, boar1) < 20
end
function BoarsRunAway()
  SNDBoar = boar1:FindSingleSoundEmitterByName("SNDMouth")
  boar1:StartAnim("FreyaHouseIntro_Boar00_0")
  boar2:StartAnim("FreyaHouseIntro_Boar00_1")
  LD.PlaySound(SNDBoar, "SND_CINE_Freya_Home_Walk_Boar")
end
function Heimili_Started()
  heimili_start = true
end
function CrowsFlyAway()
  crow1:StartAnim("FreyaHouseIntro_Crow00_0")
  crow2:StartAnim("FreyaHouseIntro_Crow00_11")
  crow3:StartAnim("FreyaHouseIntro_Crow00_22")
end
function HideWildlife()
  SetupWildlifeProps()
  crow1:Hide()
  crow2:Hide()
  crow3:Hide()
  boar1:Hide()
  boar2:Hide()
end
function SND_TriggerElkSounds()
  SNDElk = deer2Actor:GetCreature():FindSingleSoundEmitterByName("SNDMouth")
  LD.PlaySound(SNDElk, "SND_CINE_Freya_Home_Walk_Elk")
end
