local LD = require("design.LevelDesignLibrary")
local timers = require("level.timer")
local TUT = require("game.GlobalTutorials")
local uiCalls = require("ui.uicalls")
local thisObj, thisLevel, player, enabled, interactZone, sonCAIdle, banterScript, warpModule
local chestsLooted = 0
local nextReward
local training = {
  active = false,
  enter_gate_down = nil,
  exit_gate_down = nil
}
local enemyGate_L, enemyGate_R, enemyGate_C, enemyGate_L_02, enemyGate_R_02, arenaGate_Enter, arenaGate_Exit, onInteractStartCallbacks, onCancelledCallbacks, onArenaStartCallbacks, onBronzeWinCallbacks, onSilverWinCallbacks, onGoldWinCallbacks, onWinPostGoldCallbacks
local winCallbackTable = {}
local arenaNum, interact_anim_fx, interact_anim_mesh, markerEmitter, markerAnimObject
local markerAnimFrames = {
  activate_start = 120,
  activate_end = 160,
  deactivate_start = 0,
  deactivate_end = 40
}
local currentArenaAttempts = 0
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  player = game.Player.FindPlayer()
  interactZone = LD.CreateInteractZone_Standard_180(obj, "promptJoint")
  markerAnimObject = thisObj:FindSingleGOByName("Sword_Pedestal_Root")
  onInteractStartCallbacks = thisObj:FindLuaTableAttribute("OnInteractStartCallbacks")
  if onInteractStartCallbacks ~= nil then
    onInteractStartCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, onInteractStartCallbacks)
  end
  onCancelledCallbacks = thisObj:FindLuaTableAttribute("OnCancelledCallbacks")
  if onCancelledCallbacks ~= nil then
    onCancelledCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, onCancelledCallbacks)
  end
  onArenaStartCallbacks = thisObj:FindLuaTableAttribute("OnArenaStartCallbacks")
  if onArenaStartCallbacks ~= nil then
    onArenaStartCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, onArenaStartCallbacks)
  end
  onBronzeWinCallbacks = thisObj:FindLuaTableAttribute("OnBronzeWinCallbacks")
  if onBronzeWinCallbacks ~= nil then
    onBronzeWinCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, onBronzeWinCallbacks)
  end
  onSilverWinCallbacks = thisObj:FindLuaTableAttribute("OnSilverWinCallbacks")
  if onSilverWinCallbacks ~= nil then
    onSilverWinCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, onSilverWinCallbacks)
  end
  onGoldWinCallbacks = thisObj:FindLuaTableAttribute("OnGoldWinCallbacks")
  if onGoldWinCallbacks ~= nil then
    onGoldWinCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, onGoldWinCallbacks)
  end
  onWinPostGoldCallbacks = thisObj:FindLuaTableAttribute("OnWinPostGoldCallbacks")
  if onWinPostGoldCallbacks ~= nil then
    onWinPostGoldCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, onWinPostGoldCallbacks)
  end
  winCallbackTable = {
    onBronzeWinCallbacks,
    onSilverWinCallbacks,
    onGoldWinCallbacks,
    onWinPostGoldCallbacks
  }
  banterScript = GameObjects.Msp100_Banter.LuaObjectScript
  arenaNum = thisObj:FindLuaTableAttribute("ArenaNum")
  sonCAIdle = thisObj:FindSingleGOByName("CA_IdleBehavior_SonMSPInteract")
  warpModule = thisObj:FindSingleGOByName("SonWarpModule")
  interact_anim_fx = thisObj:FindSingleGOByName("interact_anim_fx")
  interact_anim_mesh = thisObj:FindSingleGOByName("interact_anim_mesh")
  interact_anim_mesh:JumpAnimToFrame(0)
  interact_anim_mesh:PauseAnim()
  local arenaString = tostring(arenaNum)
  enemyGate_L = thisLevel:FindSingleGameObject("Arena0" .. arenaString .. "EnemyGateLeft")
  enemyGate_R = thisLevel:FindSingleGameObject("Arena0" .. arenaString .. "EnemyGateRight")
  enemyGate_C = thisLevel:FindSingleGameObject("Arena0" .. arenaString .. "EnemyGateCenter")
  enemyGate_L_02 = thisLevel:FindSingleGameObject("Arena0" .. arenaString .. "EnemyGateLeft02")
  enemyGate_R_02 = thisLevel:FindSingleGameObject("Arena0" .. arenaString .. "EnemyGateRight02")
  arenaGate_Enter = thisLevel:FindSingleGameObject("arena0" .. arenaString .. "_GateEnter")
  arenaGate_Exit = thisLevel:FindSingleGameObject("arena0" .. arenaString .. "_GateExit")
  game.SubObject.Sleep(obj)
end
function OnFirstStart(level, obj)
  if arenaNum < 6 then
    enabled = true
    MarkerAnimStart()
  else
    enabled = false
    MarkerAnimOff()
  end
  HideChest(1)
  HideChest(2)
  HideChest(3)
  DisableMarkerResetZone()
  RaiseGateImmediate(GetArenaGate_Exit())
  LowerGateImmediate(GetArenaGate_Enter())
end
function OnStart(level, obj)
  RegisterChestInteractCallbacks()
  RegisterEncounterCompletionCallbacks()
  RegisterMarkerResetZoneEntryCallbacks()
  if enabled == false then
    Disable()
  else
    Enable()
  end
end
function OnUseWorld(level, obj)
  if interactZone:CanInteract() then
    player:RequestInteract(thisObj, {InteractZone = interactZone})
  end
end
function OnInteractStart()
  TUT.HideTutorial()
  if training.active == true then
    _G.StopTrainingMode()
    training.active = false
    if training.enter_gate_down == true then
      training.enter_gate_down = nil
      GetArenaGate_Enter().Child:JumpAnimToFrame(600)
      LowerGate(GetArenaGate_Enter())
    end
    if training.exit_gate_down == true then
      training.exit_gate_down = nil
      GetArenaGate_Exit().Child:JumpAnimToFrame(600)
      LowerGate(GetArenaGate_Exit())
    end
  end
  warpModule.LuaObjectScript.WarpSon()
  if onInteractStartCallbacks then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, onInteractStartCallbacks)
  end
  banterScript.Btr_ChallengeEngaged(GetArenaTrackingVar())
  EnableSonContextAction_Idle()
  LD.PlaySingleSynchMove_KratosObject(thisObj, "synchJoint", "Muspelheim Arena Start", "BRA_MuspelheimArenaStartEnter", "a", interactZone, false, nil, {completion_percentage = 0.7})
  AddMarker_KeysRequired()
end
function LuaHook_StartInteractFX()
  interact_anim_mesh:JumpAnimToFrame(3)
  interact_anim_mesh:PlayAnimToEnd(0.12)
end
function LuaHook_StartInteractFX_02()
  LD.AddControllerRumble({EffectName = "FFB_MEDIUM", Duration = 1})
  LD.ShowFX(interact_anim_fx)
end
function LuaHook_StopInteractFX()
  LD.HideFX(interact_anim_fx)
  interact_anim_mesh:PlayAnimToEnd(-0.25)
end
function IsChallengeArenaFight()
  return arenaNum == 6 and GetArenaTrackingVar() > 1
end
function UseKeyRequirement()
  return game.Level.GetVariable("MUS_KeysRequired")
end
function AddMarker_KeysRequired()
  if UseKeyRequirement() and IsChallengeArenaFight() and GameObjects.MSP_Arena06ChallengeManager.LuaObjectScript.AllKeysAcquired() == false then
    player:AddMarker("MissingMuspArenaKeys")
  end
end
function RemoveMarker_KeysRequired()
  if UseKeyRequirement() then
    player:RemoveMarker("MissingMuspArenaKeys")
  end
end
function LuaHook_ShowInteractTutorial()
  local challengeManagerScript = GameObjects.MSP_Arena06ChallengeManager.LuaObjectScript
  if IsChallengeArenaFight() then
    _G.MSP_ChangeLoadGroup()
    local challengeInfo = challengeManagerScript.GetCurrentChallengeInfo()
    TUT.Musp_ChallengeArena_Tutorial(challengeInfo)
  else
    TUT.Musp_ArenaStart_Tutorial(GetArenaTrackingVar())
  end
  ResetMeters()
