Cooldowns.lua 12.1 KB
Newer Older
1
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
2
local AB = E:GetModule('ActionBars')
Elv's avatar
Elv committed
3

4
--Lua functions
5
local next, ipairs, pairs = next, ipairs, pairs
6
local floor, tinsert = floor, tinsert
7
--WoW API / Variables
8 9 10
local GetTime = GetTime
local CreateFrame = CreateFrame
local hooksecurefunc = hooksecurefunc
11

Elv's avatar
Elv committed
12
local ICON_SIZE = 36 --the normal size for an icon (don't change this)
Elv's avatar
Elv committed
13
local FONT_SIZE = 20 --the base font size to use at a scale of 1
Elv's avatar
Elv committed
14
local MIN_SCALE = 0.5 --the minimum scale we want to show cooldown counts at, anything below this will be hidden
Elv's avatar
Elv committed
15
local MIN_DURATION = 1.5 --the minimum duration to show cooldown text for
16

17 18 19
function E:Cooldown_OnUpdate(elapsed)
	if self.nextUpdate > 0 then
		self.nextUpdate = self.nextUpdate - elapsed
Elv's avatar
Elv committed
20 21 22
		return
	end

23 24 25 26 27
	if not E:Cooldown_IsEnabled(self) then
		E:Cooldown_StopTimer(self)
	else
		local remain = self.duration - (GetTime() - self.start)
		if remain > 0.05 then
28
			if self.parent.hideText or (self.fontScale and (self.fontScale < MIN_SCALE)) then
29
				self.text:SetText('')
30 31
				self.nextUpdate = 500
			else
32
				local timeColors, timeThreshold = (self.timerOptions and self.timerOptions.timeColors) or E.TimeColors, (self.timerOptions and self.timerOptions.timeThreshold) or E.db.cooldown.threshold
33 34
				if not timeThreshold then timeThreshold = E.TimeThreshold end

35 36
				local hhmmThreshold = (self.timerOptions and self.timerOptions.hhmmThreshold) or (E.db.cooldown.checkSeconds and E.db.cooldown.hhmmThreshold)
				local mmssThreshold = (self.timerOptions and self.timerOptions.mmssThreshold) or (E.db.cooldown.checkSeconds and E.db.cooldown.mmssThreshold)
37 38 39 40

				local value1, formatid, nextUpdate, value2 = E:GetTimeInfo(remain, timeThreshold, hhmmThreshold, mmssThreshold)
				self.nextUpdate = nextUpdate
				self.text:SetFormattedText(("%s%s|r"):format(timeColors[formatid], E.TimeFormats[formatid][2]), value1, value2)
41
			end
42 43
		else
			E:Cooldown_StopTimer(self)
Elv's avatar
Elv committed
44 45 46 47
		end
	end
end

48
function E:Cooldown_OnSizeChanged(cd, width, force)
49
	local fontScale = width and (floor(width + .5) / ICON_SIZE)
50

51
	if fontScale and (fontScale == cd.fontScale) and (force ~= true) then return end
Simpy's avatar
Simpy committed
52
	cd.fontScale = fontScale
53

Simpy's avatar
Simpy committed
54
	if fontScale and (fontScale < MIN_SCALE) then
55 56 57
		cd:Hide()
	else
		local text = cd.text or cd.time
58
		if text then
Azilroka's avatar
Azilroka committed
59
			local useCustomFont = (cd.timerOptions and cd.timerOptions.fontOptions and cd.timerOptions.fontOptions.enable) and E.Libs.LSM:Fetch("font", cd.timerOptions.fontOptions.font)
60
			if useCustomFont then
Simpy's avatar
Simpy committed
61
				text:FontTemplate(useCustomFont, (fontScale * cd.timerOptions.fontOptions.fontSize), cd.timerOptions.fontOptions.fontOutline)
62 63
			elseif fontScale then
				text:FontTemplate(nil, (fontScale * FONT_SIZE), 'OUTLINE')
64
			end
65
		end
66

67
		if cd.enabled and (force ~= true) then
Simpy's avatar
Simpy committed
68
			self:Cooldown_ForceUpdate(cd)
Elv's avatar
Elv committed
69 70 71 72
		end
	end
end

73
function E:Cooldown_IsEnabled(cd)
74
	if cd.forceEnabled then
75
		return true
76
	elseif cd.forceDisabled then
77
		return false
78
	elseif cd.timerOptions and (cd.timerOptions.reverseToggle ~= nil) then
79
		return (E.db.cooldown.enable and not cd.timerOptions.reverseToggle) or (not E.db.cooldown.enable and cd.timerOptions.reverseToggle)
Simpy's avatar
Simpy committed
80
	else
81
		return E.db.cooldown.enable
Simpy's avatar
Simpy committed
82
	end
83 84
end

85
function E:Cooldown_ForceUpdate(cd)
Simpy's avatar
-1  
Simpy committed
86
	cd.nextUpdate = -1
Simpy's avatar
Simpy committed
87

Simpy's avatar
Simpy committed
88
	if cd.fontScale and (cd.fontScale >= MIN_SCALE) then
Simpy's avatar
Simpy committed
89 90
		cd:Show()
	end
Elv's avatar
Elv committed
91 92
end

93
function E:Cooldown_StopTimer(cd)
Elv's avatar
Elv committed
94 95 96 97
	cd.enabled = nil
	cd:Hide()
end

98
function E:CreateCooldownTimer(parent)
99
	local timer = CreateFrame('Frame', nil, parent)
100
	timer:Hide()
Elv's avatar
Elv committed
101
	timer:SetAllPoints()
102
	timer.parent = parent
103
	parent.timer = timer
Elv's avatar
Elv committed
104 105

	local text = timer:CreateFontString(nil, 'OVERLAY')
106
	text:Point('CENTER', 1, 1)
Elv's avatar
Elv committed
107 108 109
	text:SetJustifyH("CENTER")
	timer.text = text

110 111 112
	-- can be used to modify elements created from this function
	if parent.CooldownPreHook then
		parent.CooldownPreHook(parent)
113 114
	end

115
	-- cooldown override settings
116 117
	if parent.CooldownOverride then
		local db = E.db[parent.CooldownOverride]
118
		if db and db.cooldown then
119 120
			if not timer.timerOptions then
				timer.timerOptions = {}
121 122
			end

123
			timer.timerOptions.reverseToggle = db.cooldown.reverse
124
			timer.timerOptions.hideBlizzard = db.cooldown.hideBlizzard
125

126
			if db.cooldown.override and E.TimeColors[parent.CooldownOverride] then
127
				timer.timerOptions.timeColors, timer.timerOptions.timeThreshold = E.TimeColors[parent.CooldownOverride], db.cooldown.threshold
128
			else
129
				timer.timerOptions.timeColors, timer.timerOptions.timeThreshold = nil, nil
130 131
			end

132
			if db.cooldown.checkSeconds then
133
				timer.timerOptions.hhmmThreshold, timer.timerOptions.mmssThreshold = db.cooldown.hhmmThreshold, db.cooldown.mmssThreshold
134
			else
135
				timer.timerOptions.hhmmThreshold, timer.timerOptions.mmssThreshold = nil, nil
136 137
			end

138
			if (db.cooldown ~= self.db.cooldown) and db.cooldown.fonts and db.cooldown.fonts.enable then
139
				timer.timerOptions.fontOptions = db.cooldown.fonts
140
			elseif self.db.cooldown.fonts and self.db.cooldown.fonts.enable then
141
				timer.timerOptions.fontOptions = self.db.cooldown.fonts
142
			else
143
				timer.timerOptions.fontOptions = nil
144
			end
Simpy's avatar
Simpy committed
145 146 147 148 149

			-- prevent LibActionBar from showing blizzard CD when the CD timer is created
			if AB and (parent.CooldownOverride == 'actionbar') then
				AB:ToggleCountDownNumbers(nil, nil, parent)
			end
150
		end
Simpy's avatar
Simpy committed
151
	end
152
	----------
Simpy's avatar
Simpy committed
153

Simpy's avatar
Simpy committed
154 155
	E:ToggleBlizzardCooldownText(parent, timer)

156
	-- keep an eye on the size so we can rescale the font if needed
157 158 159
	self:Cooldown_OnSizeChanged(timer, parent:GetWidth())
	parent:SetScript('OnSizeChanged', function(_, width)
		self:Cooldown_OnSizeChanged(timer, width)
160 161
	end)

Simpy's avatar
Simpy committed
162 163 164
	-- keep this after Cooldown_OnSizeChanged
	timer:SetScript('OnUpdate', E.Cooldown_OnUpdate)

Elv's avatar
Elv committed
165 166 167
	return timer
end

168
E.RegisteredCooldowns = {}
169
function E:OnSetCooldown(start, duration)
170
	if (not self.forceDisabled) and (start and duration) and (duration > MIN_DURATION) then
171
		local timer = self.timer or E:CreateCooldownTimer(self)
Elv's avatar
Elv committed
172 173 174
		timer.start = start
		timer.duration = duration
		timer.enabled = true
Simpy's avatar
-1  
Simpy committed
175
		timer.nextUpdate = -1
Simpy's avatar
Simpy committed
176

Simpy's avatar
Simpy committed
177
		if timer.fontScale and (timer.fontScale >= MIN_SCALE) then
178 179
			timer:Show()
		end
Simpy's avatar
Simpy committed
180 181
	elseif self.timer then
		E:Cooldown_StopTimer(self.timer)
Elv's avatar
Elv committed
182 183 184
	end
end

185
function E:RegisterCooldown(cooldown)
186 187 188 189 190 191
	if not cooldown.isHooked then
		hooksecurefunc(cooldown, "SetCooldown", E.OnSetCooldown)
		cooldown.isHooked = true
	end

	if not cooldown.isRegisteredCooldown then
192
		local module = (cooldown.CooldownOverride or 'global')
193 194 195 196 197
		if not E.RegisteredCooldowns[module] then E.RegisteredCooldowns[module] = {} end

		tinsert(E.RegisteredCooldowns[module], cooldown)
		cooldown.isRegisteredCooldown = true
	end
Elv's avatar
Elv committed
198 199
end

200
function E:ToggleBlizzardCooldownText(cd, timer, request)
201 202
	-- we should hide the blizzard cooldown text when ours are enabled
	if timer and cd and cd.SetHideCountdownNumbers then
203
		local forceHide = cd.hideText or (timer.timerOptions and timer.timerOptions.hideBlizzard) or (E.db and E.db.cooldown and E.db.cooldown.hideBlizzard)
204 205 206 207 208
		if request then
			return forceHide or E:Cooldown_IsEnabled(timer)
		else
			cd:SetHideCountdownNumbers(forceHide or E:Cooldown_IsEnabled(timer))
		end
209 210 211
	end
end

212
function E:GetCooldownColors(db)
213
	if not db then db = self.db.cooldown end -- just incase someone calls this without a first arg use the global
214 215
	local c6 = E:RGBToHex(db.hhmmColor.r, db.hhmmColor.g, db.hhmmColor.b) -- HH:MM color
	local c5 = E:RGBToHex(db.mmssColor.r, db.mmssColor.g, db.mmssColor.b) -- MM:SS color
216 217 218 219 220
	local c4 = E:RGBToHex(db.expiringColor.r, db.expiringColor.g, db.expiringColor.b) -- color for timers that are soon to expire
	local c3 = E:RGBToHex(db.secondsColor.r, db.secondsColor.g, db.secondsColor.b) -- color for timers that have seconds remaining
	local c2 = E:RGBToHex(db.minutesColor.r, db.minutesColor.g, db.minutesColor.b) -- color for timers that have minutes remaining
	local c1 = E:RGBToHex(db.hoursColor.r, db.hoursColor.g, db.hoursColor.b) -- color for timers that have hours remaining
	local c0 = E:RGBToHex(db.daysColor.r, db.daysColor.g, db.daysColor.b) -- color for timers that have days remaining
221
	return c0, c1, c2, c3, c4, c5, c6
222
end
223

Simpy's avatar
Simpy committed
224 225 226
function E:UpdateCooldownOverride(module)
	local cooldowns = (module and E.RegisteredCooldowns[module])
	if (not cooldowns) or not next(cooldowns) then return end
227

Simpy's avatar
Simpy committed
228
	local CD, db, customFont, customFontSize, timer, text, blizzTextAB
Simpy's avatar
Simpy committed
229
	for _, cd in ipairs(cooldowns) do
230
		db = (cd.CooldownOverride and E.db[cd.CooldownOverride]) or self.db
Simpy's avatar
Simpy committed
231
		db = db and db.cooldown
232

Simpy's avatar
Simpy committed
233 234 235
		if db then
			timer = cd.isHooked and cd.isRegisteredCooldown and cd.timer
			CD = timer or cd
236

Simpy's avatar
Simpy committed
237
			-- cooldown override settings
238 239
			if not CD.timerOptions then
				CD.timerOptions = {}
Simpy's avatar
Simpy committed
240
			end
241

242
			CD.timerOptions.reverseToggle = db.reverse
243
			CD.timerOptions.hideBlizzard = db.hideBlizzard
244

245
			if cd.CooldownOverride and db.override and E.TimeColors[cd.CooldownOverride] then
246
				CD.timerOptions.timeColors, CD.timerOptions.timeThreshold = E.TimeColors[cd.CooldownOverride], db.threshold
Simpy's avatar
Simpy committed
247
			else
248
				CD.timerOptions.timeColors, CD.timerOptions.timeThreshold = nil, nil
Simpy's avatar
Simpy committed
249
			end
250

Simpy's avatar
Simpy committed
251
			if db.checkSeconds then
252
				CD.timerOptions.hhmmThreshold, CD.timerOptions.mmssThreshold = db.hhmmThreshold, db.mmssThreshold
Simpy's avatar
Simpy committed
253
			else
254
				CD.timerOptions.hhmmThreshold, CD.timerOptions.mmssThreshold = nil, nil
255
			end
256

Simpy's avatar
Simpy committed
257
			if (db ~= self.db.cooldown) and db.fonts and db.fonts.enable then
258
				CD.timerOptions.fontOptions = db.fonts
Simpy's avatar
Simpy committed
259
			elseif self.db.cooldown.fonts and self.db.cooldown.fonts.enable then
260
				CD.timerOptions.fontOptions = self.db.cooldown.fonts
Simpy's avatar
Simpy committed
261
			else
262
				CD.timerOptions.fontOptions = nil
263
			end
Simpy's avatar
Simpy committed
264
			----------
265

Simpy's avatar
Simpy committed
266
			-- update font
Simpy's avatar
Simpy committed
267
			if timer and CD then
268
				self:Cooldown_OnSizeChanged(CD, cd:GetWidth(), true)
Simpy's avatar
Simpy committed
269 270 271
			else
				text = CD.text or CD.time
				if text then
272
					if CD.timerOptions.fontOptions and CD.timerOptions.fontOptions.enable then
Simpy's avatar
Simpy committed
273
						if not customFont then
Azilroka's avatar
Azilroka committed
274
							customFont = E.Libs.LSM:Fetch("font", CD.timerOptions.fontOptions.font)
Simpy's avatar
Simpy committed
275 276
						end
						if customFont then
Simpy's avatar
Simpy committed
277
							text:FontTemplate(customFont, CD.timerOptions.fontOptions.fontSize, CD.timerOptions.fontOptions.fontOutline)
Simpy's avatar
Simpy committed
278
						end
279
					elseif cd.CooldownOverride then
Simpy's avatar
Simpy committed
280
						if not customFont then
Azilroka's avatar
Azilroka committed
281
							customFont = E.Libs.LSM:Fetch("font", E.db[cd.CooldownOverride].font)
Simpy's avatar
Simpy committed
282
						end
Simpy's avatar
Simpy committed
283 284 285 286 287 288

						-- cd.auraType defined in `A:UpdateHeader` and `A:CreateIcon`
						if customFont and cd.auraType and (cd.CooldownOverride == 'auras') then
							customFontSize = E.db[cd.CooldownOverride][cd.auraType] and E.db[cd.CooldownOverride][cd.auraType].durationFontSize
							if customFontSize then
								text:FontTemplate(customFont, customFontSize, E.db[cd.CooldownOverride].fontOutline)
Simpy's avatar
Simpy committed
289 290 291 292 293
							end
						end
					end
				end
			end
294

Simpy's avatar
Simpy committed
295
			-- force update cooldown
Simpy's avatar
Simpy committed
296 297
			if timer and CD then
				E:Cooldown_ForceUpdate(CD)
298
				E:ToggleBlizzardCooldownText(cd, CD)
Simpy's avatar
Simpy committed
299 300
				if (not blizzTextAB) and AB and AB.handledBars and (cd.CooldownOverride == 'actionbar') then
					blizzTextAB = true
301
				end
Simpy's avatar
Simpy committed
302 303
			elseif cd.CooldownOverride == 'auras' and not (timer and CD) then
				cd.nextUpdate = -1
304 305 306
			end
		end
	end
307

Simpy's avatar
Simpy committed
308
	if blizzTextAB then
309 310 311 312 313 314
		for _, bar in pairs(AB.handledBars) do
			if bar then
				AB:ToggleCountDownNumbers(bar)
			end
		end
	end
315 316
end

317 318
function E:UpdateCooldownSettings(module)
	local cooldownDB, timeColors = self.db.cooldown, E.TimeColors
319

320 321
	-- update the module timecolors if the config called it but ignore "global" and "all":
	-- global is the main call from config, all is the core file calls
322 323
	local isModule = module and (module ~= 'global' and module ~= 'all') and self.db[module] and self.db[module].cooldown
	if isModule then
324 325 326
		if not E.TimeColors[module] then E.TimeColors[module] = {} end
		cooldownDB, timeColors = self.db[module].cooldown, E.TimeColors[module]
	end
327

328
	timeColors[0], timeColors[1], timeColors[2], timeColors[3], timeColors[4], timeColors[5], timeColors[6] = E:GetCooldownColors(cooldownDB)
329

330
	if isModule then
Simpy's avatar
Simpy committed
331
		E:UpdateCooldownOverride(module)
332
	elseif module == 'global' then -- this is only a call from the config change
Simpy's avatar
Simpy committed
333 334
		for key in pairs(E.RegisteredCooldowns) do
			E:UpdateCooldownOverride(key)
335 336 337
		end
	end

Simpy's avatar
Simpy committed
338
	-- okay update the other override settings if it was one of the core file calls
339
	if module and (module == 'all') then
340
		E:UpdateCooldownSettings('bags')
341
		E:UpdateCooldownSettings('nameplates')
342
		E:UpdateCooldownSettings('actionbar')
343
		E:UpdateCooldownSettings('unitframe')
344
		E:UpdateCooldownSettings('auras') -- has special OnUpdate
345
	end
Simpy's avatar
Simpy committed
346
end