Mercurial > wow > turok
comparison Turok/Modules/Combat/Powerbar.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 -- User: Krakyn | |
2 -- Created: 12/15/2015 7:31 PM | |
3 --[[ | |
4 -- Turok by @project-author@ | |
5 -- @file-author@ | |
6 -- @file-revision@:@project-revision@ | |
7 -- @file-date-iso@ | |
8 -- | |
9 -- Visible element operations begin here | |
10 --]] | |
11 local _G = _G | |
12 local T, pairs, select, setmetatable, type, tinsert = _G.Turok, pairs, select, setmetatable, type, tinsert | |
13 local mod = T:NewModule("PowerBar") | |
14 local UnitPower, UnitPowerMax, GetTalentInfoByID, GetTalentInfo, CreateFrame = UnitPower, UnitPowerMax, GetTalentInfoByID, GetTalentInfo, CreateFrame | |
15 local bar, db, prototype -- convenience upvalues | |
16 local cType, cText, cNum, cWord, cKey, cPink, cBool = cText, cNum, cWord, cKey, cPink, cBool | |
17 --@debug | |
18 local cType, cText, cNum, cWord, cKey, cPink, cBool = cText, cNum, cWord, cKey, cPink, cBool | |
19 local print = function(...) | |
20 if _G.Devian and _G.DevianDB.workspace ~= 1 then | |
21 _G.print('PowerBar', ...) | |
22 end | |
23 end | |
24 print('Peep!', ...) | |
25 local addon, tg = ... | |
26 tg.what = tostring(tg.what)..'more' | |
27 print(tg.what) | |
28 --@end-debug@ | |
29 mod.OnInitialize = function(self) | |
30 self.UNIT_SPELLCAST_START = self.SpellCastEvent | |
31 self.UNIT_SPELLCAST_STOP = self.SpellCastEvent | |
32 self.UNIT_SPELLCAST_SUCCEEDED = self.SpellCastEvent | |
33 self.UNIT_SPELLCAST_CHANNEL_START = self.SpellCastEvent | |
34 self.UNIT_SPELLCAST_CHANNEL_STOP = self.SpellCastEvent | |
35 self.SPELL_UPDATE_COOLDOWN = self.SpellCooldownEvent | |
36 self.PLAYER_REGEN_DISABLED = self.CombatStart | |
37 self.PLAYER_REGEN_ENABLED = self.CombatEnd | |
38 self.focusbar = {} | |
39 self.parserLog = {} | |
40 self.currentParse = {} | |
41 end | |
42 local SPELL_POWER_MANA, SPELL_POWER_ENERGY, SPELL_POWER_RAGE, SPELL_POWER_FOCUS = SPELL_POWER_MANA, SPELL_POWER_ENERGY, SPELL_POWER_RAGE, SPELL_POWER_FOCUS | |
43 local SPELL_POWER_SHADOW_ORBS = SPELL_POWER_SHADOW_ORBS | |
44 local SPELL_POWER_SOUL_SHARDS, SPELL_POWER_BURNING_EMBERS, SPELL_POWER_DEMONIC_FURY = SPELL_POWER_SOUL_SHARDS, SPELL_POWER_BURNING_EMBERS, SPELL_POWER_DEMONIC_FURY | |
45 local SPELL_POWER_HOLY_POWER = SPELL_POWER_HOLY_POWER | |
46 local SPELL_POWER_CHI = SPELL_POWER_CHI | |
47 local SPELL_POWER_COMBO_POINTS = SPELL_POWER_COMBO_POINTS | |
48 | |
49 -- indexes for talent_update cleanup | |
50 mod.secondary_rows = {} | |
51 mod.disabled_frames = {} | |
52 | |
53 --[[ | |
54 -- Prototype list naming all the data sources and events that need to be handled for the logged in character | |
55 -- .power_type {[bliz const] = event token} list of resources represented by global SPELL_POWER_* constants in the blizzard ui and the UNIT_POWER* token argument representing it | |
56 -- .frame string frameXML template | |
57 -- .spells {[spell name/id] = {events}} list of spells tracked by the updater | |
58 -- .secondary {[aura name] = {}} list of auras tracked as secondary resources such as Thrill of Hunt, Anticipatin, Evangelism, etc. | |
59 --]] | |
60 mod.prototype = { | |
61 ['HUNTER'] = { | |
62 primary = { | |
63 [1] = {"FOCUS", SPELL_POWER_FOCUS}, -- array of power type constants associated to event strings | |
64 }, | |
65 frame = 'TkThinComboTemplate', ---------------------- desired frame template | |
66 spells = { | |
67 ["Steady Shot"] = {'UNIT_SPELL_CAST_SUCCEEDED', 'UNIT_SPELLCAST_STOP', 'UNIT_SPELLCAST_START'} -- spell events that this frame should listen to | |
68 }, | |
69 secondary = {}, | |
70 spec = { | |
71 [1] = { | |
72 secondary = { | |
73 ['Frenzy'] = { | |
74 type = 'aura', | |
75 order = 1, | |
76 scale = 5, | |
77 filters = 'HELPFUL', | |
78 max = 5, | |
79 specPage = 1, | |
80 unit = 'player', | |
81 spellID = 19623, | |
82 }, | |
83 ['Focus Fire'] = { | |
84 type = 'aura', | |
85 max = 40, | |
86 order = 2, | |
87 scale = 5, | |
88 line = 3, --------------- use this subtext value instead of count field | |
89 filters = 'HELPFUL', | |
90 specPage = 1, | |
91 unit = 'player', | |
92 spellID = 19623, | |
93 } | |
94 } | |
95 }, | |
96 [2] = { | |
97 secondary = { ------------------------ list of buffs that act as a secondary resource | |
98 ['Thrill of the Hunt'] = { | |
99 order = 1, | |
100 unit = 'player', | |
101 type = 'aura', | |
102 max = 3, | |
103 scale = 5, | |
104 filters = 'HELPFUL', | |
105 talent = {4,3}, | |
106 display = 'progressbar' | |
107 }, | |
108 }, | |
109 }, | |
110 }, | |
111 }, | |
112 ['PRIEST'] = { | |
113 primary = { | |
114 [1] = {'MANA', SPELL_POWER_MANA} | |
115 }, | |
116 frame = 'TkThinComboTemplate', | |
117 secondary = {}, | |
118 spec = { | |
119 [1] = { | |
120 secondary = { | |
121 ['Evangelism'] = { | |
122 order = 1, | |
123 max = 5, | |
124 scale = 5, | |
125 type='aura', | |
126 unit = 'player', | |
127 filters = 'HELPFUL|PLAYER', | |
128 spellID = 81662, | |
129 } | |
130 } | |
131 }, | |
132 [3] = { | |
133 primary = { | |
134 [1] = {'SHADOW_ORBS', SPELL_POWER_SHADOW_ORBS}, | |
135 }, | |
136 secondary = { | |
137 ["Surge of Darkness"] = { | |
138 order = 2, | |
139 type = 'aura', | |
140 filters = 'HELPFUL|PLAYER', | |
141 spellID = 87160, | |
142 talentID = 21751, | |
143 max = 3, | |
144 scale = 5, | |
145 unit = 'player', | |
146 }, | |
147 ["Insanity"] = { | |
148 order = 2, | |
149 type = 'aura', | |
150 binary = true, | |
151 regress = true, | |
152 size = 1, scale = 1, max = 1, | |
153 filters = 'HELPFUL|PLAYER', | |
154 spellID = 132573, | |
155 unit = 'player', | |
156 talentID = 21753}, | |
157 } | |
158 }, | |
159 }, | |
160 }, | |
161 ['ROGUE'] = { | |
162 primary = { | |
163 [1] = {'ENERGY', SPELL_POWER_ENERGY}, | |
164 [2] = {'COMBO_POINTS', SPELL_POWER_COMBO_POINTS} | |
165 }, | |
166 frame = 'TkThinComboTemplate', | |
167 secondary = { | |
168 ['Anticipation'] = { | |
169 type = 'aura', | |
170 order = 1, | |
171 max = 5, | |
172 scale = 5, | |
173 unit = 'player', | |
174 talentID = 19250, | |
175 }, | |
176 }, | |
177 spec = {}, | |
178 }, | |
179 ['MAGE'] = { | |
180 primary = { | |
181 [1] = {'MANA', SPELL_POWER_MANA}, | |
182 }, | |
183 frame = 'TkThinComboTemplate', | |
184 secondary = { | |
185 | |
186 ["Incanter's Flow"] = { | |
187 type = 'aura', | |
188 unit = 'player', | |
189 filters = 'HELPFUL|PLAYER', | |
190 spellID = 1463, | |
191 max = 5, | |
192 scale = 5, | |
193 order = 2, | |
194 talentID = 16033, | |
195 }, | |
196 ["Rune of Power"] = { | |
197 type = 'aura', | |
198 unit = 'player', | |
199 filters = 'HELPFUL|PLAYER', | |
200 binary = true, | |
201 max = 1, | |
202 scale = 1, | |
203 order = 2, | |
204 talentID = 16032, | |
205 } | |
206 }, | |
207 spec = { | |
208 [1] = { | |
209 secondary = { | |
210 ['Arcane Charge'] = { | |
211 type ='aura', | |
212 unit = 'player', | |
213 filters = 'HARMFUL|PLAYER', | |
214 spellID = 114664, | |
215 scale = 4, | |
216 max = 4, | |
217 order = 1, | |
218 }, | |
219 } | |
220 }, | |
221 [3] = { | |
222 secondary = { | |
223 ['Fingers of Frost'] = { | |
224 type = 'aura', | |
225 unit = 'player', | |
226 filters = '', | |
227 spellID = 112965, | |
228 max = 2, | |
229 scale = 4, | |
230 order = 1, | |
231 }, | |
232 ['Brain Freeze'] = { | |
233 type = 'aura', | |
234 unit = 'player', | |
235 filters = '', | |
236 spellID = 44549, | |
237 scale = 4, | |
238 max = 2, | |
239 order = 1, | |
240 mirror = true, | |
241 } | |
242 } | |
243 }, | |
244 } | |
245 } | |
246 } | |
247 local P = mod.prototype | |
248 | |
249 function mod:OnEnable() | |
250 self.disabled_freams = { | |
251 [T.playerClass] = { | |
252 [T.specPage] = {} | |
253 } | |
254 } | |
255 self.watched_units = {} | |
256 self.watched_auras = {} | |
257 self.watched_spells = {} | |
258 self.db = TurokData.powerbar | |
259 db = self.db | |
260 | |
261 self:Prototype_Init() | |
262 end | |
263 function mod:Prototype_Init() | |
264 -- consult prototype vars | |
265 prototype = {} | |
266 mod.dcopy = function(t1, t2, d) | |
267 d = d or '' | |
268 for k,v in pairs(t2) do | |
269 if type(v) == 'table' then | |
270 if type(t1[k]) ~= 'table' then | |
271 t1[k] = {} | |
272 print(d, 'adding table', cKey(k)) | |
273 else | |
274 print(d, 'merging tables', cKey(k)) | |
275 end | |
276 mod.dcopy(t1[k], v, d..' ') | |
277 else | |
278 if t1[k] then | |
279 print(d, 'clobbered', k) | |
280 else | |
281 print(d, k, '=', cType(v)) | |
282 end | |
283 t1[k] = v | |
284 end | |
285 end | |
286 end | |
287 mod.dcopy(prototype, mod.prototype[T.playerClass]) | |
288 if mod.prototype[T.playerClass].spec[T.specPage] then | |
289 mod.dcopy(prototype, mod.prototype[T.playerClass].spec[T.specPage]) | |
290 end | |
291 | |
292 mod.thisproto = prototype | |
293 | |
294 print('|cFFFF0088Template:|r', 'Frame', 'TkPowerBarFrame', UIParent, prototype.frame) | |
295 db = self.db | |
296 | |
297 if bar and bar.GetObjectType then | |
298 bar:Hide() | |
299 mod.disabled_frames[bar.specPage] = bar | |
300 print('putting away old frame') | |
301 end | |
302 | |
303 if not bar then | |
304 bar = CreateFrame('Frame', 'TkPowerBar', UIParent, prototype.frame) | |
305 end | |
306 bar.specPage = T.specPage | |
307 bar.specID = T.specID | |
308 bar.primary = {} -- {current, max, token} | |
309 bar.secondary = {} -- {current, max, token} | |
310 bar.aura = {} -- {name, duration, expires, unit, flags} | |
311 bar.spell = {} -- copy of the last T.spellevent match | |
312 print(' setting layout', db) | |
313 print(bar:GetName()) | |
314 T.SetFrameLayout(bar, prototype.cvars and db[prototype.cvars] or db) | |
315 T.SetStatusTextures(bar, db) | |
316 | |
317 print(' setting methods') | |
318 bar.Init = mod.Bar_Init | |
319 bar.Event = mod.Bar_Event | |
320 bar.Update = mod.Bar_Update | |
321 | |
322 | |
323 --- loop through aura definitions and flag accordingly | |
324 print('Primary power types:') | |
325 for order, power_data in pairs(prototype.primary) do | |
326 print( order, unpack(power_data)) | |
327 local token, power_type = unpack(power_data) | |
328 local power, max = UnitPower('player', power_type), UnitPowerMax('player', power_type) | |
329 bar.primary[token] = {power, max, power_type, order} | |
330 print(' ', cKey(token), '= {', power, max, power_type, order, '}') | |
331 end | |
332 | |
333 --- go through secondary data args and assign the appropriate source functions | |
334 local useAura, useCooldown | |
335 local used_rows = {} | |
336 if prototype.secondary then | |
337 mod.secondary = {} | |
338 for name, c in pairs(prototype.secondary) do | |
339 local isActive = true | |
340 print('parsing extra handler', name) | |
341 if c.talentID then | |
342 print(c.talentID, T.specPage) | |
343 isActive = (type(c.talentID) == 'table') and select(4, GetTalentInfo(unpack(c.talentID), T.specGroup)) or | |
344 select(4, GetTalentInfoByID(c.talentID, T.specGroup)) | |
345 print(' talentID:', cNum(isActive)) | |
346 end | |
347 if isActive then | |
348 local sc = {} | |
349 | |
350 sc = c | |
351 print(' enable:', cNum(isActive), cWord(c.type)) | |
352 if c.type == 'aura' then | |
353 sc.spellName = name | |
354 if c.binary then | |
355 sc.Get = function(self) | |
356 print('get: UnitAura', self.unit, self.spellName, c.filters) | |
357 local exists = UnitAura(self.unit, self.spellName, nil, self.filters) | |
358 return (exists) and 1 or 0 | |
359 end | |
360 else | |
361 sc.Get = function(self) | |
362 print('get: UnitAura', self.unit, self.spellName, c.filters) | |
363 local _,_,_, count = UnitAura(self.unit, self.spellName, nil, self.filters) | |
364 return count or 0 | |
365 end | |
366 end | |
367 | |
368 useAura = true | |
369 elseif c.type == 'cooldown' then | |
370 if c.inverse then | |
371 sc.Get = function(self) | |
372 local start, duration, enabled = GetSpellCooldown(c.spellID) | |
373 sc[1] = (duration > 0) and (GetTime() - start) or c.max | |
374 print('get: GetSpellCooldown (inverse)', c.spellID, '=', sc[1]) | |
375 end | |
376 else | |
377 sc.Get = function(self) | |
378 local start, duration, enabled = GetSpellCooldown(c.spellID) | |
379 sc[1] = (duration > 0) and (start + duration - GetTime()) or 0 | |
380 print('get: GetSpellCooldown', c.spellID, '=', sc[1]) | |
381 end | |
382 end | |
383 useCooldown = true | |
384 end | |
385 print(' committing', name, 'to row', sc.order) | |
386 bar.secondary[name] = sc | |
387 used_rows[sc.order] = true -- index the drawn rows for talent_update | |
388 end | |
389 end | |
390 end | |
391 | |
392 | |
393 if useAura then bar:RegisterEvent('UNIT_AURA') end | |
394 if useCooldown then bar:RegisterEvent('UNIT_SPELLCAST_SUCCEEDED') end | |
395 | |
396 bar:SetScript('OnUpdate', nil) -- make sure any xml embeds are cleaned out | |
397 bar:SetScript('OnEvent', mod.Bar_Event) | |
398 bar:RegisterEvent('UNIT_POWER_FREQUENT') | |
399 | |
400 bar:Init() | |
401 bar:Show() | |
402 | |
403 -- metrics used by data plots | |
404 bar.width = db.width | |
405 bar.foreground_inset = db.foreground_inset | |
406 bar.right_edge = bar:GetRight() | |
407 bar.fill_limit = bar.right_edge | |
408 bar.foreground.width = bar.width + (bar.foreground_inset) | |
409 bar.spacing = 1 | |
410 | |
411 mod.powerbar = bar | |
412 end | |
413 | |
414 mod.Bar_Init = function(self) | |
415 local mainPower, comboPower | |
416 for token, power in pairs(self.primary) do | |
417 if power[4] == 1 then | |
418 mainPower = power | |
419 elseif power[4] == 2 then | |
420 comboPower = power | |
421 end | |
422 end | |
423 | |
424 if mainPower then | |
425 local power, max, type, token = unpack(mainPower) | |
426 if power and max then | |
427 self.powerText:SetText(power) | |
428 self:SetProgress(power/max) | |
429 end | |
430 end | |
431 | |
432 if comboPower then | |
433 local power, max, type, token = unpack(comboPower) | |
434 local px = (self.width-db.secondary.spacing* (max -1)-db.secondary.padding*2) / max | |
435 self.combo = {} | |
436 for i = 1, max do | |
437 if not self.combo[i] then | |
438 self.combo[i] = self:CreateTexture('TkPrimaryResourcePellet'..i, 'OVERLAY') | |
439 end | |
440 | |
441 local k = i - 1 | |
442 local cx = db.secondary.padding + px * k + db.secondary.spacing * k | |
443 local cy = db.secondary.padding | |
444 self.combo[i]:ClearAllPoints() | |
445 self.combo[i]:SetSize(px, db.secondary.height) | |
446 self.combo[i]:SetPoint(db.secondary.anchor, self, db.secondary.anchorTo, cx, cy) | |
447 --print(' ', self.combo[i]:GetName(), self.pointsize1, cx, cy, self.combo[i]:GetDrawLayer()) | |
448 | |
449 self.combo[i]:Show() | |
450 end | |
451 end | |
452 | |
453 | |
454 if self.secondary then | |
455 if not self.resources then | |
456 print('|cFFFF0000creating resources block') | |
457 self.resources = {} | |
458 else | |
459 local hidecount = 0 | |
460 for i, row in pairs(self.resources) do | |
461 for j, col in pairs(row) do | |
462 col:Hide() | |
463 hidecount = hidecount + 1 | |
464 end | |
465 end | |
466 print('hiding', hidecount, 'regions') | |
467 end | |
468 for name, secondary in pairs(self.secondary) do | |
469 local n = secondary.order | |
470 local sid = 'secondary'..n | |
471 local c = db[sid] or db | |
472 if not self.resources[n] then | |
473 print(' |cFFFF8800creating resource row') | |
474 self.resources[n] = {} | |
475 end | |
476 local row = self.resources[n] | |
477 | |
478 print('secondary resource', cText(name), 'max= '..cNum(secondary.max), 'scale= '..cNum(secondary.scale)) | |
479 local px = c.padding | |
480 local pw = (self.width - c.padding*2 - c.spacing * (secondary.scale - 1)) / secondary.scale | |
481 for i = 1, (secondary.max or 1) do | |
482 if not row[i] then | |
483 row[i] = bar:CreateTexture('TkResourcePellet.'..tostring(secondary.order)..'.'..tostring(i)) | |
484 end | |
485 row[i]:Show() | |
486 row[i]:SetDrawLayer('OVERLAY', sid) | |
487 row[i]:SetPoint('BOTTOMLEFT', self, 'TOPLEFT', px, c.y) | |
488 row[i]:SetSize(pw, db[sid].height or db.height) | |
489 | |
490 print(' *', cNum(i), cKey(sid), cNum(px), cNum(c.padding)) | |
491 px = px + pw + c.spacing | |
492 end | |
493 end | |
494 end | |
495 | |
496 mod.Bar_Event(self, nil, 'player') | |
497 end | |
498 | |
499 -- we only want to update at specific points | |
500 mod.Bar_Event = function(self, event, ...) | |
501 local unit, token = ... | |
502 _G.print('Update', event, unit, token) | |
503 if token and unit == 'player' then | |
504 mod.Bar_Power(self, token) | |
505 end | |
506 --print(unit, token, ...) | |
507 mod.Bar_Aura(bar, event, unit, token, ...) | |
508 end | |
509 | |
510 mod.Bar_Aura = function (self, event, unit) | |
511 _G.print('Update','bar updating function called', event, unit) | |
512 | |
513 | |
514 if event == 'UNIT_AURA' or event == nil then | |
515 for token, info in pairs(self.secondary) do | |
516 local row = self.resources[info.order] | |
517 if info.unit == unit then | |
518 local count = info.Get(info) | |
519 local db = db['secondary'..info.order] or db | |
520 for i = 1, info.max do | |
521 local palette = (i > count) and ('background_color') or ('foreground_color') | |
522 | |
523 print(token, i, count, (i > count), palette, unpack(db[palette])) | |
524 row[i]:SetTexture(unpack(db[palette])) | |
525 end | |
526 end | |
527 end | |
528 end | |
529 end | |
530 | |
531 function mod:Bar_Power(token) | |
532 if not self.primary[token] then | |
533 return | |
534 end | |
535 | |
536 local p = self.primary[token] | |
537 -- 1=cur, 2=max, 3=type, 4=token | |
538 p[1] = UnitPower('player', p[3]) | |
539 p[2] = UnitPowerMax('player', p[3]) | |
540 _G.print('Update',' ', table.concat(self.primary[token],', ')) | |
541 | |
542 if p[4] == 1 then | |
543 _G.print('Update', 'progress:', p[1]/p[2]) | |
544 --print(unpack(p)) | |
545 self.powerText:SetText(p[1]) | |
546 self:SetProgress(p[1]/p[2]) | |
547 elseif p[4] == 2 then | |
548 --print('update on', token, 'c:', p[1], 'm:', p[2]) | |
549 self.secondaryText:SetText(p[1]) | |
550 for i = 1, p[2] do | |
551 local palette = (i > p[1]) and 'background_color' or 'foreground_color' | |
552 self.combo[i]:SetTexture(unpack(db.secondary[palette])) | |
553 | |
554 end | |
555 end | |
556 end | |
557 | |
558 --- Spell parsing | |
559 function mod:SpellCastEvent(e, u, spellName, rank, castID, spellID) | |
560 if u ~= 'player' then | |
561 return true | |
562 end | |
563 if e == 'UNIT_SPELLCAST_DELAYED' then | |
564 elseif e == 'UNIT_SPELLCAST_START' then | |
565 bar.casting = true | |
566 bar.spellevent = T.spellevent[u] | |
567 bar.spell = T.casting[u] | |
568 elseif e == 'UNIT_SPELLCAST_CHANNEL_START' then | |
569 bar.channeling = true | |
570 bar.spellevent = T.spellevent[u] | |
571 bar.spell = T.channeling[u] | |
572 elseif e == 'UNIT_SPELLCAST_SUCCEEDED' then | |
573 elseif e == 'UNIT_SPELLCAST_STOP' then | |
574 bar.casting = nil | |
575 bar.casting = nil | |
576 elseif e == 'UNIT_SPELLCAST_CHANNEL_STOP' then | |
577 bar.channeling = nil | |
578 bar.channeling = nil | |
579 end | |
580 end | |
581 | |
582 function mod:PLAYER_TALENT_UPDATE(event, unit) | |
583 print(cText('*** Talent Update'), cKey('Spec:'), cWord(T.specName), cNum(T.specPage)) | |
584 mod:Prototype_Init() | |
585 end |