local LD = require("design.LevelDesignLibrary")
local timer = require("level.timer")
local EC = require("design.Encounter")
local monitors = require("level.MonitorLibrary")
local uiCalls = require("ui.uicalls")
local checkpoint = require("level.checkpoint")
local TUT = require("game.GlobalTutorials")
thisLevel = nil
player = nil
son = nil
local Encounter01
GardenEncounterComplete = false
local camShakeLarge = {
  EffectName = "FSE_shake_temp_Generic_Large",
  Duration = 1
}
local ForceFeedbackRumble = {
  EffectName = "FFB_HEAVY_ATTACK",
  Duration = 1
}
local Area_1_Encounter_1, Area_2_Encounter_1, ZM_A1E1_Attack, ZM_A2E1_Attack, ZM_A2_E1_Start2, Repop_A1E1, Repop_A2E1
local splashShown = false
local Draugr_HealthMonitor, startStunTutorial, enemySpawned, inputMask, stunTutorialStarted, postUpStarted
local musicisactive = false
local SurpriseMusicOn = false
function OnFirstStart(level)
  GameObjects.DeathPlane:HideCollision()
  GameObjects.TraversePath_5mDrop:HideTraversePath()
end
function OnScriptLoaded(level)
  thisLevel = level
  player = game.Player.FindPlayer()
  son = game.AI.FindSon()
  Intro_Draugr_Area_1_Fight_1()
  Intro_Draugr_Area_2_Fight_1()
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 375 < cineNumber then
    Repop_Area_1_Fight_1()
    Repop_Area_2_Fight_1()
  end
end
function OnStart(level)
  GameObjects.CombatCol:HideCollision()
  GameObjects.PuzzleHintZone:HideEntityVolume()
  SoundOnStart()
  ShowFor250Vis()
  if game.Level.GetVariable("CompletedCineNumber") > 72 then
    GameObjects.TraversePath_5mDrop:HideTraversePath()
    GameObjects.LeadTheWay.LuaObjectScript.Disable()
    GameObjects.LeadTheWay_Follow.LuaObjectScript.Enable()
  end
  if game.Level.GetVariable("CompletedCineNumber") > 100 then
    GameObjects.DeathPlane:ShowCollision()
  end
end
function OnUpdate(level)
  if enemySpawned then
    StunTutorial()
  end
end
function ShowFor250Vis()
  GameObjects.For250_Vis:Show()
end
function HideFor250Vis()
  GameObjects.For250_Vis:Hide()
end
local testOnScreenPromptInfo = {
  conditionMet = false,
  GetConditionAlreadyMet = function(this)
    return this.conditionMet
  end,
  OnConditionMet = function(this)
    LD.CallFunctionAfterDelay(ShowSplashScreen, 0.9)
    For810ShallNotPass_Disable()
    this.conditionMet = true
    enemySpawned = false
  end,
  time = 0,
  raycastOptions = game.CollisionType.New("kInvisibleBarrier", "kEnvironment")
}
function StunTutorial()
  if not testOnScreenPromptInfo:GetConditionAlreadyMet() then
    local didIt = false
    local crtArr = player:FindEnemies(40)
    if 0 < #crtArr then
      for _, enemy in ipairs(crtArr) do
        if game.Camera.GetViewPenetration(enemy:GetWorldPosition(), 0, 0) > 0.5 then
          local playerPos = player:GetWorldPosition()
          local enemyPos = enemy:GetWorldPosition()
          playerPos.y = playerPos.y + 1
          enemyPos.y = enemyPos.y + 1
          if not game.World.RaycastCollision(playerPos, enemyPos, {
            EntityType = testOnScreenPromptInfo.raycastOptions,
            SourceGameObject = player,
            ExcludeGameObject = enemy,
            FindAnything = true
          }) then
            testOnScreenPromptInfo:OnConditionMet()
            didIt = true
            break
          end
        end
      end
    end
    if not didIt then
      if testOnScreenPromptInfo.time > 60 then
        testOnScreenPromptInfo:OnConditionMet()
      else
        testOnScreenPromptInfo.time = testOnScreenPromptInfo.time + player:GetUnitTime()
      end
    end
  end
end
function ApproachPostUp()
  enemySpawned = true
end
function ShowSplashScreen()
  if not splashShown then
    splashShown = true
    TUT.ArrowStun_Tutorial()
  end
end
function BareHandMsg()
  LD.CallFunctionAfterDelay(function()
    uiCalls.SendSidebarDesignerMessage({
      Text = 43913,
      MessageVariant = uiCalls.msgParam.SIDEBAR_MEDIUM,
      DisplayTime = 16
    })
  end, 0.25)
end
function For810ShallNotPass_Disable()
  local for810 = game.FindLevel("For810_TrollArenaExit")
  for810:CallScript("DisableShallNotPass")
end
function OnSaveCheckpoint(level)
  return {
    levelstate = checkpoint.Save(),
    playedSetupBool = GardenEncounterComplete,
    splashShown = splashShown
  }
end
function OnRestoreCheckpoint(level, savedInfo)
  checkpoint.Restore(savedInfo.levelstate)
  GardenEncounterComplete = savedInfo.playedSetupBool
  splashShown = savedInfo.splashShown
end
function ShakeRumble()
  game.FX.SubmitEffect(camShakeLarge)
  game.FX.SubmitEffect(ForceFeedbackRumble)
end
function Intro_Draugr_Area_1_Fight_1()
  Area_1_Encounter_1 = EC.NewEncounter(thisLevel, "[Area 1]EC:1 Intro For250", {CheckpointOnComplete = false})
  Area_1_Encounter_1:AddWave({
    {
      spawners = "Draugr_L_SWUnaware",
      markerID = "StunnedEnemy",
      spawnLocators = "A1_Loc_5",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Area_1_Encounter_1:AddWave({
    {
      spawners = "Draugr_L_SFGSW",
      markerID = "StunnedEnemy",
      spawnLocators = "A1_Loc_2",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "Draugr_L_SFGSW",
      markerID = "StunnedEnemy",
      spawnLocators = "A1_Loc_1",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 6
    }
  })
  Area_1_Encounter_1:SetStartZone(thisLevel:GetGameObject("EntZn_Area_1_Spawn"))
  Area_1_Encounter_1:OnStart(CA_LowerCombat_Enable)
  Area_1_Encounter_1:OnComplete(function()
    CA_LowerCombatCA_Disable()
    uiCalls.UI_Event_TurnOffDesignerMessage()
    ChiselSiteEncountersCheckpoint()
  end)
  Area_1_Encounter_1:OnCombatStart(function()
    Area1MusicFun()
  end)
  ZM_A1E1_Attack = monitors.CreateEntityZoneMonitor(player, thisLevel:GetGameObject("EntZn_Area_1_Attack"))
  ZM_A1E1_Attack:SetTriggerCountLimit(1)
end
function CA_LowerCombat_Enable()
  GameObjects.ca_turret_Fight1.LuaObjectScript.Enable()
  GameObjects.ca_turret_Fight2.LuaObjectScript.Enable()
  GameObjects.ca_turret_Fight3.LuaObjectScript.Enable()
end
function CA_LowerCombatCA_Disable()
  GameObjects.ca_turret_Fight1.LuaObjectScript.Disable()
  GameObjects.ca_turret_Fight2.LuaObjectScript.Disable()
  GameObjects.ca_turret_Fight3.LuaObjectScript.Disable()
  GameObjects.CA_Post_Up.LuaObjectScript.Disable()
  Enable_LTW()
  GameObjects.CA_Idle_HopUp.LuaObjectScript.Enable()
  CheckMusicArea1()
end
function Intro_Draugr_Area_2_Fight_1()
  Area_2_Encounter_1 = EC.NewEncounter(thisLevel, "[Area 2]EC:1 Upper Fight For250", {CheckpointOnComplete = false})
  Area_2_Encounter_1:AddWave({
    {
      spawners = "Draugr_L_SWPatrol1",
      spawnLocators = "A2_A_Loc_1",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "Draugr_L_SWPatrol2",
      spawnLocators = "A2_A_Loc_2",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Area_2_Encounter_1:AddWave({
    prioritizeOnScreenSpawners = true,
    requireSpawnersInRange = {5, 30},
    {
      spawners = "Draugr_L_SFGSW",
      spawnLocators = "A2_A_Loc_3",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Area_2_Encounter_1:AddWave({
    prioritizeOnScreenSpawners = true,
    requireSpawnersInRange = {5, 30},
    {
      spawners = "Draugr_L_SFGSW",
      spawnLocators = "A2_C_Loc_*",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Area_2_Encounter_1:AddWave({
    triggerWaveFromScript = true,
    {
      spawners = "Bandit_S_VUP",
      markerID = "Helwalker",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Area_2_Encounter_1:OnStart(A2E1_Started)
  Area_2_Encounter_1:SetStartZone(thisLevel:GetGameObject("EntZn_Area_2_Spawn"))
  Area_2_Encounter_1:OnCombatStart(function()
    Area2MusicFun()
  end)
  ZM_A2_E1_Start2 = monitors.CreateEntityZoneMonitor(player, GameObjects.EntZn_Area_2_Wave2)
  ZM_A2_E1_Start2:OnEnter(function()
    Area_2_Encounter_1:StartWave(2)
  end)
  Area_2_Encounter_1:OnEnemyDeath(function()
    Area_2_Encounter_1:StartWave(3)
  end, {count = 1})
  Area_2_Encounter_1:OnEnemyDeath(function()
    Area_2_Encounter_1:StartWave(4)
  end, {count = 4})
  Area_2_Encounter_1:OnEnemySpawn(function()
    AlertHelwalker()
  end, {markerID = "Helwalker"})
  Area_2_Encounter_1:OnComplete(function()
    CheckHelwalkerBestiary()
    LD.SetEntityVariable("FOR_BaldurIntroEnabled", true)
    LD.SetEntityVariable("FOR_BackyardClear", true)
    uiCalls.UI_Event_TurnOffDesignerMessage()
    LD.CallFunctionAfterDelay(function()
      game.Audio.PlayBanter("330_MothersGarden_1")
    end, 3.25)
    CheckExit()
    LD.CallFunctionAfterDelay(function()
      GameObjects.PuzzleHintZone:ShowEntityVolume()
    end, 6)
    CheckMusicArea2()
    GameObjects.DeathPlane:HideCollision()
    GameObjects.CA_Idle_HopUp.LuaObjectScript.Disable()
    GameObjects.ca_combat_Block.LuaObjectScript.Disable()
    GameObjects.CombatCol:HideCollision()
    ChiselSiteEncountersCheckpoint()
  end)
end
function CheckHelwalkerBestiary()
  local helWalkerEntry = game.Wallets.GetResourceValue("HERO", "Bestiary_Unlock_Hel_Walker")
  if helWalkerEntry < 0 then
    LD.UnlockBestiaryEntry("Bestiary_Unlock_Hel_Walker")
  end
end
function AlertHelwalker()
  LD.CallFunctionAfterDelay(function()
    Area_2_Encounter_1:AlertEnemies(4)
  end, 0.5)
  LD.CallFunctionAfterDelay(AxeResistReminder, 12)
  LD.CallFunctionAfterDelay(BareHandReminder, 32)
end
function AxeResistReminder()
  if LD.GetEntityVariable("FOR_BackyardClear") ~= true then
    TUT.AxeResistance_Tutorial()
  end
end
function BareHandReminder()
  if LD.GetEntityVariable("FOR_BackyardClear") ~= true then
    TUT.BareHand_Tutorial()
  end
end
function ChiselSiteEncountersCheckpoint()
  if Area_1_Encounter_1:IsComplete() and Area_2_Encounter_1:IsComplete() then
    game.World.StoreCheckpoint()
  end
end
function Repop_Area_1_Fight_1()
  local powerLevel01, powerLevel02
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 375 <= cineNumber and cineNumber <= 599 then
    powerLevel01 = 4
    powerLevel02 = 5
  elseif 600 <= cineNumber then
    powerLevel01 = 5
    powerLevel02 = 6
  end
  Repop_A1E1 = EC.NewEncounter(thisLevel, "[Repop Area 1]EC:1 Repop For250 Level1", {
    CheckpointOnComplete = false,
    RepopulationEncounter = true,
    MustHaveCompletedList = {
      "[Area 1]EC:1 Intro For250",
      "[Area 2]EC:1 Upper Fight For250"
    }
  })
  Repop_A1E1:AddWave({
    {
      spawners = "T4_Draugr_M_SW_SFG",
      spawnLocators = "A1_Loc_1",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0,
      powerLevel = powerLevel01
    },
    {
      spawners = "T4E_Draugr_M_SW_SFG",
      spawnLocators = "A1_Loc_4",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2,
      powerLevel = powerLevel02
    }
  })
  Repop_A1E1:SetStartZone(thisLevel:GetGameObject("EntZn_Lvl1_Repop"))
end
function Repop_Area_2_Fight_1()
  local powerLevel01, powerLevel02
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 375 <= cineNumber and cineNumber <= 599 then
    powerLevel01 = 4
    powerLevel02 = 5
  elseif 600 <= cineNumber then
    powerLevel01 = 5
    powerLevel02 = 6
  end
  Repop_A2E1 = EC.NewEncounter(thisLevel, "[Repop Area 2]EC:1 Repop For250 Level2", {
    CheckpointOnComplete = false,
    RepopulationEncounter = true,
    MustHaveCompletedList = {
      "[Area 1]EC:1 Intro For250",
      "[Area 2]EC:1 Upper Fight For250"
    }
  })
  Repop_A2E1:AddWave({
    prioritizeOnScreenSpawners = true,
    requireSpawnersInRange = {4, 25},
    {
      spawners = "T4_Bandit_S_SFG",
      spawnLocators = "A2_C_Loc_*",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0,
      powerLevel = powerLevel01
    },
    {
      spawners = "T4_Draugr_M_SW_SFG",
      spawnLocators = "A2_C_Loc_*",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2,
      powerLevel = powerLevel01
    },
    {
      spawners = "T4_Bandit_S_SFG",
      spawnLocators = "A2_C_Loc_*",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 4,
      powerLevel = powerLevel02
    },
    {
      spawners = "T4E_Draugr_M_SW_SFG",
      spawnLocators = "A2_C_Loc_*",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 8,
      powerLevel = powerLevel02
    }
  })
  Repop_A2E1:SetStartZone(thisLevel:GetGameObject("EntZn_Lvl2_Repop"))
end
function A2E1_Started()
  GameObjects.ca_combat_Block.LuaObjectScript.Enable()
  print("Area_2_Encounter_1 is hitting OnStart")
  GameObjects.DeathPlane:ShowCollision()
end
function SonReachedPosition()
  timer.StartLevelTimer(2, function()
    if game.Level.GetVariable("FOR_BackyardClear") ~= true then
      GameObjects.CombatCol:ShowCollision()
    end
  end)
end
function CheckExit()
  if LD.GetEntityVariable("FOR_LogDropClear") == false then
    timer.StartLevelTimer(21, CheckPuzzleHint)
  else
    CA_Ready2Drop()
  end
end
function CA_Ready2Drop()
  GameObjects.TraversePath_5mDrop:ShowTraversePath()
end
function EZE_DropFrom250()
  GameObjects.CA_Idle_DropDown.LuaObjectScript.Disable()
  local for200 = game.FindLevel("For200_House")
  if for200 ~= nil then
    for200:CallScript("DroppedIntoBackyard")
  end
end
function Enable_LTW()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if cineNum < 100 then
    GameObjects.LeadTheWay.LuaObjectScript.Enable()
  else
    GameObjects.LeadTheWay_Follow.LuaObjectScript.Enable()
  end
end
function Disable_LTW()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if cineNum < 100 then
    GameObjects.LeadTheWay.LuaObjectScript.Disable()
  else
    GameObjects.LeadTheWay_Follow.LuaObjectScript.Disable()
  end
end
function CheckPuzzleHint()
  if LD.GetEntityVariable("FOR_LogDropClear") == false then
    if player:GetCurrentWeapon() == "Axe" then
      for w in player:IterateActiveWeapons() do
        if w.Weapon.ThrowOutStatus == tweaks.tThrowOutStatus.eThrownWeaponStatus.kTOSStuck or w.Weapon.ThrowOutStatus == tweaks.tThrowOutStatus.eThrownWeaponStatus.kTOSFalling or w.Weapon.ThrowOutStatus == tweaks.tThrowOutStatus.eThrownWeaponStatus.kTOSOnGround then
          TUT.AimAxeReminder_Tutorial()
        elseif w.Weapon.ThrowOutStatus == tweaks.tThrowOutStatus.eThrownWeaponStatus.kTOSInHand then
          TUT.AimAxeReminder_Tutorial()
        end
      end
    else
      for w in player:IterateActiveWeapons() do
        if w.Weapon.ThrowOutStatus == tweaks.tThrowOutStatus.eThrownWeaponStatus.kTOSStuck or w.Weapon.ThrowOutStatus == tweaks.tThrowOutStatus.eThrownWeaponStatus.kTOSFalling or w.Weapon.ThrowOutStatus == tweaks.tThrowOutStatus.eThrownWeaponStatus.kTOSOnGround or w.Weapon.ThrowOutStatus == tweaks.tThrowOutStatus.eThrownWeaponStatus.kTOSInFlightOut or w.Weapon.ThrowOutStatus == tweaks.tThrowOutStatus.eThrownWeaponStatus.kTOSInFlightReturn then
          TUT.AimAxeReminder_Tutorial()
        else
          TUT.AimAxeReminder_Tutorial()
        end
      end
    end
  end
end
function WakeSleeping(encounter)
  local waveXEnemies = encounter:GetActiveEnemies(1)
  local delay = math.random()
  for key, enemy in ipairs(waveXEnemies) do
    timer.StartLevelTimer(math.random(key * 0.15 + 1), function()
      WakeMe(enemy)
    end)
  end
end
function WakeMe(enemy)
  if enemy ~= nil then
    enemy:TriggerMoveEvent("kLEAlert")
  end
end
function EnableChiselMarker()
  LD.SetMarkerState("FOR_200_ChiselEntrance", 1)
  LD.UpdateMap("FOR_200_ChiselEntrance", 0)
  ChiselQuest()
end
function DisableChiselMarker()
  LD.SetMarkerState("FOR_200_ChiselEntrance", 0)
end
function ChiselQuest()
  local questState = game.QuestManager.GetQuestState("Quest_Labor_ChiselDungeon_Find_For")
  if questState ~= "Complete" then
    LD.ActivateQuest("Quest_Labor_ChiselDungeons_Parent")
    LD.CompleteQuest("Quest_Labor_ChiselDungeon_Find_For")
    game.QuestManager.IncrementQuestProgress("Quest_Labor_ChiselDungeon_Find", 1)
  end
end
function Area1MusicFun()
  if not musicisactive then
    game.Audio.StartMusic("SND_MX_PRO_fight_3_in")
    musicisactive = true
  end
end
function Area2MusicFun()
  if not Area_1_Encounter_1:IsRunning() then
    game.Audio.StartMusic("SND_MX_PRO_fight_3b_in")
  end
end
local secondFightOver = false
function CheckMusicArea1()
  if not Area_2_Encounter_1:IsRunning() and secondFightOver == false then
    game.Audio.StartMusic("SND_MX_PRO_fight_3a_out")
  end
end
function CheckMusicArea2()
  secondFightOver = true
  if not Area_1_Encounter_1:IsRunning() then
    game.Audio.StartMusic("SND_MX_PRO_fight_3_out")
  end
end
local chiselDoorEvents = {
  OnInteractForward_Left = "SND_DOOR_Wood_Double_Pry_Apart_Seq_L",
  OnInteractForward_Right = "SND_DOOR_Wood_Double_Pry_Apart_Seq_R",
  OnInteractBackward_Left = "SND_DOOR_Wood_Double_Pry_Apart_Seq_R",
  OnInteractBackward_Right = "SND_DOOR_Wood_Double_Pry_Apart_Seq_R"
}
function SoundOnStart()
  GameObjects.SpreadDoor_Pro.LuaObjectScript.SoundSetup(chiselDoorEvents)
end
function OnEvaluateLoadGroup_Cinematic()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if cineNum < 100 then
    return "Baldur"
  else
    return "EndGame"
  end
end
function OnEvaluateLoadGroup_Cinematic_ChiselDoor()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if cineNum < 100 then
    return "Baldur"
  else
    return "EndGame"
  end
end
