Advertisement
Guest User

AuraWidget

a guest
Dec 17th, 2012
453
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.73 KB | None | 0 0
  1.  
  2. --[[
  3. Things to do..
  4.  
  5. - Single Target Mode
  6. UpdateWidgetContextTargetOnly
  7. UpdateIconGrid
  8. TargetOnlyEventHandler
  9.  
  10. - Raid-Target Only Mode
  11.  
  12. - More recycling of table entries
  13.  
  14. The Prefilter should discard spells based on a general criteria
  15.  
  16. Allowed spells
  17. - SpellID match
  18. - Debuffs (right now)
  19. - Target GUID
  20.  
  21. Testing
  22. /wg emilye nagrand arena
  23.  
  24.  
  25. Arena UnitID support
  26. - Debuffs
  27. - Cast bars
  28.  
  29.  
  30.  
  31. Idea: Store Recent non-target, non-focus, non-mouseover unitid via the Gameevent system
  32. Game events happen before combat log events
  33.  
  34.  
  35.  
  36.  
  37.  
  38. When a debuff falls off, while marked as a raid-target (and cleared), the rest of the debuffs are cleared.
  39. When one debuff falls off, the whole shebang should get re-evaluated with the data table in-mind.
  40.  
  41.  
  42.  
  43.  
  44.  
  45. -- Widget Object Functions
  46.  
  47. --]]
  48.  
  49. TidyPlatesWidgets.DebuffWidgetBuild = 2
  50.  
  51. local PlayerGUID = UnitGUID("player")
  52. local PolledHideIn = TidyPlatesWidgets.PolledHideIn
  53. local FilterFunction = function() return 1 end
  54. local AuraMonitor = CreateFrame("Frame")
  55. local WatcherIsEnabled = false
  56. local WidgetList, WidgetGUID = {}, {}
  57. local UpdateWidget
  58. local TargetOfGroupMembers = {}
  59. local DebuffColumns = 3
  60. local inArena = false
  61.  
  62. local function DefaultDebuffPreFilter() return true end
  63. local DebuffPrefilter = DefaultDebuffPreFilter
  64.  
  65. local AURA_TARGET_HOSTILE = 1
  66. local AURA_TARGET_FRIENDLY = 2
  67.  
  68. local AURA_TYPE_BUFF = 1
  69. local AURA_TYPE_DEBUFF = 6
  70.  
  71. local _
  72.  
  73. local AURA_TYPE = {
  74. ["Buff"] = 1,
  75. ["Curse"] = 2,
  76. ["Disease"] = 3,
  77. ["Magic"] = 4,
  78. ["Poison"] = 5,
  79. ["Debuff"] = 6,
  80. }
  81.  
  82. local function SetFilter(func)
  83. if func and type(func) == "function" then
  84. FilterFunction = func
  85. end
  86. end
  87.  
  88. local function GetAuraWidgetByGUID(guid)
  89. if guid then return WidgetGUID[guid] end
  90. end
  91.  
  92. local function IsAuraShown(widget, aura)
  93. if widget and widget.IsShown then
  94. for i = 1, 6 do
  95. if widget.AuraIconFrames[i] and widget.AuraIconFrames[i]:IsShown() then return true end
  96. end
  97. end
  98. end
  99.  
  100. local RaidIconBit = {
  101. ["STAR"] = 0x00000001,
  102. ["CIRCLE"] = 0x00000002,
  103. ["DIAMOND"] = 0x00000004,
  104. ["TRIANGLE"] = 0x00000008,
  105. ["MOON"] = 0x00000010,
  106. ["SQUARE"] = 0x00000020,
  107. ["CROSS"] = 0x00000040,
  108. ["SKULL"] = 0x00000080,
  109. }
  110.  
  111.  
  112. local RaidIconIndex = {
  113. "STAR",
  114. "CIRCLE",
  115. "DIAMOND",
  116. "TRIANGLE",
  117. "MOON",
  118. "SQUARE",
  119. "CROSS",
  120. "SKULL",
  121. }
  122.  
  123. local ByRaidIcon = {} -- Raid Icon to GUID -- ex. ByRaidIcon["SKULL"] = GUID
  124. local ByName = {} -- Name to GUID (PVP)
  125.  
  126. local PlayerDispelCapabilities = {
  127. ["Curse"] = false,
  128. ["Disease"] = false,
  129. ["Magic"] = false,
  130. ["Poison"] = false,
  131. }
  132.  
  133. --[[
  134. local DispelTypes = {
  135. ["Curse"] = function()
  136. if IsSpellKnown(51886) then return true end -- Cleanse Spirit, Shaman
  137. if IsSpellKnown(475) then return true end -- Remove Curse, Mage
  138. if IsSpellKnown(2782) then return true end -- Remove Corruption, Druid
  139. end,
  140. ["Poison"] = function()
  141. if IsSpellKnown(2782) then return true end -- Remove Corruption, Druid
  142. if IsSpellKnown(32375) then return true end -- Mass Dispel, Priest
  143. if IsSpellKnown(527) and IsSpellKnown(33167) then return true end -- Dispel Magic, Priest, Requires Absolution, 33167
  144. if IsSpellKnown(4987) then return true end -- Cleanse, Paladin
  145. end,
  146. ["Magic"] = function()
  147. if IsSpellKnown(4987) and IsSpellKnown(53551) then return true end -- Cleanse, Paladin, Requires Sacred Cleansing, 53551
  148. if IsSpellKnown(2782) and IsSpellKnown(88423) then return true end -- Remove Corruption, Druid, Requires Nature's Cure, 88423
  149. if IsSpellKnown(527) and IsSpellKnown(33167) then return true end -- Dispel Magic, Priest, Requires Absolution, 33167
  150. if IsSpellKnown(32375) then return true end -- Mass Dispel, Priest
  151. if IsSpellKnown(51886) and IsSpellKnown(77130) then return true end -- Cleanse Spirit, Shaman, Requires Improved Cleanse Spirit, 77130
  152. end,
  153. ["Disease"] = function()
  154. if IsSpellKnown(4987) then return true end -- Cleanse, Paladin
  155. if IsSpellKnown(528) then return true end -- Cure Disease, Shaman
  156. end,
  157. }
  158. --]]
  159.  
  160. local function UpdatePlayerDispelTypes()
  161. PlayerDispelCapabilities["Curse"] = IsSpellKnown(51886) or IsSpellKnown(475) or IsSpellKnown(2782)
  162. PlayerDispelCapabilities["Poison"] = IsSpellKnown(2782) or IsSpellKnown(32375) or IsSpellKnown(4987) or (IsSpellKnown(527) and IsSpellKnown(33167))
  163. PlayerDispelCapabilities["Magic"] = (IsSpellKnown(4987) and IsSpellKnown(53551)) or (IsSpellKnown(2782) and IsSpellKnown(88423)) or (IsSpellKnown(527) and IsSpellKnown(33167)) or (IsSpellKnown(51886) and IsSpellKnown(77130)) or IsSpellKnown(32375)
  164. PlayerDispelCapabilities["Disease"] = IsSpellKnown(4987) or IsSpellKnown(528)
  165. end
  166.  
  167. local function CanPlayerDispel(debuffType)
  168. return PlayerDispelCapabilities[debuffType or ""]
  169. end
  170.  
  171.  
  172. -----------------------------------------------------
  173. -- Default Filter
  174. -----------------------------------------------------
  175. local function DefaultFilterFunction(debuff)
  176. if (debuff.duration < 600) then
  177. return true
  178. end
  179. end
  180.  
  181. -----------------------------------------------------
  182. -- Update Via Search
  183. -----------------------------------------------------
  184.  
  185. local function FindWidgetByGUID(guid)
  186. return WidgetGUID[guid]
  187. end
  188.  
  189. local function FindWidgetByName(SearchFor)
  190. local widget
  191. --local SearchFor = strsplit("-", NameString)
  192. for widget in pairs(WidgetList) do
  193. if widget.unit.name == SearchFor then
  194. return widget
  195. end
  196. end
  197. end
  198.  
  199. local function FindWidgetByIcon(raidicon)
  200. local widget
  201. for widget in pairs(WidgetList) do
  202. if widget.unit.isMarked and widget.unit.raidIcon == raidicon then return widget end
  203. end
  204. end
  205.  
  206. local function CallForWidgetUpdate(guid, raidicon, name)
  207. local widget
  208.  
  209. if guid then widget = FindWidgetByGUID(guid) end
  210. if (not widget) and name then widget = FindWidgetByName(name) end
  211. if (not widget) and raidicon then widget = FindWidgetByIcon(raidicon) end
  212.  
  213. if widget then UpdateWidget(widget) end
  214. end
  215.  
  216.  
  217. -----------------------------------------------------
  218. -- Aura Durations
  219. -----------------------------------------------------
  220. TidyPlatesWidgetData.CachedAuraDurations = {}
  221.  
  222. local function GetSpellDuration(spellid)
  223. if spellid then return TidyPlatesWidgetData.CachedAuraDurations[spellid] end
  224. end
  225.  
  226. local function SetSpellDuration(spellid, duration)
  227. if spellid then TidyPlatesWidgetData.CachedAuraDurations[spellid] = duration end
  228. end
  229.  
  230. -----------------------------------------------------
  231. -- Aura Instances
  232. -----------------------------------------------------
  233.  
  234. -- New Style
  235. local Aura_List = {} -- Two Dimensional
  236. local Aura_Spellid = {}
  237. local Aura_Spellname = {}
  238. local Aura_Expiration = {}
  239. local Aura_Stacks = {}
  240. local Aura_Caster = {}
  241. local Aura_Duration = {}
  242. local Aura_Texture = {}
  243. local Aura_Type = {}
  244. local Aura_Target = {}
  245.  
  246. local function SetAuraInstance(guid, spellid, spellname, expiration, stacks, caster, duration, texture, auratype, auratarget)
  247. if guid and spellid and caster and texture then
  248. if DebuffPrefilter(spellid, spellname, auratype) ~= true then return end
  249.  
  250. --print("SetAuraInstance", guid, spellid, spellname, expiration, stacks, caster, duration, texture, auratype, auratarget)
  251. local aura_id = spellid..(tostring(caster or "UNKNOWN_CASTER"))
  252. local aura_instance_id = guid..aura_id
  253. Aura_List[guid] = Aura_List[guid] or {}
  254. Aura_List[guid][aura_id] = aura_instance_id
  255. Aura_Spellid[aura_instance_id] = spellid
  256. Aura_Spellname[aura_instance_id] = spellname
  257. Aura_Expiration[aura_instance_id] = expiration
  258. Aura_Stacks[aura_instance_id] = stacks
  259. Aura_Caster[aura_instance_id] = caster
  260. Aura_Duration[aura_instance_id] = duration
  261. Aura_Texture[aura_instance_id] = texture
  262. Aura_Type[aura_instance_id] = auratype
  263. Aura_Target[aura_instance_id] = auratarget
  264.  
  265. end
  266. end
  267.  
  268. local function GetAuraInstance(guid, aura_id)
  269. if guid and aura_id then
  270. local aura_instance_id = guid..aura_id
  271. local spellid, expiration, stacks, caster, duration, texture, auratype
  272. spellid = Aura_Spellid[aura_instance_id]
  273. spellname = Aura_Spellname[aura_instance_id]
  274. expiration = Aura_Expiration[aura_instance_id]
  275. stacks = Aura_Stacks[aura_instance_id]
  276. caster = Aura_Caster[aura_instance_id]
  277. duration = Aura_Duration[aura_instance_id]
  278. texture = Aura_Texture[aura_instance_id]
  279. auratype = Aura_Type[aura_instance_id]
  280. auratarget = Aura_Target[aura_instance_id]
  281. return spellid, spellname, expiration, stacks, caster, duration, texture, auratype, auratarget
  282. end
  283. end
  284.  
  285. local function WipeUnitAuraList(guid)
  286. if guid and Aura_List[guid] then
  287. local unit_aura_list = Aura_List[guid]
  288. for aura_id, aura_instance_id in pairs(unit_aura_list) do
  289. Aura_Spellid[aura_instance_id] = nil
  290. Aura_Spellname[aura_instance_id] = nil
  291. Aura_Expiration[aura_instance_id] = nil
  292. Aura_Stacks[aura_instance_id] = nil
  293. Aura_Caster[aura_instance_id] = nil
  294. Aura_Duration[aura_instance_id] = nil
  295. Aura_Texture[aura_instance_id] = nil
  296. Aura_Type[aura_instance_id] = nil
  297. Aura_Target[aura_instance_id] = nil
  298. unit_aura_list[aura_id] = nil
  299. end
  300. end
  301. end
  302.  
  303. local function GetAuraList(guid)
  304. if guid and Aura_List[guid] then return Aura_List[guid] end
  305. end
  306.  
  307. local function RemoveAuraInstance(guid, spellid, caster)
  308. if guid and spellid and Aura_List[guid] then
  309. local aura_instance_id = tostring(guid)..tostring(spellid)..(tostring(caster or "UNKNOWN_CASTER"))
  310. local aura_id = spellid..(tostring(caster or "UNKNOWN_CASTER"))
  311. if Aura_List[guid][aura_id] then
  312. Aura_Spellid[aura_instance_id] = nil
  313. Aura_Spellname[aura_instance_id] = nil
  314. Aura_Expiration[aura_instance_id] = nil
  315. Aura_Stacks[aura_instance_id] = nil
  316. Aura_Caster[aura_instance_id] = nil
  317. Aura_Duration[aura_instance_id] = nil
  318. Aura_Texture[aura_instance_id] = nil
  319. Aura_Type[aura_instance_id] = nil
  320. Aura_Target[aura_instance_id] = nil
  321. Aura_List[guid][aura_id] = nil
  322. end
  323. end
  324. end
  325.  
  326. local function CleanAuraLists() -- Removes expired auras from the lists
  327. local currentTime = GetTime()
  328. for guid, instance_list in pairs(Aura_List) do
  329. local auracount = 0
  330. for aura_id, aura_instance_id in pairs(instance_list) do
  331. local expiration = Aura_Expiration[aura_instance_id]
  332. if expiration and expiration < currentTime then
  333.  
  334. Aura_List[guid][aura_id] = nil
  335. Aura_Spellid[aura_instance_id] = nil
  336. Aura_Spellname[aura_instance_id] = nil
  337. Aura_Expiration[aura_instance_id] = nil
  338. Aura_Stacks[aura_instance_id] = nil
  339. Aura_Caster[aura_instance_id] = nil
  340. Aura_Duration[aura_instance_id] = nil
  341. Aura_Texture[aura_instance_id] = nil
  342. Aura_Type[aura_instance_id] = nil
  343. Aura_Target[aura_instance_id] = nil
  344. else
  345. auracount = auracount + 1
  346. end
  347. end
  348. if auracount == 0 then
  349. Aura_List[guid] = nil
  350. end
  351. end
  352. end
  353.  
  354. -----------------------------------------------------
  355. -- Aura Updating Via UnitID (Via UnitDebuff API function and UNIT_AURA events)
  356. -----------------------------------------------------
  357.  
  358. local function UpdateAurasByUnitID(unitid)
  359. local unitType
  360. if UnitIsFriend("player", unitid) then unitType = AURA_TARGET_FRIENDLY else unitType = AURA_TARGET_HOSTILE end
  361. --if unitType == AURA_TARGET_FRIENDLY then return end -- If the unit is hostile, quit. Right now.
  362.  
  363. -- Check the UnitIDs Debuffs
  364. local index
  365. local guid = UnitGUID(unitid)
  366. -- Reset Auras for a guid
  367. WipeUnitAuraList(guid)
  368. -- Debuffs
  369. for index = 1, 40 do
  370. local spellname , _, texture, count, dispelType, duration, expirationTime, unitCaster, _, _, spellid, _, isBossDebuff = UnitDebuff(unitid, index)
  371. if not spellname then break end
  372. SetSpellDuration(spellid, duration) -- Caches the aura data for times when the duration cannot be determined (ie. via combat log)
  373. SetAuraInstance(guid, spellid, spellname, expirationTime, count, UnitGUID(unitCaster or ""), duration, texture, AURA_TYPE[dispelType or "Debuff"], unitType)
  374. end
  375.  
  376. -- Buffs (Only for friendly units)
  377. if unitType == AURA_TARGET_FRIENDLY then
  378. for index = 1, 40 do
  379. local spellname , _, texture, count, dispelType, duration, expirationTime, unitCaster, _, _, spellid, _, isBossDebuff = UnitBuff(unitid, index)
  380. if not spellname then break end
  381. SetSpellDuration(spellid, duration) -- Caches the aura data for times when the duration cannot be determined (ie. via combat log)
  382. SetAuraInstance(guid, spellid, spellname, expirationTime, count, UnitGUID(unitCaster or ""), duration, texture, AURA_TYPE_BUFF, AURA_TARGET_FRIENDLY)
  383. end
  384. end
  385.  
  386. local raidicon, name
  387. if UnitPlayerControlled(unitid) then name = UnitName(unitid) end
  388. raidicon = RaidIconIndex[GetRaidTargetIndex(unitid) or ""]
  389. if raidicon then ByRaidIcon[raidicon] = guid end
  390.  
  391. CallForWidgetUpdate(guid, raidicon, name)
  392. end
  393.  
  394. --[[
  395. local LocalUnitLookup = {}
  396. local LocalUnitIdList = {}
  397.  
  398. do -- Populate Unit ID List
  399. LocalUnitIdList["target"] = true
  400. LocalUnitIdList["focus"] = true
  401. LocalUnitIdList["mouseover"] = true
  402.  
  403. for i = 1, 4 do
  404. LocalUnitIdList["boss"..i] = true
  405. LocalUnitIdList["party"..i] = true
  406. end
  407.  
  408. for i = 1, 5 do
  409. LocalUnitIdList["arena"..i] = true
  410. end
  411.  
  412. for i = 1, 40 do
  413. LocalUnitIdList["raid"..i] = true
  414. end
  415. end
  416. --]]
  417.  
  418.  
  419.  
  420. -----------------------------------------------------
  421. -- Aura Updating Via Combat Log
  422. -- local sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellid, spellName, spellSchool, auraType, stackCount = ...
  423. -----------------------------------------------------
  424.  
  425. local function CombatLog_ApplyAura(...)
  426. local timestamp, sourceGUID, destGUID, destName, spellid, spellname, stackCount = ...
  427. local duration = GetSpellDuration(spellid)
  428. local texture = GetSpellTexture(spellid)
  429.  
  430. SetAuraInstance(destGUID, spellid, spellname, GetTime() + (duration or 0), 1, sourceGUID, duration, texture, AURA_TYPE_DEBUFF, AURA_TARGET_HOSTILE)
  431. end
  432.  
  433. local function CombatLog_RemoveAura(...)
  434. local timestamp, sourceGUID, destGUID, destName, spellid = ...
  435.  
  436. RemoveAuraInstance(destGUID, spellid, sourceGUID)
  437. end
  438.  
  439. local function CombatLog_UpdateAuraStacks(...)
  440. local timestamp, sourceGUID, destGUID, destName, spellid, spellname, stackCount = ...
  441. local duration = GetSpellDuration(spellid)
  442. local texture = GetSpellTexture(spellid)
  443. SetAuraInstance(destGUID, spellid, spellname, GetTime() + (duration or 0), stackCount, sourceGUID, duration, texture, AURA_TYPE_DEBUFF, AURA_TARGET_HOSTILE)
  444. end
  445.  
  446.  
  447.  
  448. -----------------------------------------------------
  449. -- General Events
  450. -----------------------------------------------------
  451.  
  452.  
  453. --[[
  454. local function EventUnitTarget()
  455. TargetOfGroupMembers = wipe(TargetOfGroupMembers)
  456.  
  457. for name, unitid in pairs(TidyPlatesUtility.GroupMembers.UnitId) do
  458. local targetOf = unitid..("target" or "")
  459. if UnitExists(targetOf) then
  460. TargetOfGroupMembers[UnitGUID(targetOf)] = targetOf
  461. end
  462. end
  463. end
  464. --]]
  465.  
  466. --[[
  467. local function EventPlayerTarget()
  468. -- if UnitExists("target") then UpdateAurasByUnitID("target") end
  469. local guid = UnitGUID("target")
  470. if guid then LocalUnitLookup[guid] = "target" end
  471. end
  472. --]]
  473.  
  474. local function EventUnitAura(unitid)
  475. if inArena or unitid == "target" or unitid == "target" or unitid == "focus" then
  476. UpdateAurasByUnitID(unitid)
  477. end
  478. end
  479.  
  480. local function EventPlayerEnterWorld()
  481. CleanAuraLists()
  482. local isInstance, instanceType = IsInInstance()
  483. --[[
  484. instanceType...
  485. arena - Player versus player arena
  486. none - Not inside an instance
  487. party - 5-man instance
  488. pvp - Player versus player battleground
  489. raid - Raid instance
  490. --]]
  491. if instanceType and instanceType == "arena" then
  492. inArena = true
  493. else
  494. inArena = false
  495. end
  496. end
  497.  
  498. --[[
  499. local function EventLocalUnitUpdate()
  500. local unitid, guid
  501. LocalUnitLookup = wipe(LocalUnitLookup)
  502.  
  503. -- Party
  504. for i = 1, 5 do
  505. unitid = "party"..i
  506. guid = UnitGUID(unitid)
  507. if guid then LocalUnitLookup[guid] = unitid end
  508. end
  509.  
  510. -- Arena Opponent
  511. for i = 1, 5 do
  512. unitid = "arena"..i
  513. guid = UnitGUID(unitid)
  514. if guid then LocalUnitLookup[guid] = unitid end
  515. end
  516.  
  517. -- Raid
  518. for i = 1, 40 do
  519. unitid = "raid"..i
  520. guid = UnitGUID(unitid)
  521. if guid then LocalUnitLookup[guid] = unitid end
  522. end
  523.  
  524.  
  525. --RAID_ROSTER_UPDATE
  526. --PARTY_MEMBERS_CHANGED
  527. --ARENA_OPPONENT_UPDATE
  528. --ARENA_TEAM_UPDATE
  529.  
  530. end
  531. --]]
  532.  
  533. -----------------------------------------------------
  534. -- Function Reference Lists
  535. -----------------------------------------------------
  536. local CombatLogEvents = {
  537. -- Refresh Expire Time
  538. ["SPELL_AURA_APPLIED"] = CombatLog_ApplyAura,
  539. ["SPELL_AURA_REFRESH"] = CombatLog_ApplyAura,
  540. -- Add a stack
  541. ["SPELL_AURA_APPLIED_DOSE"] = CombatLog_UpdateAuraStacks,
  542. -- Remove a stack
  543. ["SPELL_AURA_REMOVED_DOSE"] = CombatLog_UpdateAuraStacks,
  544. -- Expires Aura
  545. ["SPELL_AURA_BROKEN"] = CombatLog_RemoveAura,
  546. ["SPELL_AURA_BROKEN_SPELL"] = CombatLog_RemoveAura,
  547. ["SPELL_AURA_REMOVED"] = CombatLog_RemoveAura,
  548. }
  549.  
  550. local GeneralEvents = {
  551. --["UNIT_TARGET"] = EventUnitTarget,
  552. ["UNIT_AURA"] = EventUnitAura,
  553. ["PLAYER_ENTERING_WORLD"] = EventPlayerEnterWorld,
  554. ["PLAYER_REGEN_ENABLED"] = CleanAuraLists,
  555.  
  556. --["PLAYER_TALENT_UPDATE"] = UpdatePlayerDispelTypes,
  557. --["ACTIVE_TALENT_GROUP_CHANGED"] = UpdatePlayerDispelTypes,
  558.  
  559. --["RAID_ROSTER_UPDATE"] = EventLocalUnitUpdate,
  560. --["PARTY_MEMBERS_CHANGED"] = EventLocalUnitUpdate,
  561. --["ARENA_OPPONENT_UPDATE"] = EventLocalUnitUpdate,
  562. --["ARENA_TEAM_UPDATE"] = EventLocalUnitUpdate,
  563. --["PLAYER_TARGET"] = EventPlayerTarget,
  564. }
  565.  
  566. local function TargetOnlyEventHandler(frame, event, unitid)
  567. if unitid == "target" then
  568. UpdateAurasByUnitID("target")
  569. end
  570. end
  571.  
  572. local function GuidIsLocalUnitId(guid)
  573. if guid == UnitGUID("target") or guid == UnitGUID("mouseover") or guid == UnitGUID("focus") then
  574. return true
  575. --elseif LocalUnitLookup[guid] then
  576. -- return true
  577. else
  578. return false
  579. end
  580. end
  581.  
  582. local GetCombatEventResults
  583. --if (tonumber((select(2, GetBuildInfo()))) >= 14299) then else end
  584.  
  585. function GetCombatEventResults(...)
  586. local timestamp, combatevent, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlag, spellid, spellname = ... -- WoW 4.2
  587. local auraType, stackCount = select(15, ...)
  588. return timestamp, combatevent, sourceGUID, destGUID, destName, destFlags, destRaidFlag, auraType, spellid, spellname, stackCount
  589. end
  590.  
  591. local function CombatEventHandler(frame, event, ...)
  592. -- General Events, Passthrough
  593. if event ~= "COMBAT_LOG_EVENT_UNFILTERED" then
  594. if GeneralEvents[event] then GeneralEvents[event](...) end
  595. return
  596. elseif inArena then
  597. return
  598. end
  599.  
  600. -- Combat Log Unfiltered
  601. local timestamp, combatevent, sourceGUID, destGUID, destName, destFlags, destRaidFlag, auraType, spellid, spellname, stackCount = GetCombatEventResults(...)
  602.  
  603. -- Evaluate only for enemy units, for now
  604. if (bit.band(destFlags, COMBATLOG_OBJECT_REACTION_FRIENDLY) == 0) then -- FILTER: ENEMY UNIT
  605.  
  606. local CombatLogUpdateFunction = CombatLogEvents[combatevent]
  607. -- Evaluate only for certain combat log events
  608. if CombatLogUpdateFunction then
  609. -- Evaluate only for debuffs
  610. if auraType == "DEBUFF" then -- FILTER: DEBUFF
  611.  
  612.  
  613. -- Update Auras via API/UnitID Search
  614. --if not UpdateAuraByLookup(destGUID) then --- REMOVE this function, and replace with a function that checks to see if the detected unit is a unitid matcher
  615. if not GuidIsLocalUnitId(destGUID) then --- REMOVE this function, and replace with a function that checks to see if the detected unit is a unitid match
  616. -- Update Auras via Combat Log
  617. CombatLogUpdateFunction(timestamp, sourceGUID, destGUID, destName, spellid, spellname, stackCount)
  618. end
  619. -- To Do: Need to write something to detect when a change was made to the destID
  620. -- Return values on functions?
  621.  
  622. local name, raidicon
  623. -- Cache Unit Name for alternative lookup strategy
  624. if bit.band(destFlags, COMBATLOG_OBJECT_CONTROL_PLAYER) > 0 then
  625. local rawName = strsplit("-", destName) -- Strip server name from players
  626. ByName[rawName] = destGUID
  627. name = rawName
  628. end
  629.  
  630. -- Cache Raid Icon Data for alternative lookup strategy
  631. for iconname, bitmask in pairs(RaidIconBit) do
  632. if bit.band(destRaidFlag, bitmask) > 0 then
  633. ByRaidIcon[iconname] = destGUID
  634. raidicon = iconname
  635. break
  636. end
  637. end
  638.  
  639. CallForWidgetUpdate(destGUID, raidicon, name)
  640. end
  641. end
  642. end
  643. end
  644.  
  645. -------------------------------------------------------------
  646. -- Widget Object Functions
  647. -------------------------------------------------------------
  648. local function DefaultFilterFunction(debuff, unit)
  649. if (debuff.duration < auraDurationFilter) then
  650. return true
  651. end
  652. end
  653.  
  654. local function UpdateWidgetTime(frame, expiration)
  655. local timeleft = expiration-GetTime()
  656. if timeleft > 60 then
  657. frame.TimeLeft:SetText(floor(timeleft/60).."m")
  658. else
  659. frame.TimeLeft:SetText(floor(timeleft))
  660. --frame.TimeLeft:SetText(floor(timeleft*10)/10)
  661. end
  662. end
  663.  
  664.  
  665. local function UpdateIcon(frame, texture, expiration, stacks)
  666. if frame and texture and expiration then
  667. -- Icon
  668. frame.Icon:SetTexture(texture)
  669.  
  670. -- Stacks
  671. if stacks > 1 then frame.Stacks:SetText(stacks)
  672. else frame.Stacks:SetText("") end
  673.  
  674. -- Expiration
  675. UpdateWidgetTime(frame, expiration)
  676. frame:Show()
  677. PolledHideIn(frame, expiration)
  678. elseif frame then
  679. PolledHideIn(frame, 0)
  680. end
  681. end
  682.  
  683. local AuraSlotspellid = {} -- auraSlot[slot] = spellid
  684. local AuraSlotPriority = {} -- auraSlot[slot] = priority
  685.  
  686. local function debuffSort(a,b) return a.priority < b.priority end
  687.  
  688. local DebuffCache = {}
  689. local CurrentAura = {}
  690.  
  691. local function UpdateIconGrid(frame, guid)
  692.  
  693. local AuraIconFrames = frame.AuraIconFrames
  694. local AurasOnUnit = GetAuraList(guid)
  695. local AuraSlotIndex = 1
  696. local instanceid
  697. local DebuffLimit = DebuffColumns * 2
  698.  
  699. DebuffCache = wipe(DebuffCache)
  700. local debuffCount = 0
  701. local currentAuraIndex = 0
  702. local aura
  703.  
  704. -- Cache displayable debuffs
  705. if AurasOnUnit then
  706. frame:Show()
  707. for instanceid in pairs(AurasOnUnit) do
  708. currentAuraIndex = debuffCount + 1
  709.  
  710. --local aura = {}
  711. CurrentAura[currentAuraIndex] = wipe(CurrentAura[currentAuraIndex] or {})
  712. aura = CurrentAura[currentAuraIndex]
  713.  
  714. aura.spellid, aura.name, aura.expiration, aura.stacks, aura.caster, aura.duration, aura.texture, aura.type, aura.reaction = GetAuraInstance(guid, instanceid)
  715.  
  716.  
  717.  
  718. if tonumber(aura.spellid) then
  719. aura.unit = frame.unit
  720.  
  721. -- Call Filter Function
  722. local show, priority = frame.Filter(aura)
  723. --local show, priority = true, 10 -- Testing
  724. aura.priority = priority or 10
  725.  
  726.  
  727. -- Get Order/Priority
  728. if show and aura.expiration > GetTime() then
  729. debuffCount = debuffCount + 1
  730. DebuffCache[debuffCount] = aura
  731. --DebuffCache[debuffCount] = instanceid
  732. end
  733.  
  734. --print("UpdateIconGrid", aura.spellid, aura.name, aura.expiration, aura.stacks, aura.caster, aura.duration, aura.texture, aura.type, aura.reaction, show, aura.priority)
  735. end
  736. end
  737. end
  738.  
  739. -- Display Auras
  740. if debuffCount > 0 then
  741. sort(DebuffCache, debuffSort)
  742. for index = 1, #DebuffCache do
  743. local cachedaura = DebuffCache[index]
  744. if cachedaura.spellid and cachedaura.expiration then
  745. --print("UpdateIcon", AuraIconFrames[AuraSlotIndex], cachedaura.texture, cachedaura.expiration, cachedaura.stacks)
  746. UpdateIcon(AuraIconFrames[AuraSlotIndex], cachedaura.texture, cachedaura.expiration, cachedaura.stacks)
  747. AuraSlotIndex = AuraSlotIndex + 1
  748. end
  749. if AuraSlotIndex > DebuffLimit then break end
  750. end
  751. end
  752.  
  753. -- Clear Extra Slots
  754. for AuraSlotIndex = AuraSlotIndex, DebuffLimit do UpdateIcon(AuraIconFrames[AuraSlotIndex]) end
  755.  
  756. DebuffCache = wipe(DebuffCache)
  757. end
  758.  
  759. function UpdateWidget(frame)
  760. -- Check for ID
  761. local unit = frame.unit
  762. if not unit then return end
  763.  
  764. local guid = unit.guid
  765.  
  766. if not guid then
  767. -- Attempt to ID widget via Name or Raid Icon
  768. if unit.type == "PLAYER" then guid = ByName[unit.name]
  769. elseif unit.isMarked then guid = ByRaidIcon[unit.raidIcon] end
  770.  
  771.  
  772. if guid then
  773. unit.guid = guid -- Feed data back into unit table -- Testing
  774. else
  775. frame:Hide()
  776. return
  777. end
  778. end
  779.  
  780. UpdateIconGrid(frame, guid)
  781. TidyPlates:RequestDelegateUpdate() -- Delegate Update, For Debuff Widget-Controlled Scale and Opacity Functions
  782. end
  783.  
  784. local function UpdateWidgetTarget(frame)
  785. UpdateIconGrid(frame, UnitGUID("target"))
  786. end
  787.  
  788.  
  789. -- Context Update (mouseover, target change)
  790. local function UpdateWidgetContextFull(frame, unit)
  791. local guid = unit.guid
  792. frame.unit = unit
  793. frame.guidcache = guid
  794.  
  795. WidgetList[frame] = true
  796. if guid then WidgetGUID[guid] = frame end
  797.  
  798. if unit.isTarget then UpdateAurasByUnitID("target")
  799. elseif unit.isMouseover then UpdateAurasByUnitID("mouseover") end
  800.  
  801. local raidicon, name
  802. if unit.isMarked then
  803. raidicon = unit.raidIcon
  804. if guid and raidicon then ByRaidIcon[raidicon] = guid end
  805. end
  806. if unit.type == "PLAYER" and unit.reaction == "HOSTILE" then name = unit.name end
  807.  
  808. CallForWidgetUpdate(guid, raidicon, name)
  809. end
  810.  
  811. local function UpdateWidgetContextTargetOnly(frame, unit)
  812. if unit.isTarget then
  813. -- UpdateAurasByUnitID("target")
  814.  
  815. end
  816. end
  817.  
  818. local UpdateWidgetContext = UpdateWidgetContextFull
  819.  
  820. local function ClearWidgetContext(frame)
  821. if frame.guidcache then
  822. WidgetGUID[frame.guidcache] = nil
  823. frame.unit = nil
  824. end
  825. WidgetList[frame] = nil
  826.  
  827. end
  828.  
  829. local function ExpireFunction(icon)
  830. UpdateWidget(icon.Parent)
  831. end
  832.  
  833. -------------------------------------------------------------
  834. -- Widget Frames
  835. -------------------------------------------------------------
  836. local WideArt = "Interface\\AddOns\\TidyPlatesWidgets\\Aura\\AuraFrameWide" -- FINISH ART
  837. local SquareArt = "Interface\\AddOns\\TidyPlatesWidgets\\Aura\\AuraFrameSquare" -- FINISH ART
  838. local AuraGlowArt = "Interface\\AddOns\\TidyPlatesWidgets\\Aura\\AuraGlow"
  839. local AuraHighlightArt = "Interface\\AddOns\\TidyPlatesWidgets\\Aura\\CCBorder" -- AuraBorderArt, AuraHighlightArt
  840. local AuraTestArt = ""
  841. --local AuraFont = "Interface\\Addons\\TidyPlates\\Media\\DefaultFont.ttf"
  842. local AuraFont = "FONTS\\ARIALN.TTF"
  843.  
  844.  
  845. local function Enable()
  846. AuraMonitor:SetScript("OnEvent", CombatEventHandler)
  847. AuraMonitor:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
  848. for event in pairs(GeneralEvents) do
  849. AuraMonitor:RegisterEvent(event)
  850. end
  851.  
  852. TidyPlatesUtility:EnableGroupWatcher()
  853. WatcherIsEnabled = true
  854.  
  855. if not TidyPlatesWidgetData.CachedAuraDurations then
  856. TidyPlatesWidgetData.CachedAuraDurations = {}
  857. end
  858. end
  859.  
  860. local function EnableForTargetOnly()
  861. AuraMonitor:UnregisterAllEvents()
  862. AuraMonitor:SetScript("OnEvent", TargetEventHandler)
  863.  
  864. -- AuraMonitor:RegisterEvent("UNIT_TARGET")
  865. AuraMonitor:RegisterEvent("UNIT_AURA")
  866.  
  867. TidyPlatesUtility:EnableGroupWatcher()
  868. WatcherIsEnabled = true
  869. end
  870.  
  871. local function Disable()
  872. AuraMonitor:SetScript("OnEvent", nil)
  873. AuraMonitor:UnregisterAllEvents()
  874. WatcherIsEnabled = false
  875. end
  876.  
  877. -- Create an Aura Icon
  878. local function CreateWideAuraIconFrame(parent)
  879. local frame = CreateFrame("Frame", nil, parent)
  880. frame.unit = nil
  881. frame.Parent = parent
  882. frame:SetWidth(26.5); frame:SetHeight(14.5)
  883. -- Icon
  884. frame.Icon = frame:CreateTexture(nil, "BACKGROUND")
  885. frame.Icon:SetAllPoints(frame)
  886. --frame.Icon:SetTexCoord(.07, 1-.07, .23, 1-.23) -- obj:SetTexCoord(left,right,top,bottom)
  887. frame.Icon:SetTexCoord(.07, 1-.07, .23, 1-.23) -- obj:SetTexCoord(left,right,top,bottom)
  888. -- Border
  889. frame.Border = frame:CreateTexture(nil, "ARTWORK")
  890. frame.Border:SetWidth(32); frame.Border:SetHeight(32)
  891. frame.Border:SetPoint("CENTER", 1, -2)
  892. frame.Border:SetTexture(WideArt)
  893. -- Glow
  894. --frame.Glow = frame:CreateTexture(nil, "ARTWORK")
  895. --frame.Glow:SetAllPoints(frame.Border)
  896. --frame.Glow:SetTexture(AuraGlowArt)
  897. -- Time Text
  898. frame.TimeLeft = frame:CreateFontString(nil, "OVERLAY")
  899. frame.TimeLeft:SetFont(AuraFont ,9, "OUTLINE")
  900. frame.TimeLeft:SetShadowOffset(1, -1)
  901. frame.TimeLeft:SetShadowColor(0,0,0,1)
  902. frame.TimeLeft:SetPoint("RIGHT", 0, 8)
  903. frame.TimeLeft:SetWidth(26)
  904. frame.TimeLeft:SetHeight(16)
  905. frame.TimeLeft:SetJustifyH("RIGHT")
  906. -- Stacks
  907. frame.Stacks = frame:CreateFontString(nil, "OVERLAY")
  908. frame.Stacks:SetFont(AuraFont,10, "OUTLINE")
  909. frame.Stacks:SetShadowOffset(1, -1)
  910. frame.Stacks:SetShadowColor(0,0,0,1)
  911. frame.Stacks:SetPoint("RIGHT", 0, -6)
  912. frame.Stacks:SetWidth(26)
  913. frame.Stacks:SetHeight(16)
  914. frame.Stacks:SetJustifyH("RIGHT")
  915. -- Information about the currently displayed aura
  916. frame.AuraInfo = {
  917. Name = "",
  918. Icon = "",
  919. Stacks = 0,
  920. Expiration = 0,
  921. Type = "",
  922. }
  923. --frame.Poll = UpdateWidgetTime
  924. frame.Expire = ExpireFunction
  925. -- UpdateWidget(frame)
  926. frame.Poll = parent.PollFunction
  927. frame:Hide()
  928. return frame
  929. end
  930.  
  931.  
  932. -- Create an Aura Icon
  933. local function CreateSquareAuraIconFrame(parent)
  934. local frame = CreateFrame("Frame", nil, parent)
  935. frame.Parent = parent
  936. frame:SetWidth(25); frame:SetHeight(20)
  937. -- Icon
  938. frame.Icon = frame:CreateTexture(nil, "BACKGROUND")
  939. frame.Icon:SetAllPoints(frame)
  940. frame.Icon:SetTexCoord(.07, 1-.07, .23, 1-.23) -- obj:SetTexCoord(left,right,top,bottom)
  941. -- Border
  942. -- [[
  943. frame.Border = frame:CreateTexture(nil, "ARTWORK")
  944. frame.Border:SetWidth(47); frame.Border:SetHeight(44)
  945. frame.Border:SetPoint("CENTER", 1, -2)
  946. frame.Border:SetTexture(SquareArt)
  947. --]]
  948. -- Time Text
  949. frame.TimeLeft = frame:CreateFontString(nil, "OVERLAY")
  950. frame.TimeLeft:SetFont(AuraFont ,9, "OUTLINE")
  951. frame.TimeLeft:SetShadowOffset(1, -1)
  952. frame.TimeLeft:SetShadowColor(0,0,0,1)
  953. frame.TimeLeft:SetPoint("RIGHT", 0, 8)
  954. frame.TimeLeft:SetWidth(26)
  955. frame.TimeLeft:SetHeight(16)
  956. frame.TimeLeft:SetJustifyH("RIGHT")
  957. -- Stacks
  958. frame.Stacks = frame:CreateFontString(nil, "OVERLAY")
  959. frame.Stacks:SetFont(AuraFont,10, "OUTLINE")
  960. frame.Stacks:SetShadowOffset(1, -1)
  961. frame.Stacks:SetShadowColor(0,0,0,1)
  962. frame.Stacks:SetPoint("RIGHT", 0, -6)
  963. frame.Stacks:SetWidth(26)
  964. frame.Stacks:SetHeight(16)
  965. frame.Stacks:SetJustifyH("RIGHT")
  966. -- Information about the currently displayed aura
  967. frame.AuraInfo = {
  968. Name = "",
  969. Icon = "",
  970. Stacks = 0,
  971. Expiration = 0,
  972. Type = "",
  973. }
  974. --frame.Poll = UpdateWidgetTime
  975. frame.Poll = parent.PollFunction
  976. frame:Hide()
  977. return frame
  978. end
  979.  
  980. local CreateIconFrame = CreateWideAuraIconFrame
  981.  
  982. -- Create the Main Widget Body and Icon Array
  983. local function CreateAuraWidget(parent, style)
  984. --if not WatcherIsEnabled then Enable() end
  985. -- Create Base frame
  986. local frame = CreateFrame("Frame", nil, parent)
  987. frame:SetWidth(128); frame:SetHeight(32); frame:Show()
  988. -- Create Icon Array
  989. frame.PollFunction = UpdateWidgetTime
  990. frame.AuraIconFrames = {}
  991. local AuraIconFrames = frame.AuraIconFrames
  992.  
  993. local DebuffLimit = DebuffColumns * 2
  994.  
  995. for index = 1, DebuffLimit do AuraIconFrames[index] = CreateIconFrame(frame); end
  996. -- Set Anchors
  997. AuraIconFrames[1]:SetPoint("LEFT", frame)
  998. for index = 2, DebuffColumns do AuraIconFrames[index]:SetPoint("LEFT", AuraIconFrames[index-1], "RIGHT", 5, 0) end
  999. AuraIconFrames[DebuffColumns+1]:SetPoint("BOTTOMLEFT", AuraIconFrames[1], "TOPLEFT", 0, 8)
  1000. for index = (DebuffColumns+2), DebuffLimit do AuraIconFrames[index]:SetPoint("LEFT", AuraIconFrames[index-1], "RIGHT", 5, 0) end
  1001. -- Functions
  1002. frame._Hide = frame.Hide
  1003. frame.Hide = function() ClearWidgetContext(frame); frame:_Hide() end
  1004. frame:SetScript("OnHide", function() for index = 1, 4 do PolledHideIn(AuraIconFrames[index], 0) end end)
  1005. frame.Filter = DefaultFilterFunction
  1006. frame.UpdateContext = UpdateWidgetContext
  1007. frame.Update = UpdateWidgetContext
  1008. frame.UpdateTarget = UpdateWidgetTarget
  1009. return frame
  1010. end
  1011.  
  1012. local function UseSquareDebuffIcon()
  1013. CreateIconFrame = CreateSquareAuraIconFrame
  1014. DebuffColumns = 5
  1015. TidyPlates:ForceUpdate()
  1016. end
  1017.  
  1018. local function UseWideDebuffIcon()
  1019. CreateIconFrame = CreateWideAuraIconFrame
  1020. DebuffColumns = 3
  1021. TidyPlates:ForceUpdate()
  1022. end
  1023.  
  1024. local function SetPrefilter(func)
  1025. DebuffPrefilter = func or DefaultDebuffPreFilter
  1026. end
  1027.  
  1028. -----------------------------------------------------
  1029. -- External
  1030. -----------------------------------------------------
  1031. TidyPlatesWidgets.GetAuraWidgetByGUID = GetAuraWidgetByGUID
  1032. TidyPlatesWidgets.IsAuraShown = IsAuraShown
  1033. TidyPlatesWidgets.CanPlayerDispel = CanPlayerDispel
  1034.  
  1035. TidyPlatesWidgets.UseSquareDebuffIcon = UseSquareDebuffIcon
  1036. TidyPlatesWidgets.UseWideDebuffIcon = UseWideDebuffIcon
  1037. TidyPlatesWidgets.SetDebuffPrefilter = SetPrefilter
  1038.  
  1039. TidyPlatesWidgets.CreateAuraWidget = CreateAuraWidget
  1040.  
  1041. TidyPlatesWidgets.EnableAuraWatcher = Enable
  1042. TidyPlatesWidgets.EnableAuraWatcherTargetOnly = EnableForTargetOnly
  1043. TidyPlatesWidgets.DisableAuraWatcher = Disable
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement