Thread Tools Display Modes
05-05-16, 10:24 PM   #1
hasnogaems
A Flamescale Wyrmkin
 
hasnogaems's Avatar
Join Date: Apr 2016
Posts: 109
Edit omnibar

I want to edit widely known addon http://mods.curse.com/addons/wow/omnibar to make it ability icon fade out only when it's on cooldown and have full opacity when it off cooldown. Currently there is reversed behavior. Im pretty sure it's can be done, but i can't find in code where this opacity settings is. Can anyone help me please?
  Reply With Quote
05-06-16, 01:57 PM   #2
hasnogaems
A Flamescale Wyrmkin
 
hasnogaems's Avatar
Join Date: Apr 2016
Posts: 109
Im also gonna post main OmniBar.lua code if it pertinent.
Code:
-- OmniBar by Jordon

OmniBar = LibStub("AceAddon-3.0"):NewAddon("OmniBar", "AceEvent-3.0", "AceHook-3.0")

OmniBar.cooldowns = {
	[47476]  = { default = true,  duration = 60,  class = "DEATHKNIGHT" },                                   -- Strangulate
	[47481]  = { default = false, duration = 60,  class = "DEATHKNIGHT", specID = { 252 } },                 -- Gnaw (Ghoul)
	[47482]  = { default = false, duration = 30,  class = "DEATHKNIGHT", specID = { 252 } },                 -- Leap (Ghoul)
	[47528]  = { default = true,  duration = 15,  class = "DEATHKNIGHT" },                                   -- Mind Freeze
	[48707]  = { default = false, duration = 45,  class = "DEATHKNIGHT" },                                   -- Anti-Magic Shell
	[48743]  = { default = false, duration = 120, class = "DEATHKNIGHT" },                                   -- Death Pact
	[48792]  = { default = false, duration = 180, class = "DEATHKNIGHT" },                                   -- Icebound Fortitude
	[49028]  = { default = false, duration = 90,  class = "DEATHKNIGHT", specID = { 250 } },                 -- Dancing Rune Weapon
	[49039]  = { default = false, duration = 120, class = "DEATHKNIGHT" },                                   -- Lichborne
	[49576]  = { default = false, duration = 25,  class = "DEATHKNIGHT" },                                   -- Death Grip
	[51052]  = { default = false, duration = 120, class = "DEATHKNIGHT" },                                   -- Anti-Magic Zone
	[51271]  = { default = false, duration = 60,  class = "DEATHKNIGHT", specID = { 251 } },                 -- Pillar of Frost
	[55233]  = { default = false, duration = 60,  class = "DEATHKNIGHT", specID = { 250 } },                 -- Vampiric Blood
	[77606]  = { default = false, duration = 30,  class = "DEATHKNIGHT" },                                   -- Dark Simulacrum
	[91802]  = { default = true,  duration = 30,  class = "DEATHKNIGHT", specID = { 252 } },                 -- Shambling Rush
	[96268]  = { default = false, duration = 30,  class = "DEATHKNIGHT" },                                   -- Death's Advance
	[108194] = { default = false, duration = 30,  class = "DEATHKNIGHT" },                                   -- Asphyxiate
	[108201] = { default = false, duration = 120, class = "DEATHKNIGHT" },                                   -- Desecrated Ground
	[152279] = { default = false, duration = 120, class = "DEATHKNIGHT" },                                   -- Breath of Sindragosa
	[498]    = { default = false, duration = 30,  class = "PALADIN" },                                       -- Divine Protection
	[642]    = { default = false, duration = 150, class = "PALADIN" },                                       -- Divine Shield
	[853]    = { default = false, duration = 60,  class = "PALADIN" },                                       -- Hammer of Justice
	    [105593] = { parent = 853, duration = 30 },                                                          -- Fist of Justice
	[1022]   = { default = false, duration = 300, class = "PALADIN", charges = 2 },                          -- Hand of Protection
	[1044]   = { default = false, duration = 25,  class = "PALADIN", charges = 2 },                          -- Hand of Freedom
	[6940]   = { default = false, duration = { default = 90, [65] = 110 }, class = "PALADIN", charges = 2 }, -- Hand of Sacrifice
	[20066]  = { default = false, duration = 15,  class = "PALADIN" },                                       -- Repentance
	[31821]  = { default = false, duration = 180, class = "PALADIN", specID = { 65 } },                      -- Devotion Aura
	[31884]  = { default = false, duration = 120, class = "PALADIN" },                                       -- Avenging Wrath
	[96231]  = { default = true,  duration = 15,  class = "PALADIN" },                                       -- Rebuke
	[114039] = { default = false, duration = 30,  class = "PALADIN" },                                       -- Hand of Purity
	[114157] = { default = false, duration = 60,  class = "PALADIN" },                                       -- Execution Sentence
	[115750] = { default = false, duration = 120, class = "PALADIN" },                                       -- Blinding Light
	[871]    = { default = false, duration = 180, class = "WARRIOR", specID = { 73 } },                      -- Shield Wall
	[1719]   = { default = false, duration = 180, class = "WARRIOR", specID = { 71, 72 } },                  -- Recklessness
	[3411]   = { default = false, duration = 30,  class = "WARRIOR" },                                       -- Intervene
	[5246]   = { default = false, duration = 90,  class = "WARRIOR" },                                       -- Intimidating Shout
	[6544]   = { default = false, duration = 45,  class = "WARRIOR" },                                       -- Heroic Leap
	[6552]   = { default = true,  duration = 15,  class = "WARRIOR" },                                       -- Pummel
	[18499]  = { default = false, duration = 30,  class = "WARRIOR" },                                       -- Berserker Rage
	[23920]  = { default = false, duration = 25,  class = "WARRIOR" },                                       -- Spell Reflection
		[114028] = { parent = 23920, duration = 30 },                                                        -- Mass Spell Reflection
	[46968]  = { default = false, duration = 20,  class = "WARRIOR" },                                       -- Shockwave
	[107570] = { default = false, duration = 30,  class = "WARRIOR" },                                       -- Storm Bolt
	[107574] = { default = false, duration = 90,  class = "WARRIOR" },                                       -- Avatar
	[114029] = { default = false, duration = 30,  class = "WARRIOR" },                                       -- Safeguard
	[118000] = { default = false, duration = 60,  class = "WARRIOR" },                                       -- Dragon Roar
	[118038] = { default = false, duration = 120, class = "WARRIOR", specID = { 71, 72 } },                  -- Die by the Sword
	[99]     = { default = false, duration = 30,  class = "DRUID" },                                         -- Disorienting Roar
	[740]    = { default = false, duration = 180, class = "DRUID" },                                         -- Tranquility
	[5211]   = { default = false, duration = 50,  class = "DRUID" },                                         -- Bash
	[22812]  = { default = false, duration = 60,  class = "DRUID", specID = { 102, 104, 105 } },             -- Barkskin
	[33891]  = { default = false, duration = 180, class = "DRUID", specID = { 105 } },                       -- Incarnation: Tree of Life
	[50334]  = { default = false, duration = 180, class = "DRUID", specID = { 103, 104 } },                  -- Berserk
	[61336]  = { default = false, duration = 180, class = "DRUID", specID = { 103, 104 }, charges = 2 },     -- Survival Instincts
	[78675]  = { default = true,  duration = 60,  class = "DRUID", specID = { 102 } },                       -- Solar Beam
	[102280] = { default = false, duration = 30,  class = "DRUID" },                                         -- Displacer Beast
	[102342] = { default = false, duration = 60,  class = "DRUID", specID = { 105 } },                       -- Ironbark
	[102359] = { default = false, duration = 30,  class = "DRUID" },                                         -- Mass Entanglement
	[102543] = { default = false, duration = 180, class = "DRUID", specID = { 103 } },                       -- Incarnation: King of the Jungle
	[102560] = { default = false, duration = 180, class = "DRUID", specID = { 102 } },                       -- Incarnation: Chosen of Elune
	[106839] = { default = true,  duration = 15,  class = "DRUID", specID = { 103, 104 } },                  -- Skull Bash
	[108291] = { default = false, duration = 360, class = "DRUID" },                                         -- Heart of the Wild (Balance)
		[108292] = { parent = 108291 },                                                                      -- Heart of the Wild (Feral)
		[108293] = { parent = 108291 },                                                                      -- Heart of the Wild (Guardian)
		[108294] = { parent = 108291 },                                                                      -- Heart of the Wild (Resto)
	[112071] = { default = false, duration = 180, class = "DRUID", specID = { 102 } },                       -- Celestial Alignment
	[124974] = { default = false, duration = 90,  class = "DRUID" },                                         -- Nature's Vigil
	[132158] = { default = false, duration = 60,  class = "DRUID", specID = { 105 } },                       -- Nature's Swiftness
	[132469] = { default = false, duration = 30,  class = "DRUID" },                                         -- Typhoon
	[159630] = { default = false, duration = 90,  class = "PRIEST", specID = { 256, 257 } },                 -- Shadow Magic
	[8122]   = { default = false, duration = 30,  class = "PRIEST" },                                        -- Psychic Scream
	[15487]  = { default = true,  duration = 45,  class = "PRIEST", specID = { 256, 258 } },                 -- Silence
	[33206]  = { default = false, duration = 120, class = "PRIEST", specID = { 256 } },                      -- Pain Suppression
	[47585]  = { default = false, duration = 120, class = "PRIEST", specID = { 258 } },                      -- Dispersion
	[47788]  = { default = false, duration = 180, class = "PRIEST", specID = { 257 } },                      -- Guardian Spirit
	[64044]  = { default = false, duration = 45,  class = "PRIEST", specID = { 258 } },                      -- Psychic Horror
	[73325]  = { default = false, duration = 90,  class = "PRIEST" },                                        -- Leap of Faith
	[5484]   = { default = false, duration = 40,  class = "WARLOCK" },                                       -- Howl of Terror
	[6360]   = { default = false, duration = 25,  class = "WARLOCK" },                                       -- Whiplash
	[6789]   = { default = false, duration = 45,  class = "WARLOCK" },                                       -- Mortal Coil
	[19505]  = { default = false, duration = 15,  class = "WARLOCK" },                                       -- Devour Magic (Felhunter)
	[30283]  = { default = false, duration = 30,  class = "WARLOCK" },                                       -- Shadowfury
	[48020]  = { default = false, duration = 26,  class = "WARLOCK" },                                       -- Demonic Portal
	[89766]  = { default = false, duration = 30,  class = "WARLOCK" },                                       -- Axe Toss
	[108482] = { default = false, duration = 120, class = "WARLOCK" },                                       -- Unbound Will
	[119910] = { default = true,  duration = 24,  class = "WARLOCK" },                                       -- Spell Lock (Command Demon)
	    [19647]  = { parent = 119910 },                                                                      -- Spell Lock (Felhunter)
	    [119911] = { parent = 119910 },                                                                      -- Optical Blast (Command Demon)
	    [115781] = { parent = 119910 },                                                                      -- Optical Blast (Observer)
	    [132409] = { parent = 119910 },                                                                      -- Spell Lock (Grimoire of Sacrifice)
	    [171138] = { parent = 119910 },                                                                      -- Shadow Lock (Doomguard)
	    [171139] = { parent = 119910 },                                                                      -- Shadow Lock (Grimoire of Sacrifice)
	    [171140] = { parent = 119910 },                                                                      -- Shadow Lock (Command Demon)
	[111859] = { default = false, duration = 120, class = "WARLOCK" },                                       -- Grimoire: Imp
	[111896] = { default = false, duration = 120, class = "WARLOCK" },                                       -- Grimoire: Succubus
	[111897] = { default = true,  duration = 120, class = "WARLOCK" },                                       -- Grimoire: Felhunter
	[77801]  = { default = false, duration = 120, class = "WARLOCK", charges = 2 },                          -- Dark Soul
		[113858] = { parent = 77801 },                                                                       -- Dark Soul: Instability
		[113860] = { parent = 77801 },                                                                       -- Dark Soul: Misery
		[113861] = { parent = 77801 },                                                                       -- Dark Soul: Knowledge
	[115284] = { default = false, duration = 15,  class = "WARLOCK" },                                       -- Clone Magic (Observer)
	[115770] = { default = false, duration = 25,  class = "WARLOCK" },                                       -- Fellash
	[8143]   = { default = false, duration = 60,  class = "SHAMAN" },                                        -- Tremor Totem
	[8177]   = { default = false, duration = 25,  class = "SHAMAN" },                                        -- Grounding Totem
	[30823]  = { default = false, duration = 60,  class = "SHAMAN", specID = { 262, 263 } },                 -- Shamanistic Rage
	[51490]  = { default = false, duration = 45,  class = "SHAMAN", specID = { 262, 263 } },                 -- Thunderstorm
	[51514]  = { default = false, duration = 45,  class = "SHAMAN" },                                        -- Hex
	[57994]  = { default = true,  duration = 12,  class = "SHAMAN" },                                        -- Wind Shear
	[98008]  = { default = false, duration = 180, class = "SHAMAN" },                                        -- Spirit Link Totem
	[108269] = { default = false, duration = 45,  class = "SHAMAN" },                                        -- Capacitor Totem
	[108271] = { default = false, duration = 90,  class = "SHAMAN" },                                        -- Astral Shift
	[108273] = { default = false, duration = 60,  class = "SHAMAN" },                                        -- Windwalk Totem
	[108285] = { default = false, duration = 180, class = "SHAMAN" },                                        -- Call of the Elements
	[114049] = { default = false, duration = 180, class = "SHAMAN" },                                        -- Ascendance
		[114050] = { parent = 114049 },                                                                      -- Ascendance (Elemental)
		[114051] = { parent = 114049 },                                                                      -- Ascendance (Enhancement)
		[114052] = { parent = 114049 },                                                                      -- Ascendance (Restoration)
	[1499]   = { default = false, duration = { default = 20, [253] = 30, [254] = 30 }, class = "HUNTER" },   -- Freezing Trap
	    [60192] = { parent = 1499 },                                                                         -- Freezing Trap (Trap Launcher)
	[13813]  = { default = false, duration = { default = 20, [253] = 30, [254] = 30 }, class = "HUNTER" },   -- Explosive Trap
	    [82939] = { parent = 13813 },                                                                        -- Explosive Trap (Trap Launcher)
	[19263]  = { default = false, duration = 180, class = "HUNTER", charges = 2 },                           -- Deterrence
	[19386]  = { default = false, duration = 45,  class = "HUNTER" },                                        -- Wyvern Sting
	[19574]  = { default = false, duration = 60,  class = "HUNTER", specID = { 253 } },                      -- Bestial Wrath
	[53480]  = { default = false, duration = 60,  class = "HUNTER" },                                        -- Roar of Sacrifice
	[131894] = { default = false, duration = 60,  class = "HUNTER" },                                        -- A Murder of Crows
	[147362] = { default = true,  duration = 24,  class = "HUNTER" },                                        -- Counter Shot
	[66]     = { default = false, duration = 300, class = "MAGE" },                                          -- Invisibility
	[1953]   = { default = false, duration = 15,  class = "MAGE" },                                          -- Blink
	[2139]   = { default = true,  duration = 24,  class = "MAGE" },                                          -- Counterspell
	[11129]  = { default = false, duration = 45,  class = "MAGE", specID = { 63 } },                         -- Combustion
	[11958]  = { default = false, duration = 180, class = "MAGE" },                                          -- Cold Snap
	[12043]  = { default = false, duration = 90,  class = "MAGE", specID = { 62 } },                         -- Presence of Mind
	[12472]  = { default = false, duration = 180, class = "MAGE", specID = { 64 } },                         -- Icy Veins
	[31661]  = { default = false, duration = 20,  class = "MAGE", specID = { 63 } },                         -- Dragon's Breath
	[44572]  = { default = false, duration = 30,  class = "MAGE", specID = { 64 } },                         -- Deep Freeze
	[45438]  = { default = false, duration = 300, class = "MAGE" },                                          -- Ice Block
	[84714]  = { default = false, duration = 60,  class = "MAGE", specID = { 64 } },                         -- Frozen Orb
	[102051] = { default = false, duration = 20,  class = "MAGE" },                                          -- Frostjaw
	[113724] = { default = false, duration = 45,  class = "MAGE" },                                          -- Ring of Frost
	[157997] = { default = false, duration = 25,  class = "MAGE", specID = { 64 }, charges = 2 },            -- Ice Nova
	[408]    = { default = false, duration = 20,  class = "ROGUE" },                                         -- Kidney Shot
	[1766]   = { default = true,  duration = 15,  class = "ROGUE" },                                         -- Kick
	[1856]   = { default = false, duration = { default = 60, [261] = 120 }, class = "ROGUE" },               -- Vanish
	[2094]   = { default = false, duration = 120, class = "ROGUE" },                                         -- Blind
	[2983]   = { default = false, duration = 60,  class = "ROGUE" },                                         -- Sprint
	[5277]   = { default = false, duration = 180, class = "ROGUE" },                                         -- Evasion
	[13750]  = { default = false, duration = 180, class = "ROGUE", specID = { 260 } },                       -- Adrenaline Rush
	[14185]  = { default = false, duration = 300, class = "ROGUE" },                                         -- Preparation
	[31224]  = { default = false, duration = 60,  class = "ROGUE" },                                         -- Cloak of Shadows
	[36554]  = { default = false, duration = 20,  class = "ROGUE" },                                         -- Shadow Step
	[51690]  = { default = false, duration = 120, class = "ROGUE", specID = { 260} },                        -- Killing Spree
	[51713]  = { default = false, duration = 60,  class = "ROGUE", specID = { 261 } },                       -- Shadow Dance
	[74001]  = { default = false, duration = 120, class = "ROGUE" },                                         -- Combat Readiness
	[76577]  = { default = false, duration = 180, class = "ROGUE" },                                         -- Smoke Bomb
	[113656] = { default = false, duration = 25,  class = "MONK", specID = { 269 } },                        -- Fists of Fury
	[115176] = { default = false, duration = 180, class = "MONK", specID = { 268, 269 } },                   -- Zen Meditation
	[115203] = { default = false, duration = 180, class = "MONK" },                                          -- Fortifying Brew
	[115310] = { default = false, duration = 180, class = "MONK" },                                          -- Revival
	[116705] = { default = true,  duration = 15,  class = "MONK" },                                          -- Spear Hand Strike
	[116844] = { default = false, duration = 45,  class = "MONK" },                                          -- Ring of Peace
	[116849] = { default = false, duration = 55,  class = "MONK", specID = { 270 } },                        -- Life Cocoon
	[119381] = { default = false, duration = 45,  class = "MONK" },                                          -- Leg Sweep
	[119996] = { default = false, duration = 25,  class = "MONK" },                                          -- Transcendence: Transfer
	[122470] = { default = false, duration = 90,  class = "MONK", specID = { 269 } },                        -- Touch of Karma
	[122783] = { default = false, duration = 90,  class = "MONK" },                                          -- Diffuse Magic
	[137562] = { default = false, duration = 120, class = "MONK" },                                          -- Nimble Brew
}

local cooldowns = OmniBar.cooldowns

local order = {
	["DEATHKNIGHT"] = 1,
	["PALADIN"] = 2,
	["WARRIOR"] = 3,
	["DRUID"] = 4,
	["PRIEST"] = 5,
	["WARLOCK"] = 6,
	["SHAMAN"] = 7,
	["HUNTER"] = 8,
	["MAGE"] = 9,
	["ROGUE"] = 10,
	["MONK"] = 11,
}

local resets = {
	--[[ Summon Felhunter
	     - Spell Lock
	  ]]
	[691] = { 119910 },

	--[[ Cold Snap
	     - Ice Block
	     - Presence of Mind
	     - Dragon's Breath
	  ]]
	[11958] = { 45438, 12043, 31661 },

	--[[ Preparation
	     - Sprint
	     - Vanish
	     - Evasion
	  ]]
	[14185] = { 2983, 1856, 5277 },

	--[[ Call of the Elements
	     - Tremor Totem
	     - Grounding Totem
	     - Capacitor Totem
	     - Windwalk Totem
	  ]]
	[108285] = { 8143, 8177, 108269, 108273 },
}

-- Defaults
local defaults = {
	size                 = 40,
	columns              = 8,
	padding              = 2,
	locked               = false,
	center               = false,
	border               = true,
	highlightTarget      = true,
	highlightFocus       = false,
	growUpward           = true,
	showUnused           = false,
	adaptive             = false,
	unusedAlpha          = 0.45,
	swipeAlpha           = 0.65,
	cooldownCount        = true,
	arena                = true,
	ratedBattleground    = true,
	battleground         = true,
	world                = true,
	ashran               = true,
	multiple             = true,
	glow                 = true,
	tooltips             = true,
	names                = false,
	maxIcons             = 500,
	align                = "CENTER",
}

local SETTINGS_VERSION = 3

local MAX_DUPLICATE_ICONS = 5

local BASE_ICON_SIZE = 36

local ASHRAN_MAP_ID = 978

local _

OmniBar.index = 1

OmniBar.bars = {}

function OmniBar:OnEnable()
	if not OmniBarDB or not OmniBarDB.version or OmniBarDB.version < SETTINGS_VERSION then OmniBarDB = { version = SETTINGS_VERSION } end

	self.db = LibStub("AceDB-3.0"):New("OmniBarDB", { profile = { bars = {} } }, true)
	
	self.index = 1

	for i = #self.bars, 1, -1 do
		OmniBar: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

	if not self.registered then
		self.db.RegisterCallback(self, "OnProfileChanged", "OnEnable")
		self.db.RegisterCallback(self, "OnProfileCopied", "OnEnable")
		self.db.RegisterCallback(self, "OnProfileReset", "OnEnable")

		self:SetupOptions()
		self.registered = true
	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("COMBAT_LOG_EVENT_UNFILTERED")
	bar:UnregisterEvent("PLAYER_ENTERING_WORLD")
	bar:UnregisterEvent("ZONE_CHANGED_NEW_AREA")
	bar:UnregisterEvent("PLAYER_TARGET_CHANGED")
	bar:UnregisterEvent("PLAYER_FOCUS_CHANGED")
	bar:UnregisterEvent("PLAYER_REGEN_DISABLED")
	bar:UnregisterEvent("ARENA_OPPONENT_UPDATE")
	bar:UnregisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
	bar:UnregisterEvent("UPDATE_BATTLEFIELD_SCORE")
	bar:UnregisterEvent("UPDATE_BATTLEFIELD_STATUS")
	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

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

	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 500
	f.key = key
	f.icons = {}
	f.active = {}
	f.cooldowns = cooldowns
	f.detected = {}
	f.specs = {}
	f.BASE_ICON_SIZE = BASE_ICON_SIZE
	f.numIcons = 0
	f:RegisterForDrag("LeftButton")

	local name = f.settings.name
	f.anchor.text:SetText(name)

	-- Load the settings
	OmniBar_LoadSettings(f)

	-- Create the icons
	for spellID,_ in pairs(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_RefreshIcons(f)
	OmniBar_UpdateIcons(f)
	OmniBar_Center(f)

	f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
	f:RegisterEvent("PLAYER_ENTERING_WORLD")
	f:RegisterEvent("ZONE_CHANGED_NEW_AREA")
	f:RegisterEvent("PLAYER_TARGET_CHANGED")
	f:RegisterEvent("PLAYER_FOCUS_CHANGED")
	f:RegisterEvent("PLAYER_REGEN_DISABLED")
	f:RegisterEvent("ARENA_OPPONENT_UPDATE")
	f:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
	f:RegisterEvent("UPDATE_BATTLEFIELD_SCORE")
	f:RegisterEvent("UPDATE_BATTLEFIELD_STATUS")

	table.insert(self.bars, f)
end


function OmniBar:Create()

	local key

	while true do
		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)
			return
		end
	end
	
end

function OmniBar:Refresh(full)
	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
				OmniBar_OnEvent(f, "PLAYER_ENTERING_WORLD")
			else
				OmniBar_LoadPosition(f)
				OmniBar_UpdateIcons(f)
				OmniBar_Center(f)
			end
		end
	end
end

local Masque = LibStub and LibStub("Masque", true)

for spellID,_ in pairs(cooldowns) do
	local name, _, icon = GetSpellInfo(spellID)
	cooldowns[spellID].icon = icon
	cooldowns[spellID].name = name
end

-- create a lookup table to translate spec names into IDs
local specNames = {}
for classID = 1, MAX_CLASSES do
	local _, classToken = GetClassInfoByID(classID)
	specNames[classToken] = {}
	for i = 1, GetNumSpecializationsForClassID(classID) do
		local id, name = GetSpecializationInfoForClassID(classID, i)
		specNames[classToken][name] = id
	end
end

local function IsHostilePlayer(unit)
	if not 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 cooldowns[spellID].specID then return true end
	for i = 1, #cooldowns[spellID].specID do
		if cooldowns[spellID].specID[i] == specID then return true end
	end
	return false
end

function OmniBar_AddIconsByClass(self, class, sourceGUID, specID)
	for spellID, spell in pairs(cooldowns) do
		if OmniBar_IsSpellEnabled(self, spellID) and spell.class == class and SpellBelongsToSpec(spellID, specID) then
			OmniBar_AddIcon(self, spellID, sourceGUID, nil, true, nil, specID)
		end
	end
end

local function IconIsSource(iconGUID, guid)
	if not guid then return end
	if string.len(iconGUID) == 1 then
		-- arena target
		return UnitGUID("arena"..iconGUID) == guid
	end
	return iconGUID == guid
end

function OmniBar_UpdateBorders(self)
	for i = 1, #self.active do
		local border
		local guid = self.active[i].sourceGUID
		if guid then
			if self.settings.highlightFocus and IconIsSource(guid, UnitGUID("focus")) then
				self.active[i].FocusTexture:SetAlpha(1)
				border = true
			else
				self.active[i].FocusTexture:SetAlpha(0)
			end
			if self.settings.highlightTarget and IconIsSource(guid, UnitGUID("target")) then
				self.active[i].FocusTexture:SetAlpha(0)
				self.active[i].TargetTexture:SetAlpha(1)
				border = true
			else
				self.active[i].TargetTexture:SetAlpha(0)
			end
		else
			local class = select(2, UnitClass("focus"))
			if self.settings.highlightFocus and class and IsHostilePlayer("focus") and class == self.active[i].class then
				self.active[i].FocusTexture:SetAlpha(1)
				border = true
			else
				self.active[i].FocusTexture:SetAlpha(0)
			end
			class = select(2, UnitClass("target"))
			if self.settings.highlightTarget and class and IsHostilePlayer("target") and class == self.active[i].class then
				self.active[i].FocusTexture:SetAlpha(0)
				self.active[i].TargetTexture:SetAlpha(1)
				border = true
			else
				self.active[i].TargetTexture:SetAlpha(0)
			end
		end

		-- Set dim
		self.active[i]:SetAlpha(self.settings.unusedAlpha and self.active[i].cooldown:GetCooldownTimes() == 0 and not border and
			self.settings.unusedAlpha or 1)
	end
end

function OmniBar_UpdateArenaSpecs(self)
	if self.zone ~= "arena" then return end
	for i = 1, 5 do
		local specID = GetArenaOpponentSpec(i)
		if specID and specID > 0 then
			local name = GetUnitName("arena"..i, true)
			if name then self.specs[name] = specID end
		end
	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
	local rated = IsRatedBattleground()
	self.disabled = (zone == "arena" and not self.settings.arena) or
		(rated and not self.settings.ratedBattleground) or
		(zone == "pvp" and not self.settings.battleground and not rated) or
		(zone == ASHRAN_MAP_ID and not self.settings.ashran) or 
		(zone ~= "arena" and zone ~= "pvp" and zone ~= ASHRAN_MAP_ID and not self.settings.world)

	if refresh or disabled ~= self.disabled then
		OmniBar_LoadPosition(self)
		OmniBar_RefreshIcons(self)
		OmniBar_UpdateIcons(self)
		OmniBar_ShowAnchor(self)
		if zone == "arena" and not self.disabled then
			wipe(self.detected)
			wipe(self.specs)
			OmniBar_OnEvent(self, "ARENA_OPPONENT_UPDATE")
		end
	end
	
end

function OmniBar_OnEvent(self, event, ...)
	if event == "COMBAT_LOG_EVENT_UNFILTERED" then
		local _, event, _, sourceGUID, sourceName, sourceFlags, _,_,_,_,_, spellID = ...
		if self.disabled then return end
		if event == "SPELL_CAST_SUCCESS" and bit.band(sourceFlags, COMBATLOG_OBJECT_REACTION_HOSTILE) ~= 0 then
			if cooldowns[spellID] then
				OmniBar_UpdateArenaSpecs(self)
				OmniBar_AddIcon(self, spellID, sourceGUID, sourceName)
			end

			-- Check if we need to reset any cooldowns
			if resets[spellID] then
				for i = 1, #self.active do
					if self.active[i] and self.active[i].spellID and self.active[i].sourceGUID and self.active[i].sourceGUID == sourceGUID and self.active[i].cooldown:IsVisible() then
						-- cooldown belongs to this source
						for j = 1, #resets[spellID] do
							if resets[spellID][j] == self.active[i].spellID then
								self.active[i].cooldown:Hide()
								OmniBar_CooldownFinish(self.active[i].cooldown, true)
								return
							end
						end
					end
				end
			end
		end

	elseif event == "PLAYER_ENTERING_WORLD" then
		OmniBar_SetZone(self, true)
		
	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
		OmniBar_SetZone(self)

	elseif event == "UPDATE_BATTLEFIELD_SCORE" then
		for i = 1, GetNumBattlefieldScores() do
			local name, _,_,_,_,_,_,_, classToken, _,_,_,_,_,_, talentSpec = GetBattlefieldScore(i)
			if name and specNames[classToken] and specNames[classToken][talentSpec] then
				self.specs[name] = specNames[classToken][talentSpec]
			end
		end

	elseif event == "ARENA_PREP_OPPONENT_SPECIALIZATIONS" or event == "ARENA_OPPONENT_UPDATE" then
		if self.disabled or not self.settings.adaptive then return end

		for i = 1, 5 do
			local specID = GetArenaOpponentSpec(i)
			if specID and specID > 0 then
				-- only add icons if show unused is checked
				if not self.settings.showUnused then return end
				if not self.detected[i] then
					local class = select(7, GetSpecializationInfoByID(specID))
					OmniBar_AddIconsByClass(self, class, i, specID)
					self.detected[i] = class
				end
			end
		end

	elseif event == "PLAYER_TARGET_CHANGED" or event == "PLAYER_FOCUS_CHANGED" or event == "PLAYER_REGEN_DISABLED" then
		if self.disabled then return end

		-- update icon borders
		OmniBar_UpdateBorders(self)

		-- we don't need to add in arena
		if self.zone == "arena" then return end

		-- only add icons if show adaptive is checked
		if not self.settings.showUnused or not self.settings.adaptive then return end

		-- only add icons when we're in combat
		--if event == "PLAYER_TARGET_CHANGED" and not InCombatLockdown() then return end

		local unit = "playertarget"
		if IsHostilePlayer(unit) then
			local guid = UnitGUID(unit)
			local _, class = UnitClass(unit)
			if class then
				if self.detected[guid] then return end
				self.detected[guid] = class
				OmniBar_AddIconsByClass(self, class)
			end
		end
	end
end

function OmniBar_LoadSettings(self)
	
	-- Set the scale
	self.container:SetScale(self.settings.size/BASE_ICON_SIZE)

	OmniBar_LoadPosition(self)
	OmniBar_RefreshIcons(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_LoadPosition(self)
	self:ClearAllPoints()
	if self.settings.position then
		local relativeTo = self.settings.position.relativeTo and self.settings.position.relativeTo or "UIParent"
		self:SetPoint(self.settings.position.point, self.settings.position.relativeTo, self.settings.position.relativePoint,
			self.settings.position.xOfs, self.settings.position.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
	-- Check for an explicit rule
	local key = "spell"..spellID
	if type(self.settings[key]) == "boolean" then
		if self.settings[key] then
			return true
		end
	elseif not self.settings.noDefault and cooldowns[spellID].default then
		-- Not user-set, but a default cooldown
		return true
	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)
			OmniBar_StartCooldown(icon:GetParent():GetParent(), icon, GetTime())
			return
		end
	end

	local bar = icon:GetParent():GetParent()

	local flash = icon.flashAnim
	local newItemGlowAnim = icon.newitemglowAnim

	if flash:IsPlaying() or newItemGlowAnim:IsPlaying() then
		flash:Stop()
		newItemGlowAnim:Stop()
	end

	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_RefreshIcons(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 and not self.settings.adaptive then
		for spellID,_ in pairs(cooldowns) do
			if OmniBar_IsSpellEnabled(self, spellID) then
				OmniBar_AddIcon(self, spellID, nil, nil, true)
			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, spellID, sourceGUID, sourceName, init, test, specID)
	-- Check for parent spellID
	local originalSpellID = spellID
	if cooldowns[spellID].parent then spellID = cooldowns[spellID].parent end

	if not OmniBar_IsSpellEnabled(self, spellID) then return end

	local icon, duplicate

	-- Try to reuse a visible frame
	for i = 1, #self.active do
		if self.active[i].spellID == spellID then
			duplicate = true
			-- check if we can use this icon, but not when initializing arena opponents
			if not init 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 sourceGUID and IconIsSource(self.active[i].sourceGUID, 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

	local now = GetTime()

	if specID then
		icon.specID = specID
	else
		if sourceName and sourceName ~= COMBATLOG_FILTER_STRING_UNKNOWN_UNITS and self.specs[sourceName] then
			icon.specID = self.specs[sourceName]
		end
	end

	icon.class = cooldowns[spellID].class
	icon.sourceGUID = sourceGUID
	icon.icon:SetTexture(cooldowns[spellID].icon)
	icon.spellID = spellID
	icon.added = now

	if icon.charges and cooldowns[originalSpellID].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)
			if self.settings.glow then
				icon.flashAnim:Play()
				icon.newitemglowAnim:Play()
			end
			return icon
		end
	elseif cooldowns[originalSpellID].charges then
		icon.charges = 1
		icon.Count:SetText("1")
	else
		icon.charges = nil
		icon.Count:SetText(nil)
	end

	local name = self.settings.names and sourceGUID and select(6, GetPlayerInfoByGUID(sourceGUID))
	if test and self.settings.names then name = "Name" end
	icon.Name:SetText(name)

	if cooldowns[originalSpellID].duration then
		if type(cooldowns[originalSpellID].duration) == "table" then
			if icon.specID and cooldowns[originalSpellID].duration[icon.specID] then
				icon.duration = cooldowns[originalSpellID].duration[icon.specID]
			else
				icon.duration = cooldowns[originalSpellID].duration.default
			end
		else
			icon.duration = cooldowns[originalSpellID].duration
		end
	else -- child doesn't have a custom duration, use parent
		if type(cooldowns[spellID].duration) == "table" then
			if icon.specID and cooldowns[spellID].duration[icon.specID] then
				icon.duration = cooldowns[spellID].duration[icon.specID]
			else
				icon.duration = cooldowns[spellID].duration.default
			end
		else
			icon.duration = cooldowns[spellID].duration
		end
	end

	-- We don't want duration to be too long if we're just testing
	if test then icon.duration = math.random(5,30) end

	-- Masque
	if Masque then
		icon.MasqueGroup = Masque:Group("OmniBar", cooldowns[spellID].name)
		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 not init then
		OmniBar_StartCooldown(self, icon, now)
		if self.settings.glow then
			icon.flashAnim:Play()
			icon.newitemglowAnim:Play()
		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 = self.settings.cooldownCount and false

		-- 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)
	self.disabled = nil
	OmniBar_RefreshIcons(self)
	for k,v in pairs(cooldowns) do
		OmniBar_AddIcon(self, k, nil, nil, nil, true)
	end
end

local function ExtractDigits(str)
	if not str then return 0 end
	if type(str) == "number" then return str end
	local num = str:gsub("%D", "")
	return tonumber(num) or 0
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 = ExtractDigits(a.sourceGUID), ExtractDigits(b.sourceGUID)
			if a.class == b.class then
				if x < y then return true end
				if x == y then return a.spellID < b.spellID end
			end
			return order[a.class] < order[b.class]
		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
  Reply With Quote
05-12-16, 02:38 PM   #3
hasnogaems
A Flamescale Wyrmkin
 
hasnogaems's Avatar
Join Date: Apr 2016
Posts: 109
Come on guys! It's can't be so hard!
  Reply With Quote
05-12-16, 02:43 PM   #4
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by hasnogaems View Post
Come on guys! It's can't be so hard!
It's not, swap all SetAlpha(1) to SetAlpha(0) and SetAlpha(0) to SetAlpha(1).
  Reply With Quote
06-02-16, 03:28 AM   #5
hasnogaems
A Flamescale Wyrmkin
 
hasnogaems's Avatar
Join Date: Apr 2016
Posts: 109
I did it, and it's basically broke now. Unused ability icons look pretty weird http://imgur.com/M6CS6uo and cooldown icon just stop showing now. Unused icon currently just dissapear and cooldown icond doesnt show up when ability was used. Thank you for answer anyway, sincerely, and sorry for my messy english. Still looking for help with my issue doe.
  Reply With Quote
11-18-19, 10:23 PM   #6
hasnogaems
A Flamescale Wyrmkin
 
hasnogaems's Avatar
Join Date: Apr 2016
Posts: 109
I can assume this addon will do https://www.wowinterface.com/downloa...o.php?id=22826
Did not tried it yet.
  Reply With Quote

WoWInterface » AddOns, Compilations, Macros » AddOn Help/Support » Edit omnibar

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off