Advertisement
Guest User

Broker_Follower_Treasure

a guest
Apr 1st, 2015
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 59.98 KB | None | 0 0
  1. local addonName, addonTable = ...
  2. -- Debugging to tekDebug
  3. local debug = false
  4. --[===[@debug@
  5. debug = true
  6. --@end-debug@]===]
  7.  
  8. local name, _, _, enabled = GetAddOnInfo("tekDebug")
  9. local player = UnitName("player")
  10. local enabled = GetAddOnEnableState(player, "tekDebug") == 2
  11. if enabled and not IsAddOnLoaded("tekDebug") then
  12.   local succ, err = LoadAddOn(name)
  13. end
  14. local debugf = debug and tekDebug and tekDebug:GetFrame(addonName)
  15. local function DebugPrint(...) if debugf then debugf:AddMessage(string.join(", ", tostringall(...))) end end
  16.  
  17. local strfind, strformat, strgsub, strlower, strmatch, tostring = string.find, string.format, string.gsub, string.lower, strmatch, tostring
  18. local _, date, ipairs, next, pairs, select, time, tinsert, tsort, type, wipe = _, date, ipairs, next, pairs, select, time, table.insert, table.sort, type, wipe
  19.  
  20. -- LibDataBroker
  21. local ldb = LibStub:GetLibrary("LibDataBroker-1.1", true)
  22. local LDBIcon = ldb and LibStub("LibDBIcon-1.0",true)
  23. local LibQTip = LibStub('LibQTip-1.0')
  24. local Toast = LibStub("LibToast-1.0")
  25. local L = LibStub("AceLocale-3.0"):GetLocale(addonName, false)
  26. local BF = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceConsole-3.0", "AceEvent-3.0")
  27.  
  28. BF.versionString = GetAddOnMetadata(addonName, "Version");
  29.  
  30. if debug then
  31.   Broker_Followers = BF
  32. end
  33.  
  34. local ABILITY_MAX_NUM = 2
  35. local TRAIT_MAX_NUM   = 3
  36.  
  37.  
  38. local TOAST_FOLLOWER_UPGRADE = "BrokerFollowerUpgrade"
  39. local TOAST_FOLLOWER_LEVELUP = "BrokerFollowerLevelup"
  40.  
  41. -- Little helpers
  42.  
  43. local mechanics = {}
  44. local q = C_Garrison.GetFollowerAbilityCounterMechanicInfo
  45. for _, aid in pairs({11, 100, 168, 148, 160, 101, 105, 157, 122}) do
  46.   local mid, _, tex = q(aid)
  47.   mechanics[mid], mechanics[tex:lower():gsub("%.blp$","")] = aid, aid
  48. end
  49.  
  50. local function getMechanicTexture(mid, formatted)
  51.   if mechanics[mid] then
  52.     local tex = select(3, q(mechanics[mid]))
  53.     return formatted and strformat(BF.formatStrings.counterIconTolltip, tex) or tex
  54.   end
  55. end
  56.  
  57. local function getMechanicName(mid)
  58.   if mechanics[mid] then
  59.     return select(2, C_Garrison.GetFollowerAbilityCounterMechanicInfo(mechanics[mid]))
  60.   end
  61. end
  62.  
  63. local function getFormattedName(q, n)
  64.   return strformat(BF.formatStrings.rarityColors[q], n)
  65. end
  66.  
  67.  
  68. local DB_VERSION = 1
  69. BF.followerList = {}
  70. BF.collectedFollowersList = {}
  71. BF.formatStrings = {
  72.   rarityColors = {},
  73. }
  74. BF.specs = {
  75.   [2] = {
  76.     1, 2, 7, 8, 10, --Blood Death Knight
  77.   },
  78.   [3] = {
  79.     1, 4, 7, 8, 10, --Frost Death Knight
  80.   },
  81.   [4] = {
  82.     1, 2, 7, 8, 10, --Unholy Death Knight
  83.   },
  84.   [5] = {
  85.     6, 7, 9, 10, --Balance Druid
  86.   },
  87.   [7] = {
  88.     1, 2, 6, 10, --Feral Druid
  89.   },
  90.   [8] = {
  91.     1, 2, 6, 9, --Guardian Druid
  92.   },
  93.   [9] = {
  94.     3, 4, 7, 9, --Restoration Druid
  95.   },
  96.   [10] = {
  97.     1, 6, 7, 9, 10, --Beast Master Hunter
  98.   },
  99.   [12] = {
  100.     6, 7, 8, 9, 10, --Marksmanship Hunter
  101.   },
  102.   [13] = {
  103.     2, 6, 7, 9, 10, --Survival Hunter
  104.   },
  105.   [14] = {
  106.     6, 8, 9, 10, --Arcane Mage
  107.   },
  108.   [15] = {
  109.     6, 7, 8, 9, 10, --Fire Mage
  110.   },
  111.   [16] = {
  112.     2, 7, 8, 9, 10, --Frost Mage
  113.   },
  114.   [17] = {
  115.     1, 2, 3, 6, 9, --Brewmaster Monk
  116.   },
  117.   [18] = {
  118.     3, 4, 6, 8, --Mistweaver Monk
  119.   },
  120.   [19] = {
  121.     1, 6, 8, 9, 10, --Windwalker Monk
  122.   },
  123.   [20] = {
  124.     3, 4, 8, 9, --Holy Paladin
  125.   },
  126.   [21] = {
  127.     1, 2, 4, 8, 9, --Protection Paladin
  128.   },
  129.   [22] = {
  130.     2, 7, 8, 9, 10, --Retribution Paladin
  131.   },
  132.   [23] = {
  133.     3, 4, 6, 9, --Discipline Priest
  134.   },
  135.   [24] = {
  136.     3, 4, 6, 7, --Holy Priest
  137.   },
  138.   [25] = {
  139.     4, 6, 7, 9, 10, --Shadow Priest
  140.   },
  141.   [26] = {
  142.     2, 6, 8, 9, 10, --Assassination Rogue
  143.   },
  144.   [27] = {
  145.     6, 7, 8, 9, 10, --Combat Rogue
  146.   },
  147.   [28] = {
  148.     2, 6, 7, 8, 9, --Subtlety Rogue
  149.   },
  150.   [29] = {
  151.     3, 7, 8, 9, 10, --Elemental Shaman
  152.   },
  153.   [30] = {
  154.     3, 6, 7, 9, 10, --Enhancement Shaman
  155.   },
  156.   [31] = {
  157.     3, 4, 7, 8, --Restoration Shaman
  158.   },
  159.   [32] = {
  160.     4, 7, 8, 9, 10, --Affliction Warlock
  161.   },
  162.   [33] = {
  163.     2, 7, 8, 10, 10, --Demonology Warlock
  164.   },
  165.   [34] = {
  166.     3, 8, 9, 10, 10, --Destruction Warlock
  167.   },
  168.   [35] = {
  169.     1, 6, 7, 8, 10, --Arms Warrior
  170.   },
  171.   [37] = {
  172.     2, 6, 7, 8, 10, --Fury Warrior
  173.   },
  174.   [38] = {
  175.     1, 2, 6, 7, 8, --Protection Warrior
  176.   },
  177. }
  178.  
  179. -- specSets, each specs is a setc of [counter#] = true
  180.  
  181. BF.specSets = {}
  182. for specID, specData in pairs(BF.specs) do
  183.   BF.specSets[specID] = {}
  184.   for _, counterID in pairs(specData) do
  185.     BF.specSets[specID][counterID] = true
  186.   end
  187. end
  188.  
  189. local defaults = {
  190.   profile = {
  191.     version = 1,
  192.     autoHideDelay             = 0.5,
  193.     availableCountersToolstip = true,
  194.     showRerollPercent         = true,
  195.     showNewComboPercent       = true,
  196.     showMarkInactive          = "X",
  197.     showInactivesList         = true,
  198.     clickableList             = true,
  199.     iconSize                  = 16,
  200.     clickToShow               = 2,
  201.     tooltipBGColor            = { r=0, g=0, b=0, a=1 },
  202.     colorMatrix               = true,
  203.     showMountScavnerRowMatrix = false,
  204.     clickableMatrix           = true,
  205.     onlyFillTopMatrixHalf     = false,
  206.     showInactivesMatrix       = true,
  207.     showToasts                = true,
  208.     -- rerollfinder
  209.     rerollFirstWanted  = 1,
  210.     rerollSecondWanted = 2,
  211.     minimapIcon = {
  212.       hide = false,
  213.       minimapPos = 220,
  214.       radius = 80,
  215.     },
  216.   },
  217.   global = {
  218.     version = 1,
  219.   },
  220. }
  221.  
  222. -- Options Handling
  223.  
  224. function BF:GenerateOptions()
  225.   if not BF.options then
  226.  
  227.     local function newCounter()
  228.       local i = 0
  229.       return function( inc )
  230.           i = i + 1
  231.           return i
  232.         end
  233.     end
  234.     local count = newCounter()
  235.  
  236.     BF.options = {
  237.       name = addonName,
  238.       type = 'group',
  239.       handler = BF,
  240.       args = {
  241.         versionsString = {
  242.           name = BF.versionString,
  243.           order = -1,
  244.           type = "description"
  245.         },
  246.         genconfig = {
  247.           name = L["General Settings"],
  248.           type = 'group',
  249.           order = 1,
  250.           get = function(info) return BF.db.profile[info[#info]] end,
  251.           set = function(info, value) BF.db.profile[info[#info]] = value end,
  252.           args = {
  253.             clickToShow = {
  254.               type = "select",
  255.               style = "dropdown",
  256.               values = {
  257.                 [1] = L["Click"],
  258.                 [2] = L["Hover"],
  259.               },
  260.               name = L["Show tooltip on:"],
  261.               desc = L["Either make the tooltip pop up when you hover the icon or make it a toggle by clicking the icon"],
  262.               order = count(),
  263.             },
  264.             autoHideDelay = {
  265.               type = "range",
  266.               min = 0,
  267.               softMax = 3,
  268.               name = L["Auto hide delay"],
  269.               desc = L["When 'Show tooltip' is set to 'hover' then the tooltip stay for this amount of time after the mouse was moved away"],
  270.               order = count(),
  271.             },
  272.             availableCountersToolstip = {
  273.               type = "toggle",
  274.               name = L["Follower Hovertooltip"],
  275.               desc = L["When hovering over the followerporait in the follower tab or while recruiting in the inn then display small tooltip with all available counters for this follower"],
  276.               order = count(),
  277.             },
  278.             showToasts = {
  279.               type = "toggle",
  280.               name = L["Show Toasts"],
  281.               desc = L["Show toasts to inform you of follower level ups and upgrades. Upgrade toasts will tell you what ability/trait the follower gained."],
  282.               order = count(),
  283.             },
  284.             iconSize = {
  285.               type = "range",
  286.               min = 4,
  287.               max = 128,
  288.               step = 1,
  289.               name = L["Tooltip: Icon size"],
  290.               order = count(),
  291.               set = function(info, value)
  292.                 BF.db.profile[info[#info]] = value
  293.                 BF.formatStrings.counterIconTolltip = "|T%s:"..value..":"..value..":0:0:64:64:5:59:5:59|t"
  294.                 BF:RedrawTooltip()
  295.               end,
  296.             },
  297.             tooltipBGColor = {
  298.               name = L["Background color"],
  299.               desc = L["Background color"],
  300.               type = 'color',
  301.               order = count(),
  302.               get  = function(info)
  303.                 return BF.db.profile[info[#info]].r, BF.db.profile[info[#info]].g, BF.db.profile[info[#info]].b, BF.db.profile[info[#info]].a
  304.               end,
  305.               set  = function(info, r, g, b, a)
  306.                 BF.db.profile[info[#info]] = { r = r, g = g, b = b, a = a }
  307.                 BF:RedrawTooltip()
  308.               end,
  309.               hasAlpha = true,
  310.             },
  311.             minimapIcon = {
  312.               type = "toggle",
  313.               name = L["Show minimap button"],
  314.               order = count(),
  315.               get = function(info) return not BF.db.profile.minimapIcon.hide end,
  316.               set = function(info, value)
  317.                 BF.db.profile.minimapIcon.hide = not value
  318.                 if value then
  319.                   LDBIcon:Show(addonName)
  320.                 else
  321.                   LDBIcon:Hide(addonName)
  322.                 end
  323.               end,
  324.             },
  325.             headerListViewOption = {
  326.               type = "header",
  327.               name = L["List view options"],
  328.               order = count(),
  329.             },
  330.             clickableList=  {
  331.               type = "toggle",
  332.               name = L["List: Clickable cells"],
  333.               desc = L["Clicking a followers name in the list will put it into the search box in the follower list"],
  334.               set = function(info, value)
  335.                 BF.db.profile[info[#info]] = value
  336.                 BF:RedrawTooltip()
  337.               end,
  338.               order = count(),
  339.             },
  340.             showRerollPercent = {
  341.               type = "toggle",
  342.               name = L["Reroll column"],
  343.               desc = L["In the list tooltip add a column at the front showing the % chance of getting a not-yet-acquired threat counter combination for epic followers when using a reroll certificate"],
  344.               set = function(info, value)
  345.                 BF.db.profile[info[#info]] = value
  346.                 BF:RedrawTooltip()
  347.               end,
  348.               order = count(),
  349.             },
  350.             showNewComboPercent = {
  351.               type = "toggle",
  352.               name = L["Follower upgrade %"],
  353.               desc = L["Use the Reroll column for non-epic followers to show the % of getting a new combination of threat counters"],
  354.               set = function(info, value)
  355.                 BF.db.profile[info[#info]] = value
  356.                 BF:RedrawTooltip()
  357.               end,
  358.               order = count(),
  359.             },
  360.             showInactivesList = {
  361.               type = "toggle",
  362.               name = L["Show Inactive followers"],
  363.               set = function(info, value)
  364.                 BF.db.profile[info[#info]] = value
  365.                 BF:RedrawTooltip()
  366.               end,
  367.               order = count(),
  368.             },
  369.             showMarkInactive = {
  370.               type = "input",
  371.               name = L["Mark inactive with"],
  372.               desc = L["Add the following after the name of incative followers in listview"],
  373.               set = function(info, value)
  374.                 BF.db.profile[info[#info]] = value
  375.                 BF:RedrawTooltip()
  376.               end,
  377.               order = count(),
  378.             },
  379.             headerMatrixViewOption = {
  380.               type = "header",
  381.               name = L["Matrix view options"],
  382.                order = count(),
  383.             },
  384.             showInactivesMatrix = {
  385.               type = "toggle",
  386.               name = L["Count Inactives"],
  387.               desc = L["Also count inactive followers in matrix view"],
  388.               set = function(info, value)
  389.                 BF.db.profile[info[#info]] = value
  390.                 BF:RedrawTooltip()
  391.               end,
  392.               order = count(),
  393.             },
  394.             colorMatrix = {
  395.               type = "toggle",
  396.               name = L["Color followers"],
  397.               desc = L["Color followers in the matrix view by itemlevel. (615+: Green, 630+: Blue, 645+: Epic)"],
  398.               set = function(info, value)
  399.                 BF.db.profile[info[#info]] = value
  400.                 BF:RedrawTooltip()
  401.               end,
  402.               order = count(),
  403.             },
  404.             showMountScavnerRowMatrix = {
  405.               type = "toggle",
  406.               name = L["Scavenger/Mount row"],
  407.               desc = L["Show a special row at the top indicating if you got a follower with scavanger/epic mount countering this threat"],
  408.               set = function(info, value)
  409.                 BF.db.profile[info[#info]] = value
  410.                 BF:RedrawTooltip()
  411.               end,
  412.               order = count(),
  413.             },
  414.             onlyFillTopMatrixHalf = {
  415.               type = "toggle",
  416.               name = L["Matrix: Top right only"],
  417.               desc = L["Only fill the top right half of the matrix without mirroring the values onto the bottom left part as well"],
  418.               set = function(info, value)
  419.                 BF.db.profile[info[#info]] = value
  420.                 BF:RedrawTooltip()
  421.               end,
  422.               order = count(),
  423.             },
  424.             clickableMatrix =  {
  425.               type = "toggle",
  426.               name = L["Matrix: Clickable cells"],
  427.               desc = L["When a cell in the matrix is clicken it will print the list of followers that correpsond to it"],
  428.               set = function(info, value)
  429.                 BF.db.profile[info[#info]] = value
  430.                 BF:RedrawTooltip()
  431.               end,
  432.               order = count(),
  433.             },
  434.           },
  435.         },
  436.         rerollfinder =  {
  437.           name = L["Reroll Finder Settings"],
  438.           type = 'group',
  439.           order = 2,
  440.           get = function(info) return BF.db.profile[info[#info]] end,
  441.           set = function(info, value) BF.db.profile[info[#info]] = value end,
  442.           args = {
  443.             generateRerollListHeader = {
  444.               type = "description",
  445.               name = L["Generate a list of follower who have the highest chance of getting the following counters when rerolling"],
  446.               order = count(),
  447.             },
  448.             rerollFirstWanted = {
  449.               type = "select",
  450.               style = "dropdown",
  451.               values = {},
  452.               set = function(info, value)
  453.                 BF.db.profile[info[#info]] = value
  454.                 BF.options.args.rerollfinder.args[info[#info]].name = L["First Counter:"]..getMechanicTexture(BF.db.profile[info[#info]], true)
  455.                 BF:GenerateRerollFinderList()
  456.               end,
  457.               get = function(info)
  458.                 BF.options.args.rerollfinder.args[info[#info]].name = L["First Counter:"]..getMechanicTexture(BF.db.profile[info[#info]], true)
  459.                 BF:GenerateRerollFinderList()
  460.                 return BF.db.profile[info[#info]]
  461.               end,
  462.               name = L["First Counter:"]..getMechanicTexture(BF.db.profile.rerollFirstWanted, true),
  463.               desc = L["First of the two counters you want to reroll towards"],
  464.               order = count(),
  465.             },
  466.             rerollSecondWanted = {
  467.               type = "select",
  468.               style = "dropdown",
  469.               values = {},
  470.               set = function(info, value)
  471.                 BF.db.profile[info[#info]] = value
  472.                 BF.options.args.rerollfinder.args[info[#info]].name = L["Second Counter:"]..getMechanicTexture(BF.db.profile[info[#info]], true)
  473.                 BF:GenerateRerollFinderList()
  474.               end,
  475.               get = function(info)
  476.                 BF.options.args.rerollfinder.args[info[#info]].name = L["Second Counter:"]..getMechanicTexture(BF.db.profile[info[#info]], true)
  477.                 BF:GenerateRerollFinderList()
  478.                 return BF.db.profile[info[#info]]
  479.               end,
  480.               name = L["Second Counter:"]..getMechanicTexture(BF.db.profile.rerollSecondWanted, true),
  481.               desc = L["Second of the two counters you want to reroll towards"],
  482.               order = count(),
  483.             },
  484.             rerollHeader1= {
  485.               type = "header",
  486.               name = L["Output"],
  487.               order = count(),
  488.             },
  489.             rerollList = {
  490.               type = "description",
  491.               name = "",
  492.               fontSize = "medium",
  493.               width = "full",
  494.               order = count(),
  495.             },
  496.           },
  497.         },
  498.       },
  499.     }
  500.     for i=1,10 do
  501.       local name = getMechanicName(i)
  502.       if name then
  503.         BF.options.args.rerollfinder.args.rerollFirstWanted.values[i]  = name
  504.         BF.options.args.rerollfinder.args.rerollSecondWanted.values[i] = name
  505.       end
  506.     end
  507.     BF.options.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(BF.db)
  508.     BF.options.args.profile.order = 3
  509.   end
  510.   return BF.options
  511. end
  512.  
  513. function BF:ReleaseTooltip()
  514.   LibQTip:Release(self.tooltip)
  515.   self.tooltip.Columns = nil
  516.   self.tooltip.Rows = nil
  517.   self.tooltip = nil
  518. end
  519.  
  520. function BF:PrepareTooltip(anchorFrame, tableInsteadOfList)
  521.   local tooltip = LibQTip:Acquire("Broker_Followers_Tooltip", 1, "LEFT")
  522.   if tooltip:IsShown() then
  523.     tableInsteadOfList = self.matrixIsUsed
  524.   end
  525.   self.tooltip = tooltip
  526.   self:DrawTooltip(tooltip, tableInsteadOfList)
  527.   tooltip:SmartAnchorTo(anchorFrame)
  528.   tooltip:Show()
  529. end
  530.  
  531. function BF:RedrawTooltip()
  532.   -- Check if we actually view matrix tooltip
  533.   local tooltip = LibQTip:Acquire("Broker_Followers_Tooltip", 1, "LEFT")
  534.   -- Only redraw if the tooltip is shown
  535.   if not tooltip:IsShown() then
  536.     return
  537.   end
  538.  
  539.   self.tooltip = tooltip
  540.   self:DrawTooltip(tooltip, self.matrixIsUsed)
  541. end
  542.  
  543. function BF:DrawTooltip(tooltip, tableInsteadOfList)
  544.   self:UpdateFollowerCounters()
  545.   self:UpdateRerollCombos()
  546.  
  547.   tooltip:Clear()
  548.  
  549.   tooltip:SetBackdropColor(self.db.profile.tooltipBGColor.r, self.db.profile.tooltipBGColor.g, self.db.profile.tooltipBGColor.b, self.db.profile.tooltipBGColor.a)
  550.   tooltip.Rows    = {}
  551.  
  552.   local function sortFollowers(f1, f2)
  553.     local f1a, f2a = BF.collectedFollowersList[f1.followerID], BF.collectedFollowersList[f2.followerID]
  554.     if f1.isCollected and f2.isCollected  then
  555.       for _,i in pairs({1,2,3,4,6,7,8,9,10}) do
  556.         if f1a[i] and not f2a[i] then
  557.           return true
  558.         end
  559.         if not f1a[i] and f2a[i] then
  560.           return false
  561.         end
  562.       end
  563.       return f1.name < f2.name
  564.     else
  565.       if not f1.isCollected and not f2.isCollected then
  566.         return f1.name > f2.name
  567.       else
  568.         return f1.isCollected
  569.       end
  570.     end
  571.   end
  572.  
  573.   local function sortAbilities(a1, a2)
  574.     if not a1.isTrait and a2.isTrait  then
  575.       return true
  576.     end
  577.     if a1.isTrait and  not a2.isTrait  then
  578.       return false
  579.     end
  580.     local a1c = next(a1.counters)
  581.     local a2c = next(a2.counters)
  582.     if a1.isTrait and a2.isTrait  then
  583.       if a1c or a2c then
  584.         return (a1c or 0) > (a2c or 0)
  585.       else
  586.         return a1.name > a2.name
  587.       end
  588.     end
  589.     a1c = next(a1.counters)
  590.     a2c = next(a2.counters)
  591.     return a1c < a2c
  592.   end
  593.   if not tooltip.Columns then
  594.     tooltip.Columns = {}
  595.   end
  596.   if not tooltip.Rows then
  597.     tooltip.Rows = {}
  598.   end
  599.   local function MyAddColumn(nameType, displayName)
  600.     if nameType then
  601.       if not displayName then
  602.         BF:Debug("MyAddColumn: missing displayName for", nameType)
  603.         displayName = nameType
  604.       end
  605.       if not formatFunc then
  606.         --formatFunc = CellFormat.Default
  607.       end
  608.  
  609.       if not tooltip.Columns[nameType] then
  610.         local colindex = tooltip:AddColumn("CENTER")
  611.         tooltip:SetCell(1, colindex, displayName)
  612.  
  613.         tooltip.Columns[nameType] = { col = colindex }
  614.       else
  615.         BF:Debug("a column already exists for", nameType)
  616.       end
  617.     end
  618.   end
  619.   local function AddSpanner(name, abbr, first, last)
  620.     -- TODO - can we, from the size of span and maybe the character count of
  621.     -- name make a guess as to whether we could use the name instead of Abbr?
  622.     if first <= last then
  623.       tooltip:SetCell(1, first, abbr, nil, nil, 1 + last - first)
  624.     end
  625.   end
  626.   local function openFollowerTabSearch( tooltip_cell, searchTerm )
  627.     local searchBox = GarrisonMissionFrameFollowers.SearchBox:IsVisible() and GarrisonMissionFrameFollowers.SearchBox or GarrisonLandingPage.FollowerList.SearchBox:IsVisible() and GarrisonLandingPage.FollowerList.SearchBox
  628.     if searchBox then
  629.       searchBox:SetText(searchTerm)
  630.       searchBox.clearText = searchTerm
  631.     end
  632.   end
  633.   local function displayFollowersWithCounter(tooltip_cell, counters )
  634.     local first, second = math.min(counters[1],counters[2]), math.max(counters[1],counters[2])
  635.     local list = tooltip.counterDualSum[first][second].list
  636.     if #list > 0 then
  637.       local formattedList = {}
  638.       for _, followerID in pairs(list) do
  639.         tinsert(formattedList, strformat("%s (%s%s)",
  640.                                          C_Garrison.GetFollowerLink(followerID),
  641.                                          BF:GetRerollPercentForSpec( C_Garrison.GetFollowerClassSpec( followerID )),
  642.                                          C_Garrison.GetFollowerStatus(followerID) == GARRISON_FOLLOWER_INACTIVE and string.format(self.formatStrings.rarityColors.red,GARRISON_FOLLOWER_INACTIVE) or ""
  643.                                          )
  644.                )
  645.       end
  646.       local displayString =  getMechanicTexture(first, true).."/"..
  647.                              getMechanicTexture(second, true)..": "..
  648.                              table.concat(formattedList,", ")
  649.       BF:Print(displayString)
  650.     end
  651.   end
  652.   local function openRerollFinderWith(tooltip_cell, counters )
  653.     BF.db.profile.rerollFirstWanted  = counters[1]
  654.     BF.db.profile.rerollSecondWanted = counters[2]
  655.     InterfaceOptionsFrame_OpenToCategory(BF.optionsFrame)
  656.     LibStub("AceConfigDialog-3.0"):SelectGroup(addonName, "rerollfinder")
  657.     BF:GenerateRerollFinderList()
  658.   end
  659.   colors = {
  660.     green = {r=0, g=1, b=0, a=1},
  661.     white = {r=1, g=1, b=1, a=1},
  662.     red = {r=1, g=0, b=0, a=1},
  663.  
  664.     lightGray = {r=(108/255), g=(115/255), b=(120/255), a=1},
  665.     green = {r=(32/255), g=(255/255), b=(32/255), a=1},
  666.     red = {r=(255/255), g=(25/255), b=(25/255), a=1},
  667.     yellow = {r=(255/255), g=(228/255), b=(0/255), a=1},
  668.  
  669.     --lightGray = {r=0.25, g=0.25, b=0.25, a=1},
  670.     darkGray = {r=0.1, g=0.1, b=0.1, a=1},
  671.     lineGrey = {r=(108/255), g=(115/255), b=(120/255), a=1},
  672.     --lightGray = {r=(82/255), g=(91/255), b=(97/255), a=1},
  673.   }
  674.   local function AddSeparator(tooltip)
  675.     tooltip:AddSeparator(1, colors.lineGrey.r, colors.lineGrey.g, colors.lineGrey.b, colors.lineGrey.a)
  676.   end
  677.  
  678.   local globaldb = self.db.global
  679.   local profiledb = self.db.profile
  680.  
  681.   if tableInsteadOfList then
  682.     self.matrixIsUsed = true
  683.     -- 9x9 table, each cell showing the number of follower who counters both
  684.     -- threats from column and row
  685.  
  686.     if tooltip:GetLineCount() == 0 then
  687.       tooltip.Rows["icon"] = tooltip.Rows["icon"] or tooltip:AddHeader()
  688.       tooltip.Rows["sum"]  = tooltip.Rows["sum"]  or tooltip:AddHeader()
  689.       if self.db.profile.showMountScavnerRowMatrix then
  690.         tooltip.Rows["scav"] = tooltip.Rows["scav"] or tooltip:AddHeader()
  691.         tooltip.Rows["epic"] = tooltip.Rows["epic"] or tooltip:AddHeader()
  692.         tooltip.Rows["treas"] = tooltip.Rows["treas"] or tooltip:AddHeader()  -- hier
  693.       end
  694.     end
  695.     MyAddColumn("icon","")
  696.  
  697.     -- Setup the tooltip: Add the textures to the cells of the first row and
  698.     -- column, "" all the other cells so we start with a clean matrix
  699.     for k=1,10 do
  700.       local tex = getMechanicTexture(k, true)
  701.       if tex then
  702.         local row = tooltip.Rows[k] or tooltip:AddHeader()
  703.         --AddSeparator(tooltip)
  704.         MyAddColumn(tostring(k))
  705.         tooltip:SetCell( tooltip.Rows["icon"], tooltip.Columns[tostring(k)].col, tex)
  706.         tooltip:SetCell( row, tooltip.Columns["icon"].col, tex)
  707.         tooltip.Rows[k] = row
  708.         for j=1,10 do
  709.           if tooltip.Columns[tostring(j)]then
  710.             tooltip:SetCell( tooltip.Rows[k], tooltip.Columns[tostring(j)].col, "")
  711.           end
  712.         end
  713.       end
  714.     end
  715.     local counterSum = {}
  716.     tooltip.counterDualSum = {}
  717.     local function addDualCounter( c1, c2, iLevel, followerData)
  718.       local first, second = math.min(c1,c2), math.max(c1,c2)
  719.       local quality = 1
  720.       if iLevel >= 615 then
  721.         quality = 2
  722.       end
  723.       if iLevel >= 630 then
  724.         quality = 3
  725.       end
  726.       if iLevel >= 645 then
  727.         quality = 4
  728.       end
  729.       tooltip.counterDualSum[first]     = tooltip.counterDualSum[first] or {}
  730.       tooltip.counterDualSum[first][second] = tooltip.counterDualSum[first][second] or {}
  731.       tooltip.counterDualSum[first][second].num     = ( tooltip.counterDualSum[first][second].num or 0 ) + 1
  732.       tooltip.counterDualSum[first][second].quality = math.max( tooltip.counterDualSum[first][second].quality or 0,  quality )
  733.       tooltip.counterDualSum[first][second].list    = tooltip.counterDualSum[first][second].list or {}
  734.       tinsert(tooltip.counterDualSum[first][second].list, followerData.followerID)
  735.     end
  736.  
  737.  
  738.     table.sort(self.followerList, sortFollowers)
  739.     local epicMountIcon = strformat(self.formatStrings.counterIconTolltip, C_Garrison.GetFollowerAbilityIcon(221))
  740.     local scavangerIcon = strformat(self.formatStrings.counterIconTolltip, C_Garrison.GetFollowerAbilityIcon(79))
  741.     local treasureIcon = strformat(self.formatStrings.counterIconTolltip, C_Garrison.GetFollowerAbilityIcon(256))
  742.     for _, followerData in pairs( self.followerList ) do
  743.       if followerData.isCollected and ( followerData.status ~= GARRISON_FOLLOWER_INACTIVE or self.db.profile.showInactivesMatrix ) then
  744.         local counters, index, counterID = {}, 1
  745.         counterID = self:GetFollowerAbilityCounterAtIndex(followerData.followerID, index)
  746.         local hasEpicMount, hasScavenger, hasTreasure = self:FollowerHasEpicMountScavenger(followerData.followerID)  -- hier
  747.  
  748.         while counterID do
  749.           tinsert(counters, counterID)
  750.           counterSum[counterID] = ( counterSum[counterID] or 0 ) + 1
  751.           tooltip:SetCell(tooltip.Rows["sum"], tooltip.Columns[tostring(counterID)].col, counterSum[counterID])
  752.           if self.db.profile.clickableMatrix then
  753.             tooltip:SetCellScript(tooltip.Rows["icon"], tooltip.Columns[tostring(counterID)].col, "OnMouseUp", openFollowerTabSearch, getMechanicName(counterID))
  754.           end
  755.           if self.db.profile.showMountScavnerRowMatrix then
  756.             if hasScavenger then
  757.               tooltip:SetCell(tooltip.Rows["scav"], tooltip.Columns[tostring(counterID)].col, scavangerIcon)
  758.             end
  759.             if hasEpicMount then
  760.               tooltip:SetCell(tooltip.Rows["epic"], tooltip.Columns[tostring(counterID)].col, epicMountIcon)
  761.             end
  762.             if hasTreasure then
  763.               tooltip:SetCell(tooltip.Rows["treas"], tooltip.Columns[tostring(counterID)].col, treasureIcon)  -- hier
  764.             end
  765.            
  766.           end
  767.           index = index+1
  768.           counterID = self:GetFollowerAbilityCounterAtIndex(followerData.followerID, index)
  769.         end
  770.  
  771.         if #counters > 1 then
  772.           addDualCounter( counters[1], counters[2], followerData.iLevel, followerData )
  773.         end
  774.       end
  775.     end
  776.  
  777.     local r,c
  778.     for r=1,9 do
  779.       for c=r+1,10 do
  780.         if tooltip.Rows[r] and tooltip.Columns[tostring(c)] then
  781.           if tooltip.counterDualSum[r] and tooltip.counterDualSum[r][c] then
  782.             local rData, formatedNumber = tooltip.counterDualSum[r][c]
  783.             if self.db.profile.colorMatrix then
  784.               formatedNumber = getFormattedName(rData.quality, rData.num)
  785.             else
  786.               formatedNumber = rData.num
  787.             end
  788.             tooltip:SetCell( tooltip.Rows[r], tooltip.Columns[tostring(c)].col, formatedNumber)
  789.             if self.db.profile.clickableMatrix then
  790.               tooltip:SetCellScript(tooltip.Rows[r], tooltip.Columns[tostring(c)].col, "OnMouseUp", displayFollowersWithCounter, {c, r})
  791.             end
  792.             if not self.db.profile.onlyFillTopMatrixHalf then
  793.               -- Mirror the matrix
  794.               tooltip:SetCell( tooltip.Rows[c], tooltip.Columns[tostring(r)].col, formatedNumber)
  795.               if self.db.profile.clickableMatrix then
  796.                 tooltip:SetCellScript( tooltip.Rows[c], tooltip.Columns[tostring(r)].col, "OnMouseUp", displayFollowersWithCounter, {r, c})
  797.               end
  798.             end
  799.           else
  800.             if self.db.profile.clickableMatrix then
  801.               tooltip:SetCell( tooltip.Rows[r], tooltip.Columns[tostring(c)].col, " ")
  802.               tooltip:SetCell( tooltip.Rows[c], tooltip.Columns[tostring(r)].col, " ")
  803.               tooltip:SetCellScript(tooltip.Rows[r], tooltip.Columns[tostring(c)].col, "OnMouseUp", openRerollFinderWith, {c, r})
  804.               tooltip:SetCellScript(tooltip.Rows[c], tooltip.Columns[tostring(r)].col, "OnMouseUp", openRerollFinderWith, {r, c})
  805.             end
  806.           end
  807.         end
  808.       end
  809.     end
  810.  
  811.     for r, cData in pairs(tooltip.counterDualSum) do
  812.       for c, rData in pairs(cData) do
  813.         local formatedNumber
  814.         if self.db.profile.colorMatrix then
  815.           formatedNumber = getFormattedName(rData.quality, rData.num)
  816.         else
  817.           formatedNumber = rData.num
  818.         end
  819.         tooltip:SetCell( tooltip.Rows[r], tooltip.Columns[tostring(c)].col, formatedNumber)
  820.         if self.db.profile.clickableMatrix then
  821.           tooltip:SetCellScript(tooltip.Rows[r], tooltip.Columns[tostring(c)].col, "OnMouseUp", displayFollowersWithCounter, {c, r})
  822.         end
  823.         if not self.db.profile.onlyFillTopMatrixHalf then
  824.           -- Mirror the matrix
  825.           tooltip:SetCell( tooltip.Rows[c], tooltip.Columns[tostring(r)].col, formatedNumber)
  826.           if self.db.profile.clickableMatrix then
  827.             tooltip:SetCellScript( tooltip.Rows[c], tooltip.Columns[tostring(r)].col, "OnMouseUp", displayFollowersWithCounter, {r, c})
  828.           end
  829.         end
  830.       end
  831.     end
  832.   else
  833.     self.matrixIsUsed = false
  834.     -- Tooltip: List of followers with 5 columns for counters/traits
  835.     tooltip:AddHeader()
  836.     table.sort( self.followerList, sortFollowers)
  837.  
  838.     if self.db.profile.showRerollPercent then
  839.       local rerollIcon =  strformat(self.formatStrings.counterIconTolltip, GetItemIcon(118354))
  840.       MyAddColumn("reroll")
  841.       tooltip:SetCell(1, tooltip.Columns["reroll"].col, rerollIcon)
  842.     end
  843.  
  844.     for i=1,ABILITY_MAX_NUM do
  845.       MyAddColumn("counter"..i,"")
  846.     end
  847.     AddSpanner("Threats", "vs", tooltip.Columns["counter1"].col, tooltip.Columns["counter"..ABILITY_MAX_NUM].col)
  848.     for i=1,TRAIT_MAX_NUM do
  849.       MyAddColumn("trait"..i,"")
  850.     end
  851.     AddSpanner("Traits", "Traits", tooltip.Columns["trait1"].col, tooltip.Columns["trait"..TRAIT_MAX_NUM].col)
  852.  
  853.     for _, followerData in pairs(  self.followerList ) do
  854.       if followerData.isCollected and
  855.         (self.db.profile.showInactivesList or followerData.status ~= GARRISON_FOLLOWER_INACTIVE) then
  856.         local row = tooltip:AddLine("")
  857.         local coloredName = getFormattedName(followerData.quality, followerData.name)
  858.         tooltip:SetCell(row, 1, strformat("%s%s (%d)",
  859.                                   (followerData.status == GARRISON_FOLLOWER_INACTIVE and self.db.profile.showMarkInactive or ""),
  860.                                   coloredName,
  861.                                   followerData.level == GARRISON_FOLLOWER_MAX_LEVEL and followerData.iLevel or followerData.level) )
  862.         if self.db.profile.clickableList then
  863.           tooltip:SetCellScript(row, 1, "OnMouseUp", openFollowerTabSearch, followerData.name)
  864.         end
  865.         local index, counters = 1, {}
  866.         local counter = self:GetFollowerAbilityCounterAtIndex(followerData.followerID, index)
  867.         while counter and index <= ABILITY_MAX_NUM do
  868.           tinsert(counters, counter)
  869.           index = index +1
  870.           counter = self:GetFollowerAbilityCounterAtIndex(followerData.followerID, index)
  871.         end
  872.         table.sort(counters)
  873.         for i=1,#counters do
  874.           tooltip:SetCell(row, tooltip.Columns["counter"..i].col, getMechanicTexture(counters[i], true) )
  875.         end
  876.  
  877.         if self.db.profile.showRerollPercent and
  878.            ( ( followerData.combo and self.reRollCombos[followerData.combo] > 1 ) or
  879.                self.db.profile.showNewComboPercent )then
  880.           local percent
  881.           if followerData.quality > 3 then
  882.             percent = self:GetRerollPercentForSpec( C_Garrison.GetFollowerClassSpec( followerData.followerID ) )
  883.           else
  884.             percent = self:GetFollowerUpgradePercent( followerData.followerID )
  885.           end
  886.           tooltip:SetCell(row, tooltip.Columns["reroll"].col, percent)
  887.         end
  888.  
  889.         index = 1
  890.         local traitID, traits = C_Garrison.GetFollowerTraitAtIndex(followerData.followerID, index), {}
  891.         while traitID > 0 and index <= TRAIT_MAX_NUM do
  892.           tinsert(traits, traitID)
  893.           index = index+1
  894.           traitID = C_Garrison.GetFollowerTraitAtIndex(followerData.followerID, index)
  895.         end
  896.         table.sort(traits)
  897.         for i=1,#traits do
  898.           tooltip:SetCell(row, tooltip.Columns["trait"..i].col, strformat(self.formatStrings.counterIconTolltip, C_Garrison.GetFollowerAbilityIcon(traits[i])) )
  899.         end
  900.       end
  901.     end
  902.   end
  903. end
  904.  
  905. --
  906.  
  907. function BF:FollowerXPChange(event, followerID, xpAward, oldXP, oldLevel, oldQuality)
  908.  
  909.   local name, displayID, level, quality, currXP, maxXP = C_Garrison.GetFollowerMissionCompleteInfo(followerID)
  910.   self.Debug(name, displayID, xpAward, oldXP, oldLevel, level, oldQuality, quality)
  911.  
  912.   if oldLevel ~= level then
  913.     -- Levelup
  914.     local replacements = {
  915.       ["lvl"]  = level,
  916.       ["name"] = getFormattedName(quality ,name),
  917.     }
  918.     local levelupString = string.gsub(L["%name% is now level %lvl%"], "%%(%w+)|?([^%%]*)%%",  function (s, default)
  919.       local key = tostring(s)
  920.       return replacements[key] or default
  921.     end)
  922.  
  923.     Toast:Spawn( TOAST_FOLLOWER_LEVELUP, levelupString )
  924.  
  925.     self:RedrawTooltip()
  926.   end
  927.   if oldQuality ~= quality then
  928.     -- Qualitiy upgrade
  929.  
  930.     local formatedToastStrings  = {}
  931.     local followerAbilitiesData = C_Garrison.GetFollowerAbilities(followerID)
  932.     local function getAcquiredString( abilityIndex )
  933.       local counterID, abilityName, abilityTexture = C_Garrison.GetFollowerAbilityCounterMechanicInfo(abilityIndex)
  934.       if not counterID then
  935.         -- It's (1)a trait and (2) one that does not actually counter stuff
  936.         -- e.g. Mount, +XP, Scavenger, Profession X
  937.         abilityName    = C_Garrison.GetFollowerAbilityName(abilityIndex)
  938.         abilityTexture = C_Garrison.GetFollowerAbilityIcon(abilityIndex)
  939.       end
  940.       local replacements, icon= {
  941.         ["name"] = abilityName,
  942.         ["icon"] = strformat(self.formatStrings.counterIconTolltip, abilityTexture),
  943.       }
  944.       local text = string.gsub(L["Acquired %name% (%icon%)"], "%%(%w+)|?([^%%]*)%%",  function (s, default)
  945.         local key = tostring(s)
  946.         return replacements[key] or default
  947.       end)
  948.       return text
  949.     end
  950.  
  951.  
  952.     local formatedToastStrings = {}
  953.     local counters = {}
  954.     tinsert(counters, self:GetFollowerAbilityCounterAtIndex(followerID, 1))
  955.  
  956.     -- Get icon for the ability the follower had since beginning
  957.     local replacements = {
  958.       ["name"] = getFormattedName(quality , name),
  959.       ["icon"] = getMechanicTexture(counters[1], true)
  960.     }
  961.     local firstTextLine = string.gsub("%name% (%icon%)", "%%(%w+)|?([^%%]*)%%",  function (s, default)
  962.       local key = tostring(s)
  963.       return replacements[key] or default
  964.     end)
  965.  
  966.     -- Name
  967.     tinsert(formatedToastStrings, firstTextLine)
  968.     if quality == 3 then
  969.       -- Green -> Blue
  970.       -- Gained C_Garrison.GetFollowerAbilities(followerID)[3]
  971.       tinsert(formatedToastStrings, getAcquiredString(C_Garrison.GetFollowerTraitAtIndex(followerID, 2)))
  972.     elseif quality == 4 then
  973.       -- Blue -> Epic
  974.       -- Determine if we got a new combination of counters
  975.       -- self.reRollCombos
  976.       tinsert(counters, self:GetFollowerAbilityCounterAtIndex(followerID, 2))
  977.       table.sort(counters)
  978.       tinsert(formatedToastStrings, getAcquiredString( C_Garrison.GetFollowerAbilityAtIndex(followerID, 2)))
  979.  
  980.       local combo = counters[1]+counters[2]/100
  981.       BF:Debug(name, counters[1], counters[2], combo, self.reRollCombos[combo] or "nil")
  982.       if not self.reRollCombos[combo] then
  983.         tinsert(formatedToastStrings, strformat( L["New epic combo: %s/%s"],
  984.           getMechanicTexture(counters[1], true) or "ERROR",
  985.           getMechanicTexture(counters[2], true) or "ERROR"
  986.         ))
  987.       end
  988.       tinsert(formatedToastStrings, getAcquiredString( C_Garrison.GetFollowerTraitAtIndex(followerID, 3)))
  989.     end
  990.     Toast:Spawn( TOAST_FOLLOWER_UPGRADE, table.concat(formatedToastStrings, "\n"))
  991.     self:RedrawTooltip()
  992.   end
  993. end
  994.  
  995. local function toastFollowerUpgrade(toast, text)
  996.   toast:SetTitle(L["Follower upgrade"])
  997.   toast:SetText(text)
  998. end
  999.  
  1000. local function toastFollowerLevelup(toast, text)
  1001.   toast:SetTitle(L["Follower levelup"])
  1002.   toast:SetText(text)
  1003. end
  1004.  
  1005. function BF:OnEnable()
  1006.   self:RegisterEvent("GARRISON_FOLLOWER_XP_CHANGED",  "FollowerXPChange")
  1007.   self:RegisterEvent("GARRISON_FOLLOWER_ADDED",       "RedrawTooltip")
  1008.   self:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE", "RedrawTooltip")
  1009.   self:RegisterEvent("GARRISON_FOLLOWER_REMOVED",     "RedrawTooltip")
  1010.   self:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE", "RedrawTooltip")
  1011.   self:RegisterEvent("GARRISON_UPDATE",               "UpdateTheFuckingFollowers")
  1012.   self:RegisterEvent("GARRISON_MISSION_NPC_OPENED",   "UpdateTheFuckingFollowers")
  1013. end
  1014.  
  1015. function BF:OnDisable()
  1016.   self:UnregisterEvent("GARRISON_FOLLOWER_XP_CHANGED"   )
  1017.   self:UnregisterEvent("GARRISON_FOLLOWER_ADDED"        )
  1018.   self:UnregisterEvent("GARRISON_FOLLOWER_LIST_UPDATE"  )
  1019.   self:UnregisterEvent("GARRISON_FOLLOWER_REMOVED"      )
  1020.   self:UnregisterEvent("GARRISON_UPDATE"                )
  1021.   self:UnregisterEvent("GARRISON_MISSION_NPC_OPENED"    )
  1022. end
  1023.  
  1024. ---- Parse Follower List
  1025.  
  1026. function BF:UpdateTheFuckingFollowers()
  1027.   self:Debug("GARRISON_UPDATE")
  1028.   self:UpdateFollowerCounters()
  1029.   self:UpdateRerollCombos()
  1030. end
  1031.  
  1032. function BF:UpdateFollowerCounters()
  1033.   self:Debug("UpdateFollowerCounters()")
  1034.   local followerData, counterID, followerAbilitiesData
  1035.   self.followerList = C_Garrison.GetFollowers()
  1036.   self.collectedFollowersList = {}
  1037.   for _, followerData in pairs( self.followerList ) do
  1038.     if followerData.isCollected then
  1039.       self.collectedFollowersList[followerData.followerID] = {}
  1040.       local index = 1
  1041.       local counter = self:GetFollowerAbilityCounterAtIndex(followerData.followerID, index)
  1042.       while counter do
  1043.         self.collectedFollowersList[followerData.followerID][counter] = true
  1044.         index = index+1
  1045.         counter = self:GetFollowerAbilityCounterAtIndex(followerData.followerID, index)
  1046.       end
  1047.     end
  1048.   end
  1049. end
  1050.  
  1051. function BF:FollowerHasEpicMountScavenger(id)
  1052.   -- C_Garrison.GetFollowerTraitAtIndex(id, i)
  1053.   -- 79 = Scavenger, 221 = Epic Mount
  1054.  
  1055.   local traitIndex, hasEpicMount, hasScavenger, hasTreasure, traidID = 1, false, false, false  -- hier
  1056.   traitID = C_Garrison.GetFollowerTraitAtIndex(id, traitIndex)
  1057.   while traitID > 0 do
  1058.     hasEpicMount = hasEpicMount or traitID == 221
  1059.     hasScavenger = hasScavenger or traitID == 79
  1060.     hasTreasure = hasTreasure or traitID == 256 -- hier
  1061.     traitIndex = traitIndex +1
  1062.     traitID = C_Garrison.GetFollowerTraitAtIndex(id, traitIndex)
  1063.   end
  1064.   return hasEpicMount, hasScavenger, hasTreasure, C_Garrison.GetFollowerAbilityIcon(221), C_Garrison.GetFollowerAbilityIcon(79), C_Garrison.GetFollowerAbilityIcon(256)
  1065. end
  1066.  
  1067. function BF:GetFollowerAbilityCounterAtIndex(id, index)
  1068.   local abilityID = C_Garrison.GetFollowerAbilityAtIndex(id, index)
  1069.   if abilityID > 0 then
  1070.     return ( C_Garrison.GetFollowerAbilityCounterMechanicInfo(abilityID) )
  1071.   else
  1072.     return nil
  1073.   end
  1074. end
  1075.  
  1076. function BF:UpdateRerollCombos()
  1077.   self:Debug("UpdateRerollCombos()")
  1078.   for c,_ in pairs(self.reRollCombos) do
  1079.     self.reRollCombos[c] = nil
  1080.   end
  1081.   for _, followerData in pairs( self.followerList ) do
  1082.     if followerData.isCollected then
  1083.       local counters = {}
  1084.       tinsert(counters, self:GetFollowerAbilityCounterAtIndex(followerData.followerID, 1))
  1085.       tinsert(counters, self:GetFollowerAbilityCounterAtIndex(followerData.followerID, 2))
  1086.       if #counters == 2 then
  1087.         table.sort(counters)
  1088.         local combo = counters[1]+counters[2]/100
  1089.         followerData.combo  = combo
  1090.         self.reRollCombos[combo] = ( self.reRollCombos[combo] or 0 ) +1
  1091.       end
  1092.     end
  1093.   end
  1094. end
  1095.  
  1096. ---- Enhancing the Inn Recruitment
  1097.  
  1098. function BF:EnhanceRecruitFrame()
  1099.   --if true then return end
  1100.   self:UpdateFollowerCounters()
  1101.   self:UpdateRerollCombos()
  1102.   local recruitFrame = GarrisonRecruitSelectFrame.FollowerSelection
  1103.   local followers = C_Garrison.GetAvailableRecruits();
  1104.   for i=1, 3 do
  1105.     recruitFrame["Recruit"..i].PortraitFrame:SetScript("OnEnter",
  1106.       function(portraitFrame)
  1107.         if not BF.db.profile.availableCountersToolstip then return end
  1108.         local tooltip = LibQTip:Acquire("Broker_Followers_EnhancementTooltip", 1, "RIGHT")
  1109.         BF.enhanceTooltip = tooltip
  1110.         BF:AdditionalAbilitesRecruitTooltip(tooltip, i)
  1111.         tooltip:SetPoint("RIGHT",portraitFrame,"LEFT")
  1112.         tooltip:Show()
  1113.       end
  1114.     )
  1115.     recruitFrame["Recruit"..i].PortraitFrame:SetScript("OnLeave",
  1116.       function()
  1117.         if not BF.db.profile.availableCountersToolstip then return end
  1118.         LibQTip:Release(BF.enhanceTooltip)
  1119.         BF.enhanceTooltip.Columns = nil
  1120.         BF.enhanceTooltip.Rows = nil
  1121.         BF.enhanceTooltip = nil
  1122.       end
  1123.     )
  1124.   end
  1125. end
  1126.  
  1127. hooksecurefunc("GarrisonRecruitSelectFrame_UpdateRecruits", function(waiting)
  1128.   if not waiting then
  1129.     BF:EnhanceRecruitFrame()
  1130.   end
  1131. end)
  1132.  
  1133. function BF:EnhanceFollowerTab( parentFrameName )
  1134.   local parentFrame = _G[parentFrameName]
  1135.   local followerTabPortrait = parentFrame.FollowerTab.PortraitFrame
  1136.   followerTabPortrait:SetScript("OnEnter",
  1137.     function(portraitFrame)
  1138.       local tooltip = LibQTip:Acquire("Broker_Followers_EnhancementTooltip", 1, "RIGHT")
  1139.       BF.enhanceTooltip = tooltip
  1140.       BF:AdditionalAbilitesTooltip(tooltip, portraitFrame:GetParent())
  1141.       tooltip:SetPoint("RIGHT",portraitFrame,"LEFT")
  1142.       tooltip:Show()
  1143.     end)
  1144.   followerTabPortrait:SetScript("OnLeave",
  1145.     function()
  1146.     LibQTip:Release(BF.enhanceTooltip)
  1147.     BF.enhanceTooltip = nil
  1148.   end )
  1149.  
  1150.   for i=1,9 do
  1151.     --GarrisonMissionFrameFollowersListScrollFrameButton1
  1152.     local btn = _G[parentFrameName.."FollowersListScrollFrameButton"..i] or _G[parentFrameName.."ListScrollFrameButton"..i]
  1153.     if btn then
  1154.       local pf = btn.PortraitFrame
  1155.       pf:SetScript("OnEnter",
  1156.         function(portraitFrame)
  1157.           local tooltip = LibQTip:Acquire("Broker_Followers_EnhancementTooltip", 1, "RIGHT")
  1158.           BF.enhanceTooltip = tooltip
  1159.           local btn = portraitFrame:GetParent()
  1160.           BF:AdditionalAbilitesTooltip(tooltip, btn.info)
  1161.           tooltip:SetPoint("RIGHT",portraitFrame,"LEFT")
  1162.           tooltip:Show()
  1163.         end)
  1164.       pf:SetScript("OnLeave",
  1165.         function()
  1166.         LibQTip:Release(BF.enhanceTooltip)
  1167.         BF.enhanceTooltip = nil
  1168.       end )
  1169.     end
  1170.   end
  1171. end
  1172.  
  1173. local function getSpec(followerID)
  1174.   if type(followerID) == "string" then
  1175.     return C_Garrison.GetFollowerClassSpec(followerID)
  1176.   else
  1177.     return C_Garrison.GetFollowerClassSpecByID(followerID)
  1178.   end
  1179. end
  1180.  
  1181. local function getAbilityAtIndex(followerID, index)
  1182.   if type(followerID) == "string" then
  1183.     return C_Garrison.GetFollowerAbilityAtIndex(followerID, index)
  1184.   else
  1185.     return C_Garrison.GetFollowerAbilityAtIndexByID(followerID, index)
  1186.   end
  1187. end
  1188.  
  1189. function BF:AdditionalAbilitesTooltip( tooltip, followerInfo)
  1190.   -- if not isCollected then we need to use ...ByID() functions instead
  1191.   local id = followerInfo.followerID
  1192.   local specID = getSpec(id)
  1193.   local possibleAbilities = self.specs[specID]
  1194.   -- 2 abilites? => Show the % of getting new on reroll
  1195.   -- else => Show % of getting new combo when upgrading to epic
  1196.   -- Is there a second ability?
  1197.   if getAbilityAtIndex(id,2) > 0 then
  1198.     for _, aid in pairs(possibleAbilities) do
  1199.       local tex = getMechanicTexture( aid, true )
  1200.       tooltip:AddHeader(tex)
  1201.     end
  1202.  
  1203.     tooltip:AddHeader(string.format(self.formatStrings.counterIconTolltip, GetItemIcon(118354)) .. self:GetRerollPercentForSpec( specID ) )
  1204.   else
  1205.     -- 1 ability => % of getting new combo is dependent on what we already got
  1206.     local pa = (C_Garrison.GetFollowerAbilityCounterMechanicInfo(getAbilityAtIndex(id,1)))
  1207.     for _, aid in pairs(possibleAbilities) do
  1208.       local tex = getMechanicTexture( aid, true )
  1209.       -- Only interested in the abilities that we can gain
  1210.       if aid ~= pa then
  1211.         local combo = math.min(aid,pa) + math.max(aid,pa)/100
  1212.         if self.reRollCombos[combo] then
  1213.           tooltip:AddHeader(string.format(self.formatStrings.rarityColors.red,self.reRollCombos[combo])..tex)
  1214.         else
  1215.           tooltip:AddHeader(string.format(self.formatStrings.rarityColors.green,"+")..tex)
  1216.         end
  1217.  
  1218.       end
  1219.     end
  1220.     tooltip:AddHeader(string.format(BF.formatStrings.counterIconTolltip, "Interface\\Buttons\\JumpUpArrow") .. self:GetFollowerUpgradePercent( id ) )
  1221.   end
  1222. end
  1223.  
  1224. function BF:AdditionalAbilitesRecruitTooltip( tooltip, index)
  1225.   -- Recruitment is different, followerID are not set yet, and they
  1226.   local followerData = C_Garrison.GetAvailableRecruits()[index]
  1227.   local id = followerData.followerID
  1228.   local specID = followerData.classSpec
  1229.   local possibleAbilities = self.specs[specID]
  1230.   -- Get the predetermined ability for the recruit
  1231.   local pa
  1232.   for _, ability in pairs( C_Garrison.GetRecruitAbilities( index ) ) do
  1233.     if not ability.isTrait then
  1234.       if pa then
  1235.         tooltip:AddHeader( "ERROR" )
  1236.         self:Debug("ERROR", "AdditionalAbilitesRecruitTooltip", index, pa)
  1237.       end
  1238.       pa = next( ability.counters )
  1239.     end
  1240.   end
  1241.   for _, aid in pairs(possibleAbilities) do
  1242.     local tex = getMechanicTexture( aid, true )
  1243.     -- Only interested in the abilities that we can gain
  1244.     if aid ~= pa then
  1245.       local combo = math.min(aid,pa) + math.max(aid,pa)/100
  1246.       if self.reRollCombos[combo] then
  1247.         tooltip:AddHeader(string.format(self.formatStrings.rarityColors.red,self.reRollCombos[combo])..tex)
  1248.       else
  1249.         tooltip:AddHeader(string.format(self.formatStrings.rarityColors.green,"+")..tex)
  1250.       end
  1251.  
  1252.     end
  1253.   end
  1254.   tooltip:AddHeader(string.format(BF.formatStrings.counterIconTolltip, "Interface\\Buttons\\JumpUpArrow") .. self:GetFollowerUpgradePercent( id, pa ) )
  1255. end
  1256.  
  1257. function BF:GetComboFromAbilities( first, second )
  1258.   if type(first) == "table" and #first == 2 then
  1259.     return math.min(first[1], first[2]) + math.max(first[1], first[2])/100
  1260.   elseif first and second then
  1261.     return math.min(first, second) + math.max(first, second)/100
  1262.   else
  1263.     -- Should error
  1264.     return 0.0
  1265.   end
  1266. end
  1267.  
  1268. function BF:GetRerollPercentForSpec( specID )
  1269.   local spec = self.specs[specID]
  1270.   local allCombos, wantedCombos = 0, 0
  1271.   if spec then
  1272.     for i=1,(#spec-1) do
  1273.       for j=i+1,#spec do
  1274.         local combo = self:GetComboFromAbilities(spec[i], spec[j])
  1275.         allCombos = allCombos +1
  1276.         if not self.reRollCombos[combo] then
  1277.           wantedCombos = wantedCombos+1
  1278.         end
  1279.       end
  1280.     end
  1281.   end
  1282.   local percentage = ( allCombos==0 ) and 0 or (  wantedCombos / allCombos * 100 )
  1283.   return math.floor(percentage).."%"
  1284. end
  1285.  
  1286.  
  1287. function BF:GetFollowerUpgradePercent( id, preset )
  1288.   local specID, allCombos, wantedCombos  = getSpec(id), 0, 0
  1289.   local spec = self.specs[specID]
  1290.   local aid = getAbilityAtIndex(id, 1)
  1291.   local presetCounter = preset or C_Garrison.GetFollowerAbilityCounterMechanicInfo(aid)
  1292.  
  1293.   local secondAbility = {}
  1294.   for k,s in pairs(spec) do
  1295.     if presetCounter and presetCounter ~= s then
  1296.       table.insert(secondAbility, s)
  1297.     end
  1298.   end
  1299.  
  1300.   for i=1,#secondAbility do
  1301.     local combo = self:GetComboFromAbilities(presetCounter, secondAbility[i])
  1302.     allCombos = allCombos +1
  1303.     if not self.reRollCombos[combo] then
  1304.       wantedCombos = wantedCombos+1
  1305.     end
  1306.   end
  1307.   local percentage = ( allCombos==0 ) and 0 or (  wantedCombos / allCombos * 100 )
  1308.   return math.floor(percentage).."%"
  1309. end
  1310. local lastRerollFinderCombo
  1311. function BF:GenerateRerollFinderList()
  1312.   local counters = {}
  1313.   tinsert(counters, self.db.profile.rerollFirstWanted )
  1314.   tinsert(counters, self.db.profile.rerollSecondWanted)
  1315.   if counters[1] == counters[2] then
  1316.     self.options.args.rerollfinder.args.rerollList.name= L["The two counters can't be of the same type"]
  1317.     LibStub("AceConfigRegistry-3.0"):NotifyChange(addonName)
  1318.     return
  1319.   end
  1320.  
  1321.  
  1322.   local ERROR_MESSAGES, dataIsWrong = {}
  1323.   -- It seems the wowhead guide has errors in it, so when going parsing all
  1324.   -- followers check if our data has a mismatches ingame  stuff
  1325.   tinsert(ERROR_MESSAGES, "!!! ERROR !!!")
  1326.   tinsert(ERROR_MESSAGES, "Wrong client data?")
  1327.  
  1328.   local wantedCombo = self:GetComboFromAbilities(counters)
  1329.   if wantedCombo == lastRerollFinderCombo then
  1330.     return
  1331.   end
  1332.   lastRerollFinderCombo = wantedCombo
  1333.   -- Lists of followers, down from most convinient:
  1334.   --    Has it  > Reroll to it > upgrade to epic (> upgrade + reroll)
  1335.   local hasCombo, rerollCombo,   upgradeCombo,    upgradeRerollCombo = {}, {}, {}, {}
  1336.   for _,f in pairs(self.followerList) do
  1337.     if f.isCollected then
  1338.       local c
  1339.       local aid = getAbilityAtIndex(f.followerID, 1)
  1340.       c = C_Garrison.GetFollowerAbilityCounterMechanicInfo(aid)
  1341.       if not BF.specSets[f.classSpec][c] then
  1342.         dataIsWrong = true
  1343.         tinsert(ERROR_MESSAGES, strformat("%s (%s) counters %s",
  1344.             getFormattedName(f.quality, f.name),
  1345.             f.className,
  1346.             getMechanicTexture(c, true)))
  1347.       end
  1348.       aid = getAbilityAtIndex(f.followerID, 2)
  1349.       if aid > 0 then
  1350.         c = C_Garrison.GetFollowerAbilityCounterMechanicInfo(aid)
  1351.         if not BF.specSets[f.classSpec][c] then
  1352.           dataIsWrong = true
  1353.           tinsert(ERROR_MESSAGES, strformat("%s (%s) counters %s",
  1354.               getFormattedName(f.quality, f.name),
  1355.               f.className,
  1356.               getMechanicTexture(c, true)))
  1357.         end
  1358.       end
  1359.  
  1360.       if self.specSets[f.classSpec][counters[1]] and
  1361.          self.specSets[f.classSpec][counters[2]] or wantedCombo == f.combo then
  1362.         -- Collected AND the spec can have the combo?
  1363.         -- We need name, quality, from how many counters we choose and the
  1364.         -- first counter for non-epic, if he can upgrade into the combo
  1365.         local dataNeeded = {}
  1366.         dataNeeded.quality      = f.quality
  1367.         dataNeeded.name         = f.name
  1368.         dataNeeded.status       = C_Garrison.GetFollowerStatus(f.followerID)
  1369.         dataNeeded.availCounter = #self.specs[f.classSpec]
  1370.         dataNeeded.reroll   = 0 -- Chance to get it on reroll
  1371.         dataNeeded.upgrade  = 0 -- Chance to get it on upgrade
  1372.         dataNeeded.counters = {}
  1373.         local aid = getAbilityAtIndex(f.followerID, 1)
  1374.         tinsert(dataNeeded.counters, (C_Garrison.GetFollowerAbilityCounterMechanicInfo(aid)))
  1375.         aid = getAbilityAtIndex(f.followerID, 2)
  1376.         if aid > 0 then
  1377.           tinsert(dataNeeded.counters, (C_Garrison.GetFollowerAbilityCounterMechanicInfo(aid)))
  1378.         end
  1379.  
  1380.         if f.quality == 4 then
  1381.           -- Epic follower
  1382.           if f.combo == wantedCombo then
  1383.             -- Has the combo already, no need to calculate anything
  1384.             tinsert(hasCombo, dataNeeded)
  1385.           else
  1386.             -- Can be rerolled to have the combo, choosing two out of
  1387.             -- .availCounter
  1388.             -- Does not take into acount that warlocks
  1389.             dataNeeded.reroll = ( 2 / dataNeeded.availCounter) * (1 / ( dataNeeded.availCounter - 1))*100
  1390.             tinsert(rerollCombo, dataNeeded)
  1391.           end
  1392.         else
  1393.           -- Non-epic follower, but the spec can have the combo
  1394.           -- Everyone has 1 ability
  1395.           if dataNeeded.counters[1] == counters[1] or dataNeeded.counters[1] == counters[2] then
  1396.             -- And we are already half-way there, so we need to get
  1397.             -- 1 from (available-1)
  1398.             dataNeeded.upgrade = 1 / ( dataNeeded.availCounter - 1)*100
  1399.             tinsert(upgradeCombo, dataNeeded)
  1400.           else
  1401.             -- Needs to upgrade and reroll!
  1402.             dataNeeded.reroll = ( 2 / dataNeeded.availCounter) * (1 / ( dataNeeded.availCounter - 1)) *100
  1403.             tinsert(upgradeRerollCombo, dataNeeded)
  1404.           end
  1405.         end
  1406.       end -- spec or wanted
  1407.     end -- is collected
  1408.   end -- pairs
  1409.  
  1410.   -- Ouput generation
  1411.   local formattedOutputStrings = {} -- output = table.concat(...,"\n")
  1412.   tinsert(formattedOutputStrings, L["Followers with this combo:"])
  1413.   if #hasCombo > 0 then
  1414.     local formattedFollowers = {}
  1415.     for _,data in pairs(hasCombo) do
  1416.       tinsert(formattedFollowers, getFormattedName(data.quality, data.name)..
  1417.                                   ( data.status == GARRISON_FOLLOWER_INACTIVE and ("("..string.format(self.formatStrings.rarityColors.red,GARRISON_FOLLOWER_INACTIVE)..")") or ""))
  1418.     end
  1419.     tinsert(formattedOutputStrings, table.concat(formattedFollowers, "\n"))
  1420.   else
  1421.     tinsert(formattedOutputStrings, L["None"])
  1422.   end
  1423.  
  1424.   tinsert(formattedOutputStrings, L["Epic followers who can be rerolled to this combo:"])
  1425.   if #rerollCombo > 0 then
  1426.     table.sort(rerollCombo, function(a,b) return a.reroll > b.reroll end)
  1427.     local formattedFollowers = {}
  1428.     for _,data in pairs(rerollCombo) do
  1429.       tinsert(formattedFollowers, strformat("%s %s/%s (%.1f%%%s)", getFormattedName(data.quality, data.name),
  1430.                                                                  getMechanicTexture(data.counters[1], true),
  1431.                                                                  getMechanicTexture(data.counters[2], true),
  1432.                                                                  data.reroll,
  1433.                                                                  data.status == GARRISON_FOLLOWER_INACTIVE and string.format(self.formatStrings.rarityColors.red,GARRISON_FOLLOWER_INACTIVE) or ""))
  1434.     end
  1435.     tinsert(formattedOutputStrings, table.concat(formattedFollowers, "\n"))
  1436.   else
  1437.     tinsert(formattedOutputStrings, L["None"])
  1438.   end
  1439.  
  1440.   tinsert(formattedOutputStrings, L["Non-epic followers who with a chance to get the combo when turning epic:"])
  1441.   if #upgradeCombo > 0 then
  1442.     table.sort(upgradeCombo, function(a,b) return a.upgrade > b.upgrade end)
  1443.     local formattedFollowers = {}
  1444.     for _,data in pairs(upgradeCombo) do
  1445.       tinsert(formattedFollowers, strformat("%s %s (%.1f%%%s)", getFormattedName(data.quality, data.name),
  1446.                                                               getMechanicTexture(data.counters[1], true),
  1447.                                                               data.upgrade,
  1448.                                                                data.status == GARRISON_FOLLOWER_INACTIVE and string.format(self.formatStrings.rarityColors.red,GARRISON_FOLLOWER_INACTIVE) or ""))
  1449.     end
  1450.     tinsert(formattedOutputStrings, table.concat(formattedFollowers, "\n"))
  1451.   else
  1452.     tinsert(formattedOutputStrings, L["None"])
  1453.   end
  1454.  
  1455.   tinsert(formattedOutputStrings, L["Non-epic followers who can be rerolled to have the combo after turning epic:"])
  1456.   if #upgradeRerollCombo > 0 then
  1457.     local formattedFollowers = {}
  1458.     table.sort(upgradeRerollCombo, function(a,b) return a.reroll > b.reroll end)
  1459.     for _,data in pairs(upgradeRerollCombo) do
  1460.       tinsert(formattedFollowers, strformat("%s %s (%.1f%%%s)", getFormattedName(data.quality, data.name),
  1461.                                                               getMechanicTexture(data.counters[1], true),
  1462.                                                               data.reroll,
  1463.                                                                  data.status == GARRISON_FOLLOWER_INACTIVE and string.format(self.formatStrings.rarityColors.red,GARRISON_FOLLOWER_INACTIVE) or ""))
  1464.     end
  1465.     tinsert(formattedOutputStrings, table.concat(formattedFollowers, "\n"))
  1466.   else
  1467.     tinsert(formattedOutputStrings, L["None"])
  1468.   end
  1469.  
  1470.   if dataIsWrong and debug then tinsert(formattedOutputStrings, table.concat(ERROR_MESSAGES, "\n")) end
  1471.   -- Make the options refresh with the list
  1472.   -- Here
  1473.   self.options.args.rerollfinder.args.rerollList.name =  table.concat(formattedOutputStrings, "\n")
  1474.   LibStub("AceConfigRegistry-3.0"):NotifyChange(addonName)
  1475. end
  1476.  
  1477. ---- Database Maintenance
  1478.  
  1479. function BF:MigrateSavedData()
  1480.   local  globaldb = self.db.global
  1481.   local profiledb = self.db.profile
  1482.  
  1483.   -- all db sections are current we can exit immediately
  1484.   if profiledb.version == DB_VERSION and
  1485.       globaldb.version == DB_VERSION then
  1486.     return
  1487.   else
  1488.     BF:Print(L["DB_VERSION_UPGRADE_PURGE"])
  1489.   end
  1490.  
  1491.   -- Migrating from before addon began keeping track of database changes
  1492.   --[[
  1493.   if globaldb.version < X then
  1494.     -- Upgrade from before version X
  1495.   end
  1496.   if profiledb.version < X then
  1497.     -- Upgrade from before version X
  1498.   end
  1499.   --]]
  1500.  
  1501.   profiledb.version = DB_VERSION
  1502.   globaldb.version = DB_VERSION
  1503. end
  1504.  
  1505. function BF:OnInitialize() -- ADDON_LOADED, only saved variables are guaranteed to be present
  1506.   self.db = LibStub("AceDB-3.0"):New("Broker_Follower_DB", defaults, true)
  1507.   self:MigrateSavedData()
  1508.  
  1509.   LibStub("AceConfig-3.0"):RegisterOptionsTable(addonName, self.GenerateOptions)
  1510.   self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions(addonName)
  1511.  
  1512.   self.BFLDB = ldb:NewDataObject(addonName, {
  1513.     type = "data source",
  1514.     text = "",
  1515.     icon = "Interface\\Icons\\inv_misc_lockboxghostiron",
  1516.     OnClick = function(clickedframe, button)
  1517.       if button == "RightButton" then
  1518.         InterfaceOptionsFrame_OpenToCategory(self.optionsFrame)
  1519.       else
  1520.         -- 1 = click2show
  1521.         -- 2 = hover2show
  1522.         if self.db.profile.clickToShow == 2 then
  1523.           self.db.profile.showInactivesMatrix = not self.db.profile.showInactivesMatrix
  1524.           self:PrepareTooltip(clickedframe, not IsShiftKeyDown())
  1525.         else
  1526.           -- Click 2 Show handling
  1527.           local tooltip = LibQTip:Acquire("Broker_Followers_Tooltip", 1, "LEFT")
  1528.           self.tooltip = tooltip
  1529.           self.tooltip:SetAutoHideDelay( nil )
  1530.           if tooltip:IsShown() then
  1531.             -- Tooltip is shown, hide it on click
  1532.             self:ReleaseTooltip()
  1533.           else
  1534.             -- No tooltip, show it on click
  1535.             self:PrepareTooltip(clickedframe, not IsShiftKeyDown())
  1536.           end
  1537.         end
  1538.       end
  1539.     end,
  1540.     OnEnter = function(enteredFrame)
  1541.       -- 1 = click2show
  1542.       -- 2 = hover2show
  1543.       if self.db.profile.clickToShow == 1 then return end
  1544.       self:PrepareTooltip(enteredFrame, not IsShiftKeyDown())
  1545.       self.tooltip:SetAutoHideDelay( self.db.profile.autoHideDelay or 0.25, enteredFrame, function() BF:ReleaseTooltip() end )
  1546.     end,
  1547.     OnLeave = function(tt)
  1548.       -- 1 = click2show
  1549.       -- 2 = hover2show
  1550.       if self.db.profile.clickToShow == 1 or true then return end
  1551.       LibQTip:Release(self.tooltip)
  1552.       if self.tooltip then
  1553.         self.tooltip.Columns = nil
  1554.         self.tooltip.Rows = nil
  1555.         self.tooltip = nil
  1556.       end
  1557.     end,
  1558.   })
  1559.  
  1560.   LDBIcon:Register(addonName, self.BFLDB, self.db.profile.minimapIcon)
  1561.  
  1562.   self.reRollCombos = {}
  1563.   self:EnhanceFollowerTab( "GarrisonMissionFrame" )
  1564.   self:EnhanceFollowerTab( "GarrisonLandingPage" )
  1565.   Toast:Register(TOAST_FOLLOWER_UPGRADE, toastFollowerUpgrade)
  1566.   Toast:Register(TOAST_FOLLOWER_LEVELUP, toastFollowerLevelup)
  1567.  
  1568.   -- Update the .format strings
  1569.   self.formatStrings.counterIconTolltip = "|T%s:"..self.db.profile.iconSize..":"..self.db.profile.iconSize..":0:0:64:64:5:59:5:59|t"
  1570.   for i=0,7 do
  1571.     self.formatStrings.rarityColors[i] = "|c"..select(4,GetItemQualityColor(i)).."%s|r"
  1572.   end
  1573.   self.formatStrings.rarityColors.green = "|cFF00FF00%s|r"
  1574.   self.formatStrings.rarityColors.red   = "|cFFFF0000%s|r"
  1575. end
  1576.  
  1577.  
  1578.  
  1579. function BF:Debug(...)
  1580.   DebugPrint( ... )
  1581. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement