389 lines
10 KiB
Lua
389 lines
10 KiB
Lua
|
--[[------------------------------------------------------------------------------------------------------
|
||
|
oUF_AuraWatch by Astromech
|
||
|
Please leave comments, suggestions, and bug reports on this addon's WoWInterface page
|
||
|
|
||
|
To setup, create a table named AuraWatch in your unit frame. There are several options
|
||
|
you can specify, as explained below.
|
||
|
|
||
|
icons
|
||
|
Mandatory!
|
||
|
A table of frames to be used as icons. oUF_Aurawatch does not position
|
||
|
these frames, so you must do so yourself. Each icon needs a spellID entry,
|
||
|
which is the spell ID of the aura to watch. Table should be set up
|
||
|
such that values are icon frames, but the keys can be anything.
|
||
|
|
||
|
Note each icon can have several options set as well. See below.
|
||
|
strictMatching
|
||
|
Default: false
|
||
|
If true, AuraWatch will only show an icon if the specific aura
|
||
|
with the specified spell id is on the unit. If false, AuraWatch
|
||
|
will show the icon if any aura with the same name and icon texture
|
||
|
is on the unit. Strict matching can be undesireable because most
|
||
|
ranks of an aura have different spell ids.
|
||
|
missingAlpha
|
||
|
Default 0.75
|
||
|
The alpha value for icons of auras which have faded from the unit.
|
||
|
presentAlpha
|
||
|
Default 1
|
||
|
The alpha value for icons or auras present on the unit.
|
||
|
onlyShowMissing
|
||
|
Default false
|
||
|
If this is true, oUF_AW will hide icons if they are present on the unit.
|
||
|
onlyShowPresent
|
||
|
Default false
|
||
|
If this is true, oUF_AW will hide icons if they have expired from the unit.
|
||
|
hideCooldown
|
||
|
Default false
|
||
|
If this is true, oUF_AW will not create a cooldown frame
|
||
|
hideCount
|
||
|
Default false
|
||
|
If this is true, oUF_AW will not create a count fontstring
|
||
|
fromUnits
|
||
|
Default {["player"] = true, ["pet"] = true, ["vehicle"] = true}
|
||
|
A table of units from which auras can originate. Have the units be the keys
|
||
|
and "true" be the values.
|
||
|
anyUnit
|
||
|
Default false
|
||
|
Set to true for oUF_AW to to show an aura no matter what unit it
|
||
|
originates from. This will override any fromUnits setting.
|
||
|
decimalThreshold
|
||
|
Default 5
|
||
|
The threshold before timers go into decimal form. Set to -1 to disable decimals.
|
||
|
PostCreateIcon
|
||
|
Default nil
|
||
|
A function to call when an icon is created to modify it, such as adding
|
||
|
a border or repositioning the count fontstring. Leave as nil to ignore.
|
||
|
The arguements are: AuraWatch table, icon, auraSpellID, auraName, unitFrame
|
||
|
|
||
|
Below are options set on a per icon basis. Set these as fields in the icon frames.
|
||
|
|
||
|
The following settings can be overridden from the AuraWatch table on a per-aura basis:
|
||
|
onlyShowMissing
|
||
|
onlyShowPresent
|
||
|
hideCooldown
|
||
|
hideCount
|
||
|
fromUnits
|
||
|
anyUnit
|
||
|
decimalThreshold
|
||
|
|
||
|
The following settings are unique to icons:
|
||
|
|
||
|
spellID
|
||
|
Mandatory!
|
||
|
The spell id of the aura, as explained above.
|
||
|
icon
|
||
|
Default aura texture
|
||
|
A texture value for this icon.
|
||
|
overlay
|
||
|
Default Blizzard aura overlay
|
||
|
An overlay for the icon. This is not created if a custom icon texture is created.
|
||
|
count
|
||
|
Default A fontstring
|
||
|
An fontstring to show the stack count of an aura.
|
||
|
|
||
|
Here is an example of how to set oUF_AW up:
|
||
|
|
||
|
local createAuraWatch = function(self, unit)
|
||
|
local auras = {}
|
||
|
|
||
|
-- A table of spellIDs to create icons for
|
||
|
-- To find spellIDs, look up a spell on www.wowhead.com and look at the URL
|
||
|
-- http://www.wowhead.com/?spell=SPELL_ID
|
||
|
local spellIDs = { ... }
|
||
|
|
||
|
auras.presentAlpha = 1
|
||
|
auras.missingAlpha = .7
|
||
|
auras.PostCreateIcon = myCustomIconSkinnerFunction
|
||
|
-- Set any other AuraWatch settings
|
||
|
auras.icons = {}
|
||
|
for i, sid in pairs(spellIDs) do
|
||
|
local icon = CreateFrame("Frame", nil, auras)
|
||
|
icon.spellID = sid
|
||
|
-- set the dimensions and positions
|
||
|
icon:Width(24)
|
||
|
icon:Height(24)
|
||
|
icon:SetPoint("BOTTOM", self, "BOTTOM", 0, 28 * i)
|
||
|
auras.icons[sid] = icon
|
||
|
-- Set any other AuraWatch icon settings
|
||
|
end
|
||
|
self.AuraWatch = auras
|
||
|
end
|
||
|
-----------------------------------------------------------------------------------------------------------]]
|
||
|
|
||
|
local _, ns = ...
|
||
|
local oUF = oUF or ns.oUF
|
||
|
assert(oUF, "oUF_AuraWatch cannot find an instance of oUF. If your oUF is embedded into a layout, it may not be embedded properly.")
|
||
|
|
||
|
local UnitBuff, UnitDebuff, UnitGUID = UnitBuff, UnitDebuff, UnitGUID
|
||
|
local GUIDs = {}
|
||
|
|
||
|
local PLAYER_UNITS = {
|
||
|
player = true,
|
||
|
vehicle = true,
|
||
|
pet = true,
|
||
|
}
|
||
|
|
||
|
local setupGUID
|
||
|
do
|
||
|
local cache = setmetatable({}, {__type = "k"})
|
||
|
|
||
|
local frame = CreateFrame"Frame"
|
||
|
frame:SetScript("OnEvent", function(self, event)
|
||
|
for k,t in pairs(GUIDs) do
|
||
|
GUIDs[k] = nil
|
||
|
for a in pairs(t) do
|
||
|
t[a] = nil
|
||
|
end
|
||
|
cache[t] = true
|
||
|
end
|
||
|
end)
|
||
|
frame:RegisterEvent"PLAYER_REGEN_ENABLED"
|
||
|
frame:RegisterEvent"PLAYER_ENTERING_WORLD"
|
||
|
|
||
|
function setupGUID(guid)
|
||
|
local t = next(cache)
|
||
|
if t then
|
||
|
cache[t] = nil
|
||
|
else
|
||
|
t = {}
|
||
|
end
|
||
|
GUIDs[guid] = t
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local day, hour, minute, second = 86400, 3600, 60, 1
|
||
|
local function formatTime(s, threshold)
|
||
|
if s >= day then
|
||
|
return format("%dd", ceil(s / hour))
|
||
|
elseif s >= hour then
|
||
|
return format("%dh", ceil(s / hour))
|
||
|
elseif s >= minute then
|
||
|
return format("%dm", ceil(s / minute))
|
||
|
elseif s >= threshold then
|
||
|
return floor(s)
|
||
|
end
|
||
|
|
||
|
return format("%.1f", s)
|
||
|
end
|
||
|
|
||
|
local function updateText(self, elapsed)
|
||
|
if self.timeLeft then
|
||
|
self.elapsed = (self.elapsed or 0) + elapsed
|
||
|
if self.elapsed >= 0.1 then
|
||
|
if not self.first then
|
||
|
self.timeLeft = self.timeLeft - self.elapsed
|
||
|
else
|
||
|
self.timeLeft = self.timeLeft - GetTime()
|
||
|
self.first = false
|
||
|
end
|
||
|
if self.timeLeft > 0 then
|
||
|
if ((self.timeLeft <= self.textThreshold) or self.textThreshold == -1) then
|
||
|
local time = formatTime(self.timeLeft, self.decimalThreshold or 5)
|
||
|
self.text:SetText(time)
|
||
|
else
|
||
|
self.text:SetText('')
|
||
|
end
|
||
|
else
|
||
|
self.text:SetText('')
|
||
|
self:SetScript("OnUpdate", nil)
|
||
|
end
|
||
|
self.elapsed = 0
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
local function resetIcon(icon, frame, count, duration, remaining)
|
||
|
if icon.onlyShowMissing then
|
||
|
icon:Hide()
|
||
|
else
|
||
|
icon:Show()
|
||
|
if icon.cd then
|
||
|
if duration and duration > 0 and icon.style ~= 'NONE' then
|
||
|
icon.cd:SetCooldown(remaining - duration, duration)
|
||
|
icon.cd:Show()
|
||
|
else
|
||
|
icon.cd:Hide()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if icon.displayText then
|
||
|
icon.timeLeft = remaining
|
||
|
icon.first = true;
|
||
|
icon:SetScript('OnUpdate', updateText)
|
||
|
end
|
||
|
|
||
|
if icon.count then
|
||
|
icon.count:SetText((count > 1 and count))
|
||
|
end
|
||
|
if icon.overlay then
|
||
|
icon.overlay:Hide()
|
||
|
end
|
||
|
icon:SetAlpha(icon.presentAlpha)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function expireIcon(icon, frame)
|
||
|
if icon.onlyShowPresent then
|
||
|
icon:Hide()
|
||
|
else
|
||
|
if (icon.cd) then icon.cd:Hide() end
|
||
|
if (icon.count) then icon.count:SetText() end
|
||
|
icon:SetAlpha(icon.missingAlpha)
|
||
|
if icon.overlay then
|
||
|
icon.overlay:Show()
|
||
|
end
|
||
|
icon:Show()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local found = {}
|
||
|
local function Update(frame, event, unit)
|
||
|
if frame.unit ~= unit or not unit then return end
|
||
|
local watch = frame.AuraWatch
|
||
|
local index, icons = 1, watch.watched
|
||
|
local _, name, texture, count, duration, remaining, caster, key, icon, spellID
|
||
|
local filter = "HELPFUL"
|
||
|
local guid = UnitGUID(unit)
|
||
|
if not guid then return end
|
||
|
if not GUIDs[guid] then setupGUID(guid) end
|
||
|
|
||
|
for key, icon in pairs(icons) do
|
||
|
if not icon.onlyShowMissing then
|
||
|
icon:Hide()
|
||
|
else
|
||
|
icon:Show()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
while true do
|
||
|
name, _, texture, count, _, duration, remaining, caster, _, _, spellID = UnitAura(unit, index, filter)
|
||
|
if not name then
|
||
|
if filter == "HELPFUL" then
|
||
|
filter = "HARMFUL"
|
||
|
index = 1
|
||
|
else
|
||
|
break
|
||
|
end
|
||
|
else
|
||
|
if watch.strictMatching then
|
||
|
key = spellID
|
||
|
else
|
||
|
key = name..texture
|
||
|
end
|
||
|
icon = icons[key]
|
||
|
|
||
|
if icon and (icon.anyUnit or (caster and icon.fromUnits and icon.fromUnits[caster])) then
|
||
|
resetIcon(icon, watch, count, duration, remaining)
|
||
|
GUIDs[guid][key] = true
|
||
|
found[key] = true
|
||
|
end
|
||
|
index = index + 1
|
||
|
end
|
||
|
end
|
||
|
|
||
|
for key in pairs(GUIDs[guid]) do
|
||
|
if icons[key] and not found[key] then
|
||
|
expireIcon(icons[key], watch)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
for k in pairs(found) do
|
||
|
found[k] = nil
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function setupIcons(self)
|
||
|
|
||
|
local watch = self.AuraWatch
|
||
|
local icons = watch.icons
|
||
|
watch.watched = {}
|
||
|
|
||
|
for _,icon in pairs(icons) do
|
||
|
|
||
|
local name, _, image = GetSpellInfo(icon.spellID)
|
||
|
|
||
|
if name then
|
||
|
icon.name = name
|
||
|
|
||
|
if not icon.cd and not (watch.hideCooldown or icon.hideCooldown) then
|
||
|
local cd = CreateFrame("Cooldown", nil, icon, "CooldownFrameTemplate")
|
||
|
cd:SetAllPoints(icon)
|
||
|
icon.cd = cd
|
||
|
end
|
||
|
|
||
|
if not icon.icon then
|
||
|
local tex = icon:CreateTexture(nil, "BACKGROUND")
|
||
|
tex:SetAllPoints(icon)
|
||
|
tex:SetTexture(image)
|
||
|
icon.icon = tex
|
||
|
if not icon.overlay then
|
||
|
local overlay = icon:CreateTexture(nil, "OVERLAY")
|
||
|
overlay:SetTexture"Interface\\Buttons\\UI-Debuff-Overlays"
|
||
|
overlay:SetAllPoints(icon)
|
||
|
overlay:SetTexCoord(.296875, .5703125, 0, .515625)
|
||
|
overlay:SetVertexColor(1, 0, 0)
|
||
|
icon.overlay = overlay
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if not icon.count and not (watch.hideCount or icon.hideCount) then
|
||
|
local count = icon:CreateFontString(nil, "OVERLAY")
|
||
|
count:SetFontObject(NumberFontNormal)
|
||
|
count:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", -1, 0)
|
||
|
icon.count = count
|
||
|
end
|
||
|
|
||
|
if icon.onlyShowMissing == nil then
|
||
|
icon.onlyShowMissing = watch.onlyShowMissing
|
||
|
end
|
||
|
if icon.onlyShowPresent == nil then
|
||
|
icon.onlyShowPresent = watch.onlyShowPresent
|
||
|
end
|
||
|
if icon.presentAlpha == nil then
|
||
|
icon.presentAlpha = watch.presentAlpha
|
||
|
end
|
||
|
if icon.missingAlpha == nil then
|
||
|
icon.missingAlpha = watch.missingAlpha
|
||
|
end
|
||
|
if icon.fromUnits == nil then
|
||
|
icon.fromUnits = watch.fromUnits or PLAYER_UNITS
|
||
|
end
|
||
|
if icon.anyUnit == nil then
|
||
|
icon.anyUnit = watch.anyUnit
|
||
|
end
|
||
|
|
||
|
if watch.strictMatching then
|
||
|
watch.watched[icon.spellID] = icon
|
||
|
else
|
||
|
watch.watched[name..image] = icon
|
||
|
end
|
||
|
|
||
|
if watch.PostCreateIcon then watch:PostCreateIcon(icon, icon.spellID, name, self) end
|
||
|
else
|
||
|
print("oUF_AuraWatch error: no spell with "..tostring(icon.spellID).." spell ID exists")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function Enable(self)
|
||
|
if self.AuraWatch then
|
||
|
self.AuraWatch.Update = setupIcons
|
||
|
self:RegisterEvent("UNIT_AURA", Update)
|
||
|
setupIcons(self)
|
||
|
return true
|
||
|
else
|
||
|
return false
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function Disable(self)
|
||
|
if self.AuraWatch then
|
||
|
self:UnregisterEvent("UNIT_AURA", Update)
|
||
|
for _,icon in pairs(self.AuraWatch.icons) do
|
||
|
icon:Hide()
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
oUF:AddElement("AuraWatch", Update, Enable, Disable)
|