WoWInterface SVN NeedToKnow-Updated

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 122 to Rev 123
    Reverse comparison

Rev 122 → Rev 123

trunk/NeedToKnow/NeedToKnow.lua
31,12 → 31,41
-- ADDON GLOBALS
-- -------------
 
local GetActiveTalentGroup = _G.GetActiveSpecGroup
 
NeedToKnow = {}
NeedToKnowLoader = {}
NeedToKnow.scratch = {}
NeedToKnow.scratch.all_stacks =
 
-- -------------
-- ADDON MEMBERS
-- -------------
local g_GetActiveTalentGroup = _G.GetActiveSpecGroup
local g_UnitAffectingCombat = UnitAffectingCombat
local g_UnitIsFriend = UnitIsFriend
local g_UnitGUID = UnitGUID
local g_GetTime = GetTime
local g_GetWeaponEnchantInfo = GetWeaponEnchantInfo
 
local m_last_guid, m_last_cast, m_last_sent, m_last_cast_head, m_last_cast_tail
local m_bInCombat, m_bCombatWithBoss
 
local mfn_Bar_AuraCheck
local mfn_AuraCheck_Single
local mfn_AuraCheck_TOTEM
local mfn_AuraCheck_BUFFCD
local mfn_AuraCheck_USABLE
local mfn_AuraCheck_EQUIPSLOT
local mfn_AuraCheck_CASTCD
local mfn_AuraCheck_Weapon
local mfn_AuraCheck_AllStacks
local mfn_GetUnresolvedCooldown
local mfn_GetAutoShotCooldown
local mfn_GetSpellCooldown
local mfn_AddInstanceToStacks
local mfn_SetStatusBarValue
local mfn_ResetScratchStacks
local mfn_UpdateVCT
 
