Here I present util how to handle with Pandemic mechanic, since I was unable to find any solution.
With a help of #WoWUIDev, this is the Pandemic util I made for my indev Warlock addon (note that the following util uses global
Tooltip, but it's just for clarity):
Lua Code:
Tooltip = Tooltip or {};
local Tooltip = Tooltip;
Tooltip._tooltip = 'Tooltip._tooltip';
Tooltip._tooltip_frame = CreateFrame('GameTooltip', Tooltip._tooltip, nil, 'GameTooltipTemplate');
-- @param {link} itemLink link to item
-- @return {object} text object of line: text from given @itemLink Tooltip
-- @credits Semlar#WoWUIDev
Tooltip.GetTooltip = Tooltip.GetTooltip or function(itemLink)
Tooltip._tooltip_frame:SetOwner(UIParent, 'ANCHOR_NONE');
Tooltip._tooltip_frame:SetHyperlink(itemLink);
local O = {}; -- output
for i = 1, Tooltip._tooltip_frame:NumLines() do
local line = _G[Tooltip._tooltip ..'TextLeft' ..i];
local text = line and line:GetText();
if not text then break end;
O[i] = tostring(text);
end;
return O;
end;
-- @param {uint|name} itemID item id or itemName item name
-- @return {number|nil} realDuration real spell duration (unaffected by pandemic) or nil if unknown
-- @credits Xuerian#WoWUIDev
Tooltip.GetSpellDuration = Tooltip.GetSpellDuration or function(itemNameORID)
local link = GetSpellLink(itemNameORID);
local text = Tooltip.GetTooltip(link);
for i = 1, #text do
local duration = string.match(text[i], "over (%d+%.?%d?) sec");
if duration ~= nil then
return tonumber(duration);
end;
end;
return nil;
end;
-- @param {string} unitID unitID
-- @param {name} itemName item name
-- @param {string} rank UnitAura's rank
-- @param {string} filter UnitAura's filter
-- @return {bool|nil} pandemic if aura is affected by pandemic or nil if unknown
Tooltip.GetUnitAuraPandemic = Tooltip.GetUnitAuraPandemic or function(unitID, itemName, rank, filter)
local realDuration = Tooltip.GetSpellDuration(itemName);
local _, _, _, _, _, duration = UnitAura(unitID, itemName, rank, filter);
if
duration == nil
or realDuration == nil
then return nil end;
-- we love float, doesn't we?
if math.abs(realDuration - duration) < 0.01 then return false end;
if math.abs(realDuration *1.3 - duration) < 0.01 then return true end;
return nil;
end;
The idea behind this method is to read the spell duration directly from tooltip, using
Tooltip.GetSpellDuration, ex.:
Lua Code:
local realDuration = Tooltip.GetSpellDuration("Siphon Life");
The cache it and whenever checking
UnitAura for the same spell, we can use cached value if it's not
nil, ex.:
Lua Code:
local _, _, _, _, _, duration = UnitAura("target" "Siphon Life", nil, "PLAYER HARMFUL");
duration = realDuration or duration;
Finally, I've added a handy
Tooltip.GetUnitAuraPandemic that takes same arguments like
UnitAura, and returns if Spell duration already benefits from Pandemic or not.
Example: Before casting Siphon Life on target:
Lua Code:
[15:20:07] Dump: value=Tooltip.GetUnitAuraPandemic("target", "Siphon Life", nil, "PLAYER HARMFUL");
[15:20:07] empty result
After casting first Siphon Life on target:
Lua Code:
[15:20:12] Dump: value=Tooltip.GetUnitAuraPandemic("target", "Siphon Life", nil, "PLAYER HARMFUL");
[15:20:12] [1]=false
After casting second Siphon Life on target:
Lua Code:
[15:20:15] Dump: value=Tooltip.GetUnitAuraPandemic("target", "Siphon Life", nil, "PLAYER HARMFUL");
[15:20:15] [1]=true