Thread Tools Display Modes
05-24-18, 04:37 PM   #1
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Highlighting lifebloom with pandemic

Update: https://www.wowinterface.com/downloa...bloomGlow.html

For anyone looking for an addon version of the code posted below.

---------------------------------------------------------------------------------------------------------------------

This person has a script that highlights lifebloom on normal raid frames when it's in pandemic range. Wondering how complex this would be to reproduce.

This is especially useful for lifebloom as you can "bloom" it when it is in this range.



Last edited by tehmoku : 06-17-18 at 05:32 AM.
  Reply With Quote
05-26-18, 03:44 PM   #2
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
It seems I've gotten this to work how I want to it work using some hacky timer code.

I'm a bit stumped still on how to get the "dispellable" white border around the icon though.

snip

Last edited by tehmoku : 06-03-18 at 10:33 PM. Reason: Removed bad code
  Reply With Quote
05-28-18, 09:14 PM   #3
sylvanaar
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Sep 2006
Posts: 92
I play (badly) a resto druid. What is this about?
  Reply With Quote
05-28-18, 10:24 PM   #4
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Originally Posted by sylvanaar View Post
I play (badly) a resto druid. What is this about?
If lifebloom is at 30% of its initial duration and you re-cast lifebloom on to that target, the finishing "bloom" will happen. It is essential to only recast it in this window or you lose that burst heal.

Since it is based on a hidden timer, there's no way to know if you can re-cast it to get the bloom effect or not. It's all guessing. On live, it can be anywhere from 4.5 seconds to 5.85 seconds from my testing.

So, I wanted to have some code that highlights lifebloom on raid frames when it is in this essential window so you don't have to guess anymore.

Still not 100% there yet, unfortunately--although I know it is possible from that screenshot I showed.

Last edited by tehmoku : 05-28-18 at 10:26 PM.
  Reply With Quote
05-29-18, 09:48 AM   #5
sylvanaar
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Sep 2006
Posts: 92
Thanks for that. What does it have to do with pandemic range? Or was that just some use for it?
  Reply With Quote
05-29-18, 09:58 AM   #6
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Pandemic was a spell for warlocks back in MoP (I think MoP) that allowed you to refresh dots up to 50% without losing any of the damage (aka the dot would just rollover into the new one you casted)

Now that ability is baked in to everything in the game at 30% all hots/dots "rollover," and pandemic is just what people have called it.
  Reply With Quote
06-02-18, 07:49 AM   #7
Sylen
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 50
Did you make progress on this topic? For the glow effect people usually use this code:

Lua Code:
  1. --Highlight Purgable Buffs on Target and Focus
  2. hooksecurefunc("TargetFrame_UpdateAuras", function(s)
  3.     for i = 1, MAX_TARGET_BUFFS do
  4.         _, _, ic, _, dT = UnitBuff(s.unit, i)
  5.         if(ic and (not s.maxBuffs or i<=s.maxBuffs)) then
  6.             fS=_G[s:GetName()..'Buff'..i..'Stealable']
  7.             if(UnitIsEnemy(PlayerFrame.unit, s.unit) and dT=='Magic') then
  8.                 fS:Show()
  9.             else
  10.                 fS:Hide()
  11.             end
  12.         end
  13.     end
  14. end)
  Reply With Quote
06-02-18, 02:34 PM   #8
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
That code only works on target and focus frames. CompactUnitFrames don't have a Stealable:Show() argument (returns nil) attached to their buff icons because technically you aren't able to steal/purge anything off a friendly target.

Last edited by tehmoku : 06-03-18 at 08:36 AM.
  Reply With Quote
06-03-18, 10:33 PM   #9
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
So, for anyone potentially following the thread..

I have finished this finally, and have working code for BfA. (A couple things were removed from UnitBuff, namely spell rank, so this code won't specifically work on live but it's easily fixable if you so choose)

The only, and major problem is that this doesn't update often enough when I need it to. If anyone has any suggestions on how I can update it more frequently, I'm open to suggestion. It updates every time an aura gets updated (applied or removed), but for this to be truly perfect it would probably need to update at least every half second with lifebloom up, regardless of anything else.

As a result, sometimes even though LB can be manually "bloomed" at 5.5 seconds, the highlight won't appear until after that. The amount of time after that varies depending on how often auras are being updated for the unit.

Lua Code:
  1. --Target Frame
  2. function TargetFrame_UpdateAuras_Hook(self)
  3.     local frame, frameName
  4.     local selfName = self:GetName()
  5.  
  6.     for i = 1, MAX_TARGET_BUFFS do
  7.     local buffName, icon, count, debuffType, duration, expirationTime, caster, canStealOrPurge, nameplateShowPersonal,
  8.     spellId, canApplyAura, isBossDebuff, casterIsPlayer, nameplateShowAll, timeMod, _ = UnitBuff(self.unit, i, nil)
  9.  
  10.         if buffName then
  11.             if spellId == 33763 and casterIsPlayer then
  12.                 frameName = selfName.."Buff"..(i)
  13.                 frame = _G[frameName]
  14.                 if frame and icon and (not self.maxBuffs or i <= self.maxBuffs) then
  15.                     local timeRemaining = (expirationTime - GetTime()) / timeMod
  16.                     local refreshTime = duration * 0.3
  17.                     local frameStealable = _G[frameName.."Stealable"]
  18.  
  19.                     if timeRemaining <= refreshTime then
  20.                         frameStealable:Show()
  21.                     else
  22.                         frameStealable:Hide()
  23.                     end
  24.                 end
  25.                 break
  26.             end
  27.         else
  28.             break
  29.         end
  30.     end
  31. end
  32. hooksecurefunc("TargetFrame_UpdateAuras", TargetFrame_UpdateAuras_Hook)
  33.  
  34. --Compact Unit Frame
  35. function CompactUnitFrame_UtilSetBuff_Hook(buffFrame, unit, index, filter)
  36.     local buffName, icon, count, debuffType, duration, expirationTime, caster, canStealOrPurge, nameplateShowPersonal,
  37.     spellId, canApplyAura, isBossDebuff, casterIsPlayer, nameplateShowAll, timeMod, _ = UnitBuff(unit, index, filter)
  38.  
  39.     if spellId == 33763 and casterIsPlayer then
  40.         local timeRemaining = (expirationTime - GetTime()) / timeMod
  41.         local refreshTime = duration * 0.3
  42.  
  43.     if not buffFrame.highlight then
  44.         local highlight = buffFrame:CreateTexture(nil, "OVERLAY")
  45.         highlight:SetTexture([[Interface\TargetingFrame\UI-TargetingFrame-Stealable]])
  46.         highlight:SetPoint("TOPLEFT", -3, 3)
  47.         highlight:SetPoint("BOTTOMRIGHT", 3, -3)
  48.         highlight:SetBlendMode("ADD")
  49.         buffFrame.highlight = highlight
  50.     end
  51.  
  52.     if timeRemaining <= refreshTime then
  53.         buffFrame.highlight:Show()
  54.     else
  55.         buffFrame.highlight:Hide()
  56.     end
  57.  
  58.     elseif buffFrame.highlight then
  59.         buffFrame.highlight:Hide()
  60.     end
  61. end
  62. hooksecurefunc("CompactUnitFrame_UtilSetBuff", CompactUnitFrame_UtilSetBuff_Hook)

Last edited by tehmoku : 06-04-18 at 03:19 PM.
  Reply With Quote
06-04-18, 02:45 AM   #10
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
If you wanted (needed?) it to update every frame, wouldn't it be easier to just hook TargetFrame_OnUpdate and CompactUnitFrame_OnUpdate?

Just be careful that your code not be too demanding so that having it run every frame doesn't risk causing performance issues, and it should be okay. It's not usually recommended to hook OnUpdate, and maybe there's a better solution, but if you absolutely need it to run every frame then OnUpdate is your solution (that's what OnUpdate does, after all.)

You could throttle it within the hook function if you needed to, to make it run only every other frame, which may help if performance ever became an issue.

Last edited by Ammako : 06-04-18 at 02:55 AM.
  Reply With Quote
06-04-18, 08:28 AM   #11
pegasu8
A Defias Bandit
Join Date: Jun 2018
Posts: 2
Originally Posted by tehmoku View Post
So, for anyone potentially following the thread..

I have finished this finally, and have working code for BfA. (A couple things were removed from UnitBuff, namely spell rank, so this code won't specifically work on live but it's easily fixable if you so choose)

The only, and major problem is that this doesn't update every frame. If anyone has any suggestions on how I can update it more frequently, I'm open to suggestion. It updates every time an aura gets updated, but for this to be truly perfect it would probably need to update at least every half second with lifebloom up, regardless of anything else.

