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