WoWInterface SVN NeedToKnow-Updated

Compare Revisions

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

Rev 123 → Rev 122

trunk/NeedToKnow/NeedToKnow.lua
31,41 → 31,12
-- ADDON GLOBALS
-- -------------
 
local GetActiveTalentGroup = _G.GetActiveSpecGroup
 
NeedToKnow = {}
NeedToKnowLoader = {}
 
-- -------------
-- 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 =
NeedToKnow.scratch = {}
NeedToKnow.scratch.all_stacks =
{
min =
{
83,7 → 54,7
total = 0,
total_ttn = { 0, 0, 0 }
}
m_scratch.buff_stacks =
NeedToKnow.scratch.buff_stacks =
{
min =
{
101,7 → 72,7
total = 0,
total_ttn = { 0, 0, 0 }
}
m_scratch.bar_entry =
NeedToKnow.scratch.bar_entry =
{
idxName = 0,
barSpell = "",
110,16 → 81,16
-- NEEDTOKNOW = {} is defined in the localization file, which must be loaded before this file
 
NEEDTOKNOW.VERSION = "4.0.08"
local c_UPDATE_INTERVAL = 0.05
local c_MAXBARS = 20
NEEDTOKNOW.UPDATE_INTERVAL = 0.05
NEEDTOKNOW.MAXBARS = 20
 
-- Get the localized name of spell 75, which is "Auto Shot" in US English
local c_AUTO_SHOT_NAME = GetSpellInfo(75)
NEEDTOKNOW.AUTO_SHOT = 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)
local c_AURAEVENTS = {
NEEDTOKNOW.AURAEVENTS = {
SPELL_AURA_APPLIED = true,
SPELL_AURA_REMOVED = true,
SPELL_AURA_APPLIED_DOSE = true,
349,26 → 320,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 m_last_sent then
m_last_sent = {}
if not NeedToKnow.last_sent then
NeedToKnow.last_sent = {}
end
m_last_sent[spell] = g_GetTime()
NeedToKnow.last_sent[spell] = GetTime()
 
-- How expensive a second check do we need?
if ( m_last_guid[spell] or NeedToKnow.BarsForPSS ) then
local r = m_last_cast[m_last_cast_tail]
if ( NeedToKnow.last_guid[spell] or NeedToKnow.BarsForPSS ) then
local r = NeedToKnow.last_cast[NeedToKnow.last_cast_tail]
if not r then
r = { spell=spell, target=tgt, serial=serialno }
m_last_cast[m_last_cast_tail] = r
NeedToKnow.last_cast[NeedToKnow.last_cast_tail] = r
else
r.spell = spell
r.target = tgt
r.serial = serialno
end
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.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
NeedToKnow_ExecutiveFrame:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
NeedToKnow_ExecutiveFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
else
383,10 → 354,10
function NeedToKnow.ExecutiveFrame_UNIT_SPELLCAST_SUCCEEDED(unit, spell, rank_str, serialno, spellid)
if unit == "player" then
local found
local t = m_last_cast
local last = m_last_cast_tail-1
local t = NeedToKnow.last_cast
local last = NeedToKnow.last_cast_tail-1
local i
for i = last,m_last_cast_head,-1 do
for i = last,NeedToKnow.last_cast_head,-1 do
if t[i].spell == spell and t[i].serial == serialno then
found = i
break
403,11 → 374,11
end
 
if ( found == last ) then
m_last_cast_tail = 1
m_last_cast_head = 1
NeedToKnow.last_cast_tail = 1
NeedToKnow.last_cast_head = 1
NeedToKnow_ExecutiveFrame:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
else
m_last_cast_head = found+1
NeedToKnow.last_cast_head = found+1
end
end
end
415,16 → 386,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 = g_GetTime()
local time = 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 = m_last_cast
local last = m_last_cast_tail-1
local t = NeedToKnow.last_cast
local last = NeedToKnow.last_cast_tail-1
local i
for i = last,m_last_cast_head,-1 do
for i = last,NeedToKnow.last_cast_head,-1 do
if t[i].spell == spell then
found = i
break
439,7 → 410,7
end
end
 
local rBySpell = m_last_guid[spell]
local rBySpell = NeedToKnow.last_guid[spell]
if ( rBySpell ) then
local rByGuid = rBySpell[guidTarget]
if not rByGuid then
453,11 → 424,11
end
 
if ( found == last ) then
m_last_cast_tail = 1
m_last_cast_head = 1
NeedToKnow.last_cast_tail = 1
NeedToKnow.last_cast_head = 1
NeedToKnow_ExecutiveFrame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
else
m_last_cast_head = found+1
NeedToKnow.last_cast_head = found+1
end
end
end
470,10 → 441,10
NeedToKnow_Visible = true
end
 
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.last_cast = {} -- [n] = { spell, target, serial }
NeedToKnow.last_cast_head = 1
NeedToKnow.last_cast_tail = 1
NeedToKnow.last_guid = {} -- [spell][guidTarget] = { time, dur, expiry }
NeedToKnow.totem_drops = {} -- array 1-4 of precise times the totems appeared
NeedToKnow.weapon_enchants = { mhand = {}, ohand = {} }
 
552,7 → 523,7
 
function NeedToKnow.ExecutiveFrame_PLAYER_TALENT_UPDATE()
if NeedToKnow.CharSettings then
local spec = g_GetActiveTalentGroup()
local spec = GetActiveTalentGroup()
 
local profile_key = NeedToKnow.CharSettings.Specs[spec]
if not profile_key then
566,12 → 537,12
 
 
function NeedToKnow.ExecutiveFrame_UNIT_TARGET(unitTargeting)
if m_bInCombat and not m_bCombatWithBoss then
if NeedToKnow.bInCombat and not NeedToKnow.bCombatWithBoss then
if UnitLevel(unitTargeting .. 'target') == -1 then
m_bCombatWithBoss = true
NeedToKnow.bCombatWithBoss = true
if NeedToKnow.BossStateBars then
for bar, unused in pairs(NeedToKnow.BossStateBars) do
mfn_Bar_AuraCheck(bar)
NeedToKnow.Bar_AuraCheck(bar)
end
end
end
625,39 → 596,39
 
 
function NeedToKnow.ExecutiveFrame_PLAYER_REGEN_DISABLED(unitTargeting)
m_bInCombat = true
m_bCombatWithBoss = false
NeedToKnow.bInCombat = true
NeedToKnow.bCombatWithBoss = false
if IsInRaid() then
for i = 1, 40 do
if UnitLevel("raid"..i.."target") == -1 then
m_bCombatWithBoss = true;
NeedToKnow.bCombatWithBoss = true;
break;
end
end
elseif IsInGroup() then
for i = 1, 5 do
if UnitLevel("party"..i.."target") == -1 then
m_bCombatWithBoss = true;
NeedToKnow.bCombatWithBoss = true;
break;
end
end
elseif UnitLevel("target") == -1 then
m_bCombatWithBoss = true
NeedToKnow.bCombatWithBoss = true
end
if NeedToKnow.BossStateBars then
for bar, unused in pairs(NeedToKnow.BossStateBars) do
mfn_Bar_AuraCheck(bar)
NeedToKnow.Bar_AuraCheck(bar)
end
end
end
 
 
function NeedToKnow.ExecutiveFrame_PLAYER_REGEN_ENABLED(unitTargeting)
m_bInCombat = false
m_bCombatWithBoss = false
NeedToKnow.bInCombat = false
NeedToKnow.bCombatWithBoss = false
if NeedToKnow.BossStateBars then
for bar, unused in pairs(NeedToKnow.BossStateBars) do
mfn_Bar_AuraCheck(bar)
NeedToKnow.Bar_AuraCheck(bar)
end
end
end
782,7 → 753,7
 
-- Switch to the new profile
NeedToKnow.ProfileSettings = NeedToKnow_Profiles[profile_key]
local spec = g_GetActiveTalentGroup()
local spec = GetActiveTalentGroup()
NeedToKnow.CharSettings.Specs[spec] = profile_key
 
-- fill in any missing defaults
820,7 → 791,7
end
 
 
mfn_SetStatusBarValue = function (bar,texture,value,value0)
local function SetStatusBarValue(bar,texture,value,value0)
local pct0 = 0
if value0 then
pct0 = value0 / bar.max_value
1218,10 → 1189,10
local idx = entry.idxName
if not id then
if ( name == "Auto Shot" or
name == c_AUTO_SHOT_NAME )
name == NEEDTOKNOW.AUTO_SHOT )
then
bar.settings.bAutoShot = true
bar.cd_functions[idx] = mfn_GetAutoShotCooldown
bar.cd_functions[idx] = NeedToKnow.GetAutoShotCooldown
else
local item_id = NeedToKnow.GetItemIDString(name)
if item_id then
1234,11 → 1205,11
if nil ~= betterSpell then
entry.id = betterSpell
entry.name = nil
bar.cd_functions[idx] = mfn_GetSpellCooldown
bar.cd_functions[idx] = NeedToKnow.GetSpellCooldown
elseif not GetSpellCooldown(name) then
bar.cd_functions[idx] = mfn_GetUnresolvedCooldown
bar.cd_functions[idx] = NeedToKnow.GetUnresolvedCooldown
else
bar.cd_functions[idx] = mfn_GetSpellCooldown
bar.cd_functions[idx] = NeedToKnow.GetSpellCooldown
end
end
end
1290,7 → 1261,7
 
bar.settings = barSettings
bar.unit = barSettings.Unit
bar.nextUpdate = g_GetTime() + c_UPDATE_INTERVAL
bar.nextUpdate = GetTime() + NEEDTOKNOW.UPDATE_INTERVAL
 
bar.fixedDuration = tonumber(groupSettings.FixedDuration)
if ( not bar.fixedDuration or 0 >= bar.fixedDuration ) then
1298,7 → 1269,7
end
 
bar.max_value = 1
mfn_SetStatusBarValue(bar,bar.bar1,1)
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"]))
1400,25 → 1371,25
 
-- Determine which helper functions to use
if "BUFFCD" == barSettings.BuffOrDebuff then
bar.fnCheck = mfn_AuraCheck_BUFFCD
bar.fnCheck = NeedToKnow.AuraCheck_BUFFCD
elseif "TOTEM" == barSettings.BuffOrDebuff then
bar.fnCheck = mfn_AuraCheck_TOTEM
bar.fnCheck = NeedToKnow.AuraCheck_TOTEM
elseif "USABLE" == barSettings.BuffOrDebuff then
bar.fnCheck = mfn_AuraCheck_USABLE
bar.fnCheck = NeedToKnow.AuraCheck_USABLE
elseif "EQUIPSLOT" == barSettings.BuffOrDebuff then
bar.fnCheck = mfn_AuraCheck_EQUIPSLOT
bar.fnCheck = NeedToKnow.AuraCheck_EQUIPSLOT
elseif "CASTCD" == barSettings.BuffOrDebuff then
bar.fnCheck = mfn_AuraCheck_CASTCD
bar.fnCheck = NeedToKnow.AuraCheck_CASTCD
for idx, entry in ipairs(bar.spells) do
table.insert(bar.cd_functions, mfn_GetSpellCooldown)
table.insert(bar.cd_functions, NeedToKnow.GetSpellCooldown)
NeedToKnow.SetupSpellCooldown(bar, entry)
end
elseif "mhand" == barSettings.Unit or "ohand" == barSettings.Unit then
bar.fnCheck = mfn_AuraCheck_Weapon
bar.fnCheck = NeedToKnow.AuraCheck_Weapon
elseif barSettings.show_all_stacks then
bar.fnCheck = mfn_AuraCheck_AllStacks
bar.fnCheck = NeedToKnow.AuraCheck_AllStacks
else
bar.fnCheck = mfn_AuraCheck_Single
bar.fnCheck = NeedToKnow.AuraCheck_Single
end
 
if ( barSettings.BuffOrDebuff == "BUFFCD" ) then
1431,7 → 1402,7
 
NeedToKnow.SetScripts(bar)
-- Events were cleared while unlocked, so need to check the bar again now
mfn_Bar_AuraCheck(bar)
NeedToKnow.Bar_AuraCheck(bar)
else
NeedToKnow.ClearScripts(bar)
bar:Hide()
1556,9 → 1527,9
spellName = entry.name
end
if spellName then
local r = m_last_guid[spellName]
local r = NeedToKnow.last_guid[spellName]
if not r then
m_last_guid[spellName] = { time=0, dur=0, expiry=0 }
NeedToKnow.last_guid[spellName] = { time=0, dur=0, expiry=0 }
end
else
print("Warning! NTK could not get name for ", entry.id)
1611,28 → 1582,28
end
 
function NeedToKnow.Bar_OnSizeChanged(self)
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
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
end
 
function NeedToKnow.Bar_OnEvent(self, event, unit, ...)
if ( event == "COMBAT_LOG_EVENT_UNFILTERED") then
local combatEvent = select(1, ...)
 
if ( c_AURAEVENTS[combatEvent] ) then
if ( NEEDTOKNOW.AURAEVENTS[combatEvent] ) then
local guidTarget = select(7, ...)
if ( guidTarget == g_UnitGUID(self.unit) ) then
if ( guidTarget == UnitGUID(self.unit) ) then
local idSpell, nameSpell = select(11, ...)
if (self.auraName:find(idSpell) or
self.auraName:find(nameSpell))
then
mfn_Bar_AuraCheck(self)
NeedToKnow.Bar_AuraCheck(self)
end
end
elseif ( combatEvent == "UNIT_DIED" ) then
local guidDeceased = select(7, ...)
if ( guidDeceased == UnitGUID(self.unit) ) then
mfn_Bar_AuraCheck(self)
NeedToKnow.Bar_AuraCheck(self)
end
end
elseif ( event == "PLAYER_TOTEM_UPDATE" ) or
1640,24 → 1611,24
( event == "SPELL_UPDATE_COOLDOWN" ) or
( event == "SPELL_UPDATE_USABLE" )
then
mfn_Bar_AuraCheck(self)
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "UNIT_AURA" ) and ( unit == self.unit ) then
mfn_Bar_AuraCheck(self)
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "UNIT_INVENTORY_CHANGED" and unit == "player" ) then
NeedToKnow.UpdateWeaponEnchants()
mfn_Bar_AuraCheck(self)
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "PLAYER_TARGET_CHANGED" ) or ( event == "PLAYER_FOCUS_CHANGED" ) then
if self.unit == "targettarget" then
NeedToKnow.CheckCombatLogRegistration(self)
end
mfn_Bar_AuraCheck(self)
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "UNIT_TARGET" and unit == "target" ) then
if self.unit == "targettarget" then
NeedToKnow.CheckCombatLogRegistration(self)
end
mfn_Bar_AuraCheck(self)
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "UNIT_PET" and unit == "player" ) then
mfn_Bar_AuraCheck(self)
NeedToKnow.Bar_AuraCheck(self)
elseif ( event == "PLAYER_SPELLCAST_SUCCEEDED" ) then
local spellName, spellID, tgt = select(1,...)
local i,entry
1665,7 → 1636,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)
mfn_Bar_AuraCheck(self)
NeedToKnow.Bar_AuraCheck(self)
break;
end
end
1675,11 → 1646,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 == c_AUTO_SHOT_NAME ) then
if ( self.settings.bAutoShot and unit == "player" and spell == NEEDTOKNOW.AUTO_SHOT ) then
local interval = UnitRangedDamage("player")
self.tAutoShotCD = interval
self.tAutoShotStart = g_GetTime()
mfn_Bar_AuraCheck(self)
self.tAutoShotStart = GetTime()
NeedToKnow.Bar_AuraCheck(self)
end
end
end
1711,7 → 1682,7
return text
end
 
-- Called by mfn_UpdateVCT, which is called from AuraCheck and possibly
-- Called by NeedToKnow.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)
1736,7 → 1707,7
return vct_duration
end
 
mfn_UpdateVCT = function (bar)
function NeedToKnow.UpdateVCT(bar)
local vct_duration = NeedToKnow.ComputeVCTDuration(bar)
 
local dur = bar.fixedDuration or bar.duration
1860,13 → 1831,13
 
-- Determine the size of the visual cast bar
if ( bar.settings.vct_enabled ) then
mfn_UpdateVCT(bar)
NeedToKnow.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 = -c_UPDATE_INTERVAL
if bar.expirationTime > g_GetTime() then
bar.nextUpdate = -NEEDTOKNOW.UPDATE_INTERVAL
if bar.expirationTime > GetTime() then
NeedToKnow.Bar_OnUpdate(bar, 0)
end
 
1874,8 → 1845,8
else
-- Hide the time text and spark for auras with "infinite" duration
bar.max_value = 1
mfn_SetStatusBarValue(bar,bar.bar1,1)
if bar.bar2 then mfn_SetStatusBarValue(bar,bar.bar2,1) end
SetStatusBarValue(bar,bar.bar1,1)
if bar.bar2 then SetStatusBarValue(bar,bar.bar2,1) end
 
bar.time:Hide()
bar.spark:Hide()
1898,7 → 1869,7
bar.time:Hide()
bar.spark:Hide()
bar.max_value = 1
mfn_SetStatusBarValue(bar,bar.bar1,1)
SetStatusBarValue(bar,bar.bar1,1)
 
if ( bar.icon ) then
bar.icon:Hide()
2061,23 → 2032,23
end
 
 
-- Helper for mfn_AuraCheck_CASTCD which gets the autoshot cooldown
mfn_GetAutoShotCooldown = function(bar)
local tNow = g_GetTime()
-- Helper for NeedToKnow.AuraCheck_CASTCD which gets the autoshot cooldown
function NeedToKnow.GetAutoShotCooldown(bar)
local tNow = GetTime()
if ( bar.tAutoShotStart and bar.tAutoShotStart + bar.tAutoShotCD > tNow ) then
local n, icon = GetSpellInfo(75)
return bar.tAutoShotStart, bar.tAutoShotCD, 1, c_AUTO_SHOT_NAME, icon
return bar.tAutoShotStart, bar.tAutoShotCD, 1, NEEDTOKNOW.AUTO_SHOT, icon
else
bar.tAutoShotStart = nil
end
end
 
 
-- Helper for mfn_AuraCheck_CASTCD for names we haven't figured out yet
mfn_GetUnresolvedCooldown = function(bar, entry)
-- Helper for NeedToKnow.AuraCheck_CASTCD for names we haven't figured out yet
function NeedToKnow.GetUnresolvedCooldown(bar, entry)
NeedToKnow.SetupSpellCooldown(bar, entry)
local fn = bar.cd_functions[entry.idxName]
if mfn_GetUnresolvedCooldown ~= fn then
if NeedToKnow.GetUnresolvedCooldown ~= fn then
return fn(bar, entry)
end
end
2085,7 → 2056,7
 
