local LD = require("design.LevelDesignLibrary")
local timers = require("level.timer")
local monitors = require("level.MonitorLibrary")
EC = require("design.Encounter")
local CCOS = require("camera.camera_oneshot")
local TUT = require("game.GlobalTutorials")
thisObj = nil
thisLevel = nil
player = nil
son = nil
local MonsterClosetEncounter, BridgeFightEncounter, AfterBridgeFightEncounter, GolemEncounter, DeadRiseEncounter, DeadRiseFanEncounter, DeadRiseAlertZoneMonitor, PossessEncounter, PossessOutroEncounter, PossessionMonitor, CameraPossMonitor, Golem_ZoneMonitor, oneShotCamFlyerPosses
E_HealthMonitor = nil
crawlersWaveTriggered = false
monsterClosetBreakable = nil
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  player = game.Player.FindPlayer()
  son = game.AI.FindSon()
  monsterClosetBreakable = GameObjects.Breakable_MonsterCloset.Child:GetBreakable()
  DeadRiseIntro()
  DeadRiseFanatic()
  BridgeFightStart()
  AfterBridgeFightStart()
  GolemFightStart()
  PossessIntro()
  PossessOutro()
  game.SubObject.Sleep(obj)
end
function OnStart(level, obj)
  if PossessEncounter:WasRunning() then
    PossessEncounter:Start()
    timers.StartLevelTimer(1, function()
      local possFly = LD.FindSingleAIByMarker("PossFlyer")
      if possFly ~= nil then
        timers.StartLevelTimer(0.5, function()
          possFly:TriggerMoveEvent("kLEAlert")
        end)
      end
      local possBand = LD.FindSingleAIByMarker("PossBand")
      if possBand ~= nil then
        timers.StartLevelTimer(0.5, function()
          possBand:TriggerMoveEvent("kLEAlert")
        end)
      end
    end)
  end
  if BridgeFightEncounter:WasRunning() then
    BridgeFightEncounter:Start()
  end
  if GolemEncounter:WasRunning() then
    GolemEncounter:Start()
  end
  if DeadRiseEncounter:WasRunning() then
    DeadRiseEncounter:Start()
  end
  if AfterBridgeFightEncounter:WasRunning() then
    AfterBridgeFightEncounter:Start()
  end
end
function OnUpdate(level, obj)
  if oneShotCamFlyerPosses ~= nil then
    oneShotCamFlyerPosses:Update()
  end
end
function CameraStartFlyerPossesOneShot()
  game.SubObject.Wake(thisObj)
  oneShotCamFlyerPosses = CCOS.OneShotCamera.New("PLYR_Nar_LookAt_FlyerPossession", 3)
  oneShotCamFlyerPosses:Start()
  oneShotCamFlyerPosses:SetCallback(CameraDestroyFlyerPossesOneShot)
  player:SetMaxSpeedOverride(1.5)
  timers.StartLevelTimer(4, function()
    player:ClearMaxSpeedOverride()
  end)
end
function CameraDestroyFlyerPossesOneShot()
  oneShotCamFlyerPosses = nil
  game.SubObject.Sleep(thisObj)
end
function OnUseWorld(level, obj)
end
function OnSaveCheckpoint(level, obj)
  return {}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
end
function DeadRiseCrystal()
  DeadRiseEncounter:AlertEnemies()
  DeadRiseFanEncounter:Start()
end
function HelwalkersDeadCheckpoint()
  if DeadRiseEncounter:IsComplete() and DeadRiseFanEncounter:IsComplete() then
    game.World.StoreCheckpoint()
  end
