changeset 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 7790dff0fe13
children e08df0af1849
files Turok/Layout/Dialog.xml Turok/Layout/Layout.lua Turok/Modules/Combat/Castbar.lua Turok/Modules/Combat/CombatLog.lua Turok/Modules/Combat/Powerbar.Init.lua Turok/Modules/Combat/Powerbar.lua Turok/Modules/Timer/Aura.lua Turok/Modules/Timer/Container.lua Turok/Modules/Timer/Cooldown.lua Turok/Modules/Timer/Editor.lua Turok/Modules/Timer/Icon.lua Turok/Modules/Timer/Import.lua Turok/Modules/Timer/Presets.lua Turok/Modules/Timer/Progressbar.lua Turok/Modules/Timer/Status.lua Turok/Modules/Timer/Timer.Init.lua Turok/Modules/Timer/Timer.lua Turok/Modules/Timer/Timer.xml Turok/Modules/Utilities/PetBattle.lua Turok/Turok.lua Turok/Turok.xml
diffstat 21 files changed, 339 insertions(+), 216 deletions(-) [+]
line wrap: on
line diff
--- a/Turok/Layout/Dialog.xml	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Layout/Dialog.xml	Sun Feb 21 13:08:30 2016 -0500
@@ -434,7 +434,6 @@
         end
         end
 
-        print('uhmmm', type(self))
         LibStub("LibFog-1.0").SetAnimationGroup(self)
         -- Turok stuff
       </OnLoad>
--- a/Turok/Layout/Layout.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Layout/Layout.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -66,7 +66,7 @@
 scriptargs.LibFog = F
 local print = function(...)
   if _G.Devian and _G.DevianDB.workspace ~= 1 then
-    _G.print('Layout', ...)
+    --_G.print('Layout', ...)
   end
 end
 --- debug highlighters
@@ -182,15 +182,15 @@
   print('  fade on combat =', self.combatFade)
   for _, type in ipairs({'alpha', 'alpha_ooc'}) do
     self[type] = c[type]
-    _G.print('DB', self:GetName(), type, self[type])
+    --_G.print('DB', self:GetName(), type, self[type])
     for _, subtype in ipairs({'_passive', '_active'}) do
       self[type..subtype] = c[type..subtype] or self[type]
-      _G.print('DB', self:GetName(), type..subtype, self[type..subtype])
+      --_G.print('DB', self:GetName(), type..subtype, self[type..subtype])
       for _, subsubtype in ipairs({'_empty', '_half', '_full'}) do
         self[type..subtype..subsubtype] = c[type..subtype..subsubtype] or self[type..subtype]
-        _G.print('DB', self:GetName(), type..subtype..subsubtype, self[type..subtype..subsubtype])
+        --_G.print('DB', self:GetName(), type..subtype..subsubtype, self[type..subtype..subsubtype])
         self[type..subsubtype] = c[type..subsubtype] or self[type..subtype]
-        _G.print('DB', self:GetName(), type..subsubtype, self[type..subsubtype])
+        --_G.print('DB', self:GetName(), type..subsubtype, self[type..subsubtype])
       end
     end
   end
@@ -372,7 +372,7 @@
   if self.fill_inverse then
     ratio = 1 - ratio
   end
-  _G.print('Update', 'dx', self.fill_x)
+  ----_G.print('Update', 'dx', self.fill_x)
   local x =
       scale * ratio * directionCoord[self.fill_direction][1]
   return min(x, scale) + self.fill_x
@@ -391,16 +391,17 @@
     ratio = 1 - ratio
   end
 
-  _G.print('Update', 'dy', self.fill_y)
+  --_G.print('Update', 'dy', self.fill_y)
   -- (height of bar offset by the size of any overlapping element) * progress ratio, offset by the size of any overlapping embed + inset
   local y =
       scale * ratio * directionCoord[self.fill_direction][2] - self.foreground_inset
   return min(y, scale) + self.fill_y
 end
 local SetProgress = function(self, progress, scaleX, scaleY)
-  _G.print('Update', cText(self:GetName()),
+  --[[_G.print('Update', cText(self:GetName()),
     "\n     d:", progress, 'dX:', directionCoord[self.fill_direction][1], 'dY:', directionCoord[self.fill_direction][2], 'dI:', self.fill_inverse,
     "\n  peak:", self.fill_anchor, self.fill_anchorTo, TranslateX(self, progress), TranslateY(self,progress))
+    --]]
 
   self.foreground:SetPoint(self.fill_anchor, self.background, self.fill_anchorTo, TranslateX(self, progress, scaleX), TranslateY(self, progress, scaleY))
 end
--- a/Turok/Modules/Combat/Castbar.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Combat/Castbar.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -8,7 +8,7 @@
 local print, tostring, tonumber, rep, pairs, min, format, unpack, select, strpad = print, tostring, tonumber, string.rep, pairs, math.min, string.format, unpack, select, string.rep
 local GetTime, UnitCastingInfo, UnitChannelInfo, GetSpellInfo, GetSpellTabInfo = GetTime, UnitCastingInfo, UnitChannelInfo, GetSpellInfo, GetSpellTabInfo
 local floor = math.floor
-local T = Turok
+local T, _G = Turok, _G
 local db
 local PING_CEILING = 190 -- transpacific
 local PING_MIDLINE = 100
@@ -20,6 +20,16 @@
     _G.print('Tek', ...)
   end
 end
+local uprint = function(...)
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('Update', ...)
+  end
+end
+local mprint = function(...)
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('Main', ...)
+  end
+end
 
 local EVENT_COLOR = '|cFF44FF44'
 local EVENT_COLOR2 = '|cFF88FF88'
@@ -449,7 +459,7 @@
       self.percent = self.fill_inverse and 0 or 1
       self.elapsed = time - s.endTime
     end
-    --_G.print('Update','   ',self.unit, self.value, self.percent)
+    uprint('   ',self.unit, self.value, self.percent)
   else
     self.value = 1000
     self.percent = 1
@@ -464,7 +474,7 @@
 -- There is no event data such as spellID directly available, so this is essentially the biggest constraint we have on what
 -- the castingbar can depend on.
 function mod:UpdateUnit(unit)
-  local print = function(...) _G.print('Update', ...) end
+  local print = function(...) uprint(...) end
   print(cText 'GUID changed:|cFFFFFF99', unit)
   local c = mod.castbar[unit]
   if c.channeling or c.casting then
@@ -502,7 +512,7 @@
   end
 end
 mod.PLAYER_TARGET_CHANGED = function(self, ...)
-  _G.print('Main', cPink(self),...)
+  mprint(cPink(self),...)
   self:UpdateUnit('target')
 end
 mod.PLAYER_FOCUS_CHANGED = function(self)
--- a/Turok/Modules/Combat/CombatLog.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Combat/CombatLog.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -12,7 +12,7 @@
 local cText, cNum, cKey, cWord, cPink, cType, cBool = cText, cNum, cKey, cWord, cPink, cType, cBool
 local print = function(...)
   if _G.Devian and _G.DevianDB.workspace ~= 1 then
-    _G.print('CombatText', ...)
+    _G.print('CT', ...)
   end
 end
 
@@ -41,13 +41,13 @@
     anchor = 'BOTTOMLEFT', anchorTo = 'BOTTOM', parent = 'UIParent',
     x = 80, y = 400,
   },
-  defaultFont = {"Interface\\Addons\\Turok\\Media\\font\\ArchivoNarrow-Regular.ttf", 18, 'OUTLINE'},
   defaultAnimation = 'slide',
-
+  defaultFont = 'font0',
   textFonts = {
+    font0 = {"Interface\\Addons\\Turok\\Media\\font\\ArchivoNarrow-Regular.ttf", 18, 'OUTLINE'},
     font1 = {"Interface\\Addons\\Turok\\Media\\font\\ArchivoNarrow-Regular.ttf" , 30, 'OUTLINE'},
     font2 = {"Interface\\Addons\\Turok\\Media\\font\\ArchivoNarrow-Regular.ttf" , 24, 'OUTLINE'},
-    font3 = {"Interface\\Addons\\Turok\\Media\\font\\ArchivoNarrow-Bold.ttf" , 20, 'OUTLINE'},
+    font3 = {"Interface\\Addons\\Turok\\Media\\font\\ArchivoNarrow-Regular.ttf" , 20, 'OUTLINE'},
   },
 
   --- [(string) combatEvent] = {[1] = (string) format [, [2] = fontKey]}
@@ -67,10 +67,10 @@
   textModifiers ={
     critical = {'%s!', 'pop'},
     overKill = {'%s |cFF0088FFKilling Blow!|r', 'slide'},
-    multistrike = {'<%s>', 'lateralSlide', 'font3'},
+    multistrike = {'%s', 'slide', 'font3'},
     absorbed = {'%s (%d)', 'slide'},
     blocked = {'%s {%d}', 'slide'},
-    pet = {'(%s)', 'lateralSlide'},
+    pet = {'(%s)', 'slide'},
     grouped = {'%s (%d hit)', 'slide'},
   },
   --- [AnimationGroup key] = {[XML attrib] = [value], d[x/y] = (number) 0-1 }
@@ -232,6 +232,9 @@
   ct.x = 0
   ct.y = 0
   ct.point = 'BOTTOMLEFT'
+
+  ct.string:SetFont(unpack(textFonts[defaultFont]))
+  ct.fontKey = 'font0'
   return ct
 end
 
@@ -304,17 +307,16 @@
   else
     currentFrame.icon:Hide()
   end
-  if fontKey  then
+  if fontKey and fontKey ~= currentFrame.fontKey then
     local newFont = fontKey and textFonts[fontKey] or defaultFont
 
     local path, size, flags = currentFrame.string:GetFont()
     path = newFont[1] or path
     size = newFont[2] or size
     flags = newFont[3] or flags
-    print(cText('font ('..cWord(fontKey)..'):'), path, size, flags)
-    local result = currentFrame.string:SetFont(path, size, flags)
-    print(cNum('     result:'), cNum(result), currentFrame.string:GetFont())
-    --currentFrame.fontKey = fontKey
+    print(cText('swapping font to "'..cWord(fontKey)..')":'), path, size, flags)
+    currentFrame.string:SetFont(path, size, flags)
+    currentFrame.fontKey = fontKey
   end
 
   currentFrame.animationType = animationType
@@ -361,8 +363,7 @@
     return
   end
 
-
-  local fontKey = 'font1'
+  local fontKey = defaultFont
   local icon = GetSpellTexture(spellID)
   local animationType = defaultAnimation
   local text = amount
@@ -378,7 +379,6 @@
     print("** font override:", '"'..cText(tString)..'",', cPink(font), cNum(size), cWord(outline))
   end
 
-  print('** getting color data', cText(spellName))
   if type(effectSchool) == 'number' then
     text = SpellSchoolColor(effectSchool) ..text..'|r'
   end
@@ -408,8 +408,6 @@
     animationType = multistrikeAnimation
     fontKey = multistrikeFont or fontKey
   end
-
-  print(ticks)
   if ticks then
     text = groupedModifier:format(text, ticks)
     animationType = groupedAnimation
@@ -417,7 +415,7 @@
   end
 
 
-  print('** sending format to SCT:', text, icon, animationType, fontKey)
+  print(cText('** AddCombatMessage(')..cKey(frame:GetName())..cText('):'), text, cWord(tostring(icon):sub(-20,-1)), cWord(animationType), cKey(fontKey))
 
 
   mod.AddCombatMessage(frame, text .. '|r', icon, animationType, fontKey)
@@ -530,16 +528,15 @@
   local isVisible
 
   local timestamp, combatEvent = ...
-  print(cText('* CT'), cKey(combatEvent))
+  print(cText('OnDamage'), cKey(combatEvent))
   if combatEvent == 'UNIT_DIED' then
     return
   end
   local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool = select(4, ...)
-  print('  from', cPink(sourceGUID), 'spell', cNum(spellID), cText(spellName), '->', cKey(destGUID))
+  --print('  from', cPink(sourceGUID), 'spell', cNum(spellID), cText(spellName), '->', cKey(destGUID))
 
   -- SWING starts at arg 10, SPELL/RANGE start at arg 13, ENVIRONMENTAL starts at arg 8
   local offset = 15
-  print(combatEvent:sub(0,3))
   if combatEvent:sub(0,3) == 'SWI' then
     offset = 10
   elseif combatEvent:sub(0,3) == 'ENV' then
@@ -547,7 +544,6 @@
   end
   local amount, overKill, effectSchool, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand, multistrike = select(offset, ...)
 
-  print('  dmg', amount, overKill)
 
   local sc = SpellSchoolColors[effectSchool]
   if groupedSpells[spellName] then
@@ -634,7 +630,6 @@
 
   --- Same as above, but for specific table values, key is determined by the combat event
   defaultAnimation = mod.db.defaultAnimation
-  defaultFont = mod.db.defaultFont
   for k,v in pairs(mod.db.textFormat) do
     textFormat[k] = {v[1], v[2]}
     print('imported textFormat.'..k, cText(textFormat[k][1]), cNum(textFormat[k][2]))
@@ -643,6 +638,7 @@
     textFonts[k] = {v[1] or defaultFont[1], v[2] or defaultFont[2], v[3] or defaultFont[3]}
     print('imported font.'..k, cText(textFonts[k][1]), cNum(textFonts[k][2]), cWord(textFonts[k][3]))
   end
+  defaultFont = mod.db.defaultFont
 
   for k,v in pairs(mod.db.animation) do
     animation[k] = {}
@@ -663,6 +659,7 @@
 function mod:OnEnable()
   T:RegisterChatCommand('tkc', CT_Unlock)
 
+  local fontPath, fontSize, fontFlags = unpack(db.textFonts.font0)
   --- Populate CT frames
   for name, CT in pairs(mod.CombatTextFrames) do
     print('create CT', name)
--- a/Turok/Modules/Combat/Powerbar.Init.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Combat/Powerbar.Init.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -19,10 +19,10 @@
   graph_blend_alert = 'BLEND',
   foreground_color = {.1,.5,1  ,1},
   background_color = {0.2,0.2,0.2,0.2},
-  y = -188,
-  x = 0,
+  anchor = 'TOP', parent = 'UIParent', anchorTo = 'CENTER',
+  x = 0, y = -230,
   height = 20,
-  width = 300,
+  width = 330,
   padding = 0,
   spacing = 1,
   strata = 'BACKGROUND',
--- a/Turok/Modules/Combat/Powerbar.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Combat/Powerbar.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -21,7 +21,11 @@
     _G.print('PowerBar', ...)
   end
 end
-print('Peep!', ...)
+local uprint = function(...)
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('Update', ...)
+  end
+end
 local addon, tg = ...
 tg.what = tostring(tg.what)..'more'
 print(tg.what)
@@ -499,7 +503,7 @@
 -- we only want to update at specific points
 mod.Bar_Event = function(self, event, ...)
   local unit, token =  ...
-  _G.print('Update', event, unit, token)
+  uprint( event, unit, token)
   if token and unit == 'player' then
     mod.Bar_Power(self, token)
   end
@@ -508,7 +512,7 @@
 end
 
 mod.Bar_Aura = function (self, event, unit)
-  _G.print('Update','bar updating function called', event, unit)
+  uprint('bar updating function called', event, unit)
 
 
   if event == 'UNIT_AURA' or event == nil then
@@ -537,10 +541,10 @@
   -- 1=cur, 2=max, 3=type, 4=token
   p[1] = UnitPower('player', p[3])
   p[2] = UnitPowerMax('player', p[3])
-  _G.print('Update',' ', table.concat(self.primary[token],', '))
+  uprint(' ', table.concat(self.primary[token],', '))
 
   if p[4] == 1 then
-    _G.print('Update', 'progress:', p[1]/p[2])
+    uprint( 'progress:', p[1]/p[2])
     --print(unpack(p))
     self.powerText:SetText(p[1])
     self:SetProgress(p[1]/p[2])
--- a/Turok/Modules/Timer/Aura.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Aura.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -15,7 +15,6 @@
     _G.print('Aura', ...)
   end
 end
-print('Peep!', ...)
 --@end-debug@
 
 T.defaults.spirit.aura = {
@@ -55,7 +54,7 @@
 --- takes user supplied values or fills itself with the cvar values provided
 p.Init = function(self, auraName, auraFilters, auraUnit)
 
-  _G.print('Prototype', 'Aura.Init')
+  print('Aura.Init')
   self.unit = auraUnit and auraUnit or self.dvars.unit
   self.spellName = auraName and auraName or self.spellName
   self.filters = auraFilters and auraFilters or self.dvars.filters
--- a/Turok/Modules/Timer/Container.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Container.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -21,7 +21,6 @@
     _G.print('TimerContainer', ...)
   end
 end
-print('Peep!', ...)
 
 --- defaults
 local Containers = {}
--- a/Turok/Modules/Timer/Cooldown.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Cooldown.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -30,7 +30,12 @@
 local FADE_TIME = 0.2
 --@debug@
 local cType, cText, cNum, cWord, cKey, cPink, cBool = cType, cText, cNum, cWord, cKey, cPink, cBool
-local print = function(...) print('Cooldown', ...) end
+
+local print = function(...)
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('Cooldown', ...)
+  end
+end
 local function GetPrint (trace)
   return trace and print or function() end
 end
@@ -50,7 +55,7 @@
   desaturated = false,
   fill_inverse = true,
   size = 24,
-  counterText = "%p",
+  counterText = "%i",
   subCounterText = "%.p",
   chargesText = "%s",
   justifyH = 'CENTER',
@@ -63,20 +68,19 @@
     icon = {
       desaturated = false,
       color = {1, 1, 1, 1},
-      blend = 'BLEND'
     }
   },
   active = {
     icon = {
-      desaturated = false,
+      desaturated = true,
       color = {1, 1, 1, .6},
-      blend = 'ADD'
     }
   },
 
   --- control displays of aura information in cooldown displays