-- Wrapper around GetSpellCooldown with extra sauce
-- Expected to return start, cd_len, enable, buffName, iconpath
mfn_GetSpellCooldown = function(bar, entry)
function NeedToKnow.GetSpellCooldown(bar, entry)
local barSpell = entry.id or entry.name
local start, cd_len, enable = GetSpellCooldown(barSpell)
if start and start > 0 then
2107,12 → 2078,12
elseif spellPower == 5 then -- Rune
-- Filter out rune cooldown artificially extending the cd
if cd_len <= 10 then
local tNow = g_GetTime()
local tNow = 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 m_last_sent and m_last_sent[spellName] and m_last_sent[spellName] > (tNow - 1.5) then
elseif NeedToKnow.last_sent and NeedToKnow.last_sent[spellName] and NeedToKnow.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
2153,7 → 2124,7
data.icon = nil
--trace("Warning: NTK couldn't figure out what enchant is on weapon slot",slot)
end
data.expiration = g_GetTime() + data.expiration/1000
data.expiration = GetTime() + data.expiration/1000
if oldname ~= data.name then
local _
_,_,data.icon = GetSpellInfo(data.name)
2179,7 → 2150,7
 
mdata.present, mdata.expiration, mdata.charges,
odata.present, odata.expiration, odata.charges
= g_GetWeaponEnchantInfo()
= GetWeaponEnchantInfo()
 
if ( mdata.present ) then
NeedToKnow.UpdateWeaponEnchantData(mdata, 16)
2195,7 → 2166,7
end
 
 
mfn_AddInstanceToStacks = function (all_stacks, bar_entry, duration, name, count, expirationTime, iconPath, caster, tt1, tt2, tt3)
local function AddInstanceToStacks(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
2226,27 → 2197,27
 
-- Bar_AuraCheck helper for Totem bars, this returns data if
-- a totem matching bar_entry is currently out.
mfn_AuraCheck_TOTEM = function(bar, bar_entry, all_stacks)
function NeedToKnow.AuraCheck_TOTEM(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 g_GetTime
-- that the totem actually appeared, so long as g_GetTime is reasonably close to
-- 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
-- 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 = g_GetTime()
local precise = GetTime()
if ( precise - startTime > 1 ) then
precise = startTime + 1
end
NeedToKnow.totem_drops[iSlot] = precise
end
 
mfn_AddInstanceToStacks(all_stacks, bar_entry,
AddInstanceToStacks(all_stacks, bar_entry,
totemDuration, -- duration
totemName, -- name
1, -- count
2262,17 → 2233,17
 
-- Bar_AuraCheck helper for tracking usable gear based on the slot its in
-- rather than the equipment name
mfn_AuraCheck_EQUIPSLOT = function (bar, bar_entry, all_stacks)
function NeedToKnow.AuraCheck_EQUIPSLOT(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 = m_scratch.bar_entry
local item_entry = NeedToKnow.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
mfn_AddInstanceToStacks(all_stacks, bar_entry,
AddInstanceToStacks(all_stacks, bar_entry,
cd_len, -- duration
name, -- name
1, -- count
2289,10 → 2260,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.
mfn_AuraCheck_Weapon = function (bar, bar_entry, all_stacks)
function NeedToKnow.AuraCheck_Weapon(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
mfn_AddInstanceToStacks( all_stacks, bar_entry,
AddInstanceToStacks( all_stacks, bar_entry,
1800, -- duration TODO: Get real duration?
data.name, -- name
data.charges, -- count
2304,10 → 2275,10
 
 
-- Bar_AuraCheck helper that checks for spell/item use cooldowns
-- Relies on mfn_GetAutoShotCooldown, mfn_GetSpellCooldown
-- Relies on NeedToKnow.GetAutoShotCooldown, NeedToKnow.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
mfn_AuraCheck_CASTCD = function(bar, bar_entry, all_stacks)
function NeedToKnow.AuraCheck_CASTCD(bar, bar_entry, all_stacks)
local idxName = bar_entry.idxName
local func = bar.cd_functions[idxName]
if ( not func ) then
2317,7 → 2288,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 ~= mfn_GetAutoShotCooldown then
if start and cd_len <= 1.5 and func ~= NeedToKnow.GetAutoShotCooldown then
if bar.expirationTime and bar.expirationTime <= (start + cd_len) then
start = bar.expirationTime - bar.duration
cd_len = bar.duration
2327,10 → 2298,10
end
 
if start and cd_len then
local tNow = g_GetTime()
local tNow = GetTime()
local tEnd = start + cd_len
if ( tEnd > tNow + 0.1 ) then
mfn_AddInstanceToStacks( all_stacks, bar_entry,
AddInstanceToStacks( all_stacks, bar_entry,
cd_len, -- duration
buffName, -- name
1, -- count
2344,7 → 2315,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
mfn_AuraCheck_USABLE = function (bar, bar_entry, all_stacks)
function NeedToKnow.AuraCheck_USABLE(bar, bar_entry, all_stacks)
local key = bar_entry.id or bar_entry.name
local settings = bar.settings
if ( not key ) then key = "" end
2354,7 → 2325,7
if (isUsable or notEnoughMana) then
local duration = settings.usable_duration
local expirationTime
local tNow = g_GetTime()
local tNow = GetTime()
if ( not bar.expirationTime or
(bar.expirationTime > 0 and bar.expirationTime < tNow - 0.01) )
then
2365,7 → 2336,7
expirationTime = bar.expirationTime
end
 
mfn_AddInstanceToStacks( all_stacks, bar_entry,
AddInstanceToStacks( all_stacks, bar_entry,
duration, -- duration
spellName, -- name
1, -- count
2377,7 → 2348,7
end
 
 
mfn_ResetScratchStacks = function (buff_stacks)
function NeedToKnow.ResetScratchStacks(buff_stacks)
buff_stacks.total = 0;
buff_stacks.total_ttn[1] = 0;
buff_stacks.total_ttn[2] = 0;
2387,20 → 2358,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
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()
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()
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)
mfn_AddInstanceToStacks( all_stacks, bar_entry,
AddInstanceToStacks( all_stacks, bar_entry,
nDur, buff_stacks.min.buffName, 1, nDur+tNow, buff_stacks.min.iconPath, buff_stacks.min.caster )
else
mfn_AddInstanceToStacks( all_stacks, bar_entry,
AddInstanceToStacks( all_stacks, bar_entry,
bar.duration, -- duration
bar.buffName, -- name
1, -- count
2414,7 → 2385,7
local duration = tonumber(bar.settings.buffcd_duration)
local expiration = tStart + duration
if ( expiration > tNow ) then
mfn_AddInstanceToStacks( all_stacks, bar_entry,
AddInstanceToStacks( all_stacks, bar_entry,
duration, -- duration
buff_stacks.min.buffName, -- name
-- Seeing the charges on the CD bar violated least surprise for me
2424,7 → 2395,7
buff_stacks.min.caster ) -- caster
end
elseif ( bar.expirationTime and bar.expirationTime > tNow + 0.1 ) then
mfn_AddInstanceToStacks( all_stacks, bar_entry,
AddInstanceToStacks( all_stacks, bar_entry,
bar.duration, -- duration
bar.buffName, -- name
1, -- count
2474,7 → 2445,7
 
-- Bar_AuraCheck helper that looks for the first instance of a buff
-- Uses the UnitAura filters exclusively if it can
mfn_AuraCheck_Single = function(bar, bar_entry, all_stacks)
function NeedToKnow.AuraCheck_Single(bar, bar_entry, all_stacks)
local settings = bar.settings
local filter = settings.BuffOrDebuff
if settings.OnlyMine then
2494,7 → 2465,7
end
 
if (spellID == barID) then
mfn_AddInstanceToStacks( all_stacks, bar_entry,
AddInstanceToStacks( all_stacks, bar_entry,
duration, -- duration
buffName, -- name
count, -- count
2509,7 → 2480,7
else
local buffName, iconPath, count, duration, expirationTime, caster, _, tt1, tt2, tt3
= UnitAuraWrapper(bar.unit, bar_entry.name, nil, filter)
mfn_AddInstanceToStacks( all_stacks, bar_entry,
AddInstanceToStacks( all_stacks, bar_entry,
duration, -- duration
buffName, -- name
count, -- count
2523,7 → 2494,7
 
-- Bar_AuraCheck helper that updates bar.all_stacks (but returns nil)
-- by scanning all the auras on the unit
mfn_AuraCheck_AllStacks = function (bar, bar_entry, all_stacks)
function NeedToKnow.AuraCheck_AllStacks(bar, bar_entry, all_stacks)
local j = 1
local settings = bar.settings
local filter = settings.BuffOrDebuff
2537,7 → 2508,7
 
if (spellID == bar_entry.id) or (bar_entry.name == buffName)
then
mfn_AddInstanceToStacks(all_stacks, bar_entry,
AddInstanceToStacks(all_stacks, bar_entry,
duration,
buffName,
count,
2553,8 → 2524,7
 
 
-- Called whenever the state of auras on the bar's unit may have changed
local g_UnitExists = UnitExists
mfn_Bar_AuraCheck = function (bar)
function NeedToKnow.Bar_AuraCheck(bar)
local settings = bar.settings
local bUnitExists, isWeapon
if "mhand" == settings.Unit or
2566,15 → 2536,15
elseif "lastraid" == settings.Unit then
bUnitExists = bar.unit and UnitExists(bar.unit)
else
bUnitExists = g_UnitExists(settings.Unit)
bUnitExists = 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 = m_scratch.all_stacks
mfn_ResetScratchStacks(all_stacks);
all_stacks = NeedToKnow.scratch.all_stacks
NeedToKnow.ResetScratchStacks(all_stacks);
 
-- Call the helper function for each of the spells in the list
for idx, entry in ipairs(bar.spells) do
2601,14 → 2571,14
-- (reset_spells will only be set for BUFFCD)
if ( bar.reset_spells ) then
local maxStart = 0
local tNow = g_GetTime()
local buff_stacks = m_scratch.buff_stacks
mfn_ResetScratchStacks(buff_stacks);
local tNow = GetTime()
local buff_stacks = NeedToKnow.scratch.buff_stacks
NeedToKnow.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
= mfn_AuraCheck_Single(bar, resetSpell, buff_stacks)
= NeedToKnow.AuraCheck_Single(bar, resetSpell, buff_stacks)
local tStart
if buff_stacks.total > 0 then
if 0 == buff_stacks.max.duration then
2639,7 → 2609,7
if (settings.bDetectExtends) then
local curStart = expirationTime - duration
local guidTarget = UnitGUID(bar.unit)
local r = m_last_guid[buffName]
local r = NeedToKnow.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
2689,7 → 2659,7
bar:Show()
else
if (settings.bDetectExtends and bar.buffName) then
local r = m_last_guid[bar.buffName]
local r = NeedToKnow.last_guid[bar.buffName]
if ( r ) then
local guidTarget = UnitGUID(bar.unit)
if guidTarget then
2710,13 → 2680,13
end
end
if ( bBlink and not settings.blink_ooc ) then
if not g_UnitAffectingCombat("player") then
if not UnitAffectingCombat("player") then
bBlink = false
end
end
if ( bBlink and settings.blink_boss ) then
if g_UnitIsFriend(bar.unit, "player") then
bBlink = m_bCombatWithBoss
if UnitIsFriend(bar.unit, "player") then
bBlink = NeedToKnow.bCombatWithBoss
else
bBlink = (UnitLevel(bar.unit) == -1)
end
2753,12 → 2723,12
end
 
function NeedToKnow.Bar_OnUpdate(self, elapsed)
local now = g_GetTime()
local now = GetTime()
if ( now > self.nextUpdate ) then
self.nextUpdate = now + c_UPDATE_INTERVAL
self.nextUpdate = now + NEEDTOKNOW.UPDATE_INTERVAL
 
if ( self.blink ) then
self.blink_phase = self.blink_phase + c_UPDATE_INTERVAL
self.blink_phase = self.blink_phase + NEEDTOKNOW.UPDATE_INTERVAL
if ( self.blink_phase >= 2 ) then
self.blink_phase = 0
end
2777,14 → 2747,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 = g_GetWeaponEnchantInfo()
local mhEnchant, mhExpire = GetWeaponEnchantInfo()
if ( mhExpire ) then
self.expirationTime = g_GetTime() + mhExpire/1000
self.expirationTime = GetTime() + mhExpire/1000
end
elseif ( origUnit == "ohand" ) then
local _, _, _, ohEnchant, ohExpire = g_GetWeaponEnchantInfo()
local _, _, _, ohEnchant, ohExpire = GetWeaponEnchantInfo()
if ( ohExpire ) then
self.expirationTime = g_GetTime() + ohExpire/1000
self.expirationTime = GetTime() + ohExpire/1000
end
end
 
2792,18 → 2762,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 - g_GetTime()
local bar1_timeLeft = self.expirationTime - GetTime()
if ( bar1_timeLeft < 0 ) then
if ( self.settings.BuffOrDebuff == "CASTCD" or
self.settings.BuffOrDebuff == "BUFFCD" or
self.settings.BuffOrDebuff == "EQUIPSLOT" )
then
mfn_Bar_AuraCheck(self)
NeedToKnow.Bar_AuraCheck(self)
return
end
bar1_timeLeft = 0
end
mfn_SetStatusBarValue(self, self.bar1, bar1_timeLeft);
SetStatusBarValue(self, self.bar1, bar1_timeLeft);
if ( self.settings.show_time ) then
local fn = NeedToKnow[self.settings.TimeFormat]
local oldText = self.time:GetText()
2829,12 → 2799,12
end
 
if ( self.max_expirationTime ) then
local bar2_timeLeft = self.max_expirationTime - g_GetTime()
mfn_SetStatusBarValue(self, self.bar2, bar2_timeLeft, bar1_timeLeft)
local bar2_timeLeft = self.max_expirationTime - GetTime()
SetStatusBarValue(self, self.bar2, bar2_timeLeft, bar1_timeLeft)
end
 
if ( self.vct_refresh ) then
mfn_UpdateVCT(self)
NeedToKnow.UpdateVCT(self)
end
end
end