end
function PossessIntro()
  PossessEncounter = EC.NewEncounter(thisLevel, "First Possession Flyer Helwalker Encounter", {
    CheckpointOnComplete = true,
    LeashZone = "LeashZone710"
  })
  PossessEncounter:AddWave({
    {
      spawners = "Bandit_S_INFECT",
      spawnLocators = "A1_Loc_O_7",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      markerID = "PossBand",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.1
    },
    {
      spawners = "Flyer_POSS",
      spawnLocators = "A1_Loc_O_8",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_SummitAscentHUB",
      markerID = "PossFlyer",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  PossessEncounter:SetStartZone(GameObjects.Zone_Possession_Spawn, {
    cineRequirement = {285, 305}
  })
  PossessEncounter:SetAlertZone(GameObjects.Zone_Possession_Alert)
  PossessionMonitor = monitors.CreateEntityZoneMonitor(player, thisLevel:GetGameObject("Zone_Possession_Alert"))
  PossessionMonitor:OnEnter(function()
    local possFly = LD.FindSingleAIByMarker("PossFlyer")
    if possFly ~= nil then
      timers.StartLevelTimer(0.7, function()
        possFly:TriggerMoveEvent("kLEAlert")
      end)
    end
    local possBand = LD.FindSingleAIByMarker("PossBand")
    if possBand ~= nil then
      possBand:TriggerMoveEvent("kLEAlert")
    end
  end)
  PossessionMonitor:SetTriggerCountLimit()
  CameraPossMonitor = monitors.CreateEntityZoneMonitor(player, thisLevel:GetGameObject("Zone_Possession_Cam"))
  CameraPossMonitor:OnEnter(function()
    CameraStartFlyerPossesOneShot()
    GameObjects.Zone_Possession_Cam:HideEntityVolume()
  end)
  PossessionMonitor:SetTriggerCountLimit(1)
  PossessEncounter:OnComplete(function()
    LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Nightmare_Possess")
    GameObjects.SCA_VibrateLift_FireReady.LuaObjectScript.Enable()
    GameObjects.ca_combat_turret_01.LuaObjectScript.Disable()
  end)
end
function CheckPosessComplete()
  if PossessEncounter ~= nil then
    if PossessEncounter:IsComplete() then
      GameObjects.SCA_VibrateLift_FireReady.LuaObjectScript.Enable()
    else
      GameObjects.CA_observe_on_alert_preCombat.LuaObjectScript.Enable()
    end
  end
end
function StartPossessOutro()
  PossessOutroEncounter:Start()
  local recenterTable = {
    RotationSpace = 1,
    TimeStart = 0,
    TimeDuration = 1.6,
    LockRecenter = 0.25,
    YawRange = -1,
    TriggerLeft = 42,
    ReturnLeft = 38,
    ReturnRight = 35,
    TriggerRight = 15,
    PitchRange = -1,
    TriggerUp = 7,
    ReturnUp = -2,
    ReturnDown = -2,
    TriggerDown = -15
  }
  game.Camera.Recenter(recenterTable)
end
function PossessOutro()
  PossessOutroEncounter = EC.NewEncounter(thisLevel, "First Possession Flyer Post Crank Encounter", {
    CheckpointOnComplete = true,
    LeashZone = "LeashZone710"
  })
  PossessOutroEncounter:AddWave({
    {
      spawners = "Flyer_FORW_1",
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.8
    },
    {
      spawners = "Flyer_FORW_2",
      spawnWad = "Peak720_SummitAscentHUB",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1.1
    }
  })
  PossessOutroEncounter:AddWave({
    {
      spawners = "Flyer_FORW_1",
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1.2
    }
  })
  PossessOutroEncounter:OnEnemyDeath(function()
    PossessOutroEncounter:StartWave(2)
  end, {count = 1})
  PossessOutroEncounter:OnComplete(function()
    LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Nightmare_Possess")
  end)
end
function DeadRiseIntro()
  DeadRiseEncounter = EC.NewEncounter(thisLevel, "First Helwalker Encounter Crystal", {
    CheckpointOnComplete = false,
    LeashZone = "LeashZone720",
    StartMusic = "SND_MX_PEAK_ascent_fight_21_in",
    StopMusic = "SND_MX_PEAK_ascent_fight_21_out"
  })
  DeadRiseEncounter:AddWave({
    {
      spawners = "Bandit_S_RISING1",
      spawnLocators = "A1_Loc_O_1",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.1
    }
  })
  DeadRiseEncounter:SetStartZone(GameObjects.Zone_FirstHelwalkers, {
    cineRequirement = {285, 305}
  })
  DeadRiseEncounter:OnComplete(HelwalkersDeadCheckpoint)
  DeadRiseAlertZoneMonitor = monitors.CreateEntityZoneMonitor(player, thisLevel:GetGameObject("Zone_MonsterCloset"))
  DeadRiseAlertZoneMonitor:OnEnter(function()
    DeadRiseEncounter:AlertEnemies()
  end)
end
function DeadRiseFanatic()
  DeadRiseFanEncounter = EC.NewEncounter(thisLevel, "First Fanatic Encounter Crystal", {
    CheckpointOnComplete = false,
    LeashZone = "LeashZone720",
    StartMusic = "SND_MX_PEAK_ascent_fight_21_in",
    StopMusic = "SND_MX_PEAK_ascent_fight_21_out"
  })
  DeadRiseFanEncounter:AddWave({
    {
      spawners = "Fanatic_2_TURRET",
      spawnLocators = "A1_Loc_O_3",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1
    },
    {
      spawners = "Bandit_S_SPRINT",
      spawnLocators = "A2_Loc_W_1",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.1
    },
    {
      spawners = "Flyer_FORW_1",
      spawnLocators = "A2_Loc_W_2",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1.6
    }
  })
  DeadRiseFanEncounter:SetStartZone(GameObjects.Zone_MonsterCloset, {
    cineRequirement = {285, 305}
  })
  DeadRiseFanEncounter:OnComplete(HelwalkersDeadCheckpoint)
  DeadRiseFanEncounter:OnStart(function()
    if monsterClosetBreakable.Broken == false then
      monsterClosetBreakable:Break()
    end
  end)
end
function MonsterClosetFightStart()
  MonsterClosetEncounter = EC.NewEncounter(thisLevel, "Monster Closet Encounter", {
    CheckpointOnComplete = false,
    LeashZone = "LeashZone720",
    StartMusic = "SND_MX_PEAK_ascent_fight_21_in",
    StopMusic = "SND_MX_PEAK_ascent_fight_21_out"
  })
  MonsterClosetEncounter:AddWave({
    {
      spawners = "Bandit_S_SPRINT",
      spawnLocators = "A2_Loc_W_1",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.1
    },
    {
      spawners = "Flyer_FORW_1",
      spawnLocators = "A2_Loc_W_2",
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2
    }
  })
  MonsterClosetEncounter:SetStartZone(GameObjects.Zone_MonsterCloset, {
    cineRequirement = {285, 305}
  })
  MonsterClosetEncounter:OnComplete(HelwalkersDeadCheckpoint)
  MonsterClosetEncounter:OnStart(function()
    if monsterClosetBreakable.Broken == false then
      monsterClosetBreakable:Break()
    end
  end)
end
function BridgeFightStart()
  BridgeFightEncounter = EC.NewEncounter(thisLevel, "Bridge Brawler Fight Encounter", {
    CheckpointOnComplete = true,
    LeashZone = "LeashZone720",
    StartMusic = "SND_MX_PEAK_ascent_fight_22_in",
    StopMusic = "SND_MX_PEAK_ascent_fight_22_out"
  })
  BridgeFightEncounter:AddWave({
    {
      spawners = "Brawler_Unaware",
      spawnLocators = "A3_Loc_O_1",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "Fanatic_2_PRAY",
      spawnLocators = "A3_Loc_O_6",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "Fanatic_2_PRAY",
      spawnLocators = "A3_Loc_O_7",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2
    }
  })
  BridgeFightEncounter:SetStartZone(GameObjects.Zone_BridgeFight, {
    cineRequirement = {285, 305}
  })
  BridgeFightEncounter:OnComplete(BridgeFightComplete)
end
function AfterBridgeFightStart()
  AfterBridgeFightEncounter = EC.NewEncounter(thisLevel, "After Bridge Bandit Encounter", {
    CheckpointOnComplete = true,
    LeashZone = "LeashZone720",
    StartMusic = "SND_MX_PEAK_ascent_fight_23_in",
    StopMusic = "SND_MX_PEAK_ascent_fight_23_out"
  })
  AfterBridgeFightEncounter:AddWave({
    {
      spawners = "Fanatic_2_S",
      spawnLocators = "A3_Loc_O_4",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "Fanatic_2_S",
      spawnLocators = "A3_Loc_O_2",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1
    },
    {
      spawners = "Bandit_S_INFECT",
      spawnLocators = "A3_Loc_O_3",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "Flyer_Alert_POSS",
      spawnLocators = "A3_Loc_O_3",
      useSpawnLocatorsOnly = true,
      spawnWad = "Peak720_AI_SummitAscent_01",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  AfterBridgeFightEncounter:SetStartZone(GameObjects.Zone_AfterBridgeFight, {
    cineRequirement = {285, 305}
  })
  AfterBridgeFightEncounter:OnComplete(EnableSonCA_LoreMarker)
end
function GolemFightStart()
  GolemEncounter = EC.NewEncounter(thisLevel, "Golem Encounter", {
    CheckpointOnComplete = true,
    LeashZone = "LeashZone700",
    StartMusic = "SND_MX_PEAK2_golem_fight_in",
    StopMusic = "SND_MX_PEAK2_golem_fight_out"
  })
  GolemEncounter:AddWave({
    {
      spawners = "Golem20_Patrol",
      spawnLocators = "A4_Loc_O_1",
      useSpawnLocatorsOnly = true,
      markerID = "KillTarget",
      spawnWad = "Peak720_AI_SummitAscent_02",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  GolemEncounter:SetStartZone(thisLevel:GetGameObject("Zone_GolemFight"), {
    cineRequirement = {459, 1000}
  })
  GolemEncounter:OnComplete(function()
    LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Ancient_Frost")
    game.AI.FindSon():CallScript("EnterBehaviorContext", "FRUSTRATED_BEHAVIOR_CONTEXT_CONFIG")
  end)
  GolemEncounter:OnStart(function()
    LD.SetMarkerState("PEAK_720_AncientFight", 1)
  end)
  GolemEncounter:OnComplete(function()
    LD.SetMarkerState("PEAK_720_AncientFight", 0)
  end)
  Golem_ZoneMonitor = monitors.CreateEntityZoneMonitor(player, thisLevel:GetGameObject("Zone_GolemAlert"))
  Golem_ZoneMonitor:OnEnter(function()
    game.AI.FindSon():TriggerMoveEvent("kLE_GolemJumpAttack")
    timers.StartLevelTimer(0.5, function()
      game.Audio.PlayBanter("SonJerk_Attack")
    end)
    GameObjects.Zone_GolemAlert:HideEntityVolume()
  end)
  Golem_ZoneMonitor:SetTriggerCountLimit(1)
end
function BridgeFightComplete()
  GameObjects.Zone_BlastBridgeIntroBanter:ShowEntityVolume()
  LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Hel_Fanatic_Archer")
  LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Hel_Brawler")
end
function EnableSonCA_LoreMarker()
  local SCA = thisLevel:FindSingleGameObject("SCA_Observe_Forward_LoreMarker")
  if SCA then
    SCA.LuaObjectScript.Enable()
  end
  LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Hel_Fanatic_Archer")
  LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Nightmare_Possess")
end
function DisableFirstVisitMidAndTopFights()
  MonsterClosetEncounter:SetComplete()
  BridgeFightEncounter:SetComplete()
end
function DisableFirstVisitBottomFight()
  GolemEncounter:SetComplete()
end
