local timers = require("level.timer")
local EC = require("design.Encounter")
local LD = require("design.LevelDesignLibrary")
local uiCalls = require("ui.uicalls")
local checkpoint = require("level.checkpoint")
local player, thisLevel
local FT_UsedOnce = false
local FT_UsedTwice = false
local GateEntryBanterPlayed = false
local trainingEncounter
local delayDestruction = false
local delayDestruction_T = {}
function OnScriptLoaded(level)
  player = game.Player.FindPlayer()
  thisLevel = level
  game.Audio.StartMusicMaster("SND_MX_MSP_start_master")
  InitTrainingEncounter()
  GameObjects.Arena6_AIWall:HideCollision()
end
function OnStart(level, obj)
  LD.SetRealmDiscovered("Muspelheim")
  RecipeCheck()
  GameObjects.FX_RESET:Hide()
  GameObjects.FX_RESET3:Hide()
  MusicOnStart()
end
function OnUpdate(level)
  if game.World.IsInsideCameraZone(player.WorldPosition, "CamZone_CC02_015") then
    game.Camera.SubmitCameraByName("PLYR_CrackClimb_Limited_50")
  end
  if game.World.IsInsideCameraZone(player.WorldPosition, "CamZone_CC02_020") then
    game.Camera.SubmitCameraByName("PLYR_CrackClimb_Vista_LS_Msp100")
  end
  if game.World.IsInsideCameraZone(player.WorldPosition, "CamZone_CC07_010") then
    game.Camera.SubmitCameraByName("PLYR_CrackClimb_OrbitOffset")
  end
  UpdateCreatureDestruction()
end
local arenaNum
function InitTrainingEncounter()
  local min = math.floor(player:AttributeGetValue("PowerLevel") + 1)
  if min - 1 <= 0 then
    min = 2
  end
  if 7 < min then
    min = 7
  end
  local max = min + 1
  trainingEncounter = EC.NewEncounter(thisLevel, "[Global] MSP Training Encounter")
  trainingEncounter:AddWave({
    {
      spawners = "train_mode_spawn_01",
      spawnLocators = "train_mode_loc_arena_01_01",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.5,
      powerLevel = min
    },
    {
      spawners = "train_mode_spawn_01",
      spawnLocators = "train_mode_loc_arena_01_01",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1.3,
      powerLevel = min + 1
    },
    {
      spawners = "train_mode_spawn_01",
      spawnLocators = "train_mode_loc_arena_01_01",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2,
      powerLevel = min - 1
    }
  })
  trainingEncounter:AddWave({
    infiniteSpawning = true,
    {
      spawnPattern = "Ordered",
      spawners = "train_mode_spawn_0",
      spawnLocators = "train_mode_loc_arena_01_01",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0,
      powerLevel = min
    },
    {
      spawnPattern = "Ordered",
      spawners = "train_mode_spawn_0",
      spawnLocators = "train_mode_loc_arena_01_01",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0,
      powerLevel = min + 1
    },
    {
      spawnPattern = "Ordered",
      spawners = "train_mode_spawn_0",
      spawnLocators = "train_mode_loc_arena_01_01",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0,
      powerLevel = min - 1
    }
  })
end
function StartTrainingMode(arena)
  arenaNum = arena
  if trainingEncounter ~= nil then
    game.Combat.TurnOnAndLockCombatStatus()
    player:MeterSetValue("Health", player:MeterGetMax("Health"))
    player:MeterSetValue("Blood", player:MeterGetMax("Blood"))
    trainingEncounter:SetLocators(thisLevel:FindGameObjects("train_mode_loc_arena_0" .. arenaNum .. "_0*"))
    trainingEncounter:Start()
    trainingEncounter:StartInfiniteSpawning(2)
    AcquirePickup("MuspelheimPreventPlayerDeath")
  end
end
function StopTrainingMode()
  if trainingEncounter ~= nil and trainingEncounter:IsRunning() then
    GameObjects["Muspelheim_Arena_Marker_0" .. arenaNum].LuaObjectScript.GetInteractZone():SetTags("NotInCombat")
    trainingEncounter:StopInfiniteSpawning()
    trainingEncounter:StopSpawnTimers()
    MSP_Despawn_Enemy_VFX(trainingEncounter)
    trainingEncounter:Reset()
    trainingEncounter:Stop()
    RelinquishPickup("MuspelheimPreventPlayerDeath")
  end
