PageRenderTime 302ms CodeModel.GetById 81ms app.highlight 121ms RepoModel.GetById 61ms app.codeStats 1ms

/Tukui/modules/actionbars/Range.lua

http://github.com/Asphyxia/Tukui
Lua | 322 lines | 245 code | 51 blank | 26 comment | 39 complexity | cd2cb360f66368f6c71a6c7b6a07a07c MD5 | raw file
  1local T, C, L = unpack(select(2, ...)) -- Import: T - functions, constants, variables; C - config; L - locales
  2--[[
  3	Thx to Tulla
  4		Adds out of range coloring to action buttons
  5		Derived from RedRange and TullaRange
  6--]]
  7
  8if not C["actionbar"].enable == true then return end
  9
 10--locals and speed
 11local _G = _G
 12local UPDATE_DELAY = 0.15
 13local ATTACK_BUTTON_FLASH_TIME = ATTACK_BUTTON_FLASH_TIME
 14local SPELL_POWER_HOLY_POWER = SPELL_POWER_HOLY_POWER
 15local ActionButton_GetPagedID = ActionButton_GetPagedID
 16local ActionButton_IsFlashing = ActionButton_IsFlashing
 17local ActionHasRange = ActionHasRange
 18local IsActionInRange = IsActionInRange
 19local IsUsableAction = IsUsableAction
 20local HasAction = HasAction
 21
 22--code for handling defaults
 23local function removeDefaults(tbl, defaults)
 24	for k, v in pairs(defaults) do
 25		if type(tbl[k]) == 'table' and type(v) == 'table' then
 26			removeDefaults(tbl[k], v)
 27			if next(tbl[k]) == nil then
 28				tbl[k] = nil
 29			end
 30		elseif tbl[k] == v then
 31			tbl[k] = nil
 32		end
 33	end
 34	return tbl
 35end
 36
 37local function copyDefaults(tbl, defaults)
 38	for k, v in pairs(defaults) do
 39		if type(v) == 'table' then
 40			tbl[k] = copyDefaults(tbl[k] or {}, v)
 41		elseif tbl[k] == nil then
 42			tbl[k] = v
 43		end
 44	end
 45	return tbl
 46end
 47
 48local function timer_Create(parent, interval)
 49	local updater = parent:CreateAnimationGroup()
 50	updater:SetLooping('NONE')
 51	updater:SetScript('OnFinished', function(self)
 52		if parent:Update() then
 53			parent:Start(interval)
 54		end
 55	end)
 56
 57	local a = updater:CreateAnimation('Animation'); a:SetOrder(1)
 58
 59	parent.Start = function(self)
 60		self:Stop()
 61		a:SetDuration(interval)
 62		updater:Play()
 63		return self
 64	end
 65
 66	parent.Stop = function(self)
 67		if updater:IsPlaying() then
 68			updater:Stop()
 69		end
 70		return self
 71	end
 72
 73	parent.Active = function(self)
 74		return updater:IsPlaying()
 75	end
 76
 77	return parent
 78end
 79
 80--stuff for holy power detection
 81local PLAYER_IS_PALADIN = select(2, UnitClass('player')) == 'PALADIN'
 82local HAND_OF_LIGHT = GetSpellInfo(90174)
 83local isHolyPowerAbility
 84do
 85	local HOLY_POWER_SPELLS = {
 86		[85256] = GetSpellInfo(85256), --Templar's Verdict
 87		[53600] = GetSpellInfo(53600), --Shield of the Righteous
 88		-- [84963] = GetSpellInfo(84963), --Inquisition
 89		-- [85673] = GetSpellInfo(85673), --Word of Glory
 90		-- [85222] = GetSpellInfo(85222), --Light of Dawn
 91	}
 92
 93	isHolyPowerAbility = function(actionId)
 94		local actionType, id = GetActionInfo(actionId)
 95		if actionType == 'macro' then
 96			local macroSpell = GetMacroSpell(id)
 97			if macroSpell then
 98				for spellId, spellName in pairs(HOLY_POWER_SPELLS) do
 99					if macroSpell == spellName then
100						return true
101					end
102				end
103			end
104		else
105			return HOLY_POWER_SPELLS[id]
106		end
107		return false
108	end
109end
110
111--[[ The main thing ]]--
112local TukuiRange = timer_Create(CreateFrame('Frame', 'TukuiRange'), UPDATE_DELAY)
113
114function TukuiRange:Load()
115	self:SetScript('OnEvent', self.OnEvent)
116	self:RegisterEvent('PLAYER_LOGIN')
117	self:RegisterEvent('PLAYER_LOGOUT')
118end
119
120
121--[[ Frame Events ]]--
122function TukuiRange:OnEvent(event, ...)
123	local action = self[event]
124	if action then
125		action(self, event, ...)
126	end
127end
128
129--[[ Game Events ]]--
130function TukuiRange:PLAYER_LOGIN()
131	if not TukuiRange_COLORS then
132		TukuiRange_COLORS = {}
133	end
134	self.colors = copyDefaults(TukuiRange_COLORS, self:GetDefaults())
135
136	--add options loader
137	local f = CreateFrame('Frame', nil, InterfaceOptionsFrame)
138	f:SetScript('OnShow', function(self)
139		self:SetScript('OnShow', nil)
140		LoadAddOn('TukuiRange_Config')
141	end)
142
143	self.buttonsToUpdate = {}
144
145	hooksecurefunc('ActionButton_OnUpdate', self.RegisterButton)
146	hooksecurefunc('ActionButton_UpdateUsable', self.OnUpdateButtonUsable)
147	hooksecurefunc('ActionButton_Update', self.OnButtonUpdate)
148end
149
150function TukuiRange:PLAYER_LOGOUT()
151	removeDefaults(TukuiRange_COLORS, self:GetDefaults())
152end
153
154--[[ Actions ]]--
155function TukuiRange:Update()
156	return self:UpdateButtons(UPDATE_DELAY)
157end
158
159function TukuiRange:ForceColorUpdate()
160	for button in pairs(self.buttonsToUpdate) do
161		TukuiRange.OnUpdateButtonUsable(button)
162	end
163end
164
165function TukuiRange:UpdateActive()
166	if next(self.buttonsToUpdate) then
167		if not self:Active() then
168			self:Start()
169		end
170	else
171		self:Stop()
172	end
173end
174
175function TukuiRange:UpdateButtons(elapsed)
176	if next(self.buttonsToUpdate) then
177		for button in pairs(self.buttonsToUpdate) do
178			self:UpdateButton(button, elapsed)
179		end
180		return true
181	end
182	return false
183end
184
185function TukuiRange:UpdateButton(button, elapsed)
186	TukuiRange.UpdateButtonUsable(button)
187	TukuiRange.UpdateFlash(button, elapsed)
188end
189
190function TukuiRange:UpdateButtonStatus(button)
191	local action = ActionButton_GetPagedID(button)
192	if button:IsVisible() and action and HasAction(action) and ActionHasRange(action) then
193		self.buttonsToUpdate[button] = true
194	else
195		self.buttonsToUpdate[button] = nil
196	end
197	self:UpdateActive()
198end
199
200--[[ Button Hooking ]]--
201function TukuiRange.RegisterButton(button)
202	button:HookScript('OnShow', TukuiRange.OnButtonShow)
203	button:HookScript('OnHide', TukuiRange.OnButtonHide)
204	button:SetScript('OnUpdate', nil)
205
206	TukuiRange:UpdateButtonStatus(button)
207end
208
209function TukuiRange.OnButtonShow(button)
210	TukuiRange:UpdateButtonStatus(button)
211end
212
213function TukuiRange.OnButtonHide(button)
214	TukuiRange:UpdateButtonStatus(button)
215end
216
217function TukuiRange.OnUpdateButtonUsable(button)
218	button.TukuiRangeColor = nil
219	TukuiRange.UpdateButtonUsable(button)
220end
221
222function TukuiRange.OnButtonUpdate(button)
223	 TukuiRange:UpdateButtonStatus(button)
224end
225
226--[[ Range Coloring ]]--
227function TukuiRange.UpdateButtonUsable(button)
228	local action = ActionButton_GetPagedID(button)
229	local isUsable, notEnoughMana = IsUsableAction(action)
230
231	--usable
232	if isUsable then
233		--but out of range
234		if IsActionInRange(action) == 0 then
235			TukuiRange.SetButtonColor(button, 'oor')
236		--a holy power abilty, and we're less than 3 Holy Power
237		elseif PLAYER_IS_PALADIN and isHolyPowerAbility(action) and not(UnitPower('player', SPELL_POWER_HOLY_POWER) == 3 or UnitBuff('player', HAND_OF_LIGHT)) then
238			TukuiRange.SetButtonColor(button, 'ooh')
239		--in range
240		else
241			TukuiRange.SetButtonColor(button, 'normal')
242		end
243	--out of mana
244	elseif notEnoughMana then
245		TukuiRange.SetButtonColor(button, 'oom')
246	--unusable
247	else
248		button.TukuiRangeColor = 'unusuable'
249	end
250end
251
252function TukuiRange.SetButtonColor(button, colorType)
253	if button.TukuiRangeColor ~= colorType then
254		button.TukuiRangeColor = colorType
255
256		local r, g, b = TukuiRange:GetColor(colorType)
257
258		local icon =  _G[button:GetName() .. 'Icon']
259		icon:SetVertexColor(r, g, b)
260
261		local nt = button:GetNormalTexture()
262		nt:SetVertexColor(r, g, b)
263	end
264end
265
266function TukuiRange.UpdateFlash(button, elapsed)
267	if ActionButton_IsFlashing(button) then
268		local flashtime = button.flashtime - elapsed
269
270		if flashtime <= 0 then
271			local overtime = -flashtime
272			if overtime >= ATTACK_BUTTON_FLASH_TIME then
273				overtime = 0
274			end
275			flashtime = ATTACK_BUTTON_FLASH_TIME - overtime
276
277			local flashTexture = _G[button:GetName() .. 'Flash']
278			if flashTexture:IsShown() then
279				flashTexture:Hide()
280			else
281				flashTexture:Show()
282			end
283		end
284
285		button.flashtime = flashtime
286	end
287end
288
289
290--[[ Configuration ]]--
291function TukuiRange:GetDefaults()
292	return {
293		normal = {1, 1, 1},
294		oor = {1, 0.1, 0.1},
295		oom = {0.1, 0.3, 1},
296		ooh = {0.45, 0.45, 1},
297	}
298end
299
300function TukuiRange:Reset()
301	TukuiRange_COLORS = {}
302	self.colors = copyDefaults(TukuiRange_COLORS, self:GetDefaults())
303
304	self:ForceColorUpdate()
305end
306
307function TukuiRange:SetColor(index, r, g, b)
308	local color = self.colors[index]
309	color[1] = r
310	color[2] = g
311	color[3] = b
312
313	self:ForceColorUpdate()
314end
315
316function TukuiRange:GetColor(index)
317	local color = self.colors[index]
318	return color[1], color[2], color[3]
319end
320
321--[[ Load The Thing ]]--
322TukuiRange:Load()