end
function LuaHook_InteractCancelled()
  RemoveMarker_KeysRequired()
  TUT.HideTutorial()
  DisableSonContextAction_Idle()
  banterScript.Btr_ChallengeCancelled()
  if onCancelledCallbacks then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, onCancelledCallbacks)
  end
end
function ResetMeters()
  player:MeterSetValue("Health", player:MeterGetMax("Health"))
end
function LuaHook_StartTraining()
  RemoveMarker_KeysRequired()
  training.active = true
  ShowChestFog()
  ShowCentralGateCollision()
  HideChest(GetArenaTrackingVar())
  RaiseGate(GetEnemyGate_Center())
  if GetArenaGate_Enter() ~= nil and GetArenaGate_Enter().LuaObjectScript.IsGateRaised() == false then
    training.enter_gate_down = true
    RaiseGate(GetArenaGate_Enter())
  end
  if GetArenaGate_Exit() ~= nil and GetArenaGate_Exit().LuaObjectScript.IsGateRaised() == false then
    training.exit_gate_down = true
    RaiseGate(GetArenaGate_Exit())
  end
  TUT.HideTutorial()
  uiCalls.SendBottomDesignerMessage({
    Text = 44180,
    AdvanceType = uiCalls.msgParam.INFINITE_TIMER
  })
  interactZone:ClearTags("NotInCombat")
  _G.StartTrainingMode(arenaNum)
end
function LuaHook_InteractAccepted()
  RemoveMarker_KeysRequired()
  DestroyAllHealth()
  DestroyAllRage()
  game.Combat.TurnOnAndLockCombatStatus()
  local fightTier = GetArenaTrackingVar()
  Disable()
  TUT.HideTutorial()
  ShowChestFog()
  MarkerAnimOff()
  DisableSonContextAction_Idle()
  if onArenaStartCallbacks then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, onArenaStartCallbacks)
  end
  game.Blender.Trigger({
    Name = "FSE_SWAY_CRANK_RUMBLE_SMALL",
    Duration = 0.5,
    TweenIn = {Time = 0}
  })
  game.Blender.Trigger({
    Name = "FFB_GENERIC_RUMBLE_STRONG",
    TweenIn = {Time = 0},
    Duration = 0.5,
    TweenOut = {Time = 0.5}
  })
  ShowCentralGateCollision()
  if 0 < fightTier then
    HideChest(fightTier)
  end
  RaiseGate(GetArenaGate_Enter())
  RaiseGate(GetArenaGate_Exit())
  if arenaNum < 6 or arenaNum == 6 and 1 < fightTier then
    LowerGate(GetEnemyGate_Center())
    LowerGate(GetEnemyGate_Left())
    LowerGate(GetEnemyGate_Right())
    LowerGate(GetEnemyGate_Left_02())
    LowerGate(GetEnemyGate_Right_02())
  end
  local encounterStartFunction = GetEncounterStartFunction()
  LD.CallFunctionAfterDelay(encounterStartFunction, 2)
  PlayAcceptedSound()
  banterScript.Btr_ChallengeAccepted(currentArenaAttempts)
  currentArenaAttempts = currentArenaAttempts + 1
  StartQuests(fightTier)
end
function ChallengeFailed()
  DestroyAllHealth()
  DestroyAllRage()
  ResetMeters()
  banterScript.Btr_ChallengeFailed()
  local gateLowerDelay = 3
  local fightTier = GetArenaTrackingVar()
  if 2 <= fightTier then
    LD.CallFunctionAfterDelay(function()
      if GetArenaGate_Exit() ~= nil then
        GetArenaGate_Exit().Child:JumpAnimToFrame(600)
      end
      LowerGate(GetArenaGate_Exit())
    end, gateLowerDelay)
  end
  RaiseGate(GetEnemyGate_Center())
  RaiseGate(GetEnemyGate_Left())
  RaiseGate(GetEnemyGate_Right())
  RaiseGate(GetEnemyGate_Left_02())
  RaiseGate(GetEnemyGate_Right_02())
  LD.CallFunctionAfterDelay(function()
    ResetMarkerInteract()
  end, 3)
  LD.CallFunctionAfterDelay(function()
    local entryGate = GetArenaGate_Enter()
    if entryGate then
      entryGate.Child:JumpAnimToFrame(600)
      LowerGate(entryGate)
    end
  end, gateLowerDelay)
