Advertisement
Guest User

Untitled

a guest
May 27th, 2016
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 33.05 KB | None | 0 0
  1. local _G = getfenv(0)
  2. local ADDON_NAME, addon = ...
  3. local LibStub = _G.LibStub
  4. local BST = LibStub("AceAddon-3.0"):GetAddon(addon.addonName)
  5. local L = LibStub("AceLocale-3.0"):GetLocale(addon.addonName)
  6.  
  7. -- Local versions for performance
  8. local ceil = _G.math.ceil
  9. local table = _G.table
  10. local tostring = _G.tostring
  11. local ipairs = _G.ipairs
  12. local tinsert, tremove = table.insert, table.remove
  13. local wipe = _G.wipe
  14. local round = addon.round
  15.  
  16. -- Local versions of WoW API calls
  17. local UnitHealth = _G.UnitHealth
  18. local UnitHealthMax = _G.UnitHealthMax
  19. local GetTime = _G.GetTime
  20. local UnitGetTotalAbsorbs = _G.UnitGetTotalAbsorbs
  21. local UnitAttackPower = _G.UnitAttackPower
  22. local GetMasteryEffect = _G.GetMasteryEffect
  23. local GetSpellCooldown = _G.GetSpellCooldown
  24.  
  25. local SpellIds = addon.SpellIds
  26. local SpellNames = addon.SpellNames
  27.  
  28. local formatStandard = "%s%s%s"
  29. local formatPercent = "%s%%"
  30.  
  31. local EstimateBar = {}
  32. addon:RegisterModule("EstimateBar", EstimateBar)
  33. EstimateBar.enabled = false
  34.  
  35. addon.defaults.profile.bars["EstimateBar"] = {
  36.     enabled = true,
  37.     hide_ooc = false,
  38.     show_text = true,
  39.     bar_mode = "DS",
  40.     usePercent = false,
  41.     alternateMinimum = 0,
  42.     show_stacks = true,
  43.     stacks_pos = "LEFT",
  44.     latencyMethod = "None",
  45.     latencyFixed = 0,
  46.     color = {r = 1.0, g = 0.0, b = 0.0, a = 1},
  47.     bgcolor = {r = 0.65, g = 0.0, b = 0.0, a = 0.8},
  48.     alt_color = {r = 0.0, g = 1.0, b = 0.0, a = 1},
  49.     alt_bgcolor = {r = 0.0, g = 0.65, b = 0.0, a = 0.8},
  50.     alt_textcolor = {r = 1.0, g = 1.0, b = 1.0, a = 1},
  51.     width = 90,
  52.     x = 0,
  53.     y = -120,
  54. }
  55.  
  56. -- Keep track of time.  Start with current client time
  57. -- but will use the combat log timestamps after that.
  58. local UPDATE_TIMER_FREQUENCY = 0.3
  59. local currentTime = time()
  60. addon.idle = true
  61. local updateTimer = nil
  62. local lastSeconds = 5
  63. local damageTaken = {}
  64. local removeList = {}
  65.  
  66. -- Constants from abilities / gear.
  67. local dsHealModifier = 0.20  -- Percent of the DS Heal from the tooltip.
  68. local dsMinHealPercent = 0.07
  69. local dsMinHealPercentSuccor = 0.20
  70. local vbHealingBonus = 0.30
  71. local guardianSpiritHealBuff = 0.60
  72.  
  73. local T14BonusAmt = 0.1
  74.  
  75. -- Curent state information
  76. local DarkSuccorBuff = false
  77. local DS_SentTime = nil
  78. local DS_Latency = nil
  79.  
  80. local Tier14Bonus = 1
  81.  
  82. -- MoP Variables --
  83. -- The actual minimum DS heal percent, based on spec.
  84. addon.maxHealth = 1
  85. local actualDsMinHeal = dsMinHealPercent
  86. local dsHealMin = 0
  87. local bsMinimum = 0
  88. -- End --
  89.  
  90. local iccBuff = false
  91. local iccBuffAmt = 0.0
  92. local vbBuff = false
  93. local vbHealingInc = 0.0
  94. local gsHealModifier = 0.0
  95. local healingDebuffMultiplier = 1
  96. local lastDSSuccess = nil
  97. local masteryRating = 0
  98. local versatilityBonus = 0
  99. local versatilityPercent = 0
  100. local shieldPercent = 0
  101. local luckOfTheDrawBuff = false
  102. local luckOfTheDrawAmt = 0
  103.  
  104. function EstimateBar:OnInitialize()
  105.     self.estimatebar = addon.Bar:Create("EstimateBar", "Estimate Bar", false)
  106. end
  107.  
  108. function EstimateBar:Enable()
  109.     if BST.db.profile.bars["EstimateBar"].enabled then
  110.         self:OnEnable()
  111.     else
  112.         self:OnDisable()
  113.     end
  114. end
  115.  
  116. function EstimateBar:OnEnable()
  117.     if self.enabled then return end
  118.     self.enabled = true
  119.     self:ToggleEstimateBar()
  120.  
  121.     addon:RegisterCallback("Auras", "EstimateBar", EstimateBar.CheckAuras)
  122.     addon:RegisterCallback("GearUpdate", "EstimateBar", EstimateBar.GearUpdate)
  123. end
  124.  
  125. function EstimateBar:OnDisable()
  126.     if not self.enabled then return end
  127.     self.enabled = false
  128.     self:ToggleEstimateBar()
  129.     addon:UnregisterCallback("Auras", "EstimateBar")
  130.     addon:UnregisterCallback("GearUpdate", "EstimateBar")
  131. end
  132.  
  133. function EstimateBar:GearUpdate()
  134.     local currentBonus = Tier14Bonus
  135.     Tier14Bonus = 1 + (addon.tierCount["T14 Tank"] >= 4 and T14BonusAmt or 0)
  136.     if currentBonus ~= Tier14Bonus then
  137.         self:UpdateMinHeal("CheckGear", "player")
  138.         if addon.db.profile.verbose and addon.idle then
  139.             local fmt = "T14 Bonus: %d%%"
  140.             BST:Print(fmt:format(Tier14Bonus*100-100))
  141.         end
  142.     end
  143.  
  144. end
  145.  
  146. local UnitEvents = {
  147.     ["any"] = {
  148.         "PLAYER_REGEN_DISABLED",
  149.         "PLAYER_REGEN_ENABLED",
  150.         "PLAYER_ALIVE",
  151.         "PLAYER_DEAD",
  152.         "COMBAT_LOG_EVENT_UNFILTERED",
  153.         "PLAYER_ENTERING_WORLD",
  154.         "COMBAT_RATING_UPDATE",
  155.         "MASTERY_UPDATE"
  156.     },
  157.     ["player"] = {
  158.         "UNIT_SPELLCAST_SUCCEEDED",
  159.         "UNIT_MAXHEALTH",
  160.         -- "UNIT_AURA",
  161.     },
  162. }
  163. local function EventFrame_OnEvent(frame, event, ...)
  164.     if event == "PLAYER_REGEN_DISABLED" then
  165.         EstimateBar:PLAYER_REGEN_DISABLED(event, ...)
  166.     elseif event == "PLAYER_REGEN_ENABLED" then
  167.         EstimateBar:PLAYER_REGEN_ENABLED(event, ...)
  168.     elseif event == "PLAYER_ALIVE" then
  169.         EstimateBar:PLAYER_ALIVE(event, ...)
  170.     elseif event == "PLAYER_DEAD" then
  171.         EstimateBar:PLAYER_DEAD(event, ...)
  172.     elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
  173.         EstimateBar:UNIT_SPELLCAST_SUCCEEDED(event, ...)
  174.     elseif event == "PLAYER_ENTERING_WORLD" then
  175.         EstimateBar:PLAYER_ENTERING_WORLD(event, ...)
  176.     elseif event == "UNIT_MAXHEALTH" then
  177.         EstimateBar:UNIT_MAXHEALTH(event, ...)
  178.     -- elseif event == "UNIT_AURA" then
  179.     --  EstimateBar:UNIT_AURA(event, ...)
  180.     elseif event == "COMBAT_LOG_EVENT_UNFILTERED" then
  181.         EstimateBar:COMBAT_LOG_EVENT_UNFILTERED(event, ...)
  182.     -- Send directly to particular functions
  183.     elseif event == "COMBAT_RATING_UPDATE" then
  184.         EstimateBar:UpdateRatings(event, ...)
  185.     elseif event == "MASTERY_UPDATE" then
  186.         EstimateBar:UpdateRatings(event, ...)
  187.     end
  188. end
  189. local EventFrames = {}
  190.  
  191. function EstimateBar:ToggleEstimateBar()
  192.     if BST.db.profile.bars["EstimateBar"].enabled then
  193.         for unit, events in _G.pairs(UnitEvents) do
  194.             local frame = EventFrames[unit] or _G.CreateFrame("Frame",
  195.                     ADDON_NAME.."_ESTBAR_EventFrame_"..unit)
  196.             if frame then
  197.                 frame:SetScript("OnEvent", EventFrame_OnEvent)
  198.                 EventFrames[unit] = frame
  199.                 for i, event in _G.ipairs(events) do
  200.                     if unit == "any" then
  201.                         frame:RegisterEvent(event)
  202.                     else
  203.                         frame:RegisterUnitEvent(event, unit)
  204.                     end
  205.                 end
  206.             end
  207.         end
  208.         self:UpdateEstimateBar(true)
  209.     else
  210.         for unit, frame in _G.pairs(EventFrames) do
  211.             if frame and frame.UnregisterAllEvents then frame:UnregisterAllEvents() end
  212.         end
  213.     end
  214.     BST.bars["EstimateBar"]:UpdateVisibility()
  215. end
  216.  
  217. local function UpdateTime(self, elapsed)
  218.     currentTime = currentTime + elapsed
  219. end
  220.  
  221. function EstimateBar:UpdateBars(timestamp)
  222.     if addon.idle then
  223.         if updateTimer then
  224.             updateTimer:Cancel()
  225.             updateTimer = nil
  226.         end
  227.     end
  228.     EstimateBar:UpdateEstimateBar(timestamp)
  229. end
  230.  
  231. function EstimateBar:UpdateEstimateBar(timestamp)
  232.     if self.estimatebar.db.enabled and not addon.idle then
  233.         local recentDamage = self:GetRecentDamageTaken(timestamp)
  234.  
  235.         local predictedValue, minimumValue = 0, 0
  236.         local baseValue = recentDamage * dsHealModifier * Tier14Bonus * (1+versatilityPercent)
  237.  
  238.         if self.estimatebar.db.bar_mode == "BS" then
  239.             predictedValue = round(baseValue * shieldPercent)
  240.             minimumValue = bsMinimum
  241.         else
  242.             predictedValue = round(baseValue *
  243.                 self:GetEffectiveHealingBuffModifiers() *
  244.                 self:GetEffectiveHealingDebuffModifiers())
  245.             minimumValue = dsHealMin
  246.         end
  247.  
  248.         local estimate = minimumValue
  249.         if predictedValue > minimumValue then
  250.             estimate = predictedValue
  251.         end
  252.  
  253.         self:UpdateEstimateBarText(estimate)
  254.         self.estimatebar.bar:SetMinMaxValues(0, minimumValue)
  255.  
  256.         local altMin = self.estimatebar.db.alternateMinimum or 0
  257.         if altMin > 0 and predictedValue >= altMin then
  258.             self.estimatebar.altcolor = true
  259.             self.estimatebar.bar:SetValue(predictedValue)
  260.         elseif altMin == 0 and predictedValue > minimumValue then
  261.             self.estimatebar.altcolor = true
  262.             self.estimatebar.bar:SetValue(minimumValue)
  263.         else
  264.             self.estimatebar.altcolor = false
  265.             self.estimatebar.bar:SetValue(predictedValue)
  266.         end
  267.         self.estimatebar:UpdateGraphics()
  268.  
  269.         addon.DataFeed.estimateBar = estimate
  270.         if addon.LDBDataFeed then
  271.             addon:UpdateLDBData()
  272.         end
  273.     end
  274. end
  275.  
  276. function EstimateBar:UpdateEstimateBarText(estimate)
  277.     local text = ""
  278.     local sep = ""
  279.     if self.estimatebar.db.show_text then
  280.         sep = ": "
  281.         if self.estimatebar.db.bar_mode == "BS" then
  282.             text = L["EstimateBarBSText"]
  283.         else
  284.             text = L["HealBarText"]
  285.         end
  286.     end
  287.  
  288.     local val
  289.     if self.estimatebar.db.usePercent then
  290.         val = formatPercent:format(
  291.             addon.FormatWithPrecision(estimate / addon.maxHealth * 100))
  292.     else
  293.         val = addon.FormatNumber(estimate)
  294.     end
  295.  
  296.     self.estimatebar.bar.value:SetText(
  297.         formatStandard:format(
  298.             text, sep, val))
  299. end
  300.  
  301. function EstimateBar:UpdateEstimateBarTextWithMin()
  302.     local value = 0
  303.     if self.estimatebar.db.bar_mode == "BS" then
  304.         value = bsMinimum
  305.     else
  306.         value = dsHealMin
  307.     end
  308.     self:UpdateEstimateBarText(value)
  309. end
  310.  
  311. function EstimateBar:UpdateMinHeal(event, unit)
  312.     if unit == "player" then
  313.         local baseValue
  314.         local maxHealth = UnitHealthMax("player")
  315.         actualDsMinHeal = dsMinHealPercent
  316.         if DarkSuccorBuff == true then
  317.             actualDsMinHeal = dsMinHealPercentSuccor
  318.         end
  319.         baseValue = maxHealth * actualDsMinHeal * Tier14Bonus * (1+versatilityPercent)
  320.         dsHealMin = round(baseValue *
  321.             self:GetEffectiveHealingBuffModifiers() *
  322.             self:GetEffectiveHealingDebuffModifiers())
  323.         bsMinimum = round(baseValue * shieldPercent)
  324.         if addon.idle then
  325.             self:UpdateEstimateBarTextWithMin()
  326.         end
  327.     end
  328. end
  329.  
  330. function EstimateBar:UpdateEstimates(event, unit)
  331.     if unit == "player" then
  332.         --if addon.idle then
  333.         self:UpdateEstimateBar()
  334.         --end
  335.     end
  336. end
  337.  
  338. function EstimateBar:PLAYER_REGEN_DISABLED()
  339.     addon.idle = false
  340.  
  341.     if addon:IsTrackerEnabled() and self.estimatebar.db.enabled then
  342.         updateTimer = _G.C_Timer.NewTicker(UPDATE_TIMER_FREQUENCY, EstimateBar.UpdateBars)
  343.         self.estimatebar.bar:Show()
  344.         self.estimatebar.bar:SetScript("OnUpdate", UpdateTime)
  345.     end
  346. end
  347.  
  348. function EstimateBar:PLAYER_REGEN_ENABLED()
  349.     addon.idle = true
  350.     if self.estimatebar.db.hide_ooc then
  351.         self.estimatebar.bar:Hide()
  352.     end
  353. end
  354.  
  355. function EstimateBar:PLAYER_DEAD()
  356.     -- Hide the health bar if configured to do so for OOC
  357.     if self.estimatebar.db.hide_ooc then
  358.         if self.estimatebar.bar:IsVisible() then
  359.             self.estimatebar.bar:Hide()
  360.         end
  361.     end
  362. end
  363.  
  364. function EstimateBar:GetRecentDamageTaken(timestamp)
  365.     local latency = 0
  366.     local damage = 0
  367.     local current = timestamp
  368.    
  369.     if not current or current <= 0 then
  370.         current = currentTime
  371.     end
  372.  
  373.     if self.estimatebar.db.latencyMethod == "DS" then
  374.         if DS_Latency and DS_Latency > 0 and DS_Latency <= 2 then
  375.             latency = DS_Latency
  376.         end
  377.     elseif self.estimatebar.db.latencyMethod == "Fixed" then
  378.         latency = self.estimatebar.db.latencyFixed / 1000
  379.     end
  380.  
  381.     if latency > 0 then
  382.         current = current - latency
  383.     end
  384.  
  385.     local diff
  386.    
  387.     for i, v in ipairs(damageTaken) do
  388.         if v and v[1] and v[2] then
  389.             diff = current - v[1]
  390.             -- If the damage occured in the window,
  391.             -- adjusted for latency above, then add it.
  392.             if diff <= lastSeconds and diff >= 0 then
  393.                 damage = damage + v[2]
  394.             end
  395.         end
  396.     end
  397.    
  398.     return damage
  399. end
  400.  
  401. function EstimateBar:AddDamageTaken(timestamp, damage)
  402.     -- Add the new damage taken data
  403.     tinsert(damageTaken, {timestamp,damage})
  404.     wipe(removeList)
  405.     -- Remove any data older than lastSeconds
  406.     for i, v in ipairs(damageTaken) do
  407.         if v and v[1] then
  408.             if timestamp - v[1] > lastSeconds + 3 then
  409.                 tinsert(removeList, i)
  410.             end
  411.         end
  412.     end
  413.    
  414.     for i, v in ipairs(removeList) do
  415.         if v then
  416.             tremove(damageTaken, v)
  417.         end
  418.     end
  419.    
  420.     self:UpdateBars(timestamp)
  421. end
  422.  
  423. local CR_VERSATILITY_DAMAGE_DONE = _G.CR_VERSATILITY_DAMAGE_DONE or 29
  424. function EstimateBar:UpdateRatings()
  425.     local update = false
  426.     local mastery = GetMasteryEffect()
  427.     if mastery ~= masteryRating then
  428.         masteryRating = mastery
  429.         shieldPercent = masteryRating/100
  430.         update = true
  431.     end
  432.  
  433.     local vers = GetCombatRatingBonus(CR_VERSATILITY_DAMAGE_DONE) +
  434.         GetVersatilityBonus(CR_VERSATILITY_DAMAGE_DONE)
  435.     if vers ~= versatilityBonus then
  436.         versatilityBonus = vers
  437.         versatilityPercent = versatilityBonus/100
  438.         update = true
  439.     end
  440.  
  441.     if update then
  442.         self:UpdateEstimates("UpdateRatings", "player")
  443.     end
  444. end
  445.  
  446. function EstimateBar:PLAYER_ENTERING_WORLD()
  447.     self:UNIT_MAXHEALTH("PLAYER_ENTERING_WORLD", "player")
  448. end
  449.  
  450. function EstimateBar:PLAYER_ALIVE()
  451.     self:UNIT_MAXHEALTH("PLAYER_ALIVE", "player")
  452.     self:UpdateEstimateBar()
  453. end
  454.  
  455. function EstimateBar:UNIT_MAXHEALTH(event, unit)
  456.     if unit == "player" then
  457.         local maxHealth = UnitHealthMax("player")
  458.         if maxHealth ~= addon.maxHealth then
  459.             addon.maxHealth = maxHealth or 1
  460.         end
  461.         self:UpdateMinHeal(event, unit)
  462.     end
  463. end
  464.  
  465. local EstDSHealFmt = "Estimated DS Heal: %d"
  466. function EstimateBar:UNIT_SPELLCAST_SENT(event, unit, spellName)
  467.     if unit == "player" and spellName == SpellNames["Death Strike"] then
  468.         DS_SentTime = GetTime()
  469.         if addon.db.profile.debug then
  470.             BST:Print(EstDSHealFmt:format(estimatedDS))
  471.         end
  472.     end
  473. end
  474.  
  475. function EstimateBar:UNIT_SPELLCAST_SUCCEEDED(event, unit, spellName, rank, lineId, spellId)
  476.     if unit == "player" then
  477.         if spellName == SpellNames["Death Strike"] then
  478.             local succeededTime = GetTime()
  479.             if DS_SentTime then
  480.                 local diff = succeededTime - DS_SentTime
  481.                 if diff > 0 then
  482.                     DS_Latency = diff
  483.                     if addon.db.profile.debug then
  484.                         BST:Print("DS Latency: "..DS_Latency)
  485.                     end
  486.                     -- If the latency appears overly large then cap it at 2 seconds.
  487.                     if DS_Latency > 2 then
  488.                         DS_Latency = 2
  489.                     end
  490.                     DS_SentTime = nil
  491.                 end
  492.             end
  493.         end
  494.     end
  495. end
  496.  
  497. function EstimateBar:CheckAuras()
  498.     local name, rank, icon, count, dispelType, duration, expires,
  499.         caster, stealable, consolidate, spellId, canApplyAura, isBossDebuff,
  500.         castByPlayer, value, value2, value3
  501.  
  502.     local iccBuffFound = false
  503.     local vampBloodFound = false
  504.     local healingDebuff = 0
  505.     DarkSuccorBuff = false
  506.     luckOfTheDrawBuff = false
  507.     luckOfTheDrawAmt = 0
  508.     healingDebuffMultiplier = 0
  509.     gsHealModifier = 0.0
  510.  
  511.     -- Loop through unit auras to find ones of interest.
  512.     local i = 1
  513.     repeat
  514.         name, rank, icon, count, dispelType, duration, expires, caster,
  515.             stealable, consolidate, spellId, canApplyAura, isBossDebuff,
  516.             castByPlayer, value, value2, value3 = UnitAura("player", i)
  517.         if name == nil or spellId == nil then break end
  518.  
  519.         if spellId == SpellIds["Dark Succor"] then
  520.             DarkSuccorBuff = true
  521.  
  522.         elseif spellId == SpellIds["Luck of the Draw"] then
  523.             luckOfTheDrawBuff = true
  524.             if not count or count == 0 then
  525.                 count = 1
  526.             end
  527.             luckOfTheDrawAmt = addon.LUCK_OF_THE_DRAW_MOD * count
  528.  
  529.         elseif name == SpellNames["Hellscream's Warsong 30"] then
  530.             iccBuffFound = true
  531.             iccBuff = true
  532.             iccBuffAmt = ICCBuffs.Horde[spellId] or
  533.             ICCBuffs.Horde[SpellIds["Hellscream's Warsong 30"]]
  534.  
  535.         elseif name == SpellNames["Strength of Wrynn 30"] then
  536.             iccBuffFound = true
  537.             iccBuff = true
  538.             iccBuffAmt = ICCBuffs.Alliance[spellId] or
  539.             ICCBuffs.Alliance[SpellIds["Strength of Wrynn 30"]]
  540.  
  541.         elseif spellId == SpellIds["Vampiric Blood"] then
  542.             vampBloodFound = true
  543.             vbBuff = true
  544.             vbHealingInc = vbHealingBonus
  545.  
  546.         elseif spellId == SpellIds["Guardian Spirit"] then
  547.             AurasFound["Guardian Spirit"] = true
  548.             gsHealModifier = guardianSpiritHealBuff
  549.  
  550.         else
  551.             -- Check for various healing debuffs
  552.             for k,v in pairs(addon.HealingDebuffs) do
  553.                 if spellId == k then
  554.                     if not count or count == 0 then
  555.                         count = 1
  556.                     end
  557.                     healingDebuff = v * count
  558.                     if healingDebuff > healingDebuffMultiplier then
  559.                         healingDebuffMultiplier = healingDebuff
  560.                     end
  561.                 end
  562.             end
  563.         end
  564.  
  565.         i = i + 1
  566.     until name == nil
  567.  
  568.     -- If the ICC buff isn't present, reset the values
  569.     if not iccBuffFound then
  570.         iccBuff = false
  571.         iccBuffAmt = 0.0
  572.     end
  573.  
  574.     if not vampBloodFound then
  575.         vbBuff = false
  576.         vbHealingInc = 0.0
  577.     end
  578.  
  579.     -- Just in case make sure the healing modifier is a sane value
  580.     if healingDebuffMultiplier > 1 then
  581.         healingDebuffMultiplier = 1
  582.     end
  583.  
  584.     EstimateBar:UpdateMinHeal("UNIT_MAXHEALTH", "player")
  585. end
  586.  
  587. local function UpdateTime(self, elapsed)
  588.     currentTime = currentTime + elapsed
  589. end
  590.  
  591. function EstimateBar:GetEffectiveHealingBuffModifiers()
  592.     return (1+iccBuffAmt) * (1+vbHealingInc) * (1+gsHealModifier) * (1+luckOfTheDrawAmt) * (1+versatilityPercent)
  593. end
  594.  
  595. function EstimateBar:GetEffectiveHealingDebuffModifiers()
  596.     return (1-healingDebuffMultiplier)
  597. end
  598.  
  599. function EstimateBar:COMBAT_LOG_EVENT_UNFILTERED(...)
  600.     local event, timestamp, eventtype, hideCaster,
  601.         srcGUID, srcName, srcFlags, srcRaidFlags,
  602.         destGUID, destName, destFlags, destRaidFlags,
  603.         param9, param10, param11, param12, param13, param14,
  604.         param15, param16, param17, param18, param19, param20
  605.  
  606.     event, timestamp, eventtype, hideCaster,
  607.     srcGUID, srcName, srcFlags, srcRaidFlags,
  608.     destGUID, destName, destFlags, destRaidFlags,
  609.     param9, param10, param11, param12, param13, param14,
  610.     param15, param16, param17, param18, param19, param20 = ...
  611.  
  612.     if not event or not eventtype or not destName then return end
  613.  
  614.     local spellName, spellAbsorb = "", ""
  615.  
  616.     currentTime = timestamp
  617.  
  618.     if eventtype:find("SPELL_ABSORBED") and destName == addon.playerName then
  619.         local absorbed
  620.         local absorbId, absorbName
  621.         if param19 then
  622.             absorbed = param19
  623.             absorbId = param16
  624.             absorbName = param17
  625.             local spellName = param10 or "n/a"
  626.             local school = param11
  627.             local schoolName = addon.GetSpellSchool(school) or "N/A"
  628.             if addon.db.profile.debug then
  629.                 local spellAbsFmt = "Spell Absorbed (%s-%s,%d) %d by %s"
  630.                 BST:Print(spellAbsFmt:format(spellName, schoolName, school, absorbed, absorbName))
  631.             end
  632.         else
  633.             absorbed = param16
  634.             absorbId = param13
  635.             absorbName = param14
  636.             if addon.db.profile.debug then
  637.                 local spellAbsFmt = "Spell Absorbed (None) %d by %s"
  638.                 BST:Print(spellAbsFmt:format(absorbed, absorbName))
  639.             end
  640.         end
  641.  
  642.         if absorbed and absorbId ~= SpellIds["Shroud of Purgatory"] then
  643.             self:AddDamageTaken(timestamp, absorbed)
  644.         end
  645.  
  646.         --         if addon.db.profile.debug then
  647.         --  local fmt = "SPELL_ABSORBED %s %s %s %s %s %s %s %s %s %s %s %s"
  648.         --  BST:Print(fmt:format(
  649.         --      _G.tostring(param9),
  650.         --      _G.tostring(param10),
  651.         --      _G.tostring(param11),
  652.         --      _G.tostring(param12),
  653.         --      _G.tostring(param13),
  654.         --      _G.tostring(param14),
  655.         --      _G.tostring(param15),
  656.         --      _G.tostring(param16),
  657.         --      _G.tostring(param17),
  658.         --      _G.tostring(param18),
  659.         --      _G.tostring(param19),
  660.         --      _G.tostring(param20)
  661.         --      ))
  662.         -- end
  663.     end
  664.  
  665.     if eventtype:find("_DAMAGE") and destName == addon.playerName then
  666.         if eventtype:find("SWING_") and param9 then
  667.             local damage, absorb = param9, param14 or 0
  668.  
  669.             if addon.db.profile.debug then
  670.                 local swingDmgFmt = "Swing Damage for %d [%d absorbed, %s]"
  671.                 BST:Print(swingDmgFmt:format(damage, absorb, eventtype))
  672.             end
  673.  
  674.             self:AddDamageTaken(timestamp, damage)
  675.         elseif eventtype:find("SPELL_") or eventtype:find("RANGE_") then
  676.             local type
  677.             if eventtype:find("SPELL_") then type = "Spell" end
  678.             if eventtype:find("RANGE_") then type = "Range" end        
  679.             local damage, absorb, school = param12 or 0, param17 or 0, param14 or 0
  680.             local spellName = param10 or "n/a"
  681.             local schoolName = addon.GetSpellSchool(school) or "N/A"
  682.  
  683.             local countDamage = true
  684.             -- Do not count damage from no source or maybe this is just
  685.             -- particular items like Shannox's Jagged Tear?
  686.             if srcName == nil then
  687.                 countDamage = false
  688.                 if addon.db.profile.debug then
  689.                     BST:Print("Ignoring no source damage [" .. spellName ..
  690.                         "] of "..(damage or 0))
  691.                 end
  692.             end
  693.  
  694.             -- Do not count Spirit Link damage since it doesn't affect DS.
  695.             if spellName == SpellIds["Spirit Link"] and
  696.                 srcName == SpellNames["Spirit Link Totem"] then
  697.                 countDamage = false
  698.                 if addon.db.profile.debug then
  699.                     BST:Print("Ignoring Spirit Link damage of "..(damage or 0))
  700.                 end
  701.             end
  702.  
  703.             if countDamage == true then
  704.                 self:AddDamageTaken(timestamp, damage)
  705.             end
  706.  
  707.             if addon.db.profile.debug then
  708.                 local spellDmgFmt = "%s Damage (%s-%s,%d) for %d [%d absorbed]"
  709.                 BST:Print(spellDmgFmt:format(
  710.                     type, spellName, schoolName, school, damage, absorb))
  711.             end
  712.         end
  713.     end    
  714.  
  715.     if eventtype:find("_MISSED") and destName == addon.playerName then
  716.         if eventtype == "SWING_MISSED" then
  717.             if param9 and param9 == "ABSORB" then
  718.                 local damage = 0
  719.                 damage = param11 or 0
  720.  
  721.                 if addon.db.profile.debug then
  722.                     local absorbFmt = "Absorbed swing for %d"
  723.                     BST:Print(absorbFmt:format(damage))
  724.                 end
  725.             end
  726.         elseif eventtype:find("SPELL_") then
  727.             if param12 and param12 == 'ABSORB' then
  728.                 local damage = 0
  729.                 damage = param14 or 0
  730.  
  731.                 local spellName, school = param10 or "n/a", param11 or 0
  732.                 local schoolName = addon.GetSpellSchool(school) or "N/A"
  733.  
  734.                 if addon.db.profile.debug then
  735.                     local absorbFmt = "Absorbed spell (%s-%s,%d) for %d"
  736.                     BST:Print(absorbFmt:format(spellName, schoolName, school, damage))
  737.                 end
  738.             end
  739.         end
  740.     end
  741.  
  742.     if eventtype == "SPELL_CAST_SUCCESS" and srcName == addon.playerName and
  743.         param9 == SpellIds["Death Strike"] then
  744.  
  745.         if addon.db.profile.debug then
  746.             local dsHealFormat = "Estimated damage: %d will be a heal for: %d"
  747.             local recentDmg = self:GetRecentDamageTaken(timestamp)
  748.             local predictedHeal = 0
  749.             if healingDebuffMultiplier ~= 1 then
  750.                 predictedHeal = round(
  751.                     recentDmg * dsHealModifier * Tier14Bonus  *
  752.                     self:GetEffectiveHealingBuffModifiers() *
  753.                     self:GetEffectiveHealingDebuffModifiers())
  754.             end
  755.             BST:Print(dsHealFormat:format(recentDmg, predictedHeal))
  756.         end
  757.     end
  758.  
  759.     if eventtype == "SPELL_HEAL" and destName == addon.playerName
  760.         and param9 == SpellIds["Death Strike Heal"] then
  761.        
  762.         local totalHeal = param12 or 0
  763.         local overheal = param13 or 0
  764.         local actualHeal = param12-param13
  765.  
  766.         -- Update the LDB data feed
  767.         addon.DataFeed.lastDS = totalHeal
  768.         if addon.LDBDataFeed then
  769.             addon:UpdateLDBData()
  770.         end
  771.  
  772.         -- Apparently the BS value server-side is calculated from the last
  773.         -- five seconds of data since the DS heal is affected by modifiers
  774.         -- and debuffs.  Because we cannot reliably calculate the server-
  775.         -- side last five seconds of damage, we will take the heal and work
  776.         -- backwards.  The forumula below attempts to factor in various
  777.         -- healing buffs.
  778.         local shieldValue, predictedHeal
  779.  
  780.         local isMinimum = false
  781.         local recentDmg = self:GetRecentDamageTaken(timestamp)
  782.         local minimumHeal = dsHealMin
  783.        
  784.         if healingDebuffMultiplier == 1 then
  785.             shieldValue = bsMinimum
  786.             predictedHeal = 0
  787.             isMinimum = true
  788.         else
  789.             shieldValue = round(totalHeal * shieldPercent /
  790.                 self:GetEffectiveHealingBuffModifiers() /
  791.                 self:GetEffectiveHealingDebuffModifiers())
  792.             if shieldValue <= bsMinimum then
  793.                 isMinimum = true
  794.                 shieldValue = bsMinimum
  795.             end
  796.             predictedHeal = round(recentDmg * dsHealModifier * Tier14Bonus *
  797.                 self:GetEffectiveHealingBuffModifiers() *
  798.                 self:GetEffectiveHealingDebuffModifiers())
  799.         end
  800.  
  801.         if addon.db.profile.debug then
  802.             local dsHealFormat = "DS [Tot:%d, Act:%d, O:%d, Pred:%d, Mast: %0.2f%%, Vers: %0.2f%%]"
  803.             BST:Print(dsHealFormat:format(
  804.                 totalHeal,actualHeal,overheal,predictedHeal,masteryRating, versatilityBonus))
  805.         end
  806.        
  807.         if addon.DEBUG_OUTPUT == true then
  808.             local dsHealFormat = "DS [Tot:%d, Act:%d, O:%d, Pred:%d, Mast: %0.2f%%, Vers: %0.2f%%]"
  809.             addon.DEBUG_BUFFER = addon.DEBUG_BUFFER .. timestamp .. "   " ..
  810.                 dsHealFormat:format(totalHeal,actualHeal,overheal, predictedHeal,
  811.                 masteryRating, versatilityBonus) .. "\n"
  812.         end
  813.     end
  814. end
  815.  
  816. function EstimateBar:GetOptions()
  817.     return "estimateBarOpts", self:GetEstimateBarOptions()
  818. end
  819.  
  820. function EstimateBar:AddOptions()
  821.     return "EstimateBar", L["Estimate Bar"], "estimateBarOpts"
  822. end
  823.  
  824. function EstimateBar:GetEstimateBarOptions()
  825.     local estimateBarOpts = {
  826.         order = 3,
  827.         type = "group",
  828.         name = L["Estimated Healing Bar"],
  829.         desc = L["Estimated Healing Bar"],
  830.         args = {
  831.             description = {
  832.                 order = 1,
  833.                 type = "description",
  834.                 name = L["EstimatedHealingBar_Desc"],
  835.             },
  836.             generalOptions = {
  837.                 order = 10,
  838.                 type = "header",
  839.                 name = L["General Options"],
  840.             },
  841.             enabled = {
  842.                 name = L["Enabled"],
  843.                 desc = L["Enable the Estimated Healing Bar."],
  844.                 type = "toggle",
  845.                 order = 20,
  846.                 set = function(info, val)
  847.                     addon.db.profile.bars["EstimateBar"].enabled = val
  848.                     addon.bars["EstimateBar"]:UpdateVisibility()
  849.                 end,
  850.                 get = function(info)
  851.                     return addon.db.profile.bars["EstimateBar"].enabled
  852.                 end,
  853.             },
  854.             lock_bar = {
  855.                 name = L["Lock bar"],
  856.                 desc = L["LockBarDesc"],
  857.                 type = "toggle",
  858.                 order = 30,
  859.                 set = function(info, val)
  860.                     addon.db.profile.bars["EstimateBar"].locked = val
  861.                     self.estimatebar:Lock()
  862.                 end,
  863.                 get = function(info)
  864.                     return addon.db.profile.bars["EstimateBar"].locked
  865.                 end,
  866.             },
  867.             hide_ooc = {
  868.                 name = L["Hide out of combat"],
  869.                 desc = L["HideOOC_OptionDesc"],
  870.                 type = "toggle",
  871.                 order = 40,
  872.                 set = function(info, val)
  873.                     addon.db.profile.bars["EstimateBar"].hide_ooc = val
  874.                     if not _G.InCombatLockdown() then
  875.                         if val then
  876.                             self.estimatebar.bar:Hide()
  877.                         elseif addon:IsTrackerEnabled() then
  878.                             self.estimatebar.bar:Show()
  879.                         end
  880.                     end
  881.                 end,
  882.                 get = function(info)
  883.                     return addon.db.profile.bars["EstimateBar"].hide_ooc
  884.                 end,
  885.             },
  886.             show_text = {
  887.                 name = L["Show Text"],
  888.                 desc = L["EstHealBarShowText_OptDesc"],
  889.                 type = "toggle",
  890.                 order = 50,
  891.                 set = function(info, val)
  892.                     addon.db.profile.bars["EstimateBar"].show_text = val
  893.                     self:UpdateMinHeal("UpdateShowText", "player")
  894.                 end,
  895.                 get = function(info)
  896.                     return addon.db.profile.bars["EstimateBar"].show_text
  897.                 end,
  898.             },
  899.             bar_mode = {
  900.                 name = L["Mode"],
  901.                 desc = L["Mode"],
  902.                 type = "select",
  903.                 values = {
  904.                     ["DS"] = L["Death Strike Heal"],
  905.                     ["BS"] = L["Blood Shield"],
  906.                 },
  907.                 order = 60,
  908.                 set = function(info, val)
  909.                     addon.db.profile.bars["EstimateBar"].bar_mode = val
  910.                 end,
  911.                 get = function(info)
  912.                     return addon.db.profile.bars["EstimateBar"].bar_mode
  913.                 end,
  914.             },
  915.             usePercent = {
  916.                 name = L["Percent"],
  917.                 desc = L["Percent_OptDesc"],
  918.                 type = "toggle",
  919.                 order = 70,
  920.                 set = function(info, val)
  921.                     addon.db.profile.bars["EstimateBar"].usePercent = val
  922.                 end,
  923.                 get = function(info)
  924.                     return addon.db.profile.bars["EstimateBar"].usePercent
  925.                 end,
  926.             },
  927.             alternateMinimum = {
  928.                 order = 80,
  929.                 name = L["Alternate Minimum"],
  930.                 desc = L["AlternateMinimum_OptDesc"],
  931.                 type = "range",
  932.                 min = 0,
  933.                 max = 1000000,
  934.                 step = 1,
  935.                 bigStep = 1000,
  936.                 set = function(info, val)
  937.                     addon.db.profile.bars["EstimateBar"].alternateMinimum = val
  938.                 end,
  939.                 get = function(info)
  940.                     return addon.db.profile.bars["EstimateBar"].alternateMinimum
  941.                 end,
  942.             },
  943.             colorsMinimum = {
  944.                 order = 400,
  945.                 type = "header",
  946.                 name = L["Colors for Minimum Heal"],
  947.             },
  948.             min_textcolor = {
  949.                 order = 410,
  950.                 name = L["Minimum Text Color"],
  951.                 desc = L["EstHealBarMinTextColor_OptionDesc"],
  952.                 type = "color",
  953.                 hasAlpha = true,
  954.                 set = function(info, r, g, b, a)
  955.                     local c = addon.db.profile.bars["EstimateBar"].textcolor
  956.                     c.r, c.g, c.b, c.a = r, g, b, a
  957.                     self.estimatebar:UpdateGraphics()
  958.                 end,
  959.                 get = function(info)
  960.                     local c = addon.db.profile.bars["EstimateBar"].textcolor
  961.                     return c.r, c.g, c.b, c.a
  962.                 end,                   
  963.             },
  964.             min_color = {
  965.                 order = 420,
  966.                 name = L["Minimum Bar Color"],
  967.                 desc = L["EstHealBarMinColor_OptionDesc"],
  968.                 type = "color",
  969.                 hasAlpha = true,
  970.                 set = function(info, r, g, b, a)
  971.                     local c = addon.db.profile.bars["EstimateBar"].color
  972.                     c.r, c.g, c.b, c.a = r, g, b, a
  973.                     self.estimatebar:UpdateGraphics()
  974.                 end,
  975.                 get = function(info)
  976.                     local c = addon.db.profile.bars["EstimateBar"].color
  977.                     return c.r, c.g, c.b, c.a
  978.                 end,                   
  979.             },
  980.             min_bgcolor = {
  981.                 order = 430,
  982.                 name = L["Minimum Bar Background Color"],
  983.                 desc = L["EstHealBarMinBackgroundColor_OptionDesc"],
  984.                 type = "color",
  985.                 hasAlpha = true,
  986.                 set = function(info, r, g, b, a)
  987.                     local c = addon.db.profile.bars["EstimateBar"].bgcolor
  988.                     c.r, c.g, c.b, c.a = r, g, b, a
  989.                     self.estimatebar:UpdateGraphics()
  990.                 end,
  991.                 get = function(info)
  992.                     local c = addon.db.profile.bars["EstimateBar"].bgcolor
  993.                     return c.r, c.g, c.b, c.a
  994.                 end,                   
  995.             },
  996.             colorsOptimal = {
  997.                 order = 500,
  998.                 type = "header",
  999.                 name = L["Colors for Optimal Heal"],
  1000.             },
  1001.             opt_textcolor = {
  1002.                 order = 510,
  1003.                 name = L["Optimal Text Color"],
  1004.                 desc = L["EstHealBarOptTextColor_OptionDesc"],
  1005.                 type = "color",
  1006.                 hasAlpha = true,
  1007.                 set = function(info, r, g, b, a)
  1008.                     local c = addon.db.profile.bars["EstimateBar"].alt_textcolor
  1009.                     c.r, c.g, c.b, c.a = r, g, b, a
  1010.                     self.estimatebar:UpdateGraphics()
  1011.                 end,
  1012.                 get = function(info)
  1013.                     local c = addon.db.profile.bars["EstimateBar"].alt_textcolor
  1014.                     return c.r, c.g, c.b, c.a
  1015.                 end,                   
  1016.             },
  1017.             opt_color = {
  1018.                 order = 520,
  1019.                 name = L["Optimal Bar Color"],
  1020.                 desc = L["EstHealBarOptColor_OptionDesc"],
  1021.                 type = "color",
  1022.                 hasAlpha = true,
  1023.                 set = function(info, r, g, b, a)
  1024.                     local c = addon.db.profile.bars["EstimateBar"].alt_color
  1025.                     c.r, c.g, c.b, c.a = r, g, b, a
  1026.                     self.estimatebar:UpdateGraphics()
  1027.                 end,
  1028.                 get = function(info)
  1029.                     local c = addon.db.profile.bars["EstimateBar"].alt_color
  1030.                     return c.r, c.g, c.b, c.a
  1031.                 end,                   
  1032.             },
  1033.             latencyOptions = {
  1034.                 order = 700,
  1035.                 type = "header",
  1036.                 name = L["Latency"],
  1037.             },
  1038.             latencyMode = {
  1039.                 name = L["Mode"],
  1040.                 desc = L["Mode"],
  1041.                 type = "select",
  1042.                 values = {
  1043.                     ["None"] = L["None"],
  1044.                     ["DS"] = L["Death Strike"],
  1045.                     ["Fixed"] = L["Fixed"],
  1046.                 },
  1047.                 order = 710,
  1048.                 set = function(info, val)
  1049.                     addon.db.profile.bars["EstimateBar"].latencyMethod = val
  1050.                 end,
  1051.                 get = function(info)
  1052.                     return addon.db.profile.bars["EstimateBar"].latencyMethod
  1053.                 end,
  1054.             },
  1055.             latencyFixed = {
  1056.                 order = 720,
  1057.                 name = L["Fixed"],
  1058.                 desc = L["Fixed"],
  1059.                 type = "range",
  1060.                 min = 0,
  1061.                 max = 2000,
  1062.                 step = 1,
  1063.                 set = function(info, val)
  1064.                     addon.db.profile.bars["EstimateBar"].latencyFixed = val
  1065.                 end,
  1066.                 get = function(info, val)
  1067.                     return addon.db.profile.bars["EstimateBar"].latencyFixed
  1068.                 end,                   
  1069.             },
  1070.         }
  1071.     }
  1072.  
  1073.     BST:AddDimensionOptions(estimateBarOpts, "EstimateBar", 200)
  1074.     BST:AddPositionOptions(estimateBarOpts, "EstimateBar", 300)
  1075.     BST:AddAppearanceOptions(estimateBarOpts, "EstimateBar")
  1076.     BST:AddAdvancedPositioning(estimateBarOpts, "EstimateBar")
  1077.     return estimateBarOpts
  1078. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement