/
end |
end |
function NeedToKnow.ExecutiveFrame_UNIT_SPELLCAST_SUCCEEDED(unit, spell, rank) |
function NeedToKnow.ExecutiveFrame_UNIT_SPELLCAST_SENT(unit, spell, tgt, serialno) |
if unit == "player" then |
local r = NeedToKnow.last_cast[spell] |
if ( r and r.state == 1 ) then |
r.state = 2 |
-- A little extra safety just in case we get two SUCCEEDED entries |
-- before we get the combat log events for them (though I don't |
-- think this is possible.) |
NeedToKnow.last_success = spell |
-- We need the actual target, which we can only get from the combat log. |
-- Thankfully, the combat log event always comes after this one, so we |
-- don't need to register for the combat log for long at all. |
NeedToKnow_ExecutiveFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
-- 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 = {} |
end |
NeedToKnow.last_sent[spell] = GetTime() |
if ( NeedToKnow.nSent > 1 ) then |
NeedToKnow.nSent = NeedToKnow.nSent - 1 |
-- 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 not r then |
r = { spell=spell, target=target, serial=serialno } |
NeedToKnow.last_cast[NeedToKnow.last_cast_tail] = r |
else |
NeedToKnow.nSent = 0 |
r.spell = spell |
r.target = target |
r.serial = serialno |
end |
NeedToKnow.last_cast_tail = NeedToKnow.last_cast_tail + 1 |
if ( NeedToKnow.last_cast_tail == 1 ) then |
NeedToKnow.last_cast_head = 0 |
if ( NeedToKnow.last_guid[spell] ) then |
NeedToKnow_ExecutiveFrame:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED") |
NeedToKnow_ExecutiveFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
else |
NeedToKnow_ExecutiveFrame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") |
end |
end |
end |
end |
end |
function NeedToKnow.ExecutiveFrame_UNIT_SPELLCAST_SUCCEEDED(unit, spell, serialno, spellid) |
if unit == "player" then |
local found |
local t = NeedToKnow.last_cast |
local last = NeedToKnow.last_cast_tail-1 |
local i |
for i = last,NeedToKnow.last_cast_head,-1 do |
if t[i].spell == spell and t[i].serial == serialno then |
found = i |
break |
end |
end |
if found then |
if ( NeedToKnow.BarsForPSS ) then |
local bar,one |
for bar,one in pairs(NeedToKnow.BarsForPSS) do |
NeedToKnow.Bar_OnEvent(bar, "PLAYER_SPELLCAST_SUCCEEDED", spell, spellid, t[i].target); |
end |
end |
if ( found == last ) then |
NeedToKnow.last_cast_tail = 0 |
NeedToKnow.last_cast_head = 0 |
NeedToKnow_ExecutiveFrame:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED") |
else |
NeedToKnow.last_cast_head = found+1 |
end |
end |
end |
-- the time that's passed in appears to be time of day, not game time like everything else. |
local time = GetTime() |
-- TODO: Is checking r.state sufficient or must event be checked instead? |
if ( guidCaster == NeedToKnow.guidPlayer ) then |
local guidTarget, _, _, _, _, spell = select(4, ...) |
local r = NeedToKnow.last_cast[spell] |
if ( r and r.state == 2) then |
r.state = 0 |
-- record this spellcast |
if ( not r[guidTarget] ) then |
r[guidTarget] = { time = time, dur = 0 } |
else |
r[guidTarget].time = time |
r[guidTarget].dur = 0 |
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 i |
for i = last,NeedToKnow.last_cast_head,-1 do |
if t[i].spell == spell then |
found = i |
break |
end |
-- Use this event to expire some targets. This should limit us to |
-- two combats' worth of targets (since GC doesn't happen in combat) |
for kG, vG in pairs(r) do |
if ( type(vG) == "table" and ( vG.time + 300 < time ) ) then |
r[kG] = nil |
end |
if found then |
if ( NeedToKnow.BarsForPSS ) then |
local bar,one |
for bar,one in pairs(NeedToKnow.BarsForPSS) do |
NeedToKnow.Bar_OnEvent(bar, "PLAYER_SPELLCAST_SUCCEEDED", spell, spellid, t[i].target); |
end |
end |
end |
if ( spell == NeedToKnow.last_success ) then |
-- We saw our spell, we can disconnect from the spam hose |
NeedToKnow_ExecutiveFrame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
local rBySpell = NeedToKnow.last_guid[spell] |
if ( rBySpell ) then |
local rByGuid = rBySpell[guidTarget] |
if not rByGuid then |
rByGuid = { time=time, dur=0, expiry=0 } |
rBySpell[guidTarget] = rByGuid |
else |
rByGuid.time= time |
rByGuid.dur = 0 |
rByGuid.expiry = 0 |
end |
end |
if ( found == last ) then |
NeedToKnow.last_cast_tail = 0 |
NeedToKnow.last_cast_head = 0 |
NeedToKnow_ExecutiveFrame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
else |
NeedToKnow.last_cast_head = found+1 |
end |
end |
end |
end |
NeedToKnow_Visible = true |
end |
NeedToKnow.last_cast = {} -- [spell][guidTarget] = { time, dur } |
NeedToKnow.nSent = 0 |
NeedToKnow.last_cast = {} -- [n] = { spell, target, serial } |
NeedToKnow.last_cast_head = 0 |
NeedToKnow.last_cast_tail = 0 |
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 = {} } |
NeedToKnow_ExecutiveFrame:RegisterEvent("PLAYER_REGEN_DISABLED") |
NeedToKnow_ExecutiveFrame:RegisterEvent("PLAYER_REGEN_ENABLED") |
if ( NeedToKnow.is_DK ) then |
NeedToKnow_ExecutiveFrame:RegisterEvent("UNIT_SPELLCAST_SENT") |
NeedToKnow.RegisterSpellcastSent(); |
end |
NeedToKnow.Update() |
NeedToKnow.UpdateWeaponEnchants() |
end |
function NeedToKnow.RegisterSpellcastSent() |
if ( NeedToKnow.nRegisteredSent ) then |
NeedToKnow.nRegisteredSent = NeedToKnow.nRegisteredSent + 1 |
else |
NeedToKnow.nRegisteredSent = 1 |
NeedToKnow_ExecutiveFrame:RegisterEvent("UNIT_SPELLCAST_SENT") |
end |
end |
function NeedToKnow.UnregisterSpellcastSent() |
if ( NeedToKnow.nRegisteredSent ) then |
NeedToKnow.nRegisteredSent = NeedToKnow.nRegisteredSent - 1 |
if ( 0 == NeedToKnow.nRegisteredSent ) then |
NeedToKnow.nRegisteredSent = nil |
NeedToKnow_ExecutiveFrame:UnregisterEvent("UNIT_SPELLCAST_SENT") |
NeedToKnow_ExecutiveFrame:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED") |
NeedToKnow_ExecutiveFrame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
end |
end |
end |
function NeedToKnow.ExecutiveFrame_ACTIVE_TALENT_GROUP_CHANGED() |
-- This is the only event we're guaranteed to get on a talent switch, |
-- so we have to listen for it. However, the client may not yet have |
end |
function NeedToKnow.ExecutiveFrame_UNIT_SPELLCAST_SENT(unit, spell) |
if NeedToKnow.is_DK then |
-- TODO: I hate that DKs have to pay this memory cost for every "spell" they 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 a 100 spells. |
if unit == "player" then |
if not NeedToKnow.last_sent then |
NeedToKnow.last_sent = {} |
end |
NeedToKnow.last_sent[spell] = GetTime() |
end |
end |
end |
function NeedToKnow.RemoveDefaultValues(t, def, k) |
if not k then k = "" end |
if def == nil then |
bar:RegisterEvent("UNIT_PET") |
end |
end |
if bar.settings.bDetectExtends then |
bar:RegisterEvent("UNIT_SPELLCAST_SENT") |
local idx,barSpell |
for idx, barSpell in ipairs(bar.spells) do |
local _, nDigits = barSpell:find("^%d+") |
local spell |
if ( nDigits == barSpell:len() ) then |
spell = GetSpellInfo(to_number(barSpell)) |
else |
spell = barSpell |
end |
if spell then |
local r = NeedToKnow.last_guid[spell] |
if not r then |
NeedToKnow.last_guid[spell] = { time=0, dur=0, expiry=0 } |
end |
else |
print("Warning! NTK could not get name for ", barSpell) |
end |
end |
NeedToKnow.RegisterSpellcastSent() |
end |
if bar.settings.blink_enabled and bar.settings.blink_boss then |
if not NeedToKnow.BossStateBars then |
bar:UnregisterEvent("UNIT_AURA") |
bar:UnregisterEvent("UNIT_INVENTORY_CHANGED") |
bar:UnregisterEvent("UNIT_TARGET") |
bar:UnregisterEvent("UNIT_SPELLCAST_SENT") |
bar:UnregisterEvent("START_AUTOREPEAT_SPELL") |
bar:UnregisterEvent("STOP_AUTOREPEAT_SPELL") |
bar:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED") |
if NeedToKnow.BossStateBars then |
NeedToKnow.BossStateBars[bar] = nil; |
end |
if bar.settings.bDetectExtends then |
NeedToKnow.UnregisterSpellcastSent() |
end |
if NeedToKnow.BarsForPSS and NeedToKnow.BarsForPSS[bar] then |
NeedToKnow.BarsForPSS[bar] = nil |
if nil == next(NeedToKnow.BarsForPSS) then |
NeedToKnow.BarsForPSS = nil |
NeedToKnow.UnregisterSpellcastSent(); |
end |
end |
end |
function NeedToKnow.Bar_OnMouseUp(self, button) |
NeedToKnow.Bar_AuraCheck(self) |
elseif ( event == "UNIT_PET" and unit == "player" ) then |
NeedToKnow.Bar_AuraCheck(self) |
elseif ( event == "UNIT_SPELLCAST_SENT" ) then |
local spell = select(1, ...) |
if ( self.settings.bDetectExtends ) then |
-- FIXME: This really does not belong on the individual bar |
if unit == "player" then --and self.buffName == spell then |
local r = NeedToKnow.last_cast[spell] |
if ( r and r.state == 0 ) then |
r.state = 1 |
NeedToKnow.nSent = NeedToKnow.nSent + 1 |
NeedToKnow_ExecutiveFrame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") |
end |
end |
end |
--elseif ( event == "PLAYER_SPELLCAST_SENT" ) then |
--if ( self.settings.Unit == "lastcast" ) then |
-- |
--end |
elseif ( event == "START_AUTOREPEAT_SPELL" ) then |
self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") |
elseif ( event == "STOP_AUTOREPEAT_SPELL" ) then |
if (settings.bDetectExtends) then |
local curStart = expirationTime - duration |
local guidTarget = UnitGUID(bar.unit) |
if ( not NeedToKnow.last_cast[buffName] ) then |
NeedToKnow.last_cast[buffName] = { state=0 } |
end |
local r = NeedToKnow.last_cast[buffName] |
local r = NeedToKnow.last_guid[buffName] |
if ( not r[guidTarget] ) then |
r[guidTarget] = { time=curStart, dur=duration } |
elseif ( r[guidTarget].dur == 0 ) then |
r[guidTarget].dur = duration |
if ( not r[guidTarget] ) then -- Should only happen from /reload or /ntk while the aura is active |
trace("WARNING! allocating guid slot for ", buffName, "on", guidTarget, "due to UNIT_AURA"); |
r[guidTarget] = { time=curStart, dur=duration, expiry=expirationTime } |
else |
local rStart = r[guidTarget] |
extended = expirationTime - rStart.time - rStart.dur |
if ( extended > 1 ) then |
duration = rStart.dur |
r = r[guidTarget] |
local oldExpiry = r.expiry |
if ( oldExpiry > 0 and oldExpiry < curStart ) then |
trace("WARNING! stale entry for ",buffName,"on",guidTarget,curStart-r.time,curStart-oldExpiry) |
end |
if ( oldExpiry < curStart ) then |
r.time = curStart |
r.dur = duration |
r.expiry= expirationTime |
else |
r.expiry= expirationTime |
extended = expirationTime - (r.time + r.dur) |
if ( extended > 1 ) then |
duration = r.dur |
else |
extended = nil |
end |
end |
end |
end |
bar:Show() |
else |
if (settings.bDetectExtends and bar.buffName) then |
if ( NeedToKnow.last_cast[bar.buffName] ) then |
local r = NeedToKnow.last_guid[bar.buffName] |
if ( r ) then |
local guidTarget = UnitGUID(bar.unit) |
if guidTarget then |
local r = NeedToKnow.last_cast[bar.buffName] |
r[guidTarget] = nil |
end |
end |