annotate Turok/Modules/Timer/Timer.lua @ 6:a9b8b0866ece

clear out log jam
author Nenue
date Sun, 21 Feb 2016 08:32:53 -0500
parents
children 9400a0ff8540
rev   line source
Nenue@6 1 --- Turok - Timer/Timer.lua
Nenue@6 2 -- @file-author@
Nenue@6 3 -- @project-revision@ @project-hash@
Nenue@6 4 -- @file-revision@ @file-hash@
Nenue@6 5 --- Defines common elements for the various timer HUDs
Nenue@6 6 local ADDON, _A = ...
Nenue@6 7 local _G, CreateFrame, tconcat, GetInventoryItemsForSlot, GetInventoryItemID = _G, CreateFrame, table.concat, GetInventoryItemsForSlot, GetInventoryItemID
Nenue@6 8 local T, F, tostring, type, max, tinsert, unpack, UIParent, loadstring = _A.Addon, _A.LibFog, tostring, type, max, table.insert, unpack, _G.UIParent, loadstring
Nenue@6 9 local mod = T.modules.TimerControl
Nenue@6 10 local P = mod.prototype
Nenue@6 11 local db
Nenue@6 12
Nenue@6 13 local pairs, ipairs, gsub, sub, setmetatable = pairs, ipairs, string.gsub, string.sub, setmetatable
Nenue@6 14 local INVTYPE_FINGER, INVSLOT_FINGER1, INVSLOT_FINGER2, INVTYPE_TRINKET, INVSLOT_TRINKET1, INVSLOT_TRINKET2 =
Nenue@6 15 INVTYPE_FINGER, INVSLOT_FINGER1, INVSLOT_FINGER2, INVTYPE_TRINKET, INVSLOT_TRINKET1, INVSLOT_TRINKET2
Nenue@6 16 --@debug@
Nenue@6 17 local DEBUG = true
Nenue@6 18 --@end-debug@
Nenue@6 19 local cType, cText, cNum, cWord, cKey, cPink, cBool = cType, cText, cNum, cWord, cKey, cPink, cBool
Nenue@6 20 local print = function(...)
Nenue@6 21 if not DEBUG then return end
Nenue@6 22 if _G.Devian and _G.DevianDB.workspace ~= 1 then
Nenue@6 23 _G.print('Timer', ...)
Nenue@6 24 end
Nenue@6 25 end
Nenue@6 26
Nenue@6 27 local Timer_GetPrintHandler = function(self)
Nenue@6 28 if self.trace then
Nenue@6 29 return function(...)
Nenue@6 30 print(...)
Nenue@6 31 _G.print('TimerFocus', ...)
Nenue@6 32 end else
Nenue@6 33 return print
Nenue@6 34 end
Nenue@6 35 end
Nenue@6 36 local pb_suppressed = {}
Nenue@6 37
Nenue@6 38 function mod:OnInitialize()
Nenue@6 39
Nenue@6 40 --@debug@
Nenue@6 41 TurokData.spirit.timers = Turok.defaults.spirit.timers
Nenue@6 42 --@end-debug@
Nenue@6 43 self.db = TurokData.spirit
Nenue@6 44 db = self.db
Nenue@6 45 self.active_cooldowns = {}
Nenue@6 46 self.cast_units = {}
Nenue@6 47 self.buff_units = {}
Nenue@6 48 self.loaded_types = {}
Nenue@6 49 self.loaded_triggers = {}
Nenue@6 50 self.equipped = {}
Nenue@6 51 self.containers = {}
Nenue@6 52 self.timers = {} -- active timers
Nenue@6 53 self.empty_frames = {} -- foster table for frames released by talent change
Nenue@6 54
Nenue@6 55
Nenue@6 56 T:RegisterChatCommand("tsp", self.Import_Open)
Nenue@6 57 T:RegisterChatCommand("tka", self.Dialog_Command)
Nenue@6 58 T:RegisterChatCommand("tki", self.CreateIndex)
Nenue@6 59 --T:Print("/tsp to import spells. /tka to open create dialog")
Nenue@6 60 -- suppress cacophony from all cooldowns activating at login
Nenue@6 61 self.quiet = true
Nenue@6 62 --self:ScheduleTimer(function() self:Dialog_Command() end, 4)
Nenue@6 63
Nenue@6 64 end
Nenue@6 65
Nenue@6 66 local mt_single = {
Nenue@6 67 __mode = "v",
Nenue@6 68 __newindex = function(t,k,v)
Nenue@6 69 rawset(t,k,v)
Nenue@6 70 _G.print('DB', 'TCMeta: adding leaf', k, '=', v)
Nenue@6 71 end}
Nenue@6 72 local mt_double = {
Nenue@6 73 __index = function(t,k)
Nenue@6 74 t[k] = setmetatable({}, mt_single)
Nenue@6 75 _G.print('DB', 'TCMeta: add layer', k, '=', t[k])
Nenue@6 76 return t[k]
Nenue@6 77 end,
Nenue@6 78 __newindex = function(t,k,v)
Nenue@6 79 rawset(t,k,v)
Nenue@6 80 _G.print('DB', 'TCMeta: adding to top layer', k, '=', v)
Nenue@6 81 end
Nenue@6 82 }
Nenue@6 83 local mt_error = {
Nenue@6 84 __call =function (t, txt)
Nenue@6 85 t.disable = true
Nenue@6 86 tinsert(t, txt)
Nenue@6 87 end
Nenue@6 88 }
Nenue@6 89
Nenue@6 90 --- Sets and cleans up index data used by event handlers
Nenue@6 91 local Timer_UpdateIndex = function(self, key)
Nenue@6 92
Nenue@6 93 -- Is there already an entry for this key/value?
Nenue@6 94 if self.frames[key] then
Nenue@6 95 local lim = #mod.frames[key]
Nenue@6 96 --[[
Nenue@6 97 for i = self.frames[key]+1, lim, 1 do
Nenue@6 98 mod.frames[key][i] = mod.frames[key+1]
Nenue@6 99 end]]
Nenue@6 100 --self.frames[key] = nil
Nenue@6 101 print(' ', cText('mod.frames.')..cWord(key), '=', #mod.frames[key])
Nenue@6 102 print(' ', cText('self.frames.')..cWord(key), '=', cNum(self.frames[key]))
Nenue@6 103 end
Nenue@6 104
Nenue@6 105 if key then
Nenue@6 106 local i = #mod.frames[key]+1
Nenue@6 107 --mod.frames[key][i] = self
Nenue@6 108 self.frames[key] = i
Nenue@6 109 print(' ', cText('self.frames.')..cWord(key), '=', #mod.frames[key])
Nenue@6 110 end
Nenue@6 111 mod.loaded_types[key] = (#mod.frames[key] == 0) and nil or true
Nenue@6 112 print(' ',cText(key..'_is_loaded'), '=', cBool(mod.loaded_types[key]))
Nenue@6 113 end
Nenue@6 114
Nenue@6 115 --- Loading initators
Nenue@6 116 function mod:OnEnable()
Nenue@6 117 mod.LoadPresets()
Nenue@6 118 mod.GetIndex()
Nenue@6 119 -- setup indexes, use nested weak table for status since they implicitly have a key variable
Nenue@6 120 mod.frames = {}
Nenue@6 121 for class, p in pairs(mod.prototype.status) do
Nenue@6 122 print('nested index table', class)
Nenue@6 123 mod.frames[class] = setmetatable({}, mt_double)
Nenue@6 124 end
Nenue@6 125 mod.frames.spellName = setmetatable({}, mt_double)
Nenue@6 126 for class, p in pairs(mod.prototype.display) do
Nenue@6 127 mod.frames[class] = setmetatable({}, mt_single)
Nenue@6 128 end
Nenue@6 129 for class, p in pairs(mod.prototype.trigger) do
Nenue@6 130 mod.frames[class] = setmetatable({}, mt_single)
Nenue@6 131 end
Nenue@6 132
Nenue@6 133 local srcIndex = mod.timers
Nenue@6 134 if T.playerClass and mod.index[T.playerClass] then
Nenue@6 135 srcIndex = mod.index[T.playerClass]
Nenue@6 136 print('*** Found index for '..tostring(T.playerClass)..', using that.')
Nenue@6 137 else
Nenue@6 138 print(cWord('*** Using global index.'))
Nenue@6 139 end
Nenue@6 140 mod.activeSpec = T.specID
Nenue@6 141
Nenue@6 142 --- go through that list
Nenue@6 143 for id, timer in pairs(srcIndex) do
Nenue@6 144 local result, message = mod:EnableTimer(id, timer)
Nenue@6 145 end
Nenue@6 146
Nenue@6 147 mod.InitTimers()
Nenue@6 148 --- Delay sound activations so there isn't a giant cacophony on load
Nenue@6 149 mod:ScheduleTimer(function()
Nenue@6 150 self.quiet = nil
Nenue@6 151 end, db.audio_delay or 2)
Nenue@6 152 end
Nenue@6 153
Nenue@6 154 function mod:EnableTimer(id, dvars)
Nenue@6 155 local print = Timer_GetPrintHandler(dvars)
Nenue@6 156 print('-{', cPink(dvars.name))
Nenue@6 157 if not dvars then
Nenue@6 158 if not mod.index.global[id] then
Nenue@6 159 return false, "Unable to resolve dvars table."
Nenue@6 160 end
Nenue@6 161 dvars = mod.index.global[id]
Nenue@6 162 end
Nenue@6 163 if dvars.virtual then
Nenue@6 164 return
Nenue@6 165 end
Nenue@6 166
Nenue@6 167 local spirit, newFrame = mod:GetTimer(id, dvars)
Nenue@6 168 if not spirit then return spirit, newFrame end
Nenue@6 169
Nenue@6 170 local cvars = spirit.cvars
Nenue@6 171 local dvars = spirit.dvars
Nenue@6 172 local trigger = P.trigger[cvars.type]
Nenue@6 173 local display = P.display[cvars.display]
Nenue@6 174 local cvars = spirit.cvars
Nenue@6 175 local index = mod.frames
Nenue@6 176 local print = Timer_GetPrintHandler(cvars)
Nenue@6 177
Nenue@6 178 if spirit.disable then
Nenue@6 179 return false, "Manually disabled." -- nothing to do, nothing to say
Nenue@6 180 end
Nenue@6 181
Nenue@6 182 --- Interpret STATUS vars
Nenue@6 183 print(cText(' *** Merging Status Data'))
Nenue@6 184 spirit.disable = dvars.disable
Nenue@6 185 local pcount = 1
Nenue@6 186 for k, handler in pairs(P.status) do
Nenue@6 187 if cvars[k] then
Nenue@6 188 if handler.Init then
Nenue@6 189 print(cWord(' * Firing ')..cKey(k)..cWord('.Init'), cNum(cvars[k]))
Nenue@6 190 handler.Init(spirit, cvars[k])
Nenue@6 191 else
Nenue@6 192 print(' ', cText('skipped'), cKey(k))
Nenue@6 193 end
Nenue@6 194 pcount = pcount + 1
Nenue@6 195 end
Nenue@6 196 end
Nenue@6 197
Nenue@6 198 spirit.Event = trigger.Event
Nenue@6 199 spirit.Value = trigger.Value
Nenue@6 200 spirit.SetText = mod.SetText
Nenue@6 201 spirit.LoadText = mod.LoadText
Nenue@6 202 spirit.Query = trigger.Query
Nenue@6 203 spirit.Set = trigger.Set
Nenue@6 204
Nenue@6 205 --- Display handler init
Nenue@6 206 if display.Init then
Nenue@6 207 print(cText(' * Display Init:'), cKey(dvars.display))
Nenue@6 208 display.Init(spirit)
Nenue@6 209 end
Nenue@6 210
Nenue@6 211 --- Trigger handler and events Load()
Nenue@6 212 print(cText(' * Trigger Init:'), cKey(dvars.type))
Nenue@6 213 trigger.Init(spirit)
Nenue@6 214
Nenue@6 215
Nenue@6 216 if C_PetBattles.IsInBattle() then
Nenue@6 217 spirit.disable = true
Nenue@6 218 spirit.debug_info("Hidden for pet battle")
Nenue@6 219 pb_suppressed[id] = true
Nenue@6 220 end
Nenue@6 221
Nenue@6 222
Nenue@6 223 if spirit.disable then
Nenue@6 224 spirit:UnregisterAllEvents()
Nenue@6 225 spirit.displayState = nil
Nenue@6 226 spirit.prevState = nil
Nenue@6 227 spirit:Hide()
Nenue@6 228 return false, tconcat(spirit.debug_info,"\n")
Nenue@6 229 else
Nenue@6 230 print('--', self.disable and cPink('DISABLED') or cNum('ENABLED'), #spirit.debug_info > 0 and tconcat(spirit.debug_info,"\n"), '}')
Nenue@6 231 return true, tconcat(spirit.debug_info,"\n")
Nenue@6 232 end
Nenue@6 233 end
Nenue@6 234
Nenue@6 235 function mod:GetTimer(id, dvars)
Nenue@6 236 local print = Timer_GetPrintHandler(dvars)
Nenue@6 237 local newFrame
Nenue@6 238 if not mod.timers[id] then
Nenue@6 239 print(cKey(' [[CreateTimer'))
Nenue@6 240 newFrame = true
Nenue@6 241 --- Compile the cvar table from the various config layers:
Nenue@6 242 -- Start with timer dvars, overwritten by any container settings, then a disable check, then merge in prototype values
Nenue@6 243 local cvars = T.Config_Push({}, dvars, nil, cKey('['..id..']')..'.'..cWord('cvars'))
Nenue@6 244 cvars.name = dvars.name -- push function ignores name keys
Nenue@6 245
Nenue@6 246 if dvars.container and db.containers[dvars.container] then
Nenue@6 247 print(cText(' * Merging Container overrides'))
Nenue@6 248 T.Config_Push(cvars, db.containers[dvars.container], cvars, cKey('['..id..']')..'.'..cWord('cvars'))
Nenue@6 249 end
Nenue@6 250
Nenue@6 251 --- Stop here if disabled via SavedVars
Nenue@6 252 if cvars.disable then
Nenue@6 253 return false, "Manually disabled"
Nenue@6 254 end
Nenue@6 255
Nenue@6 256 --- Localize the stuff we are going to loop over
Nenue@6 257 local display = P.display[cvars.display]
Nenue@6 258 local trigger = P.trigger[cvars.type]
Nenue@6 259 local displayType = cvars.display
Nenue@6 260 local triggerType = cvars.type
Nenue@6 261 if not (display and trigger) then
Nenue@6 262 return nil, "Missing prototype data. Summary: "..tostring(displayType).."="..(display and 'OK' or 'MISSING') ..
Nenue@6 263 " "..tostring(triggerType).."="..(trigger and 'OK' or 'MISSING')
Nenue@6 264 end
Nenue@6 265
Nenue@6 266 --- Establish the order in which values are merged
Nenue@6 267 print(cText(' * Merging object CVars'))
Nenue@6 268 local cvar_class = {cWord('db.'..displayType), cWord('db.'..triggerType), cWord('db.global')}
Nenue@6 269 local cvar_array = {
Nenue@6 270 db[displayType],
Nenue@6 271 db[triggerType],
Nenue@6 272 db.global,
Nenue@6 273 }
Nenue@6 274 local override_class = {cWord('trigger.'..cvars.type), cWord('display.'.. cvars.display)}
Nenue@6 275 local override_array = {
Nenue@6 276 display.cvars,
Nenue@6 277 trigger.cvars }
Nenue@6 278
Nenue@6 279 --- Table merge user settings
Nenue@6 280 for i, p in pairs(cvar_array) do
Nenue@6 281 print(' '..cNum(i)..' merge ['..cvar_class[i]..']')
Nenue@6 282 T.Config_Merge(cvars, p, cvars, cKey('['..id..']')..'.'..cWord('cvars'))
Nenue@6 283 end
Nenue@6 284
Nenue@6 285 --- Overwrite with anything defined by the prototype structure because it's important
Nenue@6 286 local _, odiff
Nenue@6 287 for i, p in ipairs(override_array) do
Nenue@6 288 _, odiff = T.Config_Push(cvars, p, cvars, cKey('['..id..']')..'.'..cWord('cvars'))
Nenue@6 289 end
Nenue@6 290 local print = Timer_GetPrintHandler(cvars)
Nenue@6 291
Nenue@6 292 --- Create the UI frame and seed it with the data we just composed
Nenue@6 293 local spirit = CreateFrame('Frame', 'TurokTimerFrame'..gsub(dvars.name, "[^%a%d]", ''), UIParent, display.inherits)
Nenue@6 294 spirit.trace = cvars.trace
Nenue@6 295 spirit.timerID = id
Nenue@6 296 spirit.timerName = dvars.name
Nenue@6 297 spirit.container = dvars.container
Nenue@6 298 spirit.cvars = cvars
Nenue@6 299 spirit.dvars = dvars
Nenue@6 300 spirit.Update = display.Update
Nenue@6 301 spirit.SetState = display.SetState
Nenue@6 302 spirit.Report = mod.Report
Nenue@6 303 spirit.Stats = trigger.Stats
Nenue@6 304
Nenue@6 305 --- Set Layout Statics
Nenue@6 306 T.SetFrameLayout(spirit, cvars)
Nenue@6 307
Nenue@6 308 --- Create troubleshooting collection
Nenue@6 309 spirit.debug_info = setmetatable({}, mt_error)
Nenue@6 310
Nenue@6 311 --- Add the frame to corresponding prototype indexes
Nenue@6 312 spirit.frames = {}
Nenue@6 313 spirit.events = {}
Nenue@6 314
Nenue@6 315 if spirit.display ~= displayType then
Nenue@6 316 spirit.display = displayType
Nenue@6 317 Timer_UpdateIndex(spirit, displayType)
Nenue@6 318 end
Nenue@6 319 if spirit.type ~= triggerType then
Nenue@6 320 spirit.type = triggerType
Nenue@6 321 Timer_UpdateIndex(spirit, triggerType)
Nenue@6 322 end
Nenue@6 323 --- Add the frame to global index
Nenue@6 324 mod.timers[id] = spirit
Nenue@6 325 end
Nenue@6 326
Nenue@6 327 return mod.timers[id], newFrame
Nenue@6 328 end
Nenue@6 329
Nenue@6 330 function mod.InitTimers()
Nenue@6 331 local print = function(...) _G.print('TimerEvent', ...) end
Nenue@6 332 print('INIT TIMERS ====================')
Nenue@6 333 for id, spirit in pairs(mod.timers) do
Nenue@6 334 if spirit.disable then
Nenue@6 335 print(id, 'disabled:', tconcat(spirit.debug_info or {}, ', '))
Nenue@6 336 else
Nenue@6 337
Nenue@6 338 print(cText('init'), cNum(id), cWord(spirit.name))
Nenue@6 339 --- Throw a dry event to initialize values
Nenue@6 340 print(cText(' *'), cWord('prototype.'..cKey(spirit.dvars.type)..'.'..cWord('Load')))
Nenue@6 341 P.trigger[spirit.dvars.type].Event(spirit)
Nenue@6 342
Nenue@6 343 --- Set loose
Nenue@6 344 print(cText(' *'), cWord('prototype')..'.'..cKey('events')..'.'..cWord('Load'))
Nenue@6 345 mod.UpdateEvents(spirit, P.trigger[spirit.dvars.type].events)
Nenue@6 346 end
Nenue@6 347 end
Nenue@6 348 print('INIT DONE =========================')
Nenue@6 349 end
Nenue@6 350
Nenue@6 351 function mod:DisableTimer(name, timer)
Nenue@6 352 local timer_frame = mod.db.timers[name]
Nenue@6 353 if timer_frame and not timer_frame.disable then
Nenue@6 354 timer_frame.disable = true
Nenue@6 355 timer_frame:UnregisterAllEvents()
Nenue@6 356 timer_frame:Hide()
Nenue@6 357 end
Nenue@6 358 end
Nenue@6 359
Nenue@6 360 function mod.UpdateEvents(self, events)
Nenue@6 361 local print = Timer_GetPrintHandler(self)
Nenue@6 362
Nenue@6 363 self:SetScript('OnEvent', nil)
Nenue@6 364 self:UnregisterAllEvents()
Nenue@6 365
Nenue@6 366 local proxy, listen = {}, {}
Nenue@6 367 for event, handler in pairs(events) do
Nenue@6 368 if mod[event] then
Nenue@6 369 tinsert(proxy, cNum(event))
Nenue@6 370 else
Nenue@6 371 tinsert(listen, cWord(event))
Nenue@6 372 self:RegisterEvent(event)
Nenue@6 373 end
Nenue@6 374 self.events[event] = handler
Nenue@6 375 end
Nenue@6 376
Nenue@6 377 if #proxy > 0 then
Nenue@6 378 print( ' -', cKey(self.name), cWord('receiving'), tconcat(proxy, ', '))
Nenue@6 379 end
Nenue@6 380 if #listen > 0 then
Nenue@6 381 print( ' -', cKey(self.name), cText('listening'), tconcat(listen, ', '))
Nenue@6 382 end
Nenue@6 383
Nenue@6 384 self:SetScript('OnEvent', self.Event)
Nenue@6 385 end
Nenue@6 386
Nenue@6 387 local match_sub = {
Nenue@6 388 {'%%c', "' .. tostring(t.caster).. '"},
Nenue@6 389 {'%%h', "' .. tostring((t.valueFull >= 60) and (math.floor(t.valueFull/60)) or t.value) .. '"},
Nenue@6 390 {'%%i', "' .. tostring((t.valueFull >= 60) and (t.value % 60) or ((t.valueFull < 6) and math.floor((t.ValueFull * 100) % 100) or '')) .. '"},
Nenue@6 391 {'%%n', "' .. tostring(t.spellName) .. '"},
Nenue@6 392 {'%%p', "' .. tostring(t.value) .. '"},
Nenue@6 393 {'%%d', "' .. tostring(t.chargeDuration or t.duration) .. '"},
Nenue@6 394 {'%%%.p', "' .. string.sub(tostring((t.valueFull %% 1) * 100),0,1) .. '"},
Nenue@6 395 {"%%s", "' .. (t.stacks or t.charges or '') .. '"},
Nenue@6 396 }
Nenue@6 397
Nenue@6 398 -- dot syntax implies use as embedded method
Nenue@6 399 function mod.LoadText(self)
Nenue@6 400 print(cKey('parsing textRegions for'), self.timerName, self.timerID)
Nenue@6 401 self.textTypes = {}
Nenue@6 402 self.textValues = {}
Nenue@6 403 for name, region in pairs(self.textRegions) do
Nenue@6 404 print(' ', cWord('textRegions')..'["'.. cType(self.timerName)..'"].'..cType(name))
Nenue@6 405 if self.cvars[name..'Text'] then
Nenue@6 406
Nenue@6 407 -- todo: collect match counts and index the text fields by match types
Nenue@6 408 local str = self.cvars[name..'Text']
Nenue@6 409 for i, args in ipairs(match_sub) do
Nenue@6 410 if str:match(args[1]) then
Nenue@6 411 if not self.textTypes[args[1]] then
Nenue@6 412 self.textTypes[args[1]] = {}
Nenue@6 413 end
Nenue@6 414 tinsert(self.textTypes[args[1]], region)
Nenue@6 415 str = str:gsub(args[1], args[2])
Nenue@6 416 end
Nenue@6 417 end
Nenue@6 418 str = "local t = _G.Turok.modules.TimerControl.timers["..self.timerID.."]\n"
Nenue@6 419 .. "\n return '" .. str .. "'"
Nenue@6 420 local func = assert(loadstring(str))
Nenue@6 421 self.textValues[name] = func
Nenue@6 422 end
Nenue@6 423 end
Nenue@6 424
Nenue@6 425 --mod.SetText(self)
Nenue@6 426 end
Nenue@6 427
Nenue@6 428 --- generic text setter
Nenue@6 429 local HIDDEN, PASSIVE, ACTIVE = 0, 1, 2
Nenue@6 430 mod.SetText = function(self)
Nenue@6 431 if self.displayState ~= ACTIVE then
Nenue@6 432 for name, region in pairs(self.textRegions) do
Nenue@6 433 region:SetText(nil)
Nenue@6 434 end
Nenue@6 435 return
Nenue@6 436 end
Nenue@6 437
Nenue@6 438 if not self.textValues then
Nenue@6 439 self.textValues = {}
Nenue@6 440 mod.LoadText(self, self.cvars)
Nenue@6 441 end
Nenue@6 442
Nenue@6 443 -- hide when above a certain number
Nenue@6 444
Nenue@6 445 if self.spiral and self.spiral.subCounter then
Nenue@6 446 if self.valueFull > 6 then
Nenue@6 447 if self.textValues.subCounter then
Nenue@6 448 --print('hiding milliseconds')
Nenue@6 449 self.textRegions.subCounter:Hide()
Nenue@6 450 self.textRegionsSub = self.textRegions.subCounter
Nenue@6 451 self.textValuesSub = self.textValues.subCounter
Nenue@6 452 self.textRegions.subCounter = nil
Nenue@6 453 self.textValues.subCounter = nil
Nenue@6 454 end
Nenue@6 455 else
Nenue@6 456 if not self.textValues.subCounter then
Nenue@6 457 --print('showing milliseconds')
Nenue@6 458 self.textValues.subCounter = self.textValuesSub
Nenue@6 459 self.textRegions.subCounter = self.textRegionsSub
Nenue@6 460 self.textRegions.subCounter:Show()
Nenue@6 461 end
Nenue@6 462 end
Nenue@6 463 end
Nenue@6 464
Nenue@6 465 for name, region in pairs(self.textRegions) do
Nenue@6 466 --print(name)
Nenue@6 467 --print(name, self.timerName, self.textValues[name](self))
Nenue@6 468 region:SetText(self.textValues[name](self))
Nenue@6 469 end
Nenue@6 470 end
Nenue@6 471
Nenue@6 472
Nenue@6 473 -------------------------------------------------------------------------
Nenue@6 474 --- Second-tier handlers to cut down on the number of Status:Event() polls
Nenue@6 475
Nenue@6 476 --- UNIT_SPELLCAST_*** use args to filter out the number of full handler runs
Nenue@6 477 function mod:UNIT_SPELLCAST_SUCCEEDED (e, unit, spellName, rank, castID, spellID)
Nenue@6 478 if not mod.frames.unit[unit] then
Nenue@6 479 return
Nenue@6 480 end
Nenue@6 481
Nenue@6 482 if #mod.frames.spellName[spellName] > 0 then
Nenue@6 483 print('spellName-ID relation detected:', cWord(spellName), cNum(spellID))
Nenue@6 484 for i, frame in pairs(mod.frames.spellName[spellName]) do
Nenue@6 485 if not frame.frames.spellID then
Nenue@6 486 frame.frames.spellID = {}
Nenue@6 487 end
Nenue@6 488 if not frame.frames.spellID[spellID] then
Nenue@6 489
Nenue@6 490 tinsert(mod.frames.spellID[spellID], frame)
Nenue@6 491 frame.frames.spellID[spellID] = #mod.frames.spellID[spellID]
Nenue@6 492 print(cText(' updating'), cKey(frame.timerName))
Nenue@6 493 end
Nenue@6 494 end
Nenue@6 495 mod.frames.spellName[spellName] = nil
Nenue@6 496 end
Nenue@6 497
Nenue@6 498
Nenue@6 499
Nenue@6 500 if mod.frames.spellID[spellID] then
Nenue@6 501 for i, timer_frame in pairs(mod.frames.spellID[spellID]) do
Nenue@6 502 print(cText('caught spell'), cWord(spellName), 'for', timer_frame:GetName())
Nenue@6 503 timer_frame:Event(e, unit, spellName, rank, castID, spellID)
Nenue@6 504 end
Nenue@6 505 end
Nenue@6 506 end
Nenue@6 507 mod.UNIT_SPELLCAST_CHANNEL_START = mod.UNIT_SPELLCAST_SUCCEEDED
Nenue@6 508
Nenue@6 509 --- Fire a dry event to force status updates on units with changing GUID's
Nenue@6 510 function mod:PLAYER_TARGET_CHANGED(e, unit)
Nenue@6 511 print('doing a target swap thing')
Nenue@6 512 for k, v in pairs( self.frames.unit.target) do
Nenue@6 513 print(k, v)
Nenue@6 514 v:Event(nil, 'target')
Nenue@6 515 end
Nenue@6 516 end
Nenue@6 517
Nenue@6 518 --- Same thing but for talent/spec-driven
Nenue@6 519 function mod:PLAYER_TALENT_UPDATE(e, unit)
Nenue@6 520 print('')
Nenue@6 521 print('')
Nenue@6 522 print(cText(e), T.specPage, T.specName)
Nenue@6 523
Nenue@6 524 local update_queue = {}
Nenue@6 525 for _, k in ipairs({'talentID', 'talentRow', 'specPage'}) do
Nenue@6 526 for value, frameSet in pairs(mod.frames.talentID) do
Nenue@6 527 for id, frame in ipairs(frameSet) do
Nenue@6 528 print(frame.timerID, frame.timerName)
Nenue@6 529 update_queue[frame.timerID] = frame
Nenue@6 530 end
Nenue@6 531 end
Nenue@6 532 end
Nenue@6 533
Nenue@6 534 for id, frame in pairs(update_queue) do
Nenue@6 535 print('Refreshing spec-related frames', id, frame.timerName)
Nenue@6 536 frame.disable = nil
Nenue@6 537 table.wipe(frame.debug_info)
Nenue@6 538 local res, msg = mod:EnableTimer(id, frame.dvars)
Nenue@6 539 end
Nenue@6 540
Nenue@6 541 end
Nenue@6 542
Nenue@6 543 function mod:PLAYER_EQUIPMENT_CHANGED(e, slot, hasItem)
Nenue@6 544 print(e, slot, hasItem)
Nenue@6 545 local itemCheckList
Nenue@6 546 if mod.frames.inventoryID and mod.frames.inventoryID[slot] then
Nenue@6 547 print(' Inventory Frames:')
Nenue@6 548 itemCheckList = GetInventoryItemsForSlot(slot, {}, false)
Nenue@6 549 for id, slotFrame in pairs(mod.frames.inventoryID[slot]) do
Nenue@6 550 print(' * Updating', cNum(id), cWord(slotFrame.timerName))
Nenue@6 551 local res, msg = mod:EnableTimer(slotFrame.timerID, slotFrame.dvars)
Nenue@6 552 print(' ', cBool(res), cText(msg))
Nenue@6 553 end
Nenue@6 554 end
Nenue@6 555 if itemCheckList then
Nenue@6 556 print(unpack(itemCheckList))
Nenue@6 557 end
Nenue@6 558 local itemID = GetInventoryItemID('player', slot)
Nenue@6 559 if itemID and mod.frames.itemID[itemID] then
Nenue@6 560 print(' Item ID Frames:')
Nenue@6 561 for id, itemFrame in pairs(mod.frames.itemID[itemID]) do
Nenue@6 562 print(' * Updating', cNum(id), cWord(itemFrame.timerName))
Nenue@6 563
Nenue@6 564 local res, msg = mod:EnableTimer(itemFrame.timerID, itemFrame.dvars)
Nenue@6 565 print(' ', cBool(res), cText(msg))
Nenue@6 566 end
Nenue@6 567 end
Nenue@6 568 end
Nenue@6 569 function mod:PET_BATTLE_OPENING_START ()
Nenue@6 570 for i, v in pairs(mod.timers) do
Nenue@6 571 if not v.disable then
Nenue@6 572 print('suppressing', v:GetName())
Nenue@6 573 v.disable = true
Nenue@6 574 v:Hide()
Nenue@6 575 pb_suppressed[i] = true
Nenue@6 576 end
Nenue@6 577 end
Nenue@6 578 end
Nenue@6 579 function mod:PET_BATTLE_CLOSE()
Nenue@6 580 for id, v in pairs(mod.timers) do
Nenue@6 581 if pb_suppressed[id] then
Nenue@6 582 print('restoring', v:GetName())
Nenue@6 583 mod:EnableTimer(id)
Nenue@6 584 pb_suppressed[id] = nil
Nenue@6 585 end
Nenue@6 586 end
Nenue@6 587 end