Mercurial > wow > turok
comparison Turok/Modules/Timer/Cooldown.lua @ 6:a9b8b0866ece
clear out log jam
author | Nenue |
---|---|
date | Sun, 21 Feb 2016 08:32:53 -0500 |
parents | |
children | 9400a0ff8540 |
comparison
equal
deleted
inserted
replaced
5:8a9a6637f082 | 6:a9b8b0866ece |
---|---|
1 | |
2 --- ${PACKAGE_NAME} | |
3 -- @file-author@ | |
4 -- @project-revision@ @project-hash@ | |
5 -- @file-revision@ @file-hash@ | |
6 -- Created: 12/25/2015 5:33 AM | |
7 --- Spell cooldown tracking resides here. | |
8 -- | |
9 -- Workflow of cooldown tracking: | |
10 -- A tracked spell cast is detected. (UNIT_SPELLCAST_*) | |
11 -- That spell ID enters the timer table. | |
12 -- The table is read by a handler that fires on the next frame, when cooldown information is available. (COOLDOWN_*) | |
13 -- Set() is called on the corresponding timer frame, and frame script takes over. | |
14 -- Timer table spells are polled on each COOLDOWN_* event, re-applying Set() when certain conditions are met. | |
15 -- The framescript or certain handlers will remove the timer table entry when there are no more positive conditions. | |
16 -- | |
17 local tostring, tonumber, tinsert = tostring, tonumber, tinsert | |
18 local GetTime, GetSpellInfo, GetInventoryItemCooldown, GetSpellCooldown, PlaySoundFile = GetTime, GetSpellInfo, GetInventoryItemCooldown, GetSpellCooldown, PlaySoundFile | |
19 local GetSpellCharges, GetSpellCount, GetInventoryItemCount, UnitAura = GetSpellCharges, GetSpellCount, GetInventoryItemCount, UnitAura | |
20 local IsUsableItem, IsUsableSpell, GetItemSpell = IsUsableItem, IsUsableSpell, GetItemSpell | |
21 local xpcall = xpcall | |
22 | |
23 local CD_SLOT, CD_ITEM, CD_SPELL = 1, 2, 3 | |
24 local HIDDEN, PASSIVE, ACTIVE = 0, 1, 2 | |
25 local format, ceil = string.format, math.ceil | |
26 local strrep, gsub, pairs = string.rep, string.gsub, pairs | |
27 local mod = Turok.modules.TimerControl | |
28 local T = Turok | |
29 local db | |
30 local FADE_TIME = 0.2 | |
31 --@debug@ | |
32 local cType, cText, cNum, cWord, cKey, cPink, cBool = cType, cText, cNum, cWord, cKey, cPink, cBool | |
33 local print = function(...) print('Cooldown', ...) end | |
34 local function GetPrint (trace) | |
35 return trace and print or function() end | |
36 end | |
37 | |
38 | |
39 local item_spells = { | |
40 ['PvP Trinket'] = 42292, | |
41 ['Burning Mirror'] = 184270, | |
42 } | |
43 | |
44 T.defaults.spirit.cooldown = { | |
45 | |
46 alpha = 1, | |
47 alpha_ooc = 0.2, | |
48 inverse = false, | |
49 persist = false, | |
50 desaturated = false, | |
51 fill_inverse = true, | |
52 size = 24, | |
53 counterText = "%p", | |
54 subCounterText = "%.p", | |
55 chargesText = "%s", | |
56 justifyH = 'CENTER', | |
57 justifyV = 'TOP', | |
58 | |
59 iconText = "%p", | |
60 leftText = "%p", | |
61 rightText = "%n / %d", | |
62 passive = { | |
63 icon = { | |
64 desaturated = false, | |
65 color = {1, 1, 1, 1}, | |
66 blend = 'BLEND' | |
67 } | |
68 }, | |
69 active = { | |
70 icon = { | |
71 desaturated = false, | |
72 color = {1, 1, 1, .6}, | |
73 blend = 'ADD' | |
74 } | |
75 }, | |
76 | |
77 --- control displays of aura information in cooldown displays | |
78 showAura = false, | |
79 cooldownAura = { | |
80 icon = { | |
81 desaturated = true, | |
82 color = {0,1,0,1}, | |
83 } | |
84 } | |
85 } | |
86 | |
87 local p = mod.prototype.trigger.cooldown | |
88 --@end-debug@ | |
89 p.class = 'trigger' | |
90 p.type = 'cooldown' | |
91 p.cvars = { | |
92 } | |
93 --- Sets initial values before dry Event is fired to check for presence | |
94 p.Init = function(self, spellID, caster, tristate, minValue, maxValue) | |
95 local print = GetPrint(self.trace) | |
96 | |
97 self.spellID = spellID and spellID or self.spellID | |
98 self.unit = caster and caster or self.unit | |
99 self.persist = tristate and tristate or self.persist | |
100 self.minValue = minValue and minValue or tonumber(self.minValue) | |
101 self.maxValue = maxValue and maxValue or tonumber(self.maxValue) | |
102 | |
103 --- current and last state values need to be flipped for inverted conditional | |
104 --- last state is defined in case it needs to be overridden to ensure proper frame update | |
105 print(cWord('Load:'),cNum(self.spellID or self.inventoryID or self.itemID), cText(self.spellName or GetItemSpell('player', self.inventoryID or self.itemID)) ) | |
106 print(cWord(' inverse=')..cBool(self.cvars.inverse)) | |
107 if self.cvars.inverse then | |
108 self.flags = { | |
109 active = HIDDEN, | |
110 active_prev = ACTIVE, | |
111 passive = PASSIVE, | |
112 passive_prev = PASSIVE, | |
113 hidden = PASSIVE, | |
114 hidden_prev = HIDDEN, | |
115 } | |
116 else | |
117 self.flags = { | |
118 active = ACTIVE, | |
119 active_prev = HIDDEN, | |
120 passive = PASSIVE, | |
121 passive_prev = HIDDEN, | |
122 hidden = HIDDEN, | |
123 hidden_prev = PASSIVE | |
124 } | |
125 end | |
126 if not (self.spellID or self.spellName) then | |
127 self.debug_info('No valid spell ID or Name') | |
128 end | |
129 end | |
130 | |
131 local GetItemCooldown, GetItemInfo = GetItemCooldown, GetItemInfo | |
132 p.Query = function(self) | |
133 local print = GetPrint(self.trace) | |
134 local id = self.inventoryID or self.itemID or self.spellID | |
135 local name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count | |
136 | |
137 --- checked in order of precedence | |
138 if self.inventoryID then | |
139 print(cText(' type'), cWord('inventory slot'), cNum(id)) | |
140 self.cooldownType = CD_SLOT | |
141 start, duration, enabled = GetInventoryItemCooldown('player', id) | |
142 charges, maxCharges, chargeStart, chargeDuration = nil, nil, nil, nil | |
143 count = GetInventoryItemCount('player', id) | |
144 usable = name and true or false | |
145 elseif self.itemID then | |
146 self.cooldownType = CD_ITEM | |
147 | |
148 start, duration, enabled = GetItemCooldown(self.itemID) | |
149 print(GetItemCooldown(self.itemID)) | |
150 print(GetItemInfo(id)) | |
151 | |
152 elseif self.spellID then | |
153 self.cooldownType = CD_SPELL | |
154 name = GetSpellInfo(self.spellID) | |
155 start, duration, enabled = GetSpellCooldown(self.spellID) | |
156 charges, maxCharges, chargeStart, chargeDuration = GetSpellCharges(self.spellID) | |
157 count = GetSpellCount(self.spellID) | |
158 usable = true -- they still exist even when dead | |
159 else | |
160 self.unit = 'notaunit' | |
161 T:Print('Timer \''..tostring(self.timerName)..'\' doesn\'t have a valid status ID.') | |
162 end | |
163 | |
164 -- may not have been stored for some reason | |
165 if charges and not self.maxCharges then | |
166 self.maxCharges = maxCharges | |
167 end | |
168 | |
169 print('cooldown.Query(',id,')', name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration) | |
170 return name, usable, start, duration, enabled, charges, chargeStart, chargeDuration, count | |
171 end | |
172 | |
173 p.Set = function(self, ...) | |
174 local print = GetPrint(self.trace) | |
175 | |
176 --name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count | |
177 local name | |
178 name, self.usable, self.start, self.duration, self.enabled, self.charges, self.chargeStart, self.chargeDuration, self.count = ... | |
179 if name then | |
180 self.spellName = name | |
181 end | |
182 | |
183 if self.duration and self.start then | |
184 self.expires = self.start + self.duration | |
185 else | |
186 self.expires = 0 | |
187 end | |
188 end | |
189 | |
190 p.Value = function(self) | |
191 return (self.charges and self.charges < self.maxCharges) and ((GetTime() - self.chargeStart) / self.chargeDuration) or ((GetTime() - self.start) / self.duration) | |
192 end | |
193 | |
194 p.SetText = mod.SetText | |
195 | |
196 --- Assign where meaning won't be amibiguous | |
197 local Cooldown_OnCast = function(self) | |
198 self.triggerState = true | |
199 end | |
200 | |
201 local Cooldown_OnUpdate = function(self, event) | |
202 local print = GetPrint(self.trace) | |
203 | |
204 if self.triggerState then | |
205 print(cWord('Event'), cText(self.timerName)) | |
206 if not event then | |
207 print(' *', cWord('Poke')) | |
208 end | |
209 local diff = 'start='..cText(self.start)..' duration='..cText(self.duration)..' charges='.. | |
210 cText(self.charges).. ' chargeStart='..cText(self.chargeStart).. ' chargeDuration='..cText(self.chargeDuration) | |
211 local name, usable, start, duration, enabled, charges, chargeStart, chargeDuration, count = self:Query() | |
212 | |
213 -- If we want and can, pull aura data and use that in place of cooldown information | |
214 local expires, hasAura, _ | |
215 if self.cvars.showAura then | |
216 print(cText('UnitAura'), self.unit, self.spellName, nil, 'HELPFUL') | |
217 local name, _, _, count, _, auraDuration, auraExpires = UnitAura(self.unit , self.spellName, nil, 'HELPFUL') | |
218 if name and (auraDuration ~= self.auraDuration or auraExpires ~= self.auraExpires) then | |
219 | |
220 print(cText('aura check ='), cBool(name), 's='..cNum(count), 'd='..cNum(auraDuration), 'e='..cNum(auraExpires)) | |
221 start = auraExpires - auraDuration | |
222 duration = auraDuration | |
223 expires = auraExpires | |
224 end | |
225 end | |
226 | |
227 -- print(name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count) | |
228 if duration ~= self.duration or | |
229 start ~= self.start or | |
230 chargeStart ~= self.chargeStart | |
231 or charges ~= self.charges then | |
232 print('a variable has changed') | |
233 local state | |
234 | |
235 | |
236 if duration == 0 and charges == self.maxCharges then | |
237 print(cText(' cooldown has reset, drop it from the queue')) | |
238 state = self.cvars.persist and self.flags.passive or self.flags.hidden | |
239 self.triggerState = nil | |
240 print(' ', cText('dropping'), cWord(self.timerName), cText('from spell tracking')) | |
241 | |
242 | |
243 self:Stats(state) | |
244 else | |
245 if duration ~= 0 then | |
246 print(cText(' cooldown has a hard duration')) | |
247 if duration > T.GCD and self.displayState ~= self.flags.active then | |
248 print(cText(' and its > GCD, update it')) | |
249 state = self.flags.active | |
250 end | |
251 end | |
252 | |
253 if charges then | |
254 print(cText(' cooldown has charges')) | |
255 if charges ~= self.charges or chargeStart ~= self.chargeStart then | |
256 print(cText(' charges count or starting time has changed')) | |
257 state = self.flags.active | |
258 end | |
259 end | |
260 | |
261 self:Stats(state) | |
262 end | |
263 | |
264 | |
265 -- form ID, id type, displayState, prevState | |
266 --T:Dispatch('TK_COOLDOWN_UPDATE', self.spellID, self.cooldownType, state, self.displayState) | |
267 if state then | |
268 self:Set(name, usable, start, duration, enabled, charges, chargeStart, chargeDuration, count) | |
269 self.expires = charges and (self.chargeStart + self.chargeDuration) or (self.start + self.duration) | |
270 self:SetState(state) | |
271 --print(' ', cText('SetState'), cNum(self.displayState), 'from', cNum(self.prevState), cWord(self.timerName)) | |
272 print(' ',diff) | |
273 print(' start='..cText(self.start)..' duration='..cText(self.duration)..' charges='.. | |
274 cText(self.charges).. ' chargeStart='..cText(self.chargeStart).. ' chargeDuration='..cText(self.chargeDuration)) | |
275 end | |
276 elseif self.cooldownType == CD_SPELL then | |
277 if duration == 0 and charges == self.maxCharges and self.displayState == HIDDEN then | |
278 print(cKey(self.timerName), cText('post-framescript clean-up')) | |
279 self.triggerState = nil | |
280 end | |
281 end | |
282 end | |
283 --self:DumpMessages() | |
284 | |
285 end | |
286 | |
287 p.Stats = function(self, state) | |
288 print(self.unit, self.spellName) | |
289 local auraName, _, _, auraCharges, _, auraDuration, auraExpires = UnitAura(self.unit, self.spellName, nil, 'HELPFUL') | |
290 local name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count = self:Query() | |
291 print('# GCD =', T.GCD) | |
292 print('# SpellCooldown', 's =', start, 'd =', duration, 's =', charges and (charges..'/'..maxCharges) or 'NA') | |
293 print('# Aura', auraName and 'yes' or 'no', auraName and ('d='..cNum(auraDuration)) or '', auraName and ('e='..auraExpires)) | |
294 print('# Frame', 'state1 =', self.displayState, 'state2 =', self.previousState, state and ('change to '..cWord(state)) or '') | |
295 | |
296 | |
297 end | |
298 | |
299 --- Event pointers | |
300 p.events = { | |
301 ['UNIT_SPELLCAST_SUCCEEDED'] = Cooldown_OnCast, | |
302 ['UNIT_SPELLCAST_CHANNEL_START'] = Cooldown_OnCast, | |
303 ['BAG_UPDATE_COOLDOWN'] = Cooldown_OnUpdate, | |
304 ['SPELL_UPDATE_COOLDOWN'] = Cooldown_OnUpdate, | |
305 ['SPELL_UPDATE_USABLE'] = Cooldown_OnUpdate, | |
306 ['SPELL_UPDATE_CHARGES'] = Cooldown_OnUpdate, | |
307 } | |
308 | |
309 local unpack, select, debugstack = unpack, select, debugstack | |
310 p.Event = function(self, e, ...) | |
311 local print = GetPrint(self.trace) | |
312 | |
313 self.event = e | |
314 --- dry event case | |
315 if not e then | |
316 print('onEvent', self.timerName, e) | |
317 self.triggerState = true | |
318 Cooldown_OnUpdate(self, e, ...) | |
319 else | |
320 local unit = select(1,...) | |
321 if self.unit and unit ~= self.unit and e ~= 'SPELL_UPDATE_COOLDOWN' then | |
322 return | |
323 end | |
324 local args = {...} | |
325 local success, d = xpcall(function() self.events[e](self, e, unpack(args)) end, function(m) print(self.name .."\n".. m .. "\n".. debugstack(3)) end) | |
326 | |
327 end | |
328 end | |
329 | |
330 p.triggerList = { | |
331 ['on_cooldown'] = function(self) | |
332 local start, duration, enabled = GetSpellCooldown(self.spellID) | |
333 local charges, _, cStart, cDuration = GetSpellCharges(self.spellID) | |
334 return (enabled and (duration ~= 0 or start ~= 0 or charges ~= self.maxCharges)), start, duration, enabled, charges, cStart, cDuration | |
335 end, | |
336 ['not_on_cooldown'] = function(self) | |
337 local start, duration, enabled = GetSpellCooldown(self.spellID) | |
338 local charges, _, cStart, cDuration = GetSpellCharges(self.spellID) | |
339 return (duration == 0 and start == 0 and charges == self.maxCharges), start, duration, enabled, charges, cStart, cDuration | |
340 end, | |
341 ['buff_active'] = function(self) | |
342 local name, rank, icon, count, dispelType, duration, expires, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff, value1, value2, value3 = UnitAura(self.unit, self.spellName, self.filters) | |
343 return (name and true or false), expires - duration, duration, true, count, 0, 0 | |
344 end | |
345 } |