end
function AcquirePickup(pickup_name)
  if player:PickupIsAcquired(pickup_name) == false then
    player:PickupAcquire(pickup_name)
  end
end
function RelinquishPickup(pickup_name)
  if player:PickupIsAcquired(pickup_name) then
    player:PickupRelinquish(pickup_name)
  end
end
function MSP_Despawn_Enemy_VFX(encounter)
  local minTime = 0
  local maxTime = 0.3
  local randomFn = function()
    return math.random(minTime * 1000, maxTime * 1000) / 1000
  end
  local enemies = encounter:GetActiveEnemies()
  for _, enemy in pairs(enemies) do
    if enemy ~= nil then
      if enemy:IsDoingSyncMove() == false then
        timers.StartLevelTimer(randomFn(), function()
          if enemy ~= nil then
            SpawnFXAtCreatureLocation(enemy)
            enemy:Destroy()
          end
        end)
      else
        CreatureInSyncMove_DelayDestruction(enemy)
      end
    end
  end
  encounter:ResetLivingEnemiesCount()
  encounter:ReportWaveDespawned(nil)
end
function SpawnFXAtCreatureLocation(creature)
  local fx = game.FX.Spawn("Body_Fire_Explode", nil, {
    AutoDelete = true,
    EffectCreator = creature,
    Scale = 1.5
  })
  local lastEnemyPos = creature:GetWorldJointPosition(creature:GetJointIndex("JOPelvis1"))
  fx:SetWorldPosition(lastEnemyPos)
end
function CreatureInSyncMove_DelayDestruction(creature)
  delayDestruction = true
  delayDestruction_T[creature] = true
end
function UpdateCreatureDestruction()
  if delayDestruction == true then
    local remaining = 0
    for creature, _ in pairs(delayDestruction_T) do
      if creature ~= nil and delayDestruction_T[creature] == true then
        if creature:IsDoingSyncMove() == false then
          SpawnFXAtCreatureLocation(creature)
          creature:Destroy()
          delayDestruction_T[creature] = nil
        else
          remaining = remaining + 1
        end
      end
    end
    if remaining == 0 then
      delayDestruction = false
      delayDestruction_T = {}
    end
  end
end
function Btr_Sword01_Found()
  GameObjects.Msp100_Banter.LuaObjectScript.PlayBanter("MuspelSwordSighted_01", true)
end
function Btr_Sword02_Found()
  GameObjects.Msp100_Banter.LuaObjectScript.PlayBanter("MuspelSwordSighted_02")
end
function Btr_Sword03_Found()
  GameObjects.Msp100_Banter.LuaObjectScript.PlayBanter("MuspelSwordSighted_03")
end
function Btr_Sword04_Found()
  GameObjects.Msp100_Banter.LuaObjectScript.PlayBanter("MuspelSwordSighted_04")
end
function Btr_Sword05_Found()
  GameObjects.Msp100_Banter.LuaObjectScript.PlayBanter("MuspelSwordSighted_05")
end
function MspAreaAnnounce()
  uiCalls.UI_Event_DiscoverLocation("MuspelheimArena")
  LD.SetMarkerState("CALT_120_MUSP_FT", 1)
end
function TriggerValkyrieFight()
  GameObjects.CBT_Script_Msp160.LuaObjectScript.Start_Area_6_Encounter_2()
end
function GetPreEncounterCooldown()
  return 5
end
function FullScreenBlast()
end
function StartMspClimbQuest()
  LD.ActivateQuest("Quest_Muspelheim_Climb_Parent")
end
function CompleteMspClimbQuest()
  LD.CompleteQuest("Quest_Muspelheim_Climb_Objective_01")