As a result, sometimes even though LB can be manually "bloomed" at 5.5 seconds, the highlight won't appear until after that. The amount of time after that varies depending on how often auras are being updated for the unit.

Lua Code:
  1. --Target Frame
  2. function TargetFrame_UpdateAuras_Hook(self)
  3.     local frame, frameName
  4.     local selfName = self:GetName()
  5.  
  6.     for i = 1, MAX_TARGET_BUFFS do
  7.     local buffName, icon, count, debuffType, duration, expirationTime, caster, canStealOrPurge, nameplateShowPersonal,
  8.     spellId, canApplyAura, isBossDebuff, casterIsPlayer, nameplateShowAll, timeMod, _ = UnitBuff(self.unit, i, nil)
  9.  
  10.         if buffName then
  11.             if spellId == 33763 and casterIsPlayer then
  12.                 frameName = selfName.."Buff"..(i)
  13.                 frame = _G[frameName]
  14.                 if frame and icon and (not self.maxBuffs or i <= self.maxBuffs) then
  15.                     local timeRemaining = (expirationTime - GetTime()) / timeMod
  16.                     local refreshTime = duration * 0.3
  17.                     local frameStealable = _G[frameName.."Stealable"]
  18.  
  19.                     if timeRemaining <= refreshTime then
  20.                         frameStealable:Show()
  21.                     else
  22.                         frameStealable:Hide()
  23.                     end
  24.                 end
  25.                 break
  26.             end
  27.         else
  28.             break
  29.         end
  30.     end
  31. end
  32. hooksecurefunc("TargetFrame_UpdateAuras", TargetFrame_UpdateAuras_Hook)
  33.  
  34. --Compact Unit Frame
  35. function CompactUnitFrame_UtilSetBuff_Hook(buffFrame, unit, index, filter)
  36.     local buffName, icon, count, debuffType, duration, expirationTime, caster, canStealOrPurge, nameplateShowPersonal,
  37.     spellId, canApplyAura, isBossDebuff, casterIsPlayer, nameplateShowAll, timeMod, _ = UnitBuff(unit, index, filter)
  38.  
  39.     if spellId == 33763 and casterIsPlayer then
  40.         local timeRemaining = (expirationTime - GetTime()) / timeMod
  41.         local refreshTime = duration * 0.3
  42.  
  43.     if not buffFrame.highlight then
  44.         local highlight = buffFrame:CreateTexture(nil, "OVERLAY")
  45.         highlight:SetTexture([[Interface\TargetingFrame\UI-TargetingFrame-Stealable]])
  46.         highlight:SetPoint("TOPLEFT", -3, 3)
  47.         highlight:SetPoint("BOTTOMRIGHT", 3, -3)
  48.         highlight:SetBlendMode("ADD")
  49.         buffFrame.highlight = highlight
  50.     end
  51.  
  52.     if timeRemaining <= refreshTime then
  53.         buffFrame.highlight:Show()
  54.     else
  55.         buffFrame.highlight:Hide()
  56.     end
  57.  
  58.     elseif buffFrame.highlight then
  59.         buffFrame.highlight:Hide()
  60.     end
  61. end
  62. hooksecurefunc("CompactUnitFrame_UtilSetBuff", CompactUnitFrame_UtilSetBuff_Hook)
Can you post a working script which also works in Legion still?
  Reply With Quote
06-04-18, 12:52 PM   #12
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Originally Posted by Ammako View Post
If you wanted (needed?) it to update every frame, wouldn't it be easier to just hook TargetFrame_OnUpdate and CompactUnitFrame_OnUpdate?
Yeah, I don't want to actually run it OnUpdate. That's entirely too demanding for this. I was hoping there was a more elegant solution that someone else may be able to tell me.

I was hooking buffFrame to OnUpdate, and it worked well, but it was just too much considering it only really needs to be a fraction of that for 30% of the time a single buff is active.

Although I'm unconvinced--maybe in practice there's enough UNIT_AURA events firing that it won't be a real issue, but if not I'll go back to OnUpdate if needed.

Originally Posted by pegasu8 View Post
Can you post a working script which also works in Legion still?
Yes, change lines 7/8 and 36/37 in the code to this

Lua Code:
  1. local buffName, _, icon, count, debuffType, duration, expirationTime, caster, canStealOrPurge, nameplateShowPersonal, spellId, canApplyAura, isBossDebuff, casterIsPlayer, nameplateShowAll, timeMod, _ = UnitBuff(unit, index, filter)

