/branches
NEEDTOKNOW.BARMENU_CASTCD = "Spell Cooldown"; |
NEEDTOKNOW.BARMENU_BUFFCD = "Internal Cooldown"; |
NEEDTOKNOW.BARMENU_USABLE = "Spell Usable"; |
NEEDTOKNOW.BARMENU_EQUIPSLOT = "Equipment Slot"; |
NEEDTOKNOW.CMD_HIDE = "hide"; |
NEEDTOKNOW.CMD_PROFILE = "profile"; |
NEEDTOKNOW.CMD_SHOW = "show"; |
{ Setting = "CASTCD", MenuText = NEEDTOKNOW.BARMENU_CASTCD }, |
{ Setting = "BUFFCD", MenuText = NEEDTOKNOW.BARMENU_BUFFCD }, |
{ Setting = "USABLE", MenuText = NEEDTOKNOW.BARMENU_USABLE }, |
{ Setting = "EQUIPSLOT", MenuText = NEEDTOKNOW.BARMENU_EQUIPSLOT }, |
}, |
TimeFormat = { |
{ Setting = "Fmt_SingleUnit", MenuText = NEEDTOKNOW.FMT_SINGLEUNIT }, |
{ VariableName = "usable_duration", MenuText = "Usable duration...", Type = "Dialog", DialogText = "USABLE_DURATION_DIALOG", Numeric=true }, |
{ VariableName = "append_usable", MenuText = "Append \"Usable\"" }, -- FIXME: Localization |
}, |
--EquipmentSlotList = |
--{ |
--{ VariableName = "AuraName", Setting = "1", MenuText = "Head" }, |
--{ VariableName = "AuraName", Setting = "2", MenuText = "Neck" }, |
--{ VariableName = "AuraName", Setting = "3", MenuText = "Shoulder" }, |
--{ VariableName = "AuraName", Setting = "4", MenuText = "Shirt" }, |
--{ VariableName = "AuraName", Setting = "5", MenuText = "Chest" }, |
--{ VariableName = "AuraName", Setting = "6", MenuText = "Belt" }, |
--{ VariableName = "AuraName", Setting = "7", MenuText = "Legs" }, |
--{ VariableName = "AuraName", Setting = "8", MenuText = "Feet" }, |
--{ VariableName = "AuraName", Setting = "9", MenuText = "Wrist" }, |
--{ VariableName = "AuraName", Setting = "10", MenuText = "Gloves" }, |
--{ VariableName = "AuraName", Setting = "11", MenuText = "Ring1" }, |
--{ VariableName = "AuraName", Setting = "12", MenuText = "Ring2" }, |
--{ VariableName = "AuraName", Setting = "13", MenuText = "Trinket1" }, |
--{ VariableName = "AuraName", Setting = "14", MenuText = "Trinket2" }, |
--{ VariableName = "AuraName", Setting = "15", MenuText = "Back" }, |
--{ VariableName = "AuraName", Setting = "16", MenuText = "Main Hand" }, |
--{ VariableName = "AuraName", Setting = "17", MenuText = "Off Hand" }, |
--{ VariableName = "AuraName", Setting = "18", MenuText = "Ranged/Relic" }, |
--{ VariableName = "AuraName", Setting = "19", MenuText = "Tabard" }, |
--}, |
VisualCastTime = { |
{ VariableName = "vct_enabled", MenuText = NEEDTOKNOW.BARMENU_VCT_ENABLE }, |
{ VariableName = "vct_color", MenuText = NEEDTOKNOW.BARMENU_VCT_COLOR, Type = "Color" }, |
local item_type = i_desc["Type"]; |
info.text = i_desc["MenuText"]; |
info.value = i_desc["VariableName"]; |
if ( nil == info.value and nil ~= i_desc["Setting"]) then |
info.value = i_parent; |
if ( nil ~= i_desc["Setting"]) then |
if ( nil == info.value ) then |
info.value = i_parent; |
end |
item_type = "SetVar"; |
end; |
<Layer level="OVERLAY"> |
<FontString name="$parentText" inherits="GameFontHighlight" justifyH="LEFT"> |
<Size> |
<AbsDimension x="180" y="16"/> |
<AbsDimension x="160" y="16"/> |
</Size> |
<Anchors> |
<Anchor point="LEFT"> |
</FontString> |
<FontString name="$parentTime" inherits="GameFontHighlight" justifyH="RIGHT"> |
<Size> |
<AbsDimension x="40" y="16"/> |
<AbsDimension x="60" y="16"/> |
</Size> |
<Anchors> |
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT"> |
NeedToKnow = {} |
NeedToKnowLoader = {} |
NeedToKnow.scratch = {} |
NeedToKnow.scratch.all_stacks = |
{ |
min = |
{ |
buffName = "", |
duration = 0, |
expirationTime = 0, |
iconPath = "", |
caster = "" |
}, |
max = |
{ |
duration = 0, |
expirationTime = 0, |
}, |
total = 0 |
} |
NeedToKnow.scratch.buff_stacks = |
{ |
min = |
{ |
buffName = "", |
duration = 0, |
expirationTime = 0, |
iconPath = "", |
caster = "" |
}, |
max = |
{ |
duration = 0, |
expirationTime = 0, |
}, |
total = 0 |
} |
NeedToKnow.scratch.bar_entry = |
{ |
idxName = 0, |
barSpell = "", |
isSpellID = false, |
} |
-- NEEDTOKNOW = {} is defined in the localization file, which must be loaded before this file |
NEEDTOKNOW.VERSION = "3.3.00" |
if player_CLASS == "DEATHKNIGHT" then |
NeedToKnow.is_DK = 1 |
end |
if player_CLASS == "DRUID" then |
NeedToKnow.is_Druid = 1 |
end |
NeedToKnow_ExecutiveFrame:RegisterEvent("PLAYER_TALENT_UPDATE") |
NeedToKnow_ExecutiveFrame:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED") |
if ( barSettings.BuffOrDebuff == "BUFFCD" or |
barSettings.BuffOrDebuff == "TOTEM" or |
barSettings.BuffOrDebuff == "USABLE" or |
barSettings.BuffOrDebuff == "EQUIPSLOT" or |
barSettings.BuffOrDebuff == "CASTCD") |
then |
barSettings.Unit = "player" |
bar.nextUpdate = GetTime() + NEEDTOKNOW.UPDATE_INTERVAL |
bar.fixedDuration = tonumber(groupSettings.FixedDuration) |
if ( 0 >= bar.fixedDuration ) then |
if ( not bar.fixedDuration or 0 >= bar.fixedDuration ) then |
bar.fixedDuration = nil |
end |
bar.fnCheck = NeedToKnow.AuraCheck_TOTEM |
elseif "USABLE" == barSettings.BuffOrDebuff then |
bar.fnCheck = NeedToKnow.AuraCheck_USABLE |
elseif "EQUIPSLOT" == barSettings.BuffOrDebuff then |
bar.fnCheck = NeedToKnow.AuraCheck_EQUIPSLOT |
elseif "CASTCD" == barSettings.BuffOrDebuff then |
bar.fnCheck = NeedToKnow.AuraCheck_CASTCD |
for idx, barSpell in ipairs(bar.spells) do |
end |
bar:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN") |
bar:RegisterEvent("SPELL_UPDATE_COOLDOWN") |
elseif ( "EQUIPSLOT" == bar.settings.BuffOrDebuff ) then |
bar:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN") |
elseif ( "USABLE" == bar.settings.BuffOrDebuff ) then |
bar:RegisterEvent("SPELL_UPDATE_USABLE") |
elseif ( "mhand" == bar.settings.Unit or "ohand" == bar.settings.Unit ) then |
end |
local function AddInstanceToStacks(all_stacks, bar_entry, duration, name, count, expirationTime, iconPath, caster) |
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 |
all_stacks.min.idxName = bar_entry.idxName |
all_stacks.min.buffName = name |
all_stacks.min.caster = caster |
all_stacks.min.duration = duration |
all_stacks.min.expirationTime = expirationTime |
all_stacks.min.iconPath = iconPath |
end |
if ( 0 == all_stacks.total or all_stacks.max.expirationTime < expirationTime ) then |
all_stacks.max.duration = duration |
all_stacks.max.expirationTime = expirationTime |
end |
all_stacks.total = all_stacks.total + count |
end |
end |
-- Bar_AuraCheck helper for Totem bars, this returns data if |
-- a totem matching barSpell is currently out. |
function NeedToKnow.AuraCheck_TOTEM(bar, idxName, barSpell, isSpellID) |
function NeedToKnow.AuraCheck_TOTEM(bar, bar_entry, all_stacks) |
local idxName, barSpell, isSpellID = bar_entry.idxName, bar_entry.barSpell, bar_entry.isSpellID |
local spellName, spellRank, spellIconPath |
if ( isSpellID ) then |
spellName, spellRank, spellIconPath = GetSpellInfo(barSpell) |
NeedToKnow.totem_drops[iSlot] = precise |
end |
return totemDuration, -- duration |
AddInstanceToStacks(all_stacks, bar_entry, |
totemDuration, -- duration |
totemName, -- name |
1, -- count |
NeedToKnow.totem_drops[iSlot] + totemDuration, -- expiration time |
totemIcon, -- icon path |
"player" -- caster |
"player" ) -- caster |
end |
end |
end |
-- 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) |
local idxName, barSpell, isSpellID = bar_entry.idxName, bar_entry.barSpell, bar_entry.isSpellID |
local spellName, spellRank, spellIconPath |
if ( isSpellID ) then |
local slot = tonumber(bar_entry.barSpell) |
local id = GetInventoryItemID("player",slot) |
if id then |
local start, cd_len, enable, name, icon = NeedToKnow.GetItemCooldown(bar, id, idx) |
if ( start and start > 0 ) then |
AddInstanceToStacks(all_stacks, bar_entry, |
cd_len, -- duration |
name, -- name |
1, -- count |
start + cd_len, -- expiration time |
icon, -- icon path |
"player" ) -- caster |
end |
end |
end |
end |
-- 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, idxName, barSpell, isSpellID) |
function NeedToKnow.AuraCheck_Weapon(bar, bar_entry, all_stacks) |
local idxName, barSpell, isSpellID = bar_entry.idxName, bar_entry.barSpell, bar_entry.isSpellID; |
local data = NeedToKnow.weapon_enchants[bar.settings.Unit] |
if ( data.present and data.name and data.name:find(barSpell) ) then |
return 1800, -- duration TODO: Get real duration? |
AddInstanceToStacks( all_stacks, bar_entry, |
1800, -- duration TODO: Get real duration? |
data.name, -- name |
data.charges, -- count |
data.expiration, -- expiration time |
data.icon, -- icon path |
"player" -- caster |
"player" ) -- caster |
end |
end |
-- 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 barSpell |
function NeedToKnow.AuraCheck_CASTCD(bar, idxName, barSpell, isSpellID) |
function NeedToKnow.AuraCheck_CASTCD(bar, bar_entry, all_stacks) |
local idxName, barSpell, isSpellID = bar_entry.idxName, bar_entry.barSpell, bar_entry.isSpellID; |
local func = bar.cd_functions[idxName] |
local start, cd_len, should_cooldown, buffName, iconPath = func(bar, barSpell, idxName) |
local tNow = GetTime() |
local tEnd = start + cd_len |
if ( tEnd > tNow + 0.1 ) then |
return cd_len, -- duration |
AddInstanceToStacks( all_stacks, bar_entry, |
cd_len, -- duration |
buffName, -- name |
1, -- count |
tEnd, -- expiration time |
iconPath, -- icon path |
"player" -- caster |
"player" ) -- caster |
end |
end |
end |
-- 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, idxName, barSpell, isSpellID) |
function NeedToKnow.AuraCheck_USABLE(bar, bar_entry, all_stacks) |
local idxName, barSpell, isSpellID = bar_entry.idxName, bar_entry.barSpell, bar_entry.isSpellID; |
local key |
local settings = bar.settings |
if ( isSpellID ) then key = tonumber(barSpell) else key = barSpell end |
expirationTime = bar.expirationTime |
end |
return duration, -- duration |
AddInstanceToStacks( all_stacks, bar_entry, |
duration, -- duration |
spellName, -- name |
1, -- count |
expirationTime, -- expiration time |
iconPath, -- icon path |
"player" -- caster |
"player" ) -- caster |
end |
end |
end |
-- 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, idxName, barSpell, isSpellID) |
local duration, buffName, _, expiration, iconPath, caster = NeedToKnow.AuraCheck_Single(bar, idxName, barSpell, isSpellID) |
function NeedToKnow.AuraCheck_BUFFCD(bar, bar_entry, all_stacks) |
local idxName, barSpell, isSpellID = bar_entry.idxName, bar_entry.barSpell, bar_entry.isSpellID; |
local buff_stacks = NeedToKnow.scratch.buff_stacks |
buff_stacks.total = 0 |
NeedToKnow.AuraCheck_Single(bar, bar_entry, buff_stacks) |
local tNow = GetTime() |
if ( duration ) then |
if expiration == 0 then |
-- TODO: This really doesn't work very well as a substitute for telling when the aura was appliedS |
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) |
return nDur, buffName, 1, nDur+tNow, iconPath, caster |
AddInstanceToStacks( all_stacks, bar_entry, |
nDur, buff_stacks.min.buffName, 1, nDur+tNow, buff_stacks.min.iconPath, buff_stacks.min.caster ) |
else |
return bar.duration, -- duration |
AddInstanceToStacks( all_stacks, bar_entry, |
bar.duration, -- duration |
bar.buffName, -- name |
1, -- count |
bar.expirationTime, -- expiration time |
bar.iconPath, -- icon path |
"player" -- caster |
end |
"player" ) -- caster |
end |
return |
end |
local tStart = expiration - duration |
duration = tonumber(bar.settings.buffcd_duration) |
expiration = tStart + duration |
local tStart = buff_stacks.max.expirationTime - buff_stacks.max.duration |
local duration = tonumber(bar.settings.buffcd_duration) |
local expiration = tStart + duration |
if ( expiration > tNow ) then |
return duration, -- duration |
buffName, -- name |
AddInstanceToStacks( all_stacks, bar_entry, |
duration, -- duration |
buff_stacks.min.buffName, -- name |
-- Seeing the charges on the CD bar violated least surprise for me |
1, -- count |
expiration, -- expiration time |
iconPath, -- icon path |
caster -- caster |
buff_stacks.min.iconPath, -- icon path |
buff_stacks.min.caster ) -- caster |
end |
elseif ( bar.expirationTime and bar.expirationTime > tNow + 0.1 ) then |
return bar.duration, -- duration |
AddInstanceToStacks( all_stacks, bar_entry, |
bar.duration, -- duration |
bar.buffName, -- name |
1, -- count |
bar.expirationTime, -- expiration time |
bar.iconPath, -- icon path |
"player" -- caster |
"player" ) -- caster |
end |
end |
-- 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, idxName, barSpell, isSpellID) |
function NeedToKnow.AuraCheck_Single(bar, bar_entry, all_stacks) |
local idxName, barSpell, isSpellID = bar_entry.idxName, bar_entry.barSpell, bar_entry.isSpellID; |
local settings = bar.settings |
local filter = settings.BuffOrDebuff |
if settings.OnlyMine then |
end |
if (spellID == barID) then |
return duration, -- duration |
AddInstanceToStacks( all_stacks, bar_entry, |
duration, -- duration |
buffName, -- name |
count, -- count |
expirationTime, -- expiration time |
iconPath, -- icon path |
caster -- caster |
caster ) -- caster |
return; |
end |
j=j+1 |
end |
local buffName, _ , iconPath, count, _, duration, expirationTime, caster |
= UnitAura(bar.unit, barSpell, nil, filter) |
return duration, -- duration |
AddInstanceToStacks( all_stacks, bar_entry, |
duration, -- duration |
buffName, -- name |
count, -- count |
expirationTime, -- expiration time |
iconPath, -- icon path |
caster -- caster |
caster ) -- caster |
end |
end |
-- Bar_AuraCheck helper that updates bar.all_stacks (but returns nil) |
-- by scanning all the auras on the unit |
function NeedToKnow.AuraCheck_AllStacks(bar, idxName, barSpell, isSpellID) |
function NeedToKnow.AuraCheck_AllStacks(bar, bar_entry, all_stacks) |
local idxName, barSpell, isSpellID = bar_entry.idxName, bar_entry.barSpell, bar_entry.isSpellID; |
local j = 1 |
local matchID |
if isSpellID then matchID = tonumber(barSpell) end |
local all_stacks = bar.all_stacks |
local settings = bar.settings |
local filter = settings.BuffOrDebuff |
end |
if (isSpellID and spellID == matchID) or (not isSpellID and barSpell == buffName) then |
if (not count or count < 1) then count = 1 end |
if ( 0 == all_stacks.total or all_stacks.min.expirationTime > expirationTime ) then |
all_stacks.min.idxName = idxName |
all_stacks.min.buffName = buffName |
all_stacks.min.caster = caster |
all_stacks.min.duration = duration |
all_stacks.min.expirationTime = expirationTime |
all_stacks.min.iconPath = iconPath |
end |
if ( 0 == all_stacks.total or all_stacks.max.expirationTime < expirationTime ) then |
all_stacks.max.duration = duration |
all_stacks.max.expirationTime = expirationTime |
end |
all_stacks.total = all_stacks.total + count |
AddInstanceToStacks(all_stacks, bar_entry, |
duration, |
buffName, |
count, |
expirationTime, |
iconPath, |
caster ) |
end |
j = j+1 |
local all_stacks |
local idxName, duration, buffName, count, expirationTime, iconPath, caster |
if ( bUnitExists ) then |
if ( settings.show_all_stacks ) then |
if ( not bar.all_stacks ) then |
bar.all_stacks = |
{ |
min = |
{ |
buffName = "", |
duration = 0, |
expirationTime = 0, |
iconPath = "", |
caster = "" |
}, |
max = |
{ |
duration = 0, |
expirationTime = 0, |
}, |
total = 0 |
} |
else |
bar.all_stacks.total = 0 |
end |
all_stacks = bar.all_stacks |
end |
all_stacks = NeedToKnow.scratch.all_stacks |
all_stacks.total = 0 |
local bar_entry = NeedToKnow.scratch.bar_entry |
-- Call the helper function for each of the spells in the list |
for idx, barSpell in ipairs(bar.spells) do |
local _, nDigits = barSpell:find("^%d+") |
local isSpellID = ( nDigits == barSpell:len() ) |
bar_entry.idxName = idx |
bar_entry.barSpell = barSpell |
bar_entry.isSpellID = ( nDigits == barSpell:len() ) |
duration, buffName, count, expirationTime, iconPath, caster |
= bar.fnCheck(bar, idx, barSpell, isSpellID); |
bar.fnCheck(bar, bar_entry, all_stacks); |
if duration then |
if not count or count < 1 then |
count = 1 |
end |
if all_stacks.total > 0 and not settings.show_all_stacks then |
idxName = idx |
break |
end |
iconPath = all_stacks.min.iconPath |
count = all_stacks.total |
end |
-- Cancel the work done above if a reset spell is encountered |
-- (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 |
buff_stacks.total = 0 |
-- Keep track of when the reset auras were last applied to the player |
for idx, resetSpell in ipairs(bar.reset_spells) do |
local _, nDigits = resetSpell:find("^%d+") |
local isSpellID = ( nDigits == resetSpell:len() ) |
local bar_entry = NeedToKnow.scratch.bar_entry |
bar_entry.idxName = idx |
bar_entry.barSpell = resetSpell |
bar_entry.isSpellID = ( nDigits == resetSpell:len() ) |
-- 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, idx, resetSpell, isSpellID) |
= NeedToKnow.AuraCheck_Single(bar, bar_entry, buff_stacks) |
local tStart |
if resetDuration then |
if 0 == resetDuration then |
if buff_stacks.total > 0 then |
if 0 == buff_stacks.max.duration then |
tStart = bar.reset_start[idx] |
if 0 == tStart then |
tStart = tNow |
end |
else |
tStart = resetExpiration-resetDuration |
tStart = buff_stacks.max.expirationTime - buff_stacks.max.duration |
end |
bar.reset_start[idx] = tStart |
## Interface: 040200 |
## Interface: 040300 |
## Title: NeedToKnow |
## Author: Kitjan, lieandswell |
## Version: 3.3.0 |