| 
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@9
 | 
    33 
 | 
| 
Nenue@9
 | 
    34 local print = function(...)
 | 
| 
Nenue@9
 | 
    35   if _G.Devian and _G.DevianDB.workspace ~= 1 then
 | 
| 
Nenue@9
 | 
    36     _G.print('Cooldown', ...)
 | 
| 
Nenue@9
 | 
    37   end
 | 
| 
Nenue@9
 | 
    38 end
 | 
| 
Nenue@6
 | 
    39 local function GetPrint (trace)
 | 
| 
Nenue@6
 | 
    40   return trace and print or function() end
 | 
| 
Nenue@6
 | 
    41 end
 | 
| 
Nenue@6
 | 
    42 
 | 
| 
Nenue@6
 | 
    43 
 | 
| 
Nenue@6
 | 
    44 local item_spells = {
 | 
| 
Nenue@6
 | 
    45   ['PvP Trinket'] = 42292,
 | 
| 
Nenue@6
 | 
    46   ['Burning Mirror'] = 184270,
 | 
| 
Nenue@6
 | 
    47 }
 | 
| 
Nenue@6
 | 
    48 
 | 
| 
Nenue@6
 | 
    49 T.defaults.spirit.cooldown = {
 | 
| 
Nenue@6
 | 
    50 
 | 
| 
Nenue@6
 | 
    51   alpha = 1,
 | 
| 
Nenue@6
 | 
    52   alpha_ooc = 0.2,
 | 
| 
Nenue@6
 | 
    53   inverse = false,
 | 
| 
Nenue@6
 | 
    54   persist = false,
 | 
| 
Nenue@6
 | 
    55   desaturated = false,
 | 
| 
Nenue@6
 | 
    56   fill_inverse = true,
 | 
| 
Nenue@6
 | 
    57   size = 24,
 | 
| 
Nenue@9
 | 
    58   counterText = "%i",
 | 
| 
Nenue@6
 | 
    59   subCounterText = "%.p",
 | 
| 
Nenue@6
 | 
    60   chargesText = "%s",
 | 
| 
Nenue@6
 | 
    61   justifyH = 'CENTER',
 | 
| 
Nenue@6
 | 
    62   justifyV = 'TOP',
 | 
| 
Nenue@6
 | 
    63 
 | 
| 
Nenue@6
 | 
    64   iconText = "%p",
 | 
| 
Nenue@6
 | 
    65   leftText = "%p",
 | 
| 
Nenue@6
 | 
    66   rightText = "%n / %d",
 | 
| 
Nenue@6
 | 
    67   passive = {
 | 
| 
Nenue@6
 | 
    68     icon = {
 | 
| 
Nenue@6
 | 
    69       desaturated = false,
 | 
| 
Nenue@6
 | 
    70       color = {1, 1, 1, 1},
 | 
| 
Nenue@6
 | 
    71     }
 | 
| 
Nenue@6
 | 
    72   },
 | 
| 
Nenue@6
 | 
    73   active = {
 | 
| 
Nenue@6
 | 
    74     icon = {
 | 
| 
Nenue@9
 | 
    75       desaturated = true,
 | 
| 
Nenue@6
 | 
    76       color = {1, 1, 1, .6},
 | 
| 
Nenue@6
 | 
    77     }
 | 
| 
Nenue@6
 | 
    78   },
 | 
| 
Nenue@6
 | 
    79 
 | 
| 
Nenue@6
 | 
    80   --- control displays of aura information in cooldown displays
 | 
| 
Nenue@9
 | 
    81   overrideAura = false,
 | 
| 
Nenue@9
 | 
    82   overrideDuration = false,
 | 
| 
Nenue@9
 | 
    83   override = {
 | 
| 
Nenue@6
 | 
    84     icon = {
 | 
| 
Nenue@6
 | 
    85       desaturated = true,
 | 
| 
Nenue@6
 | 
    86       color = {0,1,0,1},
 | 
| 
Nenue@6
 | 
    87     }
 | 
| 
Nenue@6
 | 
    88   }
 | 
| 
Nenue@6
 | 
    89 }
 | 
| 
Nenue@6
 | 
    90 
 | 
| 
Nenue@6
 | 
    91 local p = mod.prototype.trigger.cooldown
 | 
| 
Nenue@6
 | 
    92 --@end-debug@
 | 
| 
Nenue@6
 | 
    93 p.class  = 'trigger'
 | 
| 
Nenue@6
 | 
    94 p.type = 'cooldown'
 | 
| 
Nenue@6
 | 
    95 p.cvars = {
 | 
| 
Nenue@6
 | 
    96 }
 | 
| 
Nenue@6
 | 
    97 --- Sets initial values before dry Event is fired to check for presence
 | 
| 
Nenue@6
 | 
    98 p.Init = function(self, spellID, caster, tristate, minValue, maxValue)
 | 
| 
Nenue@6
 | 
    99   local print = GetPrint(self.trace)
 | 
| 
Nenue@6
 | 
   100 
 | 
| 
Nenue@6
 | 
   101   self.spellID = spellID and spellID or self.spellID
 | 
| 
Nenue@6
 | 
   102   self.unit = caster and caster or self.unit
 | 
| 
Nenue@6
 | 
   103   self.persist = tristate and tristate or self.persist
 | 
| 
Nenue@6
 | 
   104   self.minValue = minValue and minValue or tonumber(self.minValue)
 | 
| 
Nenue@6
 | 
   105   self.maxValue = maxValue and maxValue or tonumber(self.maxValue)
 | 
| 
Nenue@6
 | 
   106 
 | 
| 
Nenue@9
 | 
   107   self.start = 0
 | 
| 
Nenue@9
 | 
   108   self.duration = 0
 | 
| 
Nenue@9
 | 
   109   self.expires = 0
 | 
| 
Nenue@9
 | 
   110   self.charges = nil
 | 
| 
Nenue@9
 | 
   111   self.charges_max = 0
 | 
| 
Nenue@9
 | 
   112   self.charge_start = 0
 | 
| 
Nenue@9
 | 
   113   self.charge_duration = 0
 | 
| 
Nenue@9
 | 
   114   self.charge_expires = 0
 | 
| 
Nenue@9
 | 
   115   self.override = false
 | 
| 
Nenue@9
 | 
   116   self.override_start = 0
 | 
| 
Nenue@9
 | 
   117   self.override_duration = 0
 | 
| 
Nenue@9
 | 
   118   self.override_expires = 0
 | 
| 
Nenue@9
 | 
   119 
 | 
| 
Nenue@6
 | 
   120   --- current and last state values need to be flipped for inverted conditional
 | 
| 
Nenue@6
 | 
   121   --- last state is defined in case it needs to be overridden to ensure proper frame update
 | 
| 
Nenue@6
 | 
   122   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
 | 
   123   print(cWord('  inverse=')..cBool(self.cvars.inverse))
 | 
| 
Nenue@6
 | 
   124   if self.cvars.inverse then
 | 
| 
Nenue@6
 | 
   125     self.flags = {
 | 
| 
Nenue@6
 | 
   126       active = HIDDEN,
 | 
| 
Nenue@6
 | 
   127       active_prev = ACTIVE,
 | 
| 
Nenue@6
 | 
   128       passive = PASSIVE,
 | 
| 
Nenue@6
 | 
   129       passive_prev = PASSIVE,
 | 
| 
Nenue@6
 | 
   130       hidden = PASSIVE,
 | 
| 
Nenue@6
 | 
   131       hidden_prev = HIDDEN,
 | 
| 
Nenue@6
 | 
   132     }
 | 
| 
Nenue@6
 | 
   133   else
 | 
| 
Nenue@6
 | 
   134     self.flags = {
 | 
| 
Nenue@6
 | 
   135       active = ACTIVE,
 | 
| 
Nenue@6
 | 
   136       active_prev = HIDDEN,
 | 
| 
Nenue@6
 | 
   137       passive = PASSIVE,
 | 
| 
Nenue@6
 | 
   138       passive_prev = HIDDEN,
 | 
| 
Nenue@6
 | 
   139       hidden = HIDDEN,
 | 
| 
Nenue@6
 | 
   140       hidden_prev = PASSIVE
 | 
| 
Nenue@6
 | 
   141     }
 | 
| 
Nenue@6
 | 
   142   end
 | 
| 
Nenue@6
 | 
   143   if not (self.spellID or self.spellName) then
 | 
| 
Nenue@6
 | 
   144     self.debug_info('No valid spell ID or Name')
 | 
| 
Nenue@6
 | 
   145   end
 | 
| 
Nenue@6
 | 
   146 end
 | 
| 
Nenue@6
 | 
   147 
 | 
| 
Nenue@6
 | 
   148 local GetItemCooldown, GetItemInfo = GetItemCooldown, GetItemInfo
 | 
| 
Nenue@6
 | 
   149 p.Query = function(self)
 | 
| 
Nenue@6
 | 
   150   local print = GetPrint(self.trace)
 | 
| 
Nenue@6
 | 
   151   local id  = self.inventoryID or self.itemID or self.spellID
 | 
| 
Nenue@9
 | 
   152   local name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration = nil, false, 0, 0, nil, nil, nil, 0, 0
 | 
| 
Nenue@9
 | 
   153   local override, overrideStart, overrideDuration = false, 0, 0
 | 
| 
Nenue@6
 | 
   154 
 | 
| 
Nenue@6
 | 
   155   --- checked in order of precedence
 | 
| 
Nenue@6
 | 
   156   if self.inventoryID then
 | 
| 
Nenue@6
 | 
   157     print(cText('   type'), cWord('inventory slot'), cNum(id))
 | 
| 
Nenue@6
 | 
   158     self.cooldownType = CD_SLOT
 | 
| 
Nenue@6
 | 
   159     start, duration, enabled = GetInventoryItemCooldown('player', id)
 | 
| 
Nenue@6
 | 
   160     charges, maxCharges, chargeStart, chargeDuration = nil, nil, nil, nil
 | 
| 
Nenue@6
 | 
   161     usable = name and true or false
 | 
| 
Nenue@6
 | 
   162   elseif self.itemID then
 | 
| 
Nenue@6
 | 
   163     self.cooldownType = CD_ITEM
 | 
| 
Nenue@6
 | 
   164 
 | 
| 
Nenue@6
 | 
   165     start, duration, enabled = GetItemCooldown(self.itemID)
 | 
| 
Nenue@6
 | 
   166     print(GetItemCooldown(self.itemID))
 | 
| 
Nenue@6
 | 
   167     print(GetItemInfo(id))
 | 
| 
Nenue@6
 | 
   168 
 | 
| 
Nenue@6
 | 
   169   elseif self.spellID then
 | 
| 
Nenue@6
 | 
   170     self.cooldownType = CD_SPELL
 | 
| 
Nenue@6
 | 
   171     name = GetSpellInfo(self.spellID)
 | 
| 
Nenue@6
 | 
   172     start, duration, enabled = GetSpellCooldown(self.spellID)
 | 
| 
Nenue@6
 | 
   173     charges, maxCharges, chargeStart, chargeDuration = GetSpellCharges(self.spellID)
 | 
| 
Nenue@6
 | 
   174     usable = true -- they still exist even when dead
 | 
| 
Nenue@6
 | 
   175   else
 | 
| 
Nenue@6
 | 
   176     self.unit = 'notaunit'
 | 
| 
Nenue@6
 | 
   177     T:Print('Timer \''..tostring(self.timerName)..'\' doesn\'t have a valid status ID.')
 | 
| 
Nenue@6
 | 
   178   end
 | 
| 
Nenue@6
 | 
   179 
 | 
| 
Nenue@6
 | 
   180   -- may not have been stored for some reason
 | 
| 
Nenue@6
 | 
   181   if charges and not self.maxCharges then
 | 
| 
Nenue@6
 | 
   182     self.maxCharges = maxCharges
 | 
| 
Nenue@6
 | 
   183   end
 | 
| 
Nenue@6
 | 
   184 
 | 
| 
Nenue@9
 | 
   185   if self.spellName and self.cvars.overrideAura then
 | 
| 
Nenue@9
 | 
   186     local name, _, _, _, _, d, e = UnitAura(self.unit , self.spellName, nil, 'HELPFUL')
 | 
| 
Nenue@9
 | 
   187     if name then
 | 
| 
Nenue@9
 | 
   188       override = true
 | 
| 
Nenue@9
 | 
   189       overrideDuration = d
 | 
| 
Nenue@9
 | 
   190       overrideStart = e - d
 | 
| 
Nenue@9
 | 
   191     end
 | 
| 
Nenue@9
 | 
   192   end
 | 
| 
Nenue@9
 | 
   193 
 | 
| 
Nenue@9
 | 
   194   if self.overrideDuration and start > 0 then
 | 
| 
Nenue@9
 | 
   195     override = true
 | 
| 
Nenue@9
 | 
   196     overrideDuration = self.overrideDuration
 | 
| 
Nenue@9
 | 
   197     overrideStart = start
 | 
| 
Nenue@9
 | 
   198   end
 | 
| 
Nenue@9
 | 
   199 
 | 
| 
Nenue@9
 | 
   200   print('cooldown.Query(',id,')', 'name:'..cText(name), 'usable:'..cBool(usable), 'start:'..cNum(start), 'duration:'..cNum(duration), 'enabled:'..cWord(enabled),
 | 
| 
Nenue@9
 | 
   201     'charges:'.. cNum(charges), 'charge_start:'.. cNum(chargeStart), 'charge_duration:'.. cNum(chargeDuration),
 | 
| 
Nenue@9
 | 
   202     'override:' .. cBool(override), 'override_start'..cNum(overrideStart), 'override_duration:'.. cNum(overrideDuration))
 | 
| 
Nenue@9
 | 
   203   return name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, override, overrideStart, overrideDuration
 | 
| 
Nenue@6
 | 
   204 end
 | 
| 
Nenue@6
 | 
   205 
 | 
| 
Nenue@6
 | 
   206 p.Set = function(self, ...)
 | 
| 
Nenue@6
 | 
   207   local print = GetPrint(self.trace)
 | 
| 
Nenue@6
 | 
   208 
 | 
| 
Nenue@6
 | 
   209   --name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count
 | 
| 
Nenue@6
 | 
   210   local name
 | 
| 
Nenue@9
 | 
   211   name, self.usable, self.start, self.duration, self.enabled, self.charges, self.charges_max, self.charge_start, self.charge_duration, self.override, self.override_start, self.override_duration = ...
 | 
| 
Nenue@6
 | 
   212   if name then
 | 
| 
Nenue@6
 | 
   213     self.spellName = name
 | 
| 
Nenue@6
 | 
   214   end
 | 
| 
Nenue@6
 | 
   215 
 | 
| 
Nenue@6
 | 
   216   if self.duration and self.start then
 | 
| 
Nenue@6
 | 
   217     self.expires = self.start + self.duration
 | 
| 
Nenue@6
 | 
   218   else
 | 
| 
Nenue@6
 | 
   219     self.expires = 0
 | 
| 
Nenue@6
 | 
   220   end
 | 
| 
Nenue@9
 | 
   221 
 | 
| 
Nenue@9
 | 
   222   if self.charges then
 | 
| 
Nenue@9
 | 
   223     self.charge_expires = self.charge_start + self.charge_duration
 | 
| 
Nenue@9
 | 
   224   end
 | 
| 
Nenue@9
 | 
   225   if self.override then
 | 
| 
Nenue@9
 | 
   226     self.override_expires = self.override_start + self.override_duration
 | 
| 
Nenue@9
 | 
   227   end
 | 
| 
Nenue@9
 | 
   228 
 | 
| 
Nenue@6
 | 
   229 end
 | 
| 
Nenue@6
 | 
   230 
 | 
| 
Nenue@6
 | 
   231 p.Value = function(self)
 | 
| 
Nenue@6
 | 
   232   return (self.charges and self.charges < self.maxCharges) and ((GetTime()  - self.chargeStart) / self.chargeDuration) or ((GetTime()  - self.start) / self.duration)
 | 
| 
Nenue@6
 | 
   233 end
 | 
| 
Nenue@6
 | 
   234 
 | 
| 
Nenue@6
 | 
   235 p.SetText = mod.SetText
 | 
| 
Nenue@6
 | 
   236 
 | 
| 
Nenue@6
 | 
   237 --- Assign where meaning won't be amibiguous
 | 
| 
Nenue@6
 | 
   238 local Cooldown_OnCast = function(self)
 | 
| 
Nenue@6
 | 
   239   self.triggerState = true
 | 
| 
Nenue@6
 | 
   240 end
 | 
| 
Nenue@6
 | 
   241 
 | 
| 
Nenue@6
 | 
   242 local Cooldown_OnUpdate = function(self, event)
 | 
| 
Nenue@6
 | 
   243   local print = GetPrint(self.trace)
 | 
| 
Nenue@6
 | 
   244 
 | 
| 
Nenue@6
 | 
   245   if self.triggerState then
 | 
| 
Nenue@6
 | 
   246     print(cWord('Event'), cText(self.timerName))
 | 
| 
Nenue@6
 | 
   247     if not event then
 | 
| 
Nenue@6
 | 
   248       print(' *', cWord('Poke'))
 | 
| 
Nenue@6
 | 
   249     end
 | 
| 
Nenue@6
 | 
   250     local diff = 'start='..cText(self.start)..' duration='..cText(self.duration)..' charges='..
 | 
| 
Nenue@6
 | 
   251         cText(self.charges).. ' chargeStart='..cText(self.chargeStart).. ' chargeDuration='..cText(self.chargeDuration)
 | 
| 
Nenue@9
 | 
   252     local name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, override, overrideStart, overrideDuration = self:Query()
 | 
| 
Nenue@6
 | 
   253 
 | 
| 
Nenue@6
 | 
   254     --  print(name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count)
 | 
| 
Nenue@6
 | 
   255     if duration ~= self.duration or
 | 
| 
Nenue@6
 | 
   256           start ~= self.start or
 | 
| 
Nenue@9
 | 
   257     chargeStart ~= self.charge_start or
 | 
| 
Nenue@9
 | 
   258         charges ~= self.charges or
 | 
| 
Nenue@9
 | 
   259        override ~= self.override
 | 
| 
Nenue@9
 | 
   260     then
 | 
| 
Nenue@6
 | 
   261       print('a variable has changed')
 | 
| 
Nenue@6
 | 
   262       local state
 | 
| 
Nenue@6
 | 
   263 
 | 
| 
Nenue@6
 | 
   264 
 | 
| 
Nenue@6
 | 
   265       if duration == 0 and charges == self.maxCharges then
 | 
| 
Nenue@6
 | 
   266         print(cText('  cooldown has reset, drop it from the queue'))
 | 
| 
Nenue@6
 | 
   267         state = self.cvars.persist and self.flags.passive or self.flags.hidden
 | 
| 
Nenue@6
 | 
   268         self.triggerState = nil
 | 
| 
Nenue@6
 | 
   269         print('  ', cText('dropping'), cWord(self.timerName), cText('from spell tracking'))
 | 
| 
Nenue@6
 | 
   270 
 | 
| 
Nenue@6
 | 
   271 
 | 
| 
Nenue@6
 | 
   272         self:Stats(state)
 | 
| 
Nenue@6
 | 
   273       else
 | 
| 
Nenue@6
 | 
   274         if duration ~= 0 then
 | 
| 
Nenue@6
 | 
   275           print(cText('  cooldown has a hard duration'))
 | 
| 
Nenue@6
 | 
   276           if duration > T.GCD and self.displayState ~= self.flags.active then
 | 
| 
Nenue@6
 | 
   277             print(cText('    and its > GCD, update it'))
 | 
| 
Nenue@6
 | 
   278             state = self.flags.active
 | 
| 
Nenue@6
 | 
   279           end
 | 
| 
Nenue@6
 | 
   280         end
 | 
| 
Nenue@6
 | 
   281 
 | 
| 
Nenue@6
 | 
   282         if charges then
 | 
| 
Nenue@6
 | 
   283           print(cText('  cooldown has charges'))
 | 
| 
Nenue@6
 | 
   284           if charges ~= self.charges or chargeStart ~= self.chargeStart then
 | 
| 
Nenue@6
 | 
   285             print(cText('  charges count or starting time has changed'))
 | 
| 
Nenue@6
 | 
   286             state = self.flags.active
 | 
| 
Nenue@6
 | 
   287           end
 | 
| 
Nenue@6
 | 
   288         end
 | 
| 
Nenue@6
 | 
   289 
 | 
| 
Nenue@6
 | 
   290         self:Stats(state)
 | 
| 
Nenue@6
 | 
   291       end
 | 
| 
Nenue@6
 | 
   292 
 | 
| 
Nenue@6
 | 
   293       if state then
 | 
| 
Nenue@9
 | 
   294         self:Set(name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, override, overrideStart, overrideDuration)
 | 
| 
Nenue@6
 | 
   295         self.expires = charges and (self.chargeStart + self.chargeDuration) or (self.start + self.duration)
 | 
| 
Nenue@6
 | 
   296         self:SetState(state)
 | 
| 
Nenue@6
 | 
   297         print('   ',diff)
 | 
| 
Nenue@6
 | 
   298         print('    start='..cText(self.start)..' duration='..cText(self.duration)..' charges='..
 | 
| 
Nenue@6
 | 
   299             cText(self.charges).. ' chargeStart='..cText(self.chargeStart).. ' chargeDuration='..cText(self.chargeDuration))
 | 
| 
Nenue@6
 | 
   300       end
 | 
| 
Nenue@9
 | 
   301     else
 | 
| 
Nenue@9
 | 
   302       if self.cooldownType == CD_SPELL then
 | 
| 
Nenue@9
 | 
   303         if duration == 0 and charges == self.maxCharges and self.displayState == HIDDEN then
 | 
| 
Nenue@9
 | 
   304           print(cKey(self.timerName), cText('post-framescript clean-up'))
 | 
| 
Nenue@9
 | 
   305           self.triggerState = nil
 | 
| 
Nenue@9
 | 
   306         end
 | 
| 
Nenue@6
 | 
   307       end
 | 
| 
Nenue@6
 | 
   308     end
 | 
| 
Nenue@6
 | 
   309   end
 | 
| 
Nenue@6
 | 
   310 end
 | 
| 
Nenue@6
 | 
   311 
 | 
| 
Nenue@6
 | 
   312 p.Stats = function(self, state)
 | 
| 
Nenue@6
 | 
   313   print(self.unit, self.spellName)
 | 
| 
Nenue@9
 | 
   314   if self.spellName then
 | 
| 
Nenue@9
 | 
   315     local auraName, _, _, auraCharges, _, auraDuration, auraExpires = UnitAura(self.unit, self.spellName, nil, 'HELPFUL')
 | 
| 
Nenue@9
 | 
   316     print('  # Aura', auraName and 'yes' or 'no', auraName and ('d='..cNum(auraDuration)) or '', auraName and ('e='..auraExpires))
 | 
| 
Nenue@9
 | 
   317   end
 | 
| 
Nenue@9
 | 
   318 
 | 
| 
Nenue@6
 | 
   319   local name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count = self:Query()
 | 
| 
Nenue@9
 | 
   320   print('  # GCD =', T.GCD)
 | 
| 
Nenue@9
 | 
   321   print('  # SpellCooldown', 's =', start, 'd =', duration, 's =', charges and (charges..'/'..maxCharges) or 'NA')
 | 
| 
Nenue@9
 | 
   322   print('  # Frame', 'state1 =', self.displayState, 'state2 =', self.previousState, state and ('change to '..cWord(state)) or '')
 | 
| 
Nenue@6
 | 
   323 
 | 
| 
Nenue@6
 | 
   324 
 | 
| 
Nenue@6
 | 
   325 end
 | 
| 
Nenue@6
 | 
   326 
 | 
| 
Nenue@6
 | 
   327 --- Event pointers
 | 
| 
Nenue@6
 | 
   328 p.events = {
 | 
| 
Nenue@6
 | 
   329   ['UNIT_SPELLCAST_SUCCEEDED'] = Cooldown_OnCast,
 | 
| 
Nenue@6
 | 
   330   ['UNIT_SPELLCAST_CHANNEL_START'] = Cooldown_OnCast,
 | 
| 
Nenue@6
 | 
   331   ['BAG_UPDATE_COOLDOWN'] = Cooldown_OnUpdate,
 | 
| 
Nenue@6
 | 
   332   ['SPELL_UPDATE_COOLDOWN'] = Cooldown_OnUpdate,
 | 
| 
Nenue@6
 | 
   333   ['SPELL_UPDATE_USABLE'] = Cooldown_OnUpdate,
 | 
| 
Nenue@6
 | 
   334   ['SPELL_UPDATE_CHARGES'] = Cooldown_OnUpdate,
 | 
| 
Nenue@6
 | 
   335 }
 | 
| 
Nenue@6
 | 
   336 
 | 
| 
Nenue@6
 | 
   337 local unpack, select, debugstack = unpack, select, debugstack
 | 
| 
Nenue@6
 | 
   338 p.Event = function(self, e, ...)
 | 
| 
Nenue@6
 | 
   339   local print = GetPrint(self.trace)
 | 
| 
Nenue@6
 | 
   340 
 | 
| 
Nenue@6
 | 
   341   self.event = e
 | 
| 
Nenue@6
 | 
   342   --- dry event case
 | 
| 
Nenue@6
 | 
   343   if not e then
 | 
| 
Nenue@6
 | 
   344     print('onEvent', self.timerName, e)
 | 
| 
Nenue@6
 | 
   345     self.triggerState = true
 | 
| 
Nenue@6
 | 
   346     Cooldown_OnUpdate(self, e, ...)
 | 
| 
Nenue@6
 | 
   347   else
 | 
| 
Nenue@6
 | 
   348     local unit = select(1,...)
 | 
| 
Nenue@6
 | 
   349     if self.unit and unit ~= self.unit and  e ~= 'SPELL_UPDATE_COOLDOWN' then
 | 
| 
Nenue@6
 | 
   350       return
 | 
| 
Nenue@6
 | 
   351     end
 | 
| 
Nenue@6
 | 
   352     local args = {...}
 | 
| 
Nenue@6
 | 
   353     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
 | 
   354 
 | 
| 
Nenue@6
 | 
   355   end
 | 
| 
Nenue@6
 | 
   356 end
 | 
| 
Nenue@6
 | 
   357 
 | 
| 
Nenue@6
 | 
   358 p.triggerList = {
 | 
| 
Nenue@6
 | 
   359   ['on_cooldown'] = function(self)
 | 
| 
Nenue@6
 | 
   360     local start, duration, enabled = GetSpellCooldown(self.spellID)
 | 
| 
Nenue@6
 | 
   361     local charges, _, cStart, cDuration = GetSpellCharges(self.spellID)
 | 
| 
Nenue@6
 | 
   362     return (enabled and (duration ~= 0 or start ~= 0 or charges ~= self.maxCharges)), start, duration, enabled, charges, cStart, cDuration
 | 
| 
Nenue@6
 | 
   363   end,
 | 
| 
Nenue@6
 | 
   364   ['not_on_cooldown'] = function(self)
 | 
| 
Nenue@6
 | 
   365     local start, duration, enabled = GetSpellCooldown(self.spellID)
 | 
| 
Nenue@6
 | 
   366     local charges, _, cStart, cDuration = GetSpellCharges(self.spellID)
 | 
| 
Nenue@6
 | 
   367     return (duration == 0 and start == 0 and charges == self.maxCharges), start, duration, enabled, charges, cStart, cDuration
 | 
| 
Nenue@6
 | 
   368   end,
 | 
| 
Nenue@6
 | 
   369   ['buff_active'] = function(self)
 | 
| 
Nenue@6
 | 
   370     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
 | 
   371     return (name and true or false), expires - duration, duration, true, count, 0, 0
 | 
| 
Nenue@6
 | 
   372   end
 | 
| 
Nenue@6
 | 
   373 } |