end
function RecipeCheck()
  if game.Wallets.HasResource("HERO", "MuspBaseRecipes") == false then
    game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorChest_MspTankSet_Tier06")
    game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorWrist_MspTankSet_Tier06")
    game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorLegs_MspTankSet_Tier06")
    game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorChest_MspSpeedSet_Tier06")
    game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorWrist_MspSpeedSet_Tier06")
    game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorLegs_MspSpeedSet_Tier06")
    game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorChest_MspDamageSet_Tier06")
    game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorWrist_MspDamageSet_Tier06")
    game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorLegs_MspDamageSet_Tier06")
    game.Wallets.AddRecipe("HERO", "Recipe_Perk_Weapon_Muspelheim")
    game.Wallets.AddRecipe("HERO", "Recipe_HeartOfMuspelheim_Tier07")
    if game.GetNewGamePlus() then
      game.Wallets.AddRecipe("HERO", "Recipe_AxeWeaponSpecial_01_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_AxeWeaponSpecial_02_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_AxeWeaponSpecial_03_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_AxeWeaponSpecial_04_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_AxeWeaponSpecial_05_NGP")
    end
    game.Wallets.AddRecipe("HERO", "Recipe_AxeWeaponSpecial_01")
    game.Wallets.AddRecipe("HERO", "Recipe_AxeWeaponSpecial_02")
    game.Wallets.AddRecipe("HERO", "Recipe_AxeWeaponSpecial_03")
    game.Wallets.AddRecipe("HERO", "Recipe_AxeWeaponSpecial_04")
    game.Wallets.AddRecipe("HERO", "Recipe_AxeWeaponSpecial_05")
    game.Wallets.AddRecipe("HERO", "Recipe_UniqueValkyrie02_Enchantment")
    game.Wallets.AddRecipe("HERO", "Recipe_Stun_Enchantment")
    game.Wallets.AddRecipe("HERO", "Recipe_Perk_Talisman_Muspelheim")
    game.Wallets.AddRecipe("HERO", "WeaponSpecial_FrostSpecialAxeGandalfSlam")
    game.Wallets.AddResource("HERO", "MuspBaseRecipes", 1)
    if game.GetNewGamePlus() then
      game.Wallets.AddRecipe("HERO", "Recipe_Perk_Talisman_Muspelheim_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_Perk_Weapon_Muspelheim_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorChest_MspTankSet_Tier06_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorWrist_MspTankSet_Tier06_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorLegs_MspTankSet_Tier06_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorChest_MspSpeedSet_Tier06_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorWrist_MspSpeedSet_Tier06_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorLegs_MspSpeedSet_Tier06_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorChest_MspDamageSet_Tier06_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorWrist_MspDamageSet_Tier06_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_KratosArmorLegs_MspDamageSet_Tier06_NGP")
    end
  end
  if game.Wallets.HasResource("HERO", "Blades") == true and game.Wallets.HasResource("HERO", "MuspBladeRecipes") == false then
    game.Wallets.AddRecipe("HERO", "Recipe_WeaponComponent_Blades_Muspelheim01")
    game.Wallets.AddRecipe("HERO", "WeaponSpecial_BladeSpecialMeteorSlam")
    if game.GetNewGamePlus() then
      game.Wallets.AddRecipe("HERO", "Recipe_BladeWeaponSpecial_01_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_BladeWeaponSpecial_02_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_BladeWeaponSpecial_03_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_BladeWeaponSpecial_04_NGP")
      game.Wallets.AddRecipe("HERO", "Recipe_BladeWeaponSpecial_05_NGP")
    end
    game.Wallets.AddRecipe("HERO", "Recipe_BladeWeaponSpecial_01")
    game.Wallets.AddRecipe("HERO", "Recipe_BladeWeaponSpecial_02")
    game.Wallets.AddRecipe("HERO", "Recipe_BladeWeaponSpecial_03")
    game.Wallets.AddRecipe("HERO", "Recipe_BladeWeaponSpecial_04")
    game.Wallets.AddRecipe("HERO", "Recipe_BladeWeaponSpecial_05")
    game.Wallets.AddResource("HERO", "MuspBladeRecipes", 1)
    if game.GetNewGamePlus() then
      game.Wallets.AddRecipe("HERO", "Recipe_WeaponComponent_Blades_Muspelheim01_NGP")
    end
  end
end
function MspFastTravelUsed()
  if GateEntryBanterPlayed == false then
    game.Audio.PlayBanter("MuspelGateEntry", nil, nil, false)
    GateEntryBanterPlayed = true
  end
  enterMSP100Music()
end
function OnEvaluateLoadGroup_LoadGroup_Arena01()
  local goldUnlocked_01 = game.Level.GetVariable("MUS_Arena1Rank")
  if goldUnlocked_01 < 2 then
    return "AI_Standard_01"
  else
    return "AI_Gold_01"
  end
end
function OnEvaluateLoadGroup_LoadGroup_Arena02()
  local goldUnlocked_02 = game.Level.GetVariable("MUS_Arena2Rank")
  if goldUnlocked_02 < 2 then
    return "AI_Standard_02"
  else
    return "AI_Gold_02"
  end
end
function OnEvaluateLoadGroup_LoadGroup_Arena03()
  local goldUnlocked_03 = game.Level.GetVariable("MUS_Arena3Rank")
  if goldUnlocked_03 < 2 then
    return "AI_Standard_03"
  else
    return "AI_Gold_03"
  end
end
function OnEvaluateLoadGroup_LoadGroup_Arena04()
  local goldUnlocked_04 = game.Level.GetVariable("MUS_Arena4Rank")
  if goldUnlocked_04 < 2 then
    return "AI_Standard_04"
  else
    return "AI_Gold_04"
  end
end
function OnEvaluateLoadGroup_LoadGroup_Arena05()
  local goldUnlocked_05 = game.Level.GetVariable("MUS_Arena5Rank")
  if goldUnlocked_05 < 2 then
    return "AI_Standard_05"
  else
    return "AI_Gold_05"
  end
end
function OnEvaluateLoadGroup_LoadGroup_Arena06()
  local arenaRank = game.Level.GetVariable("MUS_Arena6Rank")
  if arenaRank < 2 then
    return "AI_Standard_06"
  else
    return GameObjects.MSP_Arena06ChallengeManager.LuaObjectScript.GetCurrentChallengeInfo().loadGroup
  end
end
function MSP_ChangeLoadGroup()
  game.EvaluateLoadZones()
end
function ShowCavernZones()
  GameObjects.SNDZnMsp100_L2Cavern1:ShowSoundEmitterVolume()
  GameObjects.SNDZnMsp100_L2Cavern1Dly:ShowSoundEmitterVolume()
end
function HideCavernZones()
  GameObjects.SNDZnMsp100_L2Cavern1:HideSoundEmitterVolume()
  GameObjects.SNDZnMsp100_L2Cavern1Dly:HideSoundEmitterVolume()
end
local msp100ExploreMusicActive = false
function MusicOnStart()
  if msp100ExploreMusicActive then
    game.Audio.StartCheckpointedMusic("SND_MX_MSP_explore1_in")
  end
end
function CalderaAirLock_FTArrival(level)
  msp100ExploreMusicActive = false
end
function enterMSP100Music_FromTop()
  if game.Level.GetVariable("ValkyrieMuspSeen") and msp100ExploreMusicActive == false then
    game.Audio.StartCheckpointedMusic("SND_MX_MSP_explore1_in")
    msp100ExploreMusicActive = true
  end
end
function enterMSP100Music()
  game.Audio.StartCheckpointedMusic("SND_MX_MSP_explore1_in")
  msp100ExploreMusicActive = true
end
function exitMSP100Mus()
  if msp100ExploreMusicActive == true then
    game.Audio.StartMusic("SND_MX_MSP_idle")
    msp100ExploreMusicActive = false
  end
end
function climbInMusic()
  game.Audio.StartMusic("SND_MX_MSP_climb_to_top")
  msp100ExploreMusicActive = false
end
function reachTopMusic()
  game.Audio.StartMusic("SND_MX_MSP_reach_top")
end
function PlayBTR_MuspelLavaFall()
  game.Audio.PlayBanter("MuspelLavaFall")
end
function OnSaveCheckpoint(level)
  return {
    levelstate = checkpoint.Save(),
    msp100ExploreMusicActive = msp100ExploreMusicActive,
    GateEntryBanterPlayed = GateEntryBanterPlayed
  }
end
function OnRestoreCheckpoint(level, savedInfo)
  checkpoint.Restore(savedInfo.levelstate)
  msp100ExploreMusicActive = savedInfo.msp100ExploreMusicActive
  GateEntryBanterPlayed = false
  if savedInfo.GateEntryBanterPlayed ~= nil then
    GateEntryBanterPlayed = savedInfo.GateEntryBanterPlayed
  end
end
