File daybreak.lua changed (mode: 100644) (index 95ea013..49703d8) |
1 |
1 |
--[[-- |
--[[-- |
2 |
|
Add paladin player aura indicator. |
|
|
2 |
|
Daybreak. |
|
3 |
|
Add custom spell activation overlay and paladin holy power bar. |
3 |
4 |
@script daybreak |
@script daybreak |
4 |
5 |
]] |
]] |
5 |
6 |
|
|
6 |
7 |
--[[-- |
--[[-- |
7 |
|
Shared constants. |
|
8 |
|
@section constant |
|
|
8 |
|
Spell activation overlay. |
|
9 |
|
Custom general purpose spell activation overlay. |
|
10 |
|
@section overlay |
9 |
11 |
]] |
]] |
10 |
12 |
|
|
11 |
13 |
--[[-- |
--[[-- |
|
... |
... |
local function getDefaultButtonSize() |
18 |
20 |
end |
end |
19 |
21 |
|
|
20 |
22 |
--[[-- |
--[[-- |
|
23 |
|
Process timer tick to update remaining aura duration. |
|
24 |
|
The update employs artificial delay to hopefully reduce the memory cost of updates. |
|
25 |
|
@function applyOverlayUpdate |
|
26 |
|
@tparam frame button button to update |
|
27 |
|
@return nothing |
|
28 |
|
]] |
|
29 |
|
local function applyOverlayUpdate(button) |
|
30 |
|
assert (button ~= nil) |
|
31 |
|
|
|
32 |
|
local auraName = button.spell |
|
33 |
|
assert (auraName ~= nil) |
|
34 |
|
assert ('string' == type(auraName)) |
|
35 |
|
assert (string.len(auraName) >= 2) |
|
36 |
|
assert (string.len(auraName) <= 256) |
|
37 |
|
|
|
38 |
|
local unitDesignation = button.unit |
|
39 |
|
assert (unitDesignation ~= nil) |
|
40 |
|
assert ('string' == type(unitDesignation)) |
|
41 |
|
assert (string.len(unitDesignation) >= 2) |
|
42 |
|
assert (string.len(unitDesignation) <= 256) |
|
43 |
|
|
|
44 |
|
local _, _, _, quantity, _, duration, expirationInstance = UnitBuff(unitDesignation, auraName) |
|
45 |
|
quantity = quantity or 0 |
|
46 |
|
assert (quantity ~= nil) |
|
47 |
|
assert ('number' == type(quantity)) |
|
48 |
|
quantity = math.ceil(math.min(math.max(0, quantity), 99)) |
|
49 |
|
|
|
50 |
|
if nil == expirationInstance then |
|
51 |
|
return |
|
52 |
|
end |
|
53 |
|
local now = GetTime() |
|
54 |
|
local remainingDuration = math.max(0, math.ceil(expirationInstance - now)) |
|
55 |
|
local isDurationUnlimited = (remainingDuration or 0) == 0 and (duration or 0) == 0 |
|
56 |
|
local t |
|
57 |
|
if isDurationUnlimited then |
|
58 |
|
t = nil |
|
59 |
|
elseif quantity < 2 then |
|
60 |
|
t = tostring(remainingDuration) |
|
61 |
|
elseif quantity > 9 then |
|
62 |
|
t = tostring(remainingDuration) .. "*?" |
|
63 |
|
else |
|
64 |
|
t = tostring(remainingDuration) .. "*" .. tostring(quantity) |
|
65 |
|
end |
|
66 |
|
button:SetText(t) |
|
67 |
|
end |
|
68 |
|
|
|
69 |
|
local function overlayUpdateProcessor(self, updateDurationSec) |
|
70 |
|
assert (self ~= nil) |
|
71 |
|
|
|
72 |
|
assert (updateDurationSec ~= nil) |
|
73 |
|
assert ('number' == type(updateDurationSec)) |
|
74 |
|
updateDurationSec = math.max(0, updateDurationSec) |
|
75 |
|
|
|
76 |
|
local updateCooldownDurationSec = self.updateCooldownDurationSec |
|
77 |
|
if nil == updateCooldownDurationSec then |
|
78 |
|
updateCooldownDurationSec = 0 |
|
79 |
|
end |
|
80 |
|
assert (updateCooldownDurationSec ~= nil) |
|
81 |
|
assert ('number' == type(updateCooldownDurationSec)) |
|
82 |
|
updateCooldownDurationSec = math.max(0, updateCooldownDurationSec) |
|
83 |
|
updateCooldownDurationSec = updateCooldownDurationSec - updateDurationSec |
|
84 |
|
|
|
85 |
|
if updateCooldownDurationSec > 0 then |
|
86 |
|
self.updateCooldownDurationSec = updateCooldownDurationSec |
|
87 |
|
return |
|
88 |
|
else |
|
89 |
|
updateCooldownDurationSec = 0.084 |
|
90 |
|
self.updateCooldownDurationSec = updateCooldownDurationSec |
|
91 |
|
applyOverlayUpdate(self) |
|
92 |
|
end |
|
93 |
|
end |
|
94 |
|
|
|
95 |
|
--[[-- |
|
96 |
|
Process reaction to UNIT_AURA event for aura indicator. |
|
97 |
|
When aura disappears from the unit associated with this button, |
|
98 |
|
hide the button. Show it otherwise. |
|
99 |
|
@function acceptOverlayUnitAura |
|
100 |
|
@tparam button frame this button frame to update |
|
101 |
|
@tparam string eventCategory given event category designation |
|
102 |
|
@return nothing |
|
103 |
|
]] |
|
104 |
|
local function acceptOverlayUnitAura(button, eventCategory) |
|
105 |
|
assert (button ~= nil) |
|
106 |
|
assert (eventCategory ~= nil) |
|
107 |
|
assert ('string' == type(eventCategory)) |
|
108 |
|
assert (string.len(eventCategory) >= 2) |
|
109 |
|
assert (string.len(eventCategory) <= 256) |
|
110 |
|
|
|
111 |
|
local auraName = button.spell |
|
112 |
|
assert (auraName ~= nil) |
|
113 |
|
assert ('string' == type(auraName)) |
|
114 |
|
assert (string.len(auraName) >= 2) |
|
115 |
|
assert (string.len(auraName) <= 256) |
|
116 |
|
|
|
117 |
|
local unitDesignation = button.unit |
|
118 |
|
assert (unitDesignation ~= nil) |
|
119 |
|
assert ('string' == type(unitDesignation)) |
|
120 |
|
assert (string.len(unitDesignation) >= 2) |
|
121 |
|
assert (string.len(unitDesignation) <= 256) |
|
122 |
|
|
|
123 |
|
local name, _, icon = UnitBuff(unitDesignation, auraName) |
|
124 |
|
if name then |
|
125 |
|
--[[ FIXME Apply graphics only once instead of every aura update ]]-- |
|
126 |
|
button:SetNormalTexture(icon) |
|
127 |
|
button:Show() |
|
128 |
|
button:SetScript('OnUpdate', overlayUpdateProcessor) |
|
129 |
|
else |
|
130 |
|
button:Hide() |
|
131 |
|
button:SetScript('OnUpdate', nil) |
|
132 |
|
end |
|
133 |
|
end |
|
134 |
|
|
|
135 |
|
--[[-- |
|
136 |
|
Allocate button frame that represents a single aura |
|
137 |
|
New button has two custom fields: unit and spell. |
|
138 |
|
that is potentially applied to the player character. |
|
139 |
|
The order of parameters allows for predictable |
|
140 |
|
code line sorting. |
|
141 |
|
@function createButton |
|
142 |
|
@tparam number column horizontal position |
|
143 |
|
@tparam number row vertical position |
|
144 |
|
@tparam string localizedSpellName aura name to track |
|
145 |
|
@tparam string buttonName |
|
146 |
|
@tparam frame parentFrame |
|
147 |
|
@treturn frame newly allocated button frame instance |
|
148 |
|
]] |
|
149 |
|
local function createButton(column, row, localizedSpellName, buttonName, parentFrame) |
|
150 |
|
assert (buttonName ~= nil) |
|
151 |
|
assert ('string' == type(buttonName)) |
|
152 |
|
assert (string.len(buttonName) >= 2) |
|
153 |
|
assert (string.len(buttonName) <= 256) |
|
154 |
|
|
|
155 |
|
assert (parentFrame ~= nil) |
|
156 |
|
|
|
157 |
|
assert (localizedSpellName ~= nil) |
|
158 |
|
assert ('string' == type(localizedSpellName)) |
|
159 |
|
assert (string.len(localizedSpellName) >= 2) |
|
160 |
|
assert (string.len(localizedSpellName) <= 256) |
|
161 |
|
|
|
162 |
|
local button = CreateFrame('BUTTON', buttonName, parentFrame) |
|
163 |
|
local padding = 4 |
|
164 |
|
local size = getDefaultButtonSize() |
|
165 |
|
local s = size + padding |
|
166 |
|
button:SetSize(size, size) |
|
167 |
|
button:SetPoint('BOTTOMLEFT', column * s, row * s) |
|
168 |
|
|
|
169 |
|
local text = button:CreateFontString(button:GetName() .. 'Text', 'OVERLAY') |
|
170 |
|
local fontHandle = DaybreakFont or NumberFont_Outline_Large |
|
171 |
|
text:SetFontObject(fontHandle) |
|
172 |
|
text:SetPoint('TOPRIGHT', button, 'TOPRIGHT', 16, 16) |
|
173 |
|
text:SetPoint('BOTTOMLEfT', button, 'BOTTOMLEFT', -16, -16) |
|
174 |
|
|
|
175 |
|
button:SetFontString(text) |
|
176 |
|
button:SetText(nil) |
|
177 |
|
|
|
178 |
|
button.spell = localizedSpellName |
|
179 |
|
button.unit = 'player' |
|
180 |
|
|
|
181 |
|
button:RegisterEvent('UNIT_AURA') |
|
182 |
|
button:SetScript('OnEvent', acceptOverlayUnitAura) |
|
183 |
|
|
|
184 |
|
button:Hide() |
|
185 |
|
|
|
186 |
|
return button |
|
187 |
|
end |
|
188 |
|
|
|
189 |
|
--[[-- |
|
190 |
|
Plyer role assignment. |
21 |
191 |
Assign player role in battlegrounds automatically. |
Assign player role in battlegrounds automatically. |
22 |
192 |
@section role |
@section role |
23 |
193 |
]] |
]] |
|
... |
... |
local function getEstimatedBattlegroundRole(unitDesignation) |
29 |
199 |
assert (string.len(unitDesignation) <= 256) |
assert (string.len(unitDesignation) <= 256) |
30 |
200 |
|
|
31 |
201 |
|
|
32 |
|
--[[ TODO ]]-- |
|
|
202 |
|
--[[ TODO Add complex rolecheck cases for Death Knight and Druid ]]-- |
33 |
203 |
local roleDesignation = 'NONE' |
local roleDesignation = 'NONE' |
34 |
204 |
local _, classDesignation = UnitClass(unitDesignation) |
local _, classDesignation = UnitClass(unitDesignation) |
35 |
205 |
local i = GetPrimaryTalentTree() |
local i = GetPrimaryTalentTree() |
36 |
|
if 'PALADIN' == classDesignation then |
|
|
206 |
|
if 'MAGE' == classDesignation then |
|
207 |
|
roleDesignation = 'DAMAGER' |
|
208 |
|
elseif 'HUNTER' == classDesignation then |
|
209 |
|
roleDesignation = 'DAMAGER' |
|
210 |
|
elseif 'PALADIN' == classDesignation then |
37 |
211 |
if 1 == i then |
if 1 == i then |
38 |
212 |
roleDesignation = 'HEALER' |
roleDesignation = 'HEALER' |
39 |
213 |
elseif 2 == i then |
elseif 2 == i then |
|
... |
... |
local function getEstimatedBattlegroundRole(unitDesignation) |
58 |
232 |
roleDesignation = 'TANK' |
roleDesignation = 'TANK' |
59 |
233 |
end |
end |
60 |
234 |
elseif 'WARLOCK' == classDesignation then |
elseif 'WARLOCK' == classDesignation then |
61 |
|
if 1 == i then |
|
62 |
|
roleDesignation = 'DAMAGER' |
|
63 |
|
elseif 2 == i then |
|
64 |
|
roleDesignation = 'DAMAGER' |
|
65 |
|
elseif 3 == i then |
|
66 |
|
roleDesignation = 'DAMAGER' |
|
67 |
|
end |
|
|
235 |
|
roleDesignation = 'DAMAGER' |
68 |
236 |
end |
end |
69 |
237 |
|
|
70 |
238 |
assert (roleDesignation ~= nil) |
assert (roleDesignation ~= nil) |
|
... |
... |
local function initRole(rootFrame) |
94 |
262 |
end |
end |
95 |
263 |
|
|
96 |
264 |
--[[-- |
--[[-- |
97 |
|
Unit holy power indicator. |
|
98 |
|
@section holypower |
|
|
265 |
|
Paladin power bar. |
|
266 |
|
Custom power bar to track paladin holy power resource. |
|
267 |
|
@section powerbar |
99 |
268 |
]] |
]] |
100 |
269 |
|
|
101 |
270 |
local function getIndicatorTable(holyPowerIndicatorFrame) |
local function getIndicatorTable(holyPowerIndicatorFrame) |
|
... |
... |
local function createHolyPowerIndicator(frameName, parentFrame, unitDesignation) |
415 |
584 |
return f |
return f |
416 |
585 |
end |
end |
417 |
586 |
|
|
418 |
|
local function initHolyPower(rootFrame) |
|
|
587 |
|
local function initPowerBar(rootFrame) |
419 |
588 |
assert (rootFrame ~= nil) |
assert (rootFrame ~= nil) |
420 |
589 |
|
|
421 |
590 |
local _, c = UnitClass('player') |
local _, c = UnitClass('player') |
|
... |
... |
local function initHolyPower(rootFrame) |
436 |
605 |
end |
end |
437 |
606 |
|
|
438 |
607 |
--[[-- |
--[[-- |
|
608 |
|
Beacon of light. |
439 |
609 |
Add dedicated Beacon of Light indicator. |
Add dedicated Beacon of Light indicator. |
440 |
610 |
@section beacon |
@section beacon |
441 |
611 |
]] |
]] |
|
... |
... |
local function beaconUpdateProcessor(self) |
506 |
676 |
self:Hide() |
self:Hide() |
507 |
677 |
end |
end |
508 |
678 |
|
|
|
679 |
|
local artwork = self:GetNormalTexture() |
509 |
680 |
if 1 == IsSpellInRange('Beacon of Light', d) then |
if 1 == IsSpellInRange('Beacon of Light', d) then |
510 |
|
self.artwork:SetVertexColor(1, 1, 1, 1) |
|
|
681 |
|
artwork:SetVertexColor(1, 1, 1, 1) |
511 |
682 |
else |
else |
512 |
|
self.artwork:SetVertexColor(1, 1, 1, 0.4) |
|
|
683 |
|
artwork:SetVertexColor(1, 1, 1, 0.4) |
513 |
684 |
end |
end |
514 |
685 |
end |
end |
515 |
686 |
|
|
|
687 |
|
--[[-- |
|
688 |
|
Initialize player Beacon of Light buff indicator. |
|
689 |
|
@function initBeacon |
|
690 |
|
@tparam frame rootFrame parent frame |
|
691 |
|
@treturn frame new frame that tracks the specific player buff |
|
692 |
|
--]] |
516 |
693 |
local function initBeacon(rootFrame) |
local function initBeacon(rootFrame) |
517 |
|
local beacon = CreateFrame('FRAME', 'DaybreakBeaconOfLightFrame', rootFrame) |
|
518 |
|
beacon:SetSize(28, 28) |
|
519 |
|
beacon:SetPoint('BOTTOMLEFT', 10 * 32, 3 * 32) |
|
520 |
|
|
|
521 |
|
local artwork = beacon:CreateTexture(beacon:GetName() .. 'Artwork', 'ARTWORK') |
|
522 |
|
artwork:SetAllPoints() |
|
523 |
|
artwork:SetTexture("Interface\\Icons\\Ability_Paladin_BeaconOfLight") |
|
524 |
|
beacon.artwork = artwork |
|
|
694 |
|
local beacon = createButton(10, 4, 'Beacon of Light', 'DaybreakOverlayPaladinBeaconOfLight', rootFrame) |
|
695 |
|
beacon:SetNormalTexture("Interface\\Icons\\Ability_Paladin_BeaconOfLight") |
525 |
696 |
|
|
|
697 |
|
beacon:UnregisterAllEvents() |
526 |
698 |
beacon:SetScript('OnEvent', beaconEventProcessor) |
beacon:SetScript('OnEvent', beaconEventProcessor) |
527 |
699 |
beacon:SetScript('OnUpdate', beaconUpdateProcessor) |
beacon:SetScript('OnUpdate', beaconUpdateProcessor) |
528 |
700 |
beacon:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED') |
beacon:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED') |
|
... |
... |
Create an indicator for Blessed Life effect for the player character. |
631 |
803 |
local function initBlessedLife(rootFrame) |
local function initBlessedLife(rootFrame) |
632 |
804 |
assert (rootFrame ~= nil) |
assert (rootFrame ~= nil) |
633 |
805 |
|
|
634 |
|
local blessedLife = CreateFrame('FRAME', 'DaybreakBlessedLifeFrame', rootFrame) |
|
635 |
|
local size = getDefaultButtonSize() |
|
636 |
|
local padding = math.max(32 - size, 0) |
|
637 |
|
local s = size + padding |
|
638 |
|
local column = 2 |
|
639 |
|
local row = 0 |
|
640 |
|
blessedLife:SetSize(size, size) |
|
641 |
|
blessedLife:SetPoint('BOTTOMLEFT', s * column, s * row) |
|
642 |
|
|
|
643 |
|
local artwork = blessedLife:CreateTexture(blessedLife:GetName() .. 'Artwork', 'ARTWORK') |
|
644 |
|
artwork:SetAllPoints() |
|
645 |
|
artwork:SetTexture("Interface\\Icons\\Spell_holy_blessedlife") |
|
646 |
|
blessedLife.artwork = artwork |
|
|
806 |
|
local blessedLife = createButton(2, 0, 'Blessed Life', 'DaybreakOverlayPaladinBlessedLife', rootFrame) |
|
807 |
|
blessedLife:SetNormalTexture("Interface\\Icons\\Spell_holy_blessedlife") |
647 |
808 |
|
|
|
809 |
|
blessedLife:UnregisterAllEvents() |
648 |
810 |
blessedLife.isEnabled = isBlessedLifePresent() |
blessedLife.isEnabled = isBlessedLifePresent() |
649 |
811 |
blessedLife:SetScript('OnEvent', blessedLifeEventProcessor) |
blessedLife:SetScript('OnEvent', blessedLifeEventProcessor) |
650 |
812 |
blessedLife:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED') |
blessedLife:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED') |
|
... |
... |
local function initBlessedLife(rootFrame) |
657 |
819 |
end |
end |
658 |
820 |
|
|
659 |
821 |
--[[-- |
--[[-- |
660 |
|
Paladin character buff tracker. |
|
661 |
|
@section daybreak |
|
|
822 |
|
Priest overlay. |
|
823 |
|
Priest spell activation overlay. |
|
824 |
|
@section serendipity |
662 |
825 |
]] |
]] |
663 |
826 |
|
|
664 |
827 |
--[[-- |
--[[-- |
665 |
|
Process timer tick to update remaining aura duration. |
|
666 |
|
The update employs artificial delay to hopefully reduce the memory cost of updates. |
|
667 |
|
@function applyUpdate |
|
668 |
|
@tparam frame button button to update |
|
669 |
|
@tparam number updateDurationSec amount of seconds elapsed since last update |
|
670 |
|
@return nothing |
|
|
828 |
|
Initialize priest spell activation overlay if necessary. |
|
829 |
|
Must only be called once per script lifetime. |
|
830 |
|
Assumes that player class is constant. |
|
831 |
|
@function initSerendipity |
|
832 |
|
@tparam frame rootFrame addon root frame to parent indicators from |
|
833 |
|
@return void |
671 |
834 |
]] |
]] |
672 |
|
local function applyUpdate(button, updateDurationSec) |
|
673 |
|
assert (button ~= nil) |
|
674 |
|
|
|
675 |
|
assert (updateDurationSec ~= nil) |
|
676 |
|
assert ('number' == type(updateDurationSec)) |
|
677 |
|
updateDurationSec = math.max(0, updateDurationSec) |
|
678 |
|
|
|
679 |
|
local updateCooldownDurationSec = button.updateCooldownDurationSec |
|
680 |
|
if nil == updateCooldownDurationSec then |
|
681 |
|
updateCooldownDurationSec = 0 |
|
682 |
|
end |
|
683 |
|
assert (updateCooldownDurationSec ~= nil) |
|
684 |
|
assert ('number' == type(updateCooldownDurationSec)) |
|
685 |
|
updateCooldownDurationSec = math.max(0, updateCooldownDurationSec) |
|
686 |
|
updateCooldownDurationSec = updateCooldownDurationSec - updateDurationSec |
|
|
835 |
|
local function initSerendipity(rootFrame) |
|
836 |
|
assert (rootFrame ~= nil) |
687 |
837 |
|
|
688 |
|
if updateCooldownDurationSec > 0 then |
|
689 |
|
button.updateCooldownDurationSec = updateCooldownDurationSec |
|
|
838 |
|
local _, classDesignation = UnitClass('player') |
|
839 |
|
if 'PRIEST' ~= classDesignation then |
690 |
840 |
return |
return |
691 |
|
else |
|
692 |
|
updateCooldownDurationSec = 0.084 |
|
693 |
|
button.updateCooldownDurationSec = updateCooldownDurationSec |
|
694 |
841 |
end |
end |
695 |
842 |
|
|
696 |
|
local auraName = button.spell |
|
697 |
|
assert (auraName ~= nil) |
|
698 |
|
assert ('string' == type(auraName)) |
|
699 |
|
assert (string.len(auraName) >= 2) |
|
700 |
|
assert (string.len(auraName) <= 256) |
|
701 |
|
|
|
702 |
|
local unitDesignation = button.unit |
|
703 |
|
assert (unitDesignation ~= nil) |
|
704 |
|
assert ('string' == type(unitDesignation)) |
|
705 |
|
assert (string.len(unitDesignation) >= 2) |
|
706 |
|
assert (string.len(unitDesignation) <= 256) |
|
|
843 |
|
--[[ Priest ]]-- |
|
844 |
|
createButton(0, 0, 'Chakra: Chastise', 'DaybreakOverlayPriestChakraChastise', rootFrame) |
|
845 |
|
createButton(0, 0, 'Chakra: Sanctuary', 'DaybreakOverlayPriestChakraSanctuary', rootFrame) |
|
846 |
|
createButton(0, 0, 'Chakra: Serenity', 'DaybreakOverlayPriestChakraSerenity', rootFrame) |
|
847 |
|
createButton(0, 1, 'Chakra', 'DaybreakOverlayPriestChakra', rootFrame) |
|
848 |
|
--[[ Holy ]]-- |
|
849 |
|
createButton(1, 0, 'Holy Word: Serenity', 'DaybreaksOverlayPriestHolyWordSerenity', rootFrame) |
|
850 |
|
createButton(1, 1, 'Surge of Light', 'DaybreakOverlayPriestSurgeOfLight', rootFrame) |
|
851 |
|
createButton(1, 2, 'Serendipity', 'DaybreakOverlayPriestSerendipity', rootFrame) |
|
852 |
|
createButton(1, 3, 'Guardian Spirit', 'DaybreakOverlayPriestGuardianSpirit', rootFrame) |
707 |
853 |
|
|
708 |
|
local _, _, _, quantity, _, duration, expirationInstance = UnitBuff(unitDesignation, auraName) |
|
709 |
|
quantity = quantity or 0 |
|
710 |
|
assert (quantity ~= nil) |
|
711 |
|
assert ('number' == type(quantity)) |
|
712 |
|
quantity = math.ceil(math.min(math.max(0, quantity), 99)) |
|
|
854 |
|
--[[ Priest general ]]-- |
|
855 |
|
createButton(9, 0, 'Inspiration', 'DaybreakOverlayPriestInspiration', rootFrame) |
|
856 |
|
createButton(9, 1, 'Renew', 'DaybreakOverlayPriestRenew', rootFrame) |
|
857 |
|
createButton(9, 2, 'Power Word: Shield', 'DaybreakOverlayPriestPowerWordShield', rootFrame) |
|
858 |
|
createButton(10, 2, 'Body and Soul', 'DaybreakOverlayPriestBodyAndSoul', rootFrame) |
713 |
859 |
|
|
714 |
|
if nil == expirationInstance then |
|
715 |
|
return |
|
716 |
|
end |
|
717 |
|
local now = GetTime() |
|
718 |
|
local remainingDuration = math.max(0, math.ceil(expirationInstance - now)) |
|
719 |
|
local isDurationUnlimited = (remainingDuration or 0) == 0 and (duration or 0) == 0 |
|
720 |
|
local t |
|
721 |
|
if isDurationUnlimited then |
|
722 |
|
t = nil |
|
723 |
|
elseif quantity < 2 then |
|
724 |
|
t = tostring(remainingDuration) |
|
725 |
|
elseif quantity > 9 then |
|
726 |
|
t = tostring(remainingDuration) .. "*?" |
|
727 |
|
else |
|
728 |
|
t = tostring(remainingDuration) .. "*" .. tostring(quantity) |
|
729 |
|
end |
|
730 |
|
button:SetText(t) |
|
|
860 |
|
--[[ Hide native spell proc indicators that flash in the middle of the screen ]]-- |
|
861 |
|
SetCVar("displaySpellActivationOverlays", false) |
731 |
862 |
end |
end |
732 |
863 |
|
|
733 |
864 |
--[[-- |
--[[-- |
734 |
|
Process reaction to UNIT_AURA event for aura indicator. |
|
735 |
|
When aura disappears from the unit associated with this button, |
|
736 |
|
hide the button. Show it otherwise. |
|
737 |
|
@function acceptUnitAura |
|
738 |
|
@tparam button frame this button frame to update |
|
739 |
|
@tparam string eventCategory given event category designation |
|
740 |
|
@return nothing |
|
|
865 |
|
Paladin overlay. |
|
866 |
|
Paladin spell activation overlay. |
|
867 |
|
@section daybreak |
741 |
868 |
]] |
]] |
742 |
|
local function acceptUnitAura(button, eventCategory) |
|
743 |
|
assert (button ~= nil) |
|
744 |
|
assert (eventCategory ~= nil) |
|
745 |
|
assert ('string' == type(eventCategory)) |
|
746 |
|
assert (string.len(eventCategory) >= 2) |
|
747 |
|
assert (string.len(eventCategory) <= 256) |
|
748 |
|
|
|
749 |
|
local auraName = button.spell |
|
750 |
|
assert (auraName ~= nil) |
|
751 |
|
assert ('string' == type(auraName)) |
|
752 |
|
assert (string.len(auraName) >= 2) |
|
753 |
|
assert (string.len(auraName) <= 256) |
|
754 |
|
|
|
755 |
|
local unitDesignation = button.unit |
|
756 |
|
assert (unitDesignation ~= nil) |
|
757 |
|
assert ('string' == type(unitDesignation)) |
|
758 |
|
assert (string.len(unitDesignation) >= 2) |
|
759 |
|
assert (string.len(unitDesignation) <= 256) |
|
760 |
|
|
|
761 |
|
local name, _, icon = UnitBuff(unitDesignation, auraName) |
|
762 |
|
if name then |
|
763 |
|
--[[ FIXME Apply graphics only once instead of every aura update ]]-- |
|
764 |
|
button:SetNormalTexture(icon) |
|
765 |
|
button:Show() |
|
766 |
|
button:SetScript('OnUpdate', applyUpdate) |
|
767 |
|
else |
|
768 |
|
button:Hide() |
|
769 |
|
button:SetScript('OnUpdate', nil) |
|
770 |
|
end |
|
771 |
|
end |
|
772 |
869 |
|
|
773 |
870 |
--[[-- |
--[[-- |
774 |
|
Allocate button frame that represents a single aura |
|
775 |
|
New button has two custom fields: unit and spell. |
|
776 |
|
that is potentially applied to the player character. |
|
777 |
|
The order of parameters allows for predictable |
|
778 |
|
code line sorting. |
|
779 |
|
@function createButton |
|
780 |
|
@tparam number column horizontal position |
|
781 |
|
@tparam number row vertical position |
|
782 |
|
@tparam string localizedSpellName aura name to track |
|
783 |
|
@tparam string buttonName |
|
784 |
|
@tparam frame parentFrame |
|
785 |
|
@treturn frame newly allocated button frame instance |
|
|
871 |
|
Initialize paladin spell activation overlay if necessary. |
|
872 |
|
Must only be called once per script lifetime. |
|
873 |
|
Assumes that player class is constant. |
|
874 |
|
@function initDaybreak |
|
875 |
|
@tparam frame rootFrame addon root frame to parent indicators from |
|
876 |
|
@return void |
786 |
877 |
]] |
]] |
787 |
|
local function createButton(column, row, localizedSpellName, buttonName, parentFrame) |
|
788 |
|
assert (buttonName ~= nil) |
|
789 |
|
assert ('string' == type(buttonName)) |
|
790 |
|
assert (string.len(buttonName) >= 2) |
|
791 |
|
assert (string.len(buttonName) <= 256) |
|
792 |
|
|
|
793 |
|
assert (parentFrame ~= nil) |
|
794 |
|
|
|
795 |
|
assert (localizedSpellName ~= nil) |
|
796 |
|
assert ('string' == type(localizedSpellName)) |
|
797 |
|
assert (string.len(localizedSpellName) >= 2) |
|
798 |
|
assert (string.len(localizedSpellName) <= 256) |
|
799 |
|
|
|
800 |
|
local button = CreateFrame('BUTTON', buttonName, parentFrame) |
|
801 |
|
local padding = 4 |
|
802 |
|
local size = getDefaultButtonSize() |
|
803 |
|
local s = size + padding |
|
804 |
|
button:SetSize(size, size) |
|
805 |
|
button:SetPoint('BOTTOMLEFT', column * s, row * s) |
|
806 |
|
|
|
807 |
|
local text = button:CreateFontString(button:GetName() .. 'Text', 'OVERLAY') |
|
808 |
|
local fontHandle = DaybreakFont or NumberFont_Outline_Large |
|
809 |
|
text:SetFontObject(fontHandle) |
|
810 |
|
text:SetPoint('TOPRIGHT', button, 'TOPRIGHT', 16, 16) |
|
811 |
|
text:SetPoint('BOTTOMLEfT', button, 'BOTTOMLEFT', -16, -16) |
|
812 |
|
|
|
813 |
|
button:SetFontString(text) |
|
814 |
|
button:SetText(nil) |
|
815 |
|
|
|
816 |
|
button.spell = localizedSpellName |
|
817 |
|
button.unit = 'player' |
|
818 |
|
|
|
819 |
|
button:RegisterEvent('UNIT_AURA') |
|
820 |
|
button:SetScript('OnEvent', acceptUnitAura) |
|
821 |
|
|
|
822 |
|
button:Hide() |
|
|
878 |
|
local function initDaybreak(rootFrame) |
|
879 |
|
assert (rootFrame ~= nil) |
823 |
880 |
|
|
824 |
|
return button |
|
825 |
|
end |
|
|
881 |
|
local _, classDesignation = UnitClass('player') |
|
882 |
|
if 'PALADIN' ~= classDesignation then |
|
883 |
|
return |
|
884 |
|
end |
826 |
885 |
|
|
827 |
|
local function initDaybreak(rootFrame) |
|
828 |
886 |
--[[ Paladin ]]-- |
--[[ Paladin ]]-- |
829 |
887 |
--[[ General ]]-- |
--[[ General ]]-- |
830 |
|
createButton(0, 0, 'Crusader', 'DaybreakButton01', rootFrame) |
|
831 |
|
createButton(0, 1, 'Divine Plea', 'DaybreakButton02', rootFrame) |
|
832 |
|
createButton(0, 2, 'Divine Protection', 'DaybreakButton03', rootFrame) |
|
833 |
|
createButton(0, 2, 'Divine Shield', 'DaybreakButton04', rootFrame) |
|
834 |
|
createButton(0, 3, 'Avenging Wrath', 'DaybreakButton05', rootFrame) |
|
835 |
|
createButton(0, 4, 'Guardian of Ancient Kings', 'DaybreakButton06', rootFrame) |
|
|
888 |
|
createButton(0, 0, 'Crusader', 'DaybreakOverlayPaladinCrusader', rootFrame) |
|
889 |
|
createButton(0, 1, 'Divine Plea', 'DaybreakOverlayPaladinDivinePlea', rootFrame) |
|
890 |
|
createButton(0, 2, 'Divine Protection', 'DaybreakOverlayPaladinDivineProtection', rootFrame) |
|
891 |
|
createButton(0, 2, 'Divine Shield', 'DaybreakOverlayPaladinDivineShield', rootFrame) |
|
892 |
|
createButton(0, 3, 'Avenging Wrath', 'DaybreakOverlayPaladinAvengingWrath', rootFrame) |
|
893 |
|
createButton(0, 4, 'Guardian of Ancient Kings', 'DaybreakOverlayPaladinGuardianOfTheAncientKings', rootFrame) |
836 |
894 |
|
|
837 |
895 |
--[[ Effects that may be applied by other players place on the right side ]]-- |
--[[ Effects that may be applied by other players place on the right side ]]-- |
838 |
|
createButton(9, 0, 'Hand of Freedom', 'DaybreakButton07', rootFrame) |
|
839 |
|
createButton(9, 1, 'Hand of Sacrifice', 'DaybreakButton08', rootFrame) |
|
840 |
|
createButton(9, 2, 'Hand of Protection', 'DaybreakButton09', rootFrame) |
|
841 |
|
createButton(9, 3, 'Divine Sacrifice', 'DaybreakButton10', rootFrame) |
|
842 |
|
createButton(9, 4, 'Aura Mastery', 'DaybreakButton16', rootFrame) |
|
843 |
|
createButton(10, 0, 'Illuminated Healing', 'DaybreakButton11', rootFrame) |
|
844 |
|
createButton(10, 1, 'Power Torrent', 'DaybreakPowerTorrentButton', rootFrame) |
|
845 |
|
createButton(10, 2, 'Surge of Dominance', 'DaybreakSurgeOfDominance', rootFrame) |
|
|
896 |
|
createButton(9, 0, 'Hand of Freedom', 'DaybreakOverlayPaladinHandOfFreedom', rootFrame) |
|
897 |
|
createButton(9, 1, 'Hand of Sacrifice', 'DaybreakOverlayPaladinHandOfSacrifice', rootFrame) |
|
898 |
|
createButton(9, 2, 'Hand of Protection', 'DaybreakOverlayPaladinHandOfProtection', rootFrame) |
|
899 |
|
createButton(9, 3, 'Divine Sacrifice', 'DaybreakOverlayPaladinDivineSacrifice', rootFrame) |
|
900 |
|
createButton(9, 4, 'Aura Mastery', 'DaybreakOverlayPaladinAuraMastery', rootFrame) |
|
901 |
|
createButton(10, 0, 'Illuminated Healing', 'DaybreakOverlayPaladinIlluminatedHealing', rootFrame) |
|
902 |
|
createButton(10, 1, 'Conviction', 'DaybreakOverlayPaladinConviction', rootFrame) |
|
903 |
|
createButton(10, 2, 'Power Torrent', 'DaybreakOverlayPaladinPowerTorrent', rootFrame) |
|
904 |
|
createButton(10, 3, 'Surge of Dominance', 'DaybreakOverlayPaladinSurgeOfDominance', rootFrame) |
846 |
905 |
|
|
847 |
906 |
--[[ Holy ]]-- |
--[[ Holy ]]-- |
848 |
|
createButton(1, 0, 'Judgements of the Pure', 'DaybreakButton12', rootFrame) |
|
849 |
|
createButton(1, 1, 'Conviction', 'DaybreakButton23', rootFrame) |
|
850 |
|
createButton(1, 2, 'Daybreak', 'DaybreakButton13', rootFrame) |
|
851 |
|
createButton(1, 3, 'Infusion of Light', 'DaybreakButton14', rootFrame) |
|
852 |
|
createButton(1, 4, 'Divine Favor', 'DaybreakButton15', rootFrame) |
|
|
907 |
|
createButton(1, 0, 'Judgements of the Pure', 'DaybreakOverlayPaladinJudgementsOfThePure', rootFrame) |
|
908 |
|
createButton(1, 2, 'Daybreak', 'DaybreakOverlayPaladinDaybreak', rootFrame) |
|
909 |
|
createButton(1, 3, 'Infusion of Light', 'DaybreakOverlayPaladinInfusionOfLight', rootFrame) |
|
910 |
|
createButton(1, 4, 'Divine Favor', 'DaybreakOverlayPaladinDivineFavor', rootFrame) |
853 |
911 |
|
|
854 |
912 |
--[[ Protection ]]-- |
--[[ Protection ]]-- |
855 |
|
createButton(1, 0, 'Guarded by the Light', 'DaybreakButton17', rootFrame) |
|
856 |
|
createButton(1, 1, 'Holy Shield', 'DaybreakButton18', rootFrame) |
|
857 |
|
createButton(1, 2, 'Ardent Defender', 'DaybreakButton19', rootFrame) |
|
858 |
|
createButton(1, 3, 'Grand Crusader', 'DaybreakButton20', rootFrame) |
|
859 |
|
createButton(1, 4, 'Sacred Duty', 'DaybreakButton21', rootFrame) |
|
|
913 |
|
createButton(1, 0, 'Guarded by the Light', 'DaybreakOverlayPaladinGuardedByTheLight', rootFrame) |
|
914 |
|
createButton(1, 1, 'Holy Shield', 'DaybreakOverlayPaladinHolyShield', rootFrame) |
|
915 |
|
createButton(1, 2, 'Ardent Defender', 'DaybreakOverlayPaladinArdentDefender', rootFrame) |
|
916 |
|
createButton(1, 3, 'Grand Crusader', 'DaybreakOverlayPaladinGrandCrusader', rootFrame) |
|
917 |
|
createButton(1, 4, 'Sacred Duty', 'DaybreakOverlayPaladinSacredDuty', rootFrame) |
860 |
918 |
|
|
861 |
919 |
--[[ Retribution ]]-- |
--[[ Retribution ]]-- |
862 |
|
createButton(10, 1, 'Inquisition', 'DaybreakButton22', rootFrame) |
|
863 |
|
|
|
864 |
|
--[[ Priest ]]-- |
|
865 |
|
local _, classDesignation = UnitClass('player') |
|
866 |
|
if 'PRIEST' == classDesignation then |
|
867 |
|
createButton(0, 0, 'Chakra: Chastise', 'DaybreakChakraChastiseButton', rootFrame) |
|
868 |
|
createButton(0, 0, 'Chakra: Sanctuary', 'DaybreakChakraSanctuaryButton', rootFrame) |
|
869 |
|
createButton(0, 0, 'Chakra: Serenity', 'DaybreakChakraSerenityButton', rootFrame) |
|
870 |
|
createButton(0, 1, 'Chakra', 'DaybreakChakraButton', rootFrame) |
|
871 |
|
--[[ Holy ]]-- |
|
872 |
|
createButton(1, 0, 'Holy Word: Serenity', 'DaybreaksHolyWordSerenityButton', rootFrame) |
|
873 |
|
createButton(1, 1, 'Surge of Light', 'DaybreakSurgeOfLightButton', rootFrame) |
|
874 |
|
createButton(1, 2, 'Serendipity', 'DaybreakSerendipityButton', rootFrame) |
|
875 |
|
createButton(1, 3, 'Guardian Spirit', 'DaybreakGuardianSpiritButton', rootFrame) |
|
876 |
|
|
|
877 |
|
--[[ Priest general ]]-- |
|
878 |
|
createButton(9, 0, 'Inspiration', 'DaybreakInspirationButton', rootFrame) |
|
879 |
|
createButton(9, 1, 'Renew', 'DaybreakRenewButton', rootFrame) |
|
880 |
|
createButton(9, 2, 'Power Word: Shield', 'DaybreakPowerWordShieldButton', rootFrame) |
|
881 |
|
createButton(10, 2, 'Body and Soul', 'DaybreakBodyAndSoulButton', rootFrame) |
|
882 |
|
end |
|
|
920 |
|
createButton(10, 4, 'Inquisition', 'DaybreakOverlayPaladinInquisition', rootFrame) |
883 |
921 |
|
|
884 |
922 |
--[[ Hide native spell proc indicators that flash in the middle of the screen ]]-- |
--[[ Hide native spell proc indicators that flash in the middle of the screen ]]-- |
885 |
923 |
SetCVar("displaySpellActivationOverlays", false) |
SetCVar("displaySpellActivationOverlays", false) |
|
... |
... |
local function init(rootFrame) |
899 |
937 |
rootFrame:SetPoint('CENTER', UIParent, |
rootFrame:SetPoint('CENTER', UIParent, |
900 |
938 |
'CENTER', 0, 0) |
'CENTER', 0, 0) |
901 |
939 |
|
|
|
940 |
|
initBeacon(rootFrame) |
902 |
941 |
initBlessedLife(rootFrame) |
initBlessedLife(rootFrame) |
903 |
942 |
initDaybreak(rootFrame) |
initDaybreak(rootFrame) |
904 |
|
initHolyPower(rootFrame) |
|
|
943 |
|
initPowerBar(rootFrame) |
905 |
944 |
initRole(rootFrame) |
initRole(rootFrame) |
906 |
|
initBeacon(rootFrame) |
|
|
945 |
|
initSerendipity(rootFrame) |
907 |
946 |
|
|
908 |
947 |
print('[Daybreak]: Addon loaded.') |
print('[Daybreak]: Addon loaded.') |
909 |
948 |
|
|