-  showAura = false,
-  cooldownAura = {
+  overrideAura = false,
+  overrideDuration = false,
+  override = {
     icon = {
       desaturated = true,
       color = {0,1,0,1},
@@ -100,6 +104,19 @@
   self.minValue = minValue and minValue or tonumber(self.minValue)
   self.maxValue = maxValue and maxValue or tonumber(self.maxValue)
 
+  self.start = 0
+  self.duration = 0
+  self.expires = 0
+  self.charges = nil
+  self.charges_max = 0
+  self.charge_start = 0
+  self.charge_duration = 0
+  self.charge_expires = 0
+  self.override = false
+  self.override_start = 0
+  self.override_duration = 0
+  self.override_expires = 0
+
   --- current and last state values need to be flipped for inverted conditional
   --- last state is defined in case it needs to be overridden to ensure proper frame update
   print(cWord('Load:'),cNum(self.spellID or self.inventoryID or self.itemID), cText(self.spellName or GetItemSpell('player', self.inventoryID or self.itemID)) )
@@ -132,7 +149,8 @@
 p.Query = function(self)
   local print = GetPrint(self.trace)
   local id  = self.inventoryID or self.itemID or self.spellID
-  local name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count
+  local name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration = nil, false, 0, 0, nil, nil, nil, 0, 0
+  local override, overrideStart, overrideDuration = false, 0, 0
 
   --- checked in order of precedence
   if self.inventoryID then
@@ -140,7 +158,6 @@
     self.cooldownType = CD_SLOT
     start, duration, enabled = GetInventoryItemCooldown('player', id)
     charges, maxCharges, chargeStart, chargeDuration = nil, nil, nil, nil
-    count = GetInventoryItemCount('player', id)
     usable = name and true or false
   elseif self.itemID then
     self.cooldownType = CD_ITEM
@@ -154,7 +171,6 @@
     name = GetSpellInfo(self.spellID)
     start, duration, enabled = GetSpellCooldown(self.spellID)
     charges, maxCharges, chargeStart, chargeDuration = GetSpellCharges(self.spellID)
-    count = GetSpellCount(self.spellID)
     usable = true -- they still exist even when dead
   else
     self.unit = 'notaunit'
@@ -166,8 +182,25 @@
     self.maxCharges = maxCharges
   end
 
-  print('cooldown.Query(',id,')', name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration)
-  return name, usable, start, duration, enabled, charges, chargeStart, chargeDuration, count
+  if self.spellName and self.cvars.overrideAura then
+    local name, _, _, _, _, d, e = UnitAura(self.unit , self.spellName, nil, 'HELPFUL')
+    if name then
+      override = true
+      overrideDuration = d
+      overrideStart = e - d
+    end
+  end
+
+  if self.overrideDuration and start > 0 then
+    override = true
+    overrideDuration = self.overrideDuration
+    overrideStart = start
+  end
+
+  print('cooldown.Query(',id,')', 'name:'..cText(name), 'usable:'..cBool(usable), 'start:'..cNum(start), 'duration:'..cNum(duration), 'enabled:'..cWord(enabled),
+    'charges:'.. cNum(charges), 'charge_start:'.. cNum(chargeStart), 'charge_duration:'.. cNum(chargeDuration),
+    'override:' .. cBool(override), 'override_start'..cNum(overrideStart), 'override_duration:'.. cNum(overrideDuration))
+  return name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, override, overrideStart, overrideDuration
 end
 
 p.Set = function(self, ...)
@@ -175,7 +208,7 @@
 
   --name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count
   local name
-  name, self.usable, self.start, self.duration, self.enabled, self.charges, self.chargeStart, self.chargeDuration, self.count = ...
+  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 = ...
   if name then
     self.spellName = name
   end
@@ -185,6 +218,14 @@
   else
     self.expires = 0
   end
+
+  if self.charges then
+    self.charge_expires = self.charge_start + self.charge_duration
+  end
+  if self.override then
+    self.override_expires = self.override_start + self.override_duration
+  end
+
 end
 
 p.Value = function(self)
@@ -208,27 +249,15 @@
     end
     local diff = 'start='..cText(self.start)..' duration='..cText(self.duration)..' charges='..
         cText(self.charges).. ' chargeStart='..cText(self.chargeStart).. ' chargeDuration='..cText(self.chargeDuration)
-    local name, usable, start, duration, enabled, charges, chargeStart, chargeDuration, count = self:Query()
-
-    -- If we want and can, pull aura data and use that in place of cooldown information
-    local expires, hasAura, _
-    if self.cvars.showAura then
-      print(cText('UnitAura'), self.unit, self.spellName, nil, 'HELPFUL')
-      local name, _, _, count, _, auraDuration, auraExpires = UnitAura(self.unit , self.spellName, nil, 'HELPFUL')
-      if name and (auraDuration ~= self.auraDuration or auraExpires ~= self.auraExpires) then
-
-        print(cText('aura check ='), cBool(name), 's='..cNum(count), 'd='..cNum(auraDuration), 'e='..cNum(auraExpires))
-        start = auraExpires - auraDuration
-        duration = auraDuration
-        expires = auraExpires
-      end
-    end
+    local name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, override, overrideStart, overrideDuration = self:Query()
 
     --  print(name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count)
     if duration ~= self.duration or
           start ~= self.start or
-          chargeStart ~= self.chargeStart
-          or charges ~= self.charges then
+    chargeStart ~= self.charge_start or
+        charges ~= self.charges or
+       override ~= self.override
+    then
       print('a variable has changed')
       local state
 
@@ -261,37 +290,36 @@
         self:Stats(state)
       end
 
-
-      -- form ID, id type, displayState, prevState
-      --T:Dispatch('TK_COOLDOWN_UPDATE', self.spellID, self.cooldownType, state, self.displayState)
       if state then
-        self:Set(name, usable, start, duration, enabled, charges, chargeStart, chargeDuration, count)
+        self:Set(name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, override, overrideStart, overrideDuration)
         self.expires = charges and (self.chargeStart + self.chargeDuration) or (self.start + self.duration)
         self:SetState(state)
-        --print('  ', cText('SetState'), cNum(self.displayState), 'from', cNum(self.prevState), cWord(self.timerName))
         print('   ',diff)
         print('    start='..cText(self.start)..' duration='..cText(self.duration)..' charges='..
             cText(self.charges).. ' chargeStart='..cText(self.chargeStart).. ' chargeDuration='..cText(self.chargeDuration))
       end
-    elseif self.cooldownType == CD_SPELL then
-      if duration == 0 and charges == self.maxCharges and self.displayState == HIDDEN then
-        print(cKey(self.timerName), cText('post-framescript clean-up'))
-        self.triggerState = nil
+    else
+      if self.cooldownType == CD_SPELL then
+        if duration == 0 and charges == self.maxCharges and self.displayState == HIDDEN then
+          print(cKey(self.timerName), cText('post-framescript clean-up'))
+          self.triggerState = nil
+        end
       end
     end
   end
-  --self:DumpMessages()
-
 end
 
 p.Stats = function(self, state)
   print(self.unit, self.spellName)
-  local auraName, _, _, auraCharges, _, auraDuration, auraExpires = UnitAura(self.unit, self.spellName, nil, 'HELPFUL')
+  if self.spellName then
+    local auraName, _, _, auraCharges, _, auraDuration, auraExpires = UnitAura(self.unit, self.spellName, nil, 'HELPFUL')
+    print('  # Aura', auraName and 'yes' or 'no', auraName and ('d='..cNum(auraDuration)) or '', auraName and ('e='..auraExpires))
+  end
+
   local name, usable, start, duration, enabled, charges, maxCharges, chargeStart, chargeDuration, count = self:Query()
-  print('# GCD =', T.GCD)
-  print('# SpellCooldown', 's =', start, 'd =', duration, 's =', charges and (charges..'/'..maxCharges) or 'NA')
-  print('# Aura', auraName and 'yes' or 'no', auraName and ('d='..cNum(auraDuration)) or '', auraName and ('e='..auraExpires))
-  print('# Frame', 'state1 =', self.displayState, 'state2 =', self.previousState, state and ('change to '..cWord(state)) or '')
+  print('  # GCD =', T.GCD)
+  print('  # SpellCooldown', 's =', start, 'd =', duration, 's =', charges and (charges..'/'..maxCharges) or 'NA')
+  print('  # Frame', 'state1 =', self.displayState, 'state2 =', self.previousState, state and ('change to '..cWord(state)) or '')
 
 
 end
--- a/Turok/Modules/Timer/Editor.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Editor.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -12,7 +12,6 @@
     print('Dialog', ...)
   end
 end
-print('Peep!', ...)
 
 
 local TimerConfig = {
--- a/Turok/Modules/Timer/Icon.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Icon.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -14,7 +14,6 @@
     _G.print('Icon', ...)
   end
 end
-print('Peep!', ...)
 --@end-debug@
 local GetPrint = function(trace)
   if trace then
@@ -80,6 +79,11 @@
   self.icon:SetTexture(self.spellIcon or self.itemIcon)
 end
 
+local function Icon_UpdateCooldown(self)
+  self.spiral:Show()
+  self.spiral:SetCooldown(self.charges and self.chargeStart or (self.override and self.override_start or self.start), self.charges and self.chargeDuration or (self.override and self.override_duration or self.duration))
+  print('spiral:Play() new', self.charges and self.chargeStart or self.start, self.charges and self.chargeDuration or self.duration)
+end
 
 --- Advances the display state, applying any visual transitions as necessary;
 -- @param self frame object
@@ -130,9 +134,7 @@
 
         -- and is ACTIVE
         self:Show()
-        self.spiral:Show()
-        self.spiral:SetCooldown(self.charges and self.chargeStart or self.start, self.charges and self.chargeDuration or self.duration)
-        print('spiral:Play() new', self.charges and self.chargeStart or self.start, self.charges and self.chargeDuration or self.duration)
+        Icon_UpdateCooldown(self)
       end
 
       if previous and previous ~= HIDDEN then
@@ -140,7 +142,6 @@
       -- from visible
         if self.event then
           self.refresh = true
-          self.Retro:Play()
         end
       else
         print(cText('  from non-vis'))
@@ -155,10 +156,7 @@
     --- No-change transitions
     if newState == ACTIVE then
       -- ACTIVE to ACTIVE
-      print(cText(''))
-      self.spiral:Show()
-      self.spiral:SetCooldown(self.charges and self.chargeStart or self.start, self.charges and self.chargeDuration or self.duration)
-      print('spiral:Play() new', self.charges and self.chargeStart or self.start, self.charges and self.chargeDuration or self.duration)
+      Icon_UpdateCooldown(self)
     else
       print(cPink('stopping spiral'))
       self.spiral:Hide()
@@ -167,7 +165,6 @@
     -- non-HIDDEN to non-HIDDEN and not a dry fire
     if self.event and newState ~= HIDDEN then
       self.refresh = true
-      self.Retro:Play()
     end
   end
 
@@ -175,8 +172,14 @@
     print(cText('  CVars:'))
     local c
     if newState == ACTIVE then
-      print('apply active profile')
-      c = self.cvars.active
+      if self.override then
+        c = self.cvars.override
+        print('apply override profile')
+      else
+        print('apply active profile')
+        c = self.cvars.active
+      end
+
       self.fillState = 1
     else
       print('apply passive profile')
@@ -220,7 +223,7 @@
     -- prevState is set externally
     local time = GetTime()
     if self.expires <= time and self.charges == self.maxCharges then
-      _G.print(self.cvars.type, 'timer expired, set to', (self.cvars.persist and self.flags.passive or self.flags.hidden))
+      print(self.cvars.type, 'timer expired, set to', (self.cvars.persist and self.flags.passive or self.flags.hidden))
       self.percent = 1
       self.duration = 0
       self.expires = 0
@@ -231,8 +234,23 @@
       self.remaining = 0
       self:SetState(self.cvars.persist and self.flags.passive or self.flags.hidden)
     else
-      self.percent = (self.charges and self.charges < self.maxCharges) and ((time  - self.chargeStart) / self.chargeDuration) or ((time  - self.start) / self.duration)
-      self.valueFull = self.expires - time
+      -- unit_aura is too ambiguous
+      if self.override and self.override_expires < time then
+        self.override = nil
+        self:SetState(self.flags.active)
+      end
+
+      if self.override then
+        self.valueFull = self.override_start + self.override_duration - time
+        self.percent = (time - self.override_start) / self.override_duration
+      elseif self.charges and self.charges < self.charges_max then
+        self.valueFull = self.charge_expires - time
+        self.percent = (time - self.charge_start) / self.charge_duration
+      else
+        self.valueFull  = self.expires - time
+        self.percent = (time - self.start) / self.duration
+      end
+
       self.elapsed = time - self.start
       self.remaining = self.duration - time
 
--- a/Turok/Modules/Timer/Import.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Import.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -21,7 +21,6 @@
     print('Dialog', ...)
   end
 end
-print('Peep!', ...)
 local strpad = function(str, num)
   return tostring(str) .. string.rep(' ', num - #tostring(str))
 end
--- a/Turok/Modules/Timer/Presets.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Presets.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -1,8 +1,12 @@
 local ADDON, Tk = ...
 local T = Tk.Addon
 local mod, tinsert, ipairs, pairs = T.modules.TimerControl, tinsert, ipairs, pairs
-local print = function(...) print('TimerPresets', ...) end
-
+local print = function(...)
+  if not DEBUG then return end
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('TimerPresets', ...)
+  end
+end
 
 
 --- Timer config presets
@@ -42,7 +46,7 @@
     },
     ["DoTs"] = {
       anchor ='BOTTOM', anchorTo='TOP',
-      parent='TekplayerCastBar',
+      parent='TkPowerBar',
       display = 'icon',
       size = 48,
       height = 48, width = 48,
@@ -201,7 +205,7 @@
 
       absolute = true, x = 0, y = -10, width = 300, height = 10,
       anchor = 'BOTTOMLEFT', anchorTo = 'BOTTOMLEFT',
-      parent = 'TekplayerCastBar', padding = 0, spacing = 0,
+      parent = 'TkPowerBar', padding = 0, spacing = 0,
 
       foreground_inset = 0, foreground_color = {1,1,1,1}, foreground_blend = 'ADD',
       background_color = {0,0,0,0},
@@ -224,7 +228,7 @@
     { virtual = true, name = "Hunter",
       playerClass = 'HUNTER', unit = 'player', container = 'default', display= 'icon', },
     { virtual = true, name = "HunterSticky", inherits = "Hunter",
-      showAura = true, persist = true, },
+      overrideAura = true, persist = true, },
     { virtual = true, name = "HunterBar",
       playerClass = 'HUNTER', unit = 'player', },
     ---- Talents
@@ -237,7 +241,15 @@
       inherits= "HunterSticky",
       name = "Animal Power", type = 'cooldown',
       talentRow = 5,
-      trace = true},
+      trace = true,
+      args = {
+        talentRow = {
+          default = {overrideDuration = nil},
+          [1] = {overrideDuration = 15},
+          [3] = {overrideDuration = 40},
+        },
+      },
+    },
     --- Spells
     {
       inherits = 'Hunter', name = "Camouflage",
@@ -279,7 +291,7 @@
       hideIcon = true,
       leftText = "", rightText = "%p",
       width = 300, height = 8,padding = 0, spacing = 0,
-      absolute = true, x = 0, y = 0, anchor = 'TOPLEFT', anchorTo = 'TOPLEFT', parent = 'TekplayerCastBar', strata='MEDIUM',
+      absolute = true, x = 0, y = 0, anchor = 'TOPLEFT', anchorTo = 'TOPLEFT', parent = 'TkPowerBar', strata='MEDIUM',
       foreground_color = {1,.125,0.43,1}, foreground_blend = 'ADD', foreground_inset = 0,
       background_color = {.5,.5,.5,0}, background_blend = 'BLEND',
     },
@@ -291,7 +303,7 @@
       hideIcon = true,
       leftText = "", rightText=  "",
       width= 330, height = 12, padding = 0,
-      absolute = true, x = 0, y = 0, anchor = 'BOTTOMLEFT', anchorTo = 'BOTTOMLEFT', parent = 'TekplayerCastBar', level = 1,
+      absolute = true, x = 0, y = 0, anchor = 'BOTTOMLEFT', anchorTo = 'BOTTOMLEFT', parent = 'TkPowerBar', level = 1,
       foreground_color = {1,0,0,1}, foreground_blend = 'BLEND',
       sound_active = '', sound_hidden = '', sound_passive = '',
     },
@@ -303,7 +315,7 @@
       hideIcon = true,
       leftText = "", rightText=  "",
       height = 12, width= 160, padding = 0,
-      absolute = true, x = 0, y = 0, anchor = 'BOTTOMLEFT', anchorTo = 'BOTTOMLEFT', parent = 'TekplayerCastBar', level = 2,
+      absolute = true, x = 0, y = 0, anchor = 'BOTTOMLEFT', anchorTo = 'BOTTOMLEFT', parent = 'TkPowerBar', level = 2,
       foreground_color = {1,1,0,1}, foreground_blend = 'BLEND',
       sound_active = '', sound_hidden = '', sound_passive = '',
     },
@@ -365,7 +377,7 @@
       unit = 'target', filters = 'PLAYER|HARMFUL',
       spellID = 184915, playerClass = 'PRIEST', specPage = 3,
 
-      parent = 'TekplayerCastBar',
+      parent = 'TkPowerBar',
       container = 'DoTs',
       order = 1,
       sound_active = '',
--- a/Turok/Modules/Timer/Progressbar.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Progressbar.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -15,7 +15,11 @@
     _G.print('Progressbar', ...)
   end
 end
-print('Peep!', ...)
+local uprint = function(...)
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('Update', ...)
+  end
+end
 --@end-debug@
 local GetPrint = function(trace)
   if trace then
@@ -94,8 +98,8 @@
 
   T.SetStatusTextures(self, self.cvars)
 
-  _G.print('Update', self.background:GetWidth(), self.background:GetHeight())
-  _G.print('Update', self.foreground:GetWidth(), self.foreground:GetHeight())
+  uprint(self.background:GetWidth(), self.background:GetHeight())
+  uprint(self.foreground:GetWidth(), self.foreground:GetHeight())
 end
 
 
--- a/Turok/Modules/Timer/Status.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Status.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -3,13 +3,9 @@
 local P = mod.prototype
 local GetInventoryItemID, GetItemInfo, GetInventoryItemTexture = GetInventoryItemID, GetItemInfo, GetInventoryItemTexture
 local GetSpellDescription, GetSpellInfo, GetSpellCharges = GetSpellDescription, GetSpellInfo, GetSpellCharges
-local GetTalentRowSelectionInfo = GetTalentRowSelectionInfo
 local tinsert, type, tonumber, pairs, ipairs, unpack = tinsert, type, tonumber, pairs, ipairs, unpack
 local UnitGUID = UnitGUID
 local GetTalentInfo, GetTalentInfoByID, GetItemSpell, PaperDoll_IsEquippedSlot = GetTalentInfo, GetTalentInfoByID, GetItemSpell, PaperDoll_IsEquippedSlot
-local print = function(...) print('Timer', ...) end
-print('Peep!', ...)
-
 --@debug@
 local DEBUG = true
 --@end-debug@
@@ -20,13 +16,19 @@
     _G.print('Timer', ...)
   end
 end
+local tfprint = function(...)
+  if not DEBUG then return end
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('TimerFocus', ...)
+  end
+end
 ------------------------------------------
 --- Parameter Prototypes
 
 local Timer_GetPrintHandler = function(self)
   return self.trace and function(...)
     print(...)
-    _G.print('TimerFocus', ...)
+    tfprint( ...)
   end or print
 end
 
@@ -61,6 +63,20 @@
   end
 end
 
+--- update conditional cvars (i.e. talentRow(5) pulls up column 3, so cvars.x = args[talentRow][3].x)
+local Timer_SetAttributeValues = function(self, key, value)
+  print('   ', cKey(key), 'sub-value =', cNum(value))
+  local sda = self.dvars.args
+  if sda and sda[key] then
+    print(cText('      conditional:'))
+    local dvals = (value and sda[key][value]) and sda[key][value] or sda[key].default
+    for k, v in pairs(dvals) do
+      print(cText('     '), 'cvars.'..cKey(k), '=', cWord(v))
+      self.cvars[k] = v
+    end
+  end
+end
+
 --- spellID
 do
   local spellID = P.status.spellID
@@ -102,6 +118,7 @@
       Timer_UpdateIndex(self, 'spellID', nil)
       Timer_UpdateIndex(self, 'spellName', spellName)
     end
+    Timer_SetAttributeValues(self, 'spellName', spellID)
   end
 end
 
@@ -126,7 +143,7 @@
 
     print('   ', cKey('talentID ('..cNum(self.talentID)..', '..cNum(T.specGroup)..'):'), self.spellName, self.talentSelected )
     Timer_UpdateIndex(self, 'talentID', talentID)
-
+    Timer_SetAttributeValues(self, 'talentID', self.talentSelected and 1 or 'default')
   end
 end
 
@@ -136,15 +153,21 @@
   talentRow.Init = function(self, row)
     local print = Timer_GetPrintHandler(self)
     self.talentRow = row
-    local noSelect, talentID = GetTalentRowSelectionInfo(row)
-    if noSelect then
+    local match
+    for i = 1, 3 do
+      local talentID, _, _, selected = GetTalentInfo(row, i, T.specGroup)
+      if selected then
+        P.status.talentID.Init(self, talentID)
+        match = i
+      end
+    end
+
+    if not match then
       self.disable = true
       self.debug_info("No talent selected in target row.")
-    else
-      P.status.talentID.Init(self, talentID)
     end
-    print('   ', cKey('talentRow ('.. cNum(row).. ') ='), talentID or 'none')
     Timer_UpdateIndex(self, 'talentRow', row)
+    Timer_SetAttributeValues(self, 'talentRow', match)
   end
 end
 
@@ -224,20 +247,19 @@
        self.debug_info ('bad itemID value')
     end
 
-    self.spellName = GetItemSpell(self.itemID)
+    local spellName = GetItemSpell(self.itemID)
 
-    if not self.spellName then
+    if not spellName then
       self.disable =  true
-       self.debug_info('no spell detected')
-    else
-      if not (self.frames.spellName and self.frames.spellName[self.spellName]) then
-        if not self.frames.spellName then
-          self.frames.spellName = {}
-        end
-
-        Timer_UpdateIndex(self, 'spellName', self.spellName)
+      self.debug_info('no spell detected')
+      if self.spellName then
+        self.spellName = nil
       end
     end
+
+    Timer_UpdateIndex(self, 'spellName', spellName)
+    Timer_SetAttributeValues(self, 'itemID', spellName)
+
     print('   ', cKey('itemID'), cNum(self.itemID), self.isEquipped)--@end-debug@
   end
 end
@@ -249,15 +271,16 @@
     local print = Timer_GetPrintHandler(self)
 
     self.inventoryID = slot
-    self.itemID = GetInventoryItemID(self.dvars.unit, slot)
-    local name = GetItemInfo(self.itemID)
+    local itemID = GetInventoryItemID(self.dvars.unit, slot)
+    local name = GetItemInfo(itemID)
     if not PaperDoll_IsEquippedSlot(slot) then
       self.disable = true
       self.debug_info('slot un-equipped')
       return
     end
 
-    P.status.itemID.Init(self, self.itemID)
+    Timer_SetAttributeValues(self, 'inventoryID', itemID)
+    P.status.itemID.Init(self, itemID)
     self.spellIcon = GetInventoryItemTexture(self.dvars.unit, slot)
     print('   ', cKey('inventoryID'), '=', '{'..cNum(self.inventoryID).. ' -> '.. cNum(self.itemID or 'no-equip').. '}')
   end
--- a/Turok/Modules/Timer/Timer.Init.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Timer.Init.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -9,7 +9,12 @@
 local mod = T:NewModule("TimerControl", "AceTimer-3.0")
 local pairs, ipairs, rawset, getmetatable, setmetatable, type, tostring, tinsert = pairs, ipairs, rawset, getmetatable, setmetatable, type, tostring, tinsert
 local cWord, cNum, cText, cKey = cWord, cNum, cText, cKey