Last edited by tehmoku : 06-04-18 at 01:00 PM.
  Reply With Quote
06-04-18, 03:10 PM   #13
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
So, here is the code for running on a throttled OnUpdate (just change the update interval to whatever you want).

Note: I only really care about raid frames being highly accurate, and I left the target frame how it was.

Fair warning, it's quite a bit more taxing on your CPU. It's a lot more reliable though, and probably what I will be using. This code is for legion, but just remove the underscore next to buffName on line 21 and it will work for BfA.

Lua Code:
  1. local ONUPDATE_INTERVAL = 0.5
  2. local lastUpdate = 0
  3.  
  4. --Compact Unit Frames
  5. hooksecurefunc("CompactUnitFrame_OnUpdate",function(frame, elapsed)
  6. lastUpdate = lastUpdate + elapsed
  7.  
  8.     if lastUpdate >= ONUPDATE_INTERVAL then
  9.         lastUpdate = 0
  10.  
  11.         local index = 1
  12.         local frameNum = 1
  13.         local filter = nil
  14.  
  15.         while ( frameNum <= frame.maxBuffs ) do
  16.             local buffNames = UnitBuff(frame.displayedUnit, index, filter)
  17.             if ( buffNames ) then
  18.                 if ( CompactUnitFrame_UtilShouldDisplayBuff(frame.displayedUnit, index, filter) and not CompactUnitFrame_UtilIsBossAura(frame.displayedUnit, index, filter, true) ) then
  19.                     local buffFrame = frame.buffFrames[frameNum]
  20.  
  21.                     local buffName, _, icon, count, debuffType, duration, expirationTime, caster, canStealOrPurge, nameplateShowPersonal,
  22.                     spellId, canApplyAura, isBossDebuff, casterIsPlayer, nameplateShowAll, timeMod, _ = UnitBuff(frame.displayedUnit, index, filter)
  23.  
  24.                     if spellId == 33763 and casterIsPlayer then
  25.                         local timeRemaining = (expirationTime - GetTime()) / timeMod
  26.                         local refreshTime = duration * 0.3
  27.  
  28.                         if not buffFrame.highlight then
  29.                             local highlight = buffFrame:CreateTexture(nil, "OVERLAY")
  30.                             highlight:SetTexture([[Interface\TargetingFrame\UI-TargetingFrame-Stealable]])
  31.                             highlight:SetPoint("TOPLEFT", -3, 3)
  32.                             highlight:SetPoint("BOTTOMRIGHT", 3, -3)
  33.                             highlight:SetBlendMode("ADD")
  34.                             buffFrame.highlight = highlight
  35.                         end
  36.  
  37.                         if timeRemaining <= refreshTime then
  38.                             buffFrame.highlight:Show()
  39.                         else
  40.                             buffFrame.highlight:Hide()
  41.                         end
  42.  
  43.                     elseif buffFrame.highlight then
  44.                         buffFrame.highlight:Hide()
  45.                     end
  46.  
  47.                     frameNum = frameNum + 1
  48.                 end
  49.             else
  50.                 break
  51.             end
  52.             index = index + 1
  53.         end
  54.     end
  55. end)

Last edited by tehmoku : 06-07-18 at 12:41 AM.
  Reply With Quote
06-06-18, 06:55 PM   #14
Kakjens
A Cliff Giant
Join Date: Apr 2017
Posts: 75
Lua Code:
  1. local index = 1
  2. local frameNum = 1
  3. local filter = nil
could be moved after lastUpdate = 0.
frame.displayedUnit gets accessed quite often, so maybe a local variable is warranted.
I would suggest fixing indentation of lines 27-40, otherwise
Lua Code:
  1. elseif buffFrame.highlight then
  2.     buffFrame.highlight:Hide()
  3. end
will look weird.
Also, I would have tried to track the player I cast Lifebloom.
  Reply With Quote
06-17-18, 04:57 PM   #15
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
It turns out the OnUpdate code was unnecessary. Lifebloom doesn't update often enough when you just have your own buffs, but CompactUnitFrame_UtilSetBuff fires very often under normal use case, resulting in desired accuracy.

https://www.wowinterface.com/downloa...bloomGlow.html

For anyone following the thread or people coming from google, here is the addon if you don't want to worry about what to do with code or whatever.

Cheers
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Highlighting lifebloom with pandemic

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off