TBC version. warlock's kick is not tracking for mounths for me!
yy241234464 opened this issue · 2 comments
i have tried
1.reinstall many versions of omnibar
2.added all related spell locks' spell id
the others spells is tracking perfectly,
just the warlock‘s kcik can’t work!
-- OmniBar by Jordon
local addonName, addon = ...
local COMBATLOG_FILTER_STRING_UNKNOWN_UNITS = COMBATLOG_FILTER_STRING_UNKNOWN_UNITS
local COMBATLOG_OBJECT_REACTION_HOSTILE = COMBATLOG_OBJECT_REACTION_HOSTILE
local COMBATLOG_OBJECT_TYPE_PLAYER = COMBATLOG_OBJECT_TYPE_PLAYER
local CanInspect = CanInspect
local ClearInspectPlayer = ClearInspectPlayer
local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo
local CreateFrame = CreateFrame
local GetArenaOpponentSpec = GetArenaOpponentSpec
local GetBattlefieldScore = GetBattlefieldScore
local GetClassInfo = GetClassInfo
local GetInspectSpecialization = GetInspectSpecialization
local GetNumBattlefieldScores = GetNumBattlefieldScores
local GetNumGroupMembers = GetNumGroupMembers
local GetNumSpecializationsForClassID = GetNumSpecializationsForClassID
local GetPlayerInfoByGUID = GetPlayerInfoByGUID
local GetRaidRosterInfo = GetRaidRosterInfo
local GetSpecialization = GetSpecialization
local GetSpecializationInfo = GetSpecializationInfo
local GetSpecializationInfoByID = GetSpecializationInfoByID
local GetSpecializationInfoForClassID = GetSpecializationInfoForClassID
local GetSpellInfo = GetSpellInfo
local GetTime = GetTime
local GetUnitName = GetUnitName
local GetZonePVPInfo = GetZonePVPInfo
local InCombatLockdown = InCombatLockdown
local InterfaceOptionsFrame_OpenToCategory = InterfaceOptionsFrame_OpenToCategory
local IsInInstance = IsInInstance
local IsRatedBattleground = C_PvP.IsRatedBattleground
local LibStub = LibStub
local MAX_CLASSES = MAX_CLASSES
local NotifyInspect = NotifyInspect
local SlashCmdList = SlashCmdList
local UIParent = UIParent
local UNITNAME_SUMMON_TITLE1 = UNITNAME_SUMMON_TITLE1
local UNITNAME_SUMMON_TITLE2 = UNITNAME_SUMMON_TITLE2
local UNITNAME_SUMMON_TITLE3 = UNITNAME_SUMMON_TITLE3
local UnitClass = UnitClass
local UnitGUID = UnitGUID
local UnitInParty = UnitInParty
local UnitInRaid = UnitInRaid
local UnitIsPlayer = UnitIsPlayer
local UnitIsPossessed = UnitIsPossessed
local UnitIsUnit = UnitIsUnit
local UnitReaction = UnitReaction
local WOW_PROJECT_CLASSIC = WOW_PROJECT_CLASSIC
local WOW_PROJECT_ID = WOW_PROJECT_ID
local WOW_PROJECT_MAINLINE = WOW_PROJECT_MAINLINE
local bit_band = bit.band
local tinsert = tinsert
local wipe = wipe
OmniBar = LibStub("AceAddon-3.0"):NewAddon("OmniBar", "AceEvent-3.0")
-- Apply cooldown reductions
for k,v in pairs(addon.Cooldowns) do
if v['decrease'] then
addon.Cooldowns[k]['duration'] = v['duration'] - v['decrease']
addon.Cooldowns[k]['decrease'] = nil
end
end
local CLASS_ORDER = {
["GENERAL"] = 0,
["DEMONHUNTER"] = 1,
["DEATHKNIGHT"] = 2,
["PALADIN"] = 3,
["WARRIOR"] = 4,
["DRUID"] = 5,
["PRIEST"] = 6,
["WARLOCK"] = 7,
["SHAMAN"] = 8,
["HUNTER"] = 9,
["MAGE"] = 10,
["ROGUE"] = 11,
["MONK"] = 12,
}
local MAX_ARENA_SIZE = addon.MAX_ARENA_SIZE or 0
local PLAYER_NAME = GetUnitName("player")
local DEFAULTS = {
adaptive = false,
align = "CENTER",
arena = true,
battleground = true,
border = true,
center = false,
columns = 8,
cooldownCount = true,
glow = true,
growUpward = true,
highlightFocus = false,
highlightTarget = true,
locked = false,
maxIcons = 32,
multiple = true,
names = false,
padding = 2,
ratedBattleground = true,
scenario = true,
showUnused = false,
size = 40,
swipeAlpha = 0.65,
tooltips = true,
trackUnit = "ENEMY",
unusedAlpha = 0.45,
world = true,
}
local DB_VERSION = 4
local MAX_DUPLICATE_ICONS = 5
local BASE_ICON_SIZE = 36
function OmniBar:OnInitialize()
self.db = LibStub("AceDB-3.0"):New("OmniBarDB", {
global = { version = DB_VERSION, cooldowns = {} },
profile = { bars = {} }
}, true)
self.cooldowns = addon.Cooldowns
self.bars = {}
self.specs = {}
self.spellCasts = {}
self.db.RegisterCallback(self, "OnProfileChanged", "OnEnable")
self.db.RegisterCallback(self, "OnProfileCopied", "OnEnable")
self.db.RegisterCallback(self, "OnProfileReset", "OnEnable")
self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
self:RegisterEvent("GROUP_ROSTER_UPDATE", "GetSpecs")
-- Remove invalid custom cooldowns
for k,v in pairs(self.db.global.cooldowns) do
if (not GetSpellInfo(k)) then
self.db.global.cooldowns[k] = nil
end
end
-- Populate cooldowns with spell names and icons
for spellId,_ in pairs(self.cooldowns) do
local name, _, icon = GetSpellInfo(spellId)
self.cooldowns[spellId].icon = self.cooldowns[spellId].icon or icon
self.cooldowns[spellId].name = name
end
self:SetupOptions()
end
function OmniBar:OnEnable()
wipe(self.specs)
wipe(self.spellCasts)
self.index = 1
for i = #self.bars, 1, -1 do
self:Delete(self.bars[i].key, true)
table.remove(self.bars, i)
end
for key,_ in pairs(self.db.profile.bars) do
self:Initialize(key)
self.index = self.index + 1
end
-- Create a default bar if none exist
if self.index == 1 then
self:Initialize("OmniBar1", "OmniBar")
self.index = 2
end
for key,_ in pairs(self.db.profile.bars) do
self:AddBarToOptions(key)
end
self:Refresh(true)
end
function OmniBar:Delete(key, keepProfile)
local bar = _G[key]
if (not bar) then return end
bar:UnregisterEvent("PLAYER_ENTERING_WORLD")
bar:UnregisterEvent("ZONE_CHANGED_NEW_AREA")
bar:UnregisterEvent("PLAYER_TARGET_CHANGED")
bar:UnregisterEvent("PLAYER_REGEN_DISABLED")
bar:UnregisterEvent("GROUP_ROSTER_UPDATE")
bar:UnregisterEvent("UPDATE_BATTLEFIELD_SCORE")
if WOW_PROJECT_ID ~= WOW_PROJECT_CLASSIC then
bar:UnregisterEvent("PLAYER_FOCUS_CHANGED")
bar:UnregisterEvent("ARENA_OPPONENT_UPDATE")
end
if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
bar:UnregisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
bar:UnregisterEvent("UPDATE_BATTLEFIELD_STATUS")
end
bar:Hide()
if (not keepProfile) then self.db.profile.bars[key] = nil end
self.options.args.bars.args[key] = nil
LibStub("AceConfigRegistry-3.0"):NotifyChange("OmniBar")
end
OmniBar.BackupCooldowns = {}
function OmniBar:CopyCooldown(cooldown)
local copy = {}
for _,v in pairs({"class", "charges", "parent", "name", "icon"}) do
if cooldown[v] then
copy[v] = cooldown[v]
end
end
if cooldown.duration then
if type(cooldown.duration) == "table" then
copy.duration = {}
for k, v in pairs(cooldown.duration) do
copy.duration[k] = v
end
else
copy.duration = { default = cooldown.duration }
end
end
if cooldown.specID then
copy.specID = {}
for i = 1, #cooldown.specID do
table.insert(copy.specID, cooldown.specID[i])
end
end
return copy
end
-- create a lookup table since CombatLogGetCurrentEventInfo() returns 0 for spellId
local SPELL_ID_BY_NAME
if WOW_PROJECT_ID == WOW_PROJECT_CLASSIC then
SPELL_ID_BY_NAME = {}
for id, value in pairs(addon.Cooldowns) do
if (not value.parent) then SPELL_ID_BY_NAME[GetSpellInfo(id)] = id end
end
end
function OmniBar:AddCustomSpells()
-- Restore any overrides
for k,v in pairs(self.BackupCooldowns) do
addon.Cooldowns[k] = self:CopyCooldown(v)
end
-- Add custom spells
for k,v in pairs(self.db.global.cooldowns) do
local name, _, icon = GetSpellInfo(k)
if name then
-- Backup if we are going to override
if addon.Cooldowns[k] and (not addon.Cooldowns[k].custom) and (not self.BackupCooldowns[k]) then
self.BackupCooldowns[k] = self:CopyCooldown(addon.Cooldowns[k])
end
addon.Cooldowns[k] = v
addon.Cooldowns[k].icon = addon.Cooldowns[k].icon or icon
addon.Cooldowns[k].name = name
if SPELL_ID_BY_NAME then SPELL_ID_BY_NAME[name] = k end
else
self.db.global.cooldowns[k] = nil
end
end
end
local function OmniBar_IsAdaptive(self)
if self.settings.adaptive then return true end
-- force adaptive in arena since enemies are finite and known
if self.zone == "arena" then return true end
-- everything but all enemies are known, so force adaptive
if self.settings.trackUnit ~= "ENEMY" then return true end
end
function OmniBar_SpellCast(self, event, name, spellID)
if self.disabled then return end
-- if GetZonePVPInfo() == "sanctuary" then return end
OmniBar_AddIcon(self, self.spellCasts[name][spellID])
end
function OmniBar:Initialize(key, name)
if (not self.db.profile.bars[key]) then
self.db.profile.bars[key] = { name = name }
for a,b in pairs(DEFAULTS) do
self.db.profile.bars[key][a] = b
end
end
self:AddCustomSpells()
local f = _G[key] or CreateFrame("Frame", key, UIParent, "OmniBarTemplate")
f:Show()
f.settings = self.db.profile.bars[key]
f.settings.align = f.settings.align or "CENTER"
f.settings.maxIcons = f.settings.maxIcons or DEFAULTS.maxIcons
f.key = key
f.icons = {}
f.active = {}
f.detected = {}
f.spellCasts = self.spellCasts
f.specs = self.specs
f.BASE_ICON_SIZE = BASE_ICON_SIZE
f.numIcons = 0
f:RegisterForDrag("LeftButton")
f.anchor.text:SetText(f.settings.name)
-- Upgrade units
f.settings.units = nil
if (not f.settings.trackUnit) then f.settings.trackUnit = "ENEMY" end
-- Remove invalid spells
if f.settings.spells then
for k,_ in pairs(f.settings.spells) do
if (not addon.Cooldowns[k]) or addon.Cooldowns[k].parent then f.settings.spells[k] = nil end
end
end
f.adaptive = OmniBar_IsAdaptive(f)
-- Upgrade custom spells
for k,v in pairs(f.settings) do
local spellID = tonumber(k:match("^spell(%d+)"))
if spellID then
if (not f.settings.spells) then
f.settings.spells = {}
if (not f.settings.noDefault) then
for k,v in pairs(addon.Cooldowns) do
if v.default then f.settings.spells[k] = true end
end
end
end
f.settings.spells[spellID] = v
f.settings[k] = nil
end
end
f.settings.noDefault = nil
-- Load the settings
OmniBar_LoadSettings(f)
-- Create the icons
for spellID,_ in pairs(addon.Cooldowns) do
if OmniBar_IsSpellEnabled(f, spellID) then
OmniBar_CreateIcon(f)
end
end
-- Create the duplicate icons
for i = 1, MAX_DUPLICATE_ICONS do
OmniBar_CreateIcon(f)
end
OmniBar_ShowAnchor(f)
OmniBar_ResetIcons(f)
OmniBar_UpdateIcons(f)
OmniBar_Center(f)
f.OnEvent = OmniBar_OnEvent
f:RegisterEvent("PLAYER_ENTERING_WORLD", "OnEvent")
f:RegisterEvent("ZONE_CHANGED_NEW_AREA", "OnEvent")
f:RegisterEvent("PLAYER_TARGET_CHANGED", "OnEvent")
f:RegisterEvent("PLAYER_REGEN_DISABLED", "OnEvent")
f:RegisterEvent("GROUP_ROSTER_UPDATE", "OnEvent")
if WOW_PROJECT_ID ~= WOW_PROJECT_CLASSIC then
f:RegisterEvent("PLAYER_FOCUS_CHANGED", "OnEvent")
f:RegisterEvent("ARENA_OPPONENT_UPDATE", "OnEvent")
end
if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
f:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS", "OnEvent")
f:RegisterEvent("UPDATE_BATTLEFIELD_STATUS", "OnEvent")
end
f:RegisterEvent("UPDATE_BATTLEFIELD_SCORE", "OnEvent")
table.insert(self.bars, f)
end
function OmniBar:Create()
while true do
local key = "OmniBar"..self.index
self.index = self.index + 1
if (not self.db.profile.bars[key]) then
self:Initialize(key, "OmniBar " .. (self.index - 1))
self:AddBarToOptions(key, true)
self:OnEnable()
return
end
end
end
function OmniBar:Refresh(full)
self:GetSpecs()
for key,_ in pairs(self.db.profile.bars) do
local f = _G[key]
if f then
f.container:SetScale(f.settings.size/BASE_ICON_SIZE)
if full then
f.adaptive = OmniBar_IsAdaptive(f)
OmniBar_OnEvent(f, "PLAYER_ENTERING_WORLD")
OmniBar_OnEvent(f, "PLAYER_TARGET_CHANGED")
OmniBar_OnEvent(f, "PLAYER_FOCUS_CHANGED")
OmniBar_OnEvent(f, "GROUP_ROSTER_UPDATE")
else
OmniBar_LoadPosition(f)
OmniBar_UpdateIcons(f)
OmniBar_Center(f)
end
end
end
end
local Masque = LibStub and LibStub("Masque", true)
-- create a lookup table to translate spec names into IDs
local SPEC_ID_BY_NAME = {}
if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
for classID = 1, MAX_CLASSES do
local _, classToken = GetClassInfo(classID)
SPEC_ID_BY_NAME[classToken] = {}
for i = 1, GetNumSpecializationsForClassID(classID) do
local id, name = GetSpecializationInfoForClassID(classID, i)
SPEC_ID_BY_NAME[classToken][name] = id
end
end
end
local function UnitIsHostile(unit)
if (not unit) then return end
if UnitIsUnit("player", unit) then return end
local reaction = UnitReaction("player", unit)
if (not reaction) then return end -- out of range
return UnitIsPlayer(unit) and reaction < 4 and (not UnitIsPossessed(unit))
end
function OmniBar_ShowAnchor(self)
if self.disabled or self.settings.locked or #self.active > 0 then
self.anchor:Hide()
else
local width = self.anchor.text:GetWidth() + 29
self.anchor:SetSize(width, 30)
self.anchor:Show()
end
end
function OmniBar_CreateIcon(self)
if InCombatLockdown() then return end
self.numIcons = self.numIcons + 1
local name = self:GetName()
local key = name.."Icon"..self.numIcons
local f = _G[key] or CreateFrame("Button", key, _G[name.."Icons"], "OmniBarButtonTemplate")
table.insert(self.icons, f)
end
local function SpellBelongsToSpec(spellID, specID)
if (not specID) then return true end
if (not addon.Cooldowns[spellID].specID) then return true end
for i = 1, #addon.Cooldowns[spellID].specID do
if addon.Cooldowns[spellID].specID[i] == specID then return true end
end
end
function OmniBar_AddIconsByClass(self, class, sourceGUID, specID)
for spellID, spell in pairs(addon.Cooldowns) do
if OmniBar_IsSpellEnabled(self, spellID) and
(spell.class == "GENERAL" or (spell.class == class and SpellBelongsToSpec(spellID, specID)))
then
OmniBar_AddIcon(self, { spellID = spellID, sourceGUID = sourceGUID, specID = specID })
end
end
end
local function IconIsUnit(iconGUID, guid)
if (not guid) then return end
if type(iconGUID) == "number" then
-- arena target
return UnitGUID("arena" .. iconGUID) == guid
end
return iconGUID == guid
end
local function OmniBar_StartAnimation(self, icon)
if (not self.settings.glow) then return end
icon.flashAnim:Play()
icon.newitemglowAnim:Play()
end
local function OmniBar_StopAnimation(self, icon)
if icon.flashAnim:IsPlaying() then icon.flashAnim:Stop() end
if icon.newitemglowAnim:IsPlaying() then icon.newitemglowAnim:Stop() end
end
function OmniBar_UpdateBorder(self, icon)
local border
local guid = icon.sourceGUID
local name = icon.sourceName
if guid or name then
if self.settings.highlightFocus and
self.settings.trackUnit == "ENEMY" and
(IconIsUnit(guid, UnitGUID("focus")) or name == GetUnitName("focus", true)) and
UnitIsPlayer("focus")
then
icon.FocusTexture:SetAlpha(1)
border = true
else
icon.FocusTexture:SetAlpha(0)
end
if self.settings.highlightTarget and
self.settings.trackUnit == "ENEMY" and
(IconIsUnit(guid, UnitGUID("target")) or name == GetUnitName("target", true)) and
UnitIsPlayer("target")
then
icon.FocusTexture:SetAlpha(0)
icon.TargetTexture:SetAlpha(1)
border = true
else
icon.TargetTexture:SetAlpha(0)
end
else
local _, class = UnitClass("focus")
if self.settings.highlightFocus and
self.settings.trackUnit == "ENEMY" and
class and (class == icon.class or icon.class == "GENERAL") and
UnitIsPlayer("focus")
then
icon.FocusTexture:SetAlpha(1)
border = true
else
icon.FocusTexture:SetAlpha(0)
end
_, class = UnitClass("target")
if self.settings.highlightTarget and
self.settings.trackUnit == "ENEMY" and
class and (class == icon.class or icon.class == "GENERAL") and
UnitIsPlayer("target")
then
icon.FocusTexture:SetAlpha(0)
icon.TargetTexture:SetAlpha(1)
border = true
else
icon.TargetTexture:SetAlpha(0)
end
end
-- Set dim
icon:SetAlpha(self.settings.unusedAlpha and
icon.cooldown:GetCooldownTimes() == 0 and
(not border) and
self.settings.unusedAlpha or 1)
end
function OmniBar_UpdateAllBorders(self)
for i = 1, #self.active do
OmniBar_UpdateBorder(self, self.active[i])
end
end
function OmniBar_SetZone(self, refresh)
local disabled = self.disabled
local _, zone = IsInInstance()
-- if zone == "none" then
-- SetMapToCurrentZone()
-- zone = GetCurrentMapAreaID()
-- end
self.zone = zone
self.rated = IsRatedBattleground and IsRatedBattleground()
self.disabled = (zone == "arena" and (not self.settings.arena)) or
(self.rated and (not self.settings.ratedBattleground)) or
(zone == "pvp" and (not self.settings.battleground) and (not self.rated)) or
(zone == "scenario" and (not self.settings.scenario)) or
(zone ~= "arena" and zone ~= "pvp" and zone ~= "scenario" and (not self.settings.world))
self.adaptive = OmniBar_IsAdaptive(self)
if refresh or disabled ~= self.disabled then
OmniBar_LoadPosition(self)
OmniBar_ResetIcons(self)
OmniBar_UpdateIcons(self)
OmniBar_ShowAnchor(self)
if zone == "arena" and (not self.disabled) then
wipe(self.detected)
wipe(self.specs)
wipe(self.spellCasts)
OmniBar_OnEvent(self, "ARENA_OPPONENT_UPDATE")
end
end
end
local UNITNAME_SUMMON_TITLES = {
UNITNAME_SUMMON_TITLE1,
UNITNAME_SUMMON_TITLE2,
UNITNAME_SUMMON_TITLE3,
}
local tooltip = CreateFrame("GameTooltip", "OmniBarPetTooltip", nil, "GameTooltipTemplate")
local tooltipText = OmniBarPetTooltipTextLeft2
local function UnitOwnerName(guid)
if (not guid) then return end
for i = 1, 3 do
_G["UNITNAME_SUMMON_TITLE" .. i] = "OmniBar %s"
end
tooltip:SetOwner(UIParent, "ANCHOR_NONE")
tooltip:SetHyperlink("unit:" .. guid)
local name = tooltipText:GetText()
for i = 1, 3 do
_G["UNITNAME_SUMMON_TITLE" .. i] = UNITNAME_SUMMON_TITLES[i]
end
if (not name) then return end
local owner = name:match("OmniBar (.+)")
if owner then return owner end
end
local function IsSourceHostile(sourceFlags)
local band = bit_band(sourceFlags, COMBATLOG_OBJECT_REACTION_HOSTILE)
if UnitIsPossessed("player") and band == 0 then return true end
return band == COMBATLOG_OBJECT_REACTION_HOSTILE
end
local function GetCooldownDuration(cooldown, specID)
if (not cooldown.duration) then return end
if type(cooldown.duration) == "table" then
if specID and cooldown.duration[specID] then
return cooldown.duration[specID]
else
return cooldown.duration.default
end
else
return cooldown.duration
end
end
function OmniBar:AddSpellCast(event, sourceGUID, sourceName, sourceFlags, spellID)
if (not addon.Resets[spellID]) and (not addon.Cooldowns[spellID]) then return end
-- unset unknown sourceName
sourceName = sourceName == COMBATLOG_FILTER_STRING_UNKNOWN_UNITS and nil or sourceName
-- if it's a pet associate with owner
local ownerName = UnitOwnerName(sourceGUID)
local name = ownerName or sourceName
if (not name) then return end
if addon.Resets[spellID] and self.spellCasts[name] and event == "SPELL_CAST_SUCCESS" then
for i = 1, #addon.Resets[spellID] do
local reset = addon.Resets[spellID][i]
if type(reset) == "table" and reset.amount then
if self.spellCasts[name][reset.spellID] then
self.spellCasts[name][reset.spellID].duration = self.spellCasts[name][reset.spellID].duration - reset.amount
if self.spellCasts[name][reset.spellID].duration < 1 then
self.spellCasts[name][reset.spellID] = nil
end
end
else
if type(reset) == "table" then reset = reset.spellID end
self.spellCasts[name][reset] = nil
end
end
self:SendMessage("OmniBar_ResetSpellCast", name, spellID)
end
if (not addon.Cooldowns[spellID]) then return end
local now = GetTime()
-- make sure we aren't adding a duplicate
if self.spellCasts[name] and self.spellCasts[name][spellID] and self.spellCasts[name][spellID].timestamp == now then
return
end
-- only track players and their pets
if (not ownerName) and bit_band(sourceFlags, COMBATLOG_OBJECT_TYPE_PLAYER) == 0 then return end
local duration = GetCooldownDuration(addon.Cooldowns[spellID])
local charges = addon.Cooldowns[spellID].charges
-- make sure spellID is parent
spellID = addon.Cooldowns[spellID].parent or spellID
-- child doesn't have custom charges, use parent
if (not charges) then
charges = addon.Cooldowns[spellID].charges
end
-- child doesn't have a custom duration, use parent
if (not duration) then
duration = GetCooldownDuration(addon.Cooldowns[spellID])
end
self.spellCasts[name] = self.spellCasts[name] or {}
self.spellCasts[name][spellID] = {
charges = charges,
duration = duration,
event = event,
expires = now + duration,
ownerName = ownerName,
sourceFlags = sourceFlags,
sourceGUID = sourceGUID,
sourceName = sourceName,
spellID = spellID,
spellName = GetSpellInfo(spellID),
timestamp = now,
}
self:SendMessage("OmniBar_SpellCast", name, spellID)
end
-- Needed to track PvP trinkets and possibly other spells that do not show up in COMBAT_LOG_EVENT_UNFILTERED
function OmniBar:UNIT_SPELLCAST_SUCCEEDED(event, unit, _, spellID)
if (not addon.Cooldowns[spellID]) then return end
local sourceFlags = 0
if UnitReaction("player", unit) < 4 then
sourceFlags = sourceFlags + COMBATLOG_OBJECT_REACTION_HOSTILE
end
if UnitIsPlayer(unit) then
sourceFlags = sourceFlags + COMBATLOG_OBJECT_TYPE_PLAYER
end
self:AddSpellCast(event, UnitGUID(unit), GetUnitName(unit, true), sourceFlags, spellID)
end
function OmniBar:COMBAT_LOG_EVENT_UNFILTERED()
local , event, , sourceGUID, sourceName, sourceFlags, ,,,,_, spellID, spellName = CombatLogGetCurrentEventInfo()
if (event == "SPELL_CAST_SUCCESS" or event == "SPELL_AURA_APPLIED") then
if spellID == 0 and SPELL_ID_BY_NAME then spellID = SPELL_ID_BY_NAME[spellName] end
self:AddSpellCast(event, sourceGUID, sourceName, sourceFlags, spellID)
end
end
function OmniBar_Refresh(self)
OmniBar_ResetIcons(self)
OmniBar_ReplaySpellCasts(self)
end
function OmniBar_OnEvent(self, event, ...)
if event == "PLAYER_ENTERING_WORLD" then
OmniBar_SetZone(self, true)
OmniBar_OnEvent(self, "ARENA_PREP_OPPONENT_SPECIALIZATIONS")
elseif event == "ZONE_CHANGED_NEW_AREA" then
OmniBar_SetZone(self, true)
elseif event == "UPDATE_BATTLEFIELD_STATUS" then -- IsRatedBattleground() doesn't return valid response until this event
if self.disabled or self.zone ~= "pvp" then return end
if (not self.rated) and IsRatedBattleground() then OmniBar_SetZone(self) end
elseif event == "UPDATE_BATTLEFIELD_SCORE" then
for i = 1, GetNumBattlefieldScores() do
local name, _,_,_,_,_,_,_, classToken, _,_,_,_,_,_, talentSpec = GetBattlefieldScore(i)
if name and SPEC_ID_BY_NAME[classToken] and SPEC_ID_BY_NAME[classToken][talentSpec] then
if (not self.specs[name]) then
self.specs[name] = SPEC_ID_BY_NAME[classToken][talentSpec]
self:SendMessage("OmniBar_SpecUpdated", name)
end
end
end
elseif event == "ARENA_PREP_OPPONENT_SPECIALIZATIONS" then
if WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE then return end
if self.disabled or (not self.adaptive) or (not self.settings.showUnused) then return end
for i = 1, MAX_ARENA_SIZE do
if self.settings.trackUnit == "ENEMY" or self.settings.trackUnit == "arena" .. i then
local specID = GetArenaOpponentSpec(i)
if specID and specID > 0 and (not self.detected[i]) then
local _,_,_,_,_, class = GetSpecializationInfoByID(specID)
if class then
self.detected[i] = class
OmniBar_AddIconsByClass(self, class, i, specID)
end
end
end
end
elseif event == "ARENA_OPPONENT_UPDATE" then
if self.disabled or (not self.settings.showUnused) then return end
-- we get the info from ARENA_PREP_OPPONENT_SPECIALIZATIONS on retail
if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
OmniBar_OnEvent(self, "ARENA_PREP_OPPONENT_SPECIALIZATIONS")
return
end
local unit = ...
if (not unit) or (not UnitIsPlayer(unit)) then return end
if unit == self.settings.trackUnit then
OmniBar_Refresh(self)
return
end
if self.settings.trackUnit == "ENEMY" then
local _, class = UnitClass(unit)
if class then
local i = tonumber(unit:match("%d+$"))
if (not self.detected[i]) then
self.detected[i] = class
OmniBar_AddIconsByClass(self, class, i)
end
end
end
elseif event == "GROUP_ROSTER_UPDATE" then
if self.disabled then return end
if self.settings.trackUnit == "GROUP" or self.settings.trackUnit:match("^party") then
OmniBar_Refresh(self)
end
elseif event == "PLAYER_TARGET_CHANGED" or event == "PLAYER_FOCUS_CHANGED" or event == "PLAYER_REGEN_DISABLED" then
if self.disabled then return end
local unit = (event == "PLAYER_TARGET_CHANGED" and "target") or (event == "PLAYER_FOCUS_CHANGED" and "focus")
if unit and unit:upper() == self.settings.trackUnit then
OmniBar_Refresh(self)
end
-- update icon borders
OmniBar_UpdateAllBorders(self)
-- we don't need to add in arena
if self.zone == "arena" then return end
-- only add to bars tracking all enemies
if self.settings.trackUnit ~= "ENEMY" then return end
-- only add icons if show adaptive is checked
if (not self.settings.showUnused) or
(not self.adaptive) or
(not UnitIsHostile("target"))
then
return
end
-- only add icons when we're in combat
-- if event == "PLAYER_TARGET_CHANGED" and (not InCombatLockdown()) then return end
local guid = UnitGUID("target")
local _, class = UnitClass("target")
if class and UnitIsPlayer("target") then
if self.detected[guid] then return end
self.detected[guid] = class
OmniBar_AddIconsByClass(self, class, nil, self.specs[GetUnitName("target", true)])
end
end
end
function OmniBar_LoadSettings(self)
-- Set the scale
self.container:SetScale(self.settings.size/BASE_ICON_SIZE)
OmniBar_LoadPosition(self)
OmniBar_ResetIcons(self)
OmniBar_UpdateIcons(self)
OmniBar_Center(self)
end
function OmniBar_SavePosition(self, set)
local point, relativeTo, relativePoint, xOfs, yOfs = self:GetPoint()
local frameStrata = self:GetFrameStrata()
relativeTo = relativeTo and relativeTo:GetName() or "UIParent"
if set then
if set.point then point = set.point end
if set.relativeTo then relativeTo = set.relativeTo end
if set.relativePoint then relativePoint = set.relativePoint end
if set.xOfs then xOfs = set.xOfs end
if set.yOfs then yOfs = set.yOfs end
if set.frameStrata then frameStrata = set.frameStrata end
end
if (not self.settings.position) then
self.settings.position = {}
end
self.settings.position.point = point
self.settings.position.relativeTo = relativeTo
self.settings.position.relativePoint = relativePoint
self.settings.position.xOfs = xOfs
self.settings.position.yOfs = yOfs
self.settings.position.frameStrata = frameStrata
end
function OmniBar_ResetPosition(self)
self.settings.position.relativeTo = "UIParent"
self.settings.position.relativePoint = "CENTER"
self.settings.position.xOfs = 0
self.settings.position.yOfs = 0
OmniBar_LoadPosition(self)
end
function OmniBar_LoadPosition(self)
self:ClearAllPoints()
if self.settings.position then
local point = self.settings.position.point or "CENTER"
local relativeTo = self.settings.position.relativeTo or "UIParent"
if (not _G[relativeTo]) then
OmniBar_ResetPosition(self)
return
end
local relativePoint = self.settings.position.relativePoint or "CENTER"
local xOfs = self.settings.position.xOfs or 0
local yOfs = self.settings.position.yOfs or 0
self:SetPoint(point, relativeTo, relativePoint, xOfs, yOfs)
if (not self.settings.position.frameStrata) then self.settings.position.frameStrata = "MEDIUM" end
self:SetFrameStrata(self.settings.position.frameStrata)
else
self:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
OmniBar_SavePosition(self)
end
end
function OmniBar_IsSpellEnabled(self, spellID)
if (not spellID) then return end
if (not self.settings.spells) then return addon.Cooldowns[spellID].default end
return self.settings.spells[spellID]
end
function OmniBar:GetSpellTexture(spellID)
spellID = tonumber(spellID)
return (addon.Cooldowns[spellID] and addon.Cooldowns[spellID].icon) or GetSpellTexture(spellID)
end
function OmniBar_SpecUpdated(self, event, name)
if self.disabled then return end
if self.settings.trackUnit == "GROUP" or UnitIsUnit(self.settings.trackUnit, name) then
OmniBar_Refresh(self)
end
end
function OmniBar:GetSpecs()
if (not GetSpecializationInfo) then return end
if (not self.specs[PLAYER_NAME]) then
self.specs[PLAYER_NAME] = GetSpecializationInfo(GetSpecialization())
self:SendMessage("OmniBar_SpecUpdated", PLAYER_NAME)
end
if self.lastInspect and GetTime() - self.lastInspect < 3 then
return
end
for i = 1, GetNumGroupMembers() do
local name, ,,,, class = GetRaidRosterInfo(i)
if name and (not self.specs[name]) and (not UnitIsUnit("player", name)) and CanInspect(name) then
self.inspectUnit = name
self.lastInspect = GetTime()
self:RegisterEvent("INSPECT_READY")
NotifyInspect(name)
return
end
end
end
function OmniBar:INSPECT_READY(event, guid)
if (not self.inspectUnit) then return end
local unit = self.inspectUnit
self.inspectUnit = nil
self:UnregisterEvent("INSPECT_READY")
if (UnitGUID(unit) ~= guid) then
ClearInspectPlayer()
self:GetSpecs()
return
end
self.specs[unit] = GetInspectSpecialization(unit)
self:SendMessage("OmniBar_SpecUpdated", unit)
ClearInspectPlayer()
self:GetSpecs()
end
function OmniBar_IsUnitEnabled(self, info)
if (not info.timestamp) then return true end
if info.test then return true end
local guid = info.sourceGUID
if guid == nil then return end
local name = info.ownerName or info.sourceName
local isHostile = IsSourceHostile(info.sourceFlags)
if self.settings.trackUnit == "ENEMY" and isHostile then
return true
end
local isPlayer = UnitIsUnit("player", name)
if self.settings.trackUnit == "PLAYER" and isPlayer then
return true
end
if self.settings.trackUnit == "TARGET" and (UnitGUID("target") == guid or GetUnitName("target", true) == name) then
return true
end
if self.settings.trackUnit == "FOCUS" and (UnitGUID("focus") == guid or GetUnitName("focus", true) == name) then
return true
end
if self.settings.trackUnit == "GROUP" and (not isPlayer) and (UnitInParty(name) or UnitInRaid(name)) then
return true
end
for i = 1, MAX_ARENA_SIZE do
local unit = "arena" .. i
if (i == guid or UnitGUID(unit) == guid) and self.settings.trackUnit == unit:lower() then
return true
end
end
for i = 1, 4 do
local unit = "party" .. i
if (i == guid or UnitGUID(unit) == guid) and self.settings.trackUnit == unit:lower() then
return true
end
end
end
function OmniBar_Center(self)
local parentWidth = UIParent:GetWidth()
local clamp = self.settings.center and (1 - parentWidth)/2 or 0
self:SetClampRectInsets(clamp, -clamp, 0, 0)
clamp = self.settings.center and (self.anchor:GetWidth() - parentWidth)/2 or 0
self.anchor:SetClampRectInsets(clamp, -clamp, 0, 0)
end
function OmniBar_CooldownFinish(self, force)
local icon = self:GetParent()
if icon.cooldown and icon.cooldown:GetCooldownTimes() > 0 and (not force) then return end -- not complete
local charges = icon.charges
if charges then
charges = charges - 1
if charges > 0 then
-- remove a charge
icon.charges = charges
icon.Count:SetText(charges)
if self.omnicc then
self.omnicc:HookScript('OnHide', function()
OmniBar_StartCooldown(icon:GetParent():GetParent(), icon, GetTime())
end)
end
OmniBar_StartCooldown(icon:GetParent():GetParent(), icon, GetTime())
return
end
end
local bar = icon:GetParent():GetParent()
OmniBar_StopAnimation(self, icon)
if (not bar.settings.showUnused) then
icon:Hide()
else
if icon.TargetTexture:GetAlpha() == 0 and
icon.FocusTexture:GetAlpha() == 0 and
bar.settings.unusedAlpha then
icon:SetAlpha(bar.settings.unusedAlpha)
end
end
bar:StopMovingOrSizing()
OmniBar_Position(bar)
end
function OmniBar_ReplaySpellCasts(self)
if self.disabled then return end
local now = GetTime()
for name,_ in pairs(self.spellCasts) do
for k,v in pairs(self.spellCasts[name]) do
if now >= v.expires then
self.spellCasts[name][k] = nil
else
OmniBar_AddIcon(self, self.spellCasts[name][k])
end
end
end
end
local function OmniBar_UnitClassAndSpec(self)
local unit = self.settings.trackUnit
if unit == "ENEMY" or unit == "GROUP" then return end
local _, class = UnitClass(unit)
local specID = self.specs[GetUnitName(unit, true)]
return class, specID
end
function OmniBar_ResetIcons(self)
-- Hide all the icons
for i = 1, self.numIcons do
if self.icons[i].MasqueGroup then
--self.icons[i].MasqueGroup:Delete()
self.icons[i].MasqueGroup = nil
end
self.icons[i].TargetTexture:SetAlpha(0)
self.icons[i].FocusTexture:SetAlpha(0)
self.icons[i].flash:SetAlpha(0)
self.icons[i].NewItemTexture:SetAlpha(0)
self.icons[i].cooldown:SetCooldown(0, 0)
self.icons[i].cooldown:Hide()
self.icons[i]:Hide()
end
wipe(self.active)
if self.disabled then return end
if self.settings.showUnused then
if self.settings.trackUnit == "ENEMY" then
if (not self.adaptive) then
for spellID,_ in pairs(addon.Cooldowns) do
if OmniBar_IsSpellEnabled(self, spellID) then
OmniBar_AddIcon(self, { spellID = spellID })
end
end
end
elseif self.settings.trackUnit == "GROUP" then
for i = 1, GetNumGroupMembers() do
local name, _,_,_,_, class = GetRaidRosterInfo(i)
local guid = UnitGUID(name)
if class and (not UnitIsUnit("player", name)) then
OmniBar_AddIconsByClass(self, class, UnitGUID(name), self.specs[name])
end
end
else
local class, specID = OmniBar_UnitClassAndSpec(self)
if class and UnitIsPlayer(self.settings.trackUnit) then
OmniBar_AddIconsByClass(self, class, nil, specID)
end
end
end
OmniBar_Position(self)
end
function OmniBar_StartCooldown(self, icon, start)
icon.cooldown:SetCooldown(start, icon.duration)
icon.cooldown.finish = start + icon.duration
icon.cooldown:SetSwipeColor(0, 0, 0, self.settings.swipeAlpha or 0.65)
icon:SetAlpha(1)
end
function OmniBar_AddIcon(self, info)
if (not OmniBar_IsUnitEnabled(self, info)) then return end
if (not OmniBar_IsSpellEnabled(self, info.spellID)) then return end
local icon, duplicate
-- Try to reuse a visible frame
for i = 1, #self.active do
if self.active[i].spellID == info.spellID then
duplicate = true
-- check if we can use this icon, but not when initializing arena opponents
if info.timestamp or self.zone ~= "arena" then
-- use icon if not bound to a sourceGUID
if (not self.active[i].sourceGUID) then
duplicate = nil
icon = self.active[i]
break
end
-- if it's the same source, reuse the icon
if info.sourceGUID and IconIsUnit(self.active[i].sourceGUID, info.sourceGUID) then
duplicate = nil
icon = self.active[i]
break
end
end
end
end
-- We couldn't find a visible frame to reuse, try to find an unused
if (not icon) then
if #self.active >= self.settings.maxIcons then return end
if (not self.settings.multiple) and duplicate then return end
for i = 1, #self.icons do
if (not self.icons[i]:IsVisible()) then
icon = self.icons[i]
icon.specID = nil
break
end
end
end
-- We couldn't find a frame to use
if (not icon) then return end
icon.class = addon.Cooldowns[info.spellID].class
icon.sourceGUID = info.sourceGUID
icon.sourceName = info.ownerName or info.sourceName
icon.specID = info.specID and info.specID or self.specs[icon.sourceName]
icon.icon:SetTexture(addon.Cooldowns[info.spellID].icon)
icon.spellID = info.spellID
icon.timestamp = info.test and GetTime() or info.timestamp
icon.duration = info.test and math.random(5,30) or info.duration
icon.added = GetTime()
if icon.charges and info.charges and icon:IsVisible() then
local start, duration = icon.cooldown:GetCooldownTimes()
if icon.cooldown.finish and icon.cooldown.finish - GetTime() > 1 then
-- add a charge
local charges = icon.charges + 1
icon.charges = charges
icon.Count:SetText(charges)
OmniBar_StartAnimation(self, icon)
return icon
end
elseif info.charges then
icon.charges = 1
icon.Count:SetText("1")
else
icon.charges = nil
icon.Count:SetText(nil)
end
if self.settings.names then
local name = info.test and "Name" or icon.sourceName
icon.Name:SetText(name)
end
-- Masque
if Masque then
icon.MasqueGroup = Masque:Group("OmniBar", info.spellName)
icon.MasqueGroup:AddButton(icon, {
FloatingBG = false,
Icon = icon.icon,
Cooldown = icon.cooldown,
Flash = false,
Pushed = false,
Normal = icon:GetNormalTexture(),
Disabled = false,
Checked = false,
Border = _G[icon:GetName().."Border"],
AutoCastable = false,
Highlight = false,
Hotkey = false,
Count = false,
Name = false,
Duration = false,
AutoCast = false,
})
end
icon:Show()
if (icon.timestamp) then
OmniBar_StartCooldown(self, icon, icon.timestamp)
if (GetTime() == icon.timestamp) then OmniBar_StartAnimation(self, icon) end
end
return icon
end
function OmniBar_UpdateIcons(self)
for i = 1, self.numIcons do
-- Set show text
self.icons[i].cooldown:SetHideCountdownNumbers(not self.settings.cooldownCount and true or false)
self.icons[i].cooldown.noCooldownCount = (not self.settings.cooldownCount)
-- Set swipe alpha
self.icons[i].cooldown:SetSwipeColor(0, 0, 0, self.settings.swipeAlpha or 0.65)
-- Set border
if self.settings.border then
self.icons[i].icon:SetTexCoord(0, 0, 0, 1, 1, 0, 1, 1)
else
self.icons[i].icon:SetTexCoord(0.07, 0.9, 0.07, 0.9)
end
-- Set dim
self.icons[i]:SetAlpha(self.settings.unusedAlpha and self.icons[i].cooldown:GetCooldownTimes() == 0 and
self.settings.unusedAlpha or 1)
-- Masque
if self.icons[i].MasqueGroup then self.icons[i].MasqueGroup:ReSkin() end
end
end
function OmniBar_Test(self)
if (not self) then return end
self.disabled = nil
OmniBar_ResetIcons(self)
if self.settings.spells then
for k,v in pairs(self.settings.spells) do
OmniBar_AddIcon(self, { spellID = k, test = true })
end
else
for k,v in pairs(addon.Cooldowns) do
if v.default then
OmniBar_AddIcon(self, { spellID = k, test = true })
end
end
end
end
function OmniBar_Position(self)
local numActive = #self.active
if numActive == 0 then
-- Show the anchor if needed
OmniBar_ShowAnchor(self)
return
end
-- Keep cooldowns together by class
if self.settings.showUnused then
table.sort(self.active, function(a, b)
local x, y = a.ownerName or a.sourceName or "", b.ownerName or b.sourceName or ""
local aClass, bClass = a.class or 0, b.class or 0
if aClass == bClass then
-- if we are tracking a single unit we don't need to sort by name
if self.settings.trackUnit ~= "ENEMY" and self.settings.trackUnit ~= "GROUP" then
return a.spellID < b.spellID
end
if x < y then return true end
if x == y then return a.spellID < b.spellID end
end
return CLASS_ORDER[aClass] < CLASS_ORDER[bClass]
end)
else
-- if we aren't showing unused, just sort by added time
table.sort(self.active, function(a, b) return a.added == b.added and a.spellID < b.spellID or a.added < b.added end)
end
local count, rows = 0, 1
local grow = self.settings.growUpward and 1 or -1
local padding = self.settings.padding and self.settings.padding or 0
for i = 1, numActive do
if self.settings.locked then
self.active[i]:EnableMouse(false)
else
self.active[i]:EnableMouse(true)
end
self.active[i]:ClearAllPoints()
local columns = self.settings.columns and self.settings.columns > 0 and self.settings.columns < numActive and
self.settings.columns or numActive
if i > 1 then
count = count + 1
if count >= columns then
if self.settings.align == "CENTER" then
self.active[i]:SetPoint("CENTER", self.anchor, "CENTER", (-BASE_ICON_SIZE-padding)*(columns-1)/2, (BASE_ICON_SIZE+padding)*rows*grow)
else
self.active[i]:SetPoint(self.settings.align, self.anchor, self.settings.align, 0, (BASE_ICON_SIZE+padding)*rows*grow)
end
count = 0
rows = rows + 1
else
if self.settings.align == "RIGHT" then
self.active[i]:SetPoint("TOPRIGHT", self.active[i-1], "TOPLEFT", -1 * padding, 0)
else
self.active[i]:SetPoint("TOPLEFT", self.active[i-1], "TOPRIGHT", padding, 0)
end
end
else
if self.settings.align == "CENTER" then
self.active[i]:SetPoint("CENTER", self.anchor, "CENTER", (-BASE_ICON_SIZE-padding)*(columns-1)/2, 0)
else
self.active[i]:SetPoint(self.settings.align, self.anchor, self.settings.align, 0, 0)
end
end
end
OmniBar_ShowAnchor(self)
end
function OmniBar:Test()
for key,_ in pairs(self.db.profile.bars) do
OmniBar_Test(_G[key])
end
end
SLASH_OmniBar1 = "/ob"
SLASH_OmniBar2 = "/omnibar"
SlashCmdList.OmniBar = function()
InterfaceOptionsFrame_OpenToCategory("OmniBar")
InterfaceOptionsFrame_OpenToCategory("OmniBar")
end