local m_scratch = {}
m_scratch.all_stacks =
{
min =
{
54,7 → 83,7
total = 0,
total_ttn = { 0, 0, 0 }
}
NeedToKnow.scratch.buff_stacks =
m_scratch.buff_stacks =
{
min =
{
72,7 → 101,7
total = 0,
total_ttn = { 0, 0, 0 }
}
NeedToKnow.scratch.bar_entry =
m_scratch.bar_entry =
{
idxName = 0,
barSpell = "",
81,16 → 110,16
-- NEEDTOKNOW = {} is defined in the localization file, which must be loaded before this file
 
NEEDTOKNOW.VERSION = "4.0.08"
NEEDTOKNOW.UPDATE_INTERVAL = 0.05
NEEDTOKNOW.MAXBARS = 20
local c_UPDATE_INTERVAL = 0.05
local c_MAXBARS = 20
 
-- Get the localized name of spell 75, which is "Auto Shot" in US English
NEEDTOKNOW.AUTO_SHOT = GetSpellInfo(75)
local c_AUTO_SHOT_NAME = GetSpellInfo(75)
 
 
-- COMBAT_LOG_EVENT_UNFILTERED events where select(6,...) is the caster, 9 is the spellid, and 10 is the spell name
-- (used for Target-of-target monitoring)
NEEDTOKNOW.AURAEVENTS = {
local c_AURAEVENTS = {
SPELL_AURA_APPLIED = true,
SPELL_AURA_REMOVED = true,
SPELL_AURA_APPLIED_DOSE = true,
320,26 → 349,26
-- TODO: I hate to pay this memory cost for every "spell" ever cast.
-- Would be nice to at least garbage collect this data at some point, but that
-- may add more overhead than just keeping track of 100 spells.
if not NeedToKnow.last_sent then
NeedToKnow.last_sent = {}
if not m_last_sent then
m_last_sent = {}
end
NeedToKnow.last_sent[spell] = GetTime()
m_last_sent[spell] = g_GetTime()
 
-- How expensive a second check do we need?
if ( NeedToKnow.last_guid[spell] or NeedToKnow.BarsForPSS ) then
local r = NeedToKnow.last_cast[NeedToKnow.last_cast_tail]
if ( m_last_guid[spell] or NeedToKnow.BarsForPSS ) then
local r = m_last_cast[m_last_cast_tail]
if not r then
r = { spell=spell, target=tgt, serial=serialno }
NeedToKnow.last_cast[NeedToKnow.last_cast_tail] = r
m_last_cast[m_last_cast_tail] = r
else
r.spell = spell
r.target = tgt
r.serial = serialno
end
NeedToKnow.last_cast_tail = NeedToKnow.last_cast_tail + 1
if ( NeedToKnow.last_cast_tail == 2 ) then
NeedToKnow.last_cast_head = 1
if ( NeedToKnow.last_guid[spell] ) then
m_last_cast_tail = m_last_cast_tail + 1
if ( m_last_cast_tail == 2 ) then
m_last_cast_head = 1
if ( m_last_guid[spell] ) then
NeedToKnow_ExecutiveFrame:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
NeedToKnow_ExecutiveFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
else
354,10 → 383,10
function NeedToKnow.ExecutiveFrame_UNIT_SPELLCAST_SUCCEEDED(unit, spell, rank_str, serialno, spellid)
if unit == "player" then
local found
local t = NeedToKnow.last_cast
local last = NeedToKnow.last_cast_tail-1
local t = m_last_cast
local last = m_last_cast_tail-1
local i
for i = last,NeedToKnow.last_cast_head,-1 do
for i = last,m_last_cast_head,-1 do
if t[i].spell == spell and t[i].serial == serialno then
found = i
break
374,11 → 403,11
end
 
if ( found == last ) then
NeedToKnow.last_cast_tail = 1
NeedToKnow.last_cast_head = 1
m_last_cast_tail = 1
m_last_cast_head = 1
NeedToKnow_ExecutiveFrame:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
else
NeedToKnow.last_cast_head = found+1
m_last_cast_head = found+1
end
end
end
386,16 → 415,16
 
function NeedToKnow.ExecutiveFrame_COMBAT_LOG_EVENT_UNFILTERED(tod, event, hideCaster, guidCaster, ...)
-- the time that's passed in appears to be time of day, not game time like everything else.
local time = GetTime()
local time = g_GetTime()
-- TODO: Is checking r.state sufficient or must event be checked instead?
if ( guidCaster == NeedToKnow.guidPlayer and event=="SPELL_CAST_SUCCESS") then
local guidTarget, nameTarget, _, _, spellid, spell = select(4, ...) -- source_name, source_flags, source_flags2,
 
local found
local t = NeedToKnow.last_cast
local last = NeedToKnow.last_cast_tail-1
local t = m_last_cast
local last = m_last_cast_tail-1
local i
for i = last,NeedToKnow.last_cast_head,-1 do
for i = last,m_last_cast_head,-1 do
if t[i].spell == spell then
found = i
break
410,7 → 439,7
end
end
 
local rBySpell = NeedToKnow.last_guid[spell]
local rBySpell = m_last_guid[spell]
if ( rBySpell ) then
local rByGuid = rBySpell[guidTarget]
if not rByGuid then
424,11 → 453,11
end
 
if ( found == last ) then
NeedToKnow.last_cast_tail = 1
NeedToKnow.last_cast_head = 1
m_last_cast_tail = 1
m_last_cast_head = 1
NeedToKnow_ExecutiveFrame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
else
NeedToKnow.last_cast_head = found+1
m_last_cast_head = found+1
end
end
end
441,10 → 470,10
NeedToKnow_Visible = true
end
 
NeedToKnow.last_cast = {} -- [n] = { spell, target, serial }
NeedToKnow.last_cast_head = 1
NeedToKnow.last_cast_tail = 1
NeedToKnow.last_guid = {} -- [spell][guidTarget] = { time, dur, expiry }
m_last_cast = {} -- [n] = { spell, target, serial }
m_last_cast_head = 1
m_last_cast_tail = 1
m_last_guid = {} -- [spell][guidTarget] = { time, dur, expiry }
NeedToKnow.totem_drops = {} -- array 1-4 of precise times the totems appeared
NeedToKnow.weapon_enchants = { mhand = {}, ohand = {} }
 
523,7 → 552,7
 
function NeedToKnow.ExecutiveFrame_PLAYER_TALENT_UPDATE()
if NeedToKnow.CharSettings then
local spec = GetActiveTalentGroup()
local spec = g_GetActiveTalentGroup()
 
local profile_key = NeedToKnow.CharSettings.Specs[spec]
if not profile_key then
537,12 → 566,12
 
 
function NeedToKnow.ExecutiveFrame_UNIT_TARGET(unitTargeting)
if NeedToKnow.bInCombat and not NeedToKnow.bCombatWithBoss then
if m_bInCombat and not m_bCombatWithBoss then
if UnitLevel(unitTargeting .. 'target') == -1 then
NeedToKnow.bCombatWithBoss = true
m_bCombatWithBoss = true
if NeedToKnow.BossStateBars then
for bar, unused in pairs(NeedToKnow.BossStateBars) do
NeedToKnow.Bar_AuraCheck(bar)
mfn_Bar_AuraCheck(bar)
end
end
end
596,39 → 625,39
 
 
function NeedToKnow.ExecutiveFrame_PLAYER_REGEN_DISABLED(unitTargeting)
NeedToKnow.bInCombat = true
NeedToKnow.bCombatWithBoss = false
m_bInCombat = true
m_bCombatWithBoss = false
if IsInRaid() then
for i = 1, 40 do
if UnitLevel("raid"..i.."target") == -1 then
NeedToKnow.bCombatWithBoss = true;
m_bCombatWithBoss = true;
break;
end
end
elseif IsInGroup() then
for i = 1, 5 do
if UnitLevel("party"..i.."target") == -1 then
NeedToKnow.bCombatWithBoss = true;
m_bCombatWithBoss = true;
break;
end
end
elseif UnitLevel("target") == -1 then
NeedToKnow.bCombatWithBoss = true
m_bCombatWithBoss = true
end
if NeedToKnow.BossStateBars then
for bar, unused in pairs(NeedToKnow.BossStateBars) do
NeedToKnow.Bar_AuraCheck(bar)
mfn_Bar_AuraCheck(bar)
end
end
end
 
 
function NeedToKnow.ExecutiveFrame_PLAYER_REGEN_ENABLED(unitTargeting)
NeedToKnow.bInCombat = false
NeedToKnow.bCombatWithBoss = false
m_bInCombat = false
m_bCombatWithBoss = false
if NeedToKnow.BossStateBars then
for bar, unused in pairs(NeedToKnow.BossStateBars) do
NeedToKnow.Bar_AuraCheck(bar)
mfn_Bar_AuraCheck(bar)
end
end
end
753,7 → 782,7
 
-- Switch to the new profile
NeedToKnow.ProfileSettings = NeedToKnow_Profiles[profile_key]
local spec = GetActiveTalentGroup()
local spec = g_GetActiveTalentGroup()
NeedToKnow.CharSettings.Specs[spec] = profile_key
 
-- fill in any missing defaults
791,7 → 820,7
end
 
 
local function SetStatusBarValue(bar,texture,value,value0)
mfn_SetStatusBarValue = function (bar,texture,value,value0)
local pct0 = 0
if value0 then
pct0 = value0 / bar.max_value
1189,10 → 1218,10
local idx = entry.idxName
if not id then
if ( name == "Auto Shot" or
name == NEEDTOKNOW.AUTO_SHOT )
name == c_AUTO_SHOT_NAME )
then
bar.settings.bAutoShot = true
bar.cd_functions[idx] = NeedToKnow.GetAutoShotCooldown
bar.cd_functions[idx] = mfn_GetAutoShotCooldown
else
local item_id = NeedToKnow.GetItemIDString(name)
if item_id then
1205,11 → 1234,11
if nil ~= betterSpell then
entry.id = betterSpell
entry.name = nil
bar.cd_functions[idx] = NeedToKnow.GetSpellCooldown
bar.cd_functions[idx] = mfn_GetSpellCooldown
elseif not GetSpellCooldown(name) then
bar.cd_functions[idx] = NeedToKnow.GetUnresolvedCooldown
bar.cd_functions[idx] = mfn_GetUnresolvedCooldown
else
bar.cd_functions[idx] = NeedToKnow.GetSpellCooldown
bar.cd_functions[idx] = mfn_GetSpellCooldown
end
end
end
1261,7 → 1290,7
 
bar.settings = barSettings
bar.unit = barSettings.Unit
bar.nextUpdate = GetTime() + NEEDTOKNOW.UPDATE_INTERVAL
bar.nextUpdate = g_GetTime() + c_UPDATE_INTERVAL
 
bar.fixedDuration = tonumber(groupSettings.FixedDuration)
if ( not bar.fixedDuration or 0 >= bar.fixedDuration ) then
1269,7 → 1298,7
end
 
bar.max_value = 1
SetStatusBarValue(bar,bar.bar1,1)
mfn_SetStatusBarValue(bar,bar.bar1,1)
bar.bar1:SetTexture(NeedToKnow.LSM:Fetch("statusbar", NeedToKnow.ProfileSettings["BarTexture"]))
if ( bar.bar2 ) then
bar.bar2:SetTexture(NeedToKnow.LSM:Fetch("statusbar", NeedToKnow.ProfileSettings["BarTexture"]))
1371,25 → 1400,25
 
-- Determine which helper functions to use
if "BUFFCD" == barSettings.BuffOrDebuff then
bar.fnCheck = NeedToKnow.AuraCheck_BUFFCD
bar.fnCheck = mfn_AuraCheck_BUFFCD
elseif "TOTEM" == barSettings.BuffOrDebuff then
bar.fnCheck = NeedToKnow.AuraCheck_TOTEM
bar.fnCheck = mfn_AuraCheck_TOTEM
elseif "USABLE" == barSettings.BuffOrDebuff then
bar.fnCheck = NeedToKnow.AuraCheck_USABLE
bar.fnCheck = mfn_AuraCheck_USABLE
elseif "EQUIPSLOT" == barSettings.BuffOrDebuff then
bar.fnCheck = NeedToKnow.AuraCheck_EQUIPSLOT
bar.fnCheck = mfn_AuraCheck_EQUIPSLOT
elseif "CASTCD" == barSettings.BuffOrDebuff then
bar.fnCheck = NeedToKnow.AuraCheck_CASTCD
bar.fnCheck = mfn_AuraCheck_CASTCD
for idx, entry in ipairs(bar.spells) do
table.insert(bar.cd_functions, NeedToKnow.GetSpellCooldown)
table.insert(bar.cd_functions, mfn_GetSpellCooldown)
NeedToKnow.SetupSpellCooldown(bar, entry)
end
elseif "mhand" == barSettings.Unit or "ohand" == barSettings.Unit then
bar.fnCheck = NeedToKnow.AuraCheck_Weapon
bar.fnCheck = mfn_AuraCheck_Weapon
elseif barSettings.show_all_stacks then
bar.fnCheck = NeedToKnow.AuraCheck_AllStacks
bar.fnCheck = mfn_AuraCheck_AllStacks
else
bar.fnCheck = NeedToKnow.AuraCheck_Single
bar.fnCheck = mfn_AuraCheck_Single
end
 
if ( barSettings.BuffOrDebuff == "BUFFCD" ) then
1402,7 → 1431,7
 
NeedToKnow.SetScripts(bar)
-- Events were cleared while unlocked, so need to check the bar again now
NeedToKnow.Bar_AuraCheck(bar)
mfn_Bar_AuraCheck(bar)
else
NeedToKnow.ClearScripts(bar)
bar:Hide()
1527,9 → 1556,9
spellName = entry.name
end
if spellName then
local r = NeedToKnow.last_guid[spellName]
local r = m_last_guid[spellName]
if not r then
NeedToKnow.last_guid[spellName] = { time=0, dur=0, expiry=0 }
m_last_guid[spellName] = { time=0, dur=0, expiry=0 }
end
else
print("Warning! NTK could not get name for ", entry.id)
1582,28 → 1611,28
end
 
function NeedToKnow.Bar_OnSizeChanged(self)
if (self.bar1.cur_value) then SetStatusBarValue(self, self.bar1, self.bar1.cur_value) end
if (self.bar2 and self.bar2.cur_value) then SetStatusBarValue(self, self.bar2, self.bar2.cur_value, self.bar1.cur_value) end
if (self.bar1.cur_value) then mfn_SetStatusBarValue(self, self.bar1, self.bar1.cur_value) end
if (self.bar2 and self.bar2.cur_value) then mfn_SetStatusBarValue(self, self.bar2, self.bar2.cur_value, self.bar1.cur_value) end
end
 
function NeedToKnow.Bar_OnEvent(self, event, unit, ...)
if ( event == "COMBAT_LOG_EVENT_UNFILTERED") then
local combatEvent = select(1, ...)
 
if ( NEEDTOKNOW.AURAEVENTS[combatEvent] ) then
if ( c_AURAEVENTS[combatEvent] ) then
local guidTarget = select(7, ...)
if ( guidTarget == UnitGUID(self.unit) ) then
if ( guidTarget == g_UnitGUID(self.unit) ) then
local idSpell, nameSpell = select(11, ...)
if (self.auraName:find(idSpell) or
self.auraName:find(nameSpell))
then
NeedToKnow.Bar_AuraCheck(self)
mfn_Bar_AuraCheck(self)
end
end
elseif ( combatEvent == "UNIT_DIED" ) then
local guidDeceased = select(7, ...)
if ( guidDeceased == UnitGUID(self.unit) ) then
NeedToKnow.Bar_AuraCheck(self)
mfn_Bar_AuraCheck(self)
end
end
elseif ( event == "PLAYER_TOTEM_UPDATE" ) or
1611,24 → 1640,24
( event == "SPELL_UPDATE_COOLDOWN" ) or
( event == "SPELL_UPDATE_USABLE" )
then
NeedToKnow.Bar_AuraCheck(self)
mfn_Bar_AuraCheck(self)
elseif ( event == "UNIT_AURA" ) and ( unit == self.unit ) then
NeedToKnow.Bar_AuraCheck(self)
mfn_Bar_AuraCheck(self)
elseif ( event == "UNIT_INVENTORY_CHANGED" and unit == "player" ) then
NeedToKnow.UpdateWeaponEnchants()
NeedToKnow.Bar_AuraCheck(self)
mfn_Bar_AuraCheck(self)
elseif ( event == "PLAYER_TARGET_CHANGED" ) or ( event == "PLAYER_FOCUS_CHANGED" ) then
if self.unit == "targettarget" then
NeedToKnow.CheckCombatLogRegistration(self)
end
NeedToKnow.Bar_AuraCheck(self)
mfn_Bar_AuraCheck(self)
elseif ( event == "UNIT_TARGET" and unit == "target" ) then
if self.unit == "targettarget" then
NeedToKnow.CheckCombatLogRegistration(self)
end
NeedToKnow.Bar_AuraCheck(self)
mfn_Bar_AuraCheck(self)
elseif ( event == "UNIT_PET" and unit == "player" ) then
NeedToKnow.Bar_AuraCheck(self)
mfn_Bar_AuraCheck(self)
elseif ( event == "PLAYER_SPELLCAST_SUCCEEDED" ) then
local spellName, spellID, tgt = select(1,...)
local i,entry
1636,7 → 1665,7
if entry.id == spellID or entry.name == spellName then
self.unit = tgt or "unknown"
--trace("Updating",self:GetName(),"since it was recast on",self.unit)
NeedToKnow.Bar_AuraCheck(self)
mfn_Bar_AuraCheck(self)
break;
end
end
1646,11 → 1675,11
self:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
elseif ( event == "UNIT_SPELLCAST_SUCCEEDED" ) then
local spell = select(1,...)
if ( self.settings.bAutoShot and unit == "player" and spell == NEEDTOKNOW.AUTO_SHOT ) then
if ( self.settings.bAutoShot and unit == "player" and spell == c_AUTO_SHOT_NAME ) then
local interval = UnitRangedDamage("player")
self.tAutoShotCD = interval
self.tAutoShotStart = GetTime()
NeedToKnow.Bar_AuraCheck(self)
self.tAutoShotStart = g_GetTime()
mfn_Bar_AuraCheck(self)
end
end
end
1682,7 → 1711,7
return text
end
 
-- Called by NeedToKnow.UpdateVCT, which is called from AuraCheck and possibly
-- Called by mfn_UpdateVCT, which is called from AuraCheck and possibly
-- by Bar_Update depending on vct_refresh. In addition to refactoring out some
-- code from the long AuraCheck, this also provides a convenient hook for other addons
function NeedToKnow.ComputeVCTDuration(bar)
1707,7 → 1736,7
return vct_duration
end
 
function NeedToKnow.UpdateVCT(bar)
mfn_UpdateVCT = function (bar)
local vct_duration = NeedToKnow.ComputeVCTDuration(bar)
 
local dur = bar.fixedDuration or bar.duration
1831,13 → 1860,13
 
-- Determine the size of the visual cast bar
if ( bar.settings.vct_enabled ) then
NeedToKnow.UpdateVCT(bar)
mfn_UpdateVCT(bar)
end
 
-- Force an update to get all the bars to the current position (sharing code)
-- This will call UpdateVCT again, but that seems ok
bar.nextUpdate = -NEEDTOKNOW.UPDATE_INTERVAL
if bar.expirationTime > GetTime() then
bar.nextUpdate = -c_UPDATE_INTERVAL
if bar.expirationTime > g_GetTime() then
NeedToKnow.Bar_OnUpdate(bar, 0)
end
 
1845,8 → 1874,8
else
-- Hide the time text and spark for auras with "infinite" duration
bar.max_value = 1
SetStatusBarValue(bar,bar.bar1,1)
if bar.bar2 then SetStatusBarValue(bar,bar.bar2,1) end
mfn_SetStatusBarValue(bar,bar.bar1,1)
if bar.bar2 then mfn_SetStatusBarValue(bar,bar.bar2,1) end
 
bar.time:Hide()
bar.spark:Hide()
1869,7 → 1898,7
bar.time:Hide()
bar.spark:Hide()
bar.max_value = 1
SetStatusBarValue(bar,bar.bar1,1)
mfn_SetStatusBarValue(bar,bar.bar1,1)
 
if ( bar.icon ) then
bar.icon:Hide()
2032,23 → 2061,23
end
 
 
-- Helper for NeedToKnow.AuraCheck_CASTCD which gets the autoshot cooldown
function NeedToKnow.GetAutoShotCooldown(bar)
local tNow = GetTime()
-- Helper for mfn_AuraCheck_CASTCD which gets the autoshot cooldown
mfn_GetAutoShotCooldown = function(bar)
local tNow = g_GetTime()
if ( bar.tAutoShotStart and bar.tAutoShotStart + bar.tAutoShotCD > tNow ) then
local n, icon = GetSpellInfo(75)
return bar.tAutoShotStart, bar.tAutoShotCD, 1, NEEDTOKNOW.AUTO_SHOT, icon
return bar.tAutoShotStart, bar.tAutoShotCD, 1, c_AUTO_SHOT_NAME, icon
else
bar.tAutoShotStart = nil
end
end
 
 
-- Helper for NeedToKnow.AuraCheck_CASTCD for names we haven't figured out yet
function NeedToKnow.GetUnresolvedCooldown(bar, entry)
-- Helper for mfn_AuraCheck_CASTCD for names we haven't figured out yet
mfn_GetUnresolvedCooldown = function(bar, entry)
NeedToKnow.SetupSpellCooldown(bar, entry)
local fn = bar.cd_functions[entry.idxName]
if NeedToKnow.GetUnresolvedCooldown ~= fn then
if mfn_GetUnresolvedCooldown ~= fn then
return fn(bar, entry)
end
end
2056,7 → 2085,7
 
-- Wrapper around GetSpellCooldown with extra sauce
-- Expected to return start, cd_len, enable, buffName, iconpath
function NeedToKnow.GetSpellCooldown(bar, entry)
mfn_GetSpellCooldown = function(bar, entry)
local barSpell = entry.id or entry.name
local start, cd_len, enable = GetSpellCooldown(barSpell)
if start and start > 0 then
2078,12 → 2107,12
elseif spellPower == 5 then -- Rune
-- Filter out rune cooldown artificially extending the cd
if cd_len <= 10 then
local tNow = GetTime()
local tNow = g_GetTime()
if bar.expirationTime and tNow < bar.expirationTime then
-- We've already seen the correct CD for this; keep using it
start = bar.expirationTime - bar.duration
cd_len = bar.duration
elseif NeedToKnow.last_sent and NeedToKnow.last_sent[spellName] and NeedToKnow.last_sent[spellName] > (tNow - 1.5) then
elseif m_last_sent and m_last_sent[spellName] and m_last_sent[spellName] > (tNow - 1.5) then
-- We think the spell was just cast, and a CD just started but it's short.
-- Look at the tooltip to tell what the correct CD should be. If it's supposed
-- to be short (Ghoul Frenzy, Howling Blast), then start a CD bar
2124,7 → 2153,7
data.icon = nil
--trace("Warning: NTK couldn't figure out what enchant is on weapon slot",slot)
end
data.expiration = GetTime() + data.expiration/1000
data.expiration = g_GetTime() + data.expiration/1000
if oldname ~= data.name then
local _
_,_,data.icon = GetSpellInfo(data.name)
2150,7 → 2179,7
 
mdata.present, mdata.expiration, mdata.charges,
odata.present, odata.expiration, odata.charges
= GetWeaponEnchantInfo()
= g_GetWeaponEnchantInfo()
 
if ( mdata.present ) then
NeedToKnow.UpdateWeaponEnchantData(mdata, 16)
2166,7 → 2195,7
end
 
 
local function AddInstanceToStacks(all_stacks, bar_entry, duration, name, count, expirationTime, iconPath, caster, tt1, tt2, tt3)
mfn_AddInstanceToStacks = function (all_stacks, bar_entry, duration, name, count, expirationTime, iconPath, caster, tt1, tt2, tt3)
if duration then
if (not count or count < 1) then count = 1 end
if ( 0 == all_stacks.total or all_stacks.min.expirationTime > expirationTime ) then
2197,27 → 2226,27
 
-- Bar_AuraCheck helper for Totem bars, this returns data if
-- a totem matching bar_entry is currently out.
function NeedToKnow.AuraCheck_TOTEM(bar, bar_entry, all_stacks)
mfn_AuraCheck_TOTEM = function(bar, bar_entry, all_stacks)
local idxName = bar_entry.idxName
local sComp = bar_entry.name or GetSpellInfo(bar_entry.id)
for iSlot=1, 4 do
local haveTotem, totemName, startTime, totemDuration, totemIcon = GetTotemInfo(iSlot)
if ( totemName and totemName:find(sComp) ) then
-- WORKAROUND: The startTime reported here is both cast to an int and off by
-- a latency meaning it can be significantly low. So we cache the GetTime
-- that the totem actually appeared, so long as GetTime is reasonably close to
-- a latency meaning it can be significantly low. So we cache the g_GetTime
-- that the totem actually appeared, so long as g_GetTime is reasonably close to
-- startTime (since the totems may have been out for awhile before this runs.)
if ( not NeedToKnow.totem_drops[iSlot] or
NeedToKnow.totem_drops[iSlot] < startTime )
then
local precise = GetTime()
local precise = g_GetTime()
if ( precise - startTime > 1 ) then
precise = startTime + 1
end
NeedToKnow.totem_drops[iSlot] = precise
end
 
AddInstanceToStacks(all_stacks, bar_entry,
mfn_AddInstanceToStacks(all_stacks, bar_entry,
totemDuration, -- duration
totemName, -- name
1, -- count
2233,17 → 2262,17
 
-- Bar_AuraCheck helper for tracking usable gear based on the slot its in
-- rather than the equipment name
function NeedToKnow.AuraCheck_EQUIPSLOT(bar, bar_entry, all_stacks)
mfn_AuraCheck_EQUIPSLOT = function (bar, bar_entry, all_stacks)
local spellName, spellRank, spellIconPath
if ( bar_entry.id ) then
local id = GetInventoryItemID("player",bar_entry.id)
if id then
local item_entry = NeedToKnow.scratch.bar_entry
local item_entry = m_scratch.bar_entry
item_entry.id = id
local start, cd_len, enable, name, icon = NeedToKnow.GetItemCooldown(bar, item_entry)
 
if ( start and start > 0 ) then
AddInstanceToStacks(all_stacks, bar_entry,
mfn_AddInstanceToStacks(all_stacks, bar_entry,
cd_len, -- duration
name, -- name
1, -- count
2260,10 → 2289,10
-- Bar_AuraCheck helper that checks the bar.weapon_enchants
-- (computed by UpdateWeaponEnchants) for the given spell.
-- FIXME: this is the only bar type that does not work with spell ids.
function NeedToKnow.AuraCheck_Weapon(bar, bar_entry, all_stacks)
mfn_AuraCheck_Weapon = function (bar, bar_entry, all_stacks)
local data = NeedToKnow.weapon_enchants[bar.settings.Unit]
if ( data.present and data.name and data.name:find(bar_entry.name) ) then
AddInstanceToStacks( all_stacks, bar_entry,
mfn_AddInstanceToStacks( all_stacks, bar_entry,
1800, -- duration TODO: Get real duration?
data.name, -- name
data.charges, -- count
2275,10 → 2304,10
 
 
-- Bar_AuraCheck helper that checks for spell/item use cooldowns
-- Relies on NeedToKnow.GetAutoShotCooldown, NeedToKnow.GetSpellCooldown
-- Relies on mfn_GetAutoShotCooldown, mfn_GetSpellCooldown
-- and NeedToKnow.GetItemCooldown. Bar_Update will have already pre-processed
-- this list so that bar.cd_functions[idxName] can do something with bar_entry
function NeedToKnow.AuraCheck_CASTCD(bar, bar_entry, all_stacks)
mfn_AuraCheck_CASTCD = function(bar, bar_entry, all_stacks)
local idxName = bar_entry.idxName
local func = bar.cd_functions[idxName]
if ( not func ) then
2288,7 → 2317,7
local start, cd_len, should_cooldown, buffName, iconPath = func(bar, bar_entry)
 
-- filter out the GCD, we only care about actual spell CDs
if start and cd_len <= 1.5 and func ~= NeedToKnow.GetAutoShotCooldown then
if start and cd_len <= 1.5 and func ~= mfn_GetAutoShotCooldown then
if bar.expirationTime and bar.expirationTime <= (start + cd_len) then
start = bar.expirationTime - bar.duration
cd_len = bar.duration
2298,10 → 2327,10
end
 
if start and cd_len then
local tNow = GetTime()
local tNow = g_GetTime()
local tEnd = start + cd_len
if ( tEnd > tNow + 0.1 ) then
AddInstanceToStacks( all_stacks, bar_entry,
mfn_AddInstanceToStacks( all_stacks, bar_entry,
cd_len, -- duration
buffName, -- name
1, -- count
2315,7 → 2344,7
 
-- Bar_AuraCheck helper for watching "Is Usable", which means that the action
-- bar button for the spell lights up. This is mostly useful for Victory Rush
function NeedToKnow.AuraCheck_USABLE(bar, bar_entry, all_stacks)
mfn_AuraCheck_USABLE = function (bar, bar_entry, all_stacks)
local key = bar_entry.id or bar_entry.name
local settings = bar.settings
if ( not key ) then key = "" end
2325,7 → 2354,7
if (isUsable or notEnoughMana) then
local duration = settings.usable_duration
local expirationTime
local tNow = GetTime()
local tNow = g_GetTime()
if ( not bar.expirationTime or
(bar.expirationTime > 0 and bar.expirationTime < tNow - 0.01) )
then
2336,7 → 2365,7
expirationTime = bar.expirationTime
end
 
AddInstanceToStacks( all_stacks, bar_entry,
mfn_AddInstanceToStacks( all_stacks, bar_entry,
duration, -- duration
spellName, -- name
1, -- count
2348,7 → 2377,7
end
 
 
function NeedToKnow.ResetScratchStacks(buff_stacks)
mfn_ResetScratchStacks = function (buff_stacks)
buff_stacks.total = 0;
buff_stacks.total_ttn[1] = 0;
buff_stacks.total_ttn[2] = 0;
2358,20 → 2387,20
-- Bar_AuraCheck helper for watching "internal cooldowns", which is like a spell
-- cooldown for spells cast automatically (procs). The "reset on buff" logic
-- is still handled by
function NeedToKnow.AuraCheck_BUFFCD(bar, bar_entry, all_stacks)
local buff_stacks = NeedToKnow.scratch.buff_stacks
NeedToKnow.ResetScratchStacks(buff_stacks);
NeedToKnow.AuraCheck_Single(bar, bar_entry, buff_stacks)
local tNow = GetTime()
mfn_AuraCheck_BUFFCD = function (bar, bar_entry, all_stacks)
local buff_stacks = m_scratch.buff_stacks
mfn_ResetScratchStacks(buff_stacks);
mfn_AuraCheck_Single(bar, bar_entry, buff_stacks)
local tNow = g_GetTime()
if ( buff_stacks.total > 0 ) then
if buff_stacks.max.expirationTime == 0 then
-- TODO: This really doesn't work very well as a substitute for telling when the aura was applied
if not bar.expirationTime then
local nDur = tonumber(bar.settings.buffcd_duration)
AddInstanceToStacks( all_stacks, bar_entry,
mfn_AddInstanceToStacks( all_stacks, bar_entry,
nDur, buff_stacks.min.buffName, 1, nDur+tNow, buff_stacks.min.iconPath, buff_stacks.min.caster )
else
AddInstanceToStacks( all_stacks, bar_entry,
mfn_AddInstanceToStacks( all_stacks, bar_entry,
bar.duration, -- duration
bar.buffName, -- name
1, -- count
2385,7 → 2414,7
local duration = tonumber(bar.settings.buffcd_duration)
local expiration = tStart + duration
if ( expiration > tNow ) then
AddInstanceToStacks( all_stacks, bar_entry,
mfn_AddInstanceToStacks( all_stacks, bar_entry,
duration, -- duration
buff_stacks.min.buffName, -- name
-- Seeing the charges on the CD bar violated least surprise for me
2395,7 → 2424,7
buff_stacks.min.caster ) -- caster
end
elseif ( bar.expirationTime and bar.expirationTime > tNow + 0.1 ) then
AddInstanceToStacks( all_stacks, bar_entry,
mfn_AddInstanceToStacks( all_stacks, bar_entry,
bar.duration, -- duration
bar.buffName, -- name
1, -- count
2445,7 → 2474,7
 
-- Bar_AuraCheck helper that looks for the first instance of a buff
-- Uses the UnitAura filters exclusively if it can
function NeedToKnow.AuraCheck_Single(bar, bar_entry, all_stacks)
mfn_AuraCheck_Single = function(bar, bar_entry, all_stacks)
local settings = bar.settings
local filter = settings.BuffOrDebuff
if settings.OnlyMine then
2465,7 → 2494,7
end
 
if (spellID == barID) then
AddInstanceToStacks( all_stacks, bar_entry,
mfn_AddInstanceToStacks( all_stacks, bar_entry,
duration, -- duration
buffName, -- name
count, -- count
2480,7 → 2509,7
else
local buffName, iconPath, count, duration, expirationTime, caster, _, tt1, tt2, tt3
= UnitAuraWrapper(bar.unit, bar_entry.name, nil, filter)
AddInstanceToStacks( all_stacks, bar_entry,
mfn_AddInstanceToStacks( all_stacks, bar_entry,
duration, -- duration
buffName, -- name
count, -- count
2494,7 → 2523,7
 
-- Bar_AuraCheck helper that updates bar.all_stacks (but returns nil)
-- by scanning all the auras on the unit
function NeedToKnow.AuraCheck_AllStacks(bar, bar_entry, all_stacks)
mfn_AuraCheck_AllStacks = function (bar, bar_entry, all_stacks)
local j = 1
local settings = bar.settings
local filter = settings.BuffOrDebuff
2508,7 → 2537,7
 
if (spellID == bar_entry.id) or (bar_entry.name == buffName)
then
AddInstanceToStacks(all_stacks, bar_entry,
mfn_AddInstanceToStacks(all_stacks, bar_entry,
duration,
buffName,
count,
2524,7 → 2553,8
 
 
-- Called whenever the state of auras on the bar's unit may have changed
function NeedToKnow.Bar_AuraCheck(bar)
local g_UnitExists = UnitExists
mfn_Bar_AuraCheck = function (bar)
local settings = bar.settings
local bUnitExists, isWeapon
if "mhand" == settings.Unit or
2536,15 → 2566,15
elseif "lastraid" == settings.Unit then
bUnitExists = bar.unit and UnitExists(bar.unit)
else
bUnitExists = UnitExists(settings.Unit)
bUnitExists = g_UnitExists(settings.Unit)
end
 
-- Determine if the bar should be showing anything
local all_stacks
local idxName, duration, buffName, count, expirationTime, iconPath, caster
if ( bUnitExists ) then
all_stacks = NeedToKnow.scratch.all_stacks
NeedToKnow.ResetScratchStacks(all_stacks);
all_stacks = m_scratch.all_stacks
mfn_ResetScratchStacks(all_stacks);
 
-- Call the helper function for each of the spells in the list
for idx, entry in ipairs(bar.spells) do
2571,14 → 2601,14
-- (reset_spells will only be set for BUFFCD)
if ( bar.reset_spells ) then
local maxStart = 0
local tNow = GetTime()
local buff_stacks = NeedToKnow.scratch.buff_stacks
NeedToKnow.ResetScratchStacks(buff_stacks);
local tNow = g_GetTime()
local buff_stacks = m_scratch.buff_stacks
mfn_ResetScratchStacks(buff_stacks);
-- Keep track of when the reset auras were last applied to the player
for idx, resetSpell in ipairs(bar.reset_spells) do
-- Note this relies on BUFFCD setting the target to player, and that the onlyMine will work either way
local resetDuration, _, _, resetExpiration
= NeedToKnow.AuraCheck_Single(bar, resetSpell, buff_stacks)
= mfn_AuraCheck_Single(bar, resetSpell, buff_stacks)
local tStart
if buff_stacks.total > 0 then
if 0 == buff_stacks.max.duration then
2609,7 → 2639,7
if (settings.bDetectExtends) then
local curStart = expirationTime - duration
local guidTarget = UnitGUID(bar.unit)
local r = NeedToKnow.last_guid[buffName]
local r = m_last_guid[buffName]
 
if ( not r[guidTarget] ) then -- Should only happen from /reload or /ntk while the aura is active
-- This went off for me, but I don't know a repro yet. I suspect it has to do with bear/cat switching
2659,7 → 2689,7
bar:Show()
else
if (settings.bDetectExtends and bar.buffName) then
local r = NeedToKnow.last_guid[bar.buffName]
local r = m_last_guid[bar.buffName]
if ( r ) then
local guidTarget = UnitGUID(bar.unit)
if guidTarget then
2680,13 → 2710,13
end
end
if ( bBlink and not settings.blink_ooc ) then
if not UnitAffectingCombat("player") then
if not g_UnitAffectingCombat("player") then
bBlink = false
end
end
if ( bBlink and settings.blink_boss ) then
if UnitIsFriend(bar.unit, "player") then
bBlink = NeedToKnow.bCombatWithBoss
if g_UnitIsFriend(bar.unit, "player") then
bBlink = m_bCombatWithBoss
else
bBlink = (UnitLevel(bar.unit) == -1)
end
2723,12 → 2753,12
end
 
function NeedToKnow.Bar_OnUpdate(self, elapsed)
local now = GetTime()
local now = g_GetTime()
if ( now > self.nextUpdate ) then
self.nextUpdate = now + NEEDTOKNOW.UPDATE_INTERVAL
self.nextUpdate = now + c_UPDATE_INTERVAL
 
if ( self.blink ) then
self.blink_phase = self.blink_phase + NEEDTOKNOW.UPDATE_INTERVAL
self.blink_phase = self.blink_phase + c_UPDATE_INTERVAL
if ( self.blink_phase >= 2 ) then
self.blink_phase = 0
end
2747,14 → 2777,14
local origUnit = self.settings.Unit
if ( origUnit == "mhand" ) then
-- The expiry time doesn't update right away, so we have to poll it
local mhEnchant, mhExpire = GetWeaponEnchantInfo()
local mhEnchant, mhExpire = g_GetWeaponEnchantInfo()
if ( mhExpire ) then
self.expirationTime = GetTime() + mhExpire/1000
self.expirationTime = g_GetTime() + mhExpire/1000
end
elseif ( origUnit == "ohand" ) then
local _, _, _, ohEnchant, ohExpire = GetWeaponEnchantInfo()
local _, _, _, ohEnchant, ohExpire = g_GetWeaponEnchantInfo()
if ( ohExpire ) then
self.expirationTime = GetTime() + ohExpire/1000
self.expirationTime = g_GetTime() + ohExpire/1000
end
end
 
2762,18 → 2792,18
-- others fire the event too soon. So we have to keep checking.
if ( self.duration and self.duration > 0 ) then
local duration = self.fixedDuration or self.duration
local bar1_timeLeft = self.expirationTime - GetTime()
local bar1_timeLeft = self.expirationTime - g_GetTime()
if ( bar1_timeLeft < 0 ) then
if ( self.settings.BuffOrDebuff == "CASTCD" or
self.settings.BuffOrDebuff == "BUFFCD" or
self.settings.BuffOrDebuff == "EQUIPSLOT" )
then
NeedToKnow.Bar_AuraCheck(self)
mfn_Bar_AuraCheck(self)
return
end
bar1_timeLeft = 0
end
SetStatusBarValue(self, self.bar1, bar1_timeLeft);
mfn_SetStatusBarValue(self, self.bar1, bar1_timeLeft);
if ( self.settings.show_time ) then
local fn = NeedToKnow[self.settings.TimeFormat]
local oldText = self.time:GetText()
2799,12 → 2829,12
end
 
if ( self.max_expirationTime ) then
local bar2_timeLeft = self.max_expirationTime - GetTime()
SetStatusBarValue(self, self.bar2, bar2_timeLeft, bar1_timeLeft)
local bar2_timeLeft = self.max_expirationTime - g_GetTime()
mfn_SetStatusBarValue(self, self.bar2, bar2_timeLeft, bar1_timeLeft)
end
 
if ( self.vct_refresh ) then
NeedToKnow.UpdateVCT(self)
mfn_UpdateVCT(self)
end
end
end