PageRenderTime 144ms CodeModel.GetById 80ms app.highlight 12ms RepoModel.GetById 49ms app.codeStats 0ms

/Tukui/modules/unitframes/plugins/oUF_RaidDebuffs/oUF_RaidDebuffs.lua

http://github.com/Asphyxia/Tukui
Lua | 278 lines | 230 code | 38 blank | 10 comment | 41 complexity | 050037714c20ebd521168996933a9c4f MD5 | raw file
  1local T, C, L = unpack(select(2, ...)) -- Import: T - functions, constants, variables; C - config; L - locales
  2-- yleaf (yaroot@gmail.com)
  3
  4if C.unitframes.enable ~= true or C.unitframes.raidunitdebuffwatch ~= true then return end
  5
  6local _, ns = ...
  7local oUF = ns.oUF or oUF
  8
  9local addon = {}
 10ns.oUF_RaidDebuffs = addon
 11if not _G.oUF_RaidDebuffs then
 12	_G.oUF_RaidDebuffs = addon
 13end
 14
 15local debuff_data = {}
 16addon.DebuffData = debuff_data
 17
 18
 19addon.ShowDispelableDebuff = true
 20addon.FilterDispellableDebuff = true
 21addon.MatchBySpellName = true
 22
 23
 24addon.priority = 10
 25
 26local function add(spell)
 27	if addon.MatchBySpellName and type(spell) == 'number' then
 28		spell = GetSpellInfo(spell)
 29	end
 30	
 31	debuff_data[spell] = addon.priority
 32	addon.priority = addon.priority + 1
 33end
 34
 35function addon:RegisterDebuffs(t)
 36	for _, v in next, t do
 37		add(v)
 38	end
 39end
 40
 41function addon:ResetDebuffData()
 42	wipe(debuff_data)
 43	addon.priority = 10
 44end
 45
 46local DispellColor = {
 47	['Magic']	= {.2, .6, 1},
 48	['Curse']	= {.6, 0, 1},
 49	['Disease']	= {.6, .4, 0},
 50	['Poison']	= {0, .6, 0},
 51	['none'] = {unpack(C.media.bordercolor)},
 52}
 53
 54local DispellPriority = {
 55	['Magic']	= 4,
 56	['Curse']	= 3,
 57	['Disease']	= 2,
 58	['Poison']	= 1,
 59}
 60
 61local DispellFilter
 62do
 63	local dispellClasses = {
 64		['PRIEST'] = {
 65			['Magic'] = true,
 66			['Disease'] = true,
 67		},
 68		['SHAMAN'] = {
 69			['Magic'] = false,
 70			['Curse'] = true,
 71		},
 72		['PALADIN'] = {
 73			['Poison'] = true,
 74			['Magic'] = false,
 75			['Disease'] = true,
 76		},
 77		['MAGE'] = {
 78			['Curse'] = true,
 79		},
 80		['DRUID'] = {
 81			['Magic'] = false,
 82			['Curse'] = true,
 83			['Poison'] = true,
 84		},
 85	}
 86	
 87	DispellFilter = dispellClasses[select(2, UnitClass('player'))] or {}
 88end
 89
 90-- Return true if the talent matching the name of the spell given by (Credit Pitbull4)
 91-- spellid has at least one point spent in it or false otherwise
 92local function CheckForKnownTalent(spellid)
 93	local wanted_name = GetSpellInfo(spellid)
 94	if not wanted_name then return nil end
 95	local num_tabs = GetNumTalentTabs()
 96	for t=1, num_tabs do
 97		local num_talents = GetNumTalents(t)
 98		for i=1, num_talents do
 99			local name_talent, _, _, _, current_rank = GetTalentInfo(t,i)
100			if name_talent and (name_talent == wanted_name) then
101				if current_rank and (current_rank > 0) then
102					return true
103				else
104					return false
105				end
106			end
107		end
108	end
109	return false
110end
111
112local function CheckSpec(self, event, levels)
113	-- Not interested in gained points from leveling	
114	if event == "CHARACTER_POINTS_CHANGED" and levels > 0 then return end
115	
116	--Check for certain talents to see if we can dispel magic or not
117	if select(2, UnitClass('player')) == "PALADIN" then
118		--Check to see if we have the 'Sacred Cleansing' talent.
119		if CheckForKnownTalent(53551) then
120			DispellFilter.Magic = true
121		else
122			DispellFilter.Magic = false	
123		end
124	elseif select(2, UnitClass('player')) == "SHAMAN" then
125		--Check to see if we have the 'Improved Cleanse Spirit' talent.
126		if CheckForKnownTalent(77130) then
127			DispellFilter.Magic = true
128		else
129			DispellFilter.Magic = false	
130		end
131	elseif select(2, UnitClass('player')) == "DRUID" then
132		--Check to see if we have the 'Nature's Cure' talent.
133		if CheckForKnownTalent(88423) then
134			DispellFilter.Magic = true
135		else
136			DispellFilter.Magic = false	
137		end
138	end
139end
140
141
142local function formatTime(s)
143	if s > 60 then
144		return format('%dm', s/60), s%60
145	elseif s < 1 then
146		return format("%.1f", s), s - floor(s)
147	else
148		return format('%d', s), s - floor(s)
149	end
150end
151
152local abs = math.abs
153local function OnUpdate(self, elapsed)
154	self.elapsed = (self.elapsed or 0) + elapsed
155	if self.elapsed >= 0.1 then
156		local timeLeft = self.endTime - GetTime()
157		if self.reverse then timeLeft = abs((self.endTime - GetTime()) - self.duration) end
158		if timeLeft > 0 then
159			local text = formatTime(timeLeft)
160			self.time:SetText(text)
161		else
162			self:SetScript('OnUpdate', nil)
163			self.time:Hide()
164		end
165		self.elapsed = 0
166	end
167end
168
169local function UpdateDebuff(self, name, icon, count, debuffType, duration, endTime, spellId)
170	local f = self.RaidDebuffs
171	if name then
172		f.icon:SetTexture(icon)
173		f.icon:Show()
174		f.duration = duration
175		
176		if f.count then
177			if count and (count > 0) then
178				f.count:SetText(count)
179				f.count:Show()
180			else
181				f.count:Hide()
182			end
183		end
184		
185		if spellId and T.ReverseTimer[spellId] then
186			f.reverse = true
187		else
188			f.reverse = nil
189		end
190		
191		if f.time then
192			if duration and (duration > 0) then
193				f.endTime = endTime
194				f.nextUpdate = 0
195				f:SetScript('OnUpdate', OnUpdate)
196				f.time:Show()
197			else
198				f:SetScript('OnUpdate', nil)
199				f.time:Hide()
200			end
201		end
202		
203		if f.cd then
204			if duration and (duration > 0) then
205				f.cd:SetCooldown(endTime - duration, duration)
206				f.cd:Show()
207			else
208				f.cd:Hide()
209			end
210		end
211		
212		local c = DispellColor[debuffType] or DispellColor.none
213		f:SetBackdropBorderColor(c[1], c[2], c[3])
214		
215		f:Show()
216	else
217		f:Hide()
218	end
219end
220
221local function Update(self, event, unit)
222	if unit ~= self.unit then return end
223	local _name, _icon, _count, _dtype, _duration, _endTime, _spellId
224	local _priority, priority = 0
225	for i = 1, 40 do
226		local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellId = UnitAura(unit, i, 'HARMFUL')
227		if (not name) then break end
228		
229		if addon.ShowDispelableDebuff and debuffType then
230			if addon.FilterDispellableDebuff then
231				DispellPriority[debuffType] = DispellPriority[debuffType] + addon.priority --Make Dispell buffs on top of Boss Debuffs
232				priority = DispellFilter[debuffType] and DispellPriority[debuffType]
233			else
234				priority = DispellPriority[debuffType]
235			end
236			
237			if priority and (priority > _priority) then
238				_priority, _name, _icon, _count, _dtype, _duration, _endTime, _spellId = priority, name, icon, count, debuffType, duration, expirationTime, spellId
239			end
240		end
241		
242		priority = debuff_data[addon.MatchBySpellName and name or spellId]
243		if priority and (priority > _priority) then
244			_priority, _name, _icon, _count, _dtype, _duration, _endTime, _spellId = priority, name, icon, count, debuffType, duration, expirationTime, spellId
245		end
246	end
247	
248	UpdateDebuff(self, _name, _icon, _count, _dtype, _duration, _endTime, _spellId)
249	
250	--Reset the DispellPriority
251	DispellPriority = {
252		['Magic']	= 4,
253		['Curse']	= 3,
254		['Disease']	= 2,
255		['Poison']	= 1,
256	}	
257end
258
259local function Enable(self)
260	if self.RaidDebuffs then
261		self:RegisterEvent('UNIT_AURA', Update)
262		return true
263	end
264	--Need to run these always
265	self:RegisterEvent("PLAYER_TALENT_UPDATE", CheckSpec)
266	self:RegisterEvent("CHARACTER_POINTS_CHANGED", CheckSpec)
267end
268
269local function Disable(self)
270	if self.RaidDebuffs then
271		self:UnregisterEvent('UNIT_AURA', Update)
272		self.RaidDebuffs:Hide()
273	end
274	self:UnregisterEvent("PLAYER_TALENT_UPDATE", CheckSpec)
275	self:UnregisterEvent("CHARACTER_POINTS_CHANGED", CheckSpec)
276end
277
278oUF:AddElement('RaidDebuffs', Update, Enable, Disable)