-local print = function(...) print('Timer', ...) end
+local print = function(...)
+  if not DEBUG then return end
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('Timer', ...)
+  end
+end
 local index_mt = {
     __newindex = function(t,k,v)
       rawset(t,k,v)
--- a/Turok/Modules/Timer/Timer.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Timer.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -5,12 +5,12 @@
 --- Defines common elements for the various timer HUDs
 local ADDON, _A = ...
 local _G, CreateFrame, tconcat, GetInventoryItemsForSlot, GetInventoryItemID = _G, CreateFrame, table.concat, GetInventoryItemsForSlot, GetInventoryItemID
-local T, F, tostring, type, max, tinsert, unpack, UIParent, loadstring = _A.Addon, _A.LibFog, tostring, type, max, table.insert, unpack, _G.UIParent, loadstring
+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
 local mod = T.modules.TimerControl
 local P = mod.prototype
 local db
 
-local pairs, ipairs, gsub, sub, setmetatable = pairs, ipairs, string.gsub, string.sub, setmetatable
+local pairs, ipairs, gsub, sub, setmetatable, wipe = pairs, ipairs, string.gsub, string.sub, setmetatable, wipe
 local INVTYPE_FINGER, INVSLOT_FINGER1, INVSLOT_FINGER2, INVTYPE_TRINKET, INVSLOT_TRINKET1, INVSLOT_TRINKET2 =
 INVTYPE_FINGER, INVSLOT_FINGER1, INVSLOT_FINGER2, INVTYPE_TRINKET, INVSLOT_TRINKET1, INVSLOT_TRINKET2
 --@debug@
@@ -23,12 +23,24 @@
     _G.print('Timer', ...)
   end
 end
+local teprint = function(...)
+  if not DEBUG then return end
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('TimerEvent',...)
+  end
+end
+local tfprint = function(...)
+  if not DEBUG then return end
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('TimerFocus',...)
+  end
+end
 
 local Timer_GetPrintHandler = function(self)
   if self.trace then
   return function(...)
     print(...)
-    _G.print('TimerFocus', ...)
+    tfprint(...)
   end else
     return print
   end
@@ -67,17 +79,17 @@
   __mode = "v",
   __newindex = function(t,k,v)
     rawset(t,k,v)
-    _G.print('DB', 'TCMeta: adding leaf', k, '=', v)
+    --_G.print('DB', 'TCMeta: adding leaf', k, '=', v)
   end}
 local mt_double = {
   __index = function(t,k)
     t[k] = setmetatable({}, mt_single)
-    _G.print('DB', 'TCMeta: add layer', k, '=', t[k])
+    --_G.print('DB', 'TCMeta: add layer', k, '=', t[k])
     return t[k]
   end,
   __newindex = function(t,k,v)
     rawset(t,k,v)
-    _G.print('DB', 'TCMeta: adding to top layer', k, '=', v)
+    --_G.print('DB', 'TCMeta: adding to top layer', k, '=', v)
   end
 }
 local mt_error = {
@@ -328,24 +340,23 @@
 end
 
 function mod.InitTimers()
-  local print = function(...) _G.print('TimerEvent', ...) end
-  print('INIT TIMERS ====================')
+  teprint('INIT TIMERS ====================')
   for id, spirit in pairs(mod.timers) do
     if spirit.disable then
-      print(id, 'disabled:', tconcat(spirit.debug_info or {}, ', '))
+      teprint(id, 'disabled:', tconcat(spirit.debug_info or {}, ', '))
     else
 
-    print(cText('init'), cNum(id), cWord(spirit.name))
+    teprint(cText('init'), cNum(id), cWord(spirit.name))
     --- Throw a dry event to initialize values
-    print(cText(' *'), cWord('prototype.'..cKey(spirit.dvars.type)..'.'..cWord('Load')))
+    teprint(cText(' *'), cWord('prototype.'..cKey(spirit.dvars.type)..'.'..cWord('Load')))
     P.trigger[spirit.dvars.type].Event(spirit)
 
     --- Set loose
-    print(cText(' *'), cWord('prototype')..'.'..cKey('events')..'.'..cWord('Load'))
+    teprint(cText(' *'), cWord('prototype')..'.'..cKey('events')..'.'..cWord('Load'))
     mod.UpdateEvents(spirit, P.trigger[spirit.dvars.type].events)
     end
   end
-  print('INIT DONE =========================')
+  teprint('INIT DONE =========================')
 end
 
 function mod:DisableTimer(name, timer)
@@ -387,7 +398,7 @@
 local match_sub = {
   {'%%c', "' .. tostring(t.caster).. '"},
   {'%%h', "' .. tostring((t.valueFull >= 60) and (math.floor(t.valueFull/60)) or t.value) .. '"},
-  {'%%i', "' .. tostring((t.valueFull >= 60) and (t.value % 60) or ((t.valueFull < 6) and math.floor((t.ValueFull * 100) % 100) or '')) .. '"},
+  {'%%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)) .. '"},
   {'%%n', "' .. tostring(t.spellName) .. '"},
   {'%%p', "' .. tostring(t.value) .. '"},
   {'%%d', "' .. tostring(t.chargeDuration or t.duration) .. '"},
@@ -516,12 +527,23 @@
 end
 
 --- Same thing but for talent/spec-driven
+local update_queue = {}
+function mod.ResetTimers(heading)
+  print(cText('*** Flushing update queue for'), cWord(heading))
+  for id, frame in pairs(update_queue) do
+    print('  ', cNum(id), cKey(frame.timerName))
+    frame.disable = nil
+    wipe(frame.debug_info)
+    local res, msg = mod:EnableTimer(id, frame.dvars)
+  end
+  wipe(update_queue)
+end
+
 function mod:PLAYER_TALENT_UPDATE(e, unit)
   print('')
   print('')
   print(cText(e), T.specPage, T.specName)
 
-  local update_queue = {}
   for _, k in ipairs({'talentID', 'talentRow', 'specPage'}) do
     for value, frameSet in pairs(mod.frames.talentID) do
       for id, frame in ipairs(frameSet) do
@@ -530,41 +552,31 @@
       end
     end
   end
-
-  for id, frame in pairs(update_queue) do
-    print('Refreshing spec-related frames', id, frame.timerName)
-    frame.disable = nil
-    table.wipe(frame.debug_info)
-    local res, msg = mod:EnableTimer(id, frame.dvars)
-  end
-
+  mod.resetTimers('Talent')
 end
 
 function mod:PLAYER_EQUIPMENT_CHANGED(e, slot, hasItem)
   print(e, slot, hasItem)
-  local itemCheckList
-  if mod.frames.inventoryID and  mod.frames.inventoryID[slot] then
-    print('  Inventory Frames:')
-      itemCheckList = GetInventoryItemsForSlot(slot, {}, false)
-       for id, slotFrame in pairs(mod.frames.inventoryID[slot]) do
-        print('   * Updating', cNum(id), cWord(slotFrame.timerName))
-        local res, msg = mod:EnableTimer(slotFrame.timerID, slotFrame.dvars)
-        print('     ', cBool(res), cText(msg))
+  if mod.frames.inventoryID and mod.frames.inventoryID[slot] then
+    print('  Inventory slot:', cNum(slot))
+    for i, slotFrame in ipairs(mod.frames.inventoryID[slot]) do
+      print('   ', cNum(i), cText(slotFrame.timerName))
+      update_queue[slotFrame.timerID] = slotFrame
+      if mod.frames.itemID then
+        local itemsForSlot = GetInventoryItemsForSlot(slot, {}, false)
+        for _, itemID in pairs(itemsForSlot) do
+          if mod.frames.itemID[itemID] then
+            print('    Frames for equippable item:', cNum(itemID))
+            for j, itemFrame in ipairs(mod.frames.itemID[itemID]) do
+              print('     ', cNum(j), cText(itemFrame.timerName))
+              update_queue[itemFrame.timerID] = itemFrame
+            end
+          end
+        end
       end
-  end
-  if itemCheckList then
-    print(unpack(itemCheckList))
-  end
-  local itemID = GetInventoryItemID('player', slot)
-  if itemID and mod.frames.itemID[itemID] then
-    print('  Item ID Frames:')
-    for id, itemFrame in pairs(mod.frames.itemID[itemID]) do
-      print('   * Updating', cNum(id), cWord(itemFrame.timerName))
-
-      local res, msg = mod:EnableTimer(itemFrame.timerID, itemFrame.dvars)
-      print('     ', cBool(res), cText(msg))
     end
   end
+  mod.ResetTimers('Equipment')
 end
 function mod:PET_BATTLE_OPENING_START ()
   for i, v in pairs(mod.timers) do
--- a/Turok/Modules/Timer/Timer.xml	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Timer/Timer.xml	Sun Feb 21 13:08:30 2016 -0500
@@ -50,7 +50,7 @@
             g.add = true
             g:Report()
             --@debug@
-            print('Layout', g.cvars.type, 'Intro |cFFFFFF00START', g:GetName())--@end-debug@
+            --print('Layout', g.cvars.type, 'Intro |cFFFFFF00START', g:GetName())--@end-debug@
             g:Show()
             if g.cvars.sound_active then
               PlaySoundFile(g.cvars.sound_active)
@@ -62,7 +62,7 @@
           <OnStop>
             local g = self:GetParent()
             --@debug@
-            print('Layout', g.cvars.type, 'Intro |cFFFF4400STOP', g:GetName())--@end-debug@
+            --print('Layout', g.cvars.type, 'Intro |cFFFF4400STOP', g:GetName())--@end-debug@
             if g.enableIcon then
               g.iconIntro:Stop()
             end
@@ -70,7 +70,7 @@
           <OnFinished>
             local g = self:GetParent()
             --@debug@
-            print('Layout', g.cvars.type, 'Intro |cFF00FF00FINISH', g:GetName())--@end-debug@
+            --print('Layout', g.cvars.type, 'Intro |cFF00FF00FINISH', g:GetName())--@end-debug@
             if g.enableIcon then
               g.iconIntro:Stop()
             end
@@ -91,7 +91,7 @@
             g.trash = true
             g:Report()
             --@debug@
-            print('Layout', g.cvars.type, '|cFF0088FFOutro |cFFFFFF00START', g:GetName())--@end-debug@
+            --print('Layout', g.cvars.type, '|cFF0088FFOutro |cFFFFFF00START', g:GetName())--@end-debug@
             if g.spiral then
               g.spiral:StopAnimating()
               g.spiral:Hide()
@@ -106,7 +106,7 @@
           <OnStop>
             local g = self:GetParent()
             --@debug@
-            print('Layout', g.cvars.type, '|cFF0088FFOutro |cFFFF4400STOP', g:GetName())--@end-debug@
+            --print('Layout', g.cvars.type, '|cFF0088FFOutro |cFFFF4400STOP', g:GetName())--@end-debug@
             if g.enableIcon then
               g.iconOutro:Stop()
             end
@@ -115,7 +115,7 @@
             local g = self:GetParent()
             g.trash = false
             --@debug@
-            print('Layout', g.cvars.type, '|cFF0088FFOutro |cFF00FF00Finish', g:GetName())--@end-debug@
+            --print('Layout', g.cvars.type, '|cFF0088FFOutro |cFF00FF00Finish', g:GetName())--@end-debug@
             if g.enableIcon then
               g.iconOutro:Stop()
             end
@@ -130,7 +130,7 @@
           <OnPlay>
             local g = self:GetParent()
             --@debug@
-            print('Layout', g.cvars.type, '|cFFFFFF00Retro |cFFFFFF00START', g:GetName())--@end-debug@
+            --print('Layout', g.cvars.type, '|cFFFFFF00Retro |cFFFFFF00START', g:GetName())--@end-debug@
             if g.iconFlash then
               g.iconFlash:Show()
             end
@@ -138,12 +138,12 @@
           <OnStop>
             local g = self:GetParent()
             --@debug@
-            print('Layout',g.cvars.type, '|cFFFFFF00Retro |cFFFF4400STOP', self:GetParent():GetName())--@end-debug@
+            --print('Layout',g.cvars.type, '|cFFFFFF00Retro |cFFFF4400STOP', self:GetParent():GetName())--@end-debug@
           </OnStop>
           <OnFinished>
             local g = self:GetParent()
             --@debug@
-            print('Layout',g.cvars.type, '|cFFFFFF00Retro |cFF00FF00FINISH', g:GetName())--@end-debug@
+            --print('Layout',g.cvars.type, '|cFFFFFF00Retro |cFF00FF00FINISH', g:GetName())--@end-debug@
             if g.iconFlash then
               g.iconFlash:Hide()
             end
@@ -197,8 +197,14 @@
     </Scripts>
     <Frames>
       <Cooldown name="$parentCooldownSpiral" parentKey="spiral" inherits="CooldownFrameTemplate">
+        <EdgeTexture file="">
+          <Color r="1" g="0" b="1" a="0" />
+        </EdgeTexture>
+        <BlingTexture file="">
+          <Color r="0" g="1" b="1" a="0" />
+        </BlingTexture>
         <SwipeTexture parentKey="spiralTex">
-          <Color r="0" g="0" b="0" a="0.6" />
+          <Color r="0" g="0" b="0" a="0.8" />
         </SwipeTexture>
         <Anchors>
           <Anchor relativeKey="$parent.icon" point="TOPLEFT" relativePoint="TOPLEFT" x="0" y="0" />
@@ -206,24 +212,22 @@
         </Anchors>
         <Layers>
           <Layer level="OVERLAY">
-            <FontString inherits="TurokFontMed" name="$parentCounter" parentKey="counter" justifyH="RIGHT" justifyV="BOTTOM">
+            <FontString inherits="TurokFontMed" name="$parentCounter" parentKey="counter" justifyH="CENTER" justifyV="MIDDLE">
+              <!-- [1] below 6 seconds remaining
               <KeyValues>
-                <!-- [1] below 6 seconds remaining -->
                 <KeyValue key="anchor1" value="TOP" />
                 <KeyValue key="anchor1_rel" value="TOP" />
-                <!-- [2] default -->
                 <KeyValue key="anchor2" value="TOP" />
                 <KeyValue key="anchor2_rel" value="TOP" />
-                <!-- [3] > 100 sec remaining -->
                 <KeyValue key="anchor3" value="TOPRIGHT" />
                 <KeyValue key="anchor3_rel" value="TOP" />
-              </KeyValues>
-              <Size x="40" y="40" />
+              </KeyValues> -->
               <Anchors>
-                <Anchor point="TOPRIGHT" relativePoint="TOP" relativeKey="$parent.$parent.icon" x="0" y="4" />
+                <Anchor point="CENTER" relativePoint="CENTER" relativeKey="$parent.$parent.icon" x="0" y="0" />
               </Anchors>
             </FontString>
             <FontString inherits="TurokFontDetail" name="$parentSubCounter" parentKey="subCounter" justifyH="LEFT" text="subtext" justifyV="BOTTOM">
+              <!--
               <KeyValues>
                 <KeyValue key="anchor1" value="LEFT" />
                 <KeyValue key="anchor1_rel" value="RIGHT" />
@@ -232,10 +236,11 @@
                 <KeyValue key="anchor3" value="LEFT" />
                 <KeyValue key="anchor3_rel" value="RIGHT" />
               </KeyValues>
+              -->
               <Size x="40" y="40" />
               <Color r="1" g="1" b="0" a="1" />
               <Anchors>
-                <Anchor point="LEFT" relativePoint="RIGHT" relativeKey="$parent.counter" x="0" y="1" />
+                <Anchor point="LEFT" relativePoint="RIGHT" relativeKey="$parent.counter" x="0" y="0" />
               </Anchors>
             </FontString>
             <FontString inherits="TurokFontDetail" name="$parentCharges" parentKey="charges" justifyH="RIGHT" justifyV="BOTTOM" text="charges">
--- a/Turok/Modules/Utilities/PetBattle.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Modules/Utilities/PetBattle.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -7,7 +7,12 @@
 local ADDON, Turok = ...
 local T, _G, pairs, pairs = Turok.Addon, _G, pairs, ipairs
 local mod = T:NewModule("PetBattle")
-local print = function(...) _G.print('Petz', ...) end
+local print = function(...)
+  if not DEBUG then return end
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('Petz', ...)
+  end
+end
 local trace = function(self, e, ...)
   print(e, ...)
 end
--- a/Turok/Turok.lua	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Turok.lua	Sun Feb 21 13:08:30 2016 -0500
@@ -25,6 +25,11 @@
     _G.print('Turok', ...)
   end
 end
+local uprint = function(...)
+  if _G.Devian and _G.DevianDB.workspace ~= 1 then
+    _G.print('Update', ...)
+  end
+end
 local GetPrint = function(trace)
   return trace and print or function() end
 end
@@ -413,14 +418,14 @@
   end
 
 function T:UNIT_SPELLCAST_INTERRUPTED(e, unit, spellName, rank, target, castID)
-  if not T.isEventUnit[unit] then
+  if not T.unit[unit] then
     return
   end
   T.spellevent[unit] = {unit, spellName, rank, target, castID, nil }
 end
 
 function T:UNIT_SPELLCAST_SENT(e,unit, spellName, rank, target, castID)
-  if not T.isEventUnit[unit] then
+  if not T.unit[unit] then
     return
   end
   T.unit[unit].spellEventString = e
@@ -428,7 +433,7 @@
 end
 
 function T:UNIT_SPELLCAST (e, unit, spellName, rank, castID, spellID)
-  if not T.isEventUnit[unit] then
+  if not T.unit[unit] then
     return
   end
   --name, subText, text, texture, startTime, endTime, isTradeSkill, castID, notInterruptible
@@ -440,7 +445,7 @@
 end
 
 function T:UNIT_CHANNEL(e, unit, spellName, rank, castID, spellID)
-  if not T.isEventUnit[unit] then
+  if not T.unit[unit] then
     return
   end
   --name, subText, text, texture, startTime, endTime, isTradeSkill, notInterruptible
@@ -467,7 +472,7 @@
   local u = T.unit[unit]
   local exists = UnitExists(unit)
   local realm
-  _G.print('Update', cText('  '..unit..' change:'), cText(unit), cText(exists and UnitName(unit)))
+  uprint(cText('  '..unit..' change:'), cText(unit), cText(exists and UnitName(unit)))
 
   u.exists = exists
   u.name, realm = UnitName(unit)
@@ -486,7 +491,7 @@
 
 
   for k,v in pairs(T.unit[unit]) do
-    _G.print('Update', cText('  -'), cText(k),'->', cText(v))
+    uprint(cText('  -'), cText(k),'->', cText(v))
   end
 end
 function T:PLAYER_TARGET_CHANGED(e)
--- a/Turok/Turok.xml	Sun Feb 21 08:49:34 2016 -0500
+++ b/Turok/Turok.xml	Sun Feb 21 13:08:30 2016 -0500
@@ -15,7 +15,6 @@
   <Script file="Init.lua" />
   <Include file="Layout\Layout.xml" />
   <Include file="Layout\Dialog.xml" />
-  <Script file="Prototypes.lua" />
   <Script file="Media.lua" />
 
   <Include file="Modules\Combat\Combat.xml" />