File clearcasting.lua changed (mode: 100644) (index 5edec42..d9d287f) |
... |
... |
FIXME Cancel aura on right click. |
6 |
6 |
@script clearcasting |
@script clearcasting |
7 |
7 |
]] |
]] |
8 |
8 |
|
|
|
9 |
|
local strtrim = _G['strtrim'] |
|
10 |
|
local GameTooltip = _G['GameTooltip'] |
|
11 |
|
local UnitAura = _G['UnitAura'] |
|
12 |
|
local GetTime = _G['GetTime'] |
|
13 |
|
local UnitExists = _G['UnitExists'] |
|
14 |
|
local date = _G['date'] |
|
15 |
|
local DebuffTypeColor = _G['DebuffTypeColor'] |
|
16 |
|
local UIParent = _G['UIParent'] |
|
17 |
|
local CreateFrame = _G['CreateFrame'] |
|
18 |
|
local BuffFrame = _G['BuffFrame'] |
|
19 |
|
local GetLocale = _G['GetLocale'] |
|
20 |
|
|
9 |
21 |
local function debug(...) |
local function debug(...) |
10 |
22 |
if true == ClearcastingDebugFlag then |
if true == ClearcastingDebugFlag then |
11 |
23 |
print(date('%X'), '[Clearcasting]: ', ...) |
print(date('%X'), '[Clearcasting]: ', ...) |
|
... |
... |
local function applySubsetButtonDuration(f, duration, expirationInstance, stackQ |
58 |
70 |
f.stackQuantity = stackQuantity |
f.stackQuantity = stackQuantity |
59 |
71 |
end |
end |
60 |
72 |
|
|
61 |
|
local function unpackAuraTable(auraTable) |
|
62 |
|
assert(auraTable ~= nil) |
|
63 |
|
assert("table" == type(auraTable)) |
|
64 |
|
|
|
65 |
|
local spellName = auraTable[1] |
|
66 |
|
local spellRank = auraTable[2] |
|
67 |
|
local pictureFile = auraTable[3] |
|
68 |
|
local stackQuantity = auraTable[4] |
|
69 |
|
local category = auraTable[5] |
|
70 |
|
local durationSec = auraTable[6] |
|
71 |
|
local expirationInstance = auraTable[7] |
|
72 |
|
local casterUnitDesignation = auraTable[8] |
|
73 |
|
local stealableFlag = auraTable[9] |
|
74 |
|
local consolidationFlag = auraTable[10] |
|
75 |
|
local spellId = auraTable[11] |
|
76 |
|
--[[ FIXME There is no 12th return value in UnitAura function. |
|
77 |
|
-- This value is added by the script in requestUnitAuraTable function. |
|
78 |
|
-- The purpose of the value is to enable game tooltip. |
|
79 |
|
-- This is a source of potential compatibility issues, |
|
80 |
|
-- especially when porting this add-on to newer client versions. |
|
81 |
|
-- For now it works.]]-- |
|
82 |
|
local unitAuraIndex = auraTable[12] |
|
83 |
|
|
|
84 |
|
return spellName, spellRank, pictureFile, stackQuantity, category, durationSec, expirationInstance, |
|
85 |
|
casterUnitDesignation, stealableFlag, consolidationFlag, spellId, unitAuraIndex |
|
86 |
|
end |
|
|
73 |
|
local function getAuraWeightSimple(now, ...) |
|
74 |
|
local expirationInstance = select(7, ...) |
|
75 |
|
local casterUnitDesignation = select(8, ...) |
87 |
76 |
|
|
88 |
|
local function getAuraWeight( |
|
89 |
|
eitherAuraTableOrSpellName, |
|
90 |
|
spellRank, |
|
91 |
|
pictureFile, |
|
92 |
|
stackQuantity, |
|
93 |
|
category, |
|
94 |
|
durationSec, |
|
95 |
|
expirationInstance, |
|
96 |
|
casterUnitDesignation, |
|
97 |
|
stealableFlag, |
|
98 |
|
consolidationFlag, |
|
99 |
|
spellId) |
|
100 |
|
|
|
101 |
|
local spellName |
|
102 |
|
if 'table' == type(eitherAuraTableOrSpellName) then |
|
103 |
|
local auraTable = eitherAuraTableOrSpellName |
|
104 |
|
|
|
105 |
|
spellName, |
|
106 |
|
spellRank, |
|
107 |
|
pictureFile, |
|
108 |
|
stackQuantity, |
|
109 |
|
category, |
|
110 |
|
durationSec, |
|
111 |
|
expirationInstance, |
|
112 |
|
casterUnitDesignation, |
|
113 |
|
stealableFlag, |
|
114 |
|
consolidationFlag, |
|
115 |
|
spellId = unpackAuraTable(auraTable) |
|
116 |
|
elseif 'string' == type(eitherAuraTableOrSpellName) then |
|
117 |
|
spellName = eitherAuraTableOrSpellName |
|
|
77 |
|
local w = 0 |
|
78 |
|
if expirationInstance > 0 then |
|
79 |
|
w = w + (expirationInstance - now) |
118 |
80 |
else |
else |
119 |
|
debug('invalid argument', eitherAuraTableOrSpellName) |
|
120 |
|
return |
|
121 |
|
end |
|
122 |
|
|
|
123 |
|
assert (spellName ~= nil) |
|
124 |
|
assert (nil == spellRank or 'string' == type(spellRank)) |
|
125 |
|
assert (pictureFile ~= nil) |
|
126 |
|
assert (stackQuantity ~= nil) |
|
127 |
|
assert (nil == stealableFlag or 1 == stealableFlag or 0 == stealableFlag) |
|
128 |
|
assert (nil == consolidationFlag or 1 == consolidationFlag or 0 == consolidationFlag) |
|
129 |
|
assert (spellId ~= nil) |
|
130 |
|
|
|
131 |
|
local casterWeight = 0 |
|
132 |
|
if 'player' == casterUnitDesignation then |
|
133 |
|
casterWeight = 1 |
|
|
81 |
|
w = w + 90000 |
134 |
82 |
end |
end |
135 |
|
|
|
136 |
|
local categoryMap = {['Magic'] = 4, ['Poison'] = 3, ['Disease'] = 2, ['Curse'] = 1} |
|
137 |
|
local categoryWeight = 0 |
|
138 |
|
if category then |
|
139 |
|
categoryWeight = categoryMap[category] or 0 |
|
|
83 |
|
if 'player' ~= casterUnitDesignation then |
|
84 |
|
w = w + 100000 |
140 |
85 |
end |
end |
141 |
|
|
|
142 |
|
local maxDurationWeight = 999 |
|
143 |
|
local durationWeight |
|
144 |
|
if expirationInstance and expirationInstance > 0 and durationSec and durationSec > 0 then |
|
145 |
|
durationWeight = maxDurationWeight / (expirationInstance - GetTime()) |
|
146 |
|
elseif durationSec and durationSec == 0 then |
|
147 |
|
durationWeight = 0 |
|
148 |
|
else |
|
149 |
|
durationWeight = maxDurationWeight |
|
150 |
|
end |
|
151 |
|
durationWeight = math.ceil(durationWeight) |
|
152 |
|
|
|
153 |
|
local weight = 0 |
|
154 |
|
weight = weight + 10000 * casterWeight |
|
155 |
|
weight = weight + 10 * durationWeight |
|
156 |
|
weight = weight + 1 * categoryWeight |
|
157 |
|
|
|
158 |
|
return weight |
|
159 |
|
end |
|
160 |
|
|
|
161 |
|
|
|
162 |
|
local function sortUnitAuraTable(a, b) |
|
163 |
|
return getAuraWeight(a) > getAuraWeight(b) |
|
|
86 |
|
return w |
164 |
87 |
end |
end |
165 |
88 |
|
|
166 |
89 |
local function requestUnitAuraIndexTable(unitDesignation, filterDescriptor) |
local function requestUnitAuraIndexTable(unitDesignation, filterDescriptor) |
|
... |
... |
local function requestUnitAuraIndexTable(unitDesignation, filterDescriptor) |
189 |
112 |
e[i] = i |
e[i] = i |
190 |
113 |
end |
end |
191 |
114 |
|
|
|
115 |
|
local now = GetTime() |
192 |
116 |
table.sort(e, function(a, b) |
table.sort(e, function(a, b) |
193 |
|
local aw = getAuraWeight(UnitAura(unitDesignation, a, filterDescriptor)) |
|
194 |
|
local bw = getAuraWeight(UnitAura(unitDesignation, b, filterDescriptor)) |
|
195 |
|
return aw > bw |
|
|
117 |
|
local aw = getAuraWeightSimple(now, UnitAura(unitDesignation, a, filterDescriptor)) |
|
118 |
|
local bw = getAuraWeightSimple(now, UnitAura(unitDesignation, b, filterDescriptor)) |
|
119 |
|
return aw < bw |
196 |
120 |
end) |
end) |
197 |
121 |
|
|
198 |
122 |
assert (e ~= nil) |
assert (e ~= nil) |
199 |
|
assert ('table' == type(e)) |
|
200 |
|
return e |
|
201 |
|
end |
|
202 |
|
|
|
203 |
|
local function requestUnitAuraTable(unitDesignation, filterDescriptor) |
|
204 |
|
assert (unitDesignation ~= nil) |
|
205 |
|
assert ('string' == type(unitDesignation)) |
|
206 |
|
unitDesignation = strtrim(unitDesignation) |
|
207 |
|
assert (string.len(unitDesignation) >= 4) |
|
208 |
|
assert (string.len(unitDesignation) <= 64) |
|
209 |
|
|
|
210 |
|
assert (filterDescriptor ~= nil) |
|
211 |
|
assert ('string' == type(filterDescriptor)) |
|
212 |
|
filterDescriptor = strtrim(filterDescriptor) |
|
213 |
|
assert (string.len(filterDescriptor) >= 4) |
|
214 |
|
assert (string.len(filterDescriptor) <= 128) |
|
215 |
|
|
|
216 |
|
local index = 0 |
|
217 |
|
local q = 0 |
|
218 |
|
local e = {} |
|
219 |
|
local maxAuraQuantityPerUnit = 144 |
|
220 |
|
while (index < maxAuraQuantityPerUnit) do |
|
221 |
|
index = index + 1 |
|
222 |
|
local name, rank, pictureFile, stackQuantity, category, |
|
223 |
|
duration, expirationInstance, |
|
224 |
|
caster, stealableFlag, consolidateFlag, id = UnitAura(unitDesignation, index, filterDescriptor) |
|
225 |
|
if name then |
|
226 |
|
local auraTable = {name, rank, pictureFile, stackQuantity, category, |
|
227 |
|
duration, expirationInstance, |
|
228 |
|
caster, stealableFlag, consolidateFlag, id, index} |
|
229 |
|
q = q + 1 |
|
230 |
|
e[q] = auraTable |
|
231 |
|
else |
|
232 |
|
break |
|
233 |
|
end |
|
234 |
|
end |
|
235 |
|
table.sort(e, sortUnitAuraTable) |
|
236 |
|
|
|
237 |
123 |
return e |
return e |
238 |
124 |
end |
end |
239 |
125 |
|
|
|
... |
... |
local function unapplySubsetButtonSpell(subsetButton, unitDesignation, filterDes |
309 |
195 |
assert (unitDesignation ~= nil) |
assert (unitDesignation ~= nil) |
310 |
196 |
assert (filterDescriptor ~= nil) |
assert (filterDescriptor ~= nil) |
311 |
197 |
|
|
312 |
|
applySubsetButtonArtwork(subsetButton, "Interface\\Icons\\spell_nature_wispsplode") |
|
|
198 |
|
--[[applySubsetButtonArtwork(subsetButton, "Interface\\Icons\\spell_nature_wispsplode")]]-- |
313 |
199 |
|
|
314 |
200 |
subsetButton.unit = unitDesignation |
subsetButton.unit = unitDesignation |
315 |
201 |
subsetButton.filter = filterDescriptor |
subsetButton.filter = filterDescriptor |
|
... |
... |
local function applySubsetButtonSpell(subsetButton, unitDesignation, filterDescr |
349 |
235 |
applySubsetButtonBackground(subsetButton, category) |
applySubsetButtonBackground(subsetButton, category) |
350 |
236 |
applySubsetButtonTextColor(subsetButton, casterUnitDesignation) |
applySubsetButtonTextColor(subsetButton, casterUnitDesignation) |
351 |
237 |
|
|
352 |
|
subsetButton.unit = unitDesignation |
|
353 |
238 |
subsetButton.spell = spellName |
subsetButton.spell = spellName |
354 |
239 |
subsetButton.index = unitAuraIndex |
subsetButton.index = unitAuraIndex |
|
240 |
|
|
|
241 |
|
if subsetButton:IsShown() then |
|
242 |
|
return |
|
243 |
|
end |
|
244 |
|
|
|
245 |
|
subsetButton.unit = unitDesignation |
355 |
246 |
subsetButton.filter = filterDescriptor |
subsetButton.filter = filterDescriptor |
356 |
247 |
|
|
357 |
248 |
subsetButton:SetScript('OnUpdate', subsetButtonUpdateProcessor) |
subsetButton:SetScript('OnUpdate', subsetButtonUpdateProcessor) |
|
... |
... |
local function applySubsetButtonSpell(subsetButton, unitDesignation, filterDescr |
359 |
250 |
end |
end |
360 |
251 |
|
|
361 |
252 |
|
|
362 |
|
local function subsetEventProcessorFactory(t) |
|
363 |
|
|
|
364 |
|
return function(subsetFrame) |
|
|
253 |
|
local function subsetEventProcessor(subsetFrame, eventCategory, targetUnit) |
365 |
254 |
assert (subsetFrame ~= nil) |
assert (subsetFrame ~= nil) |
366 |
255 |
|
|
367 |
256 |
local unitDesignation = subsetFrame.unit |
local unitDesignation = subsetFrame.unit |
|
... |
... |
return function(subsetFrame) |
371 |
260 |
assert (string.len(unitDesignation) >= 4) |
assert (string.len(unitDesignation) >= 4) |
372 |
261 |
assert (string.len(unitDesignation) <= 64) |
assert (string.len(unitDesignation) <= 64) |
373 |
262 |
|
|
|
263 |
|
if targetUnit and unitDesignation ~= targetUnit then |
|
264 |
|
return |
|
265 |
|
end |
|
266 |
|
|
374 |
267 |
if UnitExists(unitDesignation) then |
if UnitExists(unitDesignation) then |
375 |
268 |
subsetFrame:Show() |
subsetFrame:Show() |
376 |
269 |
else |
else |
|
... |
... |
return function(subsetFrame) |
388 |
281 |
local e = requestUnitAuraIndexTable(unitDesignation, filterDescriptor) |
local e = requestUnitAuraIndexTable(unitDesignation, filterDescriptor) |
389 |
282 |
|
|
390 |
283 |
local i = 0 |
local i = 0 |
391 |
|
--[[local t = {subsetFrame:GetChildren()}]]-- |
|
|
284 |
|
local t = subsetFrame.buttonSet or {subsetFrame:GetChildren()} |
|
285 |
|
assert (t ~= nil) |
|
286 |
|
assert ('table' == type(t)) |
392 |
287 |
while (i < math.min(#e, #t)) do |
while (i < math.min(#e, #t)) do |
393 |
288 |
i = i + 1 |
i = i + 1 |
394 |
289 |
|
|
|
... |
... |
return function(subsetFrame) |
413 |
308 |
end |
end |
414 |
309 |
end |
end |
415 |
310 |
|
|
416 |
|
end |
|
417 |
|
|
|
418 |
311 |
local function createSubsetButtonArtwork(subsetButton) |
local function createSubsetButtonArtwork(subsetButton) |
419 |
312 |
assert (subsetButton ~= nil) |
assert (subsetButton ~= nil) |
420 |
313 |
|
|
|
... |
... |
local function createSubset(parentFrame, frameDesignation, unitDesignation, filt |
648 |
541 |
|
|
649 |
542 |
subsetFrame.unit = unitDesignation |
subsetFrame.unit = unitDesignation |
650 |
543 |
subsetFrame.filter = filterDescriptor |
subsetFrame.filter = filterDescriptor |
|
544 |
|
subsetFrame.buttonSet = t |
|
545 |
|
|
651 |
546 |
subsetFrame:RegisterEvent('PARTY_CONVERTED_TO_RAID') |
subsetFrame:RegisterEvent('PARTY_CONVERTED_TO_RAID') |
652 |
547 |
subsetFrame:RegisterEvent('PARTY_MEMBERS_CHANGED') |
subsetFrame:RegisterEvent('PARTY_MEMBERS_CHANGED') |
653 |
548 |
--subsetFrame:RegisterEvent('PLAYER_FOCUS_CHANGED') |
--subsetFrame:RegisterEvent('PLAYER_FOCUS_CHANGED') |
|
... |
... |
local function createSubset(parentFrame, frameDesignation, unitDesignation, filt |
658 |
553 |
subsetFrame:RegisterEvent('UNIT_AURA') |
subsetFrame:RegisterEvent('UNIT_AURA') |
659 |
554 |
--subsetFrame:RegisterEvent('UNIT_HEALTH') |
--subsetFrame:RegisterEvent('UNIT_HEALTH') |
660 |
555 |
--subsetFrame:RegisterEvent('UPDATE_BATTLEFIELD_SCORE') |
--subsetFrame:RegisterEvent('UPDATE_BATTLEFIELD_SCORE') |
661 |
|
local subsetEventProcessor = subsetEventProcessorFactory(t) |
|
662 |
556 |
subsetFrame:SetScript('OnEvent', subsetEventProcessor) |
subsetFrame:SetScript('OnEvent', subsetEventProcessor) |
663 |
557 |
subsetEventProcessor(subsetFrame) |
subsetEventProcessor(subsetFrame) |
664 |
558 |
|
|
|
... |
... |
local function init(rootFrame) |
703 |
597 |
rootFrame.createSubset = function(...) |
rootFrame.createSubset = function(...) |
704 |
598 |
return createSubset(...) |
return createSubset(...) |
705 |
599 |
end |
end |
|
600 |
|
|
|
601 |
|
rootFrame.getAuraWeight = function(...) |
|
602 |
|
return getAuraWeightSimple(GetTime(), ...) |
|
603 |
|
end |
|
604 |
|
|
|
605 |
|
debug('init') |
706 |
606 |
end |
end |
707 |
607 |
|
|
708 |
608 |
local function main() |
local function main() |