annotate Turok/Modules/Timer/Timer.lua @ 9:9400a0ff8540

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