/Tukui/modules/unitframes/plugins/oUF_AuraWatch/oUF_AuraWatch.lua
Lua | 330 lines | 194 code | 29 blank | 107 comment | 48 complexity | c3b5caf40925c17c29daa8b93d600007 MD5 | raw file
1local T, C, L = unpack(select(2, ...)) -- Import: T - functions, constants, variables; C - config; L - locales 2if C.unitframes.enable ~= true or C.unitframes.raidunitdebuffwatch ~= true then return end 3 4local _, ns = ... 5local oUF = ns.oUF or oUF 6 7if not oUF then return end 8 9--[[------------------------------------------------------------------------------------------------------ 10oUF_AuraWatch by Astromech 11Please leave comments, suggestions, and bug reports on this addon's WoWInterface page 12 13To setup, create a table named AuraWatch in your unit frame. There are several options 14you can specify, as explained below. 15 16 icons 17 Mandatory! 18 A table of frames to be used as icons. oUF_Aurawatch does not position 19 these frames, so you must do so yourself. Each icon needs a spellID entry, 20 which is the spell ID of the aura to watch. Table should be set up 21 such that values are icon frames, but the keys can be anything. 22 23 Note each icon can have several options set as well. See below. 24 strictMatching 25 Default: false 26 If true, AuraWatch will only show an icon if the specific aura 27 with the specified spell id is on the unit. If false, AuraWatch 28 will show the icon if any aura with the same name and icon texture 29 is on the unit. Strict matching can be undesireable because most 30 ranks of an aura have different spell ids. 31 missingAlpha 32 Default 0.75 33 The alpha value for icons of auras which have faded from the unit. 34 presentAlpha 35 Default 1 36 The alpha value for icons or auras present on the unit. 37 onlyShowMissing 38 Default false 39 If this is true, oUF_AW will hide icons if they are present on the unit. 40 onlyShowPresent 41 Default false 42 If this is true, oUF_AW will hide icons if they have expired from the unit. 43 hideCooldown 44 Default false 45 If this is true, oUF_AW will not create a cooldown frame 46 hideCount 47 Default false 48 If this is true, oUF_AW will not create a count fontstring 49 fromUnits 50 Default {["player"] = true, ["pet"] = true, ["vehicle"] = true} 51 A table of units from which auras can originate. Have the units be the keys 52 and "true" be the values. 53 anyUnit 54 Default false 55 Set to true for oUF_AW to to show an aura no matter what unit it 56 originates from. This will override any fromUnits setting. 57 PostCreateIcon 58 Default nil 59 A function to call when an icon is created to modify it, such as adding 60 a border or repositioning the count fontstring. Leave as nil to ignore. 61 The arguements are: AuraWatch table, icon, auraSpellID, auraName, unitFrame 62 63Below are options set on a per icon basis. Set these as fields in the icon frames. 64 65The following settings can be overridden from the AuraWatch table on a per-aura basis: 66 onlyShowMissing 67 onlyShowPresent 68 hideCooldown 69 hideCount 70 fromUnits 71 anyUnit 72 73The following settings are unique to icons: 74 75 spellID 76 Mandatory! 77 The spell id of the aura, as explained above. 78 icon 79 Default aura texture 80 A texture value for this icon. 81 overlay 82 Default Blizzard aura overlay 83 An overlay for the icon. This is not created if a custom icon texture is created. 84 count 85 Default A fontstring 86 An fontstring to show the stack count of an aura. 87 88Here is an example of how to set oUF_AW up: 89 90 local createAuraWatch = function(self, unit) 91 local auras = {} 92 93 -- A table of spellIDs to create icons for 94 -- To find spellIDs, look up a spell on www.wowhead.com and look at the URL 95 -- http://www.wowhead.com/?spell=SPELL_ID 96 local spellIDs = { ... } 97 98 auras.presentAlpha = 1 99 auras.missingAlpha = .7 100 auras.PostCreateIcon = myCustomIconSkinnerFunction 101 -- Set any other AuraWatch settings 102 auras.icons = {} 103 for i, sid in pairs(spellIDs) do 104 local icon = CreateFrame("Frame", nil, auras) 105 icon.spellID = sid 106 -- set the dimensions and positions 107 icon:SetWidth(24) 108 icon:SetHeight(24) 109 icon:SetPoint("BOTTOM", self, "BOTTOM", 0, 28 * i) 110 auras.icons[sid] = icon 111 -- Set any other AuraWatch icon settings 112 end 113 self.AuraWatch = auras 114 end 115-----------------------------------------------------------------------------------------------------------]] 116 117local _, ns = ... 118local oUF = ns.oUF or _G.oUF 119assert(oUF, "oUF_AuraWatch cannot find an instance of oUF. If your oUF is embedded into a layout, it may not be embedded properly.") 120 121local UnitBuff, UnitDebuff, UnitGUID = UnitBuff, UnitDebuff, UnitGUID 122local GUIDs = {} 123 124local PLAYER_UNITS = { 125 player = true, 126 vehicle = true, 127 pet = true, 128} 129 130local setupGUID 131do 132 local cache = setmetatable({}, {__type = "k"}) 133 134 local frame = CreateFrame"Frame" 135 frame:SetScript("OnEvent", function(self, event) 136 for k,t in pairs(GUIDs) do 137 GUIDs[k] = nil 138 for a in pairs(t) do 139 t[a] = nil 140 end 141 cache[t] = true 142 end 143 end) 144 frame:RegisterEvent"PLAYER_REGEN_ENABLED" 145 frame:RegisterEvent"PLAYER_ENTERING_WORLD" 146 147 function setupGUID(guid) 148 local t = next(cache) 149 if t then 150 cache[t] = nil 151 else 152 t = {} 153 end 154 GUIDs[guid] = t 155 end 156end 157 158 159local function resetIcon(icon, frame, count, duration, remaining) 160 if icon.onlyShowMissing then 161 icon:Hide() 162 else 163 icon:Show() 164 if icon.cd then 165 if duration and duration > 0 then 166 icon.cd:SetCooldown(remaining - duration, duration) 167 icon.cd:Show() 168 else 169 icon.cd:Hide() 170 end 171 end 172 if icon.count then 173 icon.count:SetText((count > 1 and count)) 174 end 175 if icon.overlay then 176 icon.overlay:Hide() 177 end 178 icon:SetAlpha(frame.presentAlpha) 179 end 180end 181 182local function expireIcon(icon, frame) 183 if icon.onlyShowPresent then 184 icon:Hide() 185 else 186 if (icon.cd) then icon.cd:Hide() end 187 if (icon.count) then icon.count:SetText() end 188 icon:SetAlpha(frame.missingAlpha) 189 if icon.overlay then 190 icon.overlay:Show() 191 end 192 icon:Show() 193 end 194end 195 196local found = {} 197local function Update(frame, event, unit) 198 if frame.unit ~= unit then return end 199 local watch = frame.AuraWatch 200 local index, icons = 1, watch.watched 201 local _, name, texture, count, duration, remaining, caster, key, icon, spellid 202 local filter = "HELPFUL" 203 local guid = UnitGUID(unit) 204 if not guid then return end 205 if not GUIDs[guid] then setupGUID(guid) end 206 207 for key, icon in pairs(icons) do 208 icon:Hide() 209 end 210 211 while true do 212 name, _, texture, count, _, duration, remaining, caster, _, _, spellid = UnitAura(unit, index, filter) 213 if not name then 214 if filter == "HELPFUL" then 215 filter = "HARMFUL" 216 index = 1 217 else 218 break 219 end 220 else 221 if watch.strictMatching then 222 key = spellID 223 else 224 key = name..texture 225 end 226 icon = icons[key] 227 if icon and (icon.anyUnit or (caster and icon.fromUnits[caster])) then 228 resetIcon(icon, watch, count, duration, remaining) 229 GUIDs[guid][key] = true 230 found[key] = true 231 end 232 index = index + 1 233 end 234 end 235 236 for key in pairs(GUIDs[guid]) do 237 if icons[key] and not found[key] then 238 expireIcon(icons[key], watch) 239 end 240 end 241 242 for k in pairs(found) do 243 found[k] = nil 244 end 245end 246 247local function setupIcons(self) 248 249 local watch = self.AuraWatch 250 local icons = watch.icons 251 watch.watched = {} 252 if not watch.missingAlpha then watch.missingAlpha = 0.75 end 253 if not watch.presentAlpha then watch.presentAlpha = 1 end 254 255 for _,icon in pairs(icons) do 256 257 local name, _, image = GetSpellInfo(icon.spellID) 258 if not name then error("oUF_AuraWatch error: no spell with "..tostring(icon.spellID).." spell ID exists") end 259 icon.name = name 260 261 if not icon.cd and not (watch.hideCooldown or icon.hideCooldown) then 262 local cd = CreateFrame("Cooldown", nil, icon) 263 cd:SetAllPoints(icon) 264 icon.cd = cd 265 end 266 267 if not icon.icon then 268 local tex = icon:CreateTexture(nil, "BACKGROUND") 269 tex:SetAllPoints(icon) 270 tex:SetTexture(image) 271 icon.icon = tex 272 if not icon.overlay then 273 local overlay = icon:CreateTexture(nil, "OVERLAY") 274 overlay:SetTexture"Interface\\Buttons\\UI-Debuff-Overlays" 275 overlay:SetAllPoints(icon) 276 overlay:SetTexCoord(.296875, .5703125, 0, .515625) 277 overlay:SetVertexColor(1, 0, 0) 278 icon.overlay = overlay 279 end 280 end 281 282 if not icon.count and not (watch.hideCount or icon.hideCount) then 283 local count = icon:CreateFontString(nil, "OVERLAY") 284 count:SetFontObject(NumberFontNormal) 285 count:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", -1, 0) 286 icon.count = count 287 end 288 289 if icon.onlyShowMissing == nil then 290 icon.onlyShowMissing = watch.onlyShowMissing 291 end 292 if icon.onlyShowPresent == nil then 293 icon.onlyShowPresent = watch.onlyShowPresent 294 end 295 if icon.fromUnits == nil then 296 icon.fromUnits = watch.fromUnits or PLAYER_UNITS 297 end 298 if icon.anyUnit == nil then 299 icon.anyUnit = watch.anyUnit 300 end 301 302 if watch.strictMatching then 303 watch.watched[icon.spellID] = icon 304 else 305 watch.watched[name..image] = icon 306 end 307 308 if watch.PostCreateIcon then watch:PostCreateIcon(icon, icon.spellID, name, self) end 309 end 310end 311 312local function Enable(self) 313 if self.AuraWatch then 314 self:RegisterEvent("UNIT_AURA", Update) 315 setupIcons(self) 316 return true 317 else 318 return false 319 end 320end 321 322local function Disable(self) 323 if self.AuraWatch then 324 self:UnregisterEvent("UNIT_AURA", Update) 325 for _,icon in pairs(self.AuraWatch.icons) do 326 icon:Hide() 327 end 328 end 329end 330oUF:AddElement("AuraWatch", Update, Enable, Disable)