local classlib = require("core.class")
local tablex = require("core.tablex")
local animationUtil = require("ui.animationUtil")
local buttonUtil = require("ui.buttonUtil")
local colors = require("ui.colors")
local consts = require("ui.consts")
local fsm = require("ui.fsm")
local lamsConsts = require("ui.lamsConsts")
local list = require("ui.list")
local mapConsts = require("ui.mapConsts")
local mapSummaryCard = require("ui.mapSummaryCard")
local mapUtil = require("ui.mapUtil")
local menu = require("ui.menu")
local pickupUtil = require("ui.pickupUtil")
local questConsts = require("ui.questConsts")
local questUtil = require("ui.questUtil")
local util = require("ui.util")
local tutorialUtil = require("ui.tutorialUtil")
local tutorials = require("ui.tutorials")
local Audio = game.Audio
local Camera = game.Camera
local Level = game.Level
local Map = game.Map
local Player = game.Player
local UI = game.UI
local CALDERA_MAP_POSITION = engine.Vector.New(-0.336, 0, 0.921)
local enabledShowOnCompassMarkerFlags = {
  consts.COMPASS_MARKER_TYPE_VENDOR,
  consts.COMPASS_MARKER_TYPE_FAST_TRAVEL,
  consts.COMPASS_MARKER_TYPE_AREA_ENTRANCE,
  consts.COMPASS_MARKER_TYPE_FIGHT_LOCATION,
  consts.COMPASS_MARKER_TYPE_CHISEL_ENTRANCE,
  consts.COMPASS_MARKER_TYPE_DOCK_POINT,
  consts.COMPASS_MARKER_TYPE_VALKYRIE
}
local markerStates = {
  tweaks.eTokenState.kDiscovered,
  tweaks.eTokenState.kDiscoveredButLocked
}
local alwaysOnMarkerFlags = {
  "PrimaryQuest",
  "SecondaryQuest"
}
local fastTravelMarkerFlags = {
  consts.COMPASS_MARKER_TYPE_FAST_TRAVEL,
  consts.COMPASS_MARKER_TYPE_FAST_TRAVEL_NO_TRACK
}
local markerFilters = {
  {
    name = 44102,
    markerIncludeFlags = {
      consts.COMPASS_MARKER_TYPE_VENDOR,
      consts.COMPASS_MARKER_TYPE_VENDOR_NO_TRACK,
      consts.COMPASS_MARKER_TYPE_FAST_TRAVEL,
      consts.COMPASS_MARKER_TYPE_FAST_TRAVEL_NO_TRACK,
      consts.COMPASS_MARKER_TYPE_DOCK_POINT,
      consts.COMPASS_MARKER_TYPE_AREA_ENTRANCE,
      consts.COMPASS_MARKER_TYPE_CHISEL_ENTRANCE,
      consts.COMPASS_MARKER_TYPE_CHISEL_ENTRANCE_NO_TRACK,
      consts.COMPASS_MARKER_TYPE_FIGHT_LOCATION,
      consts.COMPASS_MARKER_TYPE_FIGHT_LOCATION_NO_TRACK,
      consts.COMPASS_MARKER_TYPE_INFO_ONLY,
      consts.COMPASS_MARKER_TYPE_VALKYRIE
    }
  },
  {
    name = 44103,
    markerIncludeFlags = {
      consts.COMPASS_MARKER_TYPE_VENDOR,
      consts.COMPASS_MARKER_TYPE_VENDOR_NO_TRACK
    }
  },
  {name = 44104, markerIncludeFlags = fastTravelMarkerFlags},
  {
    name = 44105,
    markerIncludeFlags = {
      consts.COMPASS_MARKER_TYPE_DOCK_POINT
    }
  },
  {
    name = 44101,
    markerIncludeFlags = {
      consts.COMPASS_MARKER_TYPE_AREA_ENTRANCE,
      consts.COMPASS_MARKER_TYPE_CHISEL_ENTRANCE,
      consts.COMPASS_MARKER_TYPE_CHISEL_ENTRANCE_NO_TRACK
    }
  },
  {
    name = 44106,
    markerIncludeFlags = {
      consts.COMPASS_MARKER_TYPE_FIGHT_LOCATION,
      consts.COMPASS_MARKER_TYPE_FIGHT_LOCATION_NO_TRACK
    }
  },
  {
    name = 37166,
    markerIncludeFlags = {
      consts.COMPASS_MARKER_TYPE_VALKYRIE
    }
  }
}
local map_camera
map_camera = tweaks.tMapCamera.New({
  Name = "MapMenuCam",
  CollisionRoot = "Midgard_collision",
  OnSkillTree = false,
  HorizontalControlSpeed = 0.1,
  VerticalControlSpeed = 0.1,
  ZoomControlSpeed = 3.2,
  ZoomSpeedScale = 3,
  HorizontalPosition = 0,
  VerticalPosition = 0,
  ZoomPosition = 5,
  Pitch = 35,
  Yaw = 0,
  Roll = 0,
  MaxLeft = -4.9,
  MaxRight = 4,
  MaxUp = -3.7,
  MaxDown = 4.5,
  MaxIn = 6,
  MaxOut = 10,
  CursorSnap_Enabled = 1,
  CursorSnap_Strength = 2.4,
  CursorGOName = "MapCursor",
  ScaleMapCursorBasedOnZoom = true,
  CursorScale_Min = 0.5,
  CursorScale_Max = 0.85,
  Tofu = "never"
})
local MapMenu = classlib.Class("MapMenu", fsm.UIState)
local MapOff = MapMenu:StateClass("MapOff", fsm.UIState)
local MapOn = MapMenu:StateClass("MapOn", fsm.UIState)
local Midgard = MapMenu:StateClass("Midgard", fsm.UIState)
local Alfheim = MapMenu:StateClass("Alfheim", fsm.UIState)
local Helheim = MapMenu:StateClass("Helheim", fsm.UIState)
local Jotunheim = MapMenu:StateClass("Jotunheim", fsm.UIState)
local Niflheim = MapMenu:StateClass("Niflheim", fsm.UIState)
local Muspelheim = MapMenu:StateClass("Muspelheim", fsm.UIState)
local Svartalheim = MapMenu:StateClass("Svartalheim", fsm.UIState)
local Vanaheim = MapMenu:StateClass("Vanaheim", fsm.UIState)
local Asgard = MapMenu:StateClass("Asgard", fsm.UIState)
local mapMenu = MapMenu.New("mapMenu", {
  MapOff,
  MapOn,
  {
    Midgard,
    Alfheim,
    Helheim,
    Jotunheim,
    Niflheim,
    Muspelheim,
    Svartalheim,
    Vanaheim,
    Asgard
  }
})
function MapMenu:Enter()
  self:WantPadEvents(true)
  self:turnoff()
end
function MapMenu:Exit()
end
function MapMenu:turnoff()
  self:Goto("MapOff")
end
MapMenu.EVT_GAME_OVER = MapMenu.turnoff
MapMenu.EVT_Restart = MapMenu.turnoff
function MapOff:Setup()
  self.mapOn = self:GetState("MapOn")
end
function MapOff:Enter()
end
function MapOff:Exit()
end
function MapOff:EVT_TURN_ON_MAP_MENU(instructionEntries, instructionArgs)
  self.mapOn.menu:set_instructionEntries(instructionEntries)
  self.mapOn.menu:set_instructionArgs(instructionArgs)
  if #instructionEntries == 0 then
    self.mapOn.menu:AddInstructionEntry({
      StateName = "MapOn",
      ListName = consts.inworldMenu_SubmenuList,
      Item = mapUtil.GetPlayerRealm()
    })
  end
  self:Goto("MapOn")
end
function MapOn:Setup()
  self.mapOff = self:GetState("MapOff")
  self.currRealmName = nil
  self.currQuestID = nil
  self.currMarkerID = nil
  self.currShownMarkerID = nil
  self.clickedMarkerInfo = nil
  self.clickedPlayer = false
  self.currMarkerPlayerIcon = false
  self.fastTravelPointSelected = false
  self.fastTravelCancelled = false
  self.realmMarkerInfo = {}
  self.filterIndex = 1
  self.filterButtonMapping = {1}
  self.alwaysOnMarkers = {}
  self.markers = {}
  util.ShowRecursive("mapScene")
  self:HideAllMaps()
  util.Hide("AllMaps")
  self.goFilter = util.GetUiObjByName("SortList")
  self.goFilterList = self.goFilter:FindSingleGOByName("list")
  self.goFilterLabelContainer = self.goFilter:FindSingleGOByName("LabelContainer")
  self.goFilterLabel = self.goFilterLabelContainer:FindSingleGOByName("Label")
  self.thFilterLabel = UI.TextObject(self.goFilterLabel)
  self.goFilterIndicatorPrev = self.goFilter:FindSingleGOByName("IndicatorPrev")
  UI.SetTextIsClickable(util.GetTextHandle(self.goFilterIndicatorPrev))
  self.goFilterIndicatorNext = self.goFilter:FindSingleGOByName("IndicatorNext")
  UI.SetTextIsClickable(util.GetTextHandle(self.goFilterIndicatorNext))
  self.goFilterButtons = {
    1,
    2,
    3,
    4,
    5,
    6,
    7
  }
  self.goFilterButtonPositions = {
    engine.Vector.New(-13.939, -48.295, 1.351),
    engine.Vector.New(-13.539, -48.295, 1.351),
    engine.Vector.New(-13.139, -48.295, 1.351),
    engine.Vector.New(-12.739, -48.295, 1.351),
    engine.Vector.New(-12.339, -48.295, 1.351),
    engine.Vector.New(-11.939, -48.295, 1.351),
    engine.Vector.New(-11.539, -48.295, 1.351)
  }
  for i = 1, 7 do
    self.goFilterButtons[i] = self.goFilterList:FindSingleGOByName("Button" .. tostring(i)):FindSingleGOByName("button")
    UI.SetIsClickable(self.goFilterButtons[i])
  end
  self.menu = menu.Menu.New(self, {})
  self.menu:SetupSubmenuList(consts.inworldMenu_SubmenuList, {
    "EVT_Left_Release"
  }, {
    "EVT_Right_Release"
  })
  local goRefnode = util.GetUiObjByName("MapCursor")
  local goRefnodeChild = goRefnode:FindSingleGOByName("Root")
  goRefnode:Show()
  goRefnodeChild:Show()
  local goRegionSummaryCard = util.GetUiObjByName("mapSummary_Region")
  self.mapSummaryCard_Region = mapSummaryCard.MapSummaryCard.New(goRegionSummaryCard)
  self.mapSummaryCard_Region:Init("Region")
  local goRealmSummaryCard = util.GetUiObjByName("mapSummary_Realm")
  self.mapSummaryCard_Realm = mapSummaryCard.MapSummaryCard.New(goRealmSummaryCard)
  self.mapSummaryCard_Realm:Init("Realm")
  local goMapCursorText = util.GetUiObjByName("MapCursorInfo")
  self._goCursorTextGroup_Top = goMapCursorText:FindSingleGOByName("CursorInfo_Top")
  self._goCursorTextGroup_Bottom = goMapCursorText:FindSingleGOByName("CursorInfo_Bottom")
  self.playerIconGO = util.GetUiObjByName("MapIconPlayer")
  UI.SetIsClickable(self.playerIconGO)
  assert(self.playerIconGO ~= nil, "The player indicator gameObject was not found.")
  tutorialUtil.RegisterDesaturationObject("MapSortList", self.goFilter)
  tutorialUtil.RegisterDesaturationObject("MapCursor", goRefnode)
  tutorialUtil.RegisterDesaturationObject("MapCursorInfo", goMapCursorText)
end
function MapOn:UpdateAccessibilityScaling()
  self.mapSummaryCard_Realm:UpdateAccessibilityScaling()
  self.mapSummaryCard_Region:UpdateAccessibilityScaling()
end
function MapOn:Enter()
  local instructionArgs = self.menu:get_instructionArgs()
  self.markerIdHashToSelectOnOpen = instructionArgs.markerIdHashToSelectOnOpen
  self.isOpenedForFastTravel = instructionArgs.openForFastTravel
  self.menu:Activate()
  self:UpdateAccessibilityScaling()
  self.fastTravelPointSelected = false
  self.fastTravelCancelled = false
  self.clickedMarkerInfo = nil
  self.clickedPlayer = false
  util.Show("AllMaps", "Map", "MapCursor", "mapDepthBlur")
  self:HideSummary()
  Audio.PlaySound("SND_UX_Pause_Menu_Map_Cursor_LP")
  local submenuList = self.menu:GetList(consts.inworldMenu_SubmenuList)
  local newItemArray = self:GetSubStateNames()
  local showList = true
  local useOnGainFocus = not self.menu:HasInstructionEntryForMenuState()
  local itemDetermineFocusabilityFunc, getDisplayNameFunc
  self.menu:RefreshSubmenuList(submenuList, newItemArray, showList, useOnGainFocus, itemDetermineFocusabilityFunc, getDisplayNameFunc)
  self.filterIndex = 1
  self.jumpToMarkerIndex = 0
  self:ClearMarkers(true)
  self:GetRealmMarkerInfo()
  if self.isOpenedForFastTravel then
    local hideList = true
    local clearButtons = false
    submenuList:Deactivate(hideList, clearButtons)
    self.markerIncludeFlags = fastTravelMarkerFlags
    self:GetAlwaysOnMarkers()
    self:GetMarkers()
  else
    self.markerIncludeFlags = markerFilters[self.filterIndex].markerIncludeFlags
    self:GetAlwaysOnMarkers()
    self:GetMarkers()
    util.Show("XPandHS")
    self.goFilter:Show()
    self.goFilterList:Show()
    self.goFilterLabelContainer:Show()
    self.goFilterLabel:Show()
    self.goFilterIndicatorPrev:Show()
    self.goFilterIndicatorNext:Show()
    local instant = true
    self.mapSummaryCard_Region:ShowCard()
    self.mapSummaryCard_Region:SetOnScreen(false, instant)
    self.mapSummaryCard_Realm:ShowCard()
    self.mapSummaryCard_Realm:SetOnScreen(true, instant)
    self:CheckForTutorial()
  end
  self:UpdateIcons()
  local compassMarkers = game.Compass.FindMarkersByIconClass(enabledShowOnCompassMarkerFlags)
  if 0 < #compassMarkers then
    self.currShownMarkerID = compassMarkers[1]
    if 1 < #compassMarkers then
      for i = 2, #compassMarkers do
        game.Compass.HideMarker(compassMarkers[i])
      end
    end
  else
    self.currShownMarkerID = nil
  end
  for _, realmName in ipairs(mapConsts.REALM_NAMES) do
    self:EnableAllFog(realmName)
  end
  self.menu:ExecuteInstructions()
end
function MapOn:Exit()
  self.menu:Deactivate(true)
  Audio.StopSound("SND_UX_Pause_Menu_Map_Cursor_LP")
  util.Hide("AllMaps", "Map", "MapCursor", "mapDepthBlur")
  self:HideSummary()
  self.mapSummaryCard_Region:HideCard()
  self.mapSummaryCard_Realm:HideCard()
  self.goFilter:Hide()
  self.goFilterList:Hide()
  self.goFilterLabelContainer:Hide()
  self.goFilterLabel:Hide()
  self.goFilterIndicatorPrev:Hide()
  self.goFilterIndicatorNext:Hide()
  util.Hide("overviewOutline_Selected", "overviewOutline_Unselected")
  self:ClearMarkers(true)
  self:ClearReticleInfo()
  self.markerIdHashToSelectOnOpen = nil
  self.openedAtMarker = nil
  self.currRealmName = nil
  self:ClearIcons()
  self.realmMarkerInfo = {}
  self.filterButtonMapping = {1}
  self.currQuestID = nil
  self.currMarkerID = nil
  self.currMarkerPlayerIcon = false
  self.fastTravelPointSelected = false
  self.fastTravelCancelled = false
  self.isOpenForFastTravel = false
  for _, realmName in ipairs(mapConsts.REALM_NAMES) do
    self:EnableAllFog(realmName)
  end
  if self.playingMoveToActiveMarker then
    Audio.StopSound("SND_UX_Pause_Menu_Map_MoveTo_Active_Marker_LP")
    self.playingMoveToActiveMarker = false
  end
end
function MapOn:EVT_TouchPad_Release()
  if tutorialUtil.CurrentlyShowingStep() then
    return
  end
  if game.IsMapAvailable then
    if not game.IsMapAvailable() then
      return
    end
  elseif game.build.GOLD_VERSION == 0 then
    return
  end
  if not self.fastTravelPointSelected then
    self.fastTravelCancelled = true
    util.CallScriptOnCurrentInteractObject("TriggerFastTravelCancel")
  end
  self:SendEventToUIFsm("globalMenu", "EVT_TURN_OFF_GLOBAL_MENU")
end
function MapOn:GetSubStateNames()
  return mapUtil.GetDiscoveredRealmNames()
end
function MapOn:SubmenuList_Button_Update(button)
  local alphaValue = 1
  local fadeTime = 0
  button:AlphaFade(alphaValue, fadeTime)
  button:SetIcon(button:get_item())
  button:UpdateNewIcon(function(button)
    return buttonUtil.ShowNotification(button, "Map")
  end)
end
function MapOn:SubmenuList_Button_OnLoseFocus(button)
  local realmName = button:get_item()
  if button._MapMenu_ManuallySelected and realmName ~= nil then
    UI.ClearNotification("Map", realmName)
    button:UpdateNewIcon(function(button)
      return buttonUtil.ShowNotification(button, "Map")
    end)
    button._MapMenu_ManuallySelected = nil
  end
  self:SendEventToUIFsm("inWorldMenu", "EVT_REFRESH_NOTIFICATIONS")
end
function MapOn:SubmenuList_Button_OnGainFocus(button)
  local currentItem = button:get_item()
  self.menu:SetSubmenuListLabelText(consts.inworldMenu_SubmenuList, util.GetLAMSMsg(lamsConsts[currentItem]))
  local subState = self:GetState(currentItem)
  subState.menu:set_instructionEntries(self.menu:get_instructionEntries())
  button._MapMenu_ManuallySelected = true
  self:Goto(currentItem)
end
function MapOn:GetShowOnCompassPrompt(currMenu)
  if not (not self.isOpenedForFastTravel and game.Compass.HaveCompass()) or self.currRealmName ~= mapUtil.GetPlayerRealm() or self.currMarkerID == nil or tutorialUtil.CurrentlyShowingStep() or not Map.MarkerHasAnyFlag(self.currMarkerID, enabledShowOnCompassMarkerFlags) then
    return false, nil
  end
  local showOnCompassText = lamsConsts.AddToCompass
  if self.currMarkerID == nil and self.currShownMarkerID ~= nil or self.currMarkerID == self.currShownMarkerID then
    showOnCompassText = lamsConsts.RemoveFromCompass
  elseif self.currShownMarkerID ~= nil and self.currMarkerID ~= self.currShownMarkerID then
    showOnCompassText = lamsConsts.ReplaceInCompass
  end
  return true, "[AdvanceButton] " .. util.GetLAMSMsg(showOnCompassText)
end
function MapOn:UpdateFooterButtonPrompt(currMenu, showConfirmFastTravel, showGoToJournal)
  local showShowOnCompass, showOnCompassText = self:GetShowOnCompassPrompt(currMenu)
  currMenu:UpdateFooterButton("ShowOnCompass", showShowOnCompass, showOnCompassText)
  currMenu:UpdateFooterButton("ConfirmFastTravel", showConfirmFastTravel and self.isOpenedForFastTravel)
  currMenu:UpdateFooterButton("GoToJournal", showGoToJournal and not self.isOpenedForFastTravel)
  currMenu:UpdateFooterButton("ActiveMarkers", not self.isOpenedForFastTravel)
  currMenu:UpdateFooterButton("Move", true)
  currMenu:UpdateFooterButton("Zoom", true)
  currMenu:UpdateFooterButton("Settings", not self.isOpenedForFastTravel)
  currMenu:UpdateFooterButton("Exit", true)
  currMenu:UpdateFooterButton("Weapon", true)
  currMenu:UpdateFooterButton("Skill", true)
  currMenu:UpdateFooterButton("Quest", true)
  currMenu:UpdateFooterButton("Close", true)
  currMenu:UpdateFooterButtonText()
end
function MapOn:HideAllMaps()
  for _, realmName in ipairs(mapConsts.REALM_NAMES) do
    util.Hide(mapUtil.GetRealmCollisionGOName(realmName))
    util.Hide(realmName)
  end
end
function MapOn:ShowMap(realmName)
  self:HideAllMaps()
  util.Show(mapUtil.GetRealmCollisionGOName(realmName))
  util.Show(realmName)
end
function MapOn:UpdateMapState()
  local GetGlobalVar = game.Level.GetVariable
  local completedCineNumber = GetGlobalVar("CompletedCineNumber")
  local hammerFallCineNumber = 355
  local stonemasonFallCineNumber = 570
  local peaksPassSummitRevealedCineNumber = 310
  local afterLightChangeCineNumber = 242
  local jotunheimRevealed = GetGlobalVar("_GBL_JotTowerRevealed")
  local goMap = util.GetUiObjByName("mapScene")
  local goAlfheim = goMap:FindSingleGOByName("Alfheim")
  local jid_red = goAlfheim:GetJointIndex("emit_map_alfheim_beam_red")
  local jid_white = goAlfheim:GetJointIndex("emit_map_alfheim_beam")
  if completedCineNumber >= afterLightChangeCineNumber then
    goAlfheim:ShowJoint(jid_white)
    goAlfheim:HideJoint(jid_red)
  else
    goAlfheim:ShowJoint(jid_red)
    goAlfheim:HideJoint(jid_white)
  end
  local goJotunheimTower = util.GetUiObjByName("RealmTower4")
  local goJotunheimTowerCollision = util.GetUiObjByName("towercollision_jotunheim")
  local goJotunheimTowerInAlfheim = goAlfheim:FindSingleGOByName("RealmTower9")
  local goNiflheim = goMap:FindSingleGOByName("Niflheim")
  local goJotunheimTowerInNiflheim = goNiflheim:FindSingleGOByName("RealmTower9")
  if jotunheimRevealed then
    goJotunheimTower:Show()
    goJotunheimTowerCollision:Show()
    goJotunheimTowerInAlfheim:Show()
    goJotunheimTowerInNiflheim:Show()
  else
    goJotunheimTower:Hide()
    goJotunheimTowerCollision:Hide()
    goJotunheimTowerInAlfheim:Hide()
    goJotunheimTowerInNiflheim:Hide()
  end
  local goAlfWaterGroup = util.GetUiObjByName("Alfheim_Water")
  local jid_AlfWater1 = goAlfWaterGroup:GetJointIndex("AlfWater1")
  if GetGlobalVar("ALF_TrenchOpen") then
    goAlfWaterGroup:HideJoint(jid_AlfWater1)
  else
    goAlfWaterGroup:ShowJoint(jid_AlfWater1)
  end
  local goHammerStatesGroup = util.GetUiObjByName("Hammer_map_states")
  local goHammer = goHammerStatesGroup:FindSingleGOByName("hammer_stonemason_map")
  goHammerStatesGroup:Show()
  goHammer:Show()
  if completedCineNumber >= hammerFallCineNumber then
    animationUtil.SetTransform(goHammer, goHammerStatesGroup, "hammer_down")
  else
    animationUtil.SetTransform(goHammer, goHammerStatesGroup, "hammer_up")
  end
  local goStonemason = util.GetUiObjByName("map_stonemason_giant")
  goStonemason:Show()
  if completedCineNumber <= stonemasonFallCineNumber then
    local targetTimelinePos = 0.1
    local animRate = 0
    UI.Anim(goStonemason, consts.AS_Forward, "", animRate, targetTimelinePos)
  else
    local targetTimelinePos = 0.2
    local animRate = 0
    UI.Anim(goStonemason, consts.AS_Forward, "", animRate, targetTimelinePos)
  end
  local goSummit_gateTree = util.GetUiObjByName("Summit_gateTree")
  if completedCineNumber >= peaksPassSummitRevealedCineNumber then
    goSummit_gateTree:Show()
  else
    goSummit_gateTree:Hide()
  end
  local goThorStatue1 = util.GetUiObjByName("thorStatue1")
  if 340 <= completedCineNumber then
    goThorStatue1:Hide()
  else
    goThorStatue1:Show()
  end
  local goMidgard = goMap:FindSingleGOByName("Midgard")
  local jid_smallThorStatue = goMidgard:GetJointIndex("smallThorStatue")
  if GetGlobalVar("ThorStatueBroken") or game.QuestManager.GetQuestState("Quest_UnfinishedBusiness03_Objective_01") == questConsts.QUEST_STATE_COMPLETE then
    goMidgard:HideJoint(jid_smallThorStatue)
  else
    goMidgard:ShowJoint(jid_smallThorStatue)
  end
  self:UpdateSnakeState(completedCineNumber)
  self:UpdateHelheimBoat()
  self:UpdateWaterLevel()
  self:AnimateFog()
end
function MapOn:CheckForTutorial()
  local resourceValue = game.Wallets.GetResourceValue("HERO", "MapTutorial")
  local hasResource = -1 < resourceValue
  if not hasResource and game.Level.GetVariable("CompletedCineNumber") >= 180 then
    self:SendEventToUIFsm("inWorldMenu", "EVT_ATTEMPT_TUTORIAL", "Map", "MapTutorial", "MapFilterTutorial")
  end
end
function MapOn:UpdateSnakeState(completedCineNumber)
  local currentSnakeState = mapConsts.snakeState_1
  for _, table in ipairs(mapConsts.snakeIdleTable) do
    if completedCineNumber >= table.MinCine and completedCineNumber < table.MaxCine then
      currentSnakeState = table.State
      break
    end
  end
  local goSnake = util.GetUiObjByName("worldSnake")
  local targetTimelinePos = currentSnakeState * 0.1
  local animRate = 0
  UI.Anim(goSnake, consts.AS_Forward, "", animRate, targetTimelinePos)
end
function MapOn:SetupCameraForMap(realmName)
  if tweaks.tMapCamera and realmName ~= nil then
    map_camera.CollisionRoot = mapUtil.GetRealmCollisionGOName(realmName)
    Camera.SetMapCamera(nil)
    Camera.SetMapCamera(map_camera)
  end
end
function MapOn:UpdateHelheimBoat()
  local GetGlobalVar = game.Level.GetVariable
  local boatState = GetGlobalVar("Hel_MapState")
  local goMapBoat = util.GetUiObjByName("map_helheim_boat")
  goMapBoat:Show()
  local targetTimelinePos = 0
  if boatState == 1 then
    targetTimelinePos = 0.1
  elseif boatState == 2 then
    targetTimelinePos = 0.2
  elseif boatState == 3 then
    targetTimelinePos = 0.3
  elseif boatState == 4 then
    targetTimelinePos = 0.4
  end
  local animRate = 0
  UI.Anim(goMapBoat, consts.AS_Forward, "", animRate, targetTimelinePos)
end
function MapOn:UpdateWaterLevel()
  local targetTimelinePos = 0.3
  local animRate = 0
  local goWaterGroup = util.GetUiObjByName("Midgard_Water")
  local jid_waterLevel0 = goWaterGroup:GetJointIndex("WaterLevel0")
  local jid_waterLevel1 = goWaterGroup:GetJointIndex("WaterLevel1")
  if game.Level.GetVariable("_GBL_WaterDrop01Triggered") == false then
    goWaterGroup:ShowJoint(jid_waterLevel0)
    goWaterGroup:HideJoint(jid_waterLevel1)
    targetTimelinePos = 0.3
  elseif game.Level.GetVariable("_GBL_WaterDrop02Triggered") == false then
    goWaterGroup:ShowJoint(jid_waterLevel1)
    goWaterGroup:HideJoint(jid_waterLevel0)
    targetTimelinePos = 0.2
  else
    goWaterGroup:HideJoint(jid_waterLevel1)
    goWaterGroup:HideJoint(jid_waterLevel0)
    targetTimelinePos = 0.1
  end
  local goLakeText = util.GetUiObjByName("CalderaLake")
  local calderaShoresARegionInfo = mapUtil.GetRegionInfo(mapConsts.REGION_CALDERASHORESA)
  local calderaShoresDiscovered = mapUtil.RegionInfo_IsDiscovered(calderaShoresARegionInfo)
  if calderaShoresDiscovered then
    goLakeText:Show()
    UI.Anim(goLakeText, consts.AS_Forward, "", animRate, targetTimelinePos)
  else
    goLakeText:Hide()
  end
end
function MapOn:UpdateTempleRotation(realmName)
  mapUtil.UpdateTempleRotation(realmName)
end
function MapOn:AnimateFog()
  local goFogAnimated = util.GetUiObjByName("fogNoise_Animated")
  local targetTimelinePos = 1
  local animRate = 0.01
  UI.Anim(goFogAnimated, consts.AS_ForwardCycle, "", animRate, targetTimelinePos)
  local goRenderLayer = util.GetUiObjByName("mapRenderLayer")
  goRenderLayer:Show()
  animRate = 0.01
  UI.Anim(goRenderLayer, consts.AS_ForwardCycle, "", animRate, targetTimelinePos)
  local goMidgardWaterGroup = util.GetUiObjByName("Midgard_Water")
  animRate = 0.01
  UI.Anim(goMidgardWaterGroup, consts.AS_ForwardCycle, "", animRate, targetTimelinePos)
  local goAlfWaterGroup = util.GetUiObjByName("Alfheim_Water")
  animRate = 0.01
  UI.Anim(goAlfWaterGroup, consts.AS_ForwardCycle, "", animRate, targetTimelinePos)
end
function MapOn:EnableAllFog(realmName)
  local fogTable = mapConsts.MAP_FOG_GAMEOBJECTS
  local allRegionInfo = mapUtil.GetAllRegionInfoInRealm(realmName)
  local goMapVis = util.GetUiObjByName("Maps")
  for _, regionInfo in ipairs(allRegionInfo) do
    local regionName = mapUtil.RegionInfo_GetName(regionInfo)
    local regionID = mapUtil.RegionInfo_GetID(regionInfo)
    local isInvertFogRegion = mapUtil.Region_HasFlags(regionID, {
      mapConsts.REGION_FLAG_INVERT_FOG
    })
    local fogObjectName = fogTable[regionName]
    if isInvertFogRegion then
      util.Show(fogObjectName)
    else
      util.Hide(fogObjectName)
    end
    local goRealm = goMapVis:FindSingleGOByName(realmName)
    if goRealm ~= nil then
      local goRealmTextHolder = goRealm:FindSingleGOByName("text")
      if goRealmTextHolder ~= nil then
        local jointName = mapConsts.MAP_TEXT_GAMEOBJECTS[regionName]
        if jointName ~= nil then
          local iJoint = goRealmTextHolder:GetJointIndex(jointName)
          goRealmTextHolder:HideJoint(iJoint)
        end
      end
    end
  end
end
function MapOn:SetupVisibilityOfRegions(realmName)
  local fogTable = mapConsts.MAP_FOG_GAMEOBJECTS
  local allRegionInfo = mapUtil.GetAllRegionInfoInRealm(realmName)
  for _, regionInfo in ipairs(allRegionInfo) do
    local regionName = mapUtil.RegionInfo_GetName(regionInfo)
    local regionID = mapUtil.RegionInfo_GetID(regionInfo)
    local isRegionDiscovered = mapUtil.RegionInfo_IsDiscovered(regionInfo)
    local isInvertFogRegion = mapUtil.Region_HasFlags(regionID, {
      mapConsts.REGION_FLAG_INVERT_FOG
    })
    local fogObjectName = fogTable[regionName]
    local shouldShowFog = isRegionDiscovered
    if isInvertFogRegion then
      shouldShowFog = not shouldShowFog
    end
    if shouldShowFog then
      util.Show(fogObjectName)
    else
      util.Hide(fogObjectName)
    end
    local goMapVis = util.GetUiObjByName("Maps")
    local goRealm = goMapVis:FindSingleGOByName(realmName)
    local goRealmTextHolder = goRealm:FindSingleGOByName("text")
    if goRealmTextHolder ~= nil then
      local jointName = mapConsts.MAP_TEXT_GAMEOBJECTS[regionName]
      if jointName ~= nil then
        local iJoint = goRealmTextHolder:GetJointIndex(jointName)
        if isRegionDiscovered then
          goRealmTextHolder:ShowJoint(iJoint)
        else
          goRealmTextHolder:HideJoint(iJoint)
        end
      end
    end
  end
end
function MapOn:MapCollisionChangeHandler(currState, collisionGameObjectTable, realmName)
  local iconCollInfo, terrainCollInfo = mapUtil.GetPrioritizedIconAndTerrain(collisionGameObjectTable)
  local showConfirmFastTravel = false
  local showGoToJournal = false
  local setReticleSelected = false
  self.currQuestID = nil
  self.currMarkerID = nil
  self.currMarkerPlayerIcon = false
  if self.isOpenedForFastTravel and Camera.HasTarget ~= nil and Camera.HasTarget() then
    local fastTravelList = currState.menu:GetList("FastTravelList")
    local currFastTravelMarkerInfo
    if self.clickedMarkerInfo ~= nil then
      currFastTravelMarkerInfo = self.clickedMarkerInfo
    else
      currFastTravelMarkerInfo = fastTravelList:GetSelectedItem()
    end
    if self.clickedPlayer then
      self.currMarkerPlayerIcon = true
    end
    if currFastTravelMarkerInfo == nil then
      Camera.PointAt(CALDERA_MAP_POSITION, true)
    else
      self.currMarkerID = currFastTravelMarkerInfo.Id
      if iconCollInfo ~= nil then
        local collisionType = mapUtil.GetMapCollisionInfoType(iconCollInfo)
        local markerInfo = mapUtil.GetMapCollisionInfoInfo(iconCollInfo)
        if self.clickedPlayer or markerInfo ~= nil and markerInfo.Id == self.currMarkerID then
          setReticleSelected = true
        end
      end
      local isDiscoveredButLocked = currFastTravelMarkerInfo.State == tweaks.eTokenState.kDiscoveredButLocked
      showConfirmFastTravel = self.clickedMarkerInfo == nil and not self.clickedPlayer and not isDiscoveredButLocked and not self:IsPlayerAtMarker(currFastTravelMarkerInfo)
    end
    if self.clickedPlayer then
      currFastTravelMarkerInfo = nil
    end
    self:UpdateReticleInfo(currState, currFastTravelMarkerInfo)
  else
    self.clickedMarkerInfo = nil
    self.clickedPlayer = false
    if iconCollInfo == nil then
      self:ClearReticleInfo()
      local cineNumberAfterWhichTowerInfoIsDisplayed = 200
      if cineNumberAfterWhichTowerInfoIsDisplayed <= game.Level.GetVariable("CompletedCineNumber") then
        for i = 1, #collisionGameObjectTable do
          local collGO = collisionGameObjectTable[i]
          if collGO ~= nil and collGO.GetName ~= nil then
            local name = collGO:GetName()
            if string.sub(name, 1, 15) == "towercollision_" then
              local towerName = string.sub(name, 16)
              local title = util.GetLAMSMsg(lamsConsts.towerDesc[towerName], towerName)
              self:SetReticleInfo(currState, title, "")
            end
          end
        end
      end
    else
      local collisionType = mapUtil.GetMapCollisionInfoType(iconCollInfo)
      local markerInfo = mapUtil.GetMapCollisionInfoInfo(iconCollInfo)
      if markerInfo ~= nil then
        if collisionType == mapConsts.MAP_COLL_ICON then
          local markerID = markerInfo.Id
          self.currMarkerID = markerID
          local hasQuest, questName = questUtil.FindQuestForMarker(markerID)
          self.currQuestID = hasQuest and questName or nil
          showGoToJournal = hasQuest
        end
        if Map.MarkerHasAnyFlag(markerInfo.Id, fastTravelMarkerFlags) then
          local isDiscoveredButLocked = markerInfo.State == tweaks.eTokenState.kDiscoveredButLocked
          showConfirmFastTravel = not isDiscoveredButLocked and not self:IsPlayerAtMarker(markerInfo)
        end
      elseif collisionType == mapConsts.MAP_COLL_PLAYER_ICON then
        self.currMarkerPlayerIcon = true
      end
      self:UpdateReticleInfo(currState, markerInfo)
      setReticleSelected = true
    end
  end
  if terrainCollInfo == nil then
    self:HideSummary()
  else
    self:UpdateSummary(realmName, terrainCollInfo)
  end
  local goCursorRefnode = util.GetUiObjByName("MapCursor")
  animationUtil.SetCursorSelected(goCursorRefnode, setReticleSelected)
  if setReticleSelected then
    Audio.PlaySound("SND_UX_Pause_Menu_Screen_Map_Region_Hover_Tick")
  end
  self:UpdateFooterButtonPrompt(currState.menu, showConfirmFastTravel, showGoToJournal)
end
function MapOn:GetMapMarkerTrackingState(markerID)
  local trackingState = questConsts.TRACKING_STATE_NONE
  local hasQuest, questID = questUtil.FindQuestForMarker(markerID)
  if hasQuest then
    local trackingInfo = questUtil.GetTrackingInfo(questID)
    trackingState = questUtil.TrackingInfo_GetTrackingState(trackingInfo, questID)
  end
  if self.currShownMarkerID ~= nil and markerID == self.currShownMarkerID then
    trackingState = questConsts.TRACKING_STATE_TRACKED
  end
  return trackingState
end
function MapOn:GetMapMarkerTrackingStateFromIconGO(goIcon)
  local trackingState = questConsts.TRACKING_STATE_NONE
  local markerInfo = Map.FindInfoFromIcon(goIcon)
  if markerInfo ~= nil then
    trackingState = self:GetMapMarkerTrackingState(markerInfo.Id)
  end
  return trackingState
end
function MapOn:UpdateMapMarkerHighlights()
  for i = 1, #self.markers do
    local markerInfo = self.markers[i]
    local goIcon = markerInfo.iconGO
    local goIconTracked = goIcon:FindSingleGOByName("MapIconAreaMainQuest_area")
    local goIconTrackedSide = goIcon:FindSingleGOByName("MapIconAreaSideQuest_area")
    local goIconUntracked = goIcon:FindSingleGOByName("untracked")
    local goIconLock = goIcon:FindSingleGOByName("lock")
    local trackingState = self:GetMapMarkerTrackingStateFromIconGO(goIcon)
    local isRadiusMarker = Map.MarkerHasAnyFlag(markerInfo.Id, {"RadiusType"})
    local isDiscoveredButLocked = markerInfo.State == tweaks.eTokenState.kDiscoveredButLocked
    local goMarkerLockIcon = goIcon:FindSingleGOByName("lock")
    if goIconLock ~= nil then
      if isDiscoveredButLocked == true then
        goIconLock:Show()
      else
        goIconLock:Hide()
      end
    end
    if isRadiusMarker and goIconUntracked then
      local offset = engine.Vector.New(markerInfo.OffsetX, 0, markerInfo.OffsetY)
      goIconUntracked:SetLocalPosition(offset)
      goIconUntracked:Show()
      if trackingState == questConsts.TRACKING_STATE_TRACKED then
        UI.Anim(goIconUntracked, consts.AS_ForwardCycle_NoReset, "", 1)
      else
        UI.Anim(goIconUntracked, consts.AS_Forward, "", 0, 0)
      end
    end
    if trackingState == questConsts.TRACKING_STATE_TRACKED then
      if isRadiusMarker and goIconTracked then
        goIconTracked:Show()
      elseif isRadiusMarker and goIconTrackedSide then
        goIconTrackedSide:Show()
      end
      UI.Anim(goIcon, consts.AS_ForwardCycle_NoReset, "", 1)
    else
      if isRadiusMarker and goIconTracked then
        goIconTracked:Hide()
      elseif isRadiusMarker and goIconTrackedSide then
        goIconTrackedSide:Hide()
      end
      UI.Anim(goIcon, consts.AS_Forward, "", 0, 0)
    end
  end
end
function MapOn:IsPlayerAtMarker(markerInfo)
  return self.openedAtMarker ~= nil and markerInfo ~= nil and markerInfo.Id == self.openedAtMarker
end
function MapOn:FastTravel_Button_Update(button)
  local markerInfo = button:get_item()
  local isPlayerAtMarker = self:IsPlayerAtMarker(markerInfo)
  local isLocked = markerInfo ~= nil and markerInfo.State == tweaks.eTokenState.kDiscoveredButLocked
  local textColor = (isPlayerAtMarker or isLocked) and colors.GRAY or colors.WHITE
  button:SetTextColor(textColor)
end
function MapOn:FastTravel_Button_OnGainFocus(currState, button)
  local markerInfo = button:get_item()
  if markerInfo ~= nil then
    Camera.PointAtGO(markerInfo.iconGO)
    Audio.PlaySound("SND_UX_Pause_Menu_Map_MoveTo_Active_Marker_LP")
    self.playingMoveToActiveMarker = true
  end
  local isDiscoveredButLocked = markerInfo.State == tweaks.eTokenState.kDiscoveredButLocked
  local showConfirmFastTravel = not isDiscoveredButLocked and not self:IsPlayerAtMarker(markerInfo)
  local showGoToJournal = false
  self:UpdateFooterButtonPrompt(currState.menu, showConfirmFastTravel, showGoToJournal)
end
function MapOn:FastTravel_Button_ItemCompare(item, otherItem)
  return item ~= nil and otherItem ~= nil and item.Id == otherItem.Id
end
function MapOn:UpdateFastTravelList(currState)
  local fastTravelList = currState.menu:GetList("FastTravelList")
  if self.isOpenedForFastTravel then
    local unlockedFastTravelMarkers = {}
    for i = 1, #self.markers do
      local markerInfo = self.markers[i]
      if (markerInfo.State == tweaks.eTokenState.kDiscovered or markerInfo.State == tweaks.eTokenState.kDiscoveredButLocked) and Map.MarkerHasAnyFlag(markerInfo.Id, fastTravelMarkerFlags) then
        unlockedFastTravelMarkers[#unlockedFastTravelMarkers + 1] = markerInfo
      end
    end
    fastTravelList:Refresh(unlockedFastTravelMarkers, true, true, nil, function(item)
      return util.GetLAMSMsg(item.LamsDescriptionId, item.Id)
    end)
    fastTravelList:HideLabel()
  else
    local hideList = true
    local clearButtons = false
    fastTravelList:Deactivate(hideList, clearButtons)
    self:UpdateFooterButtonPrompt(currState.menu, false, false)
  end
end
function MapOn:SelectFastTravelButtonByMarkerInfo(currState, markerInfoToSelect)
  local fastTravelList = currState.menu:GetList("FastTravelList")
  if not self:FastTravel_Button_ItemCompare(fastTravelList:GetSelectedItem(), markerInfoToSelect) then
    fastTravelList:SelectItem(markerInfoToSelect, true)
  end
end
function MapOn:ClearReticleInfo()
  local goMapCursorText = util.GetUiObjByName("MapCursorInfo")
  goMapCursorText:Hide()
  self._goCursorTextGroup_Top:Hide()
  self._goCursorTextGroup_Bottom:Hide()
end
function MapOn:Update()
  if Camera.GetCursorScaleValue then
    local cursorScaleValue = Camera.GetCursorScaleValue() * 0.5
    local goTop = self._goCursorTextGroup_Top
    local vTargetPos = engine.Vector.New(0, cursorScaleValue, 0)
    local translationTime = 0
    local useWorldSpace = false
    UI.SetGOTransformInterpolated(goTop, vTargetPos, translationTime, useWorldSpace)
    local goBottom = self._goCursorTextGroup_Bottom
    vTargetPos = engine.Vector.New(0, -cursorScaleValue, 0)
    UI.SetGOTransformInterpolated(goBottom, vTargetPos, translationTime, useWorldSpace)
  end
end
function MapOn:UpdateReticleInfo(currState, markerInfo)
  local title = ""
  local desc = ""
  if markerInfo ~= nil then
    local isFastTravelMarker = Map.MarkerHasAnyFlag(markerInfo.Id, fastTravelMarkerFlags)
    local isDiscoveredButLocked = markerInfo.State == tweaks.eTokenState.kDiscoveredButLocked
    title = util.GetLAMSMsg(markerInfo.LamsNameId, markerInfo.Id)
    desc = util.GetLAMSMsg(markerInfo.LamsDescriptionId, markerInfo.Id)
    if isDiscoveredButLocked then
      desc = isFastTravelMarker and util.GetLAMSMsg(lamsConsts.LockedFastTravelMarker) or util.GetLAMSMsg(lamsConsts.LockedMarker)
    end
    if self.isOpenedForFastTravel and Map.MarkerHasAnyFlag(markerInfo.Id, fastTravelMarkerFlags) then
      self:SelectFastTravelButtonByMarkerInfo(currState, markerInfo)
    end
  elseif self.currMarkerPlayerIcon then
    title = "[MSG:" .. lamsConsts.Kratos .. "]"
  end
  self:SetReticleInfo(currState, title, desc)
end
function MapOn:SetReticleInfo(currState, title, desc)
  local goMapCursorText = util.GetUiObjByName("MapCursorInfo")
  goMapCursorText:Show()
  local goTitle = goMapCursorText:FindSingleGOByName("CursorInfo_Bottom")
  local thTitle = util.GetTextHandle(goTitle, "CursorTitle_Text")
  if not util.IsStringNilOrEmpty(title) then
    UI.SetText(thTitle, title)
    goTitle:Show()
  else
    UI.SetText(thTitle, "")
    goTitle:Hide()
  end
  local thDescription = util.GetTextHandle(goTitle, "CursorDescription_Text")
  if not util.IsStringNilOrEmpty(desc) then
    UI.SetText(thDescription, desc)
  else
    UI.SetText(thDescription, "")
  end
  local goCursorInfo_Top = goMapCursorText:FindSingleGOByName("CursorInfo_Top")
  local thPrompt = util.GetTextHandle(goCursorInfo_Top, "CursorAction_Text")
  UI.SetTextIsClickable(thPrompt)
  if self.isOpenedForFastTravel then
    UI.SetText(thPrompt, "")
    goCursorInfo_Top:Hide()
  elseif self.currQuestID ~= nil then
    UI.SetText(thPrompt, "[SquareButton] " .. util.GetLAMSMsg(lamsConsts.GoToJournal))
    goCursorInfo_Top:Show()
  else
    local showShowOnCompass, promptText = self:GetShowOnCompassPrompt(currState.menu)
    if showShowOnCompass then
      UI.SetText(thPrompt, promptText)
      goCursorInfo_Top:Show()
    else
      UI.SetText(thPrompt, "")
      goCursorInfo_Top:Hide()
    end
  end
end
function MapOn:ShowRegionSummary()
  local onScreen = true
  self.mapSummaryCard_Region:SetOnScreen(onScreen)
end
function MapOn:HideSummary()
  local onScreen = false
  self.currentRegionId = nil
  self.mapSummaryCard_Region:SetOnScreen(onScreen)
end
function MapOn:UpdateRealmSummary(realmName)
  local realmInfo = game.Map.GetRealmInfo(realmName)
  self.mapSummaryCard_Realm:SetProperty("RealmInfo", realmInfo)
  local doTransitionAnim = true
  self.mapSummaryCard_Realm:Update(doTransitionAnim)
  if self.isOpenedForFastTravel or self.mapSummaryCard_Realm:GetProperty("numActiveRows") <= 0 then
    self.mapSummaryCard_Realm:HideCard()
  else
    self.mapSummaryCard_Realm:ShowCard()
  end
end
function MapOn:UpdateSummary(realmName, terrainCollInfo)
  local regionIsDifferentFromLastTime = false
  if terrainCollInfo ~= nil then
    local goTerrainCollision = mapUtil.GetMapCollisionInfoGameObject(terrainCollInfo)
    local wadName = goTerrainCollision:GetName()
    local wadRegionInfo = mapUtil.RegionInfo_GetRegionInfoFromWadName(wadName)
    local regionInfo
    if wadRegionInfo ~= nil then
      local allRegionInfo = mapUtil.GetAllRegionInfoInRealm(realmName)
      for i = 1, #allRegionInfo do
        if allRegionInfo[i].Id == wadRegionInfo.Id then
          regionInfo = wadRegionInfo
          break
        end
      end
    end
    if regionInfo ~= nil then
      local isRegionDiscovered = mapUtil.RegionInfo_IsDiscovered(regionInfo)
      local neverShowSummary = mapUtil.Region_HasFlags(regionInfo.Id, {
        "NeverShowSummary"
      })
      if isRegionDiscovered and not neverShowSummary then
        local regionSummaryInfo = Map.GetRegionSummaryInfo(regionInfo.Id)
        self.mapSummaryCard_Region:SetProperty("RegionInfo", regionInfo)
        self.mapSummaryCard_Region:SetProperty("RegionSummaryInfo", regionSummaryInfo)
        if self._previousRegionID ~= regionInfo.Id then
          self._previousRegionID = regionInfo.Id
          regionIsDifferentFromLastTime = true
        end
        if self.currentRegionId == nil or regionInfo.Id ~= self.currentRegionId then
          self:ShowRegionSummary()
        end
        self.currentRegionId = regionInfo.Id
      else
        self:HideSummary()
      end
    else
      self:HideSummary()
    end
  end
  local doTransitionAnim = regionIsDifferentFromLastTime
  self.mapSummaryCard_Region:Update(false)
end
function MapOn:SubmenuSetup(currState)
  currState.menu = menu.Menu.New(currState, {
    FooterButtonInfo = {
      {
        Item = "ConfirmFastTravel",
        Text = "[AdvanceButton] " .. util.GetLAMSMsg(lamsConsts.Confirm)
      },
      {
        Item = "ShowOnCompass",
        Text = "",
        EventHandlers = {
          {
            Events = {
              "EVT_Advance_Release"
            },
            Handler = function()
              self:ShowOnCompass(currState)
            end
          }
        }
      },
      {
        Item = "GoToJournal",
        Text = "[SquareButton] " .. util.GetLAMSMsg(lamsConsts.GoToJournal),
        EventHandlers = {
          {
            Events = {
              "EVT_Square_Release"
            },
            Handler = function()
              self:Menu_Square_ReleaseHandler()
            end
          }
        }
      },
      {
        Item = "ActiveMarkers",
        Text = "[R3] " .. util.GetLAMSMsg(lamsConsts.ActiveMarkers)
      },
      {
        Item = "Move",
        Text = "[JoystickL] " .. util.GetLAMSMsg(lamsConsts.Move)
      },
      {
        Item = "Zoom",
        Text = "[JoystickRY] " .. util.GetLAMSMsg(lamsConsts.Zoom)
      },
      {
        Item = "Settings",
        Text = "[TriangleButton] " .. util.GetLAMSMsg(lamsConsts.Options),
        EventHandlers = {
          {
            Events = {
              "EVT_Triangle_Release"
            },
            Handler = function()
              self:Menu_Triangle_ReleaseHandler()
            end
          }
        }
      },
      {
        Item = "Weapon",
        Text = "",
        EventHandlers = {
          {
            Events = {
              "EVT_GO_TO_WEAPON_MENU"
            },
            Handler = function()
              if not self.isOpenedForFastTravel then
                self:SendEventToUIFsm("globalMenu", "EVT_GO_TO_WEAPON")
              end
            end
          }
        }
      },
      {
        Item = "Skill",
        Text = "",
        EventHandlers = {
          {
            Events = {
              "EVT_GO_TO_SKILL_TREE_MENU"
            },
            Handler = function()
              self:SendEventToUIFsm("globalMenu", "EVT_GO_TO_SKILL_TREE")
            end
          }
        }
      },
      {
        Item = "Quest",
        Text = "",
        EventHandlers = {
          {
            Events = {
              "EVT_GO_TO_QUEST_MENU"
            },
            Handler = function()
              self:SendEventToUIFsm("globalMenu", "EVT_GO_TO_QUEST")
            end
          }
        }
      },
      {
        Item = "Exit",
        Text = "[BackButton] " .. util.GetLAMSMsg(lamsConsts.Exit),
        EventHandlers = {
          {
            Events = {
              "EVT_Back_Release"
            },
            Handler = function()
              self:Menu_Back_ReleaseHandler()
            end
          }
        }
      },
      {
        Item = "Close",
        Text = "",
        EventHandlers = {
          {
            Events = {
              "EVT_Options_Release"
            },
            Handler = function()
              self:Menu_Options_ReleaseHandler()
            end
          }
        }
      }
    }
  })
  local fastTravelList = list.List.New(currState, {
    MaxFocusableObjectCount = 10,
    ListObjectName = "FastTravelList",
    EmptyTextLamsID = lamsConsts.NoFastTravelPointsAvailable,
    NextEvents = {
      "EVT_Down_Release"
    },
    PreviousEvents = {
      "EVT_Up_Release"
    },
    EventHandlers = {
      {
        Events = {
          "EVT_Advance_Release"
        },
        Handler = function()
          self:ConfirmFastTravel(currState)
        end
      }
    },
    Button_Update = function(button)
      self:FastTravel_Button_Update(button)
    end,
    Button_OnGainFocus = function(button)
      self:FastTravel_Button_OnGainFocus(currState, button)
    end,
    Button_ItemCompare = function(item, otherItem)
      return self:FastTravel_Button_ItemCompare(item, otherItem)
    end
  })
  fastTravelList:SetSelectedButton(1, false)
  currState.menu:SetList("FastTravelList", fastTravelList)
  fastTravelList:SetHeaderText(util.GetLAMSMsg(lamsConsts.FastTravelPoints))
end
function MapOn:ClearMarkers(clear_all)
  local first = clear_all == true and 1 or #self.alwaysOnMarkers + 1
  for index = #self.markers, first, -1 do
    self.markers[index].shown = false
    self.markers[index] = nil
  end
  if clear_all then
    self.alwaysOnMarkers = {}
  end
end
function MapOn:ClearIcons()
  for i = 1, #self.realmMarkerInfo do
    local markerInfo = self.realmMarkerInfo[i]
    if markerInfo.iconGO ~= nil then
      Map.RecycleIcon(markerInfo.iconGO)
      markerInfo.iconGO = nil
    end
  end
end
function MapOn:UpdateIcons()
  for i = 1, #self.realmMarkerInfo do
    local markerInfo = self.realmMarkerInfo[i]
    if markerInfo.shown and markerInfo.iconGO == nil then
      markerInfo.iconGO = Map.CreateMarkerIcon(markerInfo.Id, markerInfo.regionId, "")
    elseif markerInfo.iconGO ~= nil then
      if markerInfo.shown then
        markerInfo.iconGO:Show()
      else
        markerInfo.iconGO:Hide()
      end
    end
    if markerInfo.iconGO ~= nil then
      UI.SetIsClickable(markerInfo.iconGO)
    end
  end
end
function MapOn:GetRealmMarkerInfo()
  self:ClearIcons()
  self.realmMarkerInfo = {}
  if self.currRealmName == nil then
    return
  end
  local regionInfoTable = mapUtil.GetAllRegionInfoInRealm(self.currRealmName)
  for _, regionInfo in ipairs(regionInfoTable) do
    local regionMarkerInfoTable = Map.GetMarkersInfoTable(regionInfo.Id)
    for i = 1, #regionMarkerInfoTable do
      local markerInfo = regionMarkerInfoTable[i]
      local hasQuest, questName = questUtil.FindQuestForMarker(markerInfo.Id)
      if not hasQuest or game.QuestManager.GetQuestState(questName) ~= questConsts.QUEST_STATE_COMPLETE then
        markerInfo.regionId = regionInfo.Id
        self.realmMarkerInfo[#self.realmMarkerInfo + 1] = regionMarkerInfoTable[i]
      end
    end
  end
  self:UpdateFilterButtonMapping()
end
function MapOn:GetAlwaysOnMarkers()
  self:ClearMarkers(true)
  for i = 1, #self.realmMarkerInfo do
    local markerInfo = self.realmMarkerInfo[i]
    if Map.MarkerHasAnyFlag(markerInfo.Id, alwaysOnMarkerFlags) and mapUtil.MapMarkerInfoHasStates(markerInfo, markerStates) then
      markerInfo.shown = true
      tablex.FastInsert(self.alwaysOnMarkers, markerInfo, #self.alwaysOnMarkers + 1)
      tablex.FastInsert(self.markers, markerInfo, #self.markers + 1)
    end
  end
end
function MapOn:GetMarkers()
  self:ClearMarkers()
  for i = 1, #self.realmMarkerInfo do
    local markerInfo = self.realmMarkerInfo[i]
    if Map.MarkerHasAnyFlag(markerInfo.Id, self.markerIncludeFlags) and mapUtil.MapMarkerInfoHasStates(markerInfo, markerStates) then
      markerInfo.shown = true
      tablex.FastInsert(self.markers, markerInfo, #self.markers + 1)
    end
  end
end
function MapOn:ShouldShowPlayerMarker()
  local playerRealm = mapUtil.GetPlayerRealm()
  local showPlayerMarker = playerRealm == self.currRealmName and self.playerIconGO ~= nil
  local Hel_MapState = game.Level.GetVariable("Hel_MapState")
  local inTheLight = game.Level.GetVariable("CompletedCineNumber") == 240
  local onBoat = 2 <= Hel_MapState and Hel_MapState < 5 and playerRealm == mapConsts.REALM_HELHEIM
  local fastTraveling = Player.FindPlayer().CurrentLevelWadName == "Gbl000_FastTravel"
  if onBoat or fastTraveling or inTheLight then
    showPlayerMarker = false
  end
  return showPlayerMarker
end
function MapOn:SubmenuEnter(currState, realmName)
  currState.menu:Activate()
  util.GetUiObjByName("MapCursorInfo"):Hide()
  local prevRealmName = self.currRealmName
  self.currRealmName = realmName
  self:UpdateTempleRotation(realmName)
  self:UpdateRealmSummary(realmName)
  self:HideSummary()
  self:ShowMap(realmName)
  self:SetupCameraForMap(realmName)
  self:StartTimer("FogShowDelayTimer", 0.25, function()
    self:SetupVisibilityOfRegions(realmName)
  end)
  self:UpdateMapState()
  if self.isOpenedForFastTravel then
    self:GetRealmMarkerInfo()
    self:GetAlwaysOnMarkers()
    self.markerIncludeFlags = fastTravelMarkerFlags
  elseif prevRealmName ~= self.currRealmName then
    self:GetRealmMarkerInfo()
    self:GetAlwaysOnMarkers()
  end
  self:GetMarkers()
  self:UpdateIcons()
  self:UpdateMapMarkerHighlights()
  self:UpdateFilterUI()
  if self.playerIconGO ~= nil then
    Map.SetPlayerMapMarkerToPlayerMapTransform(self.playerIconGO, "facingJoint", "arrowJoint")
  end
  local showPlayerMarker = self:ShouldShowPlayerMarker()
  if showPlayerMarker then
    self.playerIconGO:Show()
  else
    self.playerIconGO:Hide()
  end
  local selectMarker
  if self.markerIdHashToSelectOnOpen ~= nil then
    self.openedAtMarker = self.markerIdHashToSelectOnOpen
    self.markerIdHashToSelectOnOpen = nil
    for i = 1, #self.markers do
      local marker = self.markers[i]
      if marker.Id == self.openedAtMarker then
        selectMarker = marker
        local instant = true
        Camera.PointAtGO(marker.iconGO, instant)
        break
      end
    end
  elseif showPlayerMarker then
    local instant = true
    Camera.PointAtGO(self.playerIconGO, instant)
  elseif Camera.PointAt ~= nil then
    local instant = true
    Camera.PointAt(CALDERA_MAP_POSITION, instant)
  end
  self:UpdateFastTravelList(currState)
  if self.isOpenedForFastTravel and selectMarker ~= nil then
    self:SelectFastTravelButtonByMarkerInfo(currState, selectMarker)
  end
  UI.WorldUIRender(map_camera.Name)
  currState.menu:ExecuteInstructions()
end
function MapOn:SubmenuExit(currState)
  currState.menu:Deactivate(true)
  self:ClearMarkers(true)
  if self.playerIconGO ~= nil then
    self.playerIconGO:Hide()
  end
  if tweaks.tMapCamera then
    Camera.SetMapCamera()
  end
  self:HideAllMaps()
end
function MapOn:ConfirmFastTravel(currState)
  local fastTravelList = currState.menu:GetList("FastTravelList")
  local currFastTravelMarkerInfo = fastTravelList:GetSelectedItem()
  local isDiscoveredButLocked = currFastTravelMarkerInfo.State == tweaks.eTokenState.kDiscoveredButLocked
  if self.currMarkerID ~= nil and Map.MarkerHasAnyFlag(self.currMarkerID, fastTravelMarkerFlags) and self:IsPlayerAtMarker(currFastTravelMarkerInfo) == false and self.fastTravelCancelled == false and not isDiscoveredButLocked then
    self.fastTravelPointSelected = true
    util.CallScriptOnCurrentInteractObject("TriggerFastTravelPointSelected", currFastTravelMarkerInfo.Id)
    self:Menu_Options_ReleaseHandler(false)
  end
end
function MapOn:Menu_Back_ReleaseHandler()
  if self.isOpenedForFastTravel == true and self.fastTravelPointSelected == false then
    self.fastTravelCancelled = true
    util.CallScriptOnCurrentInteractObject("TriggerFastTravelCancel")
  end
  self:SendEventToUIFsm("globalMenu", "EVT_TURN_OFF_GLOBAL_MENU")
end
function MapOn:Menu_Square_ReleaseHandler()
  local currRootQuestID = questUtil.GetRootQuestID(self.currQuestID)
  if questUtil.IsValidID(currRootQuestID) then
    local goFlourish = util.GetUiObjByName("CursorInfo_Top")
    goFlourish:Show()
    local animRate = 1
    local animStartTime = 0
    local animEndTime = 1
    UI.Anim(goFlourish, consts.AS_Forward, "", animRate, animStartTime, animEndTime)
    self:SendEventToUIFsm("globalMenu", "EVT_GO_TO_QUEST", currRootQuestID)
    Audio.PlaySound("SND_UX_Pause_Menu_Map_Jump_To_Journal")
  end
end
function MapOn:Menu_Triangle_ReleaseHandler()
  self:SendEventToUIFsm("globalMenu", "EVT_OPEN_SETTINGS_MENU")
end
function MapOn:Menu_Options_ReleaseHandler()
  self:Menu_Back_ReleaseHandler()
end
function MapOn:FindNextMarker(direction)
  local startIndex = self.jumpToMarkerIndex
  local trackedMarker = false
  local cursorAtMarker = false
  repeat
    self.jumpToMarkerIndex = self.jumpToMarkerIndex + direction
    if self.jumpToMarkerIndex < 0 then
      self.jumpToMarkerIndex = #self.markers
    end
    if self.jumpToMarkerIndex > #self.markers then
      self.jumpToMarkerIndex = 0
    end
    trackedMarker = self.jumpToMarkerIndex == 0 or self:GetMapMarkerTrackingState(self.markers[self.jumpToMarkerIndex].Id) == questConsts.TRACKING_STATE_TRACKED
    cursorAtMarker = self.jumpToMarkerIndex == 0 and self.currMarkerPlayerIcon or self.jumpToMarkerIndex ~= 0 and self.currMarkerID ~= nil and self.markers[self.jumpToMarkerIndex].Id == self.currMarkerID
  until not (not trackedMarker or cursorAtMarker) or startIndex == self.jumpToMarkerIndex
  if self.jumpToMarkerIndex == 0 and not self:ShouldShowPlayerMarker() and mapUtil.GetPlayerRealm() == self.currRealmName and self.markers[1] ~= nil and self:GetMapMarkerTrackingState(self.markers[1].Id) == questConsts.TRACKING_STATE_TRACKED then
    self.jumpToMarkerIndex = 1
  end
end
function MapOn:JumpToMarker()
  if self.jumpToMarkerIndex == 0 and self:ShouldShowPlayerMarker() then
    Camera.PointAtGO(self.playerIconGO)
  elseif self.markers[self.jumpToMarkerIndex] ~= nil then
    Camera.PointAtGO(self.markers[self.jumpToMarkerIndex].iconGO)
  end
end
function MapOn:EVT_R2_Release()
  if self.isOpenedForFastTravel or not tutorialUtil.AreEventsAllowed({
    "EVT_R2_Release"
  }) then
    return true
  end
  self:Menu_Next_Filter(1)
end
function MapOn:EVT_L2_Release()
  if self.isOpenedForFastTravel or not tutorialUtil.AreEventsAllowed({
    "EVT_L2_Release"
  }) then
    return true
  end
  self:Menu_Next_Filter(-1)
end
function MapOn:EVT_R3_Release()
  if self.isOpenedForFastTravel or not tutorialUtil.AreEventsAllowed({
    "EVT_R3_Release"
  }) then
    return true
  end
  if #self.markers == 0 and self.currMarkerPlayerIcon then
    return
  end
  self:FindNextMarker(1)
  self:JumpToMarker()
  Audio.PlaySound("SND_UX_Pause_Menu_Map_MoveTo_Active_Marker_LP")
  self.playingMoveToActiveMarker = true
end
function MapOn:EVT_MAPCURSOR_ARRIVED_AT_TARGET()
  if self.playingMoveToActiveMarker then
    Audio.StopSound("SND_UX_Pause_Menu_Map_MoveTo_Active_Marker_LP")
    self.playingMoveToActiveMarker = false
  end
end
function MapOn:MouseClickHandler(currState)
  for key, button in ipairs(self.goFilterButtons) do
    if UI.GetEventSenderGameObject() == button then
      self:Menu_Next_Filter(key - self.filterIndex)
    end
  end
  for i = 1, #self.realmMarkerInfo do
    local markerInfo = self.realmMarkerInfo[i]
    if markerInfo.iconGO ~= nil and UI.GetEventSenderGameObject() == markerInfo.iconGO then
      if self.isOpenedForFastTravel and Map.MarkerHasAnyFlag(markerInfo.Id, fastTravelMarkerFlags) then
        local fastTravelList = currState.menu:GetList("FastTravelList")
        if markerInfo == fastTravelList:GetSelectedItem() then
          Camera.PointAtGO(markerInfo.iconGO)
        else
          self:SelectFastTravelButtonByMarkerInfo(currState, markerInfo)
        end
        self.clickedMarkerInfo = nil
        self.clickedPlayer = false
      else
        Camera.PointAtGO(markerInfo.iconGO)
        self.clickedMarkerInfo = markerInfo
        self.clickedPlayer = false
      end
    end
  end
  if UI.GetEventSenderGameObject() == self.playerIconGO then
    Camera.PointAtGO(self.playerIconGO)
    if self.isOpenedForFastTravel then
      self.clickedMarkerInfo = nil
      self.clickedPlayer = true
    end
  end
end
function MapOn:Menu_Next_Filter(direction)
  if self.isOpenedForFastTravel then
    return
  end
  self.filterIndex = (self.filterIndex + direction - 1) % #self.filterButtonMapping + 1
  self.markerIncludeFlags = markerFilters[self.filterButtonMapping[self.filterIndex]].markerIncludeFlags
  self:GetMarkers()
  self:UpdateIcons()
  self:UpdateFilterUI()
  self.jumpToMarkerIndex = 0
  self:UpdateMapMarkerHighlights()
  Audio.PlaySound("SND_UX_Pause_Menu_Map_Filters_Tick")
end
function MapOn:UpdateFilterButtonMapping()
  self.filterButtonMapping = {1}
  self.filterIndex = 1
  self.markerIncludeFlags = markerFilters[1].markerIncludeFlags
  for filterIndex = 2, #markerFilters do
    local markerIncludeFlags = markerFilters[filterIndex].markerIncludeFlags
    for i = 1, #self.realmMarkerInfo do
      local markerInfo = self.realmMarkerInfo[i]
      if Map.MarkerHasAnyFlag(markerInfo.Id, markerIncludeFlags) and mapUtil.MapMarkerInfoHasStates(markerInfo, markerStates) then
        self.filterButtonMapping[#self.filterButtonMapping + 1] = filterIndex
        break
      end
    end
  end
  local posOffset = (#self.goFilterButtons - #self.filterButtonMapping) * 0.2
  for i = 1, #self.filterButtonMapping do
    local button = self.goFilterButtons[i]
    local pos = engine.Vector.New(self.goFilterButtonPositions[i].x + posOffset, self.goFilterButtonPositions[i].y, self.goFilterButtonPositions[i].z)
    button:SetWorldPosition(pos)
    button:Show()
  end
  for i = #self.filterButtonMapping + 1, #self.goFilterButtons do
    local button = self.goFilterButtons[i]
    UI.Anim(button, consts.AS_Reset, "", 0, 0)
    button:Hide()
  end
  self:UpdateFilterUI()
end
function MapOn:UpdateFilterUI()
  if self.prevFilterIndex ~= nil and self.prevFilterIndex ~= self.filterIndex and self.prevFilterIndex <= #self.filterButtonMapping then
    UI.Anim(self.goFilterButtons[self.prevFilterIndex], consts.AS_Forward, "", consts.DEFAULT_BUTTON_ANIM_RATE, 0.5, 1)
  end
  self.prevFilterIndex = self.filterIndex
  UI.SetText(self.thFilterLabel, util.GetLAMSMsg(markerFilters[self.filterButtonMapping[self.filterIndex]].name))
  UI.Anim(self.goFilterButtons[self.filterIndex], consts.AS_Forward, "", consts.DEFAULT_BUTTON_ANIM_RATE, 0, 0.5)
end
function MapOn:ShowOnCompass(currState)
  local updatePrompt = false
  if self.currMarkerID ~= nil then
    if not Map.MarkerHasAnyFlag(self.currMarkerID, enabledShowOnCompassMarkerFlags) then
      return
    end
    updatePrompt = true
    if self.currMarkerID == self.currShownMarkerID then
      game.Compass.HideMarker(self.currShownMarkerID)
      Audio.PlaySound("SND_UX_Pause_Menu_Map_RemoveFromCompass")
      self.currShownMarkerID = nil
    else
      if self.currShownMarkerID ~= nil then
        game.Compass.HideMarker(self.currShownMarkerID)
      end
      local markerType
      for i = 1, #enabledShowOnCompassMarkerFlags do
        local enabledMarkerFlag = enabledShowOnCompassMarkerFlags[i]
        if Map.MarkerHasFlag(self.currMarkerID, {enabledMarkerFlag}) then
          markerType = enabledMarkerFlag
          break
        end
      end
      assert(markerType ~= nil, "unable to find ShowOnCompass marker type")
      game.Compass.ShowMarker(self.currMarkerID, markerType)
      Audio.PlaySound("SND_UX_Pause_Menu_Map_AddToCompass")
      self.currShownMarkerID = self.currMarkerID
    end
  elseif self.currShownMarkerID ~= nil then
    updatePrompt = true
    game.Compass.HideMarker(self.currShownMarkerID)
    self.currShownMarkerID = nil
  end
  if updatePrompt then
    local currMenu = currState.menu
    local showShowOnCompass, text = self:GetShowOnCompassPrompt(currMenu)
    local goMapCursorText = util.GetUiObjByName("MapCursorInfo")
    goMapCursorText:Show()
    local goCursorInfo_Top = goMapCursorText:FindSingleGOByName("CursorInfo_Top")
    local thPrompt = util.GetTextHandle(goCursorInfo_Top, "CursorAction_Text")
    UI.SetTextIsClickable(thPrompt)
    UI.SetText(thPrompt, showShowOnCompass and text or "")
    self:UpdateMapMarkerHighlights()
    currMenu:UpdateFooterButton("ShowOnCompass", showShowOnCompass, text)
    currMenu:UpdateFooterButtonText()
  end
end
function MapOn:EVT_TURN_OFF_MAP_MENU()
  self:Goto("MapOff")
end
function Midgard:Setup()
  self.mapOn = self:GetState("MapOn")
  self.mapOn:SubmenuSetup(self)
end
function Midgard:Enter()
  self.mapOn:SubmenuEnter(self, "Midgard")
end
function Midgard:Exit()
  self.mapOn:SubmenuExit(self)
end
function Midgard:EVT_HandleMapCollisionChangeHook(collisionGameObjectTable)
  self.mapOn:MapCollisionChangeHandler(self, collisionGameObjectTable, "Midgard")
end
function Midgard:EVT_MOUSE_CLICKED()
  self.mapOn:MouseClickHandler(self)
end
function Alfheim:Setup()
  self.mapOn = self:GetState("MapOn")
  self.mapOn:SubmenuSetup(self)
end
function Alfheim:Enter()
  self.mapOn:SubmenuEnter(self, "Alfheim")
end
function Alfheim:Exit()
  self.mapOn:SubmenuExit(self)
end
function Alfheim:EVT_HandleMapCollisionChangeHook(collisionGameObjectTable)
  self.mapOn:MapCollisionChangeHandler(self, collisionGameObjectTable, "Alfheim")
end
function Alfheim:EVT_MOUSE_CLICKED()
  self.mapOn:MouseClickHandler(self)
end
function Helheim:Setup()
  self.mapOn = self:GetState("MapOn")
  self.mapOn:SubmenuSetup(self)
end
function Helheim:Enter()
  self.mapOn:SubmenuEnter(self, "Helheim")
end
function Helheim:Exit()
  self.mapOn:SubmenuExit(self)
end
function Helheim:EVT_HandleMapCollisionChangeHook(collisionGameObjectTable)
  self.mapOn:MapCollisionChangeHandler(self, collisionGameObjectTable, "Helheim")
end
function Helheim:EVT_MOUSE_CLICKED()
  self.mapOn:MouseClickHandler(self)
end
function Jotunheim:Setup()
  self.mapOn = self:GetState("MapOn")
  self.mapOn:SubmenuSetup(self)
end
function Jotunheim:Enter()
  self.mapOn:SubmenuEnter(self, "Jotunheim")
end
function Jotunheim:Exit()
  self.mapOn:SubmenuExit(self)
end
function Jotunheim:EVT_HandleMapCollisionChangeHook(collisionGameObjectTable)
  self.mapOn:MapCollisionChangeHandler(self, collisionGameObjectTable, "Jotunheim")
end
function Jotunheim:EVT_MOUSE_CLICKED()
  self.mapOn:MouseClickHandler(self)
end
function Niflheim:Setup()
  self.mapOn = self:GetState("MapOn")
  self.mapOn:SubmenuSetup(self)
end
function Niflheim:Enter()
  self.mapOn:SubmenuEnter(self, "Niflheim")
end
function Niflheim:Exit()
  self.mapOn:SubmenuExit(self)
end
function Niflheim:EVT_HandleMapCollisionChangeHook(collisionGameObjectTable)
  self.mapOn:MapCollisionChangeHandler(self, collisionGameObjectTable, "Niflheim")
end
function Niflheim:EVT_MOUSE_CLICKED()
  self.mapOn:MouseClickHandler(self)
end
function Muspelheim:Setup()
  self.mapOn = self:GetState("MapOn")
  self.mapOn:SubmenuSetup(self)
end
function Muspelheim:Enter()
  self.mapOn:SubmenuEnter(self, "Muspelheim")
end
function Muspelheim:Exit()
  self.mapOn:SubmenuExit(self)
end
function Muspelheim:EVT_HandleMapCollisionChangeHook(collisionGameObjectTable)
  self.mapOn:MapCollisionChangeHandler(self, collisionGameObjectTable, "Muspelheim")
end
function Muspelheim:EVT_MOUSE_CLICKED()
  self.mapOn:MouseClickHandler(self)
end
function Svartalheim:Setup()
  self.mapOn = self:GetState("MapOn")
  self.mapOn:SubmenuSetup(self)
end
function Svartalheim:Enter()
  self.mapOn:SubmenuEnter(self, "Svartalheim")
end
function Svartalheim:Exit()
  self.mapOn:SubmenuExit(self)
end
function Svartalheim:EVT_HandleMapCollisionChangeHook(collisionGameObjectTable)
  self.mapOn:MapCollisionChangeHandler(self, collisionGameObjectTable, "Svartalheim")
end
function Svartalheim:EVT_MOUSE_CLICKED()
  self.mapOn:MouseClickHandler(self)
end
function Vanaheim:Setup()
  self.mapOn = self:GetState("MapOn")
  self.mapOn:SubmenuSetup(self)
end
function Vanaheim:Enter()
  self.mapOn:SubmenuEnter(self, "Vanaheim")
end
function Vanaheim:Exit()
  self.mapOn:SubmenuExit(self)
end
function Vanaheim:EVT_HandleMapCollisionChangeHook(collisionGameObjectTable)
  self.mapOn:MapCollisionChangeHandler(self, collisionGameObjectTable, "Vanaheim")
end
function Vanaheim:EVT_MOUSE_CLICKED()
  self.mapOn:MouseClickHandler(self)
end
function Asgard:Setup()
  self.mapOn = self:GetState("MapOn")
  self.mapOn:SubmenuSetup(self)
end
function Asgard:Enter()
  self.mapOn:SubmenuEnter(self, "Asgard")
end
function Asgard:Exit()
  self.mapOn:SubmenuExit(self)
end
function Asgard:EVT_HandleMapCollisionChangeHook(collisionGameObjectTable)
  self.mapOn:MapCollisionChangeHandler(self, collisionGameObjectTable, "Asgard")
end
function Asgard:EVT_MOUSE_CLICKED()
  self.mapOn:MouseClickHandler(self)
end
function MapMenu:OnSaveCheckpoint(tab)
end
function MapMenu:OnRestoreCheckpoint(tab)
end