end
function OnArenaComplete(currentTier)
  DestroyAllHealth()
  DestroyAllRage()
  if arenaNum < 6 or arenaNum == 6 and 2 < currentTier then
    banterScript.Btr_ChallengeSuccess(currentTier, arenaNum)
  end
  CompleteObjectives(currentTier)
  currentArenaAttempts = 0
  if 4 <= currentTier then
    currentTier = 4
  end
  if winCallbackTable[currentTier] then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, winCallbackTable[currentTier])
  end
  HideCentralGateCollision()
  RaiseGate(GetEnemyGate_Left())
  RaiseGate(GetEnemyGate_Right())
  RaiseGate(GetEnemyGate_Left_02())
  RaiseGate(GetEnemyGate_Right_02())
  HideChestFog()
  ShowChest(currentTier)
  LowerGate(GetEnemyGate_Center())
end
function CheckForChallengeKeyReward()
  if UseKeyRequirement() and GetArenaTrackingVar() > 2 then
    local totalKeys = TUT.Musp_GetNumKeys()
    if totalKeys < 3 then
      game.Wallets.AddResource("HERO", "MspArenaKey0" .. arenaNum, 1)
    end
  end
end
function OnChestInteract()
  local trackingVar = GetArenaTrackingVar()
  local usingKeys = UseKeyRequirement()
  if arenaNum == 6 then
    chestsLooted = chestsLooted + 1
  else
    banterScript.Btr_LootAcquired(trackingVar)
  end
  if arenaNum < 6 or arenaNum == 6 and chestsLooted == 2 then
    chestsLooted = 0
    LowerGate(GetArenaGate_Enter())
    if 2 <= trackingVar then
      LowerGate(GetArenaGate_Exit())
    end
    if usingKeys == true and (trackingVar < 2 or arenaNum == 6 and 3 <= trackingVar) or usingKeys == false and (trackingVar < 2 or 3 <= trackingVar) then
      EnableMarkerResetZone()
    end
    if usingKeys == true and arenaNum == 6 and 2 < trackingVar then
      GameObjects.MSP_Arena06ChallengeManager.LuaObjectScript.RemoveKeysOnComplete()
    end
    UpdateGoldChallengeAvailability(usingKeys, trackingVar)
  end
end
function UpdateGoldChallengeAvailability(usingKeys, trackingVar)
  if usingKeys == true then
    if arenaNum == 6 and trackingVar == 2 then
      EnableMarkerResetZone()
      LD.CallFunctionAfterDelay(function()
        game.Audio.PlayBanter("MuspelMastery_Gold")
      end, 8)
      ResetAllSubArenas()
    end
  elseif arenaNum == 6 and trackingVar == 2 then
    GameObjects.Muspelheim_Arena_Marker_01.LuaObjectScript.ResetMarkerInteract()
    if UseKeyRequirement() == false then
      LD.CallFunctionAfterDelay(function()
        uiCalls.UI_Event_SendTutorialMessage(40873, -1)
      end, 11)
    end
  elseif arenaNum < 6 and trackingVar == 3 and 6 >= arenaNum + 1 then
    GameObjects["Muspelheim_Arena_Marker_0" .. tostring(arenaNum + 1)].LuaObjectScript.ResetMarkerInteract()
  end
end
function ResetAllSubArenas()
  for i = 1, 5 do
    GameObjects["Muspelheim_Arena_Marker_0" .. i].LuaObjectScript.ResetMarkerInteract()
  end
end
function IncrementArenaTrackingVar()
  local newArenaValue = GetArenaTrackingVar() + 1
  local varName = "MUS_Arena" .. tostring(arenaNum) .. "Rank"
  if newArenaValue <= 4 then
    LD.SetEntityVariable(varName, newArenaValue)
  end
  return newArenaValue
end
function GetEnemyGate_Center()
  return enemyGate_C
end
function GetEnemyGate_Left()
  return enemyGate_L
end
function GetEnemyGate_Right()
  return enemyGate_R
end
function GetEnemyGate_Left_02()
  return enemyGate_L_02
end
function GetEnemyGate_Right_02()
  return enemyGate_R_02
end
function GetArenaGate_Enter()
  return arenaGate_Enter
end
function GetArenaGate_Exit()
  return arenaGate_Exit
end
function GetArenaScript()
  return thisLevel:FindSingleGameObject("CBT_Script_Msp1" .. arenaNum .. "0").LuaObjectScript
end
function GetEncounterStartFunction()
  return GetEncounter()
end
function GetArenaTrackingVar()
  local varName = "MUS_Arena" .. tostring(arenaNum) .. "Rank"
  return LD.GetEntityVariable(varName)
end
function GetChestRarityFromTrackingVar(tier)
  if tier == 1 then
    return "_bronze_legendary_tier3"
  elseif tier == 2 then
    return "_silver_legendary_tier3"
  else
    return "_gold_legendary_tier3"
  end
end
function GetEncounter()
  local arenaRank = GetArenaTrackingVar() + 1
  if 4 <= arenaRank then
    arenaRank = 3
  end
  return GetArenaScript()["Start_Area_" .. tostring(arenaNum) .. "_Encounter_" .. tostring(arenaRank)]
end
function EnableSonContextAction_Idle()
  if sonCAIdle then
    sonCAIdle.LuaObjectScript.Enable()
  end
end
function DisableSonContextAction_Idle()
  if sonCAIdle then
    sonCAIdle.LuaObjectScript.Disable()
  end
end
function RaiseGate(gateObject)
  if gateObject and gateObject.LuaObjectScript then
    gateObject.LuaObjectScript.RaiseGate()
  end
end
function LowerGate(gateObject)
  if gateObject and gateObject.LuaObjectScript then
    gateObject.LuaObjectScript.LowerGate()
  end
end
function LowerGateImmediate(gateObject)
  if gateObject and gateObject.LuaObjectScript then
    gateObject.LuaObjectScript.LowerGateImmediate()
  end
end
function RaiseGateImmediate(gateObject)
  if gateObject and gateObject.LuaObjectScript then
    gateObject.LuaObjectScript.RaiseGateImmediate()
  end
end
function MarkerAnimStart()
  markerAnimObject:ShowCollision()
  thisObj:ShowNavObstacle()
  markerAnimObject:StartAnim("sword_pedestal_lava_mat")
  markerAnimObject:StartAnim("sword_pedestal_mat_mat")
  markerAnimObject:JumpAnimToFrame(markerAnimFrames.deactivate_start)
  markerAnimObject:PauseAnim()
end
function MarkerAnimOn()
  if markerAnimObject.AnimFrame ~= markerAnimFrames.activate_end then
    markerAnimObject:ShowCollision()
    markerAnimObject:JumpAnimToFrame(markerAnimFrames.activate_start)
    markerAnimObject:PlayAnimToFrame(markerAnimFrames.activate_end)
    PlayReformSound()
  end
end
function MarkerAnimOff()
  if markerAnimObject.AnimFrame ~= markerAnimFrames.deactivate_end then
    markerAnimObject:HideCollision()
    thisObj:HideNavObstacle()
    markerAnimObject:StartAnim("sword_pedestal_lava_mat")
    markerAnimObject:StartAnim("sword_pedestal_mat_mat")
    markerAnimObject:JumpAnimToFrame(markerAnimFrames.deactivate_start)
    markerAnimObject:PlayAnimToFrame(markerAnimFrames.deactivate_end)
  end
end
function ResetMarkerInteract()
  banterScript.Btr_SwordReturns(GetArenaTrackingVar(), arenaNum)
  MarkerAnimOn()
  Enable()
  if game.AIUtil.Distance(player, thisObj) < 30 then
    game.Blender.Trigger({
      Name = "FSE_SWAY_CRANK_RUMBLE_SMALL",
      Duration = 0.5,
      TweenIn = {Time = 0}
    })
    game.Blender.Trigger({
      Name = "FFB_GENERIC_RUMBLE_STRONG",
      TweenIn = {Time = 0},
      Duration = 0.5,
      TweenOut = {Time = 0.5}
    })
  end
end
function Enable()
  enabled = true
  interactZone:Enable()
end
function Disable()
  enabled = false
  interactZone:Disable()
end
function GetInteractZone()
  return interactZone
end
function ShowChestFog()
  local fogName = "arena0" .. tostring(arenaNum) .. "_fog_center"
  LD.ShowFX(GameObjects[fogName])
end
function HideChestFog()
  local fogName = "arena0" .. tostring(arenaNum) .. "_fog_center"
  LD.HideFX(GameObjects[fogName])
end
function UpdateRewards(rewardTier)
  nextReward = rewardTier
end
function ShowChest(tier)
  if arenaNum < 6 then
    local chestName = "arena0" .. tostring(arenaNum) .. GetChestRarityFromTrackingVar(tier)
    GameObjects[chestName].LuaObjectScript.Reset()
    GameObjects[chestName].LuaObjectScript.ShowChest()
    GameObjects[chestName].LuaObjectScript.Enable()
  else
    GameObjects.Arena06_ChestElevator_R:PlayAnimToEnd()
    GameObjects.Arena06_ChestElevator_L:PlayAnimToEnd()
    if nextReward == nil then
      GameObjects.arena06_gold_legendary_tier3_R.LuaObjectScript.Reset()
      GameObjects.arena06_gold_legendary_tier3_R.LuaObjectScript.ShowChest()
      GameObjects.arena06_gold_legendary_tier3_R.LuaObjectScript.Enable()
      GameObjects.arena06_gold_legendary_tier3_L.LuaObjectScript.Reset()
      GameObjects.arena06_gold_legendary_tier3_L.LuaObjectScript.ShowChest()
      GameObjects.arena06_gold_legendary_tier3_L.LuaObjectScript.Enable()
    else
      local chests = {
        "Surtrs_Trial_",
        "Surtrs_Trial_"
      }
      for i = 1, #chests do
        chests[i] = chests[i] .. nextReward
        if i == 1 then
          chests[i] = chests[i] .. "_L"
        else
          chests[i] = chests[i] .. "_R"
        end
        GameObjects[chests[i]].LuaObjectScript.Reset()
        GameObjects[chests[i]].LuaObjectScript.ShowChest()
        GameObjects[chests[i]].LuaObjectScript.Enable()
      end
    end
  end
end
function HideChest(tier)
  if arenaNum < 6 then
    local chestName = "arena0" .. tostring(arenaNum) .. GetChestRarityFromTrackingVar(tier)
    LD.CallFunctionAfterDelay(function()
      GameObjects[chestName].LuaObjectScript.HideChest()
    end, 6)
    GameObjects[chestName].LuaObjectScript.Disable()
  else
    GameObjects.Arena06_ChestElevator_R:PlayAnimToEnd(-1)
    GameObjects.Arena06_ChestElevator_L:PlayAnimToEnd(-1)
    local chestTiers = {
      "_bronze_legendary_tier3",
      "_silver_legendary_tier3",
      "_gold_legendary_tier3"
    }
    for _, string in pairs(chestTiers) do
      local chestName_R = "arena0" .. tostring(arenaNum) .. string .. "_R"
      GameObjects[chestName_R].LuaObjectScript.Disable()
      local chestName_L = "arena0" .. tostring(arenaNum) .. string .. "_L"
      GameObjects[chestName_L].LuaObjectScript.Disable()
      LD.CallFunctionAfterDelay(function()
        GameObjects[chestName_R].LuaObjectScript.HideChest()
        GameObjects[chestName_L].LuaObjectScript.HideChest()
      end, 6)
    end
    local surtrChestTiers = {
      "Surtrs_Trial_Bronze",
      "Surtrs_Trial_Silver",
      "Surtrs_Trial_Gold"
    }
    for _, string in pairs(surtrChestTiers) do
      local chestName_R = string .. "_R"
      GameObjects[chestName_R].LuaObjectScript.Disable()
      local chestName_L = string .. "_L"
      GameObjects[chestName_L].LuaObjectScript.Disable()
      LD.CallFunctionAfterDelay(function()
        GameObjects[chestName_R].LuaObjectScript.HideChest()
        GameObjects[chestName_L].LuaObjectScript.HideChest()
      end, 6)
    end
  end
end
function ShowCentralGateCollision()
  if GetEnemyGate_Center() then
    GetEnemyGate_Center().LuaObjectScript.ShowGateCollision()
  end
end
function HideCentralGateCollision()
  if GetEnemyGate_Center() then
    GetEnemyGate_Center().LuaObjectScript.HideGateCollision()
  end
end
function RegisterChestInteractCallbacks()
  if arenaNum < 6 then
    local RegisterForKeyReward = function(obj)
      if UseKeyRequirement() then
        obj.LuaObjectScript.RegisterOnInteractFinishCallback(CheckForChallengeKeyReward)
      end
    end
    local chest01Name = "arena0" .. tostring(arenaNum) .. "_bronze_legendary_tier3"
    if GameObjects[chest01Name] then
      GameObjects[chest01Name].LuaObjectScript.RegisterOnInteractStartCallback(OnChestInteract)
      RegisterForKeyReward(GameObjects[chest01Name])
    end
    local chest02Name = "arena0" .. tostring(arenaNum) .. "_silver_legendary_tier3"
    if GameObjects[chest02Name] then
      GameObjects[chest02Name].LuaObjectScript.RegisterOnInteractStartCallback(OnChestInteract)
      RegisterForKeyReward(GameObjects[chest02Name])
    end
    local chest03Name = "arena0" .. tostring(arenaNum) .. "_gold_legendary_tier3"
    if GameObjects[chest03Name] then
      GameObjects[chest03Name].LuaObjectScript.RegisterOnInteractStartCallback(OnChestInteract)
      RegisterForKeyReward(GameObjects[chest03Name])
    end
  else
    local chest03_L_Name = "arena06_gold_legendary_tier3_L"
    GameObjects[chest03_L_Name].LuaObjectScript.RegisterOnInteractStartCallback(OnChestInteract)
    local chest03_R_Name = "arena06_gold_legendary_tier3_R"
    GameObjects[chest03_R_Name].LuaObjectScript.RegisterOnInteractStartCallback(OnChestInteract)
    local surtrChestTiers = {
      "Surtrs_Trial_Bronze",
      "Surtrs_Trial_Silver",
      "Surtrs_Trial_Gold"
    }
    for _, string in pairs(surtrChestTiers) do
      local chestName_R = string .. "_R"
      local chestName_L = string .. "_L"
      GameObjects[chestName_R].LuaObjectScript.RegisterOnInteractStartCallback(OnChestInteract)
      GameObjects[chestName_L].LuaObjectScript.RegisterOnInteractStartCallback(OnChestInteract)
    end
  end
end
function RegisterEncounterCompletionCallbacks()
  for i = 1, 3 do
    GetArenaScript().AddOnCompleteCallback(i, function()
      local newArenaValue = IncrementArenaTrackingVar()
      OnArenaComplete(newArenaValue)
    end)
  end
end
function EnableMarkerResetZone()
  GameObjects["Msp_Arena_0" .. tostring(arenaNum) .. "_ResetMarkerZone"].LuaObjectScript.Enable()
end
function DisableMarkerResetZone()
  GameObjects["Msp_Arena_0" .. tostring(arenaNum) .. "_ResetMarkerZone"].LuaObjectScript.Disable()
end
function RegisterMarkerResetZoneEntryCallbacks()
  GameObjects["Msp_Arena_0" .. tostring(arenaNum) .. "_ResetMarkerZone"].LuaObjectScript.RegisterEntryCallback(function()
    DisableMarkerResetZone()
    ResetMarkerInteract()
    if UseKeyRequirement() and arenaNum == 6 and GetArenaTrackingVar() >= 2 then
      ResetAllSubArenas()
    end
  end)
end
function StartQuests(trackingVar)
  if trackingVar < 3 then
    local rarity = GetRarityFromTrackingVar_PreFight(trackingVar)
    local questName = "Quest_Muspelheim_Arena0" .. tostring(arenaNum) .. "_" .. rarity .. "_Parent"
    LD.ActivateQuest(questName)
    print("Quest: ", questName)
  elseif 3 <= trackingVar then
    UI_RepeatGoldQuestStarted()
  end
end
function CompleteObjectives(trackingVar)
  if trackingVar <= 3 then
    local rarity = GetRarityFromTrackingVar_PostFight(trackingVar)
    local questName = "Quest_Muspelheim_Arena0" .. tostring(arenaNum) .. "_" .. rarity .. "_Objective_01"
    LD.CompleteQuest(questName)
    print("Quest: ", questName)
    if arenaNum == 6 and rarity == "Gold" then
      game.UnlockTrophy(34)
    end
  elseif 3 < trackingVar then
    UI_RepeatGoldQuestComplete()
  end
end
local goldChallengeDescriptions = {
  [1] = {
    header = 21605,
    body = 21648,
    quest = "Quest_Muspelheim_Arena01_Gold_Parent"
  },
  [2] = {
    header = 21617,
    body = 18534,
    quest = "Quest_Muspelheim_Arena02_Gold_Parent"
  },
  [3] = {
    header = 21628,
    body = 21624,
    quest = "Quest_Muspelheim_Arena03_Gold_Parent"
  },
  [4] = {
    header = 21640,
    body = 21613,
    quest = "Quest_Muspelheim_Arena04_Gold_Parent"
  },
  [5] = {
    header = 21652,
    body = 18580,
    quest = "Quest_Muspelheim_Arena05_Gold_Parent"
  },
  [6] = {
    header = 18582,
    body = 18584,
    quest = "Quest_Muspelheim_Arena06_Gold_Parent"
  }
}
function UI_RepeatGoldQuestStarted()
  uiCalls.UI_Event_SendMsgToQuestLog({
    Category = 37827,
    Header = goldChallengeDescriptions[arenaNum].header,
    Body = goldChallengeDescriptions[arenaNum].body,
    MessageType = tweaks.tQuestUiMessage.eMessageType.kQMS_Default,
    Quest = goldChallengeDescriptions[arenaNum].quest
  })
end
function UI_RepeatGoldQuestComplete()
  uiCalls.UI_Event_SendMsgToQuestLog({
    Header = 21639,
    Body = 21638,
    MessageType = tweaks.tQuestUiMessage.eMessageType.kQMS_CompleteSpecial,
    Quest = goldChallengeDescriptions[arenaNum].quest
  })
end
function GetRarityFromTrackingVar_PreFight(trackingVar)
  if trackingVar == 0 then
    return "Bronze"
  elseif trackingVar == 1 then
    return "Silver"
  elseif trackingVar == 2 then
    return "Gold"
  end
end
function GetRarityFromTrackingVar_PostFight(trackingVar)
  if trackingVar == 1 then
    return "Bronze"
  elseif trackingVar == 2 then
    return "Silver"
  elseif trackingVar == 3 then
    return "Gold"
  end
end
function OnSaveCheckpoint(level, obj)
  return {enabled = enabled, chestsLooted = chestsLooted}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  enabled = savedInfo.enabled
  chestsLooted = savedInfo.chestsLooted
end
function PlayAcceptedSound()
  markerEmitter = GameObjects.SNDArenaMarkers:FindSingleSoundEmitterByName("SNDArena" .. tostring(arenaNum) .. "Marker")
  LD.PlaySound(markerEmitter, "SND_MECH_Arena_Marker_Sword_Dissolve")
end
function PlayReformSound()
  markerEmitter = GameObjects.SNDArenaMarkers:FindSingleSoundEmitterByName("SNDArena" .. tostring(arenaNum) .. "Marker")
  LD.PlaySound(markerEmitter, "SND_MECH_Arena_Marker_Sword_Appear")
end
function DestroyAllHealth()
  local healthPickupArray = {}
  healthPickupArray = game.World.FindGameObjectsByMarker("HealthRuneDrop", player:GetWorldPosition(), 100)
  for _, hpickup in pairs(healthPickupArray) do
    if hpickup ~= nil then
      hpickup:CallScript("DestroyObject")
    end
  end
end
function DestroyAllRage()
  local ragePickupArray = {}
  ragePickupArray = game.World.FindGameObjectsByMarker("RageRuneDrop", player:GetWorldPosition(), 100)
  for _, rpickup in pairs(ragePickupArray) do
    if rpickup ~= nil then
      rpickup:CallScript("DestroyObject")
    end
  end
end
