Advertisement
Guest User

Untitled

a guest
May 21st, 2018
3,403
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 80.04 KB | None | 0 0
  1.  
  2. local LQI = LibStub("LibQuestInfo")
  3.  
  4. local DEBUG_MODE            = true
  5. QUESTTRACKER_DEBUG_TABLE    = {}
  6.  
  7. local ADDON_NAME    = "Ravalox'QuestTracker"
  8. local VERSION_CODE  = "3.6.0.0"
  9.  
  10. local CONSTRAINT_WIDTH = 100
  11. local CONSTRAINT_HEIGHT = 60
  12. -- I cut it close on the right hand border, there is practically no padding
  13. -- If text gets cut off, try changing this, but no more than +5
  14. -- If it takes that much then something is wrong, let me know & I'll look into it.
  15. local TEXT_LABEL_PADDING = 0
  16.  
  17. local colorYellow       = "|cFFFF00"    -- yellow
  18. local colorSoftYellow   = "|cCCCC00"    -- Duller Yellow for Description
  19. local colorRed          = "|cFF0000"    -- Red
  20. local colorRavalox      = "|cB60000"    -- Ravalox Red  -- B6 = Red 182  a brighter 82 red
  21. local colorCMDBlue      = "|c1155bb"    -- Dull blue used to indicate "typable" text
  22. --[[
  23. the game calls forceAssist on more than one quest before a final starting quest is arrived at. This will block us from wasting time selecting & displaying auto-tooltips for those quests until the player is completely activated and all game callbacks have been fired to prevent displaying an auto-tooltip on load, reloadUI, & zoning and from leaving nodes open the user did not open themselves, if they have exclusitivity turned off & the game selects random quests.
  24. --]]
  25. local ALLOW_QUEST_ASSIST_CALLBACK   = false
  26. local SORT_TYPE_QUEST_CATEGORIES    = 1
  27. local SORT_TYPE_QUESTS              = 2
  28. local USER_REQUESTED_OPEN           = true
  29.  
  30. local QuestTracker  = ZO_Object:New()
  31.  
  32. --=====================================================--
  33. --======= DEBUG =========--
  34. --=====================================================--
  35. local function debugMsg(msg, tableItem)
  36.     if not DEBUG_MODE then return end
  37.    
  38.     if msg and msg ~= "" then
  39.         d(msg)
  40.         table.insert(QUESTTRACKER_DEBUG_TABLE, msg)
  41.     end
  42.    
  43.     -- Used to save object references for later examination:
  44.     if tableItem then
  45.         table.insert(QUESTTRACKER_DEBUG_TABLE, tableItem)
  46.     end
  47. end
  48.  
  49. --=====================================================--
  50. --======= BACKDROP FUNCTIONS =========--
  51. --=====================================================--
  52. local backdrops = {
  53.     [1] = {name = "None"},
  54.     [2] = {name = "Fancy"},
  55.     [3] = {name = "Colored"},
  56. }
  57.  -- Used in settings menu to populate choices
  58. function QuestTracker:GetBackdropChoices()
  59.     local choices = {}
  60.     for k,v in ipairs(backdrops) do
  61.         choices[#choices+1] = v.name
  62.     end
  63.     return choices
  64. end
  65.  
  66. --=====================================================--
  67. --======= FONT FUNCTIONS =========--
  68. --=====================================================--
  69. local NodeFonts = {
  70.     [1] = {name = "Bold",                   font = "BOLD_FONT"},
  71.     [2] = {name = "Medium",                 font = "MEDIUM_FONT"},
  72.     [3] = {name = "Chat",                   font = "CHAT_FONT"},
  73.     [4] = {name = "Antique",                font = "ANTIQUE_FONT"},
  74.     [5] = {name = "Handwritten",            font = "HANDWRITTEN_FONT"},
  75.     [6] = {name = "Stone Tablet",           font = "STONE_TABLET_FONT"},
  76.     [7] = {name = "Gamepad Bold",           font = "GAMEPAD_BOLD_FONT"},
  77.     [8] = {name = "Gamepad Medium",         font = "GAMEPAD_MEDIUM_FONT"},
  78.     [9] = {name = "Arial Narrow",           font = "univers55"},
  79. }
  80.  -- Used in settings menu to populate choices
  81. function QuestTracker:GetFontChoices()
  82.     local choices = {}
  83.    
  84.     for k,v in ipairs(NodeFonts) do
  85.         choices[#choices+1] = v.name
  86.     end
  87.     return choices
  88. end
  89. function QuestTracker:GetFontByName(name)
  90.     for k,v in ipairs(NodeFonts) do
  91.         if v.name == name then
  92.             return v.font
  93.         end
  94.     end
  95.     return "ZoFontHeader"
  96. end
  97.  
  98. -- Font outline
  99. local NodeOutlines = {
  100.     [1] = {name = "None"},
  101.     [2] = {name = "Soft Thick Shadow",  outline = "soft-shadow-thick"},
  102.     [3] = {name = "Soft Thin Shadow",   outline = "soft-shadow-thin"},
  103.     [4] = {name = "Shadow",             outline = "shadow"},
  104. }
  105. function QuestTracker:GetOutlineChoices()
  106.     local choices = {}
  107.    
  108.     for k,v in ipairs(NodeOutlines) do
  109.         choices[#choices+1] = v.name
  110.     end
  111.     return choices
  112. end
  113.  
  114. function QuestTracker:GetOutlineByName(outlineName)
  115.     for k,v in ipairs(NodeOutlines) do
  116.         if v.name == outlineName then
  117.             return v.outline
  118.         end
  119.     end
  120. end
  121.  
  122.  
  123. -- font string layout example: "$(BOLD_FONT)|30|soft-shadow-thick"
  124. function QuestTracker:BuildFontString(font, size, outline)
  125.     local fontString = zo_strformat("$(<<1>>)|<<2>>", font,size)
  126.     --
  127.     if outline then
  128.         fontString = zo_strformat("<<1>>|<<2>>", fontString,outline)
  129.     end
  130.     --]]
  131.     return fontString
  132. end
  133.  
  134. function QuestTracker:GetCategoryFontString()
  135.     local categoryFontSettings  = self.svCurrent.fontSettings.categories
  136.     local font                  = self:GetFontByName(categoryFontSettings.font)
  137.     local fontOutline           = self:GetOutlineByName(categoryFontSettings.outline)
  138.     local fontSize              = categoryFontSettings.size
  139.    
  140.     return self:BuildFontString(font, fontSize, fontOutline)
  141. end
  142.  
  143. function QuestTracker:GetQuestFontString()
  144.     local questFontSettings     = self.svCurrent.fontSettings.quests
  145.     local font                  = self:GetFontByName(questFontSettings.font)
  146.     local fontOutline           = self:GetOutlineByName(questFontSettings.outline)
  147.     local fontSize              = questFontSettings.size
  148.    
  149.     return self:BuildFontString(font, fontSize, fontOutline)
  150. end
  151. function QuestTracker:GetConditionFontString()
  152.     local conditionFontSettings = self.svCurrent.fontSettings.conditions
  153.     local font                  = self:GetFontByName(conditionFontSettings.font)
  154.     local fontOutline           = self:GetOutlineByName(conditionFontSettings.outline)
  155.     local fontSize              = conditionFontSettings.size
  156.    
  157.     return self:BuildFontString(font, fontSize, fontOutline)
  158. end
  159.  
  160. --===========================================================--
  161. --======= HOOKS =========--
  162. --===========================================================--
  163. -- Handles when quests are added/removed. List must be repopulated instead of manually adding/removing
  164. -- a single quest because the game calls this function and the quest indices may change. Rather than
  165. -- trying to loop through our entire tree, compare the data and fix things, we just repopulate
  166. -- the tree by wiping it & recreating it.
  167. -- Updates are handled differently
  168. local OrigRefreshQuestMasterList = ZO_QuestJournal_Keyboard.RefreshQuestMasterList
  169. function ZO_QuestJournal_Keyboard:RefreshQuestMasterList()
  170.     OrigRefreshQuestMasterList(self)
  171.    
  172.     QUESTTRACKER:RepopulateQuestTree()
  173. end
  174.  
  175. -- QUESTTRACKER must be passed in because it does not exist yet
  176. local function HookUpdateCurrentChildrenHeightsToRoot(QUESTTRACKER)
  177.     local rootNode = QUESTTRACKER.navigationTree.rootNode
  178.     local metaTable = getmetatable(rootNode)
  179.     local origUpdateCurrentChildrenHeightsToRoot = metaTable.UpdateCurrentChildrenHeightsToRoot
  180.    
  181.     function metaTable.UpdateCurrentChildrenHeightsToRoot(self)
  182.         origUpdateCurrentChildrenHeightsToRoot(self)
  183.         QUESTTRACKER:UpdateCurrentChildrenWidthsToRoot(self)
  184.        
  185.         if QUESTTRACKER.svCurrent.mainWindow.autoWindowSizeWidth then
  186.             QUESTTRACKER:AutoSizeWinWidth()
  187.         end
  188.        
  189.         if QUESTTRACKER.svCurrent.mainWindow.autoWindowSizeHeight then
  190.             QUESTTRACKER:AutoSizeWinHeight()
  191.         end
  192.     end
  193. end
  194.  
  195. --===========================================================--
  196. --======= LOCAL REGISTERED CALLBACK/EVENT FUNCTIONS =========--
  197. --===========================================================--
  198. -- Registered callback for QuestTrackerAssistStateChanged, to select the quest
  199. -- which, in turn, scrolls the node into view.
  200. local function OnAssistChanged(self, unassistedData, assistedData)
  201.     if not assistedData then return end
  202.     local questIndex = assistedData.arg1
  203.    
  204.     --[[ ALLOW_QUEST_ASSIST_CALLBACK is used here because the game fires this more than once on load, before finally deciding what quest should be originally selected, this blocks that so random auto-tooltips don't get displayed on load and so that nodes don't get opened by those random calls and left open if the user has node exclusitivity off.
  205.     --]]
  206.     if questIndex and ALLOW_QUEST_ASSIST_CALLBACK then
  207.         self:SelectQuestIndexNode(questIndex, true)
  208.        
  209.         if self.svCurrent.tooltips.autoTooltip and not QUESTTRACKER.WINDOW_FRAGMENT:IsHidden() then
  210.             self:ShowQuestTooltip(questIndex)
  211.            
  212.             local fadeTime = self.svCurrent.tooltips.fadeTime*1000
  213.             EVENT_MANAGER:RegisterForUpdate("QuestTrackerClearAutoTooltip", fadeTime, function()
  214.                 ClearTooltip(InformationTooltip)
  215.                 EVENT_MANAGER:UnregisterForUpdate("QuestTrackerClearAutoTooltip")
  216.             end)
  217.         end
  218.     end
  219. end
  220.  
  221. -- This is cheesy, but the node won't scroll into view on player activation. The scroll
  222. -- doesn't have its extents updated yet & its still 0 so it can't scroll, must delay.
  223. local function OnPlayerActivated()
  224.     zo_callLater(function() QUESTTRACKER:RefreshSelectedQuest() end, 10)
  225.    
  226.     -- Allow auto-tooltips after the player has completely activated AND the game has finished firing all  
  227.     -- callbacks for setting the current quest to prevent displaying an auto-tooltip on load, reloadUI, & zoning
  228.     zo_callLater(function() ALLOW_QUEST_ASSIST_CALLBACK = true end, 100)
  229.    
  230.     --  Initialize the ingame questtracker state.  Needed to ensure ZOS QT is hidden on initial load of the addon or a new character.
  231.     local newSetting = QUESTTRACKER.svCurrent.hideDefaultQuestTracker and "false" or "true"
  232.     SetSetting(SETTING_TYPE_UI, UI_SETTING_SHOW_QUEST_TRACKER, newSetting)
  233. end
  234.  
  235. local function OnPlayerDeactivated()
  236.     -- Set to false to block auto-tooltips until the player is completely Re-activated
  237.     ALLOW_QUEST_ASSIST_CALLBACK = false
  238. end
  239.  
  240. local function OnQuestAdded(eventCode, journalIndex, questName)
  241.     local chatAlertType = QUESTTRACKER.svCurrent.chatAlertType
  242.    
  243.     if QUESTTRACKER.svCurrent.questTrackForceAssist then
  244.         FOCUSED_QUEST_TRACKER:ForceAssist(journalIndex)
  245.     end
  246.    
  247.     if chatAlertType == "Off" then return end
  248.    
  249.     local fQuestName = zo_strformat(SI_QUEST_JOURNAL_QUEST_NAME_FORMAT, questName)
  250.     local darkOrange = "FFA500"
  251.     local questAddedMsg = zo_strformat("|c<<1>><<2>>:|r <<3>>", darkOrange, "Quest Added: ", fQuestName)
  252.  
  253.     if chatAlertType == "Detailed" then
  254.         local isValid, questData = LQI:GetCurrentQuestStepInfo(journalIndex)
  255.        
  256.         if isValid then
  257.             questAddedMsg = zo_strformat("|c<<1>><<2>>:|r <<3>>", darkOrange, fQuestName, questData.stepText)
  258.         end
  259.     end
  260.     d(questAddedMsg)   
  261. end
  262.  
  263. -- called on event EVENT_LEVEL_UPDATE
  264. local function OnLevelUpdate(eventCode, unitTag, level)
  265.     if unitTag ~= "player" then return end
  266.    
  267.     -- This will update all nodes, forcing their setup functions to fire. Specifically we want
  268.     -- all of the QuestNodeSetup 's to fire so they will recall GetCon(nodeData.level) & RefreshTextColor()
  269.     QUESTTRACKER.navigationTree:RefreshVisible()
  270. end
  271.  
  272. -- Called on events EVENT_QUEST_ADVANCED & EVENT_QUEST_CONDITION_COUNTER_CHANGED
  273. -- If you have problems with quests not updating properly...this is where to start looking
  274. local function OnQuestUpdate(eventCode, journalIndex)
  275.     QUESTTRACKER:UpdateQuest(journalIndex)
  276. end
  277.  
  278. -- temporary test, split up for debug messages
  279. local function OnQuestAdvanced(eventCode, journalIndex)
  280.     OnQuestUpdate(eventCode, journalIndex)
  281. end
  282.  
  283. -- temporary test, split up for debug messages
  284. local function OnQuestCondtionChange(eventCode, journalIndex)
  285.     OnQuestUpdate(eventCode, journalIndex)
  286. end
  287.  
  288. -- if the user toggles the "Show quest tracker" setting, update it in settings
  289. local function OnInterfaceSettingChanged(eventCode, system, settingId)
  290.     if not system == SETTING_TYPE_UI then return end
  291.     if not settingId == UI_SETTING_SHOW_QUEST_TRACKER then return end
  292.    
  293.     local newValue = not GetSetting_Bool(SETTING_TYPE_UI, UI_SETTING_SHOW_QUEST_TRACKER)
  294.    
  295.     if QUESTTRACKER_HIDEDEFAULTQUESTTRACKERWINDOW then
  296.         QUESTTRACKER_HIDEDEFAULTQUESTTRACKERWINDOW:UpdateValue(false, newValue)
  297.        ZO_FocusedQuestTracker:UpdateVisibility (false, newValue)
  298.     end
  299. end
  300.  
  301. -- hide QT window when in combat
  302. local function OnCombatStateChange(eventCode, isInCombat)
  303.     local svCurrent = QUESTTRACKER.svCurrent
  304.     -- If its manually hidden or the combat hide feature is off do nothing
  305.     if svCurrent.hideQuestWindow or not QUESTTRACKER.svCurrent.hideInCombat then return end
  306.    
  307.     if isInCombat then
  308.         QUESTTRACKER.questTreeWin:SetHidden(true)
  309.         return
  310.     end
  311.     QUESTTRACKER.questTreeWin:SetHidden(false)
  312. end
  313.  
  314. --=====================================================--
  315. --======= QuestTracker NEW/INITIALIZE FUNCTIONS =========--
  316. --=====================================================--
  317. function QuestTracker:New()
  318.     -- First setup references:
  319.     self.questTreeWin           = QuestTrackerWin
  320.     self.backdrop               = QuestTrackerWinBackdrop
  321.     self.dragBar                = QuestTrackerWinDragBar
  322.     self.lockBtn                = QuestTrackerWinLockBtn
  323.     self.unlockBtn              = QuestTrackerWinUnlockBtn
  324.     self.navigationContainer    = QuestTrackerWinNavigationContainer
  325.     self.codeVersion            = VERSION_CODE
  326.  
  327.     -- Here just in case I need it for later I wont have to look it up again.
  328.     --ZO_HIGHLIGHT_TEXT = ZO_ColorDef:New(GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_HIGHLIGHT))
  329.     --ZO_NORMAL_TEXT = ZO_ColorDef:New(GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_NORMAL))
  330.     --ZO_DISABLED_TEXT = ZO_ColorDef:New(GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_DISABLED))
  331.     --ZO_SELECTED_TEXT = ZO_ColorDef:New(GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_SELECTED))
  332.     local norm = ZO_NORMAL_TEXT
  333.     self.FONT_COLOR_NORMAL_DEFAULT = {norm.r, norm.g, norm.b, norm.a}
  334.    
  335.     -- Then setup the UI & everything else
  336.     local defaultSV = {
  337.         mainWindow = {
  338.             offsetX = 100,
  339.             offsetY = 100,
  340.             width   = 300,
  341.             height  = 400,
  342.             locked  = false,
  343.             isItLocked = false,
  344.             hideLockIcon = "Never",
  345.             hideQuestWindow = false,
  346.             --hideWithUI = false,
  347.             showInGameScene = false,
  348.             autoWindowSizeHeight = true,
  349.             autoWindowSizeWidth = true,
  350.             backdrop = {
  351.                 backdropName        = "Colored",    -- defaults to none in code
  352.                 backdropAlpha       = .5, --1,
  353.                 backdropColor       = {0,0,0,.5},   --{.25, .25, .25, 1},
  354.                 dragBarColor        = {1,1,1,.5},
  355.                 hideMungeOverlay    = false,
  356.                 backdropHideOnLock  = false,
  357.             },
  358.         },
  359.         fontSettings = {
  360.             categories = {
  361.                 font    = "Bold",
  362.                 outline = "Soft Thick Shadow",
  363.                 size    = 20,
  364.                 color   = self.FONT_COLOR_NORMAL_DEFAULT,
  365.             },
  366.             quests = {
  367.                 font    = "Bold",
  368.                 outline = "Soft Thick Shadow",
  369.                 size    = 16,
  370.                 color   = self.FONT_COLOR_NORMAL_DEFAULT,
  371.             },
  372.             conditions = {
  373.                 font    = "Bold",
  374.                 outline = "Soft Thick Shadow",
  375.                 size    = 14,
  376.                 color   = self.FONT_COLOR_NORMAL_DEFAULT,
  377.             },
  378.         },
  379.         nodeExclusitivity = {
  380.             currentSetting  = "None",
  381.             allNodes        = false,
  382.             categoryNodes   = false,
  383.             questNodes      = false,
  384.             isTreeExclusive = false,
  385.         },
  386.         tooltips = {
  387.             show                = true,
  388.             anchorPoint         = LEFT,
  389.             relativeTo          = RIGHT,
  390.             autoTooltip         = false,
  391.             fadeTime            = 5,
  392.         },
  393.         autoOpenNodes           = false,
  394.         autoOpenCategoryOnLogin = false,
  395.         showQuestLevel          = true,
  396.         showNumCategoryQuests   = true,
  397.         overrideConColors       = false,
  398.         chatAlertType           = "Detailed",
  399.         questTrackForceAssist   = true,
  400.         accountWide             = true,
  401.         hideDefaultQuestTracker = true,
  402.         hideFocusedQuestTracker = true,
  403.         hideInCombat            = true,     -- Hide RQT window when in combat
  404.         sortByLevel             = true,         -- Sort Quests by level
  405.     }
  406.    
  407.     --********************************************************************************************--
  408.     --                SavedVar stuff MUST be done before inializing the tree
  409.     --********************************************************************************************--
  410.     -- Will hold the saved vars, either: accountwdie or per character:
  411.     self.svCurrent = {}
  412.  
  413.     self.svAccount = ZO_SavedVars:NewAccountWide("QuestTrackerSavedVars", 3.0, nil, defaultSV)
  414.     self.svCharacter = ZO_SavedVars:New("QuestTrackerSavedVars", 3.0, nil, defaultSV)
  415.     self:SwapSavedVars(self.svAccount.accountWide)
  416.     --********************************************************************************************--
  417.  
  418.     -- Initialize HotKeys
  419.     ZO_CreateStringId("SI_BINDING_NAME_QUESTTRACKER_TOGGLE_MAIN_WINDOW", "Toggle the Quest Tracker Window")
  420.    
  421.     -- Setup the tree
  422.     local scrollChild       = self.questTreeWin:GetNamedChild("NavigationContainerScrollChild")
  423.     local navigationTree    = ZO_Tree:New(scrollChild, 25, 0, 1000)
  424.    
  425.     self.navigationTree = navigationTree
  426.    
  427.     self:InitializeTree() -- initialize the tree, must be done before Initialize()
  428.    
  429.     self:Initialize()  -- initialize everything else
  430.    
  431.     return self
  432. end
  433.  
  434. -- Initialize everything else
  435. function QuestTracker:Initialize()
  436.     local svMainWindow = self.svCurrent.mainWindow
  437.    
  438.     self:InitializeWindow()
  439.    
  440.     HookUpdateCurrentChildrenHeightsToRoot(self) -- do before population so it auto-fires resize
  441.    
  442.     self:RepopulateQuestTree()  -- populates the tree with categories/quests/conditions
  443.    
  444.     QuestTracker_CreateSettingsMenu(self)
  445.    
  446.     -- Sets the selected quest in our tree, whenever it is changed somewhere else
  447.     FOCUSED_QUEST_TRACKER:RegisterCallback("QuestTrackerAssistStateChanged", function(unassistedData, assistedData) OnAssistChanged(self, unassistedData, assistedData) end)
  448.  
  449.     EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_INTERFACE_SETTING_CHANGED,       OnInterfaceSettingChanged)
  450.     EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_QUEST_CONDITION_COUNTER_CHANGED, OnQuestCondtionChange)
  451.     EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_QUEST_ADDED,           OnQuestAdded)   -- only for chat window alert
  452.     EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_PLAYER_ACTIVATED,      OnPlayerActivated)
  453.     EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_PLAYER_DEACTIVATED,    OnPlayerDeactivated)
  454.     EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_QUEST_ADVANCED,        OnQuestAdvanced)
  455.     EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_LEVEL_UPDATE,          OnLevelUpdate)  -- To update con colors when leveling
  456.     EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_PLAYER_COMBAT_STATE,   OnCombatStateChange)    -- To hide QT when in combat
  457.    
  458.     -- Auto open options
  459.     if self.svCurrent.autoOpenNodes then
  460.         self:OpenAllQuestNodes()
  461.     end
  462.    
  463.     if self.svCurrent.autoOpenCategoryOnLogin then
  464.         self:OpenSelectedCategoryQuestNodes()
  465.     end
  466.    
  467.     -- Since we can't add/remove quests and must instead repopulate the entire tree when these happen
  468.     -- because the game calls RefreshQuestMasterList at which time
  469.     -- quest indices may change and it also calls RefreshQuestMasterList on init during zone changes.
  470.     -- Were not going to use these, but instead just hook the RefreshQuestMasterList instead.
  471.     -- If we registered these & hooked RefreshQuestMasterList every time one of these events fired
  472.     -- our code would get run twice, once for the event firing & once for the RefreshQuestMasterList firing.
  473.     --EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_QUEST_ADDED,         OnQuestAdded)
  474.     --EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_QUEST_REMOVED,       OnQuestRemoved)
  475.     --EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_QUEST_LIST_UPDATED, function() self:RepopulateQuestTree() end)
  476. end
  477.  
  478. function QuestTracker:InitializeWindow()
  479.     local svMainWindow  = self.svCurrent.mainWindow
  480.     local offsetX       = svMainWindow.offsetX
  481.     local offsetY       = svMainWindow.offsetY
  482.     local width         = svMainWindow.width
  483.     local height        = svMainWindow.height
  484.     local isItLocked        = svMainWindow.isItLocked
  485.    
  486.     self.questTreeWin:ClearAnchors()
  487.     self.questTreeWin:SetAnchor(TOPLEFT, nil, TOPLEFT, offsetX, offsetY)
  488.     self.questTreeWin:SetDimensions(width, height)
  489.    
  490.     self:UpdateBackdrop(svMainWindow.backdrop.backdropName)
  491.     self:SetLockState(svMainWindow.isItLocked)
  492.    
  493.     local WINDOW_FRAGMENT   = ZO_HUDFadeSceneFragment:New(self.questTreeWin)
  494.     self.WINDOW_FRAGMENT    = WINDOW_FRAGMENT
  495.  
  496.     --Automatically show QuesTracker when game says to 
  497.     HUD_SCENE:AddFragment(WINDOW_FRAGMENT)                         
  498.     HUD_UI_SCENE:AddFragment(WINDOW_FRAGMENT)
  499.  
  500.     --Use this with force show setting in options above "auto" lines override this (use either those or this)
  501.     -- wtf? lol thats obviously not one of my comments !!!
  502.     -- Add/Remove fragment from the GAME_MENU_SCENE
  503.     QuestTracker:SetupFragmentForGameScene(svMainWindow.showInGameScene)
  504.    
  505.     self:UpdateWindowVisibility(self.svCurrent.mainWindow.hideQuestWindow)
  506. end
  507.  
  508. --===========================================================--
  509. --==================== UTILITY CODE =========================--
  510. --===========================================================--
  511.  
  512. function QuestTracker:SwapSavedVars(useAccountWide)
  513.     if useAccountWide then
  514.         self.svCurrent = self.svAccount
  515.     else
  516.         self.svCurrent = self.svCharacter
  517.     end
  518. end
  519.  
  520. function QuestTracker_ToggleWindow()
  521.     local questWindow           = QUESTTRACKER.questTreeWin
  522.     local svMainWindow          = QUESTTRACKER.svCurrent.mainWindow
  523.     local hideQuestWindow       = not svMainWindow.hideQuestWindow
  524.     svMainWindow.hideQuestWindow = hideQuestWindow
  525.    
  526.     QUESTTRACKER.WINDOW_FRAGMENT:SetHiddenForReason("QuestTracker_UserSetting_Hidden", hideQuestWindow)
  527. end
  528.  
  529. function QuestTracker:UpdateWindowVisibility(shouldHide)
  530.     local hideQuestWindow = shouldHide or self.svCurrent.mainWindow.hideQuestWindow
  531.    
  532.     self.WINDOW_FRAGMENT:SetHiddenForReason("QuestTracker_UserSetting_Hidden", hideQuestWindow)
  533. end
  534.  
  535. -- your shouldHide doesn't match with what its doing. It says if shouldHide then add it to the scene
  536. -- which makes it visible. Thats not hiding it. Changing it.
  537. function QuestTracker:SetupFragmentForGameScene(showInGameScene)    -- for force show setting
  538.     local showInGameScene   = showInGameScene or self.svCurrent.mainWindow.showInGameScene
  539.     local WINDOW_FRAGMENT   = self.WINDOW_FRAGMENT
  540.    
  541.     if showInGameScene then
  542.         GAME_MENU_SCENE:AddFragment(WINDOW_FRAGMENT)
  543.     else
  544.         GAME_MENU_SCENE:RemoveFragment(WINDOW_FRAGMENT)
  545.     end
  546. end
  547.  
  548. -- Auto Size functions
  549. function QuestTracker:AutoSizeWinHeight()
  550.     if not self.svCurrent.mainWindow.autoWindowSizeHeight then return end
  551.    
  552.     local childrenCurrentHeight = self.navigationTree.rootNode.childrenCurrentHeight
  553.     local win                   = self.questTreeWin
  554.    
  555.     local width, height = win:GetDimensions()
  556.     local dragBarHeight = self.dragBar:GetHeight()
  557.    
  558.     -- +5 is padding for the -5 offsetY anchor on the navigationContainer
  559.     -- +2 to prevent the scrollbar from flashing as the extents change
  560.     height = childrenCurrentHeight+dragBarHeight+7
  561.    
  562.     win:SetDimensions(width, height)
  563. end
  564.  
  565. function QuestTracker:AutoSizeWinWidth()
  566.     if not self.svCurrent.mainWindow.autoWindowSizeWidth then return end
  567.    
  568.     local maxNodeWidth = self.navigationTree.width
  569.    
  570.     local win = self.questTreeWin
  571.     local width, height = win:GetDimensions()
  572.    
  573.     -- Padding for scrollbar width 16 + navigationContainer both offsetX anchors left & right 5 each (in xml)
  574.     win:SetDimensions(maxNodeWidth+26, height)
  575. end
  576.  
  577. -- Calculates & returns the container width required for treeNode and all of its children.
  578. function QuestTracker:CalculateNodeContainerWidths(treeNode, totalIndent)
  579.     local children = treeNode.children
  580.     local treeNodeIndent = totalIndent or 0
  581.     local treeNodeWidth = (treeNode.totalControlWidth or 0) + treeNodeIndent
  582.     local containerWidth = 0
  583.    
  584.     if(children and treeNode:IsOpen()) then
  585.         local childIndent = treeNodeIndent+treeNode.childIndent
  586.        
  587.         for i = 1, #children do
  588.             local childNode = children[i]
  589.             local childContainerWidth = self:CalculateNodeContainerWidths(childNode, childIndent)
  590.            
  591.             containerWidth = zo_max(containerWidth, childNode.totalControlWidth+childIndent, childContainerWidth)
  592.         end
  593.     end
  594.     containerWidth = zo_max(treeNodeWidth, containerWidth)
  595.    
  596.     treeNode.containerWidth = containerWidth
  597.     treeNode.NodeIsIndentedBy = treeNodeIndent
  598.    
  599.     return containerWidth
  600. end
  601.  
  602.  
  603. function QuestTracker:UpdateCurrentChildrenWidthsToRoot()
  604.     local tree                  = self.navigationTree
  605.     local rootNode              = tree.rootNode
  606.     local rootContainerWidth    = self:CalculateNodeContainerWidths(rootNode)
  607.    
  608.     tree.width = rootContainerWidth
  609.     tree.control:SetWidth(rootContainerWidth)
  610.    
  611.     local function UpdateChildWidths(treeNode)
  612.         local control           = treeNode.control
  613.         local childContainer    = treeNode.childContainer
  614.         local children          = treeNode.children
  615.         local containerWidth    = treeNode.containerWidth
  616.        
  617.         if control then
  618.             control:SetWidth(containerWidth)
  619.         end
  620.         if childContainer then
  621.             childContainer:SetWidth(containerWidth)
  622.         end
  623.        
  624.         if(children) then
  625.             for i = 1, #children do
  626.                 local child = children[i]
  627.                 UpdateChildWidths(child)
  628.             end
  629.         end
  630.     end
  631.     UpdateChildWidths(rootNode)
  632. end
  633.  
  634. function QuestTracker:ScrollQuestNodeIntoView(questIndex, questNode)
  635.     local questNode = questNode or self.navigationTree.questIndexToTreeNode[questIndex]
  636.    
  637.     if questNode then
  638.         ZO_Scroll_ScrollControlIntoCentralView(self.navigationContainer, questNode.control)
  639.     end
  640. end
  641.  
  642. -- Get the tree node for the currently selected quest. If it exists, set that node selected
  643. function QuestTracker:SelectQuestIndexNode(questIndex, scrollIntoView)
  644.     local selectedQuestNode = self.navigationTree.questIndexToTreeNode[questIndex]
  645.    
  646.     if selectedQuestNode then
  647.         selectedQuestNode:OnSelected()
  648.        
  649.         if scrollIntoView then
  650.             self:ScrollQuestNodeIntoView(questIndex, selectedQuestNode)
  651.         end
  652.     end
  653. end
  654.  
  655. function QuestTracker:RefreshSelectedQuest()
  656.     local selectedQuestIndex = QUEST_JOURNAL_MANAGER:GetFocusedQuestIndex()
  657.    
  658.     self:SelectQuestIndexNode(selectedQuestIndex, true)
  659. end
  660.  
  661. function QuestTracker:ShowQuestTooltip(questIndex)
  662.     if QUESTTRACKER.WINDOW_FRAGMENT:IsHidden() then return end
  663.    
  664.     local svTooltips    = self.svCurrent.tooltips
  665.     local anchorPoint   = svTooltips.anchorPoint
  666.     local relativeTo    = svTooltips.relativeTo
  667.    
  668.     -- In case auto-tooltips are on & a tooltip was just set...and the user
  669.     -- mouses over a quest node, which opens a new tooltip. We don't want it to fade until the user
  670.     -- exits the node with the mouse, so cancel auto registered ClearTooltip
  671.     EVENT_MANAGER:UnregisterForUpdate("QuestTrackerClearAutoTooltip")
  672.    
  673.     InitializeTooltip(InformationTooltip, self.questTreeWin, anchorPoint, 0, 0, relativeTo)
  674.    
  675.     LQI:CreateQuestTooltip(questIndex, InformationTooltip)
  676. end
  677.  
  678. function QuestTracker:SetLockState(lock)
  679.     local lockBtn               = self.lockBtn
  680.     local unlockBtn             = self.unlockBtn
  681.     local mainWin               = self.questTreeWin
  682.     local svMainWindow          = self.svCurrent.mainWindow
  683.     local svMainWindowBackdrop  = svMainWindow.backdrop
  684.    
  685.     svMainWindow.isItLocked = lock
  686.    
  687.     local isWindowLocked = lock
  688.     local isWindowUnlocked = not lock
  689.    
  690.     if svMainWindow.hideLockIcon == "Never" then
  691.         lockBtn:SetHidden(isWindowUnlocked)
  692.         lockBtn:SetEnabled(isWindowLocked)
  693.         unlockBtn:SetHidden(isWindowLocked)
  694.         unlockBtn:SetEnabled(isWindowUnlocked)
  695.     elseif svMainWindow.hideLockIcon == "Always" then
  696.         unlockBtn:SetHidden(true)
  697.         lockBtn:SetHidden(true)    
  698.     elseif svMainWindow.hideLockIcon == "Locked" then
  699.         lockBtn:SetHidden(true)
  700.         unlockBtn:SetHidden(isWindowLocked)
  701.         unlockBtn:SetEnabled(isWindowUnlocked)     
  702.     end
  703.    
  704.     mainWin:SetMovable(isWindowUnlocked)
  705.     mainWin:SetMouseEnabled(isWindowUnlocked)
  706.    
  707.     if not svMainWindowBackdrop.backdropHideOnLock then return end
  708.    
  709.     local backdropControl   = self.backdrop
  710.     local dragBar           = self.dragBar
  711.     local isBackdropHidden  = backdropControl:IsHidden()
  712.    
  713.     if isWindowLocked and not isBackdropHidden then
  714.         backdropControl:SetHidden(true)
  715.         dragBar:SetHidden(true)
  716.     end
  717.        
  718.     if isWindowUnlocked and isBackdropHidden then
  719.         if svMainWindowBackdrop.backdropName ~= "None" then
  720.             backdropControl:SetHidden(false)
  721.             dragBar:SetHidden(false)
  722.         end
  723.     end
  724. end
  725.  
  726. -- DONT try to compare condition nodes. I did not write an equality function for them
  727. -- we don't need it. Were not updating condition nodes. When needed we wipe them out & re-add them.
  728. function QuestTracker:AreTreeNodesEqual(treeNode1, treeNode2)
  729.     if treeNode1.equalityFunction == treeNode2.equalityFunction then
  730.         if treeNode1.equalityFunction(treeNode1.data, treeNode2.data) then
  731.             return true
  732.         end
  733.     end
  734.     return false
  735. end
  736.  
  737. --===========================================================--
  738. --=========== ADD/REMOVE NODE UTILITY CODE ==================--
  739. --===========================================================--
  740. function QuestTracker:UpdateChildHeightsToRoot(treeNode)
  741.     treeNode:UpdateChildrenHeightsToRoot()
  742.     treeNode:UpdateCurrentChildrenHeightsToRoot()
  743.    
  744.     -- widths are now updated in the hook on UpdateCurrentChildrenHeightsToRoot()
  745. end
  746.  
  747. -- When removing a node, this is used to reanchor the previous node to the next node
  748. function QuestTracker:AnchorPreviousNodeToNextNode(nodeToRemove)
  749.     local previousNode  = self:GetPreviousNode(nodeToRemove)
  750.     local parentNode    = nodeToRemove.parentNode
  751.     local nextNode      = nodeToRemove.nextNode
  752.    
  753.     if nextNode then
  754.         local childControl = nextNode:GetControl()
  755.         -- This is not needed, nextNode is already a sibling, were only ever reanchoring siblings
  756.         childControl:SetParent(parentNode.childContainer)
  757.        
  758.         if(previousNode) then
  759.             previousNode:AttachNext(nextNode)
  760.         else
  761.             childControl:ClearAnchors()
  762.             childControl:SetAnchor(TOPLEFT, parentNode.childContainer, TOPLEFT, parentNode.childIndent, 0)
  763.         end
  764.     end
  765.  
  766.     self:UpdateChildHeightsToRoot(parentNode)
  767. end
  768.  
  769. -- Used to get the previous node, to reanchor nodes, when removing a node
  770. function QuestTracker:GetPreviousNode(treeNode)
  771.     local parentNode    = treeNode.parentNode
  772.     local siblingsTable = parentNode.children
  773.     local next          = next
  774.    
  775.     if not siblingsTable or next(siblingsTable) == nil then return end
  776.    
  777.     for k, siblingNode in pairs(siblingsTable) do
  778.         if self:AreTreeNodesEqual(treeNode, siblingNode)then
  779.        
  780.             -- If treeNode is the first indexed child, this will be k-1 = 0 & it will return nil, thats ok
  781.             -- It is expected to return nil if treeNode is the first child
  782.             return siblingsTable[k-1]
  783.         end
  784.     end
  785. end
  786.  
  787. -- Used to get the table index for a treeNode, when removing nodes, so that after we
  788. -- release all of the node objects we can remove the node reference from the node table.
  789. function QuestTracker:GetNodeTableIndex(treeNode)
  790.     local parentNode    = treeNode.parentNode
  791.     local siblingsTable = parentNode.children
  792.  
  793.     for tableIndex, siblingNode in pairs(siblingsTable) do
  794.         if self:AreTreeNodesEqual(treeNode, siblingNode)then
  795.             return tableIndex
  796.         end
  797.     end
  798. end
  799.  
  800. -- When creating a new Category node this is used to get the categories default table data
  801. function QuestTracker:GetDefaultCategoryNodeData(categoryName, allCategories)
  802.     for k, categoryData in pairs(allCategories) do
  803.         if categoryData.name == categoryName then
  804.             return categoryData
  805.         end
  806.     end
  807. end
  808.  
  809. -- When we add quest nodes, this is used to get the correct parent (category) node
  810. -- This happens before the quest node is created, so we can't use questNode.parentNode...we
  811. -- need to know what categoryNode to create the quest node under
  812. function QuestTracker:GetCategoryNodeByName(categoryName)
  813.     local rootChildren = self.navigationTree.rootNode.children
  814.    
  815.     for k, categoryNode in ipairs(rootChildren) do
  816.         if categoryNode.data.name == categoryName then
  817.             return categoryNode
  818.         end
  819.     end
  820. end
  821.  
  822. -- Add step & condition info to the questData table
  823. local function AddStepConditionInfo(questData)
  824.     local questInfo = LQI:GetCurrentQuestInfo(questData.questIndex)
  825.    
  826.     local trackerOverrideText       = questInfo.trackerOverrideText
  827.     questData.stepIndex             = questInfo.stepIndex -- Only for /zgoo debugging, not used
  828.     questData.stepText              = questInfo.stepText  -- Only for /zgoo debugging, not used
  829.     questData.trackerOverrideText   = trackerOverrideText
  830.    
  831.     -- This really isn't a condition, but we want to display it like one if it exists instead of the conditions.
  832.     -- BE AWARE, by doing this it means that other condition info you see in the condition tables like
  833.     -- current, isComplete, isCreditShared, exc... will not always be available in the table...here we will
  834.     -- only store the tracker override text because thats what is suppposed to be displayed & it does not belong
  835.     -- to any single condition, so we can't just copy another conditions info...there may not even be any
  836.     -- other conditions.
  837.     if(trackerOverrideText and trackerOverrideText ~= "") then
  838.         local fOverrideStepText = zo_strformat(SI_QUEST_HINT_STEP_FORMAT, trackerOverrideText)
  839.        
  840.         questData.conditions = {
  841.             [1] = {conditionText = fOverrideStepText},
  842.         }
  843.     else
  844.         questData.conditions = questInfo.conditions
  845.     end
  846.    
  847.     return questData
  848. end
  849.  
  850. --===========================================================--
  851. --================ SORT/REANCHOR CODE =======================--
  852. --===========================================================--
  853. -- Called from SortChildrenByType to reanchor the children after they have been sorted
  854. function QuestTracker:ReanchorChildren(parentNode)
  855.     local siblingsTable = parentNode.children
  856.    
  857.     if not siblingsTable then return end
  858.  
  859.     local previousNode = nil
  860.    
  861.     for _, treeNode in ipairs(siblingsTable) do
  862.         treeNode.nextNode = nil
  863.        
  864.         if previousNode then
  865.             previousNode:AttachNext(treeNode)
  866.         else
  867.             local treeNodeControl = treeNode:GetControl()
  868.             treeNodeControl:ClearAnchors()
  869.             treeNodeControl:SetAnchor(TOPLEFT, parentNode.childContainer, TOPLEFT, parentNode.childIndent, 0)
  870.         end
  871.        
  872.         previousNode = treeNode
  873.     end
  874.    
  875.     self:UpdateChildHeightsToRoot(parentNode)
  876. end
  877.  
  878. --==================================================================================================--
  879. -- ZO_TreeNode will not let you insert a child into a specific position & ZO_TreeNode is local.
  880. -- So to keep nodes in order, we let the game add it to the end of the list, resort
  881. -- the node table, and then re-anchor the nodes in the table.
  882. --==================================================================================================--
  883. -- NEVER try to sort the condition nodes !!!
  884. -- They are ordered in a special way, for step/condition order & visibility
  885. --==================================================================================================--
  886. --**** Sorts by category type and THEN by name, so all items may not "appear" to show up in alphabetical order ****--
  887. --**** This was intentional ****--
  888. function QuestTracker:SortQuestNodes(sortByLevel)
  889.     local sortByLevel = sortByLevel or self.svCurrent.sortByLevel
  890.     local categoryTable = self.navigationTree.rootNode.children
  891.    
  892.     for k,categoryNode in pairs(categoryTable) do
  893.         self:SortChildrenByType(categoryNode, SORT_TYPE_QUESTS)
  894.     end
  895. end
  896.  
  897. function QuestTracker:SortChildrenByType(parentNode, sortType)
  898.     local siblingsTable = parentNode.children
  899.     if not siblingsTable then return end
  900.  
  901.     if sortType == SORT_TYPE_QUESTS then       
  902.         local sortByLevel = self.svCurrent.sortByLevel
  903.         local function SortQuestTableEntries(questTableEntry1, questTableEntry2)
  904.             local quest1NodeData = questTableEntry1.data
  905.             local quest2NodeData = questTableEntry2.data
  906.            
  907.             if quest1NodeData.categoryType == quest2NodeData.categoryType then
  908.                 if quest1NodeData.categoryName == quest2NodeData.categoryName then
  909.                     if sortByLevel then
  910.                         return quest1NodeData.level < quest2NodeData.level
  911.                     end
  912.                     return quest1NodeData.name < quest2NodeData.name
  913.                 end
  914.                 return quest1NodeData.categoryName < quest2NodeData.categoryName
  915.             end
  916.             return quest1NodeData.categoryType < quest2NodeData.categoryType
  917.         end
  918.        
  919.         table.sort(siblingsTable, SortQuestTableEntries)
  920.        
  921.     elseif sortType == SORT_TYPE_QUEST_CATEGORIES then
  922.         local function SortCategoryTableEntries(categoryTableEntry1, categoryTableEntry2)
  923.             local category1NodeData = categoryTableEntry1.data
  924.             local category2NodeData = categoryTableEntry2.data
  925.            
  926.             if category1NodeData.type == category2NodeData.type then
  927.                 return category1NodeData.name < category2NodeData.name
  928.             else
  929.                 return category1NodeData.type < category2NodeData.type
  930.             end
  931.         end
  932.        
  933.         table.sort(siblingsTable, SortCategoryTableEntries)
  934.     end
  935.     self:ReanchorChildren(parentNode)
  936. end
  937.  
  938. --=============================================================--
  939. --==================== ADD NODE CODE ==========================--
  940. --=============================================================--
  941. function QuestTracker:AddCategoryNode(categoryData, parentNode)
  942.     local headerNode = self.navigationTree:AddNode("QuestTrackerCategoryNode", categoryData, parentNode, SOUNDS.QUEST_BLADE_SELECTED)
  943.    
  944.     return headerNode
  945. end
  946.  
  947. function QuestTracker:AddQuestEntryNode(questData, parentNode)
  948.     local questNode = self.navigationTree:AddNode("QuestTrackerQuestNode", questData, parentNode, SOUNDS.QUEST_SELECTED)
  949.     self.navigationTree.questIndexToTreeNode[questData.questIndex] = questNode    
  950.    
  951.     if QUESTTRACKER and QUESTTRACKER.svCurrent.autoOpenNodes then
  952.         questNode:SetOpenPercentage(1)
  953.         questNode.open = true
  954.     end
  955.    
  956.     return questNode
  957. end
  958.  
  959. function QuestTracker:AddQuestConditionNode(conditionData, parentNode)
  960.     local conditionNode = self.navigationTree:AddNode("QuestTrackerConditionNode", conditionData, parentNode, nil)
  961.    
  962.     return conditionNode
  963. end
  964.  
  965.  
  966. --=============================================================--
  967. --================== UPDATE QUEST CODE ========================--
  968. --=============================================================--
  969. -- Used to update quest condition nodes...well actualy wipe them out & recreate them
  970. -- on quest advance or quest condition counter change. We wipe them out rather than update them because
  971. -- its much easier/faster than looping through each node to edit/add new conditions & looping through again
  972. -- to wipe out any old left over condition nodes that are no longer valid
  973. function QuestTracker:UpdateQuest(journalIndex)
  974.     local tree = self.navigationTree
  975.     local questNode = tree.questIndexToTreeNode[journalIndex]
  976.  
  977.     -- If it doesn't exist....something is wrong somewhere else
  978.     assert(questNode, "UpdateQuest failed. Quest does not exist in the quest tree")
  979.    
  980.     -- Not really the most efficient method here, but easy
  981.     local allQuests, allCategories, seenCategories = QUEST_JOURNAL_MANAGER:GetQuestListData()
  982.     local newQuestData
  983.    
  984.     for k,questData in pairs(allQuests) do
  985.         if questData.questIndex == journalIndex then
  986.             newQuestData = questData
  987.             break
  988.         end
  989.     end
  990.     -- If newQuestData doesn't exist....something is wrong, the quest must have been removed somehow/somewhere
  991.     -- and it wasn't supposed to be or else an update event would not have fired, but don't do this:
  992.     -- if not newQuestData then return end....we want an error to let us know whats wrong
  993.     assert(newQuestData, "UpdateQuest failed. Quest does not exist in the QUEST_JOURNAL_MANAGER")
  994.    
  995.     self:ReleaseAllQuestConditionNodes(questNode)
  996.    
  997.     -- Add step & condition info to the newQuestData table
  998.     AddStepConditionInfo(newQuestData)
  999.    
  1000.     questNode.data = newQuestData
  1001.    
  1002.     -- Add all of the new condition nodes....NEVER sort the condition nodes !!!
  1003.     -- They are already ordered in a special way, for step/condition order & visibility
  1004.     local conditions = newQuestData.conditions
  1005.     for conditionKey, conditionData in ipairs(conditions) do
  1006.         local conditionNode = self:AddQuestConditionNode(conditionData, questNode)
  1007.     end
  1008.     self:UpdateChildHeightsToRoot(questNode)
  1009. end
  1010.  
  1011. --=============================================================--
  1012. --=============== ADD/REMOVE CATEGORY CODE ====================--
  1013. --=============================================================--
  1014. -- When a quest is added, if the category does not already exist, used to add the new quest category
  1015. function QuestTracker:AddQuestCategory(categoryNodeData)
  1016.     local rootNode      = self.navigationTree.rootNode
  1017.     local categoryNode  = self:AddCategoryNode(categoryNodeData, rootNode)
  1018.    
  1019.     self:SortChildrenByType(rootNode, SORT_TYPE_QUEST_CATEGORIES)
  1020.    
  1021.     return categoryNode
  1022. end
  1023.  
  1024. --==============================================================--
  1025. --============ REPOPULATE/ADDTABLE NODES CODE ============--
  1026. --==============================================================--
  1027. function QuestTracker:RepopulateQuestTree()
  1028.     -- these tables are ALREADY sorted, so use ipairs !
  1029.     local allQuests, allCategories, seenCategories = QUEST_JOURNAL_MANAGER:GetQuestListData()
  1030.     local quests = {}
  1031.    
  1032.     -- Combine the quest/category data into one table
  1033.     for categoryKey, categoryData in ipairs(allCategories) do
  1034.         local categoryName = categoryData.name
  1035.        
  1036.         quests[categoryKey] = {
  1037.             name = categoryName,
  1038.             type = categoryData.type,
  1039.             -- Note this quests table is ONLY valid here & in the below call to AddTableNodes, when repopulating the
  1040.             -- tree from scratch. When we add/remove/update nodes we do NOT update this quests table...theres no need to.
  1041.             -- This is only to reorganize the data returned by GetQuestListData to make the repopulation/AddTableNodes() easier.
  1042.             quests = {}
  1043.         }
  1044.         for questKey, questData in ipairs(allQuests) do
  1045.             if questData.categoryName == categoryName then
  1046.                 AddStepConditionInfo(questData)
  1047.                
  1048.                 table.insert(quests[categoryKey].quests, questData)
  1049.             end
  1050.         end
  1051.         if self.svCurrent.sortByLevel then
  1052.             local function SortQuestsByLevel(questTableEntry1, questTableEntry2)
  1053.                 return questTableEntry1.level < questTableEntry2.level
  1054.             end
  1055.             table.sort(quests[categoryKey].quests, SortQuestsByLevel)
  1056.         end
  1057.     end
  1058.    
  1059.     self:AddTableNodes(quests, nil)
  1060.    
  1061.     -- If there are quests when the table nodes are added it automatically calls
  1062.     -- the required functions to resize the window. If the quests table is empty, no quests
  1063.     -- no nodes are added so we must call the update ourselves.
  1064.     if next(quests) == nil then
  1065.         self:UpdateChildHeightsToRoot(self.navigationTree.rootNode)
  1066.     end
  1067.    
  1068.     -- Must refresh selected quest, that way when quests are added or removed,
  1069.     -- we keep the correct quest selected because the QuestTrackerAssistStateChanged
  1070.     -- will have already fired and it wont get updated by that !
  1071.     self:RefreshSelectedQuest()
  1072.     -- AFTER that, update the tree exclusitivity. Must be after so a quest is selected to set the
  1073.     -- exclusive path if the tree is set as exclusive.
  1074.     self:UpdateTreeExclusitivity()
  1075.     self.navigationTree:RefreshVisible()    -- Extra refresh to prevent text from being chopped off (workaround for a ZOS issue)
  1076. end
  1077.  
  1078. function QuestTracker:AddTableNodes(allQuests, parentNode)
  1079.     local tree = self.navigationTree
  1080.     -- Clear the tree nodes & questIndexToTreeNode table
  1081.     tree:Reset()
  1082.     tree.questIndexToTreeNode = {}
  1083.    
  1084.     -- They are sorted use ipairs !!
  1085.     for categoryKey, categoryData in ipairs(allQuests) do
  1086.         local categoryNode = self:AddCategoryNode(categoryData, parentNode)
  1087.         local quests = categoryData.quests
  1088.        
  1089.         for questKey, questData in ipairs(quests) do
  1090.             local questNode = self:AddQuestEntryNode(questData, categoryNode)
  1091.             tree.questIndexToTreeNode[questData.questIndex] = questNode
  1092.            
  1093.             local conditions = questData.conditions
  1094.             for conditionKey, conditionData in ipairs(conditions) do
  1095.                 local conditionNode = self:AddQuestConditionNode(conditionData, questNode)
  1096.             end
  1097.             questData.conditions = nil -- Wipe this out so you don't accidently "think" you can use it later, we don't update this data
  1098.         end
  1099.         categoryData.quests = nil -- Wipe this out so you don't accidently "think" you can use it later, we don't update this data
  1100.     end
  1101.    
  1102.     -- If the user has exclusitivity set to "All" so tree.exclusive == true this will cause problems if you do not
  1103.     -- specify which node to select...even though it really wont select the node because its not a leaf,
  1104.     -- it blocks the SelectAnything() func
  1105.     local selectedQuestIndex = QUEST_JOURNAL_MANAGER:GetFocusedQuestIndex()
  1106.     local selectedQuestNode = self.navigationTree.questIndexToTreeNode[selectedQuestIndex]
  1107.     tree:Commit(selectedQuestNode)
  1108.    
  1109.     -- On category nodes, the number of quests is only set when the category node is created (or visible/control is refreshed)
  1110.     -- But children (quests) get added after that. So after were done adding all the quests, refresh the entire visible tree
  1111.     -- to update the number of quests for every category control
  1112.     tree:RefreshVisible()
  1113. end
  1114.  
  1115. --===========================================================--
  1116. --============ BACKDROP SETTINGS MENU FUNCTIONS  ============--
  1117. --===========================================================--
  1118. function QuestTracker:UpdateBackdropColor()
  1119.     local backdropControl   = self.backdrop
  1120.     local bgColor           = self.svCurrent.mainWindow.backdrop.backdropColor
  1121.     local dragBar           = self.dragBar
  1122.     local r,g,b,alpha       = unpack(bgColor)
  1123.    
  1124.     backdropControl:SetCenterColor(r,g,b,alpha)
  1125.     backdropControl:SetEdgeColor(r,g,b,alpha)
  1126.     dragBar:SetAlpha(alpha)
  1127. end
  1128. function QuestTracker:UpdateDragBarColor()
  1129.     local bgColor             = self.svCurrent.mainWindow.backdrop.dragBarColor
  1130.     local dragBar             = self.dragBar
  1131.     local r,g,b,alpha        = unpack(bgColor)
  1132.    
  1133.     dragBar:SetCenterColor(r,g,b,alpha)
  1134.     --dragBar:SetEdgeColor(r,g,b,alpha)
  1135. end
  1136.  
  1137. function QuestTracker:UpdateBackdrop(backdropName)
  1138.     local backdropControl       = self.backdrop
  1139.     local dragBar               = self.dragBar
  1140.     local mungeOverlay          = backdropControl:GetNamedChild("MungeOverlay")
  1141.    
  1142.     local svMainWindow          = self.svCurrent.mainWindow
  1143.     local svMainWindowBackdrop  = svMainWindow.backdrop
  1144.     local bgColor               = svMainWindowBackdrop.backdropColor
  1145.     local backdropName          = backdropName or svMainWindowBackdrop.backdropName
  1146.    
  1147.     if svMainWindowBackdrop.hideMungeOverlay then
  1148.         mungeOverlay:SetHidden(true)
  1149.     else
  1150.         mungeOverlay:SetHidden(false)
  1151.     end
  1152.    
  1153.     if backdropName == "None" then
  1154.         backdropControl:SetHidden(true)
  1155.         dragBar:SetHidden(true)
  1156.        
  1157.     else
  1158.         if backdropName == "Fancy" then
  1159.             backdropControl:SetCenterTexture("EsoUI/Art/Tooltips/UI-TooltipCenter.dds", 16, WRAP)
  1160.             backdropControl:SetEdgeTexture("EsoUI/Art/Tooltips/UI-Border.dds", 128, 16, 0, 0)
  1161.             backdropControl:SetEdgeColor(1,1,1,1)
  1162.        
  1163.         elseif backdropName == "Colored" then
  1164.             backdropControl:SetCenterTexture(nil, 16, WRAP)
  1165.             backdropControl:SetEdgeTexture(nil, 128, 16, 0, 0)
  1166.             local r,g,b,alpha = unpack(bgColor)
  1167.             backdropControl:SetCenterColor(r,g,b,alpha)
  1168.             backdropControl:SetEdgeColor(r,g,b,alpha)
  1169.             local dragBar = self.dragBar
  1170.             self:UpdateDragBarColor()
  1171.             dragBar:SetAlpha(alpha)
  1172.         end
  1173.         local shouldHide = svMainWindowBackdrop.backdropHideOnLock and svMainWindow.isItLocked
  1174.         backdropControl:SetHidden(shouldHide)
  1175.         dragBar:SetHidden(shouldHide)
  1176.     end
  1177. end
  1178.  
  1179. --==========================================================--
  1180. --==================  EXCLUSITIVITY CODE  ==================--
  1181. --==========================================================--
  1182. function QuestTracker:OpenAllQuestNodes()
  1183.     local tree            = self.navigationTree
  1184.     local selectedNode     = tree.selectedNode
  1185.    
  1186.     -- The game is still loading, the user has no quests...or else theres always something selected?
  1187.     if not selectedNode then return end
  1188.    
  1189.     local categoryNodesTable     = tree.rootNode.children
  1190.    
  1191.     for k,categoryNode in pairs(categoryNodesTable) do
  1192.         local questNodeTable = categoryNode.children
  1193.        
  1194.         for k,questNode in pairs(questNodeTable) do
  1195.             tree:SetNodeOpen(questNode, true, USER_REQUESTED_OPEN)
  1196.         end
  1197.     end
  1198. end
  1199.  
  1200. function QuestTracker:OpenSelectedCategoryQuestNodes()
  1201.     local tree            = self.navigationTree
  1202.     local selectedNode     = tree.selectedNode
  1203.    
  1204.     -- The game is still loading, the user has no quests...or else theres always something selected?
  1205.     if not selectedNode then return end
  1206.    
  1207.     local selectedCategoryNode = selectedNode.parentNode
  1208.     local questNodeTable = selectedCategoryNode.children
  1209.        
  1210.     for k,questNode in pairs(questNodeTable) do
  1211.         tree:SetNodeOpen(questNode, true, USER_REQUESTED_OPEN)
  1212.     end
  1213. end
  1214.  
  1215. function QuestTracker:CloseAllQuestNodes()
  1216.     local tree          = self.navigationTree
  1217.     local selectedNode  = tree.selectedNode
  1218.    
  1219.     -- The game is still loading, the user has no quests...or else theres always something selected?
  1220.     if not selectedNode then return end
  1221.    
  1222.     local categoryNodesTable    = tree.rootNode.children
  1223.    
  1224.     for k,categoryNode in pairs(categoryNodesTable) do
  1225.         local questNodeTable = categoryNode.children
  1226.        
  1227.         for k,questNode in pairs(questNodeTable) do
  1228.             if questNode.open and not self:AreTreeNodesEqual(questNode, selectedNode) then
  1229.                 tree:SetNodeOpen(questNode, false, USER_REQUESTED_OPEN)
  1230.             end
  1231.         end
  1232.     end
  1233. end
  1234.  
  1235. function QuestTracker:CloseAllCategoryNodes()
  1236.     local tree          = self.navigationTree
  1237.     local selectedNode  = tree.selectedNode
  1238.    
  1239.     -- The game is still loading, the user has no quests...or else theres always something selected?
  1240.     if not selectedNode then return end
  1241.    
  1242.     local categoryNodeTable = tree.rootNode.children
  1243.     local selectedCategoryNode = selectedNode.parentNode
  1244.    
  1245.     for k,categoryNode in pairs(categoryNodeTable) do
  1246.         if categoryNode.open and not self:AreTreeNodesEqual(categoryNode, selectedCategoryNode) then
  1247.             tree:SetNodeOpen(categoryNode, false, USER_REQUESTED_OPEN)
  1248.         end
  1249.     end
  1250. end
  1251.  
  1252. function QuestTracker:OpenAllCategoryNodes()
  1253.     local tree          = self.navigationTree
  1254.     local selectedNode  = tree.selectedNode
  1255.    
  1256.     -- The game is still loading, the user has no quests...or else theres always something selected?
  1257.     if not selectedNode then return end
  1258.    
  1259.     local categoryNodeTable = tree.rootNode.children
  1260.     local selectedCategoryNode = selectedNode.parentNode
  1261.    
  1262.     for k,categoryNode in pairs(categoryNodeTable) do
  1263.         if categoryNode.closed and not self:AreTreeNodesEqual(categoryNode, selectedCategoryNode) then
  1264.             tree:SetNodeOpen(categoryNode, true, USER_REQUESTED_OPEN)
  1265.         end
  1266.     end
  1267. end
  1268.  
  1269. --[[ Note we do not always need to "set" the saved vars for changing node exclusitivity, this is why it is split into
  1270.      two functions For example, on load, we only need to update the newly created trees setting, so we pass in nil. But in
  1271.      the settings menu we call SetTreeExclusitivity, which saves the new sv value & calls this function to update the tree
  1272.      setting. In that route, since we already have the nodeExclusitivity table theres no reason to look it up again here, thus the parameter.
  1273. --]]
  1274. function QuestTracker:UpdateTreeExclusitivity(exclusitivityTable)
  1275.     local tree                      = self.navigationTree
  1276.     local isTreeExclusive           = tree.exclusive
  1277.     local newExclusitivityTable     = exclusitivityTable or self.svCurrent.nodeExclusitivity
  1278.     local shouldTreeBeExclusive     = newExclusitivityTable.isTreeExclusive
  1279.    
  1280.     -- If the tree is already exclusive, other nodes are already closed, so we don't need to worry about
  1281.     -- closing categories or quest nodes, just set the new exclusitivity (if needed)
  1282.     if isTreeExclusive then
  1283.         if not shouldTreeBeExclusive then
  1284.             tree:SetExclusive(false)
  1285.         end
  1286.        
  1287.     else
  1288.         -- Tree is not currently exclusive. If it should be, set it exclusive & close all nodes
  1289.         if shouldTreeBeExclusive then
  1290.             local curSelectedNode   = tree.selectedNode
  1291.            
  1292.             tree:SetExclusive(true)
  1293.            
  1294.             if curSelectedNode then
  1295.                 -- exclusivePath has not been set yet, when SetExclusive is false it does not set the path
  1296.                 -- so call OpenNode (even though it may already be open) to force it to set the path
  1297.                 -- and run exclusivitity close function after we set exclusive to true
  1298.                 tree:SetNodeOpen(curSelectedNode, true, USER_REQUESTED_OPEN)
  1299.             end
  1300.            
  1301.         else
  1302.             -- Tree is not exclusive & should not be, dont change exclusitivity, but since tree is not exclusive
  1303.             -- category/quest nodes may be open that are not supposed to be. Check & update their exclusitivity.
  1304.             if newExclusitivityTable.categoryNodes then
  1305.                 self:CloseAllCategoryNodes()
  1306.             end
  1307.             if newExclusitivityTable.questNodes then
  1308.                 self:CloseAllQuestNodes()
  1309.             end
  1310.         end
  1311.     end
  1312. end
  1313.  
  1314. -- Update saved vars with new exclusitivity info
  1315. function QuestTracker:SetTreeExclusitivity(exclusiveName)
  1316.     local exclusitivity = {
  1317.         ["None"] = {
  1318.             currentSetting  = "None",
  1319.             allNodes        = false,
  1320.             categoryNodes   = false,
  1321.             questNodes      = false,
  1322.             isTreeExclusive = false,
  1323.         },
  1324.         ["All"] = {
  1325.             currentSetting  = "All",
  1326.             allNodes        = true,
  1327.             categoryNodes   = false,
  1328.             questNodes      = false,
  1329.             isTreeExclusive = true,
  1330.         },
  1331.         ["Categories Only"] = {
  1332.             currentSetting  = "Categories Only",
  1333.             allNodes        = false,
  1334.             categoryNodes   = true,
  1335.             questNodes      = false,
  1336.             isTreeExclusive = false,
  1337.         },
  1338.         ["Quests Only"] = {
  1339.             currentSetting  = "Quests Only",
  1340.             allNodes        = false,
  1341.             categoryNodes   = false,
  1342.             questNodes      = true,
  1343.             isTreeExclusive = false,
  1344.         },
  1345.     }
  1346.     local tree                  = self.navigationTree
  1347.     local newExclusitivity      = exclusitivity[exclusiveName]
  1348.     self.svCurrent.nodeExclusitivity    = newExclusitivity
  1349.    
  1350.     self:UpdateTreeExclusitivity(newExclusitivity)
  1351.    
  1352.     -- Make sure it scrolls back into view, just incase
  1353.     self:RefreshSelectedQuest()
  1354. end
  1355.  
  1356. --=========================================================--
  1357. --=========================================================--
  1358. --======================  TREE CODE  ======================--
  1359. --=========================================================--
  1360. --=========================================================--
  1361. -- I would strongly suggest you don't mess with any of this InitializeTree code.
  1362. -- The games tree class does not do everything I needed it to do. Like selecting nodes that have children.
  1363. -- So I changed some stuff & manually called/did whatever I needed instead of using the ZO_Tree functions.
  1364. -- There are several tree functions that you can NOT use. Some just wont work & some will mess things up.
  1365. function QuestTracker:InitializeTree()
  1366.     local navigationTree = self.navigationTree
  1367.    
  1368.     local openTexture       = "EsoUI/Art/Buttons/tree_open_up.dds"
  1369.     local closedTexture     = "EsoUI/Art/Buttons/tree_closed_up.dds"
  1370.     local overOpenTexture   = "EsoUI/Art/Buttons/tree_open_over.dds"
  1371.     local overClosedTexture = "EsoUI/Art/Buttons/tree_closed_over.dds"
  1372.        
  1373.     --============ Category Node Code ============================================--
  1374.     local function CategoryNodeSetup(node, control, data, open, userRequested)
  1375.         local fontString    = self:GetCategoryFontString()
  1376.         local textControl   = control.text
  1377.         local icon          = control.icon
  1378.         local categoryName  = data.name
  1379.         local numQuests     = node.children and #node.children
  1380.        
  1381.        
  1382.         if numQuests and self.svCurrent.showNumCategoryQuests then
  1383.             categoryName = zo_strformat("[<<1>>] <<2>>", numQuests, categoryName)
  1384.         end
  1385.        
  1386.         node.label = textControl
  1387.         node.icon = icon
  1388.        
  1389.         textControl:SetFont(fontString)
  1390.         textControl:SetModifyTextType(MODIFY_TEXT_TYPE_UPPERCASE)
  1391.         textControl:SetText(categoryName)
  1392.        
  1393.         local textWidth = textControl:GetTextWidth()
  1394.         local iconWidth = icon:GetWidth()
  1395.         node.textWidth = textWidth
  1396.         node.iconWidth = iconWidth
  1397.        
  1398.         -- if theres a problem with this, check the global UI scale
  1399.         node.totalControlWidth = textWidth + iconWidth + TEXT_LABEL_PADDING
  1400.        
  1401.         -- if theres a problem with this, check the global UI scale
  1402.         local textHeight    = textControl:GetTextHeight()
  1403.         local currentHeight = control:GetHeight()
  1404.        
  1405.         if currentHeight ~= textheight then
  1406.             textControl:SetHeight(textHeight)
  1407.             control:SetHeight(textHeight)
  1408.             control.icon:SetDimensions(textHeight, textHeight)
  1409.             self:UpdateChildHeightsToRoot(node)
  1410.         end
  1411.        
  1412.         local categoryColor = ZO_ColorDef:New(unpack(self.svCurrent.fontSettings.categories.color))
  1413.         ZO_SelectableLabel_SetNormalColor(textControl, categoryColor)
  1414.        
  1415.         control.icon:SetTexture(open and openTexture or closedTexture)
  1416.         control.iconHighlight:SetTexture(open and overOpenTexture or overClosedTexture)
  1417.    
  1418.         textControl:SetSelected(open)
  1419.     end
  1420.    
  1421.     local function CategoryNodeEquality(left, right)
  1422.         return left.name == right.name
  1423.     end
  1424.     navigationTree:AddTemplate("QuestTrackerCategoryNode", CategoryNodeSetup, nil, CategoryNodeEquality, 40, 0)
  1425.     --============ End Category Node Code ========================================--
  1426.    
  1427.     --============ Quest Node Code ================================================--
  1428.     -- Shared code function for quest node setup & select
  1429.     -- Handles showing/hiding the quest selected or instance icon
  1430.     local function SetupQuestIcon(questNodeControl, nodeData, selected)
  1431.         local questNode     = questNodeControl.node
  1432.         local tree          = questNode.tree
  1433.         local curQuestNode  = tree.selectedNode
  1434.         local icon          = GetControl(questNodeControl, "Icon")
  1435.        
  1436.         icon.selected = selected
  1437.    
  1438.         if selected then
  1439.             icon:SetTexture("EsoUI/Art/Journal/journal_Quest_Selected.dds")
  1440.             icon:SetAlpha(1.00)
  1441.             icon:SetHidden(false)
  1442.            
  1443.         else
  1444.             icon:SetTexture(QUEST_JOURNAL_KEYBOARD:GetIconTexture(nodeData.displayType))
  1445.             icon.tooltipText = QUEST_JOURNAL_KEYBOARD:GetTooltipText(nodeData.displayType)
  1446.            
  1447.             if nodeData.displayType == INSTANCE_DISPLAY_TYPE_NONE then
  1448.                 icon:SetHidden(true)
  1449.             else
  1450.                 icon:SetAlpha(0.50)
  1451.                 icon:SetHidden(true)   --   should be false ...  need to find changes in ESO source since DB DLC patch.   <------------------------------------------------------
  1452.             end
  1453.         end
  1454.     end
  1455.    
  1456.     local function QuestNodeSetup(questNode, questNodeControl, nodeData, open, userRequested)
  1457.         local questName         = nodeData.name
  1458.         local fontString        = self:GetQuestFontString()
  1459.         local textHeight        = questNodeControl:GetTextHeight()
  1460.         local currentHeight     = questNodeControl:GetHeight()
  1461.         local tree              = self.navigationTree
  1462.         local selectedNode      = tree.selectedNode
  1463.         local selected          = false
  1464.        
  1465.         if self.svCurrent.showQuestLevel then
  1466.             questName = zo_strformat("[<<1>>] <<2>>", nodeData.level, questName)
  1467.         end
  1468.        
  1469.         --xxxxxx
  1470.         questNodeControl.con = GetCon(nodeData.level)
  1471.         questNodeControl.questIndex = nodeData.questIndex
  1472.         questNodeControl:SetFont(fontString)
  1473.         questNodeControl:SetText(questName)
  1474.        
  1475.        
  1476.         questNode.label = questNodeControl
  1477.        
  1478.         -- if theres a problem with this, check the global UI scale
  1479.         local textWidth = questNodeControl:GetTextWidth() + TEXT_LABEL_PADDING
  1480.         questNode.textWidth = textWidth
  1481.         questNode.totalControlWidth = textWidth
  1482.    
  1483.         -- if theres a problem with this, check the global UI scale
  1484.         if currentHeight ~= textheight then
  1485.             questNodeControl:SetHeight(textHeight)
  1486.             self:UpdateChildHeightsToRoot(questNode)
  1487.             questNodeControl.icon:SetDimensions(textHeight, textHeight)
  1488.         end
  1489.        
  1490.         if selectedNode and questNode == selectedNode then
  1491.             selected = true
  1492.         end
  1493.        
  1494.         questNodeControl:SetSelected(selected)
  1495.         SetupQuestIcon(questNodeControl, nodeData, selected)
  1496.        
  1497.         -- Used so we don't need to know if the control is selected or not, it
  1498.         -- will refresh the correct color or set the default color, must be done after GetCon(...)
  1499.         questNodeControl:RefreshTextColor()
  1500.     end
  1501.    
  1502.     -- Handles closing nodes for node exclusitivity when a node is deselected, only called from
  1503.     -- QuestNodeOnSelected. Made a seperate function for simplicity only.
  1504.     local function DeselectQuestNode(questNode)
  1505.         local tree = questNode.tree
  1506.        
  1507.         -- If tree is exclusive it will handle closing nodes on its own
  1508.         if not tree.exclusive then
  1509.             local nodeExclusitivity     = self.svCurrent.nodeExclusitivity
  1510.            
  1511.             -- If exclusive quest nodes, close the curQuestNode
  1512.             if nodeExclusitivity.questNodes then
  1513.                 tree:SetNodeOpen(questNode, false, USER_REQUESTED_OPEN)
  1514.             end
  1515.            
  1516.             -- If exclusive category nodes & new quest is in a different category, close the current category node
  1517.             if nodeExclusitivity.categoryNodes then
  1518.                 local questNodeParentNode = questNode.parentNode
  1519.                 tree:SetNodeOpen(questNodeParentNode, false, USER_REQUESTED_OPEN)
  1520.             end
  1521.         end
  1522.     end
  1523.    
  1524.     -- The tree doesn't actually fire this because it has children...the game does not allow selecting nodes unless
  1525.     -- they are leafs. I'm just defining it here with the others, and I will fire it manually myself through the node:OnSelected()
  1526.     --QUEST_JOURNAL_KEYBOARD:FireCallbacks("QuestSelected", data.questIndex) -- This is nothing, just a reminder about something
  1527.     local function QuestNodeOnSelected(questNodeControl, nodeData, selected, reselectingDuringRebuild)
  1528.         local questNode     = questNodeControl.node
  1529.         local tree          = questNode.tree
  1530.         local curQuestNode  = tree.selectedNode
  1531.         local icon          = GetControl(questNodeControl, "Icon")
  1532.        
  1533.         if selected then
  1534.             if curQuestNode and questNode ~= curQuestNode then
  1535.                 tree:ClearSelectedNode()  -- calls :OnUnselected()
  1536.             end
  1537.            
  1538.             -- SetNodeOpen forces a call to questNode setup which deselects the node & hides the icon
  1539.             -- so we must do this before setting the icon, icon.selected, or control:SetSelected
  1540.             tree.selectedNode = questNode
  1541.             tree:SetNodeOpen(questNode, true, USER_REQUESTED_OPEN)
  1542.            
  1543.         else
  1544.             DeselectQuestNode(questNode)
  1545.         end
  1546.        
  1547.         -- must be done last, see comment above SetNodeOpen
  1548.         questNodeControl:SetSelected(selected)
  1549.         SetupQuestIcon(questNodeControl, nodeData, selected)
  1550.     end
  1551.    
  1552.     local function QuestNodeEquality(left, right)
  1553.         return left.name == right.name
  1554.     end
  1555.    -- navigationTree:AddTemplate("QuestTrackerQuestNode", QuestNodeSetup, QuestNodeOnSelected, QuestNodeEquality)
  1556.    -- ChildIndent & ChildSpacing are for the children "of this node" not for when this node is a child !
  1557.     navigationTree:AddTemplate("QuestTrackerQuestNode", QuestNodeSetup, QuestNodeOnSelected, QuestNodeEquality, 15, 0)
  1558.     --============ End Quest Node Code ============================================--
  1559.    
  1560.     --============ Condition Node Code ============================================--
  1561.     local function TreeConditionSetup(conditionNode, conditionNodeControl, data, open)
  1562.         local fontString = self:GetConditionFontString()
  1563.        
  1564.         conditionNode.label = conditionNodeControl
  1565.        
  1566.         conditionNodeControl:SetFont(fontString)
  1567.         conditionNodeControl:SetColor(unpack(self.svCurrent.fontSettings.conditions.color))
  1568.         conditionNodeControl:SetText(data.conditionText)
  1569.        
  1570.         -- if theres a problem with this, check the global UI scale
  1571.         local textWidth = conditionNodeControl:GetTextWidth() + TEXT_LABEL_PADDING
  1572.         conditionNode.textWidth = textWidth
  1573.         conditionNode.totalControlWidth = textWidth
  1574.    
  1575.         -- if theres a problem with this, check the global UI scale
  1576.         local textHeight    = conditionNodeControl:GetTextHeight()
  1577.         local currentHeight = conditionNodeControl:GetHeight()
  1578.        
  1579.         if currentHeight ~= textheight then
  1580.             conditionNodeControl:SetHeight(textHeight)
  1581.             self:UpdateChildHeightsToRoot(conditionNode)
  1582.         end
  1583.     end
  1584.     navigationTree:AddTemplate("QuestTrackerConditionNode", TreeConditionSetup)
  1585.     --============ End Condition Node Code ========================================--
  1586.    
  1587.     -- true means only one can be open at a time AND you can't click to close it. You have to open another to get it to close. Just left as a reminder: navigationTree:SetExclusive(true/false)...but don't do (below) here. Or a node wont be selected yet & the exclusive path wont get set correctly.
  1588.     --self:UpdateTreeExclusitivity()
  1589.    
  1590.     navigationTree:SetOpenAnimation("ZO_TreeOpenAnimation")
  1591.    
  1592.     return navigationTree
  1593. end
  1594.  
  1595. --================================================================--
  1596. --================================================================--
  1597. --============ TREE RELEASE NODE CODE ============================--
  1598. --================================================================--
  1599. --================================================================--
  1600. function QuestTracker:ReleaseConditionNode(conditionNode)
  1601.     -- hide its highlight if it has it
  1602.     self:HideNodeSelectionHighlight(conditionNode)
  1603.    
  1604.     -- Release any animations it has
  1605.     self:ReleaseOpenAnimation(conditionNode)
  1606.    
  1607.     -- Get the objectPool for conditions & release the condition Node
  1608.     local conditionObjectPool = self.navigationTree.templateInfo["QuestTrackerConditionNode"].objectPool
  1609.     self:ReleaseNodeFromPool(conditionNode, conditionObjectPool)
  1610. end
  1611.  
  1612. function QuestTracker:ReleaseQuestNode(questNode)
  1613.     local tree              = self.navigationTree
  1614.     local selectedNode      = tree.selectedNode
  1615.     local siblingsTable     = questNode.parentNode.children
  1616.     local questIndex        = questNode.data.questIndex
  1617.     local categoryNode      = questNode.parentNode
  1618.     local next              = next
  1619.    
  1620.     -- Remove the quest node reference from the questIndexToTreeNode table
  1621.     tree.questIndexToTreeNode[questIndex] = nil
  1622.    
  1623.     if self:AreTreeNodesEqual(questNode, selectedNode) then
  1624.         tree.selectedNode = nil
  1625.     end
  1626.    
  1627.     -- Reanchor around the node to be removed
  1628.     self:AnchorPreviousNodeToNextNode(questNode)
  1629.    
  1630.     -- release all of the condition nodes
  1631.     self:ReleaseAllQuestConditionNodes(questNode)
  1632.    
  1633.     -- release all node objects including the node control, animations, child container, exc...
  1634.     local questObjectPool = tree.templateInfo["QuestTrackerQuestNode"].objectPool
  1635.     self:ReleaseNodeObjects(questNode, questObjectPool)
  1636.    
  1637.     -- If the siblingsTable is empty, there are no more quests under this category
  1638.     -- then, release the category node.
  1639.     if next(siblingsTable) == nil then
  1640.         self:ReleaseCategoryNode(categoryNode)
  1641.     end
  1642. end
  1643.  
  1644. function QuestTracker:ReleaseChildContainer(treeNode)
  1645.     local containerControlName      = treeNode.childContainer:GetName()
  1646.     local containerObjectPool       = self.navigationTree.childContainerPool
  1647.     local activeContainerObjects    = containerObjectPool.m_Active
  1648.    
  1649.     for objKey,obj in pairs(activeContainerObjects) do
  1650.         if containerControlName == obj:GetName() then
  1651.             containerObjectPool:ReleaseObject(objKey)
  1652.         end
  1653.     end
  1654.    
  1655.     self:UpdateChildHeightsToRoot(treeNode)
  1656. end
  1657.  
  1658. function QuestTracker:ReleaseNodeFromPool(treeNode, objectPool)
  1659.     local activeCategoryObjects     = objectPool.m_Active
  1660.     local CategoryNodeControlName   = treeNode.control:GetName()
  1661.     local parentNode                = treeNode.parentNode
  1662.    
  1663.     for objKey,obj in pairs(activeCategoryObjects) do
  1664.         if CategoryNodeControlName == obj:GetName() then
  1665.             objectPool:ReleaseObject(objKey)
  1666.         end
  1667.     end
  1668.    
  1669.     self:UpdateChildHeightsToRoot(parentNode)
  1670. end
  1671.  
  1672. function QuestTracker:HideNodeSelectionHighlight(treeNode)
  1673.     if(treeNode.selectionHighlight) then
  1674.         treeNode.selectionHighlight:SetHidden(true)
  1675.     end
  1676. end
  1677.  
  1678. function QuestTracker:ReleaseOpenAnimation(treeNode)
  1679.     self.navigationTree.openAnimationPool:ReleaseObject(treeNode)
  1680. end
  1681.  
  1682. function QuestTracker:ReleaseNodeObjects(treeNode, nodeObjectPool)
  1683.     -- Get the parentNode.children table index for the node to be removed
  1684.     local treeNodeTableIndex    = self:GetNodeTableIndex(treeNode)
  1685.     local siblingTable          = treeNode.parentNode.children
  1686.    
  1687.     -- release the nodes child container
  1688.     self:ReleaseChildContainer(treeNode)
  1689.    
  1690.     self:HideNodeSelectionHighlight(treeNode)
  1691.     self:ReleaseOpenAnimation(treeNode)
  1692.  
  1693.     -- Release the category node itself
  1694.     self:ReleaseNodeFromPool(treeNode, nodeObjectPool)
  1695.    
  1696.     -- This is done here because the node referenced in this table, at this index,
  1697.     -- is no longer a valid node, we just released all of its objects
  1698.     -- Remove the node from the treeNode.parentNode.children table
  1699.     table.remove(siblingTable, treeNodeTableIndex)
  1700.    
  1701.     self:UpdateChildHeightsToRoot(treeNode)
  1702. end
  1703.  
  1704. function QuestTracker:ReleaseCategoryNode(categoryNode)
  1705.     local tree              = self.navigationTree
  1706.     local rootNode          = tree.rootNode
  1707.     local rootChildren      = rootNode.children
  1708.    
  1709.     -- Reanchor around the node to be removed
  1710.     self:AnchorPreviousNodeToNextNode(categoryNode)
  1711.    
  1712.     -- release all of the quest nodes
  1713.     self:ReleaseAllCategoryQuestNodes(categoryNode)
  1714.    
  1715.     -- Release all node objects, for the category node
  1716.     local categorytObjectPool = tree.templateInfo["QuestTrackerCategoryNode"].objectPool
  1717.     self:ReleaseNodeObjects(categoryNode, categorytObjectPool)
  1718.    
  1719.     self:UpdateChildHeightsToRoot(rootNode)
  1720. end
  1721.  
  1722. -- release all of the quest nodes,
  1723. function QuestTracker:ReleaseAllCategoryQuestNodes(categoryNode)
  1724.     local categoryChildren = categoryNode.children
  1725.    
  1726.     -- children can be nil if no quests, so check it first
  1727.     if type(categoryChildren) == "table" then
  1728.         for k,questNode in pairs(categoryChildren) do
  1729.             self:ReleaseQuestNode(questNode)
  1730.         end
  1731.     end
  1732.     -- nil the child table & update heights to root
  1733.     categoryNode.children = nil
  1734.     self:UpdateChildHeightsToRoot(categoryNode)
  1735. end
  1736.  
  1737. -- release all of the condition nodes, can be nil if no conditions
  1738. function QuestTracker:ReleaseAllQuestConditionNodes(questNode)
  1739.     local questConditions = questNode.children
  1740.    
  1741.     -- children can be nil if no quests, so check it first
  1742.     if type(questConditions) == "table" then
  1743.         for k,conditionNode in pairs(questConditions) do
  1744.             self:ReleaseConditionNode(conditionNode)
  1745.         end
  1746.     end
  1747.     -- nil the child table & update heights to root
  1748.     questNode.children = nil
  1749.     self:UpdateChildHeightsToRoot(questNode)
  1750. end
  1751. --============ END TREE RELEASE NODE CODE ============================--
  1752.  
  1753.  
  1754. --========================================================--
  1755. --=================   XML CODE/Functions =================--
  1756. --========================================================--
  1757.  
  1758. --================================================================--
  1759. --==================== XML: Main Window Code  ====================--
  1760. --================================================================--
  1761. local function ResetAnchorPosition(self)
  1762.     local left = self:GetLeft()
  1763.     local top = self:GetTop()
  1764.     self:ClearAnchors()
  1765.     self:SetAnchor(TOPLEFT, nil, TOPLEFT, left, top)
  1766. end
  1767.  
  1768. local function QuestTracker_On_ResizeStop(self)
  1769.     QUESTTRACKER.svCurrent.mainWindow.width    = self:GetWidth()
  1770.     QUESTTRACKER.svCurrent.mainWindow.height    = self:GetHeight()
  1771.    
  1772.     QUESTTRACKER.questTreeWin:SetDimensionConstraints(CONSTRAINT_WIDTH, CONSTRAINT_HEIGHT, 0, 0)
  1773. end
  1774.  
  1775. local function QuestTracker_On_ResizeStart(self)
  1776.     local currentWidth  = self:GetWidth()
  1777.     local currentHeight = self:GetHeight()
  1778.    
  1779.     local autoSizeHeight    = QUESTTRACKER.svCurrent.mainWindow.autoWindowSizeHeight
  1780.     local autoSizeWidth     = QUESTTRACKER.svCurrent.mainWindow.autoWindowSizeWidth
  1781.    
  1782.     local minWidth  = autoSizeWidth  and currentWidth  or CONSTRAINT_WIDTH
  1783.     local maxWidth  = autoSizeWidth  and currentWidth  or 0
  1784.     local minHeight = autoSizeHeight and currentHeight or CONSTRAINT_HEIGHT
  1785.     local maxHeight = autoSizeHeight and currentHeight or 0
  1786.    
  1787.     QUESTTRACKER.questTreeWin:SetDimensionConstraints(minWidth, minHeight, maxWidth, maxHeight)
  1788. end
  1789.  
  1790. local function QuestTracker_On_MoveStop(self)
  1791.     QUESTTRACKER.svCurrent.mainWindow.offsetX = self:GetLeft()
  1792.     QUESTTRACKER.svCurrent.mainWindow.offsetY = self:GetTop()
  1793.     ResetAnchorPosition(self)
  1794. end
  1795.  
  1796. function QuestTracker_QuestTree_OnInitialized(self)
  1797.     self:SetHandler("OnResizeStart",    QuestTracker_On_ResizeStart)
  1798.     self:SetHandler("OnResizeStop",     QuestTracker_On_ResizeStop)
  1799.     self:SetHandler("OnMoveStop",       QuestTracker_On_MoveStop)
  1800. end
  1801.  
  1802. function QuestTracker:SetResizeHandleSize(autoResize)
  1803.     if autoResize then
  1804.         self.questTreeWin:SetResizeHandleSize(0)
  1805.         return
  1806.     end
  1807.     self.questTreeWin:SetResizeHandleSize(6)
  1808. end
  1809.  
  1810. --================================================================--
  1811. --=================== XML: Category Node Code  ===================--
  1812. --================================================================--
  1813. local function CategoryNode_OnMouseUp(self, button, upInside)
  1814.     if not upInside then return end
  1815.     ZO_TreeHeader_OnMouseUp(self, upInside)
  1816.    
  1817.     -- we only have to worry about closing category nodes when "Categories Only" exclusitivity is turned on.
  1818.     -- other code handles closing them when exclusive is set to "All"
  1819.     -- When a quest is selected by forceAssist, the questNode
  1820.     -- :OnSelected() [QuestNodeOnSelected() -> DeselectQuestNode()]
  1821.     -- handles closing category nodes for "Categories Only" exclusitivity
  1822.     if not QUESTTRACKER.svCurrent.nodeExclusitivity.categoryNodes then return end
  1823.    
  1824.     local tree          = QUESTTRACKER.navigationTree
  1825.     local rootChildren  = tree.rootNode.children
  1826.     local clickedNode   = self.node
  1827.    
  1828.     for _, categoryNode in pairs(rootChildren) do
  1829.         if categoryNode.open and not QUESTTRACKER:AreTreeNodesEqual(clickedNode, categoryNode) then
  1830.             tree:SetNodeOpen(categoryNode, false, USER_REQUESTED_OPEN)
  1831.         end
  1832.     end
  1833. end
  1834.  
  1835. function QuestTracker_CategoryNode_OnInitialized(self)
  1836.     self.icon           = self:GetNamedChild("Icon")
  1837.     self.iconHighlight  = self.icon:GetNamedChild("Highlight")
  1838.     self.text           = self:GetNamedChild("Text")
  1839.    
  1840.     -- do not try to change this & use SetHandler !!
  1841.     self.OnMouseUp      = CategoryNode_OnMouseUp
  1842. end
  1843.  
  1844. --=================================================================--
  1845. --===================== XML: Quest Node Code  =====================--
  1846. --=================================================================--
  1847. -- Used for special override of con color in quest nodes
  1848. -- ZO_SelectableLabel_OnInitialized(self, QuestTracker_QuestNode_GetTextColor),  instead of:
  1849. -- ZO_SelectableLabel_OnInitialized(self, ZO_QuestJournalNavigationEntry_GetTextColor)
  1850. function QuestTracker_QuestNode_GetTextColor(self)
  1851.     if self.selected then
  1852.         return GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_SELECTED)
  1853.     elseif self.mouseover  then
  1854.         return GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_HIGHLIGHT)     
  1855.     elseif QUESTTRACKER and QUESTTRACKER.svCurrent.overrideConColors then      
  1856.         return unpack(QUESTTRACKER.svCurrent.fontSettings.quests.color)    
  1857.     else
  1858.         return GetColorForCon(self.con)
  1859.     end
  1860. end
  1861.  
  1862. local function QuestNode_OnMouseUp(self, button, upInside)
  1863.     if not upInside then return end
  1864.    
  1865.     if button == MOUSE_BUTTON_INDEX_LEFT then
  1866.         local questIndex = self.node.data.questIndex
  1867.        
  1868.         ZO_TreeHeader_OnMouseUp(self, upInside)
  1869.        
  1870.         -- We don't need to fire self.node:OnSelected() it will cause a double call to OnSelected()
  1871.         -- Update the journal panel & force assist (which will fire the assist callback & call node:OnSelected())
  1872.         QUEST_JOURNAL_KEYBOARD:FocusQuestWithIndex(questIndex)
  1873.         FOCUSED_QUEST_TRACKER:ForceAssist(questIndex)
  1874.        
  1875.     elseif button == MOUSE_BUTTON_INDEX_RIGHT then
  1876.         ClearMenu()
  1877.         AddCustomMenuItem("Share Quest", function()
  1878.             local questIndex = self.node.data.questIndex
  1879.             ShareQuest(questIndex)
  1880.         end)
  1881.         AddCustomMenuItem("Show On Map", function()
  1882.             local questIndex = self.node.data.questIndex
  1883.             ZO_WorldMap_ShowQuestOnMap(questIndex)
  1884.         end)
  1885.         AddCustomMenuItem("Abandon Quest", function()
  1886.             local questIndex = self.node.data.questIndex
  1887.             AbandonQuest(questIndex)
  1888.         end)
  1889.         ShowMenu()
  1890.     end
  1891. end
  1892.  
  1893. local function QuestNode_OnMouseEnter(self)
  1894.     if not QUESTTRACKER.svCurrent.tooltips.show then return end
  1895.     if QUESTTRACKER.WINDOW_FRAGMENT:IsHidden() then return end
  1896.    
  1897.     local questIndex = self.node.data.questIndex
  1898.     QUESTTRACKER:ShowQuestTooltip(questIndex)
  1899. end
  1900.  
  1901. local function QuestNode_OnMouseExit(self)
  1902.     -- This is just to let you know, don't do this. Its not necessary.
  1903.     -- OnMouseEnter calls ShowQuestTooltip, which unregisters there, so by the time OnMouseExit gets called
  1904.     -- this update has already been unregistered.
  1905.     --EVENT_MANAGER:UnregisterForUpdate("QuestTrackerClearAutoTooltip")
  1906.     ClearTooltip(InformationTooltip)
  1907. end
  1908.  
  1909. function QuestTracker_QuestNode_OnInitialized(self)
  1910.     self.icon           = self:GetNamedChild("Icon")
  1911.     self.iconHighlight  = self.icon:GetNamedChild("Highlight")
  1912.     self.text           = self:GetNamedChild("Text")
  1913.  
  1914.     -- do not try to change this & use SetHandler !!
  1915.     self.OnMouseUp      = QuestNode_OnMouseUp
  1916.     self.OnMouseEnter   = QuestNode_OnMouseEnter
  1917.     self.OnMouseExit    = QuestNode_OnMouseExit
  1918. end
  1919.  
  1920. --================================================================--
  1921. --=================== XML: Lock/Unlock Buttons ===================--
  1922. --================================================================--
  1923. function QuestTracker_LockButton_OnMouseUp(self, button, upInside)
  1924.     if not upInside then return end
  1925.    
  1926.     QUESTTRACKER:SetLockState(false)
  1927. end
  1928.  
  1929. function QuestTracker_UnlockButton_OnMouseUp(self, button, upInside)
  1930.     if not upInside then return end
  1931.    
  1932.     QUESTTRACKER:SetLockState(true)
  1933. end
  1934.  
  1935. -------------------------------------------------------------------
  1936. --  OnAddOnLoaded  --
  1937. -------------------------------------------------------------------
  1938. local function OnAddOnLoaded(event, addonName)
  1939.     if addonName == ADDON_NAME then
  1940.         QUESTTRACKER = QuestTracker:New()
  1941.         -- Since QuestTracker_QuestNode_GetTextColor(...) is called from xml on initialization
  1942.         -- We must refresh the tree in case they have overridden the quest con colors
  1943.         -- to get it to update the quest con colors
  1944.         QUESTTRACKER.navigationTree:RefreshVisible()
  1945.     end
  1946. end
  1947.  
  1948. ---------------------------------------------------------------------
  1949. --  Register Events --
  1950. ---------------------------------------------------------------------
  1951. EVENT_MANAGER:RegisterForEvent(ADDON_NAME, EVENT_ADD_ON_LOADED, OnAddOnLoaded)
  1952.  
  1953. ---------------------------------------------------------------------
  1954. --  Slash Commands --
  1955. ---------------------------------------------------------------------
  1956. --SLASH_COMMANDS["/QuestTracker"]       = QuestTracker_ToggleMainWindow
  1957.  
  1958. --[[
  1959. SLASH_COMMANDS["/qto"] = function()
  1960.     if QUESTTRACKER.svCurrent.nodeExclusitivity.currentSetting ~= "None" then
  1961.         local darkOrange = "FFA500"
  1962.         local msg = zo_strformat("|c<<1>><<2>>:|r <<3>>", darkOrange, "QUESTTRACKER", "AutoClose must be turned OFF for open nodes to work")
  1963.         d(msg)
  1964.         return
  1965.     end
  1966.     QUESTTRACKER:OpenAllQuestNodes()
  1967. end
  1968. --]]
  1969.  
  1970. -- Toggle window visible
  1971. SLASH_COMMANDS["/qth"] = QuestTracker_ToggleWindow
  1972.  
  1973. -- Toggle Quests open/close
  1974. SLASH_COMMANDS["/qta"] = function()
  1975. --
  1976.     if QUESTTRACKER.svCurrent.nodeExclusitivity.currentSetting ~= "None" then
  1977.         local darkOrange = "FFA500"
  1978.         local msg = zo_strformat("|c<<1>><<2>>:|r <<3>>", darkOrange, "QUESTTRACKER", "AutoClose must be turned OFF for open nodes to work")
  1979.         d(msg)
  1980.         return
  1981.     else
  1982. --]]
  1983.         if QUESTTRACKER.svCurrent.autoOpenNodes then
  1984.             QUESTTRACKER.svCurrent.autoOpenNodes = false
  1985.             QUESTTRACKER:CloseAllQuestNodes()
  1986.         else
  1987.             QUESTTRACKER.svCurrent.autoOpenNodes = true
  1988.             QUESTTRACKER:OpenAllQuestNodes()
  1989.         end
  1990.     end
  1991. end
  1992.  
  1993. -- Toggle lock/unlock window
  1994. SLASH_COMMANDS["/qtl"] = function()
  1995.     local lock = false 
  1996.     if QUESTTRACKER.svCurrent.mainWindow.locked then
  1997.         QUESTTRACKER.svCurrent.mainWindow.locked = false
  1998.         lock = false
  1999.     else QUESTTRACKER.svCurrent.mainWindow.locked = true
  2000.         lock = true
  2001.     end        
  2002.     QuestTracker:SetLockState(lock)
  2003. end
  2004.  
  2005. -- Open all Quests in selected category and collapse all others.
  2006. SLASH_COMMANDS["/qts"] = function()
  2007.     QuestTracker:CloseAllCategoryNodes()
  2008.     QUESTTRACKER:OpenSelectedCategoryQuestNodes()
  2009.     QUESTTRACKER.navigationTree:RefreshVisible()
  2010. end
  2011.  
  2012. -- Help Menu
  2013. SLASH_COMMANDS["/qt"] = function(text)
  2014.     if not text or text == "" or text == "help" or text == "?" then
  2015.         d(colorRavalox.."[QuestTracker]"..colorYellow.." Accepted Commands:")
  2016.         d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qt"..colorSoftYellow.." << shows this help")
  2017.         --d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qt list"..colorSoftYellow.." << lists all tracked quests")
  2018.         d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qt help"..colorSoftYellow.." << shows help")
  2019.         d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qt settings"..colorSoftYellow.." << shows QuestTracker settings menu")
  2020.         d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/questtracker"..colorSoftYellow.." << shows QuestTracker settings menu")
  2021.         d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qth"..colorSoftYellow.." << hide QuestTracker UI toggle")
  2022.         d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qta"..colorSoftYellow.." << Toggle open/close all quest nodes")
  2023.         d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qt1"..colorSoftYellow.." << Toggle lock/unlock QuestTracker window")
  2024.         d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qts"..colorSoftYellow.." << opens all quests in current category")
  2025.         --d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qt help abandon"..colorSoftYellow.." << shows abandon quest help")
  2026.         --d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qt help share"..colorSoftYellow.." << shows share quest help")
  2027.         --d(colorRavalox.."[QuestTracker]"..colorCMDBlue.."/qt help track"..colorSoftYellow.." << shows track quest help")
  2028.         --d(colorRavalox.."[QuestTracker]"..colorSoftYellow.." To EDIT White and Black lists, please edit your /SavedVariables/MQTuestTools.lua file.")
  2029.         return
  2030.     end
  2031.  
  2032.     if text == "settings" then
  2033.         local LAM2 = LibStub("LibAddonMenu-2.0")
  2034.         LAM2:OpenToPanel(QUESTTRACKER.addonPanel)
  2035.     end
  2036.  
  2037.     --[[  
  2038.         -- Slash commands to possibly support from Wykkyd's Version
  2039.         self:SlashCommand("qta", _addon.Abandon)        --Abandon a quest by index #  will show index list if # omitted
  2040.         self:SlashCommand("qtbl", _addon.BlackList)     --not sure
  2041.         self:SlashCommand("qts", _addon.Share)          --share a quest by index #  will show index list if # omitted
  2042.         self:SlashCommand("qtwl", _addon.WhiteList)     --not sure
  2043.         self:SlashCommand("qtt", _addon.Track)          --focus a specific quest (by index #)  qtt with no # will list index list
  2044.     --]]
  2045. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement