----------------------------------------------------------------------------- -- Addon declaration local Omen = LibStub("AceAddon-3.0"):NewAddon("Omen", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0", "LibSink-2.0") local L = LibStub("AceLocale-3.0"):GetLocale("Omen", false) local LSM = LibStub("LibSharedMedia-3.0") local LDB = LibStub("LibDataBroker-1.1", true) local LDBIcon = LDB and LibStub("LibDBIcon-1.0", true) Omen.version = GetAddOnMetadata("Omen", "Version") Omen.versionstring = "Omen v"..GetAddOnMetadata("Omen", "Version") _G["Omen"] = Omen ----------------------------------------------------------------------------- -- Keybinding globals BINDING_HEADER_OMEN = Omen.versionstring BINDING_NAME_OMENTOGGLE = L["Toggle Omen"] BINDING_NAME_OMENTOGGLEFOCUS = L["Toggle Focus"] ----------------------------------------------------------------------------- -- Register some media LSM:Register("sound", "Rubber Ducky", [[Sound\Doodad\Goblin_Lottery_Open01.wav]]) LSM:Register("sound", "Cartoon FX", [[Sound\Doodad\Goblin_Lottery_Open03.wav]]) LSM:Register("sound", "Explosion", [[Sound\Doodad\Hellfire_Raid_FX_Explosion05.wav]]) LSM:Register("sound", "Shing!", [[Sound\Doodad\PortcullisActive_Closed.wav]]) LSM:Register("sound", "Wham!", [[Sound\Doodad\PVP_Lordaeron_Door_Open.wav]]) LSM:Register("sound", "Simon Chime", [[Sound\Doodad\SimonGame_LargeBlueTree.wav]]) LSM:Register("sound", "War Drums", [[Sound\Event Sounds\Event_wardrum_ogre.wav]]) LSM:Register("sound", "Cheer", [[Sound\Event Sounds\OgreEventCheerUnique.wav]]) LSM:Register("sound", "Humm", [[Sound\Spells\SimonGame_Visual_GameStart.wav]]) LSM:Register("sound", "Short Circuit", [[Sound\Spells\SimonGame_Visual_BadPress.wav]]) LSM:Register("sound", "Fel Portal", [[Sound\Spells\Sunwell_Fel_PortalStand.wav]]) LSM:Register("sound", "Fel Nova", [[Sound\Spells\SeepingGaseous_Fel_Nova.wav]]) LSM:Register("sound", "You Will Die!", [[Sound\Creature\CThun\CThunYouWillDIe.wav]]) LSM:Register("sound", "Omen: Aoogah!", [[Interface\AddOns\Omen\aoogah.ogg]]) ----------------------------------------------------------------------------- -- Localize some global functions local floor, format, random, pairs, type = floor, format, random, pairs, type local tinsert, tremove, next, sort, wipe = tinsert, tremove, next, sort, wipe local RAID_CLASS_COLORS = RAID_CLASS_COLORS local UnitDetailedThreatSituation = UnitDetailedThreatSituation local UnitExists, UnitGUID, UnitName, UnitClass, UnitHealth = UnitExists, UnitGUID, UnitName, UnitClass, UnitHealth local UnitIsPlayer, UnitPlayerControlled, UnitCanAttack = UnitIsPlayer, UnitPlayerControlled, UnitCanAttack local GetNumRaidMembers, GetNumPartyMembers = GetNumRaidMembers, GetNumPartyMembers ----------------------------------------------------------------------------- -- Local variables used local db local defaults = { profile = { Alpha = 1, Scale = 1, GrowUp = false, Autocollapse = false, NumBars = 10, CollapseHide = false, Locked = false, PositionW = 200, PositionH = 82, VGrip1 = 85, VGrip2 = 115, UseFocus = false, IgnorePlayerPets = true, FrameStrata = "3-MEDIUM", ClampToScreen = true, ClickThrough = false, Background = { Texture = "Blizzard Parchment", BorderTexture = "Blizzard Dialog", Color = {r = 1, g = 1, b = 1, a = 1,}, BorderColor = {r = 0.8, g = 0.6, b = 0, a = 1,}, Tile = false, TileSize = 32, EdgeSize = 8, BarInset = 3, }, TitleBar = { Height = 16, Font = "Friz Quadrata TT", FontOutline = "", FontColor = {r = 1, g = 1, b = 1, a = 1,}, FontSize = 10, ShowTitleBar = true, UseSameBG = true, Texture = "Blizzard Parchment", BorderTexture = "Blizzard Dialog", Color = {r = 1, g = 1, b = 1, a = 1,}, BorderColor = {r = 0.8, g = 0.6, b = 0, a = 1,}, Tile = false, TileSize = 32, EdgeSize = 8, }, Bar = { Texture = "Blizzard", Height = 12, Spacing = 0, AnimateBars = true, ShortNumbers = true, Font = "Friz Quadrata TT", FontOutline = "", FontColor = {r = 1, g = 1, b = 1, a = 1,}, FontSize = 10, Classes = { DEATHKNIGHT = true, DRUID = true, HUNTER = true, MAGE = true, PALADIN = true, PET = true, PRIEST = true, ROGUE = true, SHAMAN = true, WARLOCK = true, WARRIOR = true, HERO = true, ["*NOTINPARTY*"] = true, }, ShowTPS = true, TPSWindow = 10, ShowHeadings = true, HeadingBGColor = {r = 0, g = 0, b = 0, a = 0,}, UseMyBarColor = false, MyBarColor = {r = 1, g = 0, b = 0, a = 1,}, ShowPercent = true, ShowValue = true, UseClassColors = true, BarColor = {r = 1, g = 0, b = 0, a = 1,}, UseTankBarColor = false, TankBarColor = {r = 1, g = 0, b = 0, a = 1,}, AlwaysShowSelf = true, ShowAggroBar = true, AggroBarColor = {r = 1, g = 0, b = 0, a = 1,}, PetBarColor = {r = 0.77, g = 0, b = 1, a = 1}, FadeBarColor = {r = 0.5, g = 0.5, b = 0.5, a = 1}, UseCustomClassColors = true, InvertColors = false, }, ShowWith = { UseShowWith = true, Pet = true, Alone = false, Party = true, Raid = true, -- Deprecated SV values -- Resting = false, PVP = false, Dungeon = true, ShowOnlyInCombat = false, HideWhileResting = true, HideInPVP = true, HideWhenOOC = false, }, FuBar = { HideMinimapButton = true, AttachMinimap = false, }, Warnings = { Sound = true, Flash = true, Shake = false, Message = false, SinkOptions = {}, Threshold = 90, SoundFile = "Fel Nova", DisableWhileTanking = true, }, MinimapIcon = { hide = false, minimapPos = 220, radius = 80, }, }, } local guidNameLookup = {} -- Format: guidNameLookup[guid] = "Unit Name" local guidClassLookup = {} -- Format: guidClassLookup[guid] = "CLASS" local timers = {} -- Format: timers.timerName = timer returned from AceTimer-3.0 local bars = {} -- Format: bars[i] = frame containing the i-th bar from the top of Omen local inRaid, inParty -- boolean variables indicating if the player is in a raid and/or party local testMode = false -- boolean: Are we in test mode? local manualToggle = false -- boolean: Did we manually toggle Omen? local moduleOptions = {} -- Table for LoD module options registration Omen.GuidNameLookup = guidNameLookup Omen.GuidClassLookup = guidClassLookup Omen.Timers = timers Omen.Bars = bars setmetatable(guidNameLookup, {__index = function(self, guid) return L[""] end}) -- For speedups. Rather than concantenating every time we need a unitID, we just look -- it up instead. That is rID[i] is much faster than format("raid%d", i) or "raid"..i local pID = {} local ptID = {} local ppID = {} local pptID = {} local rID = {} local rtID = {} local rpID = {} local rptID = {} for i = 1, 4 do pID[i] = format("party%d", i) ptID[i] = format("party%dtarget", i) ppID[i] = format("partypet%d", i) pptID[i] = format("partypet%dtarget", i) end for i = 1, 40 do rID[i] = format("raid%d", i) rtID[i] = format("raid%dtarget", i) rpID[i] = format("raidpet%d", i) rptID[i] = format("raidpet%dtarget", i) end local showClassesOptionTable = { DEATHKNIGHT = L["DEATHKNIGHT"], DRUID = L["DRUID"], HUNTER = L["HUNTER"], MAGE = L["MAGE"], PALADIN = L["PALADIN"], PET = L["PET"], PRIEST = L["PRIEST"], ROGUE = L["ROGUE"], SHAMAN = L["SHAMAN"], WARLOCK = L["WARLOCK"], WARRIOR = L["WARRIOR"], HERO = L["HERO"], ["*NOTINPARTY*"] = L["*Not in Party*"], } ---------------------------------------------------------------------------------------- -- Use a common frame and setup some common functions for the Omen dropdown menus local Omen_DropDownMenu = CreateFrame("Frame", "Omen_DropDownMenu") Omen_DropDownMenu.displayMode = "MENU" Omen_DropDownMenu.info = {} Omen_DropDownMenu.HideMenu = function() if UIDROPDOWNMENU_OPEN_MENU == Omen_DropDownMenu then CloseDropDownMenus() end end Omen_DropDownMenu.OnClick = function(frame, button, down) if Omen_DropDownMenu.initialize ~= frame.initMenuFunc then CloseDropDownMenus() Omen_DropDownMenu.initialize = frame.initMenuFunc end ToggleDropDownMenu(1, nil, Omen_DropDownMenu, frame, 0, 0) end ----------------------------------------------------------------------------- -- Table Pool for recycling tables local tablePool = {} setmetatable(tablePool, {__mode = "kv"}) -- Weak table -- Get a new table local function newTable() local t = next(tablePool) or {} tablePool[t] = nil return t end -- Delete table and return to pool -- Recursive!! -- Use with care!! local function delTable(t) if type(t) == "table" then for k, v in pairs(t) do if type(v) == "table" then delTable(v) -- child tables get put into the pool end t[k] = nil end t[true] = true -- resize table to 1 item t[true] = nil setmetatable(t, nil) tablePool[t] = true end return nil -- return nil to assign input reference end ----------------------------------------------------------------------------- -- Omen initialization and frame functions local function startmoving(self) if not db.Locked then Omen.Anchor.IsMovingOrSizing = 1 Omen.Anchor:StartMoving() end end local function stopmoving(self) if Omen.Anchor.IsMovingOrSizing then Omen.Anchor:StopMovingOrSizing() Omen:SetAnchors() Omen:UpdateBars() Omen.Anchor.IsMovingOrSizing = nil end if self == Omen.Anchor then db.Shown = self:IsShown() end end local function sizing(self) local w = Omen.Anchor:GetWidth() db.VGrip1 = w * Omen.Anchor.VGrip1Ratio db.VGrip2 = w * Omen.Anchor.VGrip2Ratio if db.VGrip1 < 10 then db.VGrip1 = 10 end if db.VGrip1 > w - 10 then db.VGrip1 = w - 10 end if db.Bar.ShowTPS then if db.VGrip2 < db.VGrip1 + 10 then db.VGrip2 = db.VGrip1 + 10 end if db.VGrip1 > w - 20 then db.VGrip1 = w - 20 db.VGrip2 = w - 10 end Omen.VGrip2:ClearAllPoints() Omen.VGrip2:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip2, 0) Omen.VGrip2:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip2, 0) end Omen.VGrip1:ClearAllPoints() Omen.VGrip1:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip1, 0) Omen.VGrip1:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip1, 0) Omen:ResizeBars() Omen:ReAnchorLabels() Omen:UpdateBars() end local function movegrip1(self) local x = GetCursorPosition() / UIParent:GetEffectiveScale() / Omen.Anchor:GetScale() local x1 = Omen.Anchor:GetLeft() + 10 local x2 = db.Bar.ShowTPS and Omen.Anchor:GetLeft() + db.VGrip2 - 10 or Omen.Anchor:GetRight() - 10 if x > x1 and x < x2 then db.VGrip1 = x - x1 + 10 Omen.VGrip1:ClearAllPoints() Omen.VGrip1:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip1, 0) Omen.VGrip1:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip1, 0) end Omen:ReAnchorLabels() end local function movegrip2(self) local x = GetCursorPosition() / UIParent:GetEffectiveScale() / Omen.Anchor:GetScale() local x1 = Omen.Anchor:GetLeft() + db.VGrip1 + 10 local x2 = Omen.Anchor:GetRight() - 10 if x > x1 and x < x2 then db.VGrip2 = x - x1 + db.VGrip1 + 10 Omen.VGrip2:ClearAllPoints() Omen.VGrip2:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip2, 0) Omen.VGrip2:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip2, 0) end Omen:ReAnchorLabels() end function Omen:CreateFrames() -- Create anchor self.Anchor = CreateFrame("Frame", "OmenAnchor", UIParent) self.Anchor:SetResizable(true) self.Anchor:SetMinResize(90, db.Background.EdgeSize * 2) self.Anchor:SetMovable(true) self.Anchor:SetPoint("CENTER", UIParent, "CENTER") self.Anchor:SetWidth(225) self.Anchor:SetHeight(150) self.Anchor:SetScript("OnHide", stopmoving) self.Anchor:SetScript("OnShow", function(self) db.Shown = true Omen:UpdateBars() end) -- Create Title self.Title = CreateFrame("Button", "OmenTitle", self.Anchor) self.Title:SetPoint("TOPLEFT", self.Anchor, "TOPLEFT") self.Title:SetPoint("TOPRIGHT", self.Anchor, "TOPRIGHT") self.Title:SetHeight(16) self.Title:SetMinResize(90, db.Background.EdgeSize * 2) self.Title:EnableMouse(true) self.Title:SetScript("OnMouseDown", startmoving) self.Title:SetScript("OnMouseUp", stopmoving) self.Title:SetScript("OnClick", Omen_DropDownMenu.OnClick) self.Title.initMenuFunc = self.TitleQuickMenu self.Title:RegisterForClicks("RightButtonUp") -- Create Title text self.TitleText = self.Title:CreateFontString(nil, nil, "GameFontNormal") self.TitleText:SetPoint("LEFT", self.Title, "LEFT", 8, 1) self.TitleText:SetJustifyH("LEFT") self.TitleText:SetTextColor(1, 1, 1, 1) self.defaultTitle = "Omen|cffffcc003|r" self.TitleText:SetText(self.defaultTitle) -- Create Bar List self.BarList = CreateFrame("Frame", "OmenBarList", self.Anchor) self.BarList:SetResizable(true) self.BarList:EnableMouse(true) self.BarList:SetPoint("TOPLEFT", self.Title, "BOTTOMLEFT") self.BarList:SetPoint("BOTTOMRIGHT", self.Anchor, "BOTTOMRIGHT") self.BarList:SetScript("OnMouseDown", startmoving) self.BarList:SetScript("OnMouseUp", stopmoving) self.BarList:SetScript("OnHide", stopmoving) self.BarList.barsShown = 0 -- Create resizing corner grip self.Grip = CreateFrame("Button", "OmenResizeGrip", self.BarList) self.Grip:SetNormalTexture("Interface\\AddOns\\Omen\\ResizeGrip") self.Grip:SetHighlightTexture("Interface\\AddOns\\Omen\\ResizeGrip") self.Grip:SetWidth(16) self.Grip:SetHeight(16) self.Grip:SetPoint("BOTTOMRIGHT", self.BarList, "BOTTOMRIGHT", 0, 1) self.Grip:SetScript("OnMouseDown", function(self, button) if not db.Locked then Omen.Anchor.IsMovingOrSizing = 2 Omen.Anchor.VGrip1Ratio = db.VGrip1 / Omen.Anchor:GetWidth() Omen.Anchor.VGrip2Ratio = db.VGrip2 / Omen.Anchor:GetWidth() Omen.Anchor:SetScript("OnSizeChanged", sizing) Omen.Anchor:StartSizing() end end) self.Grip:SetScript("OnMouseUp", function(self) if Omen.Anchor.IsMovingOrSizing == 2 then Omen.Anchor:SetScript("OnSizeChanged", nil) Omen.Anchor:StopMovingOrSizing() sizing() Omen:SetAnchors() Omen.Anchor.IsMovingOrSizing = nil Omen.Anchor.VGrip1Ratio = nil end end) self.Grip:SetScript("OnHide", self.Grip:GetScript("OnMouseUp")) -- Create label resizing vertical grip 1 self.VGrip1 = CreateFrame("Button", "OmenVResizeGrip1", self.BarList) self.VGrip1:SetWidth(1) self.VGrip1:SetPoint("TOPLEFT", self.BarList, "TOPLEFT", db.VGrip1, 0) self.VGrip1:SetPoint("BOTTOMLEFT", self.BarList, "BOTTOMLEFT", db.VGrip1, 0) self.VGrip1:SetNormalTexture("Interface\\Tooltips\\UI-Tooltip-Background") self.VGrip1:SetHighlightTexture("Interface\\Tooltips\\UI-Tooltip-Background") self.VGrip1:GetNormalTexture():SetVertexColor(1, 1, 1, 0.5) self.VGrip1:GetHighlightTexture():SetVertexColor(1, 1, 1, 0.5) self.VGrip1:SetScript("OnMouseDown", function(self) if not db.Locked then self:SetScript("OnUpdate", movegrip1) end end) self.VGrip1:SetScript("OnMouseUp", function(self) self:SetScript("OnUpdate", nil) end) self.VGrip1:SetScript("OnHide", self.VGrip1:GetScript("OnMouseUp")) self.VGrip1:SetFrameLevel(self.BarList:GetFrameLevel() + 2) -- Create label resizing vertical grip 2 self.VGrip2 = CreateFrame("Button", "OmenVResizeGrip2", self.BarList) self.VGrip2:SetWidth(1) self.VGrip2:SetPoint("TOPLEFT", self.BarList, "TOPLEFT", db.VGrip2, 0) self.VGrip2:SetPoint("BOTTOMLEFT", self.BarList, "BOTTOMLEFT", db.VGrip2, 0) self.VGrip2:SetNormalTexture("Interface\\Tooltips\\UI-Tooltip-Background") self.VGrip2:SetHighlightTexture("Interface\\Tooltips\\UI-Tooltip-Background") self.VGrip2:GetNormalTexture():SetVertexColor(1, 1, 1, 0.5) self.VGrip2:GetHighlightTexture():SetVertexColor(1, 1, 1, 0.5) self.VGrip2:SetScript("OnMouseDown", function(self) if not db.Locked then self:SetScript("OnUpdate", movegrip2) end end) self.VGrip2:SetScript("OnMouseUp", self.VGrip1:GetScript("OnMouseUp")) self.VGrip2:SetScript("OnHide", self.VGrip1:GetScript("OnMouseUp")) self.VGrip2:SetFrameLevel(self.BarList:GetFrameLevel() + 2) --[[self.FocusButton = CreateFrame("Button", "OmenFocusButton", self.Title, "OptionsButtonTemplate") self.FocusButton:SetWidth(16) self.FocusButton:SetHeight(16) self.FocusButton:SetPoint("TOPRIGHT") self.FocusButton:SetText("F") self.FocusButton:SetScript("OnClick", function(self, button, down) db.UseFocus = not db.UseFocus if db.UseFocus then self:GetFontString():SetTextColor(1, 0.82, 0, 1) else self:GetFontString():SetTextColor(0.5, 0.5, 0.5, 1) end Omen:UpdateBars() end) if db.UseFocus then self.FocusButton:GetFontString():SetTextColor(1, 0.82, 0, 1) else self.FocusButton:GetFontString():SetTextColor(0.5, 0.5, 0.5, 1) end]] self.CreateFrames = nil end function Omen:OnInitialize() -- Create savedvariables self.db = LibStub("AceDB-3.0"):New("Omen3DB", defaults) self.db.RegisterCallback(self, "OnProfileChanged", "OnProfileChanged") self.db.RegisterCallback(self, "OnProfileCopied", "OnProfileChanged") self.db.RegisterCallback(self, "OnProfileReset", "OnProfileChanged") db = self.db.profile self:SetSinkStorage(db.Warnings.SinkOptions) LSM.RegisterCallback(self, "LibSharedMedia_Registered", "UpdateUsedMedia") -- These 2 functions self GC after running self:CreateFrames() self:SetupOptions() self:RegisterEvent("PLAYER_LOGIN") self.OnInitialize = nil end function Omen:PLAYER_LOGIN() -- We set up anchors here because we only want to do it once on -- PLAYER_LOGIN, hence we don't do it in OnEnable() which triggers on -- the same event as well as on every subsequent Enable()/Disable() calls. -- It cannot be earlier than PLAYER_LOGIN because layout-cache.txt -- is loaded just before this event fires. self:SetAnchors(true) self.Anchor:SetAlpha(db.Alpha) self.Anchor:SetFrameStrata(strsub(db.FrameStrata, 3)) self.Anchor:SetClampedToScreen(db.ClampToScreen) self:UpdateBackdrop() self:UpdateTitleBar() self:UpdateGrips() self:UpdateClickThrough() self:UpdateRaidClassColors() self:ClearAll() self:UnregisterEvent("PLAYER_LOGIN") if not db.Shown then self.Anchor:Hide() end -- Auto-show/hide will override this later if enabled -- Optional !ClassColors addon support if CUSTOM_CLASS_COLORS then CUSTOM_CLASS_COLORS:RegisterCallback("UpdateBars", self) end -- ConfigMode support do CONFIGMODE_CALLBACKS = CONFIGMODE_CALLBACKS or {} local oldTestMode = testMode local oldLocked = db.Locked function CONFIGMODE_CALLBACKS.Omen(action) if action == "ON" then oldTestMode = testMode oldLocked = db.Locked testMode = true db.Locked = false Omen:Toggle(true) elseif action == "OFF" then testMode = oldTestMode db.Locked = oldLocked manualToggle = false Omen:UpdateVisible() end Omen:UpdateGrips() Omen:UpdateBars() LibStub("AceConfigRegistry-3.0"):NotifyChange("Omen") end end -- LDB launcher if LDB then OmenLauncher = LDB:NewDataObject("Omen", { type = "launcher", icon = "Interface\\AddOns\\Omen\\icon", OnClick = function(clickedframe, button) if button == "RightButton" then Omen:ShowConfig() else Omen:Toggle() end end, OnTooltipShow = function(tt) tt:AddLine(self.defaultTitle) tt:AddLine("|cffffff00" .. L["Click|r to toggle the Omen window"]) tt:AddLine("|cffffff00" .. L["Right-click|r to open the options menu"]) end, }) if LDBIcon and not IsAddOnLoaded("Broker2FuBar") and not IsAddOnLoaded("FuBar") then LDBIcon:Register("Omen", OmenLauncher, db.MinimapIcon) end end -- Optional launcher support for LFBP-3.0 if present, this code is placed here so -- that it runs after all other addons have loaded since we don't embed LFBP-3.0 -- Yes, this is one big hack since LFBP-3.0 is a Rock library, and we embed it -- via Ace3. OnEmbedInitialize() needs to be called manually. if LibStub:GetLibrary("LibFuBarPlugin-3.0", true) and not IsAddOnLoaded("FuBar2Broker") then local LFBP = LibStub:GetLibrary("LibFuBarPlugin-3.0") LibStub("AceAddon-3.0"):EmbedLibrary(self, "LibFuBarPlugin-3.0") self:SetFuBarOption("tooltipType", "GameTooltip") self:SetFuBarOption("hasNoColor", true) self:SetFuBarOption("cannotDetachTooltip", true) self:SetFuBarOption("hideWithoutStandby", true) self:SetFuBarOption("iconPath", [[Interface\AddOns\Omen\icon]]) self:SetFuBarOption("hasIcon", true) self:SetFuBarOption("defaultPosition", "RIGHT") self:SetFuBarOption("tooltipHiddenWhenEmpty", true) self:SetFuBarOption("configType", "None") LFBP:OnEmbedInitialize(self) function Omen:OnUpdateFuBarTooltip() GameTooltip:AddLine(self.defaultTitle) GameTooltip:AddLine("|cffffff00" .. L["Click|r to toggle the Omen window"]) GameTooltip:AddLine("|cffffff00" .. L["Right-click|r to open the options menu"]) end function Omen:OnFuBarClick(button) if button == "RightButton" then self:ShowConfig() else self:Toggle() end end self.optionsFrames["FuBar"] = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("Omen", L["FuBar Options"], self.versionstring, "FuBar") self:UpdateFuBarSettings() end self.PLAYER_LOGIN = nil end function Omen:OnEnable() self:RegisterEvent("UNIT_THREAT_LIST_UPDATE") self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE") self:RegisterEvent("PLAYER_TARGET_CHANGED") self:RegisterEvent("PARTY_MEMBERS_CHANGED") self:RegisterEvent("UNIT_PET", "PARTY_MEMBERS_CHANGED") self:RegisterEvent("UNIT_NAME_UPDATE", "PARTY_MEMBERS_CHANGED") self:RegisterEvent("PLAYER_PET_CHANGED", "PARTY_MEMBERS_CHANGED") --self:RegisterEvent("RAID_ROSTER_UPDATE", "PARTY_MEMBERS_CHANGED") -- Is this needed? self:RegisterEvent("PLAYER_UPDATE_RESTING", "UpdateVisible") self:RegisterEvent("PLAYER_ENTERING_WORLD") if db.ShowWith.HideWhenOOC then self:RegisterEvent("PLAYER_REGEN_DISABLED", "UpdateVisible") self:RegisterEvent("PLAYER_REGEN_ENABLED", "UpdateVisible") end if db.UseFocus then self:RegisterEvent("UNIT_TARGET") end self:PARTY_MEMBERS_CHANGED() self:PLAYER_TARGET_CHANGED() end function Omen:OnDisable() -- Cancel all timers (well at least nil them all -- out in timers[], since AceTimer-3.0 cancels -- them all OnDisable anyway). for k, v in pairs(timers) do self:CancelTimer(v, true) timers[k] = nil end self:_toggle(false) end function Omen:OnProfileChanged(event, database, newProfileKey) db = database.profile self:SetAnchors(true) self.Anchor:SetAlpha(db.Alpha) self.Anchor:SetFrameStrata(strsub(db.FrameStrata, 3)) self.Anchor:SetClampedToScreen(db.ClampToScreen) self:UpdateBackdrop() self:UpdateTitleBar() self:UpdateGrips() self:ResizeBars() self:ReAnchorBars() self:ReAnchorLabels() self:UpdateBarLabelSettings() self:UpdateBarTextureSettings() self:UpdateClickThrough() self:UpdateRaidClassColors() self:UpdateFuBarSettings() -- These remainder settings were not placed in functions -- and were just updated directly from the config code. if LDBIcon and not IsAddOnLoaded("Broker2FuBar") and not IsAddOnLoaded("FuBar") then LDBIcon:Refresh("Omen", db.MinimapIcon) end if db.ShowWith.HideWhenOOC then self:RegisterEvent("PLAYER_REGEN_DISABLED", "UpdateVisible") self:RegisterEvent("PLAYER_REGEN_ENABLED", "UpdateVisible") else self:UnregisterEvent("PLAYER_REGEN_DISABLED") self:UnregisterEvent("PLAYER_REGEN_ENABLED") end if db.UseFocus then self:RegisterEvent("UNIT_TARGET") else self:UnregisterEvent("UNIT_TARGET") end local f = self.TPSUpdateFrame if f then if db.Bar.ShowTPS then f:Show() else f:Hide() end end if db.Bar.ShowValue and db.Bar.ShowPercent then bars[0].Text2:SetText(L["Threat [%]"]) else bars[0].Text2:SetText(L["Threat"]) end self:UpdateVisible() self:UpdateBars() end function Omen:UpdateUsedMedia(event, mediatype, key) if mediatype == "statusbar" then if key == db.Bar.Texture then self:UpdateBarTextureSettings() end elseif mediatype == "font" then if key == db.TitleBar.Font then self:UpdateTitleBar() end if key == db.Bar.Font then self:UpdateBarLabelSettings() self:UpdateBars() end elseif mediatype == "background" then if key == db.Background.Texture then self:UpdateBackdrop() end elseif mediatype == "border" then if key == db.Background.BorderTexture then self:UpdateBackdrop() end --elseif mediatype == "sound" then -- Do nothing end end function Omen:SetAnchors(useDB) local x, y, w, h -- Set the scale, since the scaling affects the position self.Anchor:SetScale(db.Scale) self.VGrip1:SetWidth(1 / self.VGrip1:GetEffectiveScale()) self.VGrip2:SetWidth(1 / self.VGrip2:GetEffectiveScale()) -- Get position if useDB then x, y = db.PositionX, db.PositionY if not x or not y then self.Anchor:ClearAllPoints() self.Anchor:SetPoint("CENTER", UIParent, "CENTER", 0, 0) x, y = self.Anchor:GetLeft(), db.GrowUp and self.Anchor:GetBottom() or self.Anchor:GetTop() end else x, y = self.Anchor:GetLeft(), db.GrowUp and self.Anchor:GetBottom() or self.Anchor:GetTop() end -- Get width/height w = useDB and db.PositionW or self.Anchor:GetWidth() h = useDB and db.PositionH or self.Anchor:GetHeight() -- Set the anchors and size self.Anchor:ClearAllPoints() self.Anchor:SetPoint(db.GrowUp and "BOTTOMLEFT" or "TOPLEFT", UIParent, "BOTTOMLEFT", x, y) self.Anchor:SetWidth(w) self.Anchor:SetHeight(h) self.Anchor:SetUserPlaced(nil) -- Save the data db.PositionX, db.PositionY = x, y db.PositionW, db.PositionH = w, h end -- For public use function Omen:Toggle(setting) -- Don't set the manualToggle flag if "Hide Omen on 0 bars" option is active if not (db.Autocollapse and db.CollapseHide) then manualToggle = true end return self:_toggle(setting) end -- For internal use function Omen:_toggle(setting) if setting == nil then setting = not self.Anchor:IsShown() end if setting then self.Anchor:Show() else self.Anchor:Hide() end end function Omen:UpdateVisible(event) local t = db.ShowWith if not t.UseShowWith or manualToggle then return end -- Hide if HideWhenOOC option is on, we're not in combat, and the triggering event is not -- "PLAYER_REGEN_DISABLED" (we're out of combat during this event just before entering combat) if t.HideWhenOOC and not InCombatLockdown() and event ~= "PLAYER_REGEN_DISABLED" then self:_toggle(false) return end -- Check for pet|party|raid|alone local show = (t.Pet and UnitExists("pet")) or (t.Party and inParty) or (t.Raid and inRaid) or (t.Alone and not inParty and not inRaid and not UnitExists("pet")) -- Then hide override if necessary for resting|pvp local inInstance, instanceType = IsInInstance() if (t.HideWhileResting and IsResting()) or (t.HideInPVP and (instanceType == "pvp" or instanceType == "arena")) then show = false end -- Hide if Autocollapse and Hide Omen on 0 Bars are both active and there are 0 bars. if db.Autocollapse and db.CollapseHide and self.BarList.barsShown == 0 then show = false end self:_toggle(show) end local bgFrame = {insets = {}} function Omen:UpdateBackdrop() bgFrame.bgFile = LSM:Fetch("background", db.Background.Texture) bgFrame.edgeFile = LSM:Fetch("border", db.Background.BorderTexture) bgFrame.tile = db.Background.Tile bgFrame.tileSize = db.Background.TileSize bgFrame.edgeSize = db.Background.EdgeSize local inset = floor(db.Background.EdgeSize / 4) bgFrame.insets.left = inset bgFrame.insets.right = inset bgFrame.insets.top = inset bgFrame.insets.bottom = inset self.BarList:SetBackdrop(bgFrame) if not db.TitleBar.UseSameBG then bgFrame.bgFile = LSM:Fetch("background", db.TitleBar.Texture) bgFrame.edgeFile = LSM:Fetch("border", db.TitleBar.BorderTexture) bgFrame.tile = db.TitleBar.Tile bgFrame.tileSize = db.TitleBar.TileSize bgFrame.edgeSize = db.TitleBar.EdgeSize local inset = floor(db.TitleBar.EdgeSize / 4) bgFrame.insets.left = inset bgFrame.insets.right = inset bgFrame.insets.top = inset bgFrame.insets.bottom = inset end self.Title:SetBackdrop(bgFrame) local c = db.Background.Color self.BarList:SetBackdropColor(c.r, c.g, c.b, c.a) if not db.TitleBar.UseSameBG then c = db.TitleBar.Color end self.Title:SetBackdropColor(c.r, c.g, c.b, c.a) c = db.Background.BorderColor self.BarList:SetBackdropBorderColor(c.r, c.g, c.b, c.a) if not db.TitleBar.UseSameBG then c = db.TitleBar.BorderColor end self.Title:SetBackdropBorderColor(c.r, c.g, c.b, c.a) local h = db.Background.EdgeSize * 2 if not db.TitleBar.UseSameBG then h = db.TitleBar.EdgeSize * 2 end self.Anchor:SetMinResize(90, h) self.Title:SetMinResize(90, h) if not db.TitleBar.ShowTitleBar then self.Title:SetHeight(1e-6) -- See comment in Omen:UpdateTitleBar() elseif h > db.TitleBar.Height then self.Title:SetHeight(h) else self.Title:SetHeight(db.TitleBar.Height) end if self.Options then self.Options.args.TitleBar.args.Height.min = h end --self.FocusButton:SetPoint("TOPRIGHT", -inset, -inset) self.BarList:ClearAllPoints() -- See comment in Omen:UpdateTitleBar() self.BarList:SetPoint("TOPLEFT", self.Title, "BOTTOMLEFT") self.BarList:SetPoint("BOTTOMRIGHT", self.Anchor, "BOTTOMRIGHT") self:ResizeBars() self:ReAnchorBars() self:UpdateBars() end function Omen:UpdateTitleBar() local font = LSM:Fetch("font", db.TitleBar.Font) local size = db.TitleBar.FontSize local flags = db.TitleBar.FontOutline local color = db.TitleBar.FontColor self.TitleText:SetFont(font, size, flags) self.TitleText:SetTextColor(color.r, color.g, color.b, color.a) local h = db.Background.EdgeSize * 2 if not db.TitleBar.UseSameBG then h = db.TitleBar.EdgeSize * 2 end if not db.TitleBar.ShowTitleBar then -- Yes, its a hack, since it can't be set to 0 self.Title:SetHeight(1e-6) self.Title:Hide() elseif h > db.TitleBar.Height then self.Title:SetHeight(h) self.Title:Show() else self.Title:SetHeight(db.TitleBar.Height) self.Title:Show() end -- This forces the UI to redraw it, I couldn't find a better way. Although it is -- anchored to the Title, it doesn't update automatically on the height change. self.BarList:ClearAllPoints() self.BarList:SetPoint("TOPLEFT", self.Title, "BOTTOMLEFT") self.BarList:SetPoint("BOTTOMRIGHT", self.Anchor, "BOTTOMRIGHT") end function Omen:UpdateFuBarSettings() if LibStub:GetLibrary("LibFuBarPlugin-3.0", true) then if db.FuBar.HideMinimapButton then self:Hide() else self:Show() if self:IsFuBarMinimapAttached() ~= db.FuBar.AttachMinimap then self:ToggleFuBarMinimapAttached() end end end end function Omen:UpdateGrips() self.VGrip1:ClearAllPoints() self.VGrip1:SetPoint("TOPLEFT", self.BarList, "TOPLEFT", db.VGrip1, 0) self.VGrip1:SetPoint("BOTTOMLEFT", self.BarList, "BOTTOMLEFT", db.VGrip1, 0) self.VGrip2:ClearAllPoints() self.VGrip2:SetPoint("TOPLEFT", self.BarList, "TOPLEFT", db.VGrip2, 0) self.VGrip2:SetPoint("BOTTOMLEFT", self.BarList, "BOTTOMLEFT", db.VGrip2, 0) if db.Locked then self.Grip:Hide() self.VGrip1:Hide() self.VGrip2:Hide() else self.Grip:Show() self.VGrip1:Show() if db.Bar.ShowTPS then self.VGrip2:Show() else self.VGrip2:Hide() end end end function Omen:ToggleFocus() db.UseFocus = not db.UseFocus if db.UseFocus then Omen:RegisterEvent("UNIT_TARGET") else Omen:UnregisterEvent("UNIT_TARGET") end Omen:UpdateBars() end function Omen:UpdateRaidClassColors() if CUSTOM_CLASS_COLORS and db.Bar.UseCustomClassColors then RAID_CLASS_COLORS = CUSTOM_CLASS_COLORS else RAID_CLASS_COLORS = _G.RAID_CLASS_COLORS end Omen:UpdateBars() end ----------------------------------------------------------------------------- -- Omen warnings function Omen:Flash() if not self.FlashFrame then local flasher = CreateFrame("Frame", "OmenFlashFrame") flasher:SetToplevel(true) flasher:SetFrameStrata("FULLSCREEN_DIALOG") flasher:SetAllPoints(UIParent) flasher:EnableMouse(false) flasher:Hide() flasher.texture = flasher:CreateTexture(nil, "BACKGROUND") flasher.texture:SetTexture("Interface\\FullScreenTextures\\LowHealth") flasher.texture:SetAllPoints(UIParent) flasher.texture:SetBlendMode("ADD") flasher:SetScript("OnShow", function(self) self.elapsed = 0 self:SetAlpha(0) end) flasher:SetScript("OnUpdate", function(self, elapsed) elapsed = self.elapsed + elapsed if elapsed < 2.6 then local alpha = elapsed % 1.3 if alpha < 0.15 then self:SetAlpha(alpha / 0.15) elseif alpha < 0.9 then self:SetAlpha(1 - (alpha - 0.15) / 0.6) else self:SetAlpha(0) end else self:Hide() end self.elapsed = elapsed end) self.FlashFrame = flasher end self.FlashFrame:Show() end -- This function is adapted from Omen2 to be self-contained, -- which was initially taken from BigWigs function Omen:Shake() local shaker = self.ShakerFrame if not shaker then shaker = CreateFrame("Frame", "OmenShaker", UIParent) shaker:Hide() shaker:SetScript("OnUpdate", function(self, elapsed) elapsed = self.elapsed + elapsed local x, y = 0, 0 -- Resets to original position if we're supposed to stop. if elapsed >= 0.8 then self:Hide() else x, y = random(-8, 8), random(-8, 8) end if WorldFrame:IsProtected() and InCombatLockdown() then if not shaker.fail then Omen:Print(L["|cffff0000Error:|r Omen cannot use shake warning if you have turned on nameplates at least once since logging in."]) shaker.fail = true end self:Hide() else WorldFrame:ClearAllPoints() for i = 1, #self.originalPoints do local v = self.originalPoints[i] WorldFrame:SetPoint(v[1], v[2], v[3], v[4] + x, v[5] + y) end end self.elapsed = elapsed end) shaker:SetScript("OnShow", function(self) -- Store old worldframe positions, we need them all, people have frame modifiers for it if not self.originalPoints then self.originalPoints = {} for i = 1, WorldFrame:GetNumPoints() do tinsert(self.originalPoints, {WorldFrame:GetPoint(i)}) end end self.elapsed = 0 end) self.ShakerFrame = shaker end shaker:Show() end function Omen:Warn(sound, flash, shake, message) if sound then PlaySoundFile(LSM:Fetch("sound", db.Warnings.SoundFile)) end if flash then self:Flash() end if shake then self:Shake() end if message then self:Pour(message, 1, 0, 0, nil, 24, "OUTLINE", true) end end ----------------------------------------------------------------------------- -- Omen bar stuff do -- OnUpdate function for bar animation, lasts 0.25 seconds local function animate(self, elapsed) local t = self.animationCursor + elapsed local animData = self.animData if t >= 0.25 then self.texture:SetWidth(animData[1]) animData[3] = nil animData[2] = nil animData[1] = nil t = 0 self:SetScript("OnUpdate", nil) else self.texture:SetWidth(animData[2] + animData[3] * t / 0.25) end self.animationCursor = t end -- function to start bar animations local function AnimateTo(self, val) if val == 1/0 or val == -1/0 then return end -- infinity, do nothing if val == 0 then val = 1 end -- at least 1 pixel width local animData = self.animData if animData[1] == val then return end -- there is already an animation to the target width local currentWidth = self.texture:GetWidth() --if currentWidth > self:GetWidth() then currentWidth = self:GetWidth() end if val == currentWidth then return end -- the current width is already the target width animData[1] = val animData[2] = currentWidth animData[3] = val - currentWidth self.animationCursor = 0 self:SetScript("OnUpdate", animate) end -- Create bars on demand setmetatable(bars, {__index = function(self, barID) local bar = CreateFrame("Frame", nil, Omen.BarList) self[barID] = bar local inset = db.Background.BarInset local inset2 = db.Background.BarInset * 2 local color = db.Bar.InvertColors and db.Bar.BarColor or db.Bar.FontColor bar:SetWidth(Omen.Anchor:GetWidth() - inset2) bar:SetHeight(db.Bar.Height) if db.Bar.ShowHeadings then bar:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", inset, -inset + (barID) * -(db.Bar.Height + db.Bar.Spacing)) else bar:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", inset, -inset + (barID-1) * -(db.Bar.Height + db.Bar.Spacing)) end bar.Text1 = bar:CreateFontString(nil, nil, "GameFontNormalSmall") bar.Text1:SetPoint("LEFT", bar, "LEFT", 5, 1) bar.Text1:SetJustifyH("LEFT") bar.Text1:SetFont(LSM:Fetch("font", db.Bar.Font), db.Bar.FontSize, db.Bar.FontOutline) bar.Text1:SetTextColor(color.r, color.g, color.b, color.a) bar.Text1:SetWidth(db.VGrip1 - 5) bar.Text1:SetHeight(db.Bar.FontSize) bar.Text1:SetNonSpaceWrap(false) bar.Text2 = bar:CreateFontString(nil, nil, "GameFontNormalSmall") bar.Text2:SetPoint("RIGHT", bar, "RIGHT", -5, 1) bar.Text2:SetJustifyH("RIGHT") bar.Text2:SetFont(LSM:Fetch("font", db.Bar.Font), db.Bar.FontSize, db.Bar.FontOutline) bar.Text2:SetTextColor(color.r, color.g, color.b, color.a) if db.Bar.ShowTPS then bar.Text2:SetWidth(Omen.BarList:GetWidth() - db.VGrip2 - 5) else bar.Text2:SetWidth(Omen.BarList:GetWidth() - db.VGrip1 - 5) end bar.Text2:SetHeight(db.Bar.FontSize) bar.Text2:SetNonSpaceWrap(false) bar.Text3 = bar:CreateFontString(nil, nil, "GameFontNormalSmall") bar.Text3:SetPoint("LEFT", bar.Text1, "RIGHT", 0, 0) bar.Text3:SetJustifyH("RIGHT") bar.Text3:SetFont(LSM:Fetch("font", db.Bar.Font), db.Bar.FontSize, db.Bar.FontOutline) bar.Text3:SetTextColor(color.r, color.g, color.b, color.a) bar.Text3:SetWidth(db.VGrip2 - db.VGrip1 - 5) bar.Text3:SetHeight(db.Bar.FontSize) bar.Text3:SetNonSpaceWrap(false) if not db.Bar.ShowTPS then bar.Text3:Hide() end bar.texture = bar:CreateTexture() bar.texture:SetTexture(LSM:Fetch("statusbar", db.Bar.Texture)) bar.texture:SetPoint("TOPLEFT", bar, "TOPLEFT") bar.texture:SetPoint("BOTTOMLEFT", bar, "BOTTOMLEFT") color = db.Bar.InvertColors and db.Bar.FontColor or db.Bar.BarColor bar.texture:SetVertexColor(color.r, color.g, color.b, color.a) bar.animData = {} bar.animationCursor = 0 bar.AnimateTo = AnimateTo if barID == 0 then bar.Text1:SetText(L["Name"]) if db.Bar.ShowValue and db.Bar.ShowPercent then bar.Text2:SetText(L["Threat [%]"]) else bar.Text2:SetText(L["Threat"]) end bar.Text3:SetText(L["TPS"]) color = db.Bar.InvertColors and db.Bar.FontColor or db.Bar.HeadingBGColor bar.texture:SetVertexColor(color.r, color.g, color.b, color.a) bar:Hide() elseif barID == 1 then -- Parent our TPS update frame to the first bar, so that TPS updates -- updates happen when at least 1 bar (the first bar) is shown. Omen.TPSUpdateFrame = CreateFrame("Frame", nil, bar) Omen.TPSUpdateFrame:SetScript("OnUpdate", function(self, elapsed) Omen:UpdateTPS() end) if not db.Bar.ShowTPS then Omen.TPSUpdateFrame:Hide() end end return bar end}) end function Omen:ResizeBars() local inset = db.Background.BarInset * 2 local w = Omen.Anchor:GetWidth() - inset for i = 0, #bars do bars[i]:SetWidth(w) bars[i]:SetHeight(db.Bar.Height) end end function Omen:ReAnchorBars() local inset = db.Background.BarInset if db.Bar.ShowHeadings then for i = 0, #bars do bars[i]:SetPoint("TOPLEFT", self.BarList, "TOPLEFT", inset, -inset + (i) * -(db.Bar.Height + db.Bar.Spacing)) end else for i = 1, #bars do bars[i]:SetPoint("TOPLEFT", self.BarList, "TOPLEFT", inset, -inset + (i-1) * -(db.Bar.Height + db.Bar.Spacing)) end bars[0]:Hide() end end function Omen:UpdateBarLabelSettings() local font = LSM:Fetch("font", db.Bar.Font) local size = db.Bar.FontSize local flags = db.Bar.FontOutline local color = db.Bar.InvertColors and db.Bar.BarColor or db.Bar.FontColor local color2 = db.Bar.InvertColors and db.Bar.FontColor or db.Bar.BarColor for i = 0, #bars do bars[i].Text1:SetFont(font, size, flags) bars[i].Text2:SetFont(font, size, flags) bars[i].Text3:SetFont(font, size, flags) bars[i].Text1:SetTextColor(color.r, color.g, color.b, color.a) bars[i].Text2:SetTextColor(color.r, color.g, color.b, color.a) bars[i].Text3:SetTextColor(color.r, color.g, color.b, color.a) bars[i].Text1:SetHeight(size) bars[i].Text2:SetHeight(size) bars[i].Text3:SetHeight(size) bars[i].texture:SetVertexColor(color2.r, color2.g, color2.b, color2.a) end color = db.Bar.InvertColors and db.Bar.FontColor or db.Bar.HeadingBGColor color2 = db.Bar.InvertColors and db.Bar.HeadingBGColor or db.Bar.FontColor bars[0].texture:SetVertexColor(color.r, color.g, color.b, color.a) bars[0].Text1:SetTextColor(color2.r, color2.g, color2.b, color2.a) bars[0].Text2:SetTextColor(color2.r, color2.g, color2.b, color2.a) bars[0].Text3:SetTextColor(color2.r, color2.g, color2.b, color2.a) end function Omen:ReAnchorLabels() local w = db.VGrip1 local w2 = db.Bar.ShowTPS and Omen.BarList:GetWidth() - db.VGrip2 or Omen.BarList:GetWidth() - w local w3 = db.VGrip2 - db.VGrip1 for i = 0, #bars do bars[i].Text1:SetWidth(w - 5) bars[i].Text2:SetWidth(w2 - 5) if db.Bar.ShowTPS then bars[i].Text3:SetWidth(w3 - 5) bars[i].Text3:Show() else bars[i].Text3:Hide() end end end function Omen:UpdateBarTextureSettings() local texturepath = LSM:Fetch("statusbar", db.Bar.Texture) for i = 0, #bars do bars[i].texture:SetTexture(texturepath) end end function Omen:UpdateClickThrough() self.Title:EnableMouse(not db.ClickThrough) self.BarList:EnableMouse(not db.ClickThrough) end ----------------------------------------------------------------------------- -- Omen event functions -- Fired when a mob has its threat list updated. The mob that -- had its list updated is the first parameter of the event. function Omen:UNIT_THREAT_LIST_UPDATE(event, unitID) -- It appears that unitID can only be "target" or "focus" self:UpdateBars() end -- Fired when a unit's threat situation changes. The unit that -- had a change in threat situation is the first parameter of -- the event. Note that this only triggers when major state -- changes, not when the raw threat values change. function Omen:UNIT_THREAT_SITUATION_UPDATE(...) self:UpdateBars() end function Omen:PLAYER_TARGET_CHANGED() -- Stop our unit update timer for updating threat on "targettarget" if timers.UpdateBars then self:CancelTimer(timers.UpdateBars, true) timers.UpdateBars = nil end self:UpdateBars() end function Omen:UNIT_TARGET(event, unitID) if unitID == "focus" and db.UseFocus and self.unitID == "focustarget" then self:UpdateBars() end end local lastPartyUpdateTime = GetTime() function Omen:PARTY_MEMBERS_CHANGED() local oldInParty, oldInRaid = inParty, inRaid inParty = GetNumPartyMembers() > 0 inRaid = GetNumRaidMembers() > 0 if oldInParty ~= inParty or oldInRaid ~= inRaid then manualToggle = false end self:UpdateVisible() -- Run the update if the last call is more than 0.5 seconds ago else -- schedule an update 0.5 seconds later if one isn't already scheduled if GetTime() - lastPartyUpdateTime > 0.5 then self:UpdatePartyGUIDs() elseif not timers.UpdatePartyGUIDs then timers.UpdatePartyGUIDs = self:ScheduleTimer("UpdatePartyGUIDs", 0.5) end end -- This function updates the name and class guid lookup tables of the raid function Omen:UpdatePartyGUIDs() lastPartyUpdateTime = GetTime() if timers.UpdatePartyGUIDs then self:CancelTimer(timers.UpdatePartyGUIDs, true) timers.UpdatePartyGUIDs = nil end local _ local me = UnitGUID("player") wipe(guidClassLookup) if me then -- Because it sometimes is nil on zoning/logging in. guidNameLookup[me] = UnitName("player") _, guidClassLookup[me] = UnitClass("player") else timers.UpdatePartyGUIDs = self:ScheduleTimer("UpdatePartyGUIDs", 0.5) end if UnitExists("pet") then local petGUID = UnitGUID("pet") guidClassLookup[petGUID] = "PET" guidNameLookup[petGUID] = UnitName("pet")--.." ["..UnitName("player").."]" end if inParty or inRaid then local playerFmt = inRaid and rID or pID local petFmt = inRaid and rpID or ppID local currentPartySize = inRaid and GetNumRaidMembers() or GetNumPartyMembers() for i = 1, currentPartySize do local unitID = playerFmt[i] local pGUID = UnitGUID(unitID) if pGUID then guidNameLookup[pGUID] = UnitName(unitID) _, guidClassLookup[pGUID] = UnitClass(unitID) -- lookup pet (if existing) local petID = petFmt[i] local petGUID = UnitGUID(petID) if petGUID then guidNameLookup[petGUID] = UnitName(petID)--.." ["..UnitName(unitID).."]" guidClassLookup[petGUID] = "PET" end end end end guidNameLookup["AGGRO"] = L["> Pull Aggro <"] guidClassLookup["AGGRO"] = "AGGRO" end function Omen:PLAYER_ENTERING_WORLD() manualToggle = false wipe(guidNameLookup) self:PARTY_MEMBERS_CHANGED() end ----------------------------------------------------------------------------- -- Omen update functions --[[ First, some definitions: * mob - enemy creature * threat list - a mob's list of possible targets, along with each possible target's current threat value * threat situation - the situation that a unit is currently in (either globally, or with respect to a certain mob) * scaled percentage - a threat percentage, where 100% means you will pull aggro (become the primary target of the mob), and thus this % cannot be higher than 100% under normal circumstances * raw threat percentage - the percentage of the units threat when divided by the threat of the mob's current primary target, this % CAN be over 100% --------- state = UnitThreatSituation(unit, mob) Returns the unit's threat situation with respect to the given mob. The state can be one of the following values: nil = the unit is not on the mob's threat list 0 = 0-99% raw threat percentage (no indicator shown) 1 = 100% or more raw threat percentage (yellow warning indicator shown) 2 = tanking, other has 100% or more raw threat percentage (orange indicator shown) 3 = tanking, all others have less than 100% raw percentage threat (red indicator shown) --------- state = UnitThreatSituation(unit) Returns the unit's maximum threat state on any mob's threat list. --------- isTanking, state, scaledPercent, rawPercent, threatValue = UnitDetailedThreatSituation(unit, mob) Returns detailed information about the unit's state on the mob's threat list. isTanking is true if the unit the primary target of the mob (and by definition has 100% threat) state is the unit's threat situation, as listed above. scaledPercent is the current percent threat of the unit, scaled in the 0-100% range based on distance from target. rawPercent is the current percent threat of the unit relative to the primary target of the mob. threatValue is the amount of threat that the unit has on the mob's threat list. This is roughly approximate to the amount of damage and healing the unit has done. --------- r, g, b = GetThreatStatusColor(state) Returns the colors used in the UI to represent each major threat state. ]] local threatTable -- Format: threatTable[guid] = threatValue local sortTable = {} -- Format: threatTable[i] = guid -- used for sorting by sortfunction() local tankGUID -- Used to store which unit is tanking and hence has 100% threat by definition local topthreat -- Used to store the top threat value local lastWarn = { -- Used to store information for threat warnings threatpercent = 0, } local threatStore = {} -- Format: threatStore[i] = threatTable[guid] -- used for storing past threatTables local threatStoreTime = {} -- Format: threatStoreTime[i] = GetTime() local negativeTable = {} -- Format: negativeTable[guid] = true -- stores if someone is under the effects of Fade or Mirror Image local function sortfunction(a, b) return threatTable[a] > threatTable[b] end local function updatethreat(unitid, mobunitid) local guid = UnitGUID(unitid) if guid and not threatTable[guid] then local isTanking, state, scaledPercent, rawPercent, threatValue = UnitDetailedThreatSituation(unitid, mobunitid) -- CoA: the Vol'jin/CoA core does not push party-member threat to the -- client, so the API call above returns nil for everyone but us. Fall -- back to values broadcast by peers running OmenSync. if not threatValue and Omen.SyncGetThreat then local mobGUID = UnitGUID(mobunitid) if mobGUID then local syncVal, syncTanking = Omen:SyncGetThreat(guid, mobGUID) if syncVal then threatValue = syncVal isTanking = syncTanking end end end if threatValue then -- Threat can be negative due to temporary threat reduction effects such as Fade and Mirror Image (-410065408). if threatValue < 0 then threatValue = threatValue + 410065408 negativeTable[guid] = true end if threatValue > topthreat then topthreat = threatValue end if isTanking then tankGUID = guid end threatTable[guid] = threatValue -- CoA: broadcast our own player/pet threat so peers' OmenSync can -- fill the gap left by their nil UnitDetailedThreatSituation call. if (unitid == "player" or unitid == "pet") and Omen.SyncBroadcastThreat then local mobGUID = UnitGUID(mobunitid) if mobGUID then Omen:SyncBroadcastThreat(guid, mobGUID, threatValue, isTanking) end end else -- We use the special value -1 to indicate nil here. threatTable[guid] = -1 end end end local threatUnitIDFindList = {"target", "targettarget"} local threatUnitIDFindList2 = {"focus", "focustarget", "target", "targettarget"} function Omen:FindThreatMob() -- Figure out which mob to show threat on. -- It has to be attackable and not human controlled. local t = db.UseFocus and threatUnitIDFindList2 or threatUnitIDFindList local name, name2 for i = 1, #t do local mob = t[i] if UnitExists(mob) then name2 = UnitName(mob) guidNameLookup[UnitGUID(mob)] = name2 if not name then name = name2 end if not UnitIsPlayer(mob) and UnitCanAttack("player", mob) and UnitHealth(mob) > 0 then if not db.IgnorePlayerPets or not UnitPlayerControlled(mob) then self.TitleText:SetText(name2) self.unitID = mob return mob end end end end self.TitleText:SetText(name) self.unitID = nil end -- Frame for throtling updates local OmenUpdateBarsThrotleFrame = CreateFrame("Frame") OmenUpdateBarsThrotleFrame:Hide() OmenUpdateBarsThrotleFrame:SetScript("OnUpdate", function(self, elapsed) self:Hide() Omen:UpdateBarsReal() end) function Omen:UpdateBars() OmenUpdateBarsThrotleFrame:Show() end local queried = false function Omen:UpdateBarsReal() if db.Autocollapse and db.CollapseHide then -- Update the visibility because it could have been hidden on 0 bars self.BarList.barsShown = 1 -- Dummy value self:UpdateVisible() end if not self.Anchor:IsShown() then self.BarList.barsShown = 0 return end local myGUID = UnitGUID("player") local dbBar = db.Bar local mob, mobGUID, mobTargetGUID topthreat = -1 if testMode then threatTable = newTable() local key = next(showClassesOptionTable) for i = 1, 25 do if i == 22 and myGUID then -- Because I've got myGUID == nil before threatTable[myGUID] = i*5000 else threatTable[i] = i*5000 guidNameLookup[i] = showClassesOptionTable[key] if key ~= "*NOTINPARTY*" then guidClassLookup[i] = key end key = next(showClassesOptionTable, key) or next(showClassesOptionTable) end end tankGUID = 25 topthreat = 25*5000 mob = "" self.TitleText:SetText(L["Test Mode"]) else mob = self:FindThreatMob() if not mob then self:ClearAll() return end mobGUID = UnitGUID(mob) -- Schedule a repeating timer for updating threat on "targettarget" -- since we get no events on a targettarget change. if mob == "targettarget" and not timers.UpdateBars then timers.UpdateBars = self:ScheduleRepeatingTimer("UpdateBars", 0.5) end -- We want the mob's target just in case the tank isn't -- in our raid (say an NPC or some other player) local mobTarget = mob.."target" local mobTargetGUID = UnitGUID(mobTarget) if mobTargetGUID then guidNameLookup[mobTargetGUID] = UnitName(mobTarget) end threatTable = newTable() threatTable[mobGUID] = -1 tankGUID = nil wipe(negativeTable) -- Get data for threat on mob by scanning the whole raid if inParty or inRaid then if inRaid then for i = 1, GetNumRaidMembers() do updatethreat(rID[i], mob) updatethreat(rpID[i], mob) updatethreat(rtID[i], mob) updatethreat(rptID[i], mob) end else for i = 1, GetNumPartyMembers() do updatethreat(pID[i], mob) updatethreat(ppID[i], mob) updatethreat(ptID[i], mob) updatethreat(pptID[i], mob) end end end if not inRaid then updatethreat("player", mob) updatethreat("pet", mob) updatethreat("target", mob) updatethreat("pettarget", mob) end updatethreat("target", mob) updatethreat("targettarget", mob) updatethreat("focus", mob) updatethreat("focustarget", mob) updatethreat(mobTarget, mob) updatethreat("mouseover", mob) updatethreat("mouseovertarget", mob) end local tankThreat = tankGUID and threatTable[tankGUID] or mobTargetGUID and threatTable[mobTargetGUID] or topthreat if dbBar.ShowAggroBar and tankThreat > 0 then if GetItemInfo(37727) then -- 5 yards (Ruby Acorn - http://www.wowhead.com/?item=37727) threatTable["AGGRO"] = tankThreat * (IsItemInRange(37727, mob) == 1 and 1.1 or 1.3) else -- 9 yards compromise threatTable["AGGRO"] = tankThreat * (CheckInteractDistance(mob, 3) and 1.1 or 1.3) if not queried and not ItemRefTooltip:IsVisible() then ItemRefTooltip:SetHyperlink("item:37727") queried = true -- Only query once per session end end end -- Sort the threatTable local i = 1 for k, v in pairs(threatTable) do if v ~= -1 then sortTable[i] = k i = i + 1 end end for j = i, #sortTable do sortTable[j] = nil end if #sortTable == 0 then self:ClearAll() self.TitleText:SetText(guidNameLookup[mobGUID]) return end sort(sortTable, sortfunction) -- Now update the bars on screen local inset = db.Background.BarInset * 2 local w = self.BarList:GetWidth() - inset local h = self.BarList:GetHeight() - inset topthreat = threatTable[sortTable[1]] if topthreat == 0 then topthreat = 1 end -- To avoid 0/0 division local showSelfYet = true if dbBar.AlwaysShowSelf then -- Check if we're one of the bars to be displayed for j = 1, #sortTable do if sortTable[j] == myGUID then showSelfYet = false -- Yes, so flag it false break end end end -- Check how many bars of space we have local numBars = db.Autocollapse and db.NumBars or floor((h - dbBar.Height) / (dbBar.Height + dbBar.Spacing) + 1.01) i = 1 -- Counts one higher than number of bars used if dbBar.ShowHeadings then if i <= numBars then i = i + 1 bars[0].texture:SetWidth(w) bars[0]:Show() end else bars[0]:Hide() end for j = 1, #sortTable do if i > numBars then break end local guid = sortTable[j] local class = guidClassLookup[guid] local show = class == nil and dbBar.Classes["*NOTINPARTY*"] or class == "AGGRO" and dbBar.ShowAggroBar or dbBar.Classes[class] if dbBar.AlwaysShowSelf and i == numBars and not showSelfYet and guid ~= myGUID then show = false end if dbBar.AlwaysShowSelf and guid == myGUID then show = true showSelfYet = true end if show then local bar = bars[dbBar.ShowHeadings and i-1 or i] local threat = threatTable[guid] -- Update the text on the bar bar.Text1:SetText(guidNameLookup[guid]) if dbBar.ShowPercent and dbBar.ShowValue then if dbBar.ShortNumbers and threat >= 100000 then bar.Text2:SetFormattedText("%2.1fk [%d%%]", threat / 100000, tankThreat == 0 and 0 or threat / tankThreat * 100) else bar.Text2:SetFormattedText("%d [%d%%]", threat / 100, tankThreat == 0 and 0 or threat / tankThreat * 100) end elseif dbBar.ShowValue then if dbBar.ShortNumbers and threat >= 100000 then bar.Text2:SetFormattedText("%2.1fk", threat / 100000) else bar.Text2:SetFormattedText("%d", threat / 100) end else bar.Text2:SetFormattedText("%d%%", tankThreat == 0 and 0 or threat / tankThreat * 100) end -- Update the color of the bar local c = (negativeTable[guid] and dbBar.FadeBarColor) or (guid == myGUID and dbBar.UseMyBarColor and dbBar.MyBarColor) or (guid == tankGUID and dbBar.UseTankBarColor and dbBar.TankBarColor) or (guid == "AGGRO" and dbBar.AggroBarColor) or (dbBar.UseClassColors and (RAID_CLASS_COLORS[class] or (class == "PET" and dbBar.PetBarColor))) or dbBar.BarColor if dbBar.InvertColors then bar.Text1:SetTextColor(c.r, c.g, c.b, c.a or 1) bar.Text2:SetTextColor(c.r, c.g, c.b, c.a or 1) bar.Text3:SetTextColor(c.r, c.g, c.b, c.a or 1) else bar.texture:SetVertexColor(c.r, c.g, c.b, c.a or 1) end -- Update the width of the bar, and animate if necessary local width = w * threat / topthreat if width <= 0 then width = 1 end if dbBar.AnimateBars and self.Anchor.IsMovingOrSizing ~= 2 then bar:AnimateTo(width) else bar.texture:SetWidth(width) end bar.guid = guid -- For TPS calcs bar:Show() i = i + 1 end end -- And hide the rest for j = dbBar.ShowHeadings and i-1 or i, #bars do bars[j]:Hide() end if db.Autocollapse then self.Anchor:SetHeight((i-1)*dbBar.Height + (i-2)*dbBar.Spacing + self.Title:GetHeight() + inset) end self.BarList:Show() self.BarList.barsShown = dbBar.ShowHeadings and i-2 or i-1 -- Threat warnings if testMode then threatTable = delTable(threatTable) elseif myGUID then local myClass = guidClassLookup[myGUID] local myThreatPercent = threatTable[myGUID] / tankThreat * 100 local t = db.Warnings if lastWarn.mobGUID == mobGUID and myThreatPercent >= t.Threshold and t.Threshold > lastWarn.threatpercent then local shapeShiftForm = GetShapeshiftForm() if not t.DisableWhileTanking or not ( myClass == "WARRIOR" and GetBonusBarOffset() == 2 or myClass == "DRUID" and GetBonusBarOffset() == 3 or myClass == "HERO" and GetBonusBarOffset() == 3 or UnitAura("player", GetSpellInfo(25780)) -- Righteous Fury or UnitAura("player", GetSpellInfo(701463)) -- Mana-forged Barrier or shapeShiftForm ~= 0 and ( GetShapeshiftFormInfo(shapeShiftForm) == "Interface\\Icons\\Ability_Warrior_DefensiveStance" or GetShapeshiftFormInfo(shapeShiftForm) == "Interface\\Icons\\Spell_Deathknight_FrostPresence" )) then self:Warn(t.Sound, t.Flash, t.Shake, t.Message and L["Passed %s%% of %s's threat!"]:format(t.Threshold, guidNameLookup[lastWarn.tankGUID])) end end -- Remove TPS data if the last scanned mob is different if lastWarn.mobGUID ~= mobGUID then delTable(threatStore) threatStore = newTable() wipe(threatStoreTime) end tinsert(threatStore, threatTable) tinsert(threatStoreTime, GetTime()) -- Store last scanned mob GUID local u = tankGUID or mobTargetGUID or (dbBar.ShowAggroBar and sortTable[2] or sortTable[1]) if u ~= "AGGRO" then lastWarn.mobGUID = mobGUID lastWarn.tankGUID = u lastWarn.threatpercent = myThreatPercent end threatTable = nil end end function Omen:ClearAll() for i = 0, #bars do bars[i]:Hide() end self.TitleText:SetText(self.defaultTitle) if db.Autocollapse then self.Anchor:SetHeight(self.Title:GetHeight()) self.BarList:Hide() if db.CollapseHide and not self.Anchor.IsMovingOrSizing and not manualToggle then self.Anchor:Hide() end end self.BarList.barsShown = 0 -- Store last scanned mob GUID lastWarn.mobGUID = nil lastWarn.tankGUID = nil lastWarn.threatpercent = 0 -- Remove TPS data delTable(threatStore) threatStore = newTable() wipe(threatStoreTime) threatTable = nil end function Omen:UpdateTPS() local numBars = #bars if testMode then if db.Bar.ShowAggroBar then bars[1].Text3:SetText("--") for i = 2, numBars do bars[i].Text3:SetText(1300 - 50*(i-1)) end else for i = 1, numBars do bars[i].Text3:SetText(1300 - 50*i) end end return end -- Remove data that is too old local TPSWindow = db.Bar.TPSWindow local startTime = GetTime() - TPSWindow while threatStoreTime[2] and startTime > threatStoreTime[2] do delTable(tremove(threatStore, 1)) tremove(threatStoreTime, 1) end -- Now check that we still have enough data local dataSize = #threatStoreTime if dataSize == 0 or startTime <= threatStoreTime[1] then -- We do not have enough data, TPSWindow seconds has not passed for i = 1, numBars do bars[i].Text3:SetText("??") end return end -- Check for special case with just 1 data point past TPSWindow seconds if dataSize == 1 then -- Threat generated is 0 for i = 1, numBars do bars[i].Text3:SetText("0") end return end -- We have at least 2 data points for i = 1, numBars do local bar = bars[i] if not bar:IsShown() then return end local guid = bar.guid if guid == "AGGRO" then bar.Text3:SetText("--") else local baseThreat = threatStore[1][guid] local secondThreat = threatStore[2][guid] local finalThreat = threatStore[dataSize][guid] if baseThreat and secondThreat and finalThreat then -- Calculate TPS local ratio = (startTime - threatStoreTime[1]) / (threatStoreTime[2] - threatStoreTime[1]) local startThreat = (secondThreat - baseThreat) * ratio + baseThreat bar.Text3:SetFormattedText("%d", (finalThreat - startThreat) / TPSWindow / 100) else -- We don't have enough data for this unit bar.Text3:SetText("??") end end end end ----------------------------------------------------------------------------- -- Title Right Click menu do -- Upvalue the functions in the menu local function updateGrip() db.Locked = not db.Locked Omen:UpdateGrips() LibStub("AceConfigRegistry-3.0"):NotifyChange("Omen") end local function toggleFocus() Omen:ToggleFocus() end local function toggleTestMode() testMode = not testMode Omen:UpdateBars() LibStub("AceConfigRegistry-3.0"):NotifyChange("Omen") end local function showConfig() Omen:ShowConfig() end local function toggle() Omen:Toggle() end function Omen.TitleQuickMenu(self, level) if not level then return end local info = self.info wipe(info) if level == 1 then -- Create the title of the menu info.isTitle = 1 info.text = L["Omen Quick Menu"] info.notCheckable = 1 UIDropDownMenu_AddButton(info, level) info.disabled = nil info.isTitle = nil info.notCheckable = nil info.text = L["Lock Omen"] info.func = updateGrip info.checked = db.Locked info.tooltipTitle = L["Lock Omen"] info.tooltipText = L["Locks Omen in place and prevents it from being dragged or resized."] UIDropDownMenu_AddButton(info, level) info.text = L["Use Focus Target"] info.func = toggleFocus info.checked = db.UseFocus info.tooltipTitle = L["Use Focus Target"] info.tooltipText = L["Tells Omen to additionally check your 'focus' and 'focustarget' before your 'target' and 'targettarget' in that order for threat display."] UIDropDownMenu_AddButton(info, level) info.text = L["Test Mode"] info.func = toggleTestMode info.checked = testMode info.tooltipTitle = L["Test Mode"] info.tooltipText = L["Tells Omen to enter Test Mode so that you can configure Omen's display much more easily."] UIDropDownMenu_AddButton(info, level) info.text = L["Open Config"] info.func = showConfig info.checked = nil info.tooltipTitle = L["Open Config"] info.tooltipText = L["Open Omen's configuration panel"] UIDropDownMenu_AddButton(info, level) info.text = L["Hide Omen"] info.func = toggle info.tooltipTitle = L["Hide Omen"] info.tooltipText = nil UIDropDownMenu_AddButton(info, level) -- Close menu item info.text = CLOSE info.func = self.HideMenu info.checked = nil info.arg1 = nil info.notCheckable = 1 info.tooltipTitle = CLOSE UIDropDownMenu_AddButton(info, level) end end end ----------------------------------------------------------------------------- -- Omen config stuff function Omen:SetupOptions() LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable("Omen", self.GenerateOptions) LibStub("AceConfig-3.0"):RegisterOptionsTable("OmenSlashCommand", self.OptionsSlash, "omen") -- The ordering here matters, it determines the order in the Blizzard Interface Options local ACD3 = LibStub("AceConfigDialog-3.0") self.optionsFrames = {} self.optionsFrames.Omen = ACD3:AddToBlizOptions("Omen", self.versionstring, nil, "General") self.optionsFrames.ShowWhen = ACD3:AddToBlizOptions("Omen", L["Show When..."], self.versionstring, "ShowWhen") self.optionsFrames.ShowClasses = ACD3:AddToBlizOptions("Omen", L["Show Classes..."], self.versionstring, "ShowClasses") self.optionsFrames.TitleBar = ACD3:AddToBlizOptions("Omen", L["Title Bar Settings"], self.versionstring, "TitleBar") self.optionsFrames.Bars = ACD3:AddToBlizOptions("Omen", L["Bar Settings"], self.versionstring, "Bars") self.optionsFrames.Warnings = ACD3:AddToBlizOptions("Omen", L["Warning Settings"], self.versionstring, "Warnings") self:RegisterModuleOptions("OmenSlashCommand", self.OptionsSlash, L["Slash Command"]) self:RegisterModuleOptions("Profiles", function() return LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) end, L["Profiles"]) self.optionsFrames.Help = ACD3:AddToBlizOptions("Omen", L["Help File"], self.versionstring, "Help") self.SetupOptions = nil end function Omen:RegisterModuleOptions(name, optionTbl, displayName) if moduleOptions then moduleOptions[name] = optionTbl else self.Options.args[name] = (type(optionTbl) == "function") and optionTbl() or optionTbl end self.optionsFrames[name] = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("Omen", displayName, self.versionstring, name) end function Omen:ShowConfig() -- Open the profiles tab before, so the menu expands InterfaceOptionsFrame_OpenToCategory(self.optionsFrames.Profiles) InterfaceOptionsFrame_OpenToCategory(self.optionsFrames.Omen) end function Omen.GenerateOptions() if Omen.noconfig then assert(false, Omen.noconfig) end if not Omen.Options then Omen.GenerateOptionsInternal() Omen.GenerateOptionsInternal = nil moduleOptions = nil end return Omen.Options end ----------------------------------------------------------------------------- -- Omen config tables -- Option table for the slash command only Omen.OptionsSlash = { type = "group", name = L["Slash Command"], order = -3, args = { intro = { order = 1, type = "description", name = L["OMEN_SLASH_DESC"], cmdHidden = true, }, toggle = { type = "execute", name = L["Toggle Omen"], desc = L["Toggle Omen"].." ( /omen toggle )", func = function() Omen:Toggle() end, }, center = { type = "execute", name = L["Center Omen"], desc = L["Center Omen"].." ( /omen center )", func = function() Omen.Anchor:ClearAllPoints() Omen.Anchor:SetPoint("CENTER", UIParent, "CENTER") Omen:SetAnchors() end, }, config = { type = "execute", name = L["Configure"], desc = L["Open the configuration dialog"].." ( /omen config )", func = function() Omen:ShowConfig() end, guiHidden = true, }, show = { type = "execute", name = L["Show Omen"], desc = L["Show Omen"].." ( /omen show )", func = function() Omen:Toggle(true) end, }, hide = { type = "execute", name = L["Hide Omen"], desc = L["Hide Omen"].." ( /omen hide )", func = function() Omen:Toggle(false) end, }, }, } -- This is to provide better error reporting feedback, and stop loading the rest of the file. if not AceGUIWidgetLSMlists then Omen.noconfig = 'Cannot find a library instance of "AceGUI-3.0-SharedMediaWidgets". Omen configuration will not be available.' assert(AceGUIWidgetLSMlists, Omen.noconfig) end function Omen.GenerateOptionsInternal() local outlines = { [""] = L["None"], ["OUTLINE"] = L["Outline"], ["THICKOUTLINE"] = L["Thick Outline"], } local function GetFuBarMinimapAttachedStatus(info) return Omen:IsFuBarMinimapAttached() or db.FuBar.HideMinimapButton end -- Option table for the AceGUI config only Omen.Options = { type = "group", name = "Omen", get = function(info) return db[ info[#info] ] end, set = function(info, value) db[ info[#info] ] = value end, args = { General = { order = 1, type = "group", name = L["General Settings"], desc = L["General Settings"], args = { intro = { order = 1, type = "description", name = L["OMEN_DESC"], }, Alpha = { order = 3, name = L["Alpha"], desc = L["Controls the transparency of the main Omen window."], type = "range", min = 0, max = 1, step = 0.01, isPercent = true, set = function(info, value) db.Alpha = value Omen.Anchor:SetAlpha(value) end, }, Scale = { order = 4, name = L["Scale"], desc = L["Controls the scaling of the main Omen window."], type = "range", min = 0.50, max = 1.50, step = 0.01, isPercent = true, set = function(info, value) db.Scale = value Omen:SetAnchors() end, }, FrameStrata = { type = "select", order = 5, name = L["Frame Strata"], desc = L["Controls the frame strata of the main Omen window. Default: MEDIUM"], values = { -- A hack to sort them in the menu ["1-BACKGROUND"] = "BACKGROUND", ["2-LOW"] = "LOW", ["3-MEDIUM"] = "MEDIUM", ["4-HIGH"] = "HIGH", ["5-DIALOG"] = "DIALOG", ["6-FULLSCREEN"] = "FULLSCREEN", ["7-FULLSCREEN_DIALOG"] = "FULLSCREEN_DIALOG", ["8-TOOLTIP"] = "TOOLTIP", }, set = function(info, value) db.FrameStrata = value Omen.Anchor:SetFrameStrata(strsub(value, 3)) end, }, ClampToScreen = { type = "toggle", name = L["Clamp To Screen"], desc = L["Controls whether the main Omen window can be dragged offscreen"], order = 6, set = function(info, value) db.ClampToScreen = value Omen.Anchor:SetClampedToScreen(value) end, }, Locked = { type = "toggle", name = L["Lock Omen"], desc = L["Locks Omen in place and prevents it from being dragged or resized."], order = 7, set = function(info, value) db.Locked = value Omen:UpdateGrips() end, }, UseFocus = { type = "toggle", name = L["Use Focus Target"], desc = L["Tells Omen to additionally check your 'focus' and 'focustarget' before your 'target' and 'targettarget' in that order for threat display."], order = 8, set = function(info, value) Omen:ToggleFocus() end, }, TestMode = { type = "toggle", name = L["Test Mode"], desc = L["Tells Omen to enter Test Mode so that you can configure Omen's display much more easily."], order = 9, get = function(info) return testMode end, set = function(info, value) testMode = value Omen:UpdateBars() end, }, MinimapIcon = { type = "toggle", name = L["Show minimap button"], desc = L["Show the Omen minimap button"], order = 10, get = function(info) return not db.MinimapIcon.hide end, set = function(info, value) db.MinimapIcon.hide = not value if value then LDBIcon:Show("Omen") else LDBIcon:Hide("Omen") end end, hidden = function() return not LDBIcon or IsAddOnLoaded("Broker2FuBar") or IsAddOnLoaded("FuBar") end, }, IgnorePlayerPets = { type = "toggle", name = L["Ignore Player Pets"], desc = L["IGNORE_PLAYER_PETS_DESC"], order = 11, set = function(info, value) db.IgnorePlayerPets = value Omen:UpdateBars() end, }, ClickThrough = { type = "toggle", name = L["Click Through"], desc = L["Makes the Omen window non-interactive"], order = 12, set = function(info, value) db.ClickThrough = value Omen:UpdateClickThrough() end, }, AutocollapseGroup = { type = "group", name = L["Autocollapse Options"], guiInline = true, order = 21, disabled = function() return not db.Autocollapse end, set = function(info, value) db[ info[#info] ] = value Omen:UpdateVisible() Omen:UpdateBars() end, args = { Autocollapse = { type = "toggle", name = L["Autocollapse"], desc = L["Collapse to show a minimum number of bars"], order = 1, set = function(info, value) db.Autocollapse = value Omen.Anchor:SetHeight(6*db.Bar.Height + 5*db.Bar.Spacing + Omen.Title:GetHeight() + 2*db.Background.BarInset) Omen:SetAnchors() Omen.BarList:Show() Omen:UpdateVisible() Omen:UpdateBars() end, disabled = false, }, GrowUp = { order = 2, type = "toggle", name = L["Grow bars upwards"], desc = L["Grow bars upwards"], set = function(info, value) db.GrowUp = value Omen:SetAnchors() end, }, CollapseHide = { order = 3, type = "toggle", name = L["Hide Omen on 0 bars"], desc = L["Hide Omen entirely if it collapses to show 0 bars"], set = function(info, value) db.CollapseHide = value if value then manualToggle = false end Omen:UpdateVisible() Omen:UpdateBars() end, }, NumBars = { order = 4, name = L["Max bars to show"], desc = L["Max number of bars to show"], type = "range", min = 1, max = 40, step = 1, }, }, }, Background = { type = "group", name = L["Background Options"], guiInline = true, order = 31, get = function(info) return db.Background[ info[#info] ] end, set = function(info, value) db.Background[ info[#info] ] = value Omen:UpdateBackdrop() end, args = { Texture = { type = "select", dialogControl = 'LSM30_Background', order = 1, name = L["Background Texture"], desc = L["Texture to use for the frame's background"], values = AceGUIWidgetLSMlists.background, }, BorderTexture = { type = "select", dialogControl = 'LSM30_Border', order = 2, name = L["Border Texture"], desc = L["Texture to use for the frame's border"], values = AceGUIWidgetLSMlists.border, }, Color = { type = "color", order = 3, name = L["Background Color"], desc = L["Frame's background color"], hasAlpha = true, get = function(info) local t = db.Background.Color return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.Background.Color t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBackdrop() end, }, BorderColor = { type = "color", order = 4, name = L["Border Color"], desc = L["Frame's border color"], hasAlpha = true, get = function(info) local t = db.Background.BorderColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.Background.BorderColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBackdrop() end, }, Tile = { type = "toggle", order = 5, name = L["Tile Background"], desc = L["Tile the background texture"], }, TileSize = { type = "range", order = 6, name = L["Background Tile Size"], desc = L["The size used to tile the background texture"], min = 16, max = 256, step = 1, disabled = function() return not db.Background.Tile end, }, EdgeSize = { type = "range", order = 7, name = L["Border Thickness"], desc = L["The thickness of the border"], min = 1, max = 16, step = 1, }, BarInset = { type = "range", order = 8, name = L["Bar Inset"], desc = L["Sets how far inside the frame the threat bars will display from the 4 borders of the frame"], min = 1, max = 16, step = 1, }, }, }, }, }, ShowWhen = { order = 2, type = "group", name = L["Show When..."], desc = L["Show Omen when..."], get = function(info) return db.ShowWith[ info[#info] ] end, set = function(info, value) db.ShowWith[ info[#info] ] = value manualToggle = false Omen:UpdateVisible() Omen:UpdateBars() end, args = { intro = { order = 1, type = "description", name = L["This section controls when Omen is automatically shown or hidden."], disabled = false, }, UseShowWith = { type = "toggle", order = 2, name = L["Use Auto Show/Hide"], desc = L["Use Auto Show/Hide"], disabled = false, }, ShowWithGroup = { type = "group", order = 3, guiInline = true, name = L["Use Auto Show/Hide"], desc = L["Use Auto Show/Hide"], disabled = function(info) return not db.ShowWith.UseShowWith end, args = { intro2 = { order = 10, type = "description", name = L["Show Omen when any of the following are true"], }, Alone = { type = "toggle", order = 11, name = L["You are alone"], desc = L["Show Omen when you are alone"], }, Party = { type = "toggle", order = 12, name = L["You are in a party"], desc = L["Show Omen when you are in a 5-man party"], }, Raid = { type = "toggle", order = 13, name = L["You are in a raid"], desc = L["Show Omen when you are in a raid"], }, Pet = { type = "toggle", order = 14, name = L["You have a pet"], desc = L["Show Omen when you have a pet out"], }, intro3 = { order = 20, type = "description", name = L["However, hide Omen if any of the following are true (higher priority than the above)."], }, HideInPVP = { type = "toggle", order = 21, width = "double", name = L["You are in a battleground"], desc = L["Turning this on will cause Omen to hide whenever you are in a battleground or arena."], }, HideWhileResting = { type = "toggle", order = 22, width = "double", name = L["You are resting"], desc = L["Turning this on will cause Omen to hide whenever you are in a city or inn."], }, HideWhenOOC = { type = "toggle", order = 23, width = "double", name = L["You are not in combat"], desc = L["Turning this on will cause Omen to hide whenever you are not in combat."], set = function(info, value) db.ShowWith.HideWhenOOC = value manualToggle = false if value then Omen:RegisterEvent("PLAYER_REGEN_DISABLED", "UpdateVisible") Omen:RegisterEvent("PLAYER_REGEN_ENABLED", "UpdateVisible") else Omen:UnregisterEvent("PLAYER_REGEN_DISABLED") Omen:UnregisterEvent("PLAYER_REGEN_ENABLED") end Omen:UpdateVisible() Omen:UpdateBars() end, }, intro4 = { order = 30, type = "description", name = L["AUTO_SHOW/HIDE_NOTE"], }, }, }, }, }, ShowClasses = { order = 3, type = "group", name = L["Show Classes..."], desc = L["Show Classes..."], args = { intro = { order = 1, type = "description", name = L["SHOW_CLASSES_DESC"], }, Classes = { type = "multiselect", order = 30, name = L["Show bars for these classes"], values = showClassesOptionTable, get = function(info, k) return db.Bar.Classes[k] end, set = function(info, k, v) db.Bar.Classes[k] = v Omen:UpdateBars() end, }, }, }, TitleBar = { order = 4, type = "group", name = L["Title Bar Settings"], desc = L["Title Bar Settings"], get = function(info) return db.TitleBar[ info[#info] ] end, set = function(info, value) db.TitleBar[ info[#info] ] = value Omen:UpdateTitleBar() Omen:UpdateBars() end, args = { intro = { order = 1, type = "description", name = L["Configure title bar settings."], }, ShowTitleBar = { type = "toggle", order = 2, name = L["Show Title Bar"], desc = L["Show the Omen Title Bar"], }, Height = { type = "range", order = 5, name = L["Title Bar Height"], desc = L["Height of the title bar. The minimum height allowed is twice the background border thickness."], min = 2, max = 32, step = 1, disabled = function() return not db.TitleBar.ShowTitleBar end, }, TitleText = { type = "group", name = L["Title Text Options"], guiInline = true, order = 20, set = function(info, value) db.TitleBar[ info[#info] ] = value Omen:UpdateTitleBar() end, disabled = function() return not db.TitleBar.ShowTitleBar end, args = { Font = { type = "select", dialogControl = 'LSM30_Font', order = 1, name = L["Font"], desc = L["The font that the title text will use"], values = AceGUIWidgetLSMlists.font, }, FontOutline = { type = "select", order = 2, name = L["Font Outline"], desc = L["The outline that the title text will use"], values = outlines, }, FontColor = { type = "color", order = 3, name = L["Font Color"], desc = L["The color of the title text"], hasAlpha = true, get = function(info) local t = db.TitleBar.FontColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.TitleBar.FontColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateTitleBar() end, }, FontSize = { type = "range", order = 4, name = L["Font Size"], desc = L["Control the font size of the title text"], min = 4, max = 30, step = 1, }, }, }, UseSameBG = { type = "toggle", order = 30, width = "double", name = L["Use Same Background"], desc = L["Use the same background settings for the title bar as the main window's background"], set = function(info, value) db.TitleBar.UseSameBG = value Omen:UpdateBackdrop() end, disabled = function() return not db.TitleBar.ShowTitleBar end, }, Background = { type = "group", name = L["Title Bar Background Options"], guiInline = true, order = 31, get = function(info) return db.TitleBar[ info[#info] ] end, set = function(info, value) db.TitleBar[ info[#info] ] = value Omen:UpdateBackdrop() end, disabled = function() return not db.TitleBar.ShowTitleBar or db.TitleBar.UseSameBG end, args = { Texture = { type = "select", dialogControl = 'LSM30_Background', order = 1, name = L["Background Texture"], desc = L["Texture to use for the frame's background"], values = AceGUIWidgetLSMlists.background, }, BorderTexture = { type = "select", dialogControl = 'LSM30_Border', order = 2, name = L["Border Texture"], desc = L["Texture to use for the frame's border"], values = AceGUIWidgetLSMlists.border, }, Color = { type = "color", order = 3, name = L["Background Color"], desc = L["Frame's background color"], hasAlpha = true, get = function(info) local t = db.TitleBar.Color return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.TitleBar.Color t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBackdrop() end, }, BorderColor = { type = "color", order = 4, name = L["Border Color"], desc = L["Frame's border color"], hasAlpha = true, get = function(info) local t = db.TitleBar.BorderColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.TitleBar.BorderColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBackdrop() end, }, Tile = { type = "toggle", order = 5, name = L["Tile Background"], desc = L["Tile the background texture"], }, TileSize = { type = "range", order = 6, name = L["Background Tile Size"], desc = L["The size used to tile the background texture"], min = 16, max = 256, step = 1, disabled = function() return not db.TitleBar.ShowTitleBar or db.TitleBar.UseSameBG or not db.TitleBar.Tile end, }, EdgeSize = { type = "range", order = 7, name = L["Border Thickness"], desc = L["The thickness of the border"], min = 1, max = 16, step = 1, }, }, }, }, }, Bars = { order = 5, type = "group", name = L["Bar Settings"], desc = L["Bar Settings"], get = function(info) return db.Bar[ info[#info] ] end, set = function(info, value) db.Bar[ info[#info] ] = value Omen:UpdateBars() end, args = { intro = { order = 1, type = "description", name = L["Configure bar settings."], }, AnimateBars = { type = "toggle", order = 2, name = L["Animate Bars"], desc = L["Smoothly animate bar changes"], }, ShortNumbers = { type = "toggle", order = 3, name = L["Short Numbers"], desc = L["Display large numbers in Ks"], disabled = function() return not db.Bar.ShowValue end }, Height = { type = "range", order = 4, name = L["Bar Height"], desc = L["Height of each bar"], min = 5, max = 50, step = 1, bigStep = 1, set = function(info, value) db.Bar.Height = value Omen:ReAnchorBars() Omen:ResizeBars() Omen:UpdateBars() end, }, Spacing = { type = "range", order = 5, name = L["Bar Spacing"], desc = L["Spacing between each bar"], min = 0, max = 20, step = 1, bigStep = 1, set = function(info, value) db.Bar.Spacing = value Omen:ReAnchorBars() Omen:UpdateBars() end, }, ShowTPS = { type = "toggle", order = 6, name = L["Show TPS"], desc = L["Show threat per second values"], set = function(info, value) db.Bar.ShowTPS = value if db.VGrip1 > db.VGrip2 then db.VGrip1, db.VGrip2 = db.VGrip2, db.VGrip1 end movegrip1() movegrip2() Omen:UpdateGrips() local f = Omen.TPSUpdateFrame if f then if value then f:Show() else f:Hide() end end end, }, TPSWindow = { type = "range", order = 7, name = L["TPS Window"], desc = L["TPS_WINDOW_DESC"], min = 3, max = 15, step = 0.1, disabled = function() return not db.Bar.ShowTPS end, }, ShowValue = { type = "toggle", order = 8, name = L["Show Threat Values"], desc = L["Show Threat Values"], set = function(info, value) db.Bar.ShowValue = value if not value then db.Bar.ShowPercent = true bars[0].Text2:SetText(L["Threat"]) elseif db.Bar.ShowPercent then bars[0].Text2:SetText(L["Threat [%]"]) end Omen:UpdateBars() end, }, ShowPercent = { type = "toggle", order = 9, name = L["Show Threat %"], desc = L["Show Threat %"], set = function(info, value) db.Bar.ShowPercent = value if not value then db.Bar.ShowValue = true bars[0].Text2:SetText(L["Threat"]) elseif db.Bar.ShowValue then bars[0].Text2:SetText(L["Threat [%]"]) end Omen:UpdateBars() end, }, ShowHeadings = { type = "toggle", order = 11, name = L["Show Headings"], desc = L["Show column headings"], set = function(info, value) db.Bar.ShowHeadings = value Omen:ReAnchorBars() Omen:UpdateBars() end, }, HeadingBGColor = { type = "color", order = 12, name = L["Heading BG Color"], desc = L["Heading background color"], hasAlpha = true, get = function(info) local t = db.Bar.HeadingBGColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.Bar.HeadingBGColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBarLabelSettings() Omen:UpdateBars() end, disabled = function() return not db.Bar.ShowHeadings end, }, UseMyBarColor = { type = "toggle", order = 13, name = L["Use 'My Bar' color"], desc = L["Use a different colored background for your threat bar in Omen"], }, MyBarColor = { type = "color", order = 14, name = L["'My Bar' BG Color"], desc = L["The background color for your threat bar"], hasAlpha = true, get = function(info) local t = db.Bar.MyBarColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.Bar.MyBarColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBars() end, disabled = function() return not db.Bar.UseMyBarColor end, }, UseTankBarColor = { type = "toggle", order = 15, name = L["Use Tank Bar color"], desc = L["Use a different colored background for the tank's threat bar in Omen"], }, TankBarColor = { type = "color", order = 16, name = L["Tank Bar Color"], desc = L["The background color for your tank's threat bar"], hasAlpha = true, get = function(info) local t = db.Bar.TankBarColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.Bar.TankBarColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBars() end, disabled = function() return not db.Bar.UseTankBarColor end, }, ShowAggroBar = { type = "toggle", order = 17, name = L["Show Pull Aggro Bar"], desc = L["Show a bar for the amount of threat you will need to reach in order to pull aggro."], }, AggroBarColor = { type = "color", order = 18, name = L["Pull Aggro Bar Color"], desc = L["The background color for your Pull Aggro bar"], hasAlpha = true, get = function(info) local t = db.Bar.AggroBarColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.Bar.AggroBarColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBars() end, disabled = function() return not db.Bar.ShowAggroBar end, }, UseClassColors = { type = "toggle", order = 21, name = L["Use Class Colors"], desc = L["Use standard class colors for the background color of threat bars"], }, PetBarColor = { type = "color", order = 22, name = L["Pet Bar Color"], desc = L["The background color for pets"], hasAlpha = true, get = function(info) local t = db.Bar.PetBarColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.Bar.PetBarColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBars() end, disabled = function() return not db.Bar.UseClassColors end, }, UseCustomClassColors = { type = "toggle", order = 23, name = L["Use !ClassColors"], desc = L["Use !ClassColors addon for class colors for the background color of threat bars"], set = function(info, v) db.Bar.UseCustomClassColors = v Omen:UpdateRaidClassColors() end, disabled = function() return not db.Bar.UseClassColors or not CUSTOM_CLASS_COLORS end, }, FadeBarColor = { type = "color", order = 24, name = L["Fade/MI Bar Color"], desc = L["The background color for players under the effects of Fade and Mirror Image (they will be at negative 4 million threat)"], hasAlpha = true, get = function(info) local t = db.Bar.FadeBarColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.Bar.FadeBarColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBars() end, }, BarColor = { type = "color", order = 25, name = L["Bar BG Color"], desc = L["The background color for all threat bars"], hasAlpha = true, get = function(info) local t = db.Bar.BarColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.Bar.BarColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBars() end, disabled = function() return db.Bar.UseClassColors end, }, AlwaysShowSelf = { type = "toggle", order = 26, name = L["Always Show Self"], desc = L["Always show your threat bar on Omen (ignores class filter settings), showing your bar on the last row if necessary"], }, InvertColors = { type = "toggle", order = 27, name = L["Invert Bar/Text Colors"], desc = L["Switch the colors so that the bar background colors and the text colors are swapped."], set = function(info, v) db.Bar.InvertColors = v Omen:UpdateBarLabelSettings() Omen:UpdateBars() end, }, Texture = { type = "select", dialogControl = 'LSM30_Statusbar', order = 29, name = L["Bar Texture"], desc = L["The texture that the bar will use"], values = AceGUIWidgetLSMlists.statusbar, set = function(info, v) db.Bar.Texture = v Omen:UpdateBarTextureSettings() end, }, BarLabelsGroup = { type = "group", name = L["Bar Label Options"], guiInline = true, order = 30, set = function(info, v) db.Bar[ info[#info] ] = v Omen:UpdateBarLabelSettings() Omen:UpdateBars() end, args = { Font = { type = "select", dialogControl = 'LSM30_Font', order = 1, name = L["Font"], desc = L["The font that the labels will use"], values = AceGUIWidgetLSMlists.font, }, FontOutline = { type = "select", order = 2, name = L["Font Outline"], desc = L["The outline that the labels will use"], values = outlines, }, FontColor = { type = "color", order = 3, name = L["Font Color"], desc = L["The color of the labels"], hasAlpha = true, get = function(info) local t = db.Bar.FontColor return t.r, t.g, t.b, t.a end, set = function(info, r, g, b, a) local t = db.Bar.FontColor t.r, t.g, t.b, t.a = r, g, b, a Omen:UpdateBarLabelSettings() Omen:UpdateBars() end, }, FontSize = { type = "range", order = 4, name = L["Font Size"], desc = L["Control the font size of the labels"], min = 4, max = 30, step = 1, }, }, }, }, }, Warnings = { order = 6, type = "group", name = L["Warning Settings"], desc = L["Warning Settings"], get = function(info) return db.Warnings[ info[#info] ] end, set = function(info, value) db.Warnings[ info[#info] ] = value end, args = { intro = { order = 1, type = "description", name = L["OMEN_WARNINGS_DESC"], }, Sound = { type = "toggle", order = 2, name = L["Enable Sound"], desc = L["Causes Omen to play a chosen sound effect"], }, Flash = { type = "toggle", order = 3, name = L["Enable Screen Flash"], desc = L["Causes the entire screen to flash red momentarily"], }, Shake = { type = "toggle", order = 4, name = L["Enable Screen Shake"], desc = L["Causes the entire game world to shake momentarily. This option only works if nameplates are turned off."], }, Message = { type = "toggle", order = 5, name = L["Enable Warning Message"], desc = L["Print a message to screen when you accumulate too much threat"], }, Output = Omen:GetSinkAce3OptionsDataTable(), Threshold = { type = "range", order = 7, name = L["Warning Threshold %"], desc = L["Warning Threshold %"], min = 60, max = 130, step = 1, }, SoundFile = { type = "select", dialogControl = 'LSM30_Sound', order = 8, name = L["Sound to play"], desc = L["Sound to play"], values = AceGUIWidgetLSMlists.sound, disabled = function() return not db.Warnings.Sound end, }, DisableWhileTanking = { type = "toggle", order = 9, name = L["Disable while tanking"], desc = L["DISABLE_WHILE_TANKING_DESC"], }, test = { type = "execute", order = -1, name = L["Test warnings"], desc = L["Test warnings"], func = function() local t = db.Warnings Omen:Warn(t.Sound, t.Flash, t.Shake, t.Message and L["Test warnings"]) end, }, }, }, FuBar = { order = -4, type = "group", name = L["FuBar Options"], desc = L["FuBar Options"], hidden = function() return Omen.IsFuBarMinimapAttached == nil end, args = { hideIcon = { type = "toggle", order = 1, name = L["Hide minimap/FuBar icon"], desc = L["Hide minimap/FuBar icon"], get = function(info) return db.FuBar.HideMinimapButton end, set = function(info, v) db.FuBar.HideMinimapButton = v Omen:UpdateFuBarSettings() end, }, attachMinimap = { type = "toggle", order = 2, name = L["Attach to minimap"], desc = L["Attach to minimap"], get = function(info) return Omen:IsFuBarMinimapAttached() end, set = function(info, v) Omen:ToggleFuBarMinimapAttached() db.FuBar.AttachMinimap = Omen:IsFuBarMinimapAttached() end, disabled = function() return db.FuBar.HideMinimapButton end, }, showIcon = { type = "toggle", order = 3, name = L["Show icon"], desc = L["Show icon"], get = function(info) return Omen:IsFuBarIconShown() end, set = function(info, v) Omen:ToggleFuBarIconShown() end, disabled = GetFuBarMinimapAttachedStatus, }, showText = { type = "toggle", order = 4, name = L["Show text"], desc = L["Show text"], get = function(info) return Omen:IsFuBarTextShown() end, set = function(info, v) Omen:ToggleFuBarTextShown() end, disabled = GetFuBarMinimapAttachedStatus, }, position = { type = "select", order = 5, name = L["Position"], desc = L["Position"], values = {LEFT = L["Left"], CENTER = L["Center"], RIGHT = L["Right"]}, get = function() return Omen:GetPanel() and Omen:GetPanel():GetPluginSide(Omen) end, set = function(info, val) if Omen:GetPanel() and Omen:GetPanel().SetPluginSide then Omen:GetPanel():SetPluginSide(Omen, val) end end, disabled = GetFuBarMinimapAttachedStatus, } } }, Help = { type = "group", order = -1, name = L["Help File"], desc = L["A collection of help pages"], childGroups = "select", args = { FAQ1 = { type = "group", order = 1, name = L["FAQ Part 1"], args = { header = { type = "header", name = L["Frequently Asked Questions"], order = 0, }, text = { order = 1, type = "description", name = L["GENERAL_FAQ"], }, }, }, FAQ2 = { type = "group", order = 2, name = L["FAQ Part 2"], args = { header = { type = "header", name = L["Frequently Asked Questions"], order = 0, }, text = { order = 1, type = "description", name = L["GENERAL_FAQ2"], }, }, }, WARRIOR = { type = "group", name = L["Warrior"], args = { header = { type = "header", name = L["Warrior"], order = 0, }, text = { order = 1, type = "description", name = L["WARRIOR_FAQ"], }, }, }, }, }, }, } Omen.Options.args.Warnings.args.Output.order = 6 Omen.Options.args.Warnings.args.Output.inline = true Omen.Options.args.Warnings.args.Output.disabled = function() return not db.Warnings.Message end for k, v in pairs(moduleOptions) do Omen.Options.args[k] = (type(v) == "function") and v() or v end -- Add ordering data to the option table generated by AceDBOptions-3.0 Omen.Options.args.Profiles.order = -2 local h = db.Background.EdgeSize * 2 if not db.TitleBar.UseSameBG then h = db.TitleBar.EdgeSize * 2 end Omen.Options.args.TitleBar.args.Height.min = h end