/branches
-------------------------------------------------------------------------- |
-- Install.lua -- SoopUI Version 3.0.0 Beta 1 |
-- For help please check WoWinterface or TopShelfSargeras.com |
-- You can reach me on Twitter @TrueSteve or Soopie (Sargeras [US] Alliance) |
-- http://www.wowinterface.com/downloads/info22541-SoopUI.html |
-------------------------------------------------------------------------- |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI") |
local db, dbc, dbg, spec |
local CURRENT_PAGE = 0 |
local MAX_PAGE = 5 |
local SoopUICharacter = { |
installStage = 0, |
} |
-------------------------------------------------------------------------- |
-- Console Variables (CVars) |
-------------------------------------------------------------------------- |
function SoopUI:SetupCVars() |
-- Graphics |
if GetCVar("gxMultisample") ~= "1" then |
SetCVar("gxMultisample", 1) |
RestartGx() |
end |
-- Sounds |
SetCVar("Sound_EnableErrorSpeech", 0) |
-- Screenshots |
SetCVar("screenshotFormat", "jpg") |
SetCVar("screenshotQuality", "10") |
-- Help |
SetCVar("showGameTips", 0) |
SetCVar("showTutorials", 0) |
SetCVar("UberTooltips", 1) |
if UnitName("player") == "Soopie - Sargeras" then |
SetCVar("scriptErrors", 1) |
else |
SetCVar("scriptErrors", 0) |
end |
-- Controls |
SetCVar("deselectOnClick", 1) |
-- Camera |
SetCVar("cameraYawSmoothSpeed", 210) |
SetCVar("cameraView", 1) |
SetCVar("cameraDistanceMax", 50) |
SetCVar("cameraDistanceMaxFactor", 3) |
SetCVar("cameraPivot", 0) |
SetCVar("cameraSmoothStyle", 0) |
-- Other |
SetCVar("profanityFilter", 0) |
SetCVar("checkAddonVersion", 0) |
if GetCVar("autoLootDefault") == 0 then |
SetCVar("autoLootDefault", 1) |
end |
end |
-------------------------------------------------------------------------- |
-- Chat Setup |
-------------------------------------------------------------------------- |
function SoopUI:SetupChat() |
FCF_ResetChatWindows() |
FCF_SetLocked(ChatFrame1, 1) |
FCF_DockFrame(ChatFrame2) |
FCF_SetLocked(ChatFrame2, 1) |
FCF_OpenNewWindow(LOOT) |
FCF_DockFrame(ChatFrame4) |
FCF_SetLocked(ChatFrame4, 1) |
FCF_OpenNewWindow(LOOT) |
FCF_DockFrame(ChatFrame3) |
FCF_SetLocked(ChatFrame3, 1) |
for i = 1, 3 do |
local frame = _G[format("ChatFrame%s", i)] |
local chatFrameId = frame:GetID() |
local chatName = FCF_GetChatWindowInfo(chatFrameId) |
if i == 1 then |
frame:ClearAllPoints() |
frame:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT", 0, 0) |
frame:SetHeight(100) |
frame:SetWidth(375) |
end |
FCF_SavePositionAndDimensions(frame) |
FCF_StopDragging(frame) |
FCF_SetWindowAlpha(ChatFrame1, 0) |
FCF_SetWindowAlpha(ChatFrame2, 0) |
if i == 1 then |
FCF_SetWindowName(frame, "G/S/W") |
elseif i == 2 then |
FCF_SetWindowName(frame, "COMBAT_LOG") |
elseif i == 3 then |
FCF_SetWindowName(frame, "Gen / Trade") |
elseif i == 4 then |
FCF_SetWindowName(frame, "Loot") |
end |
end |
---------------- Chat 1 G/S/W |
ChatFrame_RemoveAllMessageGroups(ChatFrame1) |
ChatFrame_AddMessageGroup(ChatFrame1, "SAY") |
ChatFrame_AddMessageGroup(ChatFrame1, "EMOTE") |
ChatFrame_AddMessageGroup(ChatFrame1, "YELL") |
ChatFrame_AddMessageGroup(ChatFrame1, "GUILD") |
ChatFrame_AddMessageGroup(ChatFrame1, "OFFICER") |
ChatFrame_AddMessageGroup(ChatFrame1, "GUILD_ACHIEVEMENT") |
ChatFrame_AddMessageGroup(ChatFrame1, "WHISPER") |
ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_SAY") |
ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_EMOTE") |
ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_YELL") |
ChatFrame_AddMessageGroup(ChatFrame1, "MONSTER_BOSS_EMOTE") |
ChatFrame_AddMessageGroup(ChatFrame1, "PARTY") |
ChatFrame_AddMessageGroup(ChatFrame1, "PARTY_LEADER") |
ChatFrame_AddMessageGroup(ChatFrame1, "RAID") |
ChatFrame_AddMessageGroup(ChatFrame1, "RAID_LEADER") |
ChatFrame_AddMessageGroup(ChatFrame1, "RAID_WARNING") |
ChatFrame_AddMessageGroup(ChatFrame1, "INSTANCE_CHAT") |
ChatFrame_AddMessageGroup(ChatFrame1, "INSTANCE_CHAT_LEADER") |
ChatFrame_AddMessageGroup(ChatFrame1, "BATTLEGROUND") |
ChatFrame_AddMessageGroup(ChatFrame1, "BATTLEGROUND_LEADER") |
ChatFrame_AddMessageGroup(ChatFrame1, "BG_HORDE") |
ChatFrame_AddMessageGroup(ChatFrame1, "BG_ALLIANCE") |
ChatFrame_AddMessageGroup(ChatFrame1, "BG_NEUTRAL") |
ChatFrame_AddMessageGroup(ChatFrame1, "SYSTEM") |
ChatFrame_AddMessageGroup(ChatFrame1, "ERRORS") |
ChatFrame_AddMessageGroup(ChatFrame1, "AFK") |
ChatFrame_AddMessageGroup(ChatFrame1, "DND") |
ChatFrame_AddMessageGroup(ChatFrame1, "IGNORED") |
ChatFrame_AddMessageGroup(ChatFrame1, "ACHIEVEMENT") |
ChatFrame_AddMessageGroup(ChatFrame1, "BN_WHISPER") |
ChatFrame_AddMessageGroup(ChatFrame1, "BN_CONVERSATION") |
ChatFrame_AddMessageGroup(ChatFrame1, "BN_INLINE_TOAST_ALERT") |
ChatFrame_RemoveChannel(ChatFrame1, GENERAL) |
ChatFrame_RemoveChannel(ChatFrame1, TRADE) |
---------------- Chat 3 General / Trade |
ChatFrame_RemoveAllMessageGroups(ChatFrame3) |
ChatFrame_AddChannel(ChatFrame3, TRADE) |
ChatFrame_AddChannel(ChatFrame3, GENERAL) |
---------------- Chat 4 Loot |
ChatFrame_RemoveAllMessageGroups(ChatFrame4) |
ChatFrame_AddMessageGroup(ChatFrame4, "SKILL") |
ChatFrame_AddMessageGroup(ChatFrame4, "LOOT") |
ChatFrame_AddMessageGroup(ChatFrame4, "MONEY") |
ChatFrame_AddMessageGroup(ChatFrame4, "COMBAT_XP_GAIN") |
ChatFrame_AddMessageGroup(ChatFrame4, "COMBAT_HONOR_GAIN") |
ChatFrame_AddMessageGroup(ChatFrame4, "COMBAT_GUILD_XP_GAIN") |
--Adjust Chat Colors |
--General |
ChangeChatColor("CHANNEL1", 195/255, 230/255, 232/255) |
--Trade |
ChangeChatColor("CHANNEL2", 232/255, 158/255, 121/255) |
--Local Defense |
ChangeChatColor("CHANNEL3", 232/255, 228/255, 121/255) |
---------------- enable class color automatically on login and on each character without doing /configure each time. |
ToggleChatColorNamesByClassGroup(true, "SAY") |
ToggleChatColorNamesByClassGroup(true, "EMOTE") |
ToggleChatColorNamesByClassGroup(true, "YELL") |
ToggleChatColorNamesByClassGroup(true, "GUILD") |
ToggleChatColorNamesByClassGroup(true, "OFFICER") |
ToggleChatColorNamesByClassGroup(true, "GUILD_ACHIEVEMENT") |
ToggleChatColorNamesByClassGroup(true, "ACHIEVEMENT") |
ToggleChatColorNamesByClassGroup(true, "WHISPER") |
ToggleChatColorNamesByClassGroup(true, "PARTY") |
ToggleChatColorNamesByClassGroup(true, "PARTY_LEADER") |
ToggleChatColorNamesByClassGroup(true, "RAID") |
ToggleChatColorNamesByClassGroup(true, "RAID_LEADER") |
ToggleChatColorNamesByClassGroup(true, "RAID_WARNING") |
ToggleChatColorNamesByClassGroup(true, "BATTLEGROUND") |
ToggleChatColorNamesByClassGroup(true, "BATTLEGROUND_LEADER") |
ToggleChatColorNamesByClassGroup(true, "INSTANCE_CHAT") |
ToggleChatColorNamesByClassGroup(true, "INSTANCE_CHAT_LEADER") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL1") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL2") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL3") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL4") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL5") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL6") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL7") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL8") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL9") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL10") |
ToggleChatColorNamesByClassGroup(true, "CHANNEL11") |
end |
local function ResetAll() |
InstallNextButton:Disable() |
InstallPrevButton:Disable() |
InstallOption1Button:Hide() |
InstallOption1Button:SetScript("OnClick", nil) |
InstallOption1Button:SetText("") |
InstallOption2Button:Hide() |
InstallOption2Button:SetScript('OnClick', nil) |
InstallOption2Button:SetText('') |
SoopUIInstallFrame.subtitle:SetText("") |
SoopUIInstallFrame.desc1:SetText("") |
SoopUIInstallFrame.desc2:SetText("") |
SoopUIInstallFrame.desc3:SetText("") |
SoopUIInstallFrame:SetSize(550, 400) |
end |
local function SetupTank() |
SoopUI:Setup("Tank") |
SoopUI.db.char.layout.current = 1 |
end |
local function SetupHealing() |
SoopUI:Setup("Healing") |
SoopUI.db.char.layout.current = 2 |
end |
local function SC() |
SoopUI:SetupChat() |
end |
local function SCV() |
SoopUI:SetupCVars() |
end |
function SoopUI:SwitchLayout() |
if SoopUI.cLayout == 1 then |
SoopUI.db.char.layout.current = 2 |
SoopUI.cLayout = 2 |
SoopUI:SetLayoutProfile() |
elseif SoopUI.cLayout == 2 then |
SoopUI.db.char.layout.current = 1 |
SoopUI.cLayout = 1 |
SoopUI:SetLayoutProfile() |
end |
StaticPopup_Show ("SOOPUI_RELOADUI") |
end |
function SoopUI:Setup(spec) |
db = self.db.profile |
dbc = self.db.char |
dbg = self.db.global |
spec = spec |
SoopUICharacter.installStage = -1 |
if dbg.tags.firsttime then |
dbg.tags.firsttime = false |
dbg.install.stage = 0 |
end |
SoopUI:MakeProfile(spec) |
end |
local function FinishSetup() |
ReloadUI() |
end |
function SoopUI:reloadUI() |
ReloadUI() |
end |
local function SetPage(PageNum) |
CURRENT_PAGE = PageNum |
ResetAll() |
InstallStatus:SetValue(PageNum) |
local f = SoopUIInstallFrame |
if PageNum == MAX_PAGE then |
InstallNextButton:Disable() |
else |
InstallNextButton:Enable() |
end |
if PageNum == 1 then |
InstallPrevButton:Disable() |
else |
InstallPrevButton:Enable() |
end |
-------------------------------------------------------------------------- |
-- Installation Text |
-------------------------------------------------------------------------- |
if PageNum == 1 then |
f.subtitle:SetText("This is SoopUI!!") |
----------------- Logo |
f.logoText = f:CreateTexture(nil, "OVERLAY") ---- <--- might break it |
f.logoText:SetPoint("CENTER", f, "CENTER") |
f.logoText:SetSize(400, 100) |
f.logoText:SetTexture(MEDIA_PATH .. "Interface\\AddOns\\SoopUI\\media\\logo_sui") |
----------------- Logo |
f.desc1:SetText("SoopUI 3 Beta 1") |
f.desc2:SetText("Healing NOT supported this beta version") |
InstallOption1Button:Hide() |
InstallOption2Button:Hide() |
elseif PageNum == 2 then |
f.subtitle:SetText("Spec Setup") |
f.desc1:SetText("Certain functions will be automatically enabled or disabled") |
f.desc3:SetText("This UI is optimized for Tanking (or DPS). ") |
InstallOption1Button:Show() |
InstallOption1Button:SetScript("OnClick", SetupTank) |
InstallOption1Button:SetText("Tank") |
InstallOption2Button:Show() |
InstallOption2Button:SetPoint("BOTTOM", 50, 45) |
InstallOption2Button:SetScript("OnClick", SetupHealing) |
InstallOption2Button:SetText("Healing") |
elseif PageNum == 3 then |
f.subtitle:SetText("Console Variables (CVars)") |
f.desc1:SetText("Optimized default WoW console settings") |
f.desc2:SetText("Changes options like, disabling profanity filter and camera by default") |
f.desc3:SetText("Press Setup CVars to load SoopUI CVars and continue.") |
InstallOption2Button:Hide() |
InstallOption1Button:Show() |
InstallOption1Button:SetScript("OnClick", SCV) |
InstallOption1Button:SetText("Setup CVars") |
elseif PageNum == 4 then |
f.subtitle:SetText("Chat Setup") |
f.desc1:SetText("Setup chat options now so you don't have to do it yourself") |
f.desc2:SetText("Creates chat tabs, etc.") |
f.desc3:Hide() |
InstallOption2Button:Hide() |
InstallOption1Button:Show() |
InstallOption1Button:SetScript("OnClick", SC) |
InstallOption1Button:SetText("Setup Chat") |
elseif PageNum == 5 then |
f.subtitle:SetText("We're Done!") |
f.desc1:SetText("SoopUI is all setup!") |
f.desc2:SetText("If you have questions or feedback, get in touch on WoWInterface.") |
InstallOption1Button:Show() |
InstallOption1Button:SetText("Finish") |
InstallOption1Button:SetScript("OnClick", FinishSetup) |
InstallOption2Button:Hide() |
else |
SetPage(1) |
end |
end |
local function NextPage() |
if CURRENT_PAGE ~= MAX_PAGE then |
CURRENT_PAGE = CURRENT_PAGE + 1 |
SetPage(CURRENT_PAGE) |
end |
end |
local function PrevPage() |
if CURRENT_PAGE ~= 1 then |
CURRENT_PAGE = CURRENT_PAGE - 1 |
SetPage(CURRENT_PAGE) |
end |
end |
-------------------------------------------------------------------------- |
-- Installation Button Positions |
-------------------------------------------------------------------------- |
function SoopUI:NewInstallProcess() |
if not SoopUIInstallFrame then |
local f = CreateFrame("Button", "SoopUIInstallFrame", UIParent) |
f:SetSize(550, 400) |
f:SetBackdrop({bgFile = [[Interface\Addons\SoopUI\media\Minimalist]], ---- <--- might break it |
edgeFile = "", |
tile = false, tileSize = 0, edgeSize = 1, |
insets = { left = 0, right = 0, top = 0, bottom = 0 } |
}); |
f:SetBackdropColor(0,0,0,.8); |
f:SetPoint("CENTER") |
f:SetFrameStrata("TOOLTIP") |
f.title = f:CreateFontString(nil, "OVERLAY") |
f.title:SetPoint("TOP", 0, -5) |
f.title:SetFont([[Interface\Addons\SoopUI\media\expressway.ttf]], 13) |
f.title:SetText("SoopUI Installation v"..SoopUI.version) |
f.subtitle = f:CreateFontString(nil, "OVERLAY") |
f.subtitle:SetPoint("TOP", 0, -40) |
f.subtitle:SetFont(SoopUI.media.express, 15) |
f.subtitle:SetTextColor(0, 1, 0, 1) |
f.next = CreateFrame("Button", "InstallNextButton", f, "UIPanelButtonTemplate") |
f.next:SetSize(110, 25) |
f.next:SetPoint("BOTTOMRIGHT", -5, 5) |
f.next:SetText(CONTINUE) |
f.next:SetScript("OnClick", NextPage) |
SoopUI:HandleButton(f.next, true) |
f.prev = CreateFrame("Button", "InstallPrevButton", f, "UIPanelButtonTemplate") |
f.prev:SetSize(110, 25) |
f.prev:SetPoint("BOTTOMLEFT", -5, 5) |
f.prev:SetText(PREVIOUS) |
f.prev:SetScript("OnClick", PrevPage) |
SoopUI:HandleButton(f.prev, true) |
f.status = CreateFrame("StatusBar", "InstallStatus", f) |
f.status:SetFrameLevel(f.status:GetFrameLevel() + 2) |
f.status:SetBackdrop({ |
bgFile = [[Interface\BUTTONS\WHITE8X8]], |
edgeFile = "", |
tile = false, tileSize = 0, EdgeSize = 1, |
insets = { left = 0, right = 0, top = 0, bottom = 0} |
}) |
f.status:SetBackdropColor(.2, .8, .2, 1) |
f.status:SetMinMaxValues(0, MAX_PAGE) |
f.status:SetPoint("TOPLEFT", f.prev, "TOPRIGHT", 6, -2) |
f.status:SetPoint("BOTTOMRIGHT", f.next, "BOTTOMLEFT", -6, 2) |
f.status.text = f.status:CreateFontString(nil, "OVERLAY") |
f.status.text:SetFont(SoopUI.media.express, 12) |
f.status.text:SetPoint("CENTER") |
f.status.text:SetText(CURRENT_PAGE.." / "..MAX_PAGE) |
f.status:SetScript("OnValueChanged", function(self) |
self.text:SetText(self:GetValue().." / "..MAX_PAGE) |
end) |
f.option1 = CreateFrame("Button", "InstallOption1Button", f, "UIPanelButtonTemplate") |
f.option1:SetSize(160, 30) |
f.option1:SetPoint("BOTTOM", 0, 45) |
f.option1:SetText("") |
f.option1:Hide() |
SoopUI:HandleButton(f.option1, true) |
f.option2 = CreateFrame("Button", "InstallOption2Button", f, "UIPanelButtonTemplate") |
f.option2:SetSize(160, 30) |
f.option2:SetPoint("BOTTOM", 0, 45) |
f.option2:SetText("") |
f.option2:Hide() |
f.option2:SetScript('OnShow', function() f.option1:SetWidth(110); f.option1:ClearAllPoints(); f.option1:SetPoint('BOTTOMRIGHT', f, 'BOTTOM', -15, 45) end) |
f.option2:SetScript('OnHide', function() f.option1:SetWidth(160); f.option1:ClearAllPoints(); f.option1:SetPoint("BOTTOM", 0, 45) end) |
SoopUI:HandleButton(f.option2, true) |
f.desc1 = f:CreateFontString(nil, "OVERLAY") |
f.desc1:SetFont(SoopUI.media.express, 13) |
f.desc1:SetPoint("TOPLEFT", 20, -75) |
f.desc1:SetWidth(f:GetWidth() - 40) |
f.desc2 = f:CreateFontString(nil, "OVERLAY") |
f.desc2:SetFont(SoopUI.media.express, 13) |
f.desc2:SetPoint("TOPLEFT", 20, -125) |
f.desc2:SetWidth(f:GetWidth() - 40) |
f.desc3 = f:CreateFontString(nil, "OVERLAY") |
f.desc3:SetFont(SoopUI.media.express, 13) |
f.desc3:SetPoint("TOPLEFT", 20, -175) |
f.desc3:SetWidth(f:GetWidth() - 40) |
local close = CreateFrame("Button", "InstallCloseButton", f, "UIPanelCloseButton") |
close:SetPoint("TOPRIGHT", f, "TOPRIGHT") |
close:SetScript("OnClick", function() |
f:Hide() |
CURRENT_PAGE = 0 |
end) |
SoopUI:HandleCloseButton(close) |
end |
SoopUIInstallFrame:Show() |
NextPage() |
end |
-------------------------------------------------------------------------- |
-- Button handlers |
-------------------------------------------------------------------------- |
function SoopUI:HandleButton(f, strip) |
if f.Left then f.Left:SetAlpha(0) end |
if f.Middle then f.Middle:SetAlpha(0) end |
if f.Right then f.Right:SetAlpha(0) end |
if f.SetNormalTexture then f:SetNormalTexture("") end |
if f.SetHighlightTexture then f:SetHighlightTexture("") end |
if f.SetPushedTexture then f:SetPushedTexture("") end |
if f.SetDisabledTexture then f:SetDisabledTexture("") end |
end |
function SoopUI:HandleCloseButton(f, point, text) |
if not text then text = 'x' end |
if not f.text then |
f.text = f:CreateFontString(nil, 'OVERLAY') |
f.text:SetFont([[Interface\AddOns\SoopUI\media\expressway.ttf]], 16, 'OUTLINE') |
f.text:SetText(text) |
f.text:SetJustifyH('CENTER') |
f.text:SetPoint('CENTER', f, 'CENTER') |
end |
if point then |
f:Point("TOPRIGHT", point, "TOPRIGHT", 2, 2) |
end |
end |
-------------------------------------------------------------------------- |
-- Popup Dialogues |
-------------------------------------------------------------------------- |
StaticPopupDialogs["SOOPUI_RELOADUI"] = { |
text = "You must reload your UI before using it. Should we do that now?", |
button1 = "Yes", |
button2 = "No", |
OnAccept = function() |
ReloadUI() |
end, |
timeout = 0, |
whileDead = true, |
hideOnEscape = true, |
preferredIndex = 3, -- avoid some UI taint, see http://www.wowace.com/announcements/how-to-avoid-some-ui-taint/ |
} |
StaticPopupDialogs["SOOP_UIERROR"] = { |
text = "We do not support this resolution, use SoopUI UI at own risk.", |
button1 = "Disable Addon", |
button2 = "Okay", |
OnAccept = function() |
DisableAddOn("SoopUI") |
ReloadUI() |
end, |
OnCancel = function() |
StaticPopup_Hide("SoopUI_UIERROR") |
SoopUI.db.global.tags.uaor = 1 |
end, |
timeout = 0, |
whileDead = true, |
hideOnEscape = false, |
preferredIndex = 3, -- avoid some UI taint, see http://www.wowace.com/announcements/how-to-avoid-some-ui-taint/ |
} |
-------------------------------------------------------------------------- |
-- Resolution Check |
-------------------------------------------------------------------------- |
function SoopUI:CheckResolution() |
local resolution = GetCVar("gxResolution") |
local resHeight = tonumber(string.match(resolution, "%d+x(%d+)")) |
if(resHeight < 900) then |
if self.db.global.tags.uaor == -1 then |
StaticPopup_Show("SOOP_UIERROR") |
end |
end |
end |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI") |
local db, dbc, dbg |
local suim = SoopUI:NewModule("SoopUIMedia", "AceEvent-3.0") |
suim = { |
logoBG = "Interface\\AddOns\\SoopUI\\media\\logo", |
logoText ="Interface\\AddOns\\SoopUI\\media\\logo_sui", |
plain = "Interface\\AddOns\\SoopUI\\media\\Plain", |
blank = "Interface\\AddOns\\SoopUI\\media\\blank", |
highlight_texture = "Interface\\AddOns\\SoopUI\\media\\raidbg", |
backdrop_edge_texture = "Interface\\AddOns\\SoopUI\\media\\backdrop_edge", |
backdrop_texture = "Interface\\AddOns\\SoopUI\\media\\backdrop", |
powerbar_texture = "Interface\\AddOns\\SoopUI\\media\\Minimalist", |
iconborder = "Interface\\AddOns\\SoopUI\\media\\iconborder", |
---- Font |
express = "Interface\\AddOns\\SoopUI\\media\\expressway.ttf", |
} |
function suim:OnInitialize() |
self.db = SoopUI.db:RegisterNamespace(suim) |
end |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI") |
SoopUI:RegisterChatCommand("rl", function() ReloadUI() end) |
SoopUI:RegisterChatCommand("install", function() SoopUI:NewInstallProcess() end) |
SoopUI:RegisterChatCommand("getcharlayout", function() print("Current layout: "..dbc.layout.current) end) |
SoopUI:RegisterChatCommand("switch", function() SoopUI:SwitchLayout() end) |
SoopUI:RegisterChatCommand("suihelp", function() |
print("SoopUI Help") |
print("-----------------------------------------------------") |
print("/install to make a new clean install.") |
print("/switch to switch between tank/dps and healing layout.") |
print("suihelp to show this message.") |
end) |
SLASH_FRAME1 = "/frame" |
SlashCmdList["FRAME"] = function(arg) |
if arg ~= "" then |
arg = _G[arg] |
else |
arg = GetMouseFocus() |
end |
if arg ~= nil then FRAME = arg end --Set the global variable FRAME to = whatever we are mousing over to simplify messing with frames that have no name. |
if arg ~= nil and arg:GetName() ~= nil then |
local point, relativeTo, relativePoint, xOfs, yOfs = arg:GetPoint() |
ChatFrame1:AddMessage("|cffCC0000----------------------------") |
ChatFrame1:AddMessage("Name: |cffFFD100"..arg:GetName()) |
if arg:GetParent() and arg:GetParent():GetName() then |
ChatFrame1:AddMessage("Parent: |cffFFD100"..arg:GetParent():GetName()) |
end |
ChatFrame1:AddMessage("Width: |cffFFD100"..format("%.2f",arg:GetWidth())) |
ChatFrame1:AddMessage("Height: |cffFFD100"..format("%.2f",arg:GetHeight())) |
ChatFrame1:AddMessage("Strata: |cffFFD100"..arg:GetFrameStrata()) |
ChatFrame1:AddMessage("Level: |cffFFD100"..arg:GetFrameLevel()) |
if xOfs then |
ChatFrame1:AddMessage("X: |cffFFD100"..format("%.2f",xOfs)) |
end |
if yOfs then |
ChatFrame1:AddMessage("Y: |cffFFD100"..format("%.2f",yOfs)) |
end |
if relativeTo and relativeTo:GetName() then |
ChatFrame1:AddMessage("Point: |cffFFD100"..point.."|r anchored to "..relativeTo:GetName().."'s |cffFFD100"..relativePoint) |
end |
ChatFrame1:AddMessage("|cffCC0000----------------------------") |
elseif arg == nil then |
ChatFrame1:AddMessage("Invalid frame name") |
else |
ChatFrame1:AddMessage("Could not find frame info") |
end |
end |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI") |
local db, ndb, ndbc |
local SoopUIAddOns = { |
["Bartender4"] = {isAce = true, db = "Bartender4DB", skipLayoutChange = true}, |
} |
function SetProfileKey(addonDB, profile, isAce, skipLayoutChange) |
local profKey = isAce and "profileKeys" |
if _G[addonDB] then |
if isAce then |
if (skipLayoutChange) then |
_G[addonDB][profKey][SoopUI.key] = 'Tank' |
else |
_G[addonDB][profKey][SoopUI.key] = profile |
end |
else |
if (skipLayoutChange) then |
_G[addonDB][profKey] = 'Tank' |
else |
_G[addonDB][profKey] = profile |
end |
end |
end |
end |
function SoopUI:MakeProfile(spec) |
for addon, data in pairs(SoopUIAddOns) do |
local profile = spec |
SetProfileKey(data.db, profile, data.isAce, data.skipLayoutChange) |
end |
end |
function SoopUI:SetLayoutProfile() |
for addon, data in pairs(SoopUIAddOns) do |
if data.skipLayoutChange == false then |
local profile = nil |
if SoopUI.db.char.layout.current == 1 then |
profile = "Tank" |
else |
profile = "Healing" |
end |
local aceAddon = LibStub("AceAddon-3.0"):GetAddon(addon) |
if aceAddon then |
aceAddon.db:SetProfile(profile) |
end |
end |
end |
end |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="libs\AceAddon-3.0\AceAddon-3.0.lua"/> |
<Script file="libs\AceDB-3.0\AceDB-3.0.lua"/> |
<Script file="libs\AceDBOptions-3.0\AceDBOptions-3.0.lua"/> |
<Script file="libs\AceConsole-3.0\AceConsole-3.0.lua"/> |
<Script file="libs\AceEvent-3.0\AceEvent-3.0.lua"/> |
<Script file="libs\LibStub\LibStub.lua"/> |
</Ui> |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="AceDBOptions-3.0.lua"/> |
</Ui> |
--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles. |
-- @class file |
-- @name AceDBOptions-3.0 |
-- @release $Id: AceDBOptions-3.0.lua 1066 2012-09-18 14:36:49Z nevcairiel $ |
local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 14 |
local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR) |
if not AceDBOptions then return end -- No upgrade needed |
-- Lua APIs |
local pairs, next = pairs, next |
-- WoW APIs |
local UnitClass = UnitClass |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: NORMAL_FONT_COLOR_CODE, FONT_COLOR_CODE_CLOSE |
AceDBOptions.optionTables = AceDBOptions.optionTables or {} |
AceDBOptions.handlers = AceDBOptions.handlers or {} |
--[[ |
Localization of AceDBOptions-3.0 |
]] |
local L = { |
choose = "Existing Profiles", |
choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already existing profiles.", |
choose_sub = "Select one of your currently available profiles.", |
copy = "Copy From", |
copy_desc = "Copy the settings from one existing profile into the currently active profile.", |
current = "Current Profile:", |
default = "Default", |
delete = "Delete a Profile", |
delete_confirm = "Are you sure you want to delete the selected profile?", |
delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.", |
delete_sub = "Deletes a profile from the database.", |
intro = "You can change the active database profile, so you can have different settings for every character.", |
new = "New", |
new_sub = "Create a new empty profile.", |
profiles = "Profiles", |
profiles_sub = "Manage Profiles", |
reset = "Reset Profile", |
reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.", |
reset_sub = "Reset the current profile to the default", |
} |
local LOCALE = GetLocale() |
if LOCALE == "deDE" then |
L["choose"] = "Vorhandene Profile" |
L["choose_desc"] = "Du kannst ein neues Profil erstellen, indem du einen neuen Namen in der Eingabebox 'Neu' eingibst, oder wähle eines der vorhandenen Profile aus." |
L["choose_sub"] = "Wählt ein bereits vorhandenes Profil aus." |
L["copy"] = "Kopieren von..." |
L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil." |
-- L["current"] = "Current Profile:" |
L["default"] = "Standard" |
L["delete"] = "Profil löschen" |
L["delete_confirm"] = "Willst du das ausgewählte Profil wirklich löschen?" |
L["delete_desc"] = "Lösche vorhandene oder unbenutzte Profile aus der Datenbank um Platz zu sparen und um die SavedVariables Datei 'sauber' zu halten." |
L["delete_sub"] = "Löscht ein Profil aus der Datenbank." |
L["intro"] = "Hier kannst du das aktive Datenbankprofile ändern, damit du verschiedene Einstellungen für jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration möglich wird." |
L["new"] = "Neu" |
L["new_sub"] = "Ein neues Profil erstellen." |
L["profiles"] = "Profile" |
L["profiles_sub"] = "Profile verwalten" |
L["reset"] = "Profil zurücksetzen" |
L["reset_desc"] = "Setzt das momentane Profil auf Standardwerte zurück, für den Fall das mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst." |
L["reset_sub"] = "Das aktuelle Profil auf Standard zurücksetzen." |
elseif LOCALE == "frFR" then |
L["choose"] = "Profils existants" |
L["choose_desc"] = "Vous pouvez créer un nouveau profil en entrant un nouveau nom dans la boîte de saisie, ou en choississant un des profils déjà existants." |
L["choose_sub"] = "Permet de choisir un des profils déjà disponibles." |
L["copy"] = "Copier à partir de" |
L["copy_desc"] = "Copie les paramètres d'un profil déjà existant dans le profil actuellement actif." |
-- L["current"] = "Current Profile:" |
L["default"] = "Défaut" |
L["delete"] = "Supprimer un profil" |
L["delete_confirm"] = "Etes-vous sûr de vouloir supprimer le profil sélectionné ?" |
L["delete_desc"] = "Supprime les profils existants inutilisés de la base de données afin de gagner de la place et de nettoyer le fichier SavedVariables." |
L["delete_sub"] = "Supprime un profil de la base de données." |
L["intro"] = "Vous pouvez changer le profil actuel afin d'avoir des paramètres différents pour chaque personnage, permettant ainsi d'avoir une configuration très flexible." |
L["new"] = "Nouveau" |
L["new_sub"] = "Créée un nouveau profil vierge." |
L["profiles"] = "Profils" |
L["profiles_sub"] = "Gestion des profils" |
L["reset"] = "Réinitialiser le profil" |
L["reset_desc"] = "Réinitialise le profil actuel au cas où votre configuration est corrompue ou si vous voulez tout simplement faire table rase." |
L["reset_sub"] = "Réinitialise le profil actuel avec les paramètres par défaut." |
elseif LOCALE == "koKR" then |
L["choose"] = "íë¡í ì í" |
L["choose_desc"] = "ìë¡ì´ ì´ë¦ì ì ë ¥íê±°ë, ì´ë¯¸ ìë íë¡íì¤ íë를 ì ííì¬ ìë¡ì´ íë¡íì ë§ë¤ ì ììµëë¤." |
L["choose_sub"] = "ë¹ì ì´ íì¬ ì´ì©í ì ìë íë¡íì ì íí©ëë¤." |
L["copy"] = "ë³µì¬" |
L["copy_desc"] = "íì¬ ì¬ì©ì¤ì¸ íë¡íì, ì íí íë¡íì ì¤ì ì ë³µì¬í©ëë¤." |
-- L["current"] = "Current Profile:" |
L["default"] = "기본ê°" |
L["delete"] = "íë¡í ìì " |
L["delete_confirm"] = "ì ë§ë¡ ì íí íë¡íì ìì 를 ìíìëê¹?" |
L["delete_desc"] = "ë°ì´í°ë² ì´ì¤ì ì¬ì©ì¤ì´ê±°ë ì ì¥ë íë¡íì¼ ìì ë¡ SavedVariables íì¼ì ì 리ì ê³µê° ì ì½ì´ ë©ëë¤." |
L["delete_sub"] = "ë°ì´í°ë² ì´ì¤ì íë¡íì ìì í©ëë¤." |
L["intro"] = "모ë ìºë¦í°ì ë¤ìí ì¤ì ê³¼ ì¬ì©ì¤ì¸ ë°ì´í°ë² ì´ì¤ íë¡í, ì´ëê²ì´ëì§ ë§¤ì° ë¤ë£¨ê¸° ì½ê² ë°ê¿ì ììµëë¤." |
L["new"] = "ìë¡ì´ íë¡í" |
L["new_sub"] = "ìë¡ì´ íë¡íì ë§ëëë¤." |
L["profiles"] = "íë¡í" |
L["profiles_sub"] = "íë¡í ì¤ì " |
L["reset"] = "íë¡í ì´ê¸°í" |
L["reset_desc"] = "ë¨ìí ë¤ì ìë¡ê² 구ì±ì ìíë ê²½ì°, íì¬ íë¡íì 기본ê°ì¼ë¡ ì´ê¸°í í©ëë¤." |
L["reset_sub"] = "íì¬ì íë¡íì 기본ê°ì¼ë¡ ì´ê¸°í í©ëë¤" |
elseif LOCALE == "esES" or LOCALE == "esMX" then |
L["choose"] = "Perfiles existentes" |
L["choose_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes." |
L["choose_sub"] = "Selecciona uno de los perfiles disponibles." |
L["copy"] = "Copiar de" |
L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual." |
-- L["current"] = "Current Profile:" |
L["default"] = "Por defecto" |
L["delete"] = "Borrar un Perfil" |
L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?" |
L["delete_desc"] = "Borra los perfiles existentes y sin uso de la base de datos para ganar espacio y limpiar el archivo SavedVariables." |
L["delete_sub"] = "Borra un perfil de la base de datos." |
L["intro"] = "Puedes cambiar el perfil activo de tal manera que cada personaje tenga diferentes configuraciones." |
L["new"] = "Nuevo" |
L["new_sub"] = "Crear un nuevo perfil vacio." |
L["profiles"] = "Perfiles" |
L["profiles_sub"] = "Manejar Perfiles" |
L["reset"] = "Reiniciar Perfil" |
L["reset_desc"] = "Reinicia el perfil actual a los valores por defectos, en caso de que se haya estropeado la configuración o quieras volver a empezar de nuevo." |
L["reset_sub"] = "Reinicar el perfil actual al de por defecto" |
elseif LOCALE == "zhTW" then |
L["choose"] = "ç¾æçè¨å®æª" |
L["choose_desc"] = "ä½ å¯ä»¥ééå¨ææ¬æ¡å §è¼¸å ¥ä¸ååååµç«ä¸åæ°çè¨å®æªï¼ä¹å¯ä»¥é¸æä¸åå·²ç¶åå¨çè¨å®æªã" |
L["choose_sub"] = "å¾ç¶åå¯ç¨çè¨å®æªè£é¢é¸æä¸åã" |
L["copy"] = "è¤è£½èª" |
L["copy_desc"] = "å¾ç¶åæåå·²ä¿åçè¨å®æªè¤è£½å°ç¶åæ£ä½¿ç¨çè¨å®æªã" |
-- L["current"] = "Current Profile:" |
L["default"] = "é è¨" |
L["delete"] = "åªé¤ä¸åè¨å®æª" |
L["delete_confirm"] = "ä½ ç¢ºå®è¦åªé¤æé¸æçè¨å®æªåï¼" |
L["delete_desc"] = "å¾è³æ庫è£åªé¤ä¸å使ç¨çè¨å®æªï¼ä»¥ç¯ç空éï¼ä¸¦ä¸æ¸ çSavedVariablesæªã" |
L["delete_sub"] = "å¾è³æ庫è£åªé¤ä¸åè¨å®æªã" |
L["intro"] = "ä½ å¯ä»¥é¸æä¸åæ´»åçè³æè¨å®æªï¼éæ¨£ä½ çæ¯åè§è²å°±å¯ä»¥ææä¸åçè¨å®å¼ï¼å¯ä»¥çµ¦ä½ çæ件è¨å®å¸¶ä¾æ¥µå¤§çéæ´»æ§ã" |
L["new"] = "æ°å»º" |
L["new_sub"] = "æ°å»ºä¸å空çè¨å®æªã" |
L["profiles"] = "è¨å®æª" |
L["profiles_sub"] = "管çè¨å®æª" |
L["reset"] = "éç½®è¨å®æª" |
L["reset_desc"] = "å°ç¶åçè¨å®æªæ¢å¾©å°å®çé è¨å¼ï¼ç¨æ¼ä½ çè¨å®æªæå£ï¼æè ä½ åªæ¯æ³éä¾çæ æ³ã" |
L["reset_sub"] = "å°ç¶åçè¨å®æªæ¢å¾©çºé è¨å¼" |
elseif LOCALE == "zhCN" then |
L["choose"] = "ç°æçé ç½®æ件" |
L["choose_desc"] = "ä½ å¯ä»¥éè¿å¨ææ¬æ¡å è¾å ¥ä¸ä¸ªåååç«ä¸ä¸ªæ°çé ç½®æ件ï¼ä¹å¯ä»¥éæ©ä¸ä¸ªå·²ç»åå¨çé ç½®æ件ã" |
L["choose_sub"] = "ä»å½åå¯ç¨çé ç½®æ件éé¢éæ©ä¸ä¸ªã" |
L["copy"] = "å¤å¶èª" |
L["copy_desc"] = "ä»å½åæ个已ä¿åçé ç½®æ件å¤å¶å°å½åæ£ä½¿ç¨çé ç½®æ件ã" |
-- L["current"] = "Current Profile:" |
L["default"] = "é»è®¤" |
L["delete"] = "å é¤ä¸ä¸ªé ç½®æ件" |
L["delete_confirm"] = "ä½ ç¡®å®è¦å é¤æéæ©çé ç½®æ件ä¹ï¼" |
L["delete_desc"] = "ä»æ°æ®åºéå é¤ä¸å使ç¨çé ç½®æ件ï¼ä»¥èç空é´ï¼å¹¶ä¸æ¸ çSavedVariablesæ件ã" |
L["delete_sub"] = "ä»æ°æ®åºéå é¤ä¸ä¸ªé ç½®æ件ã" |
L["intro"] = "ä½ å¯ä»¥éæ©ä¸ä¸ªæ´»å¨çæ°æ®é ç½®æ件ï¼è¿æ ·ä½ çæ¯ä¸ªè§è²å°±å¯ä»¥æ¥æä¸åç设置å¼ï¼å¯ä»¥ç»ä½ çæ件é 置带æ¥æ大ççµæ´»æ§ã" |
L["new"] = "æ°å»º" |
L["new_sub"] = "æ°å»ºä¸ä¸ªç©ºçé ç½®æ件ã" |
L["profiles"] = "é ç½®æ件" |
L["profiles_sub"] = "管çé ç½®æ件" |
L["reset"] = "éç½®é ç½®æ件" |
L["reset_desc"] = "å°å½åçé ç½®æ件æ¢å¤å°å®çé»è®¤å¼ï¼ç¨äºä½ çé ç½®æ件æåï¼æè ä½ åªæ¯æ³éæ¥çæ åµã" |
L["reset_sub"] = "å°å½åçé ç½®æ件æ¢å¤ä¸ºé»è®¤å¼" |
elseif LOCALE == "ruRU" then |
L["choose"] = "СÑÑеÑÑвÑÑÑие пÑоÑили" |
L["choose_desc"] = "ÐÑ Ð¼Ð¾Ð¶ÐµÑе ÑоздаÑÑ Ð½Ð¾Ð²Ñй пÑоÑилÑ, Ð²Ð²ÐµÐ´Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ в поле ввода, или вÑбÑаÑÑ Ð¾Ð´Ð¸Ð½ из Ñже ÑÑÑеÑÑвÑÑÑÐ¸Ñ Ð¿ÑоÑилей." |
L["choose_sub"] = "ÐÑÐ±Ð¾Ñ Ð¾Ð´Ð¸Ð½Ð¾Ð³Ð¾ из Ñже доÑÑÑпнÑÑ Ð¿ÑоÑилей" |
L["copy"] = "СкопиÑоваÑÑ Ð¸Ð·" |
L["copy_desc"] = "СкопиÑоваÑÑ Ð½Ð°ÑÑÑойки из вÑбÑанного пÑоÑÐ¸Ð»Ñ Ð² акÑивнÑй." |
-- L["current"] = "Current Profile:" |
L["default"] = "Ðо ÑмолÑаниÑ" |
L["delete"] = "УдалиÑÑ Ð¿ÑоÑилÑ" |
L["delete_confirm"] = "ÐÑ ÑвеÑенÑ, ÑÑо Ð²Ñ Ñ Ð¾ÑиÑе ÑдалиÑÑ Ð²ÑбÑаннÑй пÑоÑилÑ?" |
L["delete_desc"] = "УдалиÑÑ ÑÑÑеÑÑвÑÑÑий и неиÑполÑзÑемÑй пÑоÑÐ¸Ð»Ñ Ð¸Ð· ÐÐ Ð´Ð»Ñ ÑÐ¾Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð¼ÐµÑÑа, и оÑиÑÑиÑÑ SavedVariables Ñайл." |
L["delete_sub"] = "Удаление пÑоÑÐ¸Ð»Ñ Ð¸Ð· ÐÐ" |
L["intro"] = "ÐзменÑÑ Ð°ÐºÑивнÑй пÑоÑилÑ, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе задаÑÑ ÑазлиÑнÑе наÑÑÑойки модиÑикаÑий Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пеÑÑонажа." |
L["new"] = "ÐовÑй" |
L["new_sub"] = "СоздаÑÑ Ð½Ð¾Ð²Ñй ÑиÑÑÑй пÑоÑилÑ" |
L["profiles"] = "ÐÑоÑили" |
L["profiles_sub"] = "УпÑавление пÑоÑилÑми" |
L["reset"] = "СбÑÐ¾Ñ Ð¿ÑоÑилÑ" |
L["reset_desc"] = "ÐÑли ваÑа конÑигÑÑаÑии иÑпоÑÑена или еÑли Ð²Ñ Ñ Ð¾ÑиÑе наÑÑÑоиÑÑ Ð²ÑÑ Ð·Ð°Ð½Ð¾Ð²Ð¾ - ÑбÑоÑÑÑе ÑекÑÑий пÑоÑÐ¸Ð»Ñ Ð½Ð° ÑÑандаÑÑнÑе знаÑениÑ." |
L["reset_sub"] = "СбÑÐ¾Ñ ÑекÑÑего пÑоÑÐ¸Ð»Ñ Ð½Ð° ÑÑандаÑÑнÑй" |
elseif LOCALE == "itIT" then |
L["choose"] = "Profili esistenti" |
L["choose_desc"] = "Puoi creare un nuovo profilo digitando il nome della casella di testo, oppure scegliendone uno tra i profili gia' esistenti." |
L["choose_sub"] = "Seleziona uno dei profili disponibili." |
L["copy"] = "Copia Da" |
L["copy_desc"] = "Copia le impostazioni da un profilo esistente, nel profilo attivo in questo momento." |
L["current"] = "Profilo Attivo:" |
L["default"] = "Standard" |
L["delete"] = "Cancella un profilo" |
L["delete_confirm"] = "Sei sicuro di voler cancellare il profilo selezionato?" |
L["delete_desc"] = "Cancella i profili non utilizzati dal database per risparmiare spazio e mantenere puliti i file di configurazione SavedVariables." |
L["delete_sub"] = "Cancella un profilo dal Database." |
L["intro"] = "Puoi cambiare il profilo attivo, in modo da usare impostazioni diverse per ogni personaggio." |
L["new"] = "Nuovo" |
L["new_sub"] = "Crea un nuovo profilo vuoto." |
L["profiles"] = "Profili" |
L["profiles_sub"] = "Gestisci Profili" |
L["reset"] = "Reimposta Profilo" |
L["reset_desc"] = "Riporta il tuo profilo attivo alle sue impostazioni di default, nel caso in cui la tua configurazione si sia corrotta, o semplicemente tu voglia re-inizializzarla." |
L["reset_sub"] = "Reimposta il profilo ai suoi valori di default." |
end |
local defaultProfiles |
local tmpprofiles = {} |
-- Get a list of available profiles for the specified database. |
-- You can specify which profiles to include/exclude in the list using the two boolean parameters listed below. |
-- @param db The db object to retrieve the profiles from |
-- @param common If true, getProfileList will add the default profiles to the return list, even if they have not been created yet |
-- @param nocurrent If true, then getProfileList will not display the current profile in the list |
-- @return Hashtable of all profiles with the internal name as keys and the display name as value. |
local function getProfileList(db, common, nocurrent) |
local profiles = {} |
-- copy existing profiles into the table |
local currentProfile = db:GetCurrentProfile() |
for i,v in pairs(db:GetProfiles(tmpprofiles)) do |
if not (nocurrent and v == currentProfile) then |
profiles[v] = v |
end |
end |
-- add our default profiles to choose from ( or rename existing profiles) |
for k,v in pairs(defaultProfiles) do |
if (common or profiles[k]) and not (nocurrent and k == currentProfile) then |
profiles[k] = v |
end |
end |
return profiles |
end |
--[[ |
OptionsHandlerPrototype |
prototype class for handling the options in a sane way |
]] |
local OptionsHandlerPrototype = {} |
--[[ Reset the profile ]] |
function OptionsHandlerPrototype:Reset() |
self.db:ResetProfile() |
end |
--[[ Set the profile to value ]] |
function OptionsHandlerPrototype:SetProfile(info, value) |
self.db:SetProfile(value) |
end |
--[[ returns the currently active profile ]] |
function OptionsHandlerPrototype:GetCurrentProfile() |
return self.db:GetCurrentProfile() |
end |
--[[ |
List all active profiles |
you can control the output with the .arg variable |
currently four modes are supported |
(empty) - return all available profiles |
"nocurrent" - returns all available profiles except the currently active profile |
"common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default") |
"both" - common except the active profile |
]] |
function OptionsHandlerPrototype:ListProfiles(info) |
local arg = info.arg |
local profiles |
if arg == "common" and not self.noDefaultProfiles then |
profiles = getProfileList(self.db, true, nil) |
elseif arg == "nocurrent" then |
profiles = getProfileList(self.db, nil, true) |
elseif arg == "both" then -- currently not used |
profiles = getProfileList(self.db, (not self.noDefaultProfiles) and true, true) |
else |
profiles = getProfileList(self.db) |
end |
return profiles |
end |
function OptionsHandlerPrototype:HasNoProfiles(info) |
local profiles = self:ListProfiles(info) |
return ((not next(profiles)) and true or false) |
end |
--[[ Copy a profile ]] |
function OptionsHandlerPrototype:CopyProfile(info, value) |
self.db:CopyProfile(value) |
end |
--[[ Delete a profile from the db ]] |
function OptionsHandlerPrototype:DeleteProfile(info, value) |
self.db:DeleteProfile(value) |
end |
--[[ fill defaultProfiles with some generic values ]] |
local function generateDefaultProfiles(db) |
defaultProfiles = { |
["Default"] = L["default"], |
[db.keys.char] = db.keys.char, |
[db.keys.realm] = db.keys.realm, |
[db.keys.class] = UnitClass("player") |
} |
end |
--[[ create and return a handler object for the db, or upgrade it if it already existed ]] |
local function getOptionsHandler(db, noDefaultProfiles) |
if not defaultProfiles then |
generateDefaultProfiles(db) |
end |
local handler = AceDBOptions.handlers[db] or { db = db, noDefaultProfiles = noDefaultProfiles } |
for k,v in pairs(OptionsHandlerPrototype) do |
handler[k] = v |
end |
AceDBOptions.handlers[db] = handler |
return handler |
end |
--[[ |
the real options table |
]] |
local optionsTable = { |
desc = { |
order = 1, |
type = "description", |
name = L["intro"] .. "\n", |
}, |
descreset = { |
order = 9, |
type = "description", |
name = L["reset_desc"], |
}, |
reset = { |
order = 10, |
type = "execute", |
name = L["reset"], |
desc = L["reset_sub"], |
func = "Reset", |
}, |
current = { |
order = 11, |
type = "description", |
name = function(info) return L["current"] .. " " .. NORMAL_FONT_COLOR_CODE .. info.handler:GetCurrentProfile() .. FONT_COLOR_CODE_CLOSE end, |
width = "default", |
}, |
choosedesc = { |
order = 20, |
type = "description", |
name = "\n" .. L["choose_desc"], |
}, |
new = { |
name = L["new"], |
desc = L["new_sub"], |
type = "input", |
order = 30, |
get = false, |
set = "SetProfile", |
}, |
choose = { |
name = L["choose"], |
desc = L["choose_sub"], |
type = "select", |
order = 40, |
get = "GetCurrentProfile", |
set = "SetProfile", |
values = "ListProfiles", |
arg = "common", |
}, |
copydesc = { |
order = 50, |
type = "description", |
name = "\n" .. L["copy_desc"], |
}, |
copyfrom = { |
order = 60, |
type = "select", |
name = L["copy"], |
desc = L["copy_desc"], |
get = false, |
set = "CopyProfile", |
values = "ListProfiles", |
disabled = "HasNoProfiles", |
arg = "nocurrent", |
}, |
deldesc = { |
order = 70, |
type = "description", |
name = "\n" .. L["delete_desc"], |
}, |
delete = { |
order = 80, |
type = "select", |
name = L["delete"], |
desc = L["delete_sub"], |
get = false, |
set = "DeleteProfile", |
values = "ListProfiles", |
disabled = "HasNoProfiles", |
arg = "nocurrent", |
confirm = true, |
confirmText = L["delete_confirm"], |
}, |
} |
--- Get/Create a option table that you can use in your addon to control the profiles of AceDB-3.0. |
-- @param db The database object to create the options table for. |
-- @return The options table to be used in AceConfig-3.0 |
-- @usage |
-- -- Assuming `options` is your top-level options table and `self.db` is your database: |
-- options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) |
function AceDBOptions:GetOptionsTable(db, noDefaultProfiles) |
local tbl = AceDBOptions.optionTables[db] or { |
type = "group", |
name = L["profiles"], |
desc = L["profiles_sub"], |
} |
tbl.handler = getOptionsHandler(db, noDefaultProfiles) |
tbl.args = optionsTable |
AceDBOptions.optionTables[db] = tbl |
return tbl |
end |
-- upgrade existing tables |
for db,tbl in pairs(AceDBOptions.optionTables) do |
tbl.handler = getOptionsHandler(db) |
tbl.args = optionsTable |
end |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="AceEvent-3.0.lua"/> |
</Ui> |
--- AceEvent-3.0 provides event registration and secure dispatching. |
-- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around |
-- CallbackHandler, and dispatches all game events or addon message to the registrees. |
-- |
-- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by |
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object |
-- and can be accessed directly, without having to explicitly call AceEvent itself.\\ |
-- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you |
-- make into AceEvent. |
-- @class file |
-- @name AceEvent-3.0 |
-- @release $Id: AceEvent-3.0.lua 975 2010-10-23 11:26:18Z nevcairiel $ |
local MAJOR, MINOR = "AceEvent-3.0", 3 |
local AceEvent = LibStub:NewLibrary(MAJOR, MINOR) |
if not AceEvent then return end |
-- Lua APIs |
local pairs = pairs |
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0") |
AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame |
AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib |
-- APIs and registry for blizzard events, using CallbackHandler lib |
if not AceEvent.events then |
AceEvent.events = CallbackHandler:New(AceEvent, |
"RegisterEvent", "UnregisterEvent", "UnregisterAllEvents") |
end |
function AceEvent.events:OnUsed(target, eventname) |
AceEvent.frame:RegisterEvent(eventname) |
end |
function AceEvent.events:OnUnused(target, eventname) |
AceEvent.frame:UnregisterEvent(eventname) |
end |
-- APIs and registry for IPC messages, using CallbackHandler lib |
if not AceEvent.messages then |
AceEvent.messages = CallbackHandler:New(AceEvent, |
"RegisterMessage", "UnregisterMessage", "UnregisterAllMessages" |
) |
AceEvent.SendMessage = AceEvent.messages.Fire |
end |
--- embedding and embed handling |
local mixins = { |
"RegisterEvent", "UnregisterEvent", |
"RegisterMessage", "UnregisterMessage", |
"SendMessage", |
"UnregisterAllEvents", "UnregisterAllMessages", |
} |
--- Register for a Blizzard Event. |
-- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied) |
-- Any arguments to the event will be passed on after that. |
-- @name AceEvent:RegisterEvent |
-- @class function |
-- @paramsig event[, callback [, arg]] |
-- @param event The event to register for |
-- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name) |
-- @param arg An optional argument to pass to the callback function |
--- Unregister an event. |
-- @name AceEvent:UnregisterEvent |
-- @class function |
-- @paramsig event |
-- @param event The event to unregister |
--- Register for a custom AceEvent-internal message. |
-- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied) |
-- Any arguments to the event will be passed on after that. |
-- @name AceEvent:RegisterMessage |
-- @class function |
-- @paramsig message[, callback [, arg]] |
-- @param message The message to register for |
-- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name) |
-- @param arg An optional argument to pass to the callback function |
--- Unregister a message |
-- @name AceEvent:UnregisterMessage |
-- @class function |
-- @paramsig message |
-- @param message The message to unregister |
--- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message. |
-- @name AceEvent:SendMessage |
-- @class function |
-- @paramsig message, ... |
-- @param message The message to send |
-- @param ... Any arguments to the message |
-- Embeds AceEvent into the target object making the functions from the mixins list available on target:.. |
-- @param target target object to embed AceEvent in |
function AceEvent:Embed(target) |
for k, v in pairs(mixins) do |
target[v] = self[v] |
end |
self.embeds[target] = true |
return target |
end |
-- AceEvent:OnEmbedDisable( target ) |
-- target (object) - target object that is being disabled |
-- |
-- Unregister all events messages etc when the target disables. |
-- this method should be called by the target manually or by an addon framework |
function AceEvent:OnEmbedDisable(target) |
target:UnregisterAllEvents() |
target:UnregisterAllMessages() |
end |
-- Script to fire blizzard events into the event listeners |
local events = AceEvent.events |
AceEvent.frame:SetScript("OnEvent", function(this, event, ...) |
events:Fire(event, ...) |
end) |
--- Finally: upgrade our old embeds |
for target, v in pairs(AceEvent.embeds) do |
AceEvent:Embed(target) |
end |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="AceConsole-3.0.lua"/> |
</Ui> |
--- **AceConsole-3.0** provides registration facilities for slash commands. |
-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them |
-- to your addons individual needs. |
-- |
-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by |
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object |
-- and can be accessed directly, without having to explicitly call AceConsole itself.\\ |
-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you |
-- make into AceConsole. |
-- @class file |
-- @name AceConsole-3.0 |
-- @release $Id: AceConsole-3.0.lua 878 2009-11-02 18:51:58Z nevcairiel $ |
local MAJOR,MINOR = "AceConsole-3.0", 7 |
local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR) |
if not AceConsole then return end -- No upgrade needed |
AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in. |
AceConsole.commands = AceConsole.commands or {} -- table containing commands registered |
AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable |
-- Lua APIs |
local tconcat, tostring, select = table.concat, tostring, select |
local type, pairs, error = type, pairs, error |
local format, strfind, strsub = string.format, string.find, string.sub |
local max = math.max |
-- WoW APIs |
local _G = _G |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList |
local tmp={} |
local function Print(self,frame,...) |
local n=0 |
if self ~= AceConsole then |
n=n+1 |
tmp[n] = "|cff33ff99"..tostring( self ).."|r:" |
end |
for i=1, select("#", ...) do |
n=n+1 |
tmp[n] = tostring(select(i, ...)) |
end |
frame:AddMessage( tconcat(tmp," ",1,n) ) |
end |
--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function) |
-- @paramsig [chatframe ,] ... |
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function) |
-- @param ... List of any values to be printed |
function AceConsole:Print(...) |
local frame = ... |
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member? |
return Print(self, frame, select(2,...)) |
else |
return Print(self, DEFAULT_CHAT_FRAME, ...) |
end |
end |
--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function) |
-- @paramsig [chatframe ,] "format"[, ...] |
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function) |
-- @param format Format string - same syntax as standard Lua format() |
-- @param ... Arguments to the format string |
function AceConsole:Printf(...) |
local frame = ... |
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member? |
return Print(self, frame, format(select(2,...))) |
else |
return Print(self, DEFAULT_CHAT_FRAME, format(...)) |
end |
end |
--- Register a simple chat command |
-- @param command Chat command to be registered WITHOUT leading "/" |
-- @param func Function to call when the slash command is being used (funcref or methodname) |
-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true) |
function AceConsole:RegisterChatCommand( command, func, persist ) |
if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end |
if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk |
local name = "ACECONSOLE_"..command:upper() |
if type( func ) == "string" then |
SlashCmdList[name] = function(input, editBox) |
self[func](self, input, editBox) |
end |
else |
SlashCmdList[name] = func |
end |
_G["SLASH_"..name.."1"] = "/"..command:lower() |
AceConsole.commands[command] = name |
-- non-persisting commands are registered for enabling disabling |
if not persist then |
if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end |
AceConsole.weakcommands[self][command] = func |
end |
return true |
end |
--- Unregister a chatcommand |
-- @param command Chat command to be unregistered WITHOUT leading "/" |
function AceConsole:UnregisterChatCommand( command ) |
local name = AceConsole.commands[command] |
if name then |
SlashCmdList[name] = nil |
_G["SLASH_" .. name .. "1"] = nil |
hash_SlashCmdList["/" .. command:upper()] = nil |
AceConsole.commands[command] = nil |
end |
end |
--- Get an iterator over all Chat Commands registered with AceConsole |
-- @return Iterator (pairs) over all commands |
function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end |
local function nils(n, ...) |
if n>1 then |
return nil, nils(n-1, ...) |
elseif n==1 then |
return nil, ... |
else |
return ... |
end |
end |
--- Retreive one or more space-separated arguments from a string. |
-- Treats quoted strings and itemlinks as non-spaced. |
-- @param string The raw argument string |
-- @param numargs How many arguments to get (default 1) |
-- @param startpos Where in the string to start scanning (default 1) |
-- @return Returns arg1, arg2, ..., nextposition\\ |
-- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string. |
function AceConsole:GetArgs(str, numargs, startpos) |
numargs = numargs or 1 |
startpos = max(startpos or 1, 1) |
local pos=startpos |
-- find start of new arg |
pos = strfind(str, "[^ ]", pos) |
if not pos then -- whoops, end of string |
return nils(numargs, 1e9) |
end |
if numargs<1 then |
return pos |
end |
-- quoted or space separated? find out which pattern to use |
local delim_or_pipe |
local ch = strsub(str, pos, pos) |
if ch=='"' then |
pos = pos + 1 |
delim_or_pipe='([|"])' |
elseif ch=="'" then |
pos = pos + 1 |
delim_or_pipe="([|'])" |
else |
delim_or_pipe="([| ])" |
end |
startpos = pos |
while true do |
-- find delimiter or hyperlink |
local ch,_ |
pos,_,ch = strfind(str, delim_or_pipe, pos) |
if not pos then break end |
if ch=="|" then |
-- some kind of escape |
if strsub(str,pos,pos+1)=="|H" then |
-- It's a |H....|hhyper link!|h |
pos=strfind(str, "|h", pos+2) -- first |h |
if not pos then break end |
pos=strfind(str, "|h", pos+2) -- second |h |
if not pos then break end |
elseif strsub(str,pos, pos+1) == "|T" then |
-- It's a |T....|t texture |
pos=strfind(str, "|t", pos+2) |
if not pos then break end |
end |
pos=pos+2 -- skip past this escape (last |h if it was a hyperlink) |
else |
-- found delimiter, done with this arg |
return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1) |
end |
end |
-- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink) |
return strsub(str, startpos), nils(numargs-1, 1e9) |
end |
--- embedding and embed handling |
local mixins = { |
"Print", |
"Printf", |
"RegisterChatCommand", |
"UnregisterChatCommand", |
"GetArgs", |
} |
-- Embeds AceConsole into the target object making the functions from the mixins list available on target:.. |
-- @param target target object to embed AceBucket in |
function AceConsole:Embed( target ) |
for k, v in pairs( mixins ) do |
target[v] = self[v] |
end |
self.embeds[target] = true |
return target |
end |
function AceConsole:OnEmbedEnable( target ) |
if AceConsole.weakcommands[target] then |
for command, func in pairs( AceConsole.weakcommands[target] ) do |
target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry |
end |
end |
end |
function AceConsole:OnEmbedDisable( target ) |
if AceConsole.weakcommands[target] then |
for command, func in pairs( AceConsole.weakcommands[target] ) do |
target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care? |
end |
end |
end |
for addon in pairs(AceConsole.embeds) do |
AceConsole:Embed(addon) |
end |
local parent, ns = ... |
local oUF = ns.oUF |
local hiddenParent = CreateFrame("Frame") |
hiddenParent:Hide() |
local HandleFrame = function(baseName) |
local frame |
if(type(baseName) == 'string') then |
frame = _G[baseName] |
else |
frame = baseName |
end |
if(frame) then |
frame:UnregisterAllEvents() |
frame:Hide() |
-- Keep frame hidden without causing taint |
frame:SetParent(hiddenParent) |
local health = frame.healthbar |
if(health) then |
health:UnregisterAllEvents() |
end |
local power = frame.manabar |
if(power) then |
power:UnregisterAllEvents() |
end |
local spell = frame.spellbar |
if(spell) then |
spell:UnregisterAllEvents() |
end |
local altpowerbar = frame.powerBarAlt |
if(altpowerbar) then |
altpowerbar:UnregisterAllEvents() |
end |
end |
end |
function oUF:DisableBlizzard(unit) |
if(not unit) then return end |
if(unit == 'player') then |
HandleFrame(PlayerFrame) |
-- For the damn vehicle support: |
PlayerFrame:RegisterEvent('PLAYER_ENTERING_WORLD') |
PlayerFrame:RegisterEvent('UNIT_ENTERING_VEHICLE') |
PlayerFrame:RegisterEvent('UNIT_ENTERED_VEHICLE') |
PlayerFrame:RegisterEvent('UNIT_EXITING_VEHICLE') |
PlayerFrame:RegisterEvent('UNIT_EXITED_VEHICLE') |
-- User placed frames don't animate |
PlayerFrame:SetUserPlaced(true) |
PlayerFrame:SetDontSavePosition(true) |
elseif(unit == 'pet') then |
HandleFrame(PetFrame) |
elseif(unit == 'target') then |
HandleFrame(TargetFrame) |
HandleFrame(ComboFrame) |
elseif(unit == 'focus') then |
HandleFrame(FocusFrame) |
HandleFrame(TargetofFocusFrame) |
elseif(unit == 'targettarget') then |
HandleFrame(TargetFrameToT) |
elseif(unit:match'(boss)%d?$' == 'boss') then |
local id = unit:match'boss(%d)' |
if(id) then |
HandleFrame('Boss' .. id .. 'TargetFrame') |
else |
for i=1, 4 do |
HandleFrame(('Boss%dTargetFrame'):format(i)) |
end |
end |
elseif(unit:match'(party)%d?$' == 'party') then |
local id = unit:match'party(%d)' |
if(id) then |
HandleFrame('PartyMemberFrame' .. id) |
else |
for i=1, 4 do |
HandleFrame(('PartyMemberFrame%d'):format(i)) |
end |
end |
elseif(unit:match'(arena)%d?$' == 'arena') then |
local id = unit:match'arena(%d)' |
if(id) then |
HandleFrame('ArenaEnemyFrame' .. id) |
else |
for i=1, 4 do |
HandleFrame(('ArenaEnemyFrame%d'):format(i)) |
end |
end |
-- Blizzard_ArenaUI should not be loaded |
Arena_LoadUI = function() end |
SetCVar('showArenaEnemyFrames', '0', 'SHOW_ARENA_ENEMY_FRAMES_TEXT') |
end |
end |
local parent, ns = ... |
local oUF = ns.oUF |
local Private = oUF.Private |
local frame_metatable = Private.frame_metatable |
local colors = { |
smooth = { |
1, 0, 0, |
1, 1, 0, |
0, 1, 0 |
}, |
disconnected = {.6, .6, .6}, |
tapped = {.6,.6,.6}, |
class = {}, |
reaction = {}, |
} |
-- We do this because people edit the vars directly, and changing the default |
-- globals makes SPICE FLOW! |
local customClassColors = function() |
if(CUSTOM_CLASS_COLORS) then |
local updateColors = function() |
for eclass, color in next, CUSTOM_CLASS_COLORS do |
colors.class[eclass] = {color.r, color.g, color.b} |
end |
for _, obj in next, oUF.objects do |
obj:UpdateAllElements("CUSTOM_CLASS_COLORS") |
end |
end |
updateColors() |
CUSTOM_CLASS_COLORS:RegisterCallback(updateColors) |
return true |
end |
end |
if not customClassColors() then |
for eclass, color in next, RAID_CLASS_COLORS do |
colors.class[eclass] = {color.r, color.g, color.b} |
end |
local f = CreateFrame("Frame") |
f:RegisterEvent("ADDON_LOADED") |
f:SetScript("OnEvent", function() |
if customClassColors() then |
f:UnregisterEvent("ADDON_LOADED") |
f:SetScript("OnEvent", nil) |
end |
end) |
end |
for eclass, color in next, FACTION_BAR_COLORS do |
colors.reaction[eclass] = {color.r, color.g, color.b} |
end |
-- http://www.wowwiki.com/ColorGradient |
local ColorGradient = function(a, b, ...) |
local perc |
if(b == 0) then |
perc = 0 |
else |
perc = a / b |
end |
if perc >= 1 then |
local r, g, b = select(select('#', ...) - 2, ...) |
return r, g, b |
elseif perc <= 0 then |
local r, g, b = ... |
return r, g, b |
end |
local num = select('#', ...) / 3 |
local segment, relperc = math.modf(perc*(num-1)) |
local r1, g1, b1, r2, g2, b2 = select((segment*3)+1, ...) |
return r1 + (r2-r1)*relperc, g1 + (g2-g1)*relperc, b1 + (b2-b1)*relperc |
end |
Private.colors = colors |
oUF.colors = colors |
oUF.ColorGradient = ColorGradient |
frame_metatable.__index.colors = colors |
frame_metatable.__index.ColorGradient = ColorGradient |
local parent, ns = ... |
-- It's named Private for a reason! |
ns.oUF.Private = nil |
Copyright (c) 2006-2012 Trond A Ekseth <troeks@gmail.com> |
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, |
copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the |
Software is furnished to do so, subject to the following |
conditions: |
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
OTHER DEALINGS IN THE SOFTWARE. |
local parent, ns = ... |
local oUF = ns.oUF |
local Private = oUF.Private |
local enableTargetUpdate = Private.enableTargetUpdate |
-- Handles unit specific actions. |
function oUF:HandleUnit(object, unit) |
local unit = object.unit or unit |
if(unit == 'target') then |
object:RegisterEvent('PLAYER_TARGET_CHANGED', object.UpdateAllElements) |
elseif(unit == 'mouseover') then |
object:RegisterEvent('UPDATE_MOUSEOVER_UNIT', object.UpdateAllElements) |
elseif(unit == 'focus') then |
object:RegisterEvent('PLAYER_FOCUS_CHANGED', object.UpdateAllElements) |
elseif(unit:match'%w+target') then |
enableTargetUpdate(object) |
end |
end |
local parent, ns = ... |
ns.oUF = {} |
ns.oUF.Private = {} |
local parent, ns = ... |
local oUF = ns.oUF |
local Private = oUF.Private |
local argcheck = Private.argcheck |
local error = Private.error |
local frame_metatable = Private.frame_metatable |
-- Events |
local RegisterEvent, UnregisterEvent, IsEventRegistered |
do |
local eventFrame = CreateFrame("Frame") |
local registry = {} |
local framesForUnit = {} |
local RegisterFrameForUnit = function(frame, unit) |
if not unit then return end |
if framesForUnit[unit] then |
framesForUnit[unit][frame] = true |
else |
framesForUnit[unit] = { [frame] = true } |
end |
end |
local UnregisterFrameForUnit = function(frame, unit) |
if not unit then return end |
local frames = framesForUnit[unit] |
if frames and frames[frame] then |
frames[frame] = nil |
if not next(frames) then |
framesForUnit[unit] = nil |
end |
end |
end |
Private.UpdateUnits = function(frame, unit, realUnit) |
if unit == realUnit then |
realUnit = nil |
end |
if frame.unit ~= unit or frame.realUnit ~= realUnit then |
if not frame:GetScript('OnUpdate') then |
UnregisterFrameForUnit(frame, frame.unit) |
UnregisterFrameForUnit(frame, frame.realUnit) |
RegisterFrameForUnit(frame, unit) |
RegisterFrameForUnit(frame, realUnit) |
end |
frame.unit = unit |
frame.realUnit = realUnit |
frame.id = unit:match'^.-(%d+)' |
return true |
end |
end |
-- Holds true for every event, where the first (unit) argument should be ignored. |
local sharedUnitEvents = { |
UNIT_ENTERED_VEHICLE = true, |
UNIT_EXITED_VEHICLE = true, |
UNIT_PET = true, |
} |
eventFrame:SetScript('OnEvent', function(_, event, arg1, ...) |
local listeners = registry[event] |
if arg1 and not sharedUnitEvents[event] then |
local frames = framesForUnit[arg1] |
if frames then |
for frame in next, frames do |
if listeners[frame] and frame:IsVisible() then |
frame[event](frame, event, arg1, ...) |
end |
end |
end |
else |
for frame in next, listeners do |
if frame:IsVisible() then |
frame[event](frame, event, arg1, ...) |
end |
end |
end |
end) |
function RegisterEvent(self, event, unitless) |
if(unitless) then |
sharedUnitEvents[event] = true |
end |
if not registry[event] then |
registry[event] = { [self] = true } |
eventFrame:RegisterEvent(event) |
else |
registry[event][self] = true |
end |
end |
function UnregisterEvent(self, event) |
if registry[event] then |
registry[event][self] = nil |
if not next(registry[event]) then |
registry[event] = nil |
eventFrame:UnregisterEvent(event) |
end |
end |
end |
function IsEventRegistered(self, event) |
return registry[event] and registry[event][self] |
end |
end |
local event_metatable = { |
__call = function(funcs, self, ...) |
for _, func in next, funcs do |
func(self, ...) |
end |
end, |
} |
function frame_metatable.__index:RegisterEvent(event, func, unitless) |
-- Block OnUpdate polled frames from registering events. |
if(self.__eventless) then return end |
argcheck(event, 2, 'string') |
if(type(func) == 'string' and type(self[func]) == 'function') then |
func = self[func] |
end |
local curev = self[event] |
local kind = type(curev) |
if(curev and func) then |
if(kind == 'function' and curev ~= func) then |
self[event] = setmetatable({curev, func}, event_metatable) |
elseif(kind == 'table') then |
for _, infunc in next, curev do |
if(infunc == func) then return end |
end |
table.insert(curev, func) |
end |
elseif(IsEventRegistered(self, event)) then |
return |
else |
if(type(func) == 'function') then |
self[event] = func |
elseif(not self[event]) then |
return error("Style [%s] attempted to register event [%s] on unit [%s] with a handler that doesn't exist.", self.style, event, self.unit or 'unknown') |
end |
RegisterEvent(self, event, unitless) |
end |
end |
function frame_metatable.__index:UnregisterEvent(event, func) |
argcheck(event, 2, 'string') |
local curev = self[event] |
if(type(curev) == 'table' and func) then |
for k, infunc in next, curev do |
if(infunc == func) then |
table.remove(curev, k) |
local n = #curev |
if(n == 1) then |
local _, handler = next(curev) |
self[event] = handler |
elseif(n == 0) then |
UnregisterEvent(self, event) |
end |
break |
end |
end |
elseif(curev == func) then |
self[event] = nil |
UnregisterEvent(self, event) |
end |
end |
function frame_metatable.__index:IsEventRegistered(event) |
return IsEventRegistered(self, event) |
end |
local parent, ns = ... |
local oUF = ns.oUF |
local Private = oUF.Private |
local argcheck = Private.argcheck |
local _QUEUE = {} |
local _FACTORY = CreateFrame'Frame' |
_FACTORY:SetScript('OnEvent', function(self, event, ...) |
return self[event](self, event, ...) |
end) |
_FACTORY:RegisterEvent'PLAYER_LOGIN' |
_FACTORY.active = true |
function _FACTORY:PLAYER_LOGIN() |
if(not self.active) then return end |
for _, func in next, _QUEUE do |
func(oUF) |
end |
-- Avoid creating dupes. |
wipe(_QUEUE) |
end |
function oUF:Factory(func) |
argcheck(func, 2, 'function') |
-- Call the function directly if we're active and logged in. |
if(IsLoggedIn() and _FACTORY.active) then |
return func(self) |
else |
table.insert(_QUEUE, func) |
end |
end |
function oUF:EnableFactory() |
_FACTORY.active = true |
end |
function oUF:DisableFactory() |
_FACTORY.active = nil |
end |
function oUF:RunFactoryQueue() |
_FACTORY:PLAYER_LOGIN() |
end |
<Ui xmlns="http://www.blizzard.com/wow/ui/"> |
<Script file='init.lua' /> |
<Script file='private.lua' /> |
<Script file='ouf.lua' /> |
<Script file='events.lua'/> |
<Script file='factory.lua' /> |
<Script file='blizzard.lua' /> |
<Script file='units.lua' /> |
<Script file='colors.lua' /> |
<Script file='finalize.lua' /> |
<Script file='elements\power.lua' /> |
<Script file='elements\aura.lua' /> |
<Script file='elements\health.lua' /> |
<Script file='elements\cpoints.lua' /> |
<Script file='elements\ricons.lua' /> |
<Script file='elements\leader.lua' /> |
<Script file='elements\combat.lua' /> |
<Script file='elements\resting.lua' /> |
<Script file='elements\pvp.lua' /> |
<Script file='elements\portraits.lua' /> |
<Script file='elements\range.lua' /> |
<Script file='elements\castbar.lua' /> |
<Script file='elements\threat.lua' /> |
<Script file='elements\tags.lua' /> |
<Script file='elements\masterlooter.lua' /> |
<Script file='elements\assistant.lua' /> |
<Script file='elements\runebar.lua' /> |
<Script file='elements\lfdrole.lua' /> |
<Script file='elements\healprediction.lua' /> |
<Script file='elements\picon.lua' /> |
<Script file='elements\readycheck.lua' /> |
<Script file='elements\qicon.lua' /> |
<Script file='elements\eclipsebar.lua' /> |
<Script file='elements\altpowerbar.lua' /> |
<Script file='elements\totems.lua' /> |
<Script file='elements\resurrect.lua' /> |
<Script file='elements\druidmana.lua' /> |
<Script file='elements\classicons.lua' /> |
<!-- Clique support --> |
<Button name="oUF_ClickCastUnitTemplate" virtual="true" inherits="SecureUnitButtonTemplate,SecureHandlerEnterLeaveTemplate"> |
<Attributes> |
<Attribute name="_onenter" type="string" value="local snippet = self:GetAttribute('clickcast_onenter'); if snippet then self:Run(snippet) end"/> |
<Attribute name="_onleave" type="string" value="local snippet = self:GetAttribute('clickcast_onleave'); if snippet then self:Run(snippet) end"/> |
</Attributes> |
</Button> |
<!-- Pet Battle Hider Frame --> |
<Frame name="oUF_PetBattleFrameHider" inherits="SecureHandlerStateTemplate" parent="UIParent" setAllPoints="true"> |
<Scripts> |
<OnLoad> |
RegisterStateDriver(self, "visibility", "[petbattle] hide; show") |
</OnLoad> |
</Scripts> |
</Frame> |
<!-- |
Sub-object as a child of the parent unit frame: |
<Button name="oUF_HeaderTargetTemplate" inherits="SecureUnitButtonTemplate" hidden="true" virtual="true"> |
<Frames> |
<Button name="$parentTarget" inherits="SecureUnitButtonTemplate"> |
<Attributes> |
<Attribute name="unitsuffix" type="string" value="target"/> |
<Attribute name="useparent-unit" type="boolean" value="true"/> |
</Attributes> |
</Button> |
</Frames> |
</Button> |
Separate unit template example: |
<Button name="oUF_HeaderSeparateSubOjectsTemplate" inherits="SecureUnitButtonTemplate" hidden="true" virtual="true"> |
<Attributes> |
<Attribute name="oUF-onlyProcessChildren" type="boolean" value="true"/> |
</Attributes> |
<Frames> |
<Button name="$parentUnit" inherits="SecureUnitButtonTemplate"> |
<Attributes> |
<Attribute name="useparent-unit" type="boolean" value="true"/> |
</Attributes> |
</Button> |
<Button name="$parentPet" inherits="SecureUnitButtonTemplate"> |
<Attributes> |
<Attribute name="unitsuffix" type="string" value="pet"/> |
<Attribute name="useparent-unit" type="boolean" value="true"/> |
</Attributes> |
</Button> |
<Button name="$parentTarget" inherits="SecureUnitButtonTemplate"> |
<Attributes> |
<Attribute name="unitsuffix" type="string" value="target"/> |
<Attribute name="useparent-unit" type="boolean" value="true"/> |
</Attributes> |
</Button> |
</Frames> |
</Button> |
--> |
</Ui> |
local parent, ns = ... |
local global = GetAddOnMetadata(parent, 'X-oUF') |
local _VERSION = GetAddOnMetadata(parent, 'version') |
local oUF = ns.oUF |
local Private = oUF.Private |
local argcheck = Private.argcheck |
local print = Private.print |
local error = Private.error |
local styles, style = {} |
local callback, objects = {}, {} |
local elements = {} |
local activeElements = {} |
-- updating of "invalid" units. |
local enableTargetUpdate = function(object) |
object.onUpdateFrequency = object.onUpdateFrequency or .5 |
object.__eventless = true |
local total = 0 |
object:SetScript('OnUpdate', function(self, elapsed) |
if(not self.unit) then |
return |
elseif(total > self.onUpdateFrequency) then |
self:UpdateAllElements'OnUpdate' |
total = 0 |
end |
total = total + elapsed |
end) |
end |
Private.enableTargetUpdate = enableTargetUpdate |
local updateActiveUnit = function(self, event, unit) |
-- Calculate units to work with |
local realUnit, modUnit = SecureButton_GetUnit(self), SecureButton_GetModifiedUnit(self) |
-- _GetUnit() doesn't rewrite playerpet -> pet like _GetModifiedUnit does. |
if(realUnit == 'playerpet') then |
realUnit = 'pet' |
elseif(realUnit == 'playertarget') then |
realUnit = 'target' |
end |
if(modUnit == "pet" and realUnit ~= "pet") then |
modUnit = "vehicle" |
end |
-- Drop out if the event unit doesn't match any of the frame units. |
if(not UnitExists(modUnit) or unit and unit ~= realUnit and unit ~= modUnit) then return end |
-- Change the active unit and run a full update. |
if Private.UpdateUnits(self, modUnit, realUnit) then |
self:UpdateAllElements('RefreshUnit') |
return true |
end |
end |
local iterateChildren = function(...) |
for l = 1, select("#", ...) do |
local obj = select(l, ...) |
if(type(obj) == 'table' and obj.isChild) then |
updateActiveUnit(obj, "iterateChildren") |
end |
end |
end |
local OnAttributeChanged = function(self, name, value) |
if(name == "unit" and value) then |
if(self.hasChildren) then |
iterateChildren(self:GetChildren()) |
end |
if(not self:GetAttribute'oUF-onlyProcessChildren') then |
updateActiveUnit(self, "OnAttributeChanged") |
end |
end |
end |
local frame_metatable = { |
__index = CreateFrame"Button" |
} |
Private.frame_metatable = frame_metatable |
for k, v in pairs{ |
EnableElement = function(self, name, unit) |
argcheck(name, 2, 'string') |
argcheck(unit, 3, 'string', 'nil') |
local element = elements[name] |
if(not element or self:IsElementEnabled(name)) then return end |
if(element.enable(self, unit or self.unit)) then |
activeElements[self][name] = true |
if(element.update) then |
table.insert(self.__elements, element.update) |
end |
end |
end, |
DisableElement = function(self, name) |
argcheck(name, 2, 'string') |
local enabled = self:IsElementEnabled(name) |
if(not enabled) then return end |
local update = elements[name].update |
for k, func in next, self.__elements do |
if(func == update) then |
table.remove(self.__elements, k) |
break |
end |
end |
activeElements[self][name] = nil |
-- We need to run a new update cycle in-case we knocked ourself out of sync. |
-- The main reason we do this is to make sure the full update is completed |
-- if an element for some reason removes itself _during_ the update |
-- progress. |
self:UpdateAllElements('DisableElement', name) |
return elements[name].disable(self) |
end, |
IsElementEnabled = function(self, name) |
argcheck(name, 2, 'string') |
local element = elements[name] |
if(not element) then return end |
local active = activeElements[self] |
return active and active[name] |
end, |
Enable = RegisterUnitWatch, |
Disable = function(self) |
UnregisterUnitWatch(self) |
self:Hide() |
end, |
UpdateAllElements = function(self, event) |
local unit = self.unit |
if(not UnitExists(unit)) then return end |
if(self.PreUpdate) then |
self:PreUpdate(event) |
end |
for _, func in next, self.__elements do |
func(self, event, unit) |
end |
if(self.PostUpdate) then |
self:PostUpdate(event) |
end |
end, |
} do |
frame_metatable.__index[k] = v |
end |
local OnShow = function(self) |
if(not updateActiveUnit(self, 'OnShow')) then |
return self:UpdateAllElements'OnShow' |
end |
end |
local UpdatePet = function(self, event, unit) |
local petUnit |
if(unit == 'target') then |
return |
elseif(unit == 'player') then |
petUnit = 'pet' |
else |
-- Convert raid26 -> raidpet26 |
petUnit = unit:gsub('^(%a+)(%d+)', '%1pet%2') |
end |
if(self.unit ~= petUnit) then return end |
if(not updateActiveUnit(self, event)) then |
return self:UpdateAllElements(event) |
end |
end |
local initObject = function(unit, style, styleFunc, header, ...) |
local num = select('#', ...) |
for i=1, num do |
local object = select(i, ...) |
local objectUnit = object:GetAttribute'oUF-guessUnit' or unit |
local suffix = object:GetAttribute'unitsuffix' |
object.__elements = {} |
object.style = style |
object = setmetatable(object, frame_metatable) |
-- Expose the frame through oUF.objects. |
table.insert(objects, object) |
-- We have to force update the frames when PEW fires. |
object:RegisterEvent("PLAYER_ENTERING_WORLD", object.UpdateAllElements) |
-- Handle the case where someone has modified the unitsuffix attribute in |
-- oUF-initialConfigFunction. |
if(suffix and not objectUnit:match(suffix)) then |
objectUnit = objectUnit .. suffix |
end |
if(not (suffix == 'target' or objectUnit and objectUnit:match'target')) then |
object:RegisterEvent('UNIT_ENTERED_VEHICLE', updateActiveUnit) |
object:RegisterEvent('UNIT_EXITED_VEHICLE', updateActiveUnit) |
-- We don't need to register UNIT_PET for the player unit. We register it |
-- mainly because UNIT_EXITED_VEHICLE and UNIT_ENTERED_VEHICLE doesn't always |
-- have pet information when they fire for party and raid units. |
if(objectUnit ~= 'player') then |
object:RegisterEvent('UNIT_PET', UpdatePet) |
end |
end |
if(not header) then |
-- No header means it's a frame created through :Spawn(). |
object:SetAttribute("*type1", "target") |
object:SetAttribute('*type2', 'togglemenu') |
-- No need to enable this for *target frames. |
if(not (unit:match'target' or suffix == 'target')) then |
object:SetAttribute('toggleForVehicle', true) |
end |
-- Other boss and target units are handled by :HandleUnit(). |
if(suffix == 'target') then |
enableTargetUpdate(object) |
else |
oUF:HandleUnit(object) |
end |
else |
-- Used to update frames when they change position in a group. |
object:RegisterEvent('GROUP_ROSTER_UPDATE', object.UpdateAllElements) |
if(num > 1) then |
if(object:GetParent() == header) then |
object.hasChildren = true |
else |
object.isChild = true |
end |
end |
if(suffix == 'target') then |
enableTargetUpdate(object) |
end |
end |
Private.UpdateUnits(object, objectUnit) |
styleFunc(object, objectUnit, not header) |
object:SetScript("OnAttributeChanged", OnAttributeChanged) |
object:SetScript("OnShow", OnShow) |
activeElements[object] = {} |
for element in next, elements do |
object:EnableElement(element, objectUnit) |
end |
for _, func in next, callback do |
func(object) |
end |
-- Make Clique happy |
_G.ClickCastFrames = ClickCastFrames or {} |
ClickCastFrames[object] = true |
end |
end |
local walkObject = function(object, unit) |
local parent = object:GetParent() |
local style = parent.style or style |
local styleFunc = styles[style] |
local header = parent:GetAttribute'oUF-headerType' and parent |
-- Check if we should leave the main frame blank. |
if(object:GetAttribute'oUF-onlyProcessChildren') then |
object.hasChildren = true |
object:SetScript('OnAttributeChanged', OnAttributeChanged) |
return initObject(unit, style, styleFunc, header, object:GetChildren()) |
end |
return initObject(unit, style, styleFunc, header, object, object:GetChildren()) |
end |
function oUF:RegisterInitCallback(func) |
table.insert(callback, func) |
end |
function oUF:RegisterMetaFunction(name, func) |
argcheck(name, 2, 'string') |
argcheck(func, 3, 'function', 'table') |
if(frame_metatable.__index[name]) then |
return |
end |
frame_metatable.__index[name] = func |
end |
function oUF:RegisterStyle(name, func) |
argcheck(name, 2, 'string') |
argcheck(func, 3, 'function', 'table') |
if(styles[name]) then return error("Style [%s] already registered.", name) end |
if(not style) then style = name end |
styles[name] = func |
end |
function oUF:SetActiveStyle(name) |
argcheck(name, 2, 'string') |
if(not styles[name]) then return error("Style [%s] does not exist.", name) end |
style = name |
end |
do |
local function iter(_, n) |
-- don't expose the style functions. |
return (next(styles, n)) |
end |
function oUF.IterateStyles() |
return iter, nil, nil |
end |
end |
local getCondition |
do |
local conditions = { |
raid40 = '[@raid26,exists] show;', |
raid25 = '[@raid11,exists] show;', |
raid10 = '[@raid6,exists] show;', |
raid = '[group:raid] show;', |
party = '[group:party,nogroup:raid] show;', |
solo = '[@player,exists,nogroup:party] show;', |
} |
function getCondition(...) |
local cond = '' |
for i=1, select('#', ...) do |
local short = select(i, ...) |
local condition = conditions[short] |
if(condition) then |
cond = cond .. condition |
end |
end |
return cond .. 'hide' |
end |
end |
local generateName = function(unit, ...) |
local name = 'oUF_' .. style:gsub('[^%a%d_]+', '') |
local raid, party, groupFilter |
for i=1, select('#', ...), 2 do |
local att, val = select(i, ...) |
if(att == 'showRaid') then |
raid = true |
elseif(att == 'showParty') then |
party = true |
elseif(att == 'groupFilter') then |
groupFilter = val |
end |
end |
local append |
if(raid) then |
if(groupFilter) then |
if(type(groupFilter) == 'number' and groupFilter > 0) then |
append = groupFilter |
elseif(groupFilter:match'TANK') then |
append = 'MainTank' |
elseif(groupFilter:match'ASSIST') then |
append = 'MainAssist' |
else |
local _, count = groupFilter:gsub(',', '') |
if(count == 0) then |
append = 'Raid' .. groupFilter |
else |
append = 'Raid' |
end |
end |
else |
append = 'Raid' |
end |
elseif(party) then |
append = 'Party' |
elseif(unit) then |
append = unit:gsub("^%l", string.upper) |
end |
if(append) then |
name = name .. append |
end |
-- Change oUF_LilyRaidRaid into oUF_LilyRaid |
name = name:gsub('(%u%l+)([%u%l]*)%1', '%1') |
-- Change oUF_LilyTargettarget into oUF_LilyTargetTarget |
name = name:gsub('t(arget)', 'T%1') |
local base = name |
local i = 2 |
while(_G[name]) do |
name = base .. i |
i = i + 1 |
end |
return name |
end |
do |
local styleProxy = function(self, frame, ...) |
return walkObject(_G[frame]) |
end |
-- There has to be an easier way to do this. |
local initialConfigFunction = [[ |
local header = self:GetParent() |
local frames = table.new() |
table.insert(frames, self) |
self:GetChildList(frames) |
for i=1, #frames do |
local frame = frames[i] |
local unit |
-- There's no need to do anything on frames with onlyProcessChildren |
if(not frame:GetAttribute'oUF-onlyProcessChildren') then |
RegisterUnitWatch(frame) |
-- Attempt to guess what the header is set to spawn. |
local groupFilter = header:GetAttribute'groupFilter' |
if(type(groupFilter) == 'string' and groupFilter:match('MAIN[AT]')) then |
local role = groupFilter:match('MAIN([AT])') |
if(role == 'T') then |
unit = 'maintank' |
else |
unit = 'mainassist' |
end |
elseif(header:GetAttribute'showRaid') then |
unit = 'raid' |
elseif(header:GetAttribute'showParty') then |
unit = 'party' |
end |
local headerType = header:GetAttribute'oUF-headerType' |
local suffix = frame:GetAttribute'unitsuffix' |
if(unit and suffix) then |
if(headerType == 'pet' and suffix == 'target') then |
unit = unit .. headerType .. suffix |
else |
unit = unit .. suffix |
end |
elseif(unit and headerType == 'pet') then |
unit = unit .. headerType |
end |
frame:SetAttribute('*type1', 'target') |
frame:SetAttribute('*type2', 'togglemenu') |
frame:SetAttribute('toggleForVehicle', true) |
frame:SetAttribute('oUF-guessUnit', unit) |
end |
local body = header:GetAttribute'oUF-initialConfigFunction' |
if(body) then |
frame:Run(body, unit) |
end |
end |
header:CallMethod('styleFunction', self:GetName()) |
local clique = header:GetFrameRef("clickcast_header") |
if(clique) then |
clique:SetAttribute("clickcast_button", self) |
clique:RunAttribute("clickcast_register") |
end |
]] |
function oUF:SpawnHeader(overrideName, template, visibility, ...) |
if(not style) then return error("Unable to create frame. No styles have been registered.") end |
template = (template or 'SecureGroupHeaderTemplate') |
local isPetHeader = template:match'PetHeader' |
local name = overrideName or generateName(nil, ...) |
local header = CreateFrame('Frame', name, oUF_PetBattleFrameHider, template) |
header:SetAttribute("template", "oUF_ClickCastUnitTemplate") |
for i=1, select("#", ...), 2 do |
local att, val = select(i, ...) |
if(not att) then break end |
header:SetAttribute(att, val) |
end |
header.style = style |
header.styleFunction = styleProxy |
-- We set it here so layouts can't directly override it. |
header:SetAttribute('initialConfigFunction', initialConfigFunction) |
header:SetAttribute('oUF-headerType', isPetHeader and 'pet' or 'group') |
if(Clique) then |
SecureHandlerSetFrameRef(header, 'clickcast_header', Clique.header) |
end |
if(header:GetAttribute'showParty') then |
self:DisableBlizzard'party' |
end |
if(visibility) then |
local type, list = string.split(' ', visibility, 2) |
if(list and type == 'custom') then |
RegisterAttributeDriver(header, 'state-visibility', list) |
else |
local condition = getCondition(string.split(',', visibility)) |
RegisterAttributeDriver(header, 'state-visibility', condition) |
end |
end |
return header |
end |
end |
function oUF:Spawn(unit, overrideName) |
argcheck(unit, 2, 'string') |
if(not style) then return error("Unable to create frame. No styles have been registered.") end |
unit = unit:lower() |
local name = overrideName or generateName(unit) |
local object = CreateFrame("Button", name, oUF_PetBattleFrameHider, "SecureUnitButtonTemplate") |
Private.UpdateUnits(object, unit) |
self:DisableBlizzard(unit) |
walkObject(object, unit) |
object:SetAttribute("unit", unit) |
RegisterUnitWatch(object) |
return object |
end |
function oUF:AddElement(name, update, enable, disable) |
argcheck(name, 2, 'string') |
argcheck(update, 3, 'function', 'nil') |
argcheck(enable, 4, 'function', 'nil') |
argcheck(disable, 5, 'function', 'nil') |
if(elements[name]) then return error('Element [%s] is already registered.', name) end |
elements[name] = { |
update = update; |
enable = enable; |
disable = disable; |
} |
end |
oUF.version = _VERSION |
oUF.objects = objects |
if(global) then |
if(parent ~= 'oUF' and global == 'oUF') then |
error("%s is doing it wrong and setting its global to oUF.", parent) |
else |
_G[global] = oUF |
end |
end |
local parent, ns = ... |
local Private = ns.oUF.Private |
function Private.argcheck(value, num, ...) |
assert(type(num) == 'number', "Bad argument #2 to 'argcheck' (number expected, got "..type(num)..")") |
for i=1,select("#", ...) do |
if type(value) == select(i, ...) then return end |
end |
local types = strjoin(", ", ...) |
local name = string.match(debugstack(2,2,0), ": in function [`<](.-)['>]") |
error(("Bad argument #%d to '%s' (%s expected, got %s"):format(num, name, types, type(value)), 3) |
end |
function Private.print(...) |
print("|cff33ff99oUF:|r", ...) |
end |
function Private.error(...) |
Private.print("|cffff0000Error:|r "..string.format(...)) |
end |
--[[ Element: Raid Icon |
Handles updating and toggles visibility of raid target icons. |
Widget |
RaidIcon - A Texture used to display the raid target icon. |
Notes |
This element updates by changing the texture. |
The default raid icons will be used if the UI widget is a texture and doesn't |
have a texture or color defined. |
Examples |
-- Position and size |
local RaidIcon = self:CreateTexture(nil, 'OVERLAY') |
RaidIcon:SetSize(16, 16) |
RaidIcon:SetPoint('TOPRIGHT', self) |
-- Register it with oUF |
self.RaidIcon = RaidIcon |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local GetRaidTargetIndex = GetRaidTargetIndex |
local SetRaidTargetIconTexture = SetRaidTargetIconTexture |
local Update = function(self, event) |
local icon = self.RaidIcon |
if(icon.PreUpdate) then |
icon:PreUpdate() |
end |
local index = GetRaidTargetIndex(self.unit) |
if(index) then |
SetRaidTargetIconTexture(icon, index) |
icon:Show() |
else |
icon:Hide() |
end |
if(icon.PostUpdate) then |
return icon:PostUpdate(index) |
end |
end |
local Path = function(self, ...) |
return (self.RaidIcon.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
if(not element.__owner.unit) then return end |
return Path(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self) |
local ricon = self.RaidIcon |
if(ricon) then |
ricon.__owner = self |
ricon.ForceUpdate = ForceUpdate |
self:RegisterEvent("RAID_TARGET_UPDATE", Path, true) |
if(ricon:IsObjectType"Texture" and not ricon:GetTexture()) then |
ricon:SetTexture[[Interface\TargetingFrame\UI-RaidTargetingIcons]] |
end |
return true |
end |
end |
local Disable = function(self) |
local ricon = self.RaidIcon |
if(ricon) then |
self:UnregisterEvent("RAID_TARGET_UPDATE", Path) |
end |
end |
oUF:AddElement('RaidIcon', Path, Enable, Disable) |
--[[ |
-- Credits: Vika, Cladhaire, Tekkub |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local _PATTERN = '%[..-%]+' |
local _ENV = { |
Hex = function(r, g, b) |
if type(r) == "table" then |
if r.r then r, g, b = r.r, r.g, r.b else r, g, b = unpack(r) end |
end |
return string.format("|cff%02x%02x%02x", r*255, g*255, b*255) |
end, |
ColorGradient = oUF.ColorGradient, |
} |
local _PROXY = setmetatable(_ENV, {__index = _G}) |
local tagStrings = { |
["creature"] = [[function(u) |
return UnitCreatureFamily(u) or UnitCreatureType(u) |
end]], |
["dead"] = [[function(u) |
if(UnitIsDead(u)) then |
return 'Dead' |
elseif(UnitIsGhost(u)) then |
return 'Ghost' |
end |
end]], |
["difficulty"] = [[function(u) |
if UnitCanAttack("player", u) then |
local l = UnitLevel(u) |
return Hex(GetQuestDifficultyColor((l > 0) and l or 99)) |
end |
end]], |
["leader"] = [[function(u) |
if(UnitIsGroupLeader(u)) then |
return 'L' |
end |
end]], |
["leaderlong"] = [[function(u) |
if(UnitIsGroupLeader(u)) then |
return 'Leader' |
end |
end]], |
["level"] = [[function(u) |
local l = UnitLevel(u) |
if(UnitIsWildBattlePet(u) or UnitIsBattlePetCompanion(u)) then |
l = UnitBattlePetLevel(u) |
end |
if(l > 0) then |
return l |
else |
return '??' |
end |
end]], |
["missinghp"] = [[function(u) |
local current = UnitHealthMax(u) - UnitHealth(u) |
if(current > 0) then |
return current |
end |
end]], |
["missingpp"] = [[function(u) |
local current = UnitPowerMax(u) - UnitPower(u) |
if(current > 0) then |
return current |
end |
end]], |
["name"] = [[function(u, r) |
return UnitName(r or u) |
end]], |
["offline"] = [[function(u) |
if(not UnitIsConnected(u)) then |
return 'Offline' |
end |
end]], |
["perhp"] = [[function(u) |
local m = UnitHealthMax(u) |
if(m == 0) then |
return 0 |
else |
return math.floor(UnitHealth(u)/m*100+.5) |
end |
end]], |
["perpp"] = [[function(u) |
local m = UnitPowerMax(u) |
if(m == 0) then |
return 0 |
else |
return math.floor(UnitPower(u)/m*100+.5) |
end |
end]], |
["plus"] = [[function(u) |
local c = UnitClassification(u) |
if(c == 'elite' or c == 'rareelite') then |
return '+' |
end |
end]], |
["pvp"] = [[function(u) |
if(UnitIsPVP(u)) then |
return 'PvP' |
end |
end]], |
["raidcolor"] = [[function(u) |
local _, x = UnitClass(u) |
if(x) then |
return Hex(_COLORS.class[x]) |
end |
end]], |
["rare"] = [[function(u) |
local c = UnitClassification(u) |
if(c == 'rare' or c == 'rareelite') then |
return 'Rare' |
end |
end]], |
["resting"] = [[function(u) |
if(u == 'player' and IsResting()) then |
return 'zzz' |
end |
end]], |
["sex"] = [[function(u) |
local s = UnitSex(u) |
if(s == 2) then |
return 'Male' |
elseif(s == 3) then |
return 'Female' |
end |
end]], |
["smartclass"] = [[function(u) |
if(UnitIsPlayer(u)) then |
return _TAGS['class'](u) |
end |
return _TAGS['creature'](u) |
end]], |
["status"] = [[function(u) |
if(UnitIsDead(u)) then |
return 'Dead' |
elseif(UnitIsGhost(u)) then |
return 'Ghost' |
elseif(not UnitIsConnected(u)) then |
return 'Offline' |
else |
return _TAGS['resting'](u) |
end |
end]], |
["threat"] = [[function(u) |
local s = UnitThreatSituation(u) |
if(s == 1) then |
return '++' |
elseif(s == 2) then |
return '--' |
elseif(s == 3) then |
return 'Aggro' |
end |
end]], |
["threatcolor"] = [[function(u) |
return Hex(GetThreatStatusColor(UnitThreatSituation(u))) |
end]], |
["cpoints"] = [[function(u) |
local cp |
if(UnitHasVehicleUI'player') then |
cp = GetComboPoints('vehicle', 'target') |
else |
cp = GetComboPoints('player', 'target') |
end |
if(cp > 0) then |
return cp |
end |
end]], |
['smartlevel'] = [[function(u) |
local c = UnitClassification(u) |
if(c == 'worldboss') then |
return 'Boss' |
else |
local plus = _TAGS['plus'](u) |
local level = _TAGS['level'](u) |
if(plus) then |
return level .. plus |
else |
return level |
end |
end |
end]], |
["classification"] = [[function(u) |
local c = UnitClassification(u) |
if(c == 'rare') then |
return 'Rare' |
elseif(c == 'rareelite') then |
return 'Rare Elite' |
elseif(c == 'elite') then |
return 'Elite' |
elseif(c == 'worldboss') then |
return 'Boss' |
elseif(c == 'minus') then |
return 'Affix' |
end |
end]], |
["shortclassification"] = [[function(u) |
local c = UnitClassification(u) |
if(c == 'rare') then |
return 'R' |
elseif(c == 'rareelite') then |
return 'R+' |
elseif(c == 'elite') then |
return '+' |
elseif(c == 'worldboss') then |
return 'B' |
elseif(c == 'minus') then |
return '-' |
end |
end]], |
["group"] = [[function(unit) |
local name, server = UnitName(unit) |
if(server and server ~= "") then |
name = string.format("%s-%s", name, server) |
end |
for i=1, GetNumGroupMembers() do |
local raidName, _, group = GetRaidRosterInfo(i) |
if( raidName == name ) then |
return group |
end |
end |
end]], |
["deficit:name"] = [[function(u) |
local missinghp = _TAGS['missinghp'](u) |
if(missinghp) then |
return '-' .. missinghp |
else |
return _TAGS['name'](u) |
end |
end]], |
['pereclipse'] = [[function(u) |
local m = UnitPowerMax('player', SPELL_POWER_ECLIPSE) |
if(m == 0) then |
return 0 |
else |
return math.abs(UnitPower('player', SPELL_POWER_ECLIPSE)/m*100) |
end |
end]], |
['curmana'] = [[function(unit) |
return UnitPower(unit, SPELL_POWER_MANA) |
end]], |
['maxmana'] = [[function(unit) |
return UnitPowerMax(unit, SPELL_POWER_MANA) |
end]], |
['soulshards'] = [[function() |
local num = UnitPower('player', SPELL_POWER_SOUL_SHARDS) |
if(num > 0) then |
return num |
end |
end]], |
['holypower'] = [[function() |
local num = UnitPower('player', SPELL_POWER_HOLY_POWER) |
if(num > 0) then |
return num |
end |
end]], |
['chi'] = [[function() |
local num = UnitPower('player', SPELL_POWER_CHI) |
if(num > 0) then |
return num |
end |
end]], |
['shadoworbs'] = [[function() |
local num = UnitPower('player', SPELL_POWER_SHADOW_ORBS) |
if(num > 0) then |
return num |
end |
end]], |
['affix'] = [[function(u) |
local c = UnitClassification(u) |
if(c == 'minus') then |
return 'Affix' |
end |
end]], |
} |
local tags = setmetatable( |
{ |
curhp = UnitHealth, |
curpp = UnitPower, |
maxhp = UnitHealthMax, |
maxpp = UnitPowerMax, |
class = UnitClass, |
faction = UnitFactionGroup, |
race = UnitRace, |
}, |
{ |
__index = function(self, key) |
local tagFunc = tagStrings[key] |
if(tagFunc) then |
local func, err = loadstring('return ' .. tagFunc) |
if(func) then |
func = func() |
-- Want to trigger __newindex, so no rawset. |
self[key] = func |
tagStrings[key] = nil |
return func |
else |
error(err, 3) |
end |
end |
end, |
__newindex = function(self, key, val) |
if(type(val) == 'string') then |
tagStrings[key] = val |
elseif(type(val) == 'function') then |
-- So we don't clash with any custom envs. |
if(getfenv(val) == _G) then |
setfenv(val, _PROXY) |
end |
rawset(self, key, val) |
end |
end, |
} |
) |
_ENV._TAGS = tags |
local tagEvents = { |
["curhp"] = "UNIT_HEALTH", |
["dead"] = "UNIT_HEALTH", |
["leader"] = "PARTY_LEADER_CHANGED", |
["leaderlong"] = "PARTY_LEADER_CHANGED", |
["level"] = "UNIT_LEVEL PLAYER_LEVEL_UP", |
["maxhp"] = "UNIT_MAXHEALTH", |
["missinghp"] = "UNIT_HEALTH UNIT_MAXHEALTH", |
["name"] = "UNIT_NAME_UPDATE", |
["perhp"] = "UNIT_HEALTH UNIT_MAXHEALTH", |
["pvp"] = "UNIT_FACTION", |
["resting"] = "PLAYER_UPDATE_RESTING", |
["smartlevel"] = "UNIT_LEVEL PLAYER_LEVEL_UP UNIT_CLASSIFICATION_CHANGED", |
["threat"] = "UNIT_THREAT_SITUATION_UPDATE", |
["threatcolor"] = "UNIT_THREAT_SITUATION_UPDATE", |
['cpoints'] = 'UNIT_COMBO_POINTS PLAYER_TARGET_CHANGED', |
['affix'] = 'UNIT_CLASSIFICATION_CHANGED', |
['plus'] = 'UNIT_CLASSIFICATION_CHANGED', |
['rare'] = 'UNIT_CLASSIFICATION_CHANGED', |
['classification'] = 'UNIT_CLASSIFICATION_CHANGED', |
['shortclassification'] = 'UNIT_CLASSIFICATION_CHANGED', |
["group"] = "GROUP_ROSTER_UPDATE", |
["curpp"] = 'UNIT_POWER', |
["maxpp"] = 'UNIT_MAXPOWER', |
["missingpp"] = 'UNIT_MAXPOWER UNIT_POWER', |
["perpp"] = 'UNIT_MAXPOWER UNIT_POWER', |
["offline"] = "UNIT_HEALTH UNIT_CONNECTION", |
["status"] = "UNIT_HEALTH PLAYER_UPDATE_RESTING UNIT_CONNECTION", |
["pereclipse"] = 'UNIT_POWER', |
['curmana'] = 'UNIT_POWER UNIT_MAXPOWER', |
['maxmana'] = 'UNIT_POWER UNIT_MAXPOWER', |
['soulshards'] = 'UNIT_POWER', |
['holypower'] = 'UNIT_POWER', |
['chi'] = 'UNIT_POWER', |
['shadoworbs'] = 'UNIT_POWER', |
} |
local unitlessEvents = { |
PLAYER_LEVEL_UP = true, |
PLAYER_UPDATE_RESTING = true, |
PLAYER_TARGET_CHANGED = true, |
PARTY_LEADER_CHANGED = true, |
GROUP_ROSTER_UPDATE = true, |
UNIT_COMBO_POINTS = true |
} |
local events = {} |
local frame = CreateFrame"Frame" |
frame:SetScript('OnEvent', function(self, event, unit) |
local strings = events[event] |
if(strings) then |
for k, fontstring in next, strings do |
if(fontstring:IsVisible() and (unitlessEvents[event] or fontstring.parent.unit == unit)) then |
fontstring:UpdateTag() |
end |
end |
end |
end) |
local OnUpdates = {} |
local eventlessUnits = {} |
local createOnUpdate = function(timer) |
local OnUpdate = OnUpdates[timer] |
if(not OnUpdate) then |
local total = timer |
local frame = CreateFrame'Frame' |
local strings = eventlessUnits[timer] |
frame:SetScript('OnUpdate', function(self, elapsed) |
if(total >= timer) then |
for k, fs in next, strings do |
if(fs.parent:IsShown() and UnitExists(fs.parent.unit)) then |
fs:UpdateTag() |
end |
end |
total = 0 |
end |
total = total + elapsed |
end) |
OnUpdates[timer] = frame |
end |
end |
local OnShow = function(self) |
for _, fs in next, self.__tags do |
fs:UpdateTag() |
end |
end |
local getTagName = function(tag) |
local s = (tag:match('>+()') or 2) |
local e = tag:match('.*()<+') |
e = (e and e - 1) or -2 |
return tag:sub(s, e), s, e |
end |
local RegisterEvent = function(fontstr, event) |
if(not events[event]) then events[event] = {} end |
frame:RegisterEvent(event) |
table.insert(events[event], fontstr) |
end |
local RegisterEvents = function(fontstr, tagstr) |
for tag in tagstr:gmatch(_PATTERN) do |
tag = getTagName(tag) |
local tagevents = tagEvents[tag] |
if(tagevents) then |
for event in tagevents:gmatch'%S+' do |
RegisterEvent(fontstr, event) |
end |
end |
end |
end |
local UnregisterEvents = function(fontstr) |
for event, data in pairs(events) do |
for k, tagfsstr in pairs(data) do |
if(tagfsstr == fontstr) then |
if(#data == 1) then |
frame:UnregisterEvent(event) |
end |
table.remove(data, k) |
end |
end |
end |
end |
local tagPool = {} |
local funcPool = {} |
local tmp = {} |
local Tag = function(self, fs, tagstr) |
if(not fs or not tagstr) then return end |
if(not self.__tags) then |
self.__tags = {} |
table.insert(self.__elements, OnShow) |
else |
-- Since people ignore everything that's good practice - unregister the tag |
-- if it already exists. |
for _, tag in pairs(self.__tags) do |
if(fs == tag) then |
-- We don't need to remove it from the __tags table as Untag handles |
-- that for us. |
self:Untag(fs) |
end |
end |
end |
fs.parent = self |
local func = tagPool[tagstr] |
if(not func) then |
local format, numTags = tagstr:gsub('%%', '%%%%'):gsub(_PATTERN, '%%s') |
local args = {} |
for bracket in tagstr:gmatch(_PATTERN) do |
local tagFunc = funcPool[bracket] or tags[bracket:sub(2, -2)] |
if(not tagFunc) then |
local tagName, s, e = getTagName(bracket) |
local tag = tags[tagName] |
if(tag) then |
s = s - 2 |
e = e + 2 |
if(s ~= 0 and e ~= 0) then |
local pre = bracket:sub(2, s) |
local ap = bracket:sub(e, -2) |
tagFunc = function(u,r) |
local str = tag(u,r) |
if(str) then |
return pre..str..ap |
end |
end |
elseif(s ~= 0) then |
local pre = bracket:sub(2, s) |
tagFunc = function(u,r) |
local str = tag(u,r) |
if(str) then |
return pre..str |
end |
end |
elseif(e ~= 0) then |
local ap = bracket:sub(e, -2) |
tagFunc = function(u,r) |
local str = tag(u,r) |
if(str) then |
return str..ap |
end |
end |
end |
funcPool[bracket] = tagFunc |
end |
end |
if(tagFunc) then |
table.insert(args, tagFunc) |
else |
return error(('Attempted to use invalid tag %s.'):format(bracket), 3) |
end |
end |
if(numTags == 1) then |
func = function(self) |
local parent = self.parent |
local realUnit |
if(self.overrideUnit) then |
realUnit = parent.realUnit |
end |
_ENV._COLORS = parent.colors |
return self:SetFormattedText( |
format, |
args[1](parent.unit, realUnit) or '' |
) |
end |
elseif(numTags == 2) then |
func = function(self) |
local parent = self.parent |
local unit = parent.unit |
local realUnit |
if(self.overrideUnit) then |
realUnit = parent.realUnit |
end |
_ENV._COLORS = parent.colors |
return self:SetFormattedText( |
format, |
args[1](unit, realUnit) or '', |
args[2](unit, realUnit) or '' |
) |
end |
elseif(numTags == 3) then |
func = function(self) |
local parent = self.parent |
local unit = parent.unit |
local realUnit |
if(self.overrideUnit) then |
realUnit = parent.realUnit |
end |
_ENV._COLORS = parent.colors |
return self:SetFormattedText( |
format, |
args[1](unit, realUnit) or '', |
args[2](unit, realUnit) or '', |
args[3](unit, realUnit) or '' |
) |
end |
else |
func = function(self) |
local parent = self.parent |
local unit = parent.unit |
local realUnit |
if(self.overrideUnit) then |
realUnit = parent.realUnit |
end |
_ENV._COLORS = parent.colors |
for i, func in next, args do |
tmp[i] = func(unit, realUnit) or '' |
end |
-- We do 1, numTags because tmp can hold several unneeded variables. |
return self:SetFormattedText(format, unpack(tmp, 1, numTags)) |
end |
end |
tagPool[tagstr] = func |
end |
fs.UpdateTag = func |
local unit = self.unit |
if((unit and unit:match'%w+target') or fs.frequentUpdates) then |
local timer |
if(type(fs.frequentUpdates) == 'number') then |
timer = fs.frequentUpdates |
else |
timer = .5 |
end |
if(not eventlessUnits[timer]) then eventlessUnits[timer] = {} end |
table.insert(eventlessUnits[timer], fs) |
createOnUpdate(timer) |
else |
RegisterEvents(fs, tagstr) |
end |
table.insert(self.__tags, fs) |
end |
local Untag = function(self, fs) |
if(not fs) then return end |
UnregisterEvents(fs) |
for _, timers in next, eventlessUnits do |
for k, fontstr in next, timers do |
if(fs == fontstr) then |
table.remove(timers, k) |
end |
end |
end |
for k, fontstr in next, self.__tags do |
if(fontstr == fs) then |
table.remove(self.__tags, k) |
end |
end |
fs.UpdateTag = nil |
end |
oUF.Tags = { |
Methods = tags, |
Events = tagEvents, |
SharedEvents = unitlessEvents, |
} |
oUF:RegisterMetaFunction('Tag', Tag) |
oUF:RegisterMetaFunction('Untag', Untag) |
--[[ Element: Runes Bar |
Handle updating and visibility of the Death Knight's Rune indicators. |
Widget |
Runes - An array holding six StatusBar's. |
Sub-Widgets |
.bg - A Texture which functions as a background. It will inherit the color of |
the main StatusBar. |
Notes |
The default StatusBar texture will be applied if the UI widget doesn't have a |
status bar texture or color defined. |
Sub-Widgets Options |
.multiplier - Defines a multiplier, which is used to tint the background based |
on the main widgets R, G and B values. Defaults to 1 if not |
present. |
Examples |
local Runes = {} |
for index = 1, 6 do |
-- Position and size of the rune bar indicators |
local Rune = CreateFrame('StatusBar', nil, self) |
Rune:SetSize(120 / 6, 20) |
Rune:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * 120 / 6, 0) |
Runes[index] = Rune |
end |
-- Register with oUF |
self.Runes = Runes |
]] |
if select(2, UnitClass("player")) ~= "DEATHKNIGHT" then return end |
local parent, ns = ... |
local oUF = ns.oUF |
oUF.colors.runes = { |
{1, 0, 0}, -- blood |
{0, .5, 0}, -- unholy |
{0, 1, 1}, -- frost |
{.9, .1, 1}, -- death |
} |
local runemap = { 1, 2, 5, 6, 3, 4 } |
local OnUpdate = function(self, elapsed) |
local duration = self.duration + elapsed |
if(duration >= self.max) then |
return self:SetScript("OnUpdate", nil) |
else |
self.duration = duration |
return self:SetValue(duration) |
end |
end |
local UpdateType = function(self, event, rid, alt) |
local runes = self.Runes |
local rune = runes[runemap[rid]] |
local colors = self.colors.runes[GetRuneType(rid) or alt] |
local r, g, b = colors[1], colors[2], colors[3] |
rune:SetStatusBarColor(r, g, b) |
if(rune.bg) then |
local mu = rune.bg.multiplier or 1 |
rune.bg:SetVertexColor(r * mu, g * mu, b * mu) |
end |
if(runes.PostUpdateType) then |
return runes:PostUpdateType(rune, rid, alt) |
end |
end |
local UpdateRune = function(self, event, rid) |
local runes = self.Runes |
local rune = runes[runemap[rid]] |
if(not rune) then return end |
local start, duration, runeReady = GetRuneCooldown(rid) |
if(runeReady) then |
rune:SetMinMaxValues(0, 1) |
rune:SetValue(1) |
rune:SetScript("OnUpdate", nil) |
else |
rune.duration = GetTime() - start |
rune.max = duration |
rune:SetMinMaxValues(1, duration) |
rune:SetScript("OnUpdate", OnUpdate) |
end |
if(runes.PostUpdateRune) then |
return runes:PostUpdateRune(rune, rid, start, duration, runeReady) |
end |
end |
local Update = function(self, event) |
for i=1, 6 do |
UpdateRune(self, event, i) |
end |
end |
local ForceUpdate = function(element) |
return Update(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self, unit) |
local runes = self.Runes |
if(runes and unit == 'player') then |
runes.__owner = self |
runes.ForceUpdate = ForceUpdate |
for i=1, 6 do |
local rune = runes[runemap[i]] |
if(rune:IsObjectType'StatusBar' and not rune:GetStatusBarTexture()) then |
rune:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] |
end |
-- From my minor testing this is a okey solution. A full login always remove |
-- the death runes, or at least the clients knowledge about them. |
UpdateType(self, nil, i, math.floor((i+1)/2)) |
end |
self:RegisterEvent("RUNE_POWER_UPDATE", UpdateRune, true) |
self:RegisterEvent("RUNE_TYPE_UPDATE", UpdateType, true) |
-- oUF leaves the vehicle events registered on the player frame, so |
-- buffs and such are correctly updated when entering/exiting vehicles. |
-- |
-- This however makes the code also show/hide the RuneFrame. |
RuneFrame.Show = RuneFrame.Hide |
RuneFrame:Hide() |
return true |
end |
end |
local Disable = function(self) |
RuneFrame.Show = nil |
RuneFrame:Show() |
self:UnregisterEvent("RUNE_POWER_UPDATE", UpdateRune) |
self:UnregisterEvent("RUNE_TYPE_UPDATE", UpdateType) |
end |
oUF:AddElement("Runes", Update, Enable, Disable) |
--[[ Element: Raid Role Icon |
Handles visibility and updating of `self.RaidRole` based upon the units |
party assignment. |
Widget |
RaidRole - A Texture representing the units party assignment. This is can be |
main tank, main assist or blank. |
Notes |
This element updates by changing the texture. |
Examples |
-- Position and size |
local RaidRole = self:CreateTexture(nil, 'OVERLAY') |
RaidRole:SetSize(16, 16) |
RaidRole:SetPoint('TOPLEFT') |
-- Register it with oUF |
self.RaidRole = RaidRole |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event) |
local unit = self.unit |
if(not UnitInRaid(unit)) then return end |
local raidrole = self.RaidRole |
if(raidrole.PreUpdate) then |
raidrole:PreUpdate() |
end |
local inVehicle = UnitHasVehicleUI(unit) |
if(GetPartyAssignment('MAINTANK', unit) and not inVehicle) then |
raidrole:Show() |
raidrole:SetTexture[[Interface\GROUPFRAME\UI-GROUP-MAINTANKICON]] |
elseif(GetPartyAssignment('MAINASSIST', unit) and not inVehicle) then |
raidrole:Show() |
raidrole:SetTexture[[Interface\GROUPFRAME\UI-GROUP-MAINASSISTICON]] |
else |
raidrole:Hide() |
end |
if(raidrole.PostUpdate) then |
return raidrole:PostUpdate(rinfo) |
end |
end |
local Path = function(self, ...) |
return (self.RaidRole.Override or Update)(self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self) |
local raidrole = self.RaidRole |
if(raidrole) then |
raidrole.__owner = self |
raidrole.ForceUpdate = ForceUpdate |
self:RegisterEvent('GROUP_ROSTER_UPDATE', Path, true) |
return true |
end |
end |
local Disable = function(self) |
local raidrole = self.RaidRole |
if(raidrole) then |
self:UnregisterEvent('GROUP_ROSTER_UPDATE', Path) |
end |
end |
oUF:AddElement('RaidRole', Path, Enable, Disable) |
--[[ Element: Class Icons |
Toggles the visibility of icons depending on the player's class and |
specialization. |
Widget |
ClassIcons - An array consisting of five UI Textures. |
Notes |
Monk - Harmony Orbs |
Paladin - Holy Power |
Priest - Shadow Orbs |
Warlock - Soul Shards |
Examples |
local ClassIcons = {} |
for index = 1, 5 do |
local Icon = self:CreateTexture(nil, 'BACKGROUND') |
-- Position and size. |
Icon:SetSize(16, 16) |
Icon:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * Icon:GetWidth(), 0) |
ClassIcons[index] = Icon |
end |
-- Register with oUF |
self.ClassIcons = ClassIcons |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local PlayerClass = select(2, UnitClass'player') |
-- Holds the class specific stuff. |
local ClassPowerType, ClassPowerTypes |
local ClassPowerEnable, ClassPowerDisable |
local RequireSpec, RequireSpell |
local UpdateTexture = function(element) |
local red, green, blue, desaturated |
if(PlayerClass == 'MONK') then |
red, green, blue = 0, 1, .59 |
desaturated = true |
elseif(PlayerClass == 'WARLOCK') then |
red, green, blue = 1, .5, 1 |
desaturated = true |
elseif(PlayerClass == 'PRIEST') then |
red, green, blue = 1, 1, 1 |
elseif(PlayerClass == 'PALADIN') then |
red, green, blue = 1, .96, .41 |
desaturated = true |
end |
for i=1, 5 do |
if(element[i].SetDesaturated) then |
element[i]:SetDesaturated(desaturated) |
end |
element[i]:SetVertexColor(red, green, blue) |
end |
end |
local ToggleVehicle = function(self, state) |
local element = self.ClassIcons |
for i=1, 5 do |
element[i]:Hide() |
end |
(element.UpdateTexture or UpdateTexture) (element) |
if(state) then |
ClassPowerDisable(self) |
else |
ClassPowerEnable(self) |
end |
end |
local Update = function(self, event, unit, powerType) |
local element = self.ClassIcons |
local hasVehicle = UnitHasVehicleUI('player') |
if(element.__inVehicle ~= hasVehicle) then |
element.__inVehicle = hasVehicle |
ToggleVehicle(self, hasVehicle) |
-- Continue the update if we left a vehicle. |
if(hasVehicle) then return end |
end |
if((unit and unit ~= 'player') or (powerType and not ClassPowerTypes[powerType])) then |
return |
end |
if(element.PreUpdate) then |
element:PreUpdate() |
end |
local cur = UnitPower('player', ClassPowerType) |
local max = UnitPowerMax('player', ClassPowerType) |
for i=1, max do |
if(i <= cur) then |
element[i]:Show() |
else |
element[i]:Hide() |
end |
end |
local oldMax = element.__max |
if(max ~= element.__max) then |
if(max < element.__max) then |
for i=max + 1, element.__max do |
element[i]:Hide() |
end |
end |
element.__max = max |
end |
if(element.PostUpdate) then |
return element:PostUpdate(cur, max, oldMax ~= max) |
end |
end |
local Path = function(self, ...) |
return (self.ClassIcons.Override or Update) (self, ...) |
end |
local Visibility = function(self, event, unit) |
local element = self.ClassIcons |
if( |
(RequireSpec and RequireSpec ~= GetSpecialization()) |
or (RequireSpell and not IsPlayerSpell(RequireSpell))) then |
for i=1, 5 do |
element[i]:Hide() |
end |
ClassPowerDisable(self) |
else |
ClassPowerEnable(self) |
return Path(self, 'UpdateVisibility') |
end |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
do |
if(PlayerClass == 'MONK') then |
ClassPowerType = SPELL_POWER_CHI |
ClassPowerTypes = { |
['CHI'] = true, |
['DARK_FORCE'] = true, |
} |
ClassPowerEnable = function(self) |
local element = self.ClassIcons |
self:RegisterEvent('UNIT_DISPLAYPOWER', Update) |
self:RegisterEvent('UNIT_POWER_FREQUENT', Update) |
end |
ClassPowerDisable = function(self) |
self:UnregisterEvent('UNIT_DISPLAYPOWER', Update) |
self:UnregisterEvent('UNIT_POWER_FREQUENT', Update) |
end |
elseif(PlayerClass == 'PALADIN') then |
ClassPowerType = SPELL_POWER_HOLY_POWER |
ClassPowerTypes = { |
HOLY_POWER = true, |
} |
ClassPowerEnable = function(self) |
local element = self.ClassIcons |
self:RegisterEvent('UNIT_DISPLAYPOWER', Update) |
self:RegisterEvent('UNIT_POWER', Update) |
end |
ClassPowerDisable = function(self) |
self:UnregisterEvent('UNIT_DISPLAYPOWER', Update) |
self:UnregisterEvent('UNIT_POWER', Update) |
end |
elseif(PlayerClass == 'PRIEST') then |
ClassPowerType = SPELL_POWER_SHADOW_ORBS |
ClassPowerTypes = { |
SHADOW_ORBS = true, |
} |
RequireSpec = SPEC_PRIEST_SHADOW |
ClassPowerEnable = function(self) |
local element = self.ClassIcons |
self:RegisterEvent('UNIT_DISPLAYPOWER', Update) |
self:RegisterEvent('UNIT_POWER_FREQUENT', Update) |
end |
ClassPowerDisable = function(self) |
self:UnregisterEvent('UNIT_DISPLAYPOWER', Update) |
self:UnregisterEvent('UNIT_POWER_FREQUENT', Update) |
end |
elseif(PlayerClass == 'WARLOCK') then |
ClassPowerType = SPELL_POWER_SOUL_SHARDS |
ClassPowerTypes = { |
SOUL_SHARDS = true, |
} |
RequireSpell = WARLOCK_SOULBURN |
ClassPowerEnable = function(self) |
local element = self.ClassIcons |
self:RegisterEvent('UNIT_DISPLAYPOWER', Update) |
self:RegisterEvent('UNIT_POWER_FREQUENT', Update) |
end |
ClassPowerDisable = function(self) |
self:UnregisterEvent('UNIT_DISPLAYPOWER', Update) |
self:UnregisterEvent('UNIT_POWER_FREQUENT', Update) |
end |
end |
end |
local Enable = function(self, unit) |
local element = self.ClassIcons |
if(not element) then return end |
element.__owner = self |
element.__max = 0 |
element.ForceUpdate = ForceUpdate |
if(ClassPowerEnable) then |
if(PlayerClass == 'PRIEST') then |
self:RegisterEvent('PLAYER_TALENT_UPDATE', Visibility, true) |
elseif(PlayerClass == 'WARLOCK') then |
self:RegisterEvent('SPELLS_CHANGED', Visibility, true) |
end |
ClassPowerEnable(self) |
for i=1, 5 do |
local icon = element[i] |
if(icon:IsObjectType'Texture' and not icon:GetTexture()) then |
icon:SetTexCoord(0.45703125, 0.60546875, 0.44531250, 0.73437500) |
icon:SetTexture([[Interface\PlayerFrame\Priest-ShadowUI]]) |
end |
end |
(element.UpdateTexture or UpdateTexture) (element) |
return true |
end |
end |
local Disable = function(self) |
local element = self.ClassIcons |
if(not element) then return end |
self:UnregisterEvent('SPELLS_CHANGED', Visibility) |
self:UnregisterEvent('PLAYER_TALENT_UPDATE', Visibility) |
ClassPowerDisable(self) |
end |
oUF:AddElement('ClassIcons', Update, Enable, Disable) |
--[[ Element: Ready Check Icon |
Handles updating and visibility of `self.ReadyCheck` based upon the units |
ready check status. |
Widget |
ReadyCheck - A Texture representing ready check status. |
Notes |
This element updates by changing the texture. |
Options |
.finishedTime - The number of seconds the icon should stick after a check has |
completed. Defaults to 10 seconds. |
.fadeTime - The number of seconds the icon should used to fade away after |
the stick duration has completed. Defaults to 1.5 seconds. |
Examples |
-- Position and size |
local ReadyCheck = self:CreateTexture(nil, 'OVERLAY') |
ReadyCheck:SetSize(16, 16) |
ReadyCheck:SetPoint('TOP') |
-- Register with oUF |
self.ReadyCheck = ReadyCheck |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local _TIMERS = {} |
local ReadyCheckFrame |
local removeEntry = function(icon) |
_TIMERS[icon] = nil |
if(not next(_TIMERS)) then |
return ReadyCheckFrame:Hide() |
end |
end |
local Start = function(self) |
removeEntry(self) |
self:SetTexture(READY_CHECK_WAITING_TEXTURE) |
self.state = 'waiting' |
self:SetAlpha(1) |
self:Show() |
end |
local Confirm = function(self, ready) |
removeEntry(self) |
if(ready) then |
self:SetTexture(READY_CHECK_READY_TEXTURE) |
self.state = 'ready' |
else |
self:SetTexture(READY_CHECK_NOT_READY_TEXTURE) |
self.state = 'notready' |
end |
self:SetAlpha(1) |
self:Show() |
end |
local Finish = function(self) |
if(self.state == 'waiting') then |
self:SetTexture(READY_CHECK_AFK_TEXTURE) |
self.state = 'afk' |
end |
self.finishedTimer = self.finishedTime or 10 |
self.fadeTimer = self.fadeTime or 1.5 |
_TIMERS[self] = true |
ReadyCheckFrame:Show() |
end |
local OnUpdate = function(self, elapsed) |
for icon in next, _TIMERS do |
if(icon.finishedTimer) then |
icon.finishedTimer = icon.finishedTimer - elapsed |
if(icon.finishedTimer <= 0) then |
icon.finishedTimer = nil |
end |
elseif(icon.fadeTimer) then |
icon.fadeTimer = icon.fadeTimer - elapsed |
icon:SetAlpha(icon.fadeTimer / (icon.fadeTime or 1.5)) |
if(icon.fadeTimer <= 0) then |
icon:Hide() |
removeEntry(icon) |
end |
end |
end |
end |
local Update = function(self, event) |
local unit = self.unit |
local readyCheck = self.ReadyCheck |
if(event == 'READY_CHECK_FINISHED') then |
Finish(readyCheck) |
else |
local status = GetReadyCheckStatus(unit) |
if(UnitExists(unit) and status) then |
if(status == 'ready') then |
Confirm(readyCheck, 1) |
elseif(status == 'notready') then |
Confirm(readyCheck) |
else |
Start(readyCheck) |
end |
end |
end |
end |
local Path = function(self, ...) |
return (self.ReadyCheck.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self, unit) |
local readyCheck = self.ReadyCheck |
if(readyCheck and (unit and (unit:sub(1, 5) == 'party' or unit:sub(1,4) == 'raid'))) then |
readyCheck.__owner = self |
readyCheck.ForceUpdate = ForceUpdate |
if(not ReadyCheckFrame) then |
ReadyCheckFrame = CreateFrame'Frame' |
ReadyCheckFrame:SetScript('OnUpdate', OnUpdate) |
end |
self:RegisterEvent('READY_CHECK', Path, true) |
self:RegisterEvent('READY_CHECK_CONFIRM', Path, true) |
self:RegisterEvent('READY_CHECK_FINISHED', Path, true) |
return true |
end |
end |
local Disable = function(self) |
local readyCheck = self.ReadyCheck |
if(readyCheck) then |
self:UnregisterEvent('READY_CHECK', Path) |
self:UnregisterEvent('READY_CHECK_CONFIRM', Path) |
self:UnregisterEvent('READY_CHECK_FINISHED', Path) |
end |
end |
oUF:AddElement('ReadyCheck', Path, Enable, Disable) |
--[[ Element: Druid Mana Bar |
Handles updating and visibility of a status bar displaying the druid's mana |
while outside of caster form. |
Widget |
DruidMana - A StatusBar to represent current caster mana. |
Sub-Widgets |
.bg - A Texture which functions as a background. It will inherit the color of |
the main StatusBar. |
Notes |
The default StatusBar texture will be applied if the UI widget doesn't have a |
status bar texture or color defined. |
Options |
.colorClass - Use `self.colors.class[class]` to color the bar. This will |
always use DRUID as class. |
.colorSmooth - Use `self.colors.smooth` to color the bar with a smooth |
gradient based on the players current mana percentage. |
.colorPower - Use `self.colors.power[token]` to color the bar. This will |
always use MANA as token. |
Sub-Widget Options |
.multiplier - Defines a multiplier, which is used to tint the background based |
on the main widgets R, G and B values. Defaults to 1 if not |
present. |
Examples |
-- Position and size |
local DruidMana = CreateFrame("StatusBar", nil, self) |
DruidMana:SetSize(20, 20) |
DruidMana:SetPoint('TOP') |
DruidMana:SetPoint('LEFT') |
DruidMana:SetPoint('RIGHT') |
-- Add a background |
local Background = DruidMana:CreateTexture(nil, 'BACKGROUND') |
Background:SetAllPoints(DruidMana) |
Background:SetTexture(1, 1, 1, .5) |
-- Register it with oUF |
self.DruidMana = DruidMana |
self.DruidMana.bg = Background |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
if(select(2, UnitClass('player')) ~= 'DRUID') then return end |
local _, ns = ... |
local oUF = ns.oUF |
local function Update(self, event, unit, powertype) |
if(unit ~= 'player' or (powertype and powertype ~= 'MANA')) then return end |
local druidmana = self.DruidMana |
if(druidmana.PreUpdate) then druidmana:PreUpdate(unit) end |
-- Hide the bar if the active power type is mana. |
if(UnitPowerType('player') == SPELL_POWER_MANA) then |
return druidmana:Hide() |
else |
druidmana:Show() |
end |
local min, max = UnitPower('player', SPELL_POWER_MANA), UnitPowerMax('player', SPELL_POWER_MANA) |
druidmana:SetMinMaxValues(0, max) |
druidmana:SetValue(min) |
local r, g, b, t |
if(druidmana.colorClass) then |
t = self.colors.class['DRUID'] |
elseif(druidmana.colorSmooth) then |
r, g, b = self.ColorGradient(min, max, unpack(druidmana.smoothGradient or self.colors.smooth)) |
elseif(druidmana.colorPower) then |
t = self.colors.power['MANA'] |
end |
if(t) then |
r, g, b = t[1], t[2], t[3] |
end |
if(b) then |
druidmana:SetStatusBarColor(r, g, b) |
local bg = druidmana.bg |
if(bg) then |
local mu = bg.multiplier or 1 |
bg:SetVertexColor(r * mu, g * mu, b * mu) |
end |
end |
if(druidmana.PostUpdate) then |
return druidmana:PostUpdate(unit, min, max) |
end |
end |
local function Path(self, ...) |
return (self.DruidMana.Override or Update) (self, ...) |
end |
local function ForceUpdate(element) |
return Path(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local OnDruidManaUpdate |
do |
local UnitPower = UnitPower |
OnDruidManaUpdate = function(self) |
local unit = self.__owner.unit |
local mana = UnitPower(unit, SPELL_POWER_MANA) |
if(mana ~= self.min) then |
self.min = mana |
return Path(self.__owner, 'OnDruidManaUpdate', unit) |
end |
end |
end |
local Enable = function(self, unit) |
local druidmana = self.DruidMana |
if(druidmana and unit == 'player') then |
druidmana.__owner = self |
druidmana.ForceUpdate = ForceUpdate |
if(druidmana.frequentUpdates) then |
druidmana:SetScript('OnUpdate', OnDruidManaUpdate) |
else |
self:RegisterEvent('UNIT_POWER', Path) |
end |
self:RegisterEvent('UNIT_DISPLAYPOWER', Path) |
self:RegisterEvent('UNIT_MAXPOWER', Path) |
if(druidmana:IsObjectType'StatusBar' and not druidmana:GetStatusBarTexture()) then |
druidmana:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] |
end |
return true |
end |
end |
local Disable = function(self) |
local druidmana = self.DruidMana |
if(druidmana) then |
if(druidmana:GetScript'OnUpdate') then |
druidmana:SetScript("OnUpdate", nil) |
else |
self:UnregisterEvent('UNIT_POWER', Path) |
end |
self:UnregisterEvent('UNIT_DISPLAYPOWER', Path) |
self:UnregisterEvent('UNIT_MAXPOWER', Path) |
end |
end |
oUF:AddElement('DruidMana', Path, Enable, Disable) |
--[[ Element: Health Bar |
Handles updating of `self.Health` based on the units health. |
Widget |
Health - A StatusBar used to represent current unit health. |
Sub-Widgets |
.bg - A Texture which functions as a background. It will inherit the color of |
the main StatusBar. |
Notes |
The default StatusBar texture will be applied if the UI widget doesn't have a |
status bar texture or color defined. |
Options |
The following options are listed by priority. The first check that returns |
true decides the color of the bar. |
.colorTapping - Use `self.colors.tapping` to color the bar if the unit |
isn't tapped by the player. |
.colorDisconnected - Use `self.colors.disconnected` to color the bar if the |
unit is offline. |
.colorClass - Use `self.colors.class[class]` to color the bar based on |
unit class. `class` is defined by the second return of |
[UnitClass](http://wowprogramming.com/docs/api/UnitClass). |
.colorClassNPC - Use `self.colors.class[class]` to color the bar if the |
unit is a NPC. |
.colorClassPet - Use `self.colors.class[class]` to color the bar if the |
unit is player controlled, but not a player. |
.colorReaction - Use `self.colors.reaction[reaction]` to color the bar |
based on the player's reaction towards the unit. |
`reaction` is defined by the return value of |
[UnitReaction](http://wowprogramming.com/docs/api/UnitReaction). |
.colorSmooth - Use `self.colors.smooth` to color the bar with a smooth |
gradient based on the player's current health percentage. |
.colorHealth - Use `self.colors.health` to color the bar. This flag is |
used to reset the bar color back to default if none of the |
above conditions are met. |
Sub-Widgets Options |
.multiplier - Defines a multiplier, which is used to tint the background based |
on the main widgets R, G and B values. Defaults to 1 if not |
present. |
Examples |
-- Position and size |
local Health = CreateFrame("StatusBar", nil, self) |
Health:SetHeight(20) |
Health:SetPoint('TOP') |
Health:SetPoint('LEFT') |
Health:SetPoint('RIGHT') |
-- Add a background |
local Background = Health:CreateTexture(nil, 'BACKGROUND') |
Background:SetAllPoints(Health) |
Background:SetTexture(1, 1, 1, .5) |
-- Options |
Health.frequentUpdates = true |
Health.colorTapping = true |
Health.colorDisconnected = true |
Health.colorClass = true |
Health.colorReaction = true |
Health.colorHealth = true |
-- Make the background darker. |
Background.multiplier = .5 |
-- Register it with oUF |
self.Health = Health |
self.Health.bg = Background |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
oUF.colors.health = {49/255, 207/255, 37/255} |
local Update = function(self, event, unit) |
if(self.unit ~= unit) then return end |
local health = self.Health |
if(health.PreUpdate) then health:PreUpdate(unit) end |
local min, max = UnitHealth(unit), UnitHealthMax(unit) |
local disconnected = not UnitIsConnected(unit) |
health:SetMinMaxValues(0, max) |
if(disconnected) then |
health:SetValue(max) |
else |
health:SetValue(min) |
end |
health.disconnected = disconnected |
local r, g, b, t |
if(health.colorTapping and not UnitPlayerControlled(unit) and |
UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit) and not |
UnitIsTappedByAllThreatList(unit)) then |
t = self.colors.tapped |
elseif(health.colorDisconnected and not UnitIsConnected(unit)) then |
t = self.colors.disconnected |
elseif(health.colorClass and UnitIsPlayer(unit)) or |
(health.colorClassNPC and not UnitIsPlayer(unit)) or |
(health.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then |
local _, class = UnitClass(unit) |
t = self.colors.class[class] |
elseif(health.colorReaction and UnitReaction(unit, 'player')) then |
t = self.colors.reaction[UnitReaction(unit, "player")] |
elseif(health.colorSmooth) then |
r, g, b = self.ColorGradient(min, max, unpack(health.smoothGradient or self.colors.smooth)) |
elseif(health.colorHealth) then |
t = self.colors.health |
end |
if(t) then |
r, g, b = t[1], t[2], t[3] |
end |
if(b) then |
health:SetStatusBarColor(r, g, b) |
local bg = health.bg |
if(bg) then local mu = bg.multiplier or 1 |
bg:SetVertexColor(r * mu, g * mu, b * mu) |
end |
end |
if(health.PostUpdate) then |
return health:PostUpdate(unit, min, max) |
end |
end |
local Path = function(self, ...) |
return (self.Health.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local Enable = function(self, unit) |
local health = self.Health |
if(health) then |
health.__owner = self |
health.ForceUpdate = ForceUpdate |
if(health.frequentUpdates) then |
self:RegisterEvent('UNIT_HEALTH_FREQUENT', Path) |
else |
self:RegisterEvent('UNIT_HEALTH', Path) |
end |
self:RegisterEvent("UNIT_MAXHEALTH", Path) |
self:RegisterEvent('UNIT_CONNECTION', Path) |
-- For tapping. |
self:RegisterEvent('UNIT_FACTION', Path) |
if(health:IsObjectType'StatusBar' and not health:GetStatusBarTexture()) then |
health:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] |
end |
return true |
end |
end |
local Disable = function(self) |
local health = self.Health |
if(health) then |
self:UnregisterEvent('UNIT_HEALTH_FREQUENT', Path) |
self:UnregisterEvent('UNIT_HEALTH', Path) |
self:UnregisterEvent('UNIT_MAXHEALTH', Path) |
self:UnregisterEvent('UNIT_CONNECTION', Path) |
self:UnregisterEvent('UNIT_FACTION', Path) |
end |
end |
oUF:AddElement('Health', Path, Enable, Disable) |
--[[ Element: Combat Icon |
Toggles the visibility of `self.Combat` based on the player's combat status. |
Widget |
Combat - Any UI widget. |
Notes |
The default assistant icon will be applied if the UI widget is a texture and |
doesn't have a texture or color defined. |
Examples |
-- Position and size |
local Combat = self:CreateTexture(nil, "OVERLAY") |
Combat:SetSize(16, 16) |
Combat:SetPoint('TOP', self) |
-- Register it with oUF |
self.Combat = Combat |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event) |
local combat = self.Combat |
if(combat.PreUpdate) then |
combat:PreUpdate() |
end |
local inCombat = UnitAffectingCombat('player') |
if(inCombat) then |
combat:Show() |
else |
combat:Hide() |
end |
if(combat.PostUpdate) then |
return combat:PostUpdate(inCombat) |
end |
end |
local Path = function(self, ...) |
return (self.Combat.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self, unit) |
local combat = self.Combat |
if(combat and unit == 'player') then |
combat.__owner = self |
combat.ForceUpdate = ForceUpdate |
self:RegisterEvent("PLAYER_REGEN_DISABLED", Path, true) |
self:RegisterEvent("PLAYER_REGEN_ENABLED", Path, true) |
if(combat:IsObjectType"Texture" and not combat:GetTexture()) then |
combat:SetTexture[[Interface\CharacterFrame\UI-StateIcon]] |
combat:SetTexCoord(.5, 1, 0, .49) |
end |
return true |
end |
end |
local Disable = function(self) |
if(self.Combat) then |
self:UnregisterEvent("PLAYER_REGEN_DISABLED", Path) |
self:UnregisterEvent("PLAYER_REGEN_ENABLED", Path) |
end |
end |
oUF:AddElement('Combat', Path, Enable, Disable) |
--[[ Element: PvP Icon |
Handles updating and toggles visibility based upon the units PvP status. |
Widget |
PvP - A Texture used to display the faction or FFA icon. |
Notes |
This element updates by changing the texture. |
Examples |
-- Position and size |
local PvP = self:CreateTexture(nil, 'OVERLAY') |
PvP:SetSize(16, 16) |
PvP:SetPoint('TOPRIGHT', self) |
-- Register it with oUF |
self.PvP = PvP |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event, unit) |
if(unit ~= self.unit) then return end |
local pvp = self.PvP |
if(pvp.PreUpdate) then |
pvp:PreUpdate() |
end |
local status |
local factionGroup = UnitFactionGroup(unit) |
if(UnitIsPVPFreeForAll(unit)) then |
pvp:SetTexture[[Interface\TargetingFrame\UI-PVP-FFA]] |
status = 'ffa' |
-- XXX - WoW5: UnitFactionGroup() can return Neutral as well. |
elseif(factionGroup and factionGroup ~= 'Neutral' and UnitIsPVP(unit)) then |
pvp:SetTexture([[Interface\TargetingFrame\UI-PVP-]]..factionGroup) |
status = factionGroup |
end |
if(status) then |
pvp:Show() |
else |
pvp:Hide() |
end |
if(pvp.PostUpdate) then |
return pvp:PostUpdate(status) |
end |
end |
local Path = function(self, ...) |
return (self.PvP.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local Enable = function(self) |
local pvp = self.PvP |
if(pvp) then |
pvp.__owner = self |
pvp.ForceUpdate = ForceUpdate |
self:RegisterEvent("UNIT_FACTION", Path) |
return true |
end |
end |
local Disable = function(self) |
local pvp = self.PvP |
if(pvp) then |
self:UnregisterEvent("UNIT_FACTION", Path) |
end |
end |
oUF:AddElement('PvP', Path, Enable, Disable) |
--[[ Element: Phasing Icon |
Toggles visibility of the phase icon based on the units phasing compared to the |
player. |
Widget |
PhaseIcon - Any UI widget. |
Notes |
The default phasing icon will be used if the UI widget is a texture and doesn't |
have a texture or color defined. |
Examples |
-- Position and size |
local PhaseIcon = self:CreateTexture(nil, 'OVERLAY') |
PhaseIcon:SetSize(16, 16) |
PhaseIcon:SetPoint('TOPLEFT', self) |
-- Register it with oUF |
self.PhaseIcon = PhaseIcon |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event) |
local picon = self.PhaseIcon |
if(picon.PreUpdate) then |
picon:PreUpdate() |
end |
local inPhase = UnitInPhase(self.unit) |
if(inPhase) then |
picon:Hide() |
else |
picon:Show() |
end |
if(picon.PostUpdate) then |
return picon:PostUpdate(inPhase) |
end |
end |
local Path = function(self, ...) |
return (self.PhaseIcon.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self) |
local picon = self.PhaseIcon |
if(picon) then |
picon.__owner = self |
picon.ForceUpdate = ForceUpdate |
self:RegisterEvent('UNIT_PHASE', Path, true) |
if(picon:IsObjectType'Texture' and not picon:GetTexture()) then |
picon:SetTexture[[Interface\TargetingFrame\UI-PhasingIcon]] |
end |
return true |
end |
end |
local Disable = function(self) |
local picon = self.PhaseIcon |
if(picon) then |
self:UnregisterEvent('UNIT_PHASE', Path) |
end |
end |
oUF:AddElement('PhaseIcon', Path, Enable, Disable) |
--[[ Element: Eclipse Bar |
Handle updating and visibility of the Druid eclipse state status bars. |
Widget |
EclipseBar - A table to hold the sub-widgets. |
Sub-Widgets |
LunarBar - A StatusBar used to represent the lunar power state. |
SolarBar - A StatusBar used to represent the solar power state. |
Notes |
The default StatusBar texture will be applied if the UI widget doesn't have a |
status bar texture or color defined. |
Examples |
-- Position and size |
local LunarBar = CreateFrame('StatusBar', nil, self) |
LunarBar:SetPoint('LEFT') |
LunarBar:SetSize(160, 20) |
local SolarBar = CreateFrame('StatusBar', nil, self) |
SolarBar:SetPoint('LEFT', LunarBar:GetStatusBarTexture(), 'RIGHT') |
SolarBar:SetSize(160, 20) |
-- Register with oUF |
self.EclipseBar = { |
LunarBar = LunarBar, |
SolarBar = SolarBar, |
} |
Hooks and Callbacks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
if(select(2, UnitClass('player')) ~= 'DRUID') then return end |
local parent, ns = ... |
local oUF = ns.oUF |
local ECLIPSE_BAR_SOLAR_BUFF_ID = ECLIPSE_BAR_SOLAR_BUFF_ID |
local ECLIPSE_BAR_LUNAR_BUFF_ID = ECLIPSE_BAR_LUNAR_BUFF_ID |
local SPELL_POWER_ECLIPSE = SPELL_POWER_ECLIPSE |
local MOONKIN_FORM = MOONKIN_FORM |
local UNIT_POWER = function(self, event, unit, powerType) |
if(self.unit ~= unit or (event == 'UNIT_POWER' and powerType ~= 'ECLIPSE')) then return end |
local eb = self.EclipseBar |
local power = UnitPower('player', SPELL_POWER_ECLIPSE) |
local maxPower = UnitPowerMax('player', SPELL_POWER_ECLIPSE) |
if(eb.LunarBar) then |
eb.LunarBar:SetMinMaxValues(-maxPower, maxPower) |
eb.LunarBar:SetValue(power) |
end |
if(eb.SolarBar) then |
eb.SolarBar:SetMinMaxValues(-maxPower, maxPower) |
eb.SolarBar:SetValue(power * -1) |
end |
if(eb.PostUpdatePower) then |
--[[ :PostUpdatePower(unit) |
Callback which is called after lunar and solar bar was updated. |
Arguments |
self - The widget that holds the eclipse frame. |
unit - The unit that has the widget. |
]] |
return eb:PostUpdatePower(unit) |
end |
end |
local UPDATE_VISIBILITY = function(self, event) |
local eb = self.EclipseBar |
-- check form/mastery |
local showBar |
local form = GetShapeshiftFormID() |
if(not form) then |
local ptt = GetSpecialization() |
if(ptt and ptt == 1) then -- player has balance spec |
showBar = true |
end |
elseif(form == MOONKIN_FORM) then |
showBar = true |
end |
if(showBar) then |
eb:Show() |
else |
eb:Hide() |
end |
if(eb.PostUpdateVisibility) then |
--[[ :PostUpdateVisibility(unit) |
Callback which is called after the eclipse frame was shown or hidden. |
Arguments |
self - The widget that holds the eclipse frame. |
unit - The unit that has the widget. |
]] |
return eb:PostUpdateVisibility(self.unit) |
end |
end |
local UNIT_AURA = function(self, event, unit) |
if(self.unit ~= unit) then return end |
local i = 1 |
local hasSolarEclipse, hasLunarEclipse |
repeat |
local _, _, _, _, _, _, _, _, _, _, spellID = UnitAura(unit, i, 'HELPFUL') |
if(spellID == ECLIPSE_BAR_SOLAR_BUFF_ID) then |
hasSolarEclipse = true |
elseif(spellID == ECLIPSE_BAR_LUNAR_BUFF_ID) then |
hasLunarEclipse = true |
end |
i = i + 1 |
until not spellID |
local eb = self.EclipseBar |
eb.hasSolarEclipse = hasSolarEclipse |
eb.hasLunarEclipse = hasLunarEclipse |
if(eb.PostUnitAura) then |
--[[ :PostUnitAura(unit) |
Callback which is called after the eclipse state was checked. |
Arguments |
self - The widget that holds the eclipse frame. |
unit - The unit that has the widget. |
]] |
return eb:PostUnitAura(unit) |
end |
end |
local ECLIPSE_DIRECTION_CHANGE = function(self, event, isLunar) |
local eb = self.EclipseBar |
eb.directionIsLunar = isLunar |
if(eb.PostDirectionChange) then |
--[[ :PostDirectionChange(unit) |
Callback which is called after eclipse direction was changed. |
Arguments |
self - The widget that holds the eclipse frame. |
unit - The unit that has the widget. |
]] |
return eb:PostDirectionChange(self.unit) |
end |
end |
local Update = function(self, ...) |
UNIT_POWER(self, ...) |
UNIT_AURA(self, ...) |
return UPDATE_VISIBILITY(self, ...) |
end |
local ForceUpdate = function(element) |
return Update(element.__owner, 'ForceUpdate', element.__owner.unit, 'ECLIPSE') |
end |
local function Enable(self) |
local eb = self.EclipseBar |
if(eb) then |
eb.__owner = self |
eb.ForceUpdate = ForceUpdate |
if(eb.LunarBar and eb.LunarBar:IsObjectType'StatusBar' and not eb.LunarBar:GetStatusBarTexture()) then |
eb.LunarBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) |
end |
if(eb.SolarBar and eb.SolarBar:IsObjectType'StatusBar' and not eb.SolarBar:GetStatusBarTexture()) then |
eb.SolarBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) |
end |
self:RegisterEvent('ECLIPSE_DIRECTION_CHANGE', ECLIPSE_DIRECTION_CHANGE, true) |
self:RegisterEvent('PLAYER_TALENT_UPDATE', UPDATE_VISIBILITY, true) |
self:RegisterEvent('UNIT_AURA', UNIT_AURA) |
self:RegisterEvent('UNIT_POWER', UNIT_POWER) |
self:RegisterEvent('UPDATE_SHAPESHIFT_FORM', UPDATE_VISIBILITY, true) |
return true |
end |
end |
local function Disable(self) |
local eb = self.EclipseBar |
if(eb) then |
self:UnregisterEvent('ECLIPSE_DIRECTION_CHANGE', ECLIPSE_DIRECTION_CHANGE) |
self:UnregisterEvent('PLAYER_TALENT_UPDATE', UPDATE_VISIBILITY) |
self:UnregisterEvent('UNIT_AURA', UNIT_AURA) |
self:UnregisterEvent('UNIT_POWER', UNIT_POWER) |
self:UnregisterEvent('UPDATE_SHAPESHIFT_FORM', UPDATE_VISIBILITY) |
end |
end |
oUF:AddElement('EclipseBar', Update, Enable, Disable) |
--[[ Element: Assistant Icon |
Toggles visibility of `self.Assistant` based on the units raid officer status. |
Widget |
Assistant - Any UI widget. |
Notes |
The default assistant icon will be applied if the UI widget is a texture and |
doesn't have a texture or color defined. |
Examples |
-- Position and size |
local Assistant = self:CreateTexture(nil, "OVERLAY") |
Assistant:SetSize(16, 16) |
Assistant:SetPoint('TOP', self) |
-- Register it with oUF |
self.Assistant = Assistant |
Hooks and Callbacks |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event) |
local assistant = self.Assistant |
--[[ :PreUpdate() |
Called before the element has been updated. |
Arguments |
self - The Assistant element. |
]] |
if(assistant.PreUpdate) then |
assistant:PreUpdate() |
end |
local unit = self.unit |
local isAssistant = UnitInRaid(unit) and UnitIsGroupAssistant(unit) and not UnitIsGroupLeader(unit) |
if(isAssistant) then |
assistant:Show() |
else |
assistant:Hide() |
end |
--[[ :PostUpdate(isAssistant) |
Called after the element has been updated. |
Arguments |
self - The Assistant element. |
isAssistant - A boolean holding whether the unit is a raid officer or not. |
]] |
if(assistant.PostUpdate) then |
return assistant:PostUpdate(isAssistant) |
end |
end |
local Path = function(self, ...) |
--[[ :Override(self, event, ...) |
Used to completely override the internal update function. Removing the |
table key entry will make the element fall-back to its internal function |
again. |
Arguments |
self - The Assistant element. |
event - The UI event that fired. |
... - A vararg with the arguments that accompany the event. |
]] |
return (self.Assistant.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self) |
local assistant = self.Assistant |
if(assistant) then |
self:RegisterEvent("GROUP_ROSTER_UPDATE", Path, true) |
if(assistant:IsObjectType"Texture" and not assistant:GetTexture()) then |
assistant:SetTexture[[Interface\GroupFrame\UI-Group-AssistantIcon]] |
end |
assistant.__owner = self |
assistant.ForceUpdate = ForceUpdate |
return true |
end |
end |
local Disable = function(self) |
local assistant = self.Assistant |
if(assistant) then |
self:UnregisterEvent("GROUP_ROSTER_UPDATE", Path) |
end |
end |
oUF:AddElement('Assistant', Path, Enable, Disable) |
--[[ Element: Quest Icon |
Handles updating and toggles visibility based upon the units connection to a |
quest. |
Widget |
QuestIcon - Any UI widget. |
Notes |
The default quest icon will be used if the UI widget is a texture and doesn't |
have a texture or color defined. |
Examples |
-- Position and size |
local QuestIcon = self:CreateTexture(nil, 'OVERLAY') |
QuestIcon:SetSize(16, 16) |
QuestIcon:SetPoint('TOPRIGHT', self) |
-- Register it with oUF |
self.QuestIcon = QuestIcon |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event, unit) |
if(unit ~= self.unit) then return end |
local qicon = self.QuestIcon |
if(qicon.PreUpdate) then |
qicon:PreUpdate() |
end |
local isQuestBoss = UnitIsQuestBoss(unit) |
if(isQuestBoss) then |
qicon:Show() |
else |
qicon:Hide() |
end |
if(qicon.PostUpdate) then |
return qicon:PostUpdate(isQuestBoss) |
end |
end |
local Path = function(self, ...) |
return (self.QuestIcon.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local Enable = function(self) |
local qicon = self.QuestIcon |
if(qicon) then |
qicon.__owner = self |
qicon.ForceUpdate = ForceUpdate |
self:RegisterEvent('UNIT_CLASSIFICATION_CHANGED', Path) |
if(qicon:IsObjectType'Texture' and not qicon:GetTexture()) then |
qicon:SetTexture[[Interface\TargetingFrame\PortraitQuestBadge]] |
end |
return true |
end |
end |
local Disable = function(self) |
if(self.QuestIcon) then |
self:UnregisterEvent('UNIT_CLASSIFICATION_CHANGED', Path) |
end |
end |
oUF:AddElement('QuestIcon', Path, Enable, Disable) |
--[[ Element: Resting Icon |
Toggles visibility of the resting icon. |
Widget |
Resting - Any UI widget. |
Notes |
The default resting icon will be used if the UI widget is a texture and doesn't |
have a texture or color defined. |
Examples |
-- Position and size |
local Resting = self:CreateTexture(nil, 'OVERLAY') |
Resting:SetSize(16, 16) |
Resting:SetPoint('TOPLEFT', self) |
-- Register it with oUF |
self.Resting = Resting |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event) |
local resting = self.Resting |
if(resting.PreUpdate) then |
resting:PreUpdate() |
end |
local isResting = IsResting() |
if(isResting) then |
resting:Show() |
else |
resting:Hide() |
end |
if(resting.PostUpdate) then |
return resting:PostUpdate(isResting) |
end |
end |
local Path = function(self, ...) |
return (self.Resting.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self, unit) |
local resting = self.Resting |
if(resting and unit == 'player') then |
resting.__owner = self |
resting.ForceUpdate = ForceUpdate |
self:RegisterEvent("PLAYER_UPDATE_RESTING", Path, true) |
if(resting:IsObjectType"Texture" and not resting:GetTexture()) then |
resting:SetTexture[[Interface\CharacterFrame\UI-StateIcon]] |
resting:SetTexCoord(0, .5, 0, .421875) |
end |
return true |
end |
end |
local Disable = function(self) |
local resting = self.Resting |
if(resting) then |
self:UnregisterEvent("PLAYER_UPDATE_RESTING", Path) |
end |
end |
oUF:AddElement('Resting', Path, Enable, Disable) |
--[[ Element: Totem Indicator |
Handles updating and visibility of Shaman totems, Druid mushrooms and Death |
Knight ghouls. |
Widget |
Totems - A table to hold sub-widgets. |
Sub-Widgets |
Totem - Any UI widget. |
.Icon - A Texture representing the totem icon. |
.Cooldown - A Cooldown representing the duration of the totem. |
Notes |
OnEnter and OnLeave will be set to display the default Tooltip, if the |
`Totem` widget is mouse enabled. |
Options |
:UpdateTooltip - The function that should populate the tooltip, when the |
`Totem` widget is hovered. A default function, which calls |
`:SetTotem(id)`, will be used if none is defined. |
Examples |
local Totems = {} |
for index = 1, MAX_TOTEMS do |
-- Position and size of the totem indicator |
local Totem = CreateFrame('Button', nil, self) |
Totem:SetSize(40, 40) |
Totem:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * Totem:GetWidth(), 0) |
local Icon = Totem:CreateTexture(nil, "OVERLAY") |
Icon:SetAllPoints() |
local Cooldown = CreateFrame("Cooldown", nil, Totem) |
Cooldown:SetAllPoints() |
Totem.Icon = Icon |
Totem.Cooldown = Cooldown |
Totems[index] = Totem |
end |
-- Register with oUF |
self.Totems = Totems |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
-- Order the list based upon the default UIs priorities. |
local priorities = STANDARD_TOTEM_PRIORITIES |
if(select(2, UnitClass'player') == 'SHAMAN') then |
priorities = SHAMAN_TOTEM_PRIORITIES |
end |
local UpdateTooltip = function(self) |
GameTooltip:SetTotem(self:GetID()) |
end |
local OnEnter = function(self) |
if(not self:IsVisible()) then return end |
GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT') |
self:UpdateTooltip() |
end |
local OnLeave = function() |
GameTooltip:Hide() |
end |
local UpdateTotem = function(self, event, slot) |
if(slot > MAX_TOTEMS) then return end |
local totems = self.Totems |
if(totems.PreUpdate) then totems:PreUpdate(priorities[slot]) end |
local totem = totems[priorities[slot]] |
local haveTotem, name, start, duration, icon = GetTotemInfo(slot) |
if(duration > 0) then |
if(totem.Icon) then |
totem.Icon:SetTexture(icon) |
end |
if(totem.Cooldown) then |
totem.Cooldown:SetCooldown(start, duration) |
end |
totem:Show() |
else |
totem:Hide() |
end |
if(totems.PostUpdate) then |
return totems:PostUpdate(priorities[slot], haveTotem, name, start, duration, icon) |
end |
end |
local Path = function(self, ...) |
return (self.Totems.Override or UpdateTotem) (self, ...) |
end |
local Update = function(self, event) |
for i = 1, MAX_TOTEMS do |
Path(self, event, i) |
end |
end |
local ForceUpdate = function(element) |
return Update(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self) |
local totems = self.Totems |
if(totems) then |
totems.__owner = self |
totems.ForceUpdate = ForceUpdate |
for i = 1, MAX_TOTEMS do |
local totem = totems[i] |
totem:SetID(priorities[i]) |
if(totem:IsMouseEnabled()) then |
totem:SetScript('OnEnter', OnEnter) |
totem:SetScript('OnLeave', OnLeave) |
if(not totem.UpdateTooltip) then |
totem.UpdateTooltip = UpdateTooltip |
end |
end |
end |
self:RegisterEvent('PLAYER_TOTEM_UPDATE', Path, true) |
TotemFrame.Show = TotemFrame.Hide |
TotemFrame:Hide() |
TotemFrame:UnregisterEvent"PLAYER_TOTEM_UPDATE" |
TotemFrame:UnregisterEvent"PLAYER_ENTERING_WORLD" |
TotemFrame:UnregisterEvent"UPDATE_SHAPESHIFT_FORM" |
TotemFrame:UnregisterEvent"PLAYER_TALENT_UPDATE" |
return true |
end |
end |
local Disable = function(self) |
if(self.Totems) then |
TotemFrame.Show = nil |
TotemFrame:Show() |
TotemFrame:RegisterEvent"PLAYER_TOTEM_UPDATE" |
TotemFrame:RegisterEvent"PLAYER_ENTERING_WORLD" |
TotemFrame:RegisterEvent"UPDATE_SHAPESHIFT_FORM" |
TotemFrame:RegisterEvent"PLAYER_TALENT_UPDATE" |
self:UnregisterEvent('PLAYER_TOTEM_UPDATE', Path) |
end |
end |
oUF:AddElement("Totems", Update, Enable, Disable) |
--[[ Element: Resurrect Icon |
Handles updating and toggles visibility of incoming resurrect icon. |
Widget |
ResurrectIcon - A Texture used to display if the unit has an incoming |
resurrect. |
Notes |
The default resurrect icon will be used if the UI widget is a texture and |
doesn't have a texture or color defined. |
Examples |
-- Position and size |
local ResurrectIcon = self:CreateTexture(nil, 'OVERLAY') |
ResurrectIcon:SetSize(16, 16) |
ResurrectIcon:SetPoint('TOPRIGHT', self) |
-- Register it with oUF |
self.ResurrectIcon = ResurrectIcon |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event) |
local resurrect = self.ResurrectIcon |
if(resurrect.PreUpdate) then |
resurrect:PreUpdate() |
end |
local incomingResurrect = UnitHasIncomingResurrection(self.unit) |
if(incomingResurrect) then |
resurrect:Show() |
else |
resurrect:Hide() |
end |
if(resurrect.PostUpdate) then |
return resurrect:PostUpdate(incomingResurrect) |
end |
end |
local Path = function(self, ...) |
return (self.ResurrectIcon.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self) |
local resurrect = self.ResurrectIcon |
if(resurrect) then |
resurrect.__owner = self |
resurrect.ForceUpdate = ForceUpdate |
self:RegisterEvent('INCOMING_RESURRECT_CHANGED', Path, true) |
if(resurrect:IsObjectType('Texture') and not resurrect:GetTexture()) then |
resurrect:SetTexture[[Interface\RaidFrame\Raid-Icon-Rez]] |
end |
return true |
end |
end |
local Disable = function(self) |
local resurrect = self.ResurrectIcon |
if(resurrect) then |
self:UnregisterEvent('INCOMING_RESURRECT_CHANGED', Path) |
end |
end |
oUF:AddElement('ResurrectIcon', Path, Enable, Disable) |
--[[ Element: Combo Point Icons |
Toggles visibility of the player and vehicles combo points. |
Widget |
CPoints - An array consisting of five UI widgets. |
Notes |
The default combo point texture will be applied to textures within the CPoints |
array that don't have a texture or color defined. |
Examples |
local CPoints = {} |
for index = 1, MAX_COMBO_POINTS do |
local CPoint = self:CreateTexture(nil, 'BACKGROUND') |
-- Position and size of the combo point. |
CPoint:SetSize(12, 16) |
CPoint:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * CPoint:GetWidth(), 0) |
CPoints[index] = CPoint |
end |
-- Register with oUF |
self.CPoints = CPoints |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local GetComboPoints = GetComboPoints |
local MAX_COMBO_POINTS = MAX_COMBO_POINTS |
local Update = function(self, event, unit) |
if(unit == 'pet') then return end |
local cpoints = self.CPoints |
if(cpoints.PreUpdate) then |
cpoints:PreUpdate() |
end |
local cp |
if(UnitHasVehicleUI'player') then |
cp = GetComboPoints('vehicle', 'target') |
else |
cp = GetComboPoints('player', 'target') |
end |
for i=1, MAX_COMBO_POINTS do |
if(i <= cp) then |
cpoints[i]:Show() |
else |
cpoints[i]:Hide() |
end |
end |
if(cpoints.PostUpdate) then |
return cpoints:PostUpdate(cp) |
end |
end |
local Path = function(self, ...) |
return (self.CPoints.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local Enable = function(self) |
local cpoints = self.CPoints |
if(cpoints) then |
cpoints.__owner = self |
cpoints.ForceUpdate = ForceUpdate |
self:RegisterEvent('UNIT_COMBO_POINTS', Path, true) |
self:RegisterEvent('PLAYER_TARGET_CHANGED', Path, true) |
for index = 1, MAX_COMBO_POINTS do |
local cpoint = cpoints[index] |
if(cpoint:IsObjectType'Texture' and not cpoint:GetTexture()) then |
cpoint:SetTexture[[Interface\ComboFrame\ComboPoint]] |
cpoint:SetTexCoord(0, 0.375, 0, 1) |
end |
end |
return true |
end |
end |
local Disable = function(self) |
local cpoints = self.CPoints |
if(cpoints) then |
self:UnregisterEvent('UNIT_COMBO_POINTS', Path) |
self:UnregisterEvent('PLAYER_TARGET_CHANGED', Path) |
end |
end |
oUF:AddElement('CPoints', Path, Enable, Disable) |
--[[ Element: Castbar |
Handles updating and visibility of unit castbars. |
Widget |
Castbar - A StatusBar to represent spell progress. |
Sub-Widgets |
.Text - A FontString to represent spell name. |
.Icon - A Texture to represent spell icon. |
.Time - A FontString to represent spell duration. |
.Shield - A Texture to represent if it's possible to interrupt or spell |
steal. |
.SafeZone - A Texture to represent latency. |
Credits |
Based upon oUF_Castbar by starlon. |
Notes |
The default texture will be applied if the UI widget doesn't have a texture or |
color defined. |
Examples |
-- Position and size |
local Castbar = CreateFrame("StatusBar", nil, self) |
Castbar:SetSize(20, 20) |
Castbar:SetPoint('TOP') |
Castbar:SetPoint('LEFT') |
Castbar:SetPoint('RIGHT') |
-- Add a background |
local Background = Castbar:CreateTexture(nil, 'BACKGROUND') |
Background:SetAllPoints(Castbar) |
Background:SetTexture(1, 1, 1, .5) |
-- Add a spark |
local Spark = Castbar:CreateTexture(nil, "OVERLAY") |
Spark:SetSize(20, 20) |
Spark:SetBlendMode("ADD") |
-- Add a timer |
local Time = Castbar:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") |
Time:SetPoint("RIGHT", Castbar) |
-- Add spell text |
local Text = Castbar:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") |
Text:SetPoint("LEFT", Castbar) |
-- Add spell icon |
local Icon = Castbar:CreateTexture(nil, "OVERLAY") |
Icon:SetSize(20, 20) |
Icon:SetPoint("TOPLEFT", Castbar, "TOPLEFT") |
-- Add Shield |
local Shield = Castbar:CreateTexture(nil, "OVERLAY") |
Shield:SetSize(20, 20) |
Shield:SetPoint("CENTER", Castbar) |
-- Add safezone |
local SafeZone = Castbar:CreateTexture(nil, "OVERLAY") |
-- Register it with oUF |
self.Castbar = Castbar |
self.Castbar.bg = Background |
self.Castbar.Spark = Spark |
self.Castbar.Time = Time |
self.Castbar.Text = Text |
self.Castbar.Icon = Icon |
self.Castbar.SafeZone = SafeZone |
Hooks and Callbacks |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local UnitName = UnitName |
local GetTime = GetTime |
local UnitCastingInfo = UnitCastingInfo |
local UnitChannelInfo = UnitChannelInfo |
local updateSafeZone = function(self) |
local sz = self.SafeZone |
local width = self:GetWidth() |
local _, _, _, ms = GetNetStats() |
-- Guard against GetNetStats returning latencies of 0. |
if(ms ~= 0) then |
-- MADNESS! |
local safeZonePercent = (width / self.max) * (ms / 1e5) |
if(safeZonePercent > 1) then safeZonePercent = 1 end |
sz:SetWidth(width * safeZonePercent) |
sz:Show() |
else |
sz:Hide() |
end |
end |
local UNIT_SPELLCAST_START = function(self, event, unit, spell) |
if(self.unit ~= unit) then return end |
local castbar = self.Castbar |
local name, _, text, texture, startTime, endTime, _, castid, interrupt = UnitCastingInfo(unit) |
if(not name) then |
castbar:Hide() |
return |
end |
endTime = endTime / 1e3 |
startTime = startTime / 1e3 |
local max = endTime - startTime |
castbar.castid = castid |
castbar.duration = GetTime() - startTime |
castbar.max = max |
castbar.delay = 0 |
castbar.casting = true |
castbar.interrupt = interrupt |
castbar:SetMinMaxValues(0, max) |
castbar:SetValue(0) |
if(castbar.Text) then castbar.Text:SetText(text) end |
if(castbar.Icon) then castbar.Icon:SetTexture(texture) end |
if(castbar.Time) then castbar.Time:SetText() end |
local shield = castbar.Shield |
if(shield and interrupt) then |
shield:Show() |
elseif(shield) then |
shield:Hide() |
end |
local sf = castbar.SafeZone |
if(sf) then |
sf:ClearAllPoints() |
sf:SetPoint'RIGHT' |
sf:SetPoint'TOP' |
sf:SetPoint'BOTTOM' |
updateSafeZone(castbar) |
end |
if(castbar.PostCastStart) then |
castbar:PostCastStart(unit, name, castid) |
end |
castbar:Show() |
end |
local UNIT_SPELLCAST_FAILED = function(self, event, unit, spellname, _, castid) |
if(self.unit ~= unit) then return end |
local castbar = self.Castbar |
if(castbar.castid ~= castid) then |
return |
end |
castbar.casting = nil |
castbar.interrupt = nil |
castbar:SetValue(0) |
castbar:Hide() |
if(castbar.PostCastFailed) then |
return castbar:PostCastFailed(unit, spellname, castid) |
end |
end |
local UNIT_SPELLCAST_INTERRUPTED = function(self, event, unit, spellname, _, castid) |
if(self.unit ~= unit) then return end |
local castbar = self.Castbar |
if(castbar.castid ~= castid) then |
return |
end |
castbar.casting = nil |
castbar.channeling = nil |
castbar:SetValue(0) |
castbar:Hide() |
if(castbar.PostCastInterrupted) then |
return castbar:PostCastInterrupted(unit, spellname, castid) |
end |
end |
local UNIT_SPELLCAST_INTERRUPTIBLE = function(self, event, unit) |
if(self.unit ~= unit) then return end |
local shield = self.Castbar.Shield |
if(shield) then |
shield:Hide() |
end |
local castbar = self.Castbar |
if(castbar.PostCastInterruptible) then |
return castbar:PostCastInterruptible(unit) |
end |
end |
local UNIT_SPELLCAST_NOT_INTERRUPTIBLE = function(self, event, unit) |
if(self.unit ~= unit) then return end |
local shield = self.Castbar.Shield |
if(shield) then |
shield:Show() |
end |
local castbar = self.Castbar |
if(castbar.PostCastNotInterruptible) then |
return castbar:PostCastNotInterruptible(unit) |
end |
end |
local UNIT_SPELLCAST_DELAYED = function(self, event, unit, spellname, _, castid) |
if(self.unit ~= unit) then return end |
local castbar = self.Castbar |
local name, _, text, texture, startTime, endTime = UnitCastingInfo(unit) |
if(not startTime or not castbar:IsShown()) then return end |
local duration = GetTime() - (startTime / 1000) |
if(duration < 0) then duration = 0 end |
castbar.delay = castbar.delay + castbar.duration - duration |
castbar.duration = duration |
castbar:SetValue(duration) |
if(castbar.PostCastDelayed) then |
return castbar:PostCastDelayed(unit, name, castid) |
end |
end |
local UNIT_SPELLCAST_STOP = function(self, event, unit, spellname, _, castid) |
if(self.unit ~= unit) then return end |
local castbar = self.Castbar |
if(castbar.castid ~= castid) then |
return |
end |
castbar.casting = nil |
castbar.interrupt = nil |
castbar:SetValue(0) |
castbar:Hide() |
if(castbar.PostCastStop) then |
return castbar:PostCastStop(unit, spellname, castid) |
end |
end |
local UNIT_SPELLCAST_CHANNEL_START = function(self, event, unit, spellname) |
if(self.unit ~= unit) then return end |
local castbar = self.Castbar |
local name, _, text, texture, startTime, endTime, isTrade, interrupt = UnitChannelInfo(unit) |
if(not name) then |
return |
end |
endTime = endTime / 1e3 |
startTime = startTime / 1e3 |
local max = (endTime - startTime) |
local duration = endTime - GetTime() |
castbar.duration = duration |
castbar.max = max |
castbar.delay = 0 |
castbar.channeling = true |
castbar.interrupt = interrupt |
-- We have to do this, as it's possible for spell casts to never have _STOP |
-- executed or be fully completed by the OnUpdate handler before CHANNEL_START |
-- is called. |
castbar.casting = nil |
castbar.castid = nil |
castbar:SetMinMaxValues(0, max) |
castbar:SetValue(duration) |
if(castbar.Text) then castbar.Text:SetText(name) end |
if(castbar.Icon) then castbar.Icon:SetTexture(texture) end |
if(castbar.Time) then castbar.Time:SetText() end |
local shield = castbar.Shield |
if(shield and interrupt) then |
shield:Show() |
elseif(shield) then |
shield:Hide() |
end |
local sf = castbar.SafeZone |
if(sf) then |
sf:ClearAllPoints() |
sf:SetPoint'LEFT' |
sf:SetPoint'TOP' |
sf:SetPoint'BOTTOM' |
updateSafeZone(castbar) |
end |
if(castbar.PostChannelStart) then castbar:PostChannelStart(unit, name) end |
castbar:Show() |
end |
local UNIT_SPELLCAST_CHANNEL_UPDATE = function(self, event, unit, spellname) |
if(self.unit ~= unit) then return end |
local castbar = self.Castbar |
local name, _, text, texture, startTime, endTime, oldStart = UnitChannelInfo(unit) |
if(not name or not castbar:IsShown()) then |
return |
end |
local duration = (endTime / 1000) - GetTime() |
castbar.delay = castbar.delay + castbar.duration - duration |
castbar.duration = duration |
castbar.max = (endTime - startTime) / 1000 |
castbar:SetMinMaxValues(0, castbar.max) |
castbar:SetValue(duration) |
if(castbar.PostChannelUpdate) then |
return castbar:PostChannelUpdate(unit, name) |
end |
end |
local UNIT_SPELLCAST_CHANNEL_STOP = function(self, event, unit, spellname) |
if(self.unit ~= unit) then return end |
local castbar = self.Castbar |
if(castbar:IsShown()) then |
castbar.channeling = nil |
castbar.interrupt = nil |
castbar:SetValue(castbar.max) |
castbar:Hide() |
if(castbar.PostChannelStop) then |
return castbar:PostChannelStop(unit, spellname) |
end |
end |
end |
local onUpdate = function(self, elapsed) |
if(self.casting) then |
local duration = self.duration + elapsed |
if(duration >= self.max) then |
self.casting = nil |
self:Hide() |
if(self.PostCastStop) then self:PostCastStop(self.__owner.unit) end |
return |
end |
if(self.Time) then |
if(self.delay ~= 0) then |
if(self.CustomDelayText) then |
self:CustomDelayText(duration) |
else |
self.Time:SetFormattedText("%.1f|cffff0000-%.1f|r", duration, self.delay) |
end |
else |
if(self.CustomTimeText) then |
self:CustomTimeText(duration) |
else |
self.Time:SetFormattedText("%.1f", duration) |
end |
end |
end |
self.duration = duration |
self:SetValue(duration) |
if(self.Spark) then |
self.Spark:SetPoint("CENTER", self, "LEFT", (duration / self.max) * self:GetWidth(), 0) |
end |
elseif(self.channeling) then |
local duration = self.duration - elapsed |
if(duration <= 0) then |
self.channeling = nil |
self:Hide() |
if(self.PostChannelStop) then self:PostChannelStop(self.__owner.unit) end |
return |
end |
if(self.Time) then |
if(self.delay ~= 0) then |
if(self.CustomDelayText) then |
self:CustomDelayText(duration) |
else |
self.Time:SetFormattedText("%.1f|cffff0000-%.1f|r", duration, self.delay) |
end |
else |
if(self.CustomTimeText) then |
self:CustomTimeText(duration) |
else |
self.Time:SetFormattedText("%.1f", duration) |
end |
end |
end |
self.duration = duration |
self:SetValue(duration) |
if(self.Spark) then |
self.Spark:SetPoint("CENTER", self, "LEFT", (duration / self.max) * self:GetWidth(), 0) |
end |
else |
self.unitName = nil |
self.casting = nil |
self.castid = nil |
self.channeling = nil |
self:SetValue(1) |
self:Hide() |
end |
end |
local Update = function(self, ...) |
UNIT_SPELLCAST_START(self, ...) |
return UNIT_SPELLCAST_CHANNEL_START(self, ...) |
end |
local ForceUpdate = function(element) |
return Update(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local Enable = function(object, unit) |
local castbar = object.Castbar |
if(castbar) then |
castbar.__owner = object |
castbar.ForceUpdate = ForceUpdate |
if(not (unit and unit:match'%wtarget$')) then |
object:RegisterEvent("UNIT_SPELLCAST_START", UNIT_SPELLCAST_START) |
object:RegisterEvent("UNIT_SPELLCAST_FAILED", UNIT_SPELLCAST_FAILED) |
object:RegisterEvent("UNIT_SPELLCAST_STOP", UNIT_SPELLCAST_STOP) |
object:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED", UNIT_SPELLCAST_INTERRUPTED) |
object:RegisterEvent("UNIT_SPELLCAST_INTERRUPTIBLE", UNIT_SPELLCAST_INTERRUPTIBLE) |
object:RegisterEvent("UNIT_SPELLCAST_NOT_INTERRUPTIBLE", UNIT_SPELLCAST_NOT_INTERRUPTIBLE) |
object:RegisterEvent("UNIT_SPELLCAST_DELAYED", UNIT_SPELLCAST_DELAYED) |
object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START", UNIT_SPELLCAST_CHANNEL_START) |
object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", UNIT_SPELLCAST_CHANNEL_UPDATE) |
object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", UNIT_SPELLCAST_CHANNEL_STOP) |
end |
castbar:SetScript("OnUpdate", castbar.OnUpdate or onUpdate) |
if(object.unit == "player") then |
CastingBarFrame:UnregisterAllEvents() |
CastingBarFrame.Show = CastingBarFrame.Hide |
CastingBarFrame:Hide() |
elseif(object.unit == 'pet') then |
PetCastingBarFrame:UnregisterAllEvents() |
PetCastingBarFrame.Show = PetCastingBarFrame.Hide |
PetCastingBarFrame:Hide() |
end |
if(castbar:IsObjectType'StatusBar' and not castbar:GetStatusBarTexture()) then |
castbar:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] |
end |
local spark = castbar.Spark |
if(spark and spark:IsObjectType'Texture' and not spark:GetTexture()) then |
spark:SetTexture[[Interface\CastingBar\UI-CastingBar-Spark]] |
end |
local shield = castbar.Shield |
if(shield and shield:IsObjectType'Texture' and not shield:GetTexture()) then |
shield:SetTexture[[Interface\CastingBar\UI-CastingBar-Small-Shield]] |
end |
local sz = castbar.SafeZone |
if(sz and sz:IsObjectType'Texture' and not sz:GetTexture()) then |
sz:SetTexture(1, 0, 0) |
end |
castbar:Hide() |
return true |
end |
end |
local Disable = function(object, unit) |
local castbar = object.Castbar |
if(castbar) then |
object:UnregisterEvent("UNIT_SPELLCAST_START", UNIT_SPELLCAST_START) |
object:UnregisterEvent("UNIT_SPELLCAST_FAILED", UNIT_SPELLCAST_FAILED) |
object:UnregisterEvent("UNIT_SPELLCAST_STOP", UNIT_SPELLCAST_STOP) |
object:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED", UNIT_SPELLCAST_INTERRUPTED) |
object:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTIBLE", UNIT_SPELLCAST_INTERRUPTIBLE) |
object:UnregisterEvent("UNIT_SPELLCAST_NOT_INTERRUPTIBLE", UNIT_SPELLCAST_NOT_INTERRUPTIBLE) |
object:UnregisterEvent("UNIT_SPELLCAST_DELAYED", UNIT_SPELLCAST_DELAYED) |
object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_START", UNIT_SPELLCAST_CHANNEL_START) |
object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", UNIT_SPELLCAST_CHANNEL_UPDATE) |
object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", UNIT_SPELLCAST_CHANNEL_STOP) |
castbar:SetScript("OnUpdate", nil) |
end |
end |
oUF:AddElement('Castbar', Update, Enable, Disable) |
--[[ Element: Master Looter Icon |
Toggles visibility of the master looter icon. |
Widget |
MasterLooter - Any UI widget. |
Notes |
The default master looter icon will be applied if the UI widget is a texture |
and doesn't have a texture or color defined. |
Examples |
-- Position and size |
local MasterLooter = self:CreateTexture(nil, 'OVERLAY') |
MasterLooter:SetSize(16, 16) |
MasterLooter:SetPoint('TOPRIGHT', self) |
-- Register it with oUF |
self.MasterLooter = MasterLooter |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event) |
local unit = self.unit |
local masterlooter = self.MasterLooter |
if(not (UnitInParty(unit) or UnitInRaid(unit))) then |
return masterlooter:Hide() |
end |
if(masterlooter.PreUpdate) then |
masterlooter:PreUpdate() |
end |
local method, pid, rid = GetLootMethod() |
if(method == 'master') then |
local mlUnit |
if(pid) then |
if(pid == 0) then |
mlUnit = 'player' |
else |
mlUnit = 'party'..pid |
end |
elseif(rid) then |
mlUnit = 'raid'..rid |
end |
if(UnitIsUnit(unit, mlUnit)) then |
masterlooter:Show() |
elseif(masterlooter:IsShown()) then |
masterlooter:Hide() |
end |
else |
masterlooter:Hide() |
end |
if(masterlooter.PostUpdate) then |
return masterlooter:PostUpdate(masterlooter:IsShown()) |
end |
end |
local Path = function(self, ...) |
return (self.MasterLooter.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate') |
end |
local function Enable(self, unit) |
local masterlooter = self.MasterLooter |
if(masterlooter) then |
masterlooter.__owner = self |
masterlooter.ForceUpdate = ForceUpdate |
self:RegisterEvent('PARTY_LOOT_METHOD_CHANGED', Path, true) |
self:RegisterEvent('GROUP_ROSTER_UPDATE', Path, true) |
if(masterlooter:IsObjectType('Texture') and not masterlooter:GetTexture()) then |
masterlooter:SetTexture([[Interface\GroupFrame\UI-Group-MasterLooter]]) |
end |
return true |
end |
end |
local function Disable(self) |
if(self.MasterLooter) then |
self:UnregisterEvent('PARTY_LOOT_METHOD_CHANGED', Path) |
self:UnregisterEvent('GROUP_ROSTER_UPDATE', Path) |
end |
end |
oUF:AddElement('MasterLooter', Path, Enable, Disable) |
--[[ Element: Alternative Power Bar |
Handles visibility and updating of the alternative power bar. |
This bar is used to display encounter/quest related power information, such as |
the number of hour glass uses left on the end boss in End Time. |
Widget |
AltPowerBar - A StatusBar to represent alternative power. |
Options |
.colorTexture - Use the vertex color values returned by |
UnitAlternatePowerTextureInfo to color the bar. |
Notes |
OnEnter and OnLeave handlers to display a tooltip will be set on the widget if |
it is mouse enabled. |
Examples |
-- Position and size |
local AltPowerBar = CreateFrame('StatusBar', nil, self) |
AltPowerBar:SetHeight(20) |
AltPowerBar:SetPoint('BOTTOM') |
AltPowerBar:SetPoint('LEFT') |
AltPowerBar:SetPoint('RIGHT') |
-- Register with oUF |
self.AltPowerBar = AltPowerBar |
Callbacks |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local ALTERNATE_POWER_INDEX = ALTERNATE_POWER_INDEX |
--[[ :UpdateTooltip() |
The function called when the widget is hovered. Used to populate the tooltip. |
Arguments |
self - The AltPowerBar element. |
]] |
local UpdateTooltip = function(self) |
GameTooltip:SetText(self.powerName, 1, 1, 1) |
GameTooltip:AddLine(self.powerTooltip, nil, nil, nil, 1) |
GameTooltip:Show() |
end |
local OnEnter = function(self) |
if(not self:IsVisible()) then return end |
GameTooltip_SetDefaultAnchor(GameTooltip, self) |
self:UpdateTooltip() |
end |
local OnLeave = function() |
GameTooltip:Hide() |
end |
local UpdatePower = function(self, event, unit, powerType) |
if(self.unit ~= unit or powerType ~= 'ALTERNATE') then return end |
local altpowerbar = self.AltPowerBar |
--[[ :PreUpdate() |
Called before the element has been updated. |
Arguments |
self - The AltPowerBar element. |
]] |
if(altpowerbar.PreUpdate) then |
altpowerbar:PreUpdate() |
end |
local _, r, g, b |
if(altpowerbar.colorTexture) then |
_, r, g, b = UnitAlternatePowerTextureInfo(unit, 2) |
end |
local cur = UnitPower(unit, ALTERNATE_POWER_INDEX) |
local max = UnitPowerMax(unit, ALTERNATE_POWER_INDEX) |
local barType, min, _, _, _, _, _, _, _, powerName, powerTooltip = UnitAlternatePowerInfo(unit) |
altpowerbar.barType = barType |
altpowerbar.powerName = powerName |
altpowerbar.powerTooltip = powerTooltip |
altpowerbar:SetMinMaxValues(min, max) |
altpowerbar:SetValue(cur) |
if(b) then |
altpowerbar:SetStatusBarColor(r, g, b) |
end |
--[[ :PostUpdate(min, cur, max) |
Called after the element has been updated. |
Arguments |
self - The AltPowerBar element. |
min - The minimum possible power value for the active type. |
cur - The current power value. |
max - The maximum possible power value for the active type. |
]] |
if(altpowerbar.PostUpdate) then |
return altpowerbar:PostUpdate(min, cur, max) |
end |
end |
local ForceUpdate = function(element) |
return UpdatePower(element.__owner, 'ForceUpdate', element.__owner.unit, 'ALTERNATE') |
end |
local Toggler = function(self, event, unit) |
if(unit ~= self.unit) then return end |
local altpowerbar = self.AltPowerBar |
local barType, minPower, _, _, _, hideFromOthers = UnitAlternatePowerInfo(unit) |
if(barType and (not hideFromOthers or unit == 'player' or self.realUnit == 'player')) then |
self:RegisterEvent('UNIT_POWER', UpdatePower) |
self:RegisterEvent('UNIT_MAXPOWER', UpdatePower) |
ForceUpdate(altpowerbar) |
altpowerbar:Show() |
else |
self:UnregisterEvent('UNIT_POWER', UpdatePower) |
self:UnregisterEvent('UNIT_MAXPOWER', UpdatePower) |
altpowerbar:Hide() |
end |
end |
local Enable = function(self, unit) |
local altpowerbar = self.AltPowerBar |
if(altpowerbar) then |
altpowerbar.__owner = self |
altpowerbar.ForceUpdate = ForceUpdate |
self:RegisterEvent('UNIT_POWER_BAR_SHOW', Toggler) |
self:RegisterEvent('UNIT_POWER_BAR_HIDE', Toggler) |
altpowerbar:Hide() |
if(altpowerbar:IsMouseEnabled()) then |
if(not altpowerbar:HasScript('OnEnter')) then |
altpowerbar:SetScript('OnEnter', OnEnter) |
end |
altpowerbar:SetScript('OnLeave', OnLeave) |
if(not altpowerbar.UpdateTooltip) then |
altpowerbar.UpdateTooltip = UpdateTooltip |
end |
end |
if(unit == 'player') then |
PlayerPowerBarAlt:UnregisterEvent'UNIT_POWER_BAR_SHOW' |
PlayerPowerBarAlt:UnregisterEvent'UNIT_POWER_BAR_HIDE' |
PlayerPowerBarAlt:UnregisterEvent'PLAYER_ENTERING_WORLD' |
end |
return true |
end |
end |
local Disable = function(self, unit) |
local altpowerbar = self.AltPowerBar |
if(altpowerbar) then |
self:UnregisterEvent('UNIT_POWER_BAR_SHOW', Toggler) |
self:UnregisterEvent('UNIT_POWER_BAR_HIDE', Toggler) |
if(unit == 'player') then |
PlayerPowerBarAlt:RegisterEvent'UNIT_POWER_BAR_SHOW' |
PlayerPowerBarAlt:RegisterEvent'UNIT_POWER_BAR_HIDE' |
PlayerPowerBarAlt:RegisterEvent'PLAYER_ENTERING_WORLD' |
end |
end |
end |
oUF:AddElement('AltPowerBar', Toggler, Enable, Disable) |
--[[ Element: Threat Icon |
Handles updating and toggles visibility of current threat level icon. |
Widget |
Threat - A Texture used to display the current threat level. |
Notes |
This element updates by changing colors of the texture. |
The default threat icon will be used if the UI widget is a texture and doesn't |
have a texture or color defined. |
Examples |
-- Position and size |
local Threat = self:CreateTexture(nil, 'OVERLAY') |
Threat:SetSize(16, 16) |
Threat:SetPoint('TOPRIGHT', self) |
-- Register it with oUF |
self.Threat = Threat |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event, unit) |
if(unit ~= self.unit) then return end |
local threat = self.Threat |
if(threat.PreUpdate) then threat:PreUpdate(unit) end |
unit = unit or self.unit |
local status = UnitThreatSituation(unit) |
local r, g, b |
if(status and status > 0) then |
r, g, b = GetThreatStatusColor(status) |
threat:SetVertexColor(r, g, b) |
threat:Show() |
else |
threat:Hide() |
end |
if(threat.PostUpdate) then |
return threat:PostUpdate(unit, status, r, g, b) |
end |
end |
local Path = function(self, ...) |
return (self.Threat.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local Enable = function(self) |
local threat = self.Threat |
if(threat) then |
threat.__owner = self |
threat.ForceUpdate = ForceUpdate |
self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE", Path) |
if(threat:IsObjectType"Texture" and not threat:GetTexture()) then |
threat:SetTexture[[Interface\Minimap\ObjectIcons]] |
threat:SetTexCoord(6/8, 7/8, 1/8, 2/8) |
end |
threat:Hide() |
return true |
end |
end |
local Disable = function(self) |
local threat = self.Threat |
if(threat) then |
self:UnregisterEvent("UNIT_THREAT_SITUATION_UPDATE", Path) |
end |
end |
oUF:AddElement('Threat', Path, Enable, Disable) |
--[[ Element: LFD Role Icon |
Toggles visibility of the LFD role icon based upon the units current dungeon |
role. |
Widget |
LFDRole - A Texture containing the LFD role icons at specific locations. Look |
at the default LFD role icon texture for an example of this. |
Alternatively you can look at the return values of |
GetTexCoordsForRoleSmallCircle(role). |
Notes |
The default LFD role texture will be applied if the UI widget is a texture and |
doesn't have a texture or color defined. |
Examples |
-- Position and size |
local LFDRole = self:CreateTexture(nil, "OVERLAY") |
LFDRole:SetSize(16, 16) |
LFDRole:SetPoint("LEFT", self) |
-- Register it with oUF |
self.LFDRole = LFDRole |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event) |
local lfdrole = self.LFDRole |
if(lfdrole.PreUpdate) then |
lfdrole:PreUpdate() |
end |
local role = UnitGroupRolesAssigned(self.unit) |
if(role == 'TANK' or role == 'HEALER' or role == 'DAMAGER') then |
lfdrole:SetTexCoord(GetTexCoordsForRoleSmallCircle(role)) |
lfdrole:Show() |
else |
lfdrole:Hide() |
end |
if(lfdrole.PostUpdate) then |
return lfdrole:PostUpdate(role) |
end |
end |
local Path = function(self, ...) |
return (self.LFDRole.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self) |
local lfdrole = self.LFDRole |
if(lfdrole) then |
lfdrole.__owner = self |
lfdrole.ForceUpdate = ForceUpdate |
if(self.unit == "player") then |
self:RegisterEvent("PLAYER_ROLES_ASSIGNED", Path, true) |
else |
self:RegisterEvent("GROUP_ROSTER_UPDATE", Path, true) |
end |
if(lfdrole:IsObjectType"Texture" and not lfdrole:GetTexture()) then |
lfdrole:SetTexture[[Interface\LFGFrame\UI-LFG-ICON-PORTRAITROLES]] |
end |
return true |
end |
end |
local Disable = function(self) |
local lfdrole = self.LFDRole |
if(lfdrole) then |
self:UnregisterEvent("PLAYER_ROLES_ASSIGNED", Path) |
self:UnregisterEvent("GROUP_ROSTER_UPDATE", Path) |
end |
end |
oUF:AddElement('LFDRole', Path, Enable, Disable) |
--[[ Element: Portraits |
Handles updating of the unit's portrait. |
Widget |
Portrait - A PlayerModel or Texture used to represent the unit's portrait. |
Notes |
The quest delivery question mark will be used instead of the unit's model when |
the client doesn't have the model information for the unit. |
Examples |
-- 3D Portrait |
-- Position and size |
local Portrait = CreateFrame('PlayerModel', nil, self) |
Portrait:SetSize(32, 32) |
Portrait:SetPoint('RIGHT', self, 'LEFT') |
-- Register it with oUF |
self.Portrait = Portrait |
-- 2D Portrait |
local Portrait = self:CreateTexture(nil, 'OVERLAY') |
Portrait:SetSize(32, 32) |
Portrait:SetPoint('RIGHT', self, 'LEFT') |
-- Register it with oUF |
self.Portrait = Portrait |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event, unit) |
if(not unit or not UnitIsUnit(self.unit, unit)) then return end |
local portrait = self.Portrait |
if(portrait.PreUpdate) then portrait:PreUpdate(unit) end |
if(portrait:IsObjectType'Model') then |
local guid = UnitGUID(unit) |
if(not UnitExists(unit) or not UnitIsConnected(unit) or not UnitIsVisible(unit)) then |
portrait:SetCamDistanceScale(0.25) |
portrait:SetPortraitZoom(0) |
portrait:SetPosition(0,0,0.5) |
portrait:ClearModel() |
portrait:SetModel('interface\\buttons\\talktomequestionmark.m2') |
portrait.guid = nil |
elseif(portrait.guid ~= guid or event == 'UNIT_MODEL_CHANGED') then |
portrait:SetCamDistanceScale(1) |
portrait:SetPortraitZoom(1) |
portrait:SetPosition(0,0,0) |
portrait:ClearModel() |
portrait:SetUnit(unit) |
portrait.guid = guid |
end |
else |
SetPortraitTexture(portrait, unit) |
end |
if(portrait.PostUpdate) then |
return portrait:PostUpdate(unit) |
end |
end |
local Path = function(self, ...) |
return (self.Portrait.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local Enable = function(self, unit) |
local portrait = self.Portrait |
if(portrait) then |
portrait.__owner = self |
portrait.ForceUpdate = ForceUpdate |
self:RegisterEvent("UNIT_PORTRAIT_UPDATE", Path) |
self:RegisterEvent("UNIT_MODEL_CHANGED", Path) |
self:RegisterEvent('UNIT_CONNECTION', Path) |
-- The quest log uses PARTY_MEMBER_{ENABLE,DISABLE} to handle updating of |
-- party members overlapping quests. This will probably be enough to handle |
-- model updating. |
-- |
-- DISABLE isn't used as it fires when we most likely don't have the |
-- information we want. |
if(unit == 'party') then |
self:RegisterEvent('PARTY_MEMBER_ENABLE', Path) |
end |
return true |
end |
end |
local Disable = function(self) |
local portrait = self.Portrait |
if(portrait) then |
self:UnregisterEvent("UNIT_PORTRAIT_UPDATE", Path) |
self:UnregisterEvent("UNIT_MODEL_CHANGED", Path) |
self:UnregisterEvent('PARTY_MEMBER_ENABLE', Path) |
self:UnregisterEvent('UNIT_CONNECTION', Path) |
end |
end |
oUF:AddElement('Portrait', Path, Enable, Disable) |
--[[ Element: Auras |
Handles creation and updating of aura icons. |
Widget |
Auras - A Frame to hold icons representing both buffs and debuffs. |
Buffs - A Frame to hold icons representing buffs. |
Debuffs - A Frame to hold icons representing debuffs. |
Options |
.disableCooldown - Disables the cooldown spiral. Defaults to false. |
.size - Aura icon size. Defaults to 16. |
.onlyShowPlayer - Only show auras created by player/vehicle. |
.showStealableBuffs - Display the stealable texture on buffs that can be |
stolen. |
.spacing - Spacing between each icon. Defaults to 0. |
.['spacing-x'] - Horizontal spacing between each icon. Takes priority over |
`spacing`. |
.['spacing-y'] - Vertical spacing between each icon. Takes priority over |
`spacing`. |
.['growth-x'] - Horizontal growth direction. Defaults to RIGHT. |
.['growth-y'] - Vertical growth direction. Defaults to UP. |
.initialAnchor - Anchor point for the icons. Defaults to BOTTOMLEFT. |
.filter - Custom filter list for auras to display. Defaults to |
HELPFUL on buffs and HARMFUL on debuffs. |
Options Auras |
.numBuffs - The maximum number of buffs to display. Defaults to 32. |
.numDebuffs - The maximum number of debuffs to display. Defaults to 40. |
.gap - Controls the creation of an invisible icon between buffs and |
debuffs. Defaults to false. |
.buffFilter - Custom filter list for buffs to display. Takes priority over |
`filter`. |
.debuffFilter - Custom filter list for debuffs to display. Takes priority over |
`filter`. |
Options Buffs |
.num - Number of buffs to display. Defaults to 32. |
Options Debuffs |
.num - Number of debuffs to display. Defaults to 40. |
Examples |
-- Position and size |
local Buffs = CreateFrame("Frame", nil, self) |
Buffs:SetPoint("RIGHT", self, "LEFT") |
Buffs:SetSize(16 * 2, 16 * 16) |
-- Register with oUF |
self.Buffs = Buffs |
Hooks and Callbacks |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local VISIBLE = 1 |
local HIDDEN = 0 |
local UpdateTooltip = function(self) |
GameTooltip:SetUnitAura(self:GetParent().__owner.unit, self:GetID(), self.filter) |
end |
local OnEnter = function(self) |
if(not self:IsVisible()) then return end |
GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT") |
self:UpdateTooltip() |
end |
local OnLeave = function() |
GameTooltip:Hide() |
end |
local createAuraIcon = function(icons, index) |
icons.createdIcons = icons.createdIcons + 1 |
local button = CreateFrame("Button", nil, icons) |
button:RegisterForClicks'RightButtonUp' |
local cd = CreateFrame("Cooldown", nil, button) |
cd:SetAllPoints(button) |
local icon = button:CreateTexture(nil, "BORDER") |
icon:SetAllPoints(button) |
local count = button:CreateFontString(nil, "OVERLAY") |
count:SetFontObject(NumberFontNormal) |
count:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -1, 0) |
local overlay = button:CreateTexture(nil, "OVERLAY") |
overlay:SetTexture"Interface\\Buttons\\UI-Debuff-Overlays" |
overlay:SetAllPoints(button) |
overlay:SetTexCoord(.296875, .5703125, 0, .515625) |
button.overlay = overlay |
local stealable = button:CreateTexture(nil, 'OVERLAY') |
stealable:SetTexture[[Interface\TargetingFrame\UI-TargetingFrame-Stealable]] |
stealable:SetPoint('TOPLEFT', -3, 3) |
stealable:SetPoint('BOTTOMRIGHT', 3, -3) |
stealable:SetBlendMode'ADD' |
button.stealable = stealable |
button.UpdateTooltip = UpdateTooltip |
button:SetScript("OnEnter", OnEnter) |
button:SetScript("OnLeave", OnLeave) |
table.insert(icons, button) |
button.icon = icon |
button.count = count |
button.cd = cd |
--[[ :PostCreateIcon(button) |
Callback which is called after a new aura icon button has been created. |
Arguments |
button - The newly created aura icon button. |
]] |
if(icons.PostCreateIcon) then icons:PostCreateIcon(button) end |
return button |
end |
local customFilter = function(icons, unit, icon, name, rank, texture, count, dtype, duration, timeLeft, caster) |
if((icons.onlyShowPlayer and icon.isPlayer) or (not icons.onlyShowPlayer and name)) then |
return true |
end |
end |
local updateIcon = function(unit, icons, index, offset, filter, isDebuff, visible) |
local name, rank, texture, count, dtype, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff = UnitAura(unit, index, filter) |
if(name) then |
local n = visible + offset + 1 |
local icon = icons[n] |
if(not icon) then |
--[[ :CreateIcon(index) |
A function which creates the aura icon for a given index. |
Arguments |
index - The offset the icon should be created at. |
Returns |
A button used to represent aura icons. |
]] |
icon = (icons.CreateIcon or createAuraIcon) (icons, n) |
end |
local isPlayer |
if(caster == 'player' or caster == 'vehicle') then |
isPlayer = true |
end |
icon.owner = caster |
icon.filter = filter |
icon.isDebuff = isDebuff |
icon.isPlayer = isPlayer |
--[[ :CustomFilter(unit, icon, ...) |
Defines a custom filter which controls if the aura icon should be shown |
or not. |
Arguments |
self - The widget that holds the aura icon. |
unit - The unit that has the aura. |
icon - The button displaying the aura. |
... - The return values from |
[UnitAura](http://wowprogramming.com/docs/api/UnitAura). |
Returns |
A boolean value telling the aura element if it should be show the icon |
or not. |
]] |
local show = (icons.CustomFilter or customFilter) (icons, unit, icon, name, rank, texture, count, dtype, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff) |
if(show) then |
-- We might want to consider delaying the creation of an actual cooldown |
-- object to this point, but I think that will just make things needlessly |
-- complicated. |
local cd = icon.cd |
if(cd and not icons.disableCooldown) then |
if(duration and duration > 0) then |
cd:SetCooldown(timeLeft - duration, duration) |
cd:Show() |
else |
cd:Hide() |
end |
end |
if((isDebuff and icons.showDebuffType) or (not isDebuff and icons.showBuffType) or icons.showType) then |
local color = DebuffTypeColor[dtype] or DebuffTypeColor.none |
icon.overlay:SetVertexColor(color.r, color.g, color.b) |
icon.overlay:Show() |
else |
icon.overlay:Hide() |
end |
local stealable = not isDebuff and isStealable |
if(stealable and icons.showStealableBuffs and not UnitIsUnit('player', unit)) then |
icon.stealable:Show() |
else |
icon.stealable:Hide() |
end |
icon.icon:SetTexture(texture) |
icon.count:SetText((count > 1 and count)) |
local size = icons.size or 16 |
icon:SetSize(size, size) |
icon:EnableMouse(true) |
icon:SetID(index) |
icon:Show() |
--[[ :PostUpdateIcon(unit, icon, index, offest) |
Callback which is called after the aura icon was updated. |
Arguments |
self - The widget that holds the aura icon. |
unit - The unit that has the aura. |
icon - The button that was updated. |
index - The index of the aura. |
offset - The offset the button was created at. |
]] |
if(icons.PostUpdateIcon) then |
icons:PostUpdateIcon(unit, icon, index, n) |
end |
return VISIBLE |
else |
return HIDDEN |
end |
end |
end |
--[[ :SetPosition(from, to) |
Function used to (re-)anchor aura icons. This function is only called when |
new aura icons have been created or if :PreSetPosition is defined. |
Arguments |
self - The widget that holds the aura icons. |
from - The aura icon before the new aura icon. |
to - The current number of created icons. |
]] |
local SetPosition = function(icons, from, to) |
local sizex = (icons.size or 16) + (icons['spacing-x'] or icons.spacing or 0) |
local sizey = (icons.size or 16) + (icons['spacing-y'] or icons.spacing or 0) |
local anchor = icons.initialAnchor or "BOTTOMLEFT" |
local growthx = (icons["growth-x"] == "LEFT" and -1) or 1 |
local growthy = (icons["growth-y"] == "DOWN" and -1) or 1 |
local cols = math.floor(icons:GetWidth() / sizex + .5) |
for i = from, to do |
local button = icons[i] |
-- Bail out if the to range is out of scope. |
if(not button) then break end |
local col = (i - 1) % cols |
local row = math.floor((i - 1) / cols) |
button:ClearAllPoints() |
button:SetPoint(anchor, icons, anchor, col * sizex * growthx, row * sizey * growthy) |
end |
end |
local filterIcons = function(unit, icons, filter, limit, isDebuff, offset, dontHide) |
if(not offset) then offset = 0 end |
local index = 1 |
local visible = 0 |
local hidden = 0 |
while(visible < limit) do |
local result = updateIcon(unit, icons, index, offset, filter, isDebuff, visible) |
if(not result) then |
break |
elseif(result == VISIBLE) then |
visible = visible + 1 |
elseif(result == HIDDEN) then |
hidden = hidden + 1 |
end |
index = index + 1 |
end |
if(not dontHide) then |
for i = visible + offset + 1, #icons do |
icons[i]:Hide() |
end |
end |
return visible, hidden |
end |
local UpdateAuras = function(self, event, unit) |
if(self.unit ~= unit) then return end |
local auras = self.Auras |
if(auras) then |
if(auras.PreUpdate) then auras:PreUpdate(unit) end |
local numBuffs = auras.numBuffs or 32 |
local numDebuffs = auras.numDebuffs or 40 |
local max = numBuffs + numDebuffs |
local visibleBuffs, hiddenBuffs = filterIcons(unit, auras, auras.buffFilter or auras.filter or 'HELPFUL', numBuffs, nil, 0, true) |
auras.visibleBuffs = visibleBuffs |
local hasGap |
if(visibleBuffs ~= 0 and auras.gap) then |
hasGap = true |
visibleBuffs = visibleBuffs + 1 |
local icon = auras[visibleBuffs] or (auras.CreateIcon or createAuraIcon) (auras, visibleBuffs) |
-- Prevent the icon from displaying anything. |
if(icon.cd) then icon.cd:Hide() end |
icon:EnableMouse(false) |
icon.icon:SetTexture() |
icon.overlay:Hide() |
icon.stealable:Hide() |
icon.count:SetText() |
icon:Show() |
--[[ :PostUpdateGapIcon(unit, icon, visibleBuffs) |
Callback which is called after an invisible aura icon has been |
created. This is only used by Auras when the `gap` option is enabled. |
Arguments |
self - The widget that holds the aura icon. |
unit - The unit that has the aura icon. |
icon - The invisible aura icon / gap. |
visibleBuffs - The number of currently visible buffs. |
]] |
if(auras.PostUpdateGapIcon) then |
auras:PostUpdateGapIcon(unit, icon, visibleBuffs) |
end |
end |
local visibleDebuffs, hiddenDebuffs = filterIcons(unit, auras, auras.debuffFilter or auras.filter or 'HARMFUL', numDebuffs, true, visibleBuffs) |
auras.visibleDebuffs = visibleDebuffs |
if(hasGap and visibleDebuffs == 0) then |
auras[visibleBuffs]:Hide() |
visibleBuffs = visibleBuffs - 1 |
end |
auras.visibleAuras = auras.visibleBuffs + auras.visibleDebuffs |
local fromRange, toRange |
if(auras.PreSetPosition) then |
fromRange, toRange = auras:PreSetPosition(max) |
end |
if(fromRange or auras.createdIcons > auras.anchoredIcons) then |
(auras.SetPosition or SetPosition) (auras, fromRange or auras.anchoredIcons + 1, toRange or auras.createdIcons) |
auras.anchoredIcons = auras.createdIcons |
end |
if(auras.PostUpdate) then auras:PostUpdate(unit) end |
end |
local buffs = self.Buffs |
if(buffs) then |
if(buffs.PreUpdate) then buffs:PreUpdate(unit) end |
local numBuffs = buffs.num or 32 |
local visibleBuffs, hiddenBuffs = filterIcons(unit, buffs, buffs.filter or 'HELPFUL', numBuffs) |
buffs.visibleBuffs = visibleBuffs |
local fromRange, toRange |
if(buffs.PreSetPosition) then |
fromRange, toRange = buffs:PreSetPosition(numBuffs) |
end |
if(fromRange or buffs.createdIcons > buffs.anchoredIcons) then |
(buffs.SetPosition or SetPosition) (buffs, fromRange or buffs.anchoredIcons + 1, toRange or buffs.createdIcons) |
buffs.anchoredIcons = buffs.createdIcons |
end |
if(buffs.PostUpdate) then buffs:PostUpdate(unit) end |
end |
local debuffs = self.Debuffs |
if(debuffs) then |
if(debuffs.PreUpdate) then debuffs:PreUpdate(unit) end |
local numDebuffs = debuffs.num or 40 |
local visibleDebuffs, hiddenDebuffs = filterIcons(unit, debuffs, debuffs.filter or 'HARMFUL', numDebuffs, true) |
debuffs.visibleDebuffs = visibleDebuffs |
local fromRange, toRange |
if(debuffs.PreSetPosition) then |
fromRange, toRange = debuffs:PreSetPosition(numDebuffs) |
end |
if(fromRange or debuffs.createdIcons > debuffs.anchoredIcons) then |
(debuffs.SetPosition or SetPosition) (debuffs, fromRange or debuffs.anchoredIcons + 1, toRange or debuffs.createdIcons) |
debuffs.anchoredIcons = debuffs.createdIcons |
end |
if(debuffs.PostUpdate) then debuffs:PostUpdate(unit) end |
end |
end |
local Update = function(self, event, unit) |
if(self.unit ~= unit) then return end |
UpdateAuras(self, event, unit) |
-- Assume no event means someone wants to re-anchor things. This is usually |
-- done by UpdateAllElements and :ForceUpdate. |
if(event == 'ForceUpdate' or not event) then |
local buffs = self.Buffs |
if(buffs) then |
(buffs.SetPosition or SetPosition) (buffs, 1, buffs.createdIcons) |
end |
local debuffs = self.Debuffs |
if(debuffs) then |
(debuffs.SetPosition or SetPosition) (debuffs, 1, debuffs.createdIcons) |
end |
local auras = self.Auras |
if(auras) then |
(auras.SetPosition or SetPosition) (auras, 1, auras.createdIcons) |
end |
end |
end |
local ForceUpdate = function(element) |
return Update(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local Enable = function(self) |
if(self.Buffs or self.Debuffs or self.Auras) then |
self:RegisterEvent("UNIT_AURA", UpdateAuras) |
local buffs = self.Buffs |
if(buffs) then |
buffs.__owner = self |
buffs.ForceUpdate = ForceUpdate |
buffs.createdIcons = 0 |
buffs.anchoredIcons = 0 |
end |
local debuffs = self.Debuffs |
if(debuffs) then |
debuffs.__owner = self |
debuffs.ForceUpdate = ForceUpdate |
debuffs.createdIcons = 0 |
debuffs.anchoredIcons = 0 |
end |
local auras = self.Auras |
if(auras) then |
auras.__owner = self |
auras.ForceUpdate = ForceUpdate |
auras.createdIcons = 0 |
auras.anchoredIcons = 0 |
end |
return true |
end |
end |
local Disable = function(self) |
if(self.Buffs or self.Debuffs or self.Auras) then |
self:UnregisterEvent("UNIT_AURA", UpdateAuras) |
end |
end |
oUF:AddElement('Aura', Update, Enable, Disable) |
--[[ Element: Heal Prediction Bar |
Handle updating and visibility of the heal prediction status bars. |
Widget |
HealPrediction - A table containing `myBar` and `otherBar`. |
Sub-Widgets |
myBar - A StatusBar used to represent your incoming heals. |
otherBar - A StatusBar used to represent other peoples incoming heals. |
Notes |
The default StatusBar texture will be applied if the UI widget doesn't have a |
status bar texture or color defined. |
Options |
.maxOverflow - Defines the maximum amount of overflow past the end of the |
health bar. |
Examples |
-- Position and size |
local myBar = CreateFrame('StatusBar', nil, self.Health) |
myBar:SetPoint('TOP') |
myBar:SetPoint('BOTTOM') |
myBar:SetPoint('LEFT', self.Health:GetStatusBarTexture(), 'RIGHT') |
myBar:SetWidth(200) |
local otherBar = CreateFrame('StatusBar', nil, self.Health) |
otherBar:SetPoint('TOP') |
otherBar:SetPoint('BOTTOM') |
otherBar:SetPoint('LEFT', self.Health:GetStatusBarTexture(), 'RIGHT') |
otherBar:SetWidth(200) |
-- Register with oUF |
self.HealPrediction = { |
myBar = myBar, |
otherBar = otherBar, |
maxOverflow = 1.05, |
} |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local _, ns = ... |
local oUF = ns.oUF |
local function Update(self, event, unit) |
if(self.unit ~= unit) then return end |
local hp = self.HealPrediction |
if(hp.PreUpdate) then hp:PreUpdate(unit) end |
local myIncomingHeal = UnitGetIncomingHeals(unit, 'player') or 0 |
local allIncomingHeal = UnitGetIncomingHeals(unit) or 0 |
local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit) |
if(health + allIncomingHeal > maxHealth * hp.maxOverflow) then |
allIncomingHeal = maxHealth * hp.maxOverflow - health |
end |
if(allIncomingHeal < myIncomingHeal) then |
myIncomingHeal = allIncomingHeal |
allIncomingHeal = 0 |
else |
allIncomingHeal = allIncomingHeal - myIncomingHeal |
end |
if(hp.myBar) then |
hp.myBar:SetMinMaxValues(0, maxHealth) |
hp.myBar:SetValue(myIncomingHeal) |
hp.myBar:Show() |
end |
if(hp.otherBar) then |
hp.otherBar:SetMinMaxValues(0, maxHealth) |
hp.otherBar:SetValue(allIncomingHeal) |
hp.otherBar:Show() |
end |
if(hp.PostUpdate) then |
return hp:PostUpdate(unit) |
end |
end |
local function Path(self, ...) |
return (self.HealPrediction.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local function Enable(self) |
local hp = self.HealPrediction |
if(hp) then |
hp.__owner = self |
hp.ForceUpdate = ForceUpdate |
self:RegisterEvent('UNIT_HEAL_PREDICTION', Path) |
self:RegisterEvent('UNIT_MAXHEALTH', Path) |
self:RegisterEvent('UNIT_HEALTH', Path) |
if(not hp.maxOverflow) then |
hp.maxOverflow = 1.05 |
end |
if(hp.myBar and hp.myBar:IsObjectType'StatusBar' and not hp.myBar:GetStatusBarTexture()) then |
hp.myBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) |
end |
if(hp.otherBar and hp.otherBar:IsObjectType'StatusBar' and not hp.otherBar:GetStatusBarTexture()) then |
hp.otherBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) |
end |
return true |
end |
end |
local function Disable(self) |
local hp = self.HealPrediction |
if(hp) then |
self:UnregisterEvent('UNIT_HEAL_PREDICTION', Path) |
self:UnregisterEvent('UNIT_MAXHEALTH', Path) |
self:UnregisterEvent('UNIT_HEALTH', Path) |
end |
end |
oUF:AddElement('HealPrediction', Path, Enable, Disable) |
--[[ Element: Range Fader |
Widget |
Range - A table containing opacity values. |
Options |
.outsideAlpha - Opacity when the unit is out of range. Values 0 (fully |
transparent) - 1 (fully opaque). |
.insideAlpha - Opacity when the unit is within range. Values 0 (fully |
transparent) - 1 (fully opaque). |
Examples |
-- Register with oUF |
self.Range = { |
insideAlpha = 1, |
outsideAlpha = 1/2, |
} |
Hooks |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local _FRAMES = {} |
local OnRangeFrame |
local UnitInRange, UnitIsConnected = UnitInRange, UnitIsConnected |
-- updating of range. |
local timer = 0 |
local OnRangeUpdate = function(self, elapsed) |
timer = timer + elapsed |
if(timer >= .20) then |
for _, object in next, _FRAMES do |
if(object:IsShown()) then |
local range = object.Range |
if(UnitIsConnected(object.unit)) then |
local inRange, checkedRange = UnitInRange(object.unit) |
if(checkedRange and not inRange) then |
if(range.Override) then |
--[[ .Override(self, status) |
A function used to override the calls to :SetAlpha(). |
Arguments |
self - The unit object. |
status - The range status of the unit. Either `inside` or |
`outside`. |
]] |
range.Override(object, 'outside') |
else |
object:SetAlpha(range.outsideAlpha) |
end |
else |
if(range.Override) then |
range.Override(object, 'inside') |
elseif(object:GetAlpha() ~= range.insideAlpha) then |
object:SetAlpha(range.insideAlpha) |
end |
end |
else |
if(range.Override) then |
range.Override(object, 'offline') |
elseif(object:GetAlpha() ~= range.insideAlpha) then |
object:SetAlpha(range.insideAlpha) |
end |
end |
end |
end |
timer = 0 |
end |
end |
local Enable = function(self) |
local range = self.Range |
if(range and range.insideAlpha and range.outsideAlpha) then |
table.insert(_FRAMES, self) |
if(not OnRangeFrame) then |
OnRangeFrame = CreateFrame"Frame" |
OnRangeFrame:SetScript("OnUpdate", OnRangeUpdate) |
end |
OnRangeFrame:Show() |
return true |
end |
end |
local Disable = function(self) |
local range = self.Range |
if(range) then |
for k, frame in next, _FRAMES do |
if(frame == self) then |
table.remove(_FRAMES, k) |
break |
end |
end |
if(#_FRAMES == 0) then |
OnRangeFrame:Hide() |
end |
end |
end |
oUF:AddElement('Range', nil, Enable, Disable) |
--[[ Element: Power Bar |
Handles updating of `self.Power` based upon the units power. |
Widget |
Power - A StatusBar used to represent mana. |
Sub-Widgets |
.bg - A Texture which functions as a background. It will inherit the color of |
the main StatusBar. |
Notes |
The default StatusBar texture will be applied if the UI widget doesn't have a |
status bar texture or color defined. |
Options |
The following options are listed by priority. The first check that returns |
true decides the color of the bar. |
.colorTapping - Use `self.colors.tapping` to color the bar if the unit |
isn't tapped by the player. |
.colorDisconnected - Use `self.colors.disconnected` to color the bar if the |
unit is offline. |
.colorPower - Use `self.colors.power[token]` to color the bar based on |
the unit's power type. This method will fall-back to |
`:GetAlternativeColor()` if it can't find a color matching |
the token. If this function isn't defined, then it will |
attempt to color based upon the alternative power colors |
returned by [UnitPowerType](http://wowprogramming.com/docs/api/UnitPowerType). |
Finally, if these aren't defined, then it will attempt to |
color the bar based upon `self.colors.power[type]`. |
.colorClass - Use `self.colors.class[class]` to color the bar based on |
unit class. `class` is defined by the second return of |
[UnitClass](http://wowprogramming.com/docs/api/UnitClass). |
.colorClassNPC - Use `self.colors.class[class]` to color the bar if the |
unit is a NPC. |
.colorClassPet - Use `self.colors.class[class]` to color the bar if the |
unit is player controlled, but not a player. |
.colorReaction - Use `self.colors.reaction[reaction]` to color the bar |
based on the player's reaction towards the unit. |
`reaction` is defined by the return value of |
[UnitReaction](http://wowprogramming.com/docs/api/UnitReaction). |
.colorSmooth - Use `self.colors.smooth` to color the bar with a smooth |
gradient based on the player's current health percentage. |
Sub-Widget Options |
.multiplier - Defines a multiplier, which is used to tint the background based |
on the main widgets R, G and B values. Defaults to 1 if not |
present. |
Examples |
-- Position and size |
local Power = CreateFrame("StatusBar", nil, self) |
Power:SetHeight(20) |
Power:SetPoint('BOTTOM') |
Power:SetPoint('LEFT') |
Power:SetPoint('RIGHT') |
-- Add a background |
local Background = Power:CreateTexture(nil, 'BACKGROUND') |
Background:SetAllPoints(Power) |
Background:SetTexture(1, 1, 1, .5) |
-- Options |
Power.frequentUpdates = true |
Power.colorTapping = true |
Power.colorDisconnected = true |
Power.colorPower = true |
Power.colorClass = true |
Power.colorReaction = true |
-- Make the background darker. |
Background.multiplier = .5 |
-- Register it with oUF |
self.Power = Power |
self.Power.bg = Background |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
oUF.colors.power = {} |
for power, color in next, PowerBarColor do |
if (type(power) == "string") then |
oUF.colors.power[power] = {color.r, color.g, color.b} |
end |
end |
oUF.colors.power[0] = oUF.colors.power["MANA"] |
oUF.colors.power[1] = oUF.colors.power["RAGE"] |
oUF.colors.power[2] = oUF.colors.power["FOCUS"] |
oUF.colors.power[3] = oUF.colors.power["ENERGY"] |
oUF.colors.power[4] = oUF.colors.power["UNUSED"] |
oUF.colors.power[5] = oUF.colors.power["RUNES"] |
oUF.colors.power[6] = oUF.colors.power["RUNIC_POWER"] |
oUF.colors.power[7] = oUF.colors.power["SOUL_SHARDS"] |
oUF.colors.power[8] = oUF.colors.power["ECLIPSE"] |
oUF.colors.power[9] = oUF.colors.power["HOLY_POWER"] |
local GetDisplayPower = function(power, unit) |
local _, _, _, _, _, _, showOnRaid = UnitAlternatePowerInfo(unit) |
if(power.displayAltPower and showOnRaid) then |
return ALTERNATE_POWER_INDEX |
else |
return (UnitPowerType(unit)) |
end |
end |
local Update = function(self, event, unit) |
if(self.unit ~= unit) then return end |
local power = self.Power |
if(power.PreUpdate) then power:PreUpdate(unit) end |
local displayType = GetDisplayPower(power, unit) |
local min, max = UnitPower(unit, displayType), UnitPowerMax(unit, displayType) |
local disconnected = not UnitIsConnected(unit) |
power:SetMinMaxValues(0, max) |
if(disconnected) then |
power:SetValue(max) |
else |
power:SetValue(min) |
end |
power.disconnected = disconnected |
local r, g, b, t |
if(power.colorTapping and not UnitPlayerControlled(unit) and |
UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit) and not |
UnitIsTappedByAllThreatList(unit)) then |
t = self.colors.tapped |
elseif(power.colorDisconnected and not UnitIsConnected(unit)) then |
t = self.colors.disconnected |
elseif(power.colorPower) then |
local ptype, ptoken, altR, altG, altB = UnitPowerType(unit) |
t = self.colors.power[ptoken] |
if(not t) then |
if(power.GetAlternativeColor) then |
r, g, b = power:GetAlternativeColor(unit, ptype, ptoken, altR, altG, altB) |
elseif(altR) then |
r, g, b = altR, altG, altB |
else |
t = self.colors.power[ptype] |
end |
end |
elseif(power.colorClass and UnitIsPlayer(unit)) or |
(power.colorClassNPC and not UnitIsPlayer(unit)) or |
(power.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then |
local _, class = UnitClass(unit) |
t = self.colors.class[class] |
elseif(power.colorReaction and UnitReaction(unit, 'player')) then |
t = self.colors.reaction[UnitReaction(unit, "player")] |
elseif(power.colorSmooth) then |
r, g, b = self.ColorGradient(min, max, unpack(power.smoothGradient or self.colors.smooth)) |
end |
if(t) then |
r, g, b = t[1], t[2], t[3] |
end |
if(b) then |
power:SetStatusBarColor(r, g, b) |
local bg = power.bg |
if(bg) then |
local mu = bg.multiplier or 1 |
bg:SetVertexColor(r * mu, g * mu, b * mu) |
end |
end |
if(power.PostUpdate) then |
return power:PostUpdate(unit, min, max) |
end |
end |
local Path = function(self, ...) |
return (self.Power.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate', element.__owner.unit) |
end |
local Enable = function(self, unit) |
local power = self.Power |
if(power) then |
power.__owner = self |
power.ForceUpdate = ForceUpdate |
if(power.frequentUpdates and (unit == 'player' or unit == 'pet')) then |
self:RegisterEvent('UNIT_POWER_FREQUENT', Path) |
else |
self:RegisterEvent('UNIT_POWER', Path) |
end |
self:RegisterEvent('UNIT_POWER_BAR_SHOW', Path) |
self:RegisterEvent('UNIT_POWER_BAR_HIDE', Path) |
self:RegisterEvent('UNIT_DISPLAYPOWER', Path) |
self:RegisterEvent('UNIT_CONNECTION', Path) |
self:RegisterEvent('UNIT_MAXPOWER', Path) |
-- For tapping. |
self:RegisterEvent('UNIT_FACTION', Path) |
if(power:IsObjectType'StatusBar' and not power:GetStatusBarTexture()) then |
power:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] |
end |
return true |
end |
end |
local Disable = function(self) |
local power = self.Power |
if(power) then |
self:UnregisterEvent('UNIT_POWER_FREQUENT', Path) |
self:UnregisterEvent('UNIT_POWER', Path) |
self:UnregisterEvent('UNIT_POWER_BAR_SHOW', Path) |
self:UnregisterEvent('UNIT_POWER_BAR_HIDE', Path) |
self:UnregisterEvent('UNIT_DISPLAYPOWER', Path) |
self:UnregisterEvent('UNIT_CONNECTION', Path) |
self:UnregisterEvent('UNIT_MAXPOWER', Path) |
self:UnregisterEvent('UNIT_FACTION', Path) |
end |
end |
oUF:AddElement('Power', Path, Enable, Disable) |
--[[ Element: Leader Icon |
Toggles visibility based on the units leader status. |
Widget |
Leader - Any UI widget. |
Notes |
The default leader icon will be applied if the UI widget is a texture and |
doesn't have a texture or color defined. |
Examples |
-- Position and size |
local Leader = self:CreateTexture(nil, "OVERLAY") |
Leader:SetSize(16, 16) |
Leader:SetPoint("BOTTOM", self, "TOP") |
-- Register it with oUF |
self.Leader = Leadera |
Hooks |
Override(self) - Used to completely override the internal update function. |
Removing the table key entry will make the element fall-back |
to its internal function again. |
]] |
local parent, ns = ... |
local oUF = ns.oUF |
local Update = function(self, event) |
local leader = self.Leader |
if(leader.PreUpdate) then |
leader:PreUpdate() |
end |
local unit = self.unit |
local isLeader = (UnitInParty(unit) or UnitInRaid(unit)) and UnitIsGroupLeader(unit) |
if(isLeader) then |
leader:Show() |
else |
leader:Hide() |
end |
if(leader.PostUpdate) then |
return leader:PostUpdate(isLeader) |
end |
end |
local Path = function(self, ...) |
return (self.Leader.Override or Update) (self, ...) |
end |
local ForceUpdate = function(element) |
return Path(element.__owner, 'ForceUpdate') |
end |
local Enable = function(self) |
local leader = self.Leader |
if(leader) then |
leader.__owner = self |
leader.ForceUpdate = ForceUpdate |
self:RegisterEvent("PARTY_LEADER_CHANGED", Path, true) |
self:RegisterEvent("GROUP_ROSTER_UPDATE", Path, true) |
if(leader:IsObjectType"Texture" and not leader:GetTexture()) then |
leader:SetTexture[[Interface\GroupFrame\UI-Group-LeaderIcon]] |
end |
return true |
end |
end |
local Disable = function(self) |
local leader = self.Leader |
if(leader) then |
self:UnregisterEvent("PARTY_LEADER_CHANGED", Path) |
self:UnregisterEvent("GROUP_ROSTER_UPDATE", Path) |
end |
end |
oUF:AddElement('Leader', Path, Enable, Disable) |
## Interface: 50300 |
## Title: oUF |
## Author: Haste |
## Version: 1.6.5 |
## OptionalDeps: Clique |
## X-eMail: troeks@gmail.com |
## X-oUF: oUF |
## Notes: Unit frame framework. Does nothing by itself. |
## Notes-ruRU: ÐаÑÐºÐ°Ñ Ð´Ð»Ñ Ð¼Ð¾Ð´Ð¸ÑикаÑии ÑÑеймов игÑоков. Сам по Ñебе не Ð´ÐµÐ»Ð°ÐµÑ Ð½Ð¸Ñего. |
oUF.xml |
#!/usr/bin/env lua |
local tags = {} |
do |
for tag in io.popen('git tag'):lines() do |
local split = tag:gmatch('[^.]+') |
local release, api, bugfix = split(), split(), split() or 0 |
table.insert( |
tags, |
{ |
string = tag, |
release = release, |
api = api, |
bugfix = bugfix, |
} |
) |
end |
table.sort(tags, function(a,b) |
a = a.release * 1e4 + a.api * 100 + a.bugfix |
b = b.release * 1e4 + b.api * 100 + b.bugfix |
return a > b |
end) |
end |
local generateLog = function(prevTag, currentTag) |
local ti = table.insert |
local sf = string.format |
local out = {} |
ti(out, sf('[b]Changes in %s:[/b]', currentTag)) |
ti(out, '[list]') |
for line in io.popen(sf('git shortlog %s..%s', prevTag, currentTag)):lines() do |
if(line:sub(1, 6) == ' ') then |
local offset = line:match('() ', 7) |
if(offset) then |
line = line:sub(7, offset - 1) |
else |
line = line:sub(7) |
end |
ti(out, sf(' [*] %s', line)) |
elseif(#line == 0) then |
ti(out, ' [/list]') |
else |
ti(out, sf(' [*][i]%s[/i]', line)) |
ti(out, ' [list=1]') |
end |
end |
ti(out, '[/list]') |
local p = assert(io.popen(sf('git diff --shortstat %s..%s', prevTag, currentTag))) |
local stat = p:read'*a' |
p:close() |
ti(out, sf('[indent]%s[/indent]', stat:sub(2, -2))) |
return table.concat(out, '\n') |
end |
local stop |
local to = ... |
if(to) then |
for i=1, #tags do |
if(tags[i].string == to) then |
stop = i + 1 |
end |
end |
if(not stop) then stop = #tags end |
else |
stop = #tags |
end |
for i=2, stop do |
local current, prev = tags[i -1], tags[i] |
print(generateLog(prev.string, current.string)) |
end |
-- vim: set filetype=lua : |
#!/usr/bin/env lua |
-- docs |
-- oUF documentation generator |
-- |
-- This is really just a quick and dirty way of generating documentation for |
-- oUF[1]. The syntax is inspired by TomDoc[2], but a lot of the non-oUF and |
-- non-Lua things aren't implemented. |
-- |
-- Why implement my own documentation generator? |
-- It was mainly done because oUF is kind-of special, but also because the |
-- available alternatives aren't good enough or have issues I can't workaround. |
-- |
-- Things that need fixing: |
-- - No highlighting of Lua code. |
-- - Doesn't validate that comments are documentation strings. |
-- - Doesn't parse its own documentation header. |
-- - Close to zero error handling. |
-- |
-- Usage |
-- |
-- docs [docs path] [file...] |
-- |
-- Links |
-- |
-- [1] https://github.com/haste/oUF |
-- [2] http://tomdoc.org/ |
local out |
local lines |
local tisf = function(fmt, ...) |
table.insert(out, fmt:format(...)) |
end |
local trim = function(str) |
return str:match('^()%s*$') and '' or str:match('^%s*(.*%S)') |
end |
local findNextEmpty = function(start, stop) |
for i=start, stop or #lines do |
if(lines[i] == '') then |
return i |
end |
end |
end |
local findNextHeader = function(offest) |
for i=offest, #lines do |
local pre, header, post = unpack(lines, i, i + 2) |
-- Single lines without punctuation are headers. |
if(pre == '' and post == '' and not header:match'%.') then |
return i + 1 |
end |
end |
end |
local findNextArguent = function(start, stop, padding, pattern) |
for i=start, stop do |
local match, pad = lines[i]:match(pattern) |
if(match and pad == padding) then |
return i |
end |
end |
end |
local replaceMarkup = function(str) |
return str |
-- `in-line code` to <code>in-line code</code> |
:gsub('`([^`]+)`', '<code>%1</code>') |
-- [Link](http://example.com) to <a href="http://example.com">Link</a> |
:gsub('%[([^%]]+)%]%(([^)]+)%)', '<a href="%2">%1</a>') |
end |
local handleArguments = function(start, stop, pattern) |
tisf('<dl>') |
repeat |
-- Tear out the argument name and offset of where the description begins. |
local def, padding, offset = lines[start]:match(pattern) |
tisf('<dt>%s</dt>', def) |
-- Insert the first line of the description. |
tisf('<dd>') |
tisf(lines[start]:sub(offset)) |
-- Find the next argument in the list or continue to the end of the |
-- current section. |
local nextarg = findNextArguent(start + 1, stop, padding, pattern) |
nextarg = (nextarg or stop + 1) - 1 |
for i=start + 1, nextarg do |
tisf(trim(lines[i])) |
end |
tisf('</dd>') |
start = nextarg + 1 |
until start > stop |
tisf('</dl>') |
end |
local handleExamples = function(start, stop) |
-- An extra line gets added if we don't do this. |
tisf('<pre><code>%s', lines[start]:sub(3)) |
for i=start + 1, stop do |
tisf(lines[i]:sub(3)) |
end |
tisf('</code></pre>') |
end |
local handleParagraph = function(start, stop) |
tisf('<p>') |
for i=start, stop do |
tisf(trim(lines[i])) |
end |
tisf('</p>') |
end |
local handleSection = function(start, stop) |
while(start) do |
-- Find the next empty line or continue until the end of the section. |
-- findNextEmpty() returns the position of the empty line, so we need to |
-- subtract one from it. |
local nextEmpty = findNextEmpty(start + 1, stop) |
if(nextEmpty) then |
nextEmpty = nextEmpty - 1 |
else |
nextEmpty = stop |
end |
local line = lines[start] |
if(not line) then |
return |
elseif(line:match('^%S+%s*%- ')) then |
handleArguments(start, nextEmpty, '(%S+)%s*()%- ()') |
elseif(line:sub(1, 2) == ' ') then |
handleExamples(start, nextEmpty) |
else |
handleParagraph(start, nextEmpty) |
end |
start = findNextEmpty(nextEmpty, stop) |
if(start) then start = start + 1 end |
end |
end |
local generateDocs = function(str, level) |
lines = {} |
out = {} |
for line in str:gmatch('([^\n]*)\n') do |
table.insert(lines, line:gsub('\t*', ''):sub(2)) |
end |
-- The first line is always the main header. |
tisf('<h%d>%s</h%d>', level, lines[1], level) |
-- Then comes the main description. |
local offset = findNextHeader(1) |
-- Continue until two lines before the header or to the end of the comment. |
if(offset) then |
offset = offset - 2 |
else |
offset = #lines |
end |
local init = findNextEmpty(1) + 1 |
if(init > offset) then |
init = 2 |
end |
handleSection(init, offset) |
while(true) do |
offset = findNextHeader(offset) |
if(not offset) then break end |
-- Every section has a header. |
tisf('<h%d>%s</h%d>', level + 1, lines[offset], level + 1) |
-- Find out the size of the section. |
local start = findNextEmpty(offset) + 1 |
if(not lines[start]) then |
-- There's no section here, only a headline. |
break |
end |
local stop |
local nextHeader = findNextHeader(start) |
if(nextHeader) then |
stop = nextHeader - 2 |
else |
local nextEmpty = findNextEmpty(start) |
if(nextEmpty) then |
stop = nextEmpty - 1 |
else |
stop = #lines |
end |
end |
handleSection(start, stop) |
offset = stop + 1 |
end |
return table.concat(out, '\n') |
end |
local handleFile = function(path) |
local file = io.open(path, 'r') |
local content = file:read'*a' |
file:close() |
local out = {} |
local init = 1 |
repeat |
local _, comStart, depth = content:find('%-%-%[(=*)%[ ', init) |
if(comStart) then |
local comEnd = content:find('%]' .. depth .. '%]', comStart) |
local comment = content:sub(comStart, comEnd - 1) |
-- Convert markup to html. |
comment = replaceMarkup(comment) |
-- The first comment uses h1 and h2, while the subsequent ones uses h3 |
-- and h4. |
local level = init == 1 and 1 or 3 |
table.insert(out, generateDocs(comment, init == 1 and 1 or 3)) |
init = comEnd |
end |
until not comStart |
return table.concat(out, '\n') |
end |
local destination = (...) |
for i=2, select('#', ...) do |
local file = select(i, ...) |
local path, filename = file:match('(.+)/(.+)$') |
if(path:sub(1,3) == '../') then |
path = path:sub(4) |
end |
if(#path == 0) then path = nil end |
filename = filename:gsub('lua', 'html') |
local doc = handleFile(file) |
if(doc) then |
local dfPath = string.format('%s/%s', destination, path or '') |
os.execute(string.format('mkdir -p %s', dfPath)) |
local docFile = io.open(string.format('%s/%s', dfPath, filename), 'w+') |
docFile:write(doc) |
docFile:close() |
end |
end |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="AceAddon-3.0.lua"/> |
</Ui> |
--- **AceAddon-3.0** provides a template for creating addon objects. |
-- It'll provide you with a set of callback functions that allow you to simplify the loading |
-- process of your addon.\\ |
-- Callbacks provided are:\\ |
-- * **OnInitialize**, which is called directly after the addon is fully loaded. |
-- * **OnEnable** which gets called during the PLAYER_LOGIN event, when most of the data provided by the game is already present. |
-- * **OnDisable**, which is only called when your addon is manually being disabled. |
-- @usage |
-- -- A small (but complete) addon, that doesn't do anything, |
-- -- but shows usage of the callbacks. |
-- local MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon") |
-- |
-- function MyAddon:OnInitialize() |
-- -- do init tasks here, like loading the Saved Variables, |
-- -- or setting up slash commands. |
-- end |
-- |
-- function MyAddon:OnEnable() |
-- -- Do more initialization here, that really enables the use of your addon. |
-- -- Register Events, Hook functions, Create Frames, Get information from |
-- -- the game that wasn't available in OnInitialize |
-- end |
-- |
-- function MyAddon:OnDisable() |
-- -- Unhook, Unregister Events, Hide frames that you created. |
-- -- You would probably only use an OnDisable if you want to |
-- -- build a "standby" mode, or be able to toggle modules on/off. |
-- end |
-- @class file |
-- @name AceAddon-3.0.lua |
-- @release $Id: AceAddon-3.0.lua 1084 2013-04-27 20:14:11Z nevcairiel $ |
local MAJOR, MINOR = "AceAddon-3.0", 12 |
local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR) |
if not AceAddon then return end -- No Upgrade needed. |
AceAddon.frame = AceAddon.frame or CreateFrame("Frame", "AceAddon30Frame") -- Our very own frame |
AceAddon.addons = AceAddon.addons or {} -- addons in general |
AceAddon.statuses = AceAddon.statuses or {} -- statuses of addon. |
AceAddon.initializequeue = AceAddon.initializequeue or {} -- addons that are new and not initialized |
AceAddon.enablequeue = AceAddon.enablequeue or {} -- addons that are initialized and waiting to be enabled |
AceAddon.embeds = AceAddon.embeds or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end }) -- contains a list of libraries embedded in an addon |
-- Lua APIs |
local tinsert, tconcat, tremove = table.insert, table.concat, table.remove |
local fmt, tostring = string.format, tostring |
local select, pairs, next, type, unpack = select, pairs, next, type, unpack |
local loadstring, assert, error = loadstring, assert, error |
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: LibStub, IsLoggedIn, geterrorhandler |
--[[ |
xpcall safecall implementation |
]] |
local xpcall = xpcall |
local function errorhandler(err) |
return geterrorhandler()(err) |
end |
local function CreateDispatcher(argCount) |
local code = [[ |
local xpcall, eh = ... |
local method, ARGS |
local function call() return method(ARGS) end |
local function dispatch(func, ...) |
method = func |
if not method then return end |
ARGS = ... |
return xpcall(call, eh) |
end |
return dispatch |
]] |
local ARGS = {} |
for i = 1, argCount do ARGS[i] = "arg"..i end |
code = code:gsub("ARGS", tconcat(ARGS, ", ")) |
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler) |
end |
local Dispatchers = setmetatable({}, {__index=function(self, argCount) |
local dispatcher = CreateDispatcher(argCount) |
rawset(self, argCount, dispatcher) |
return dispatcher |
end}) |
Dispatchers[0] = function(func) |
return xpcall(func, errorhandler) |
end |
local function safecall(func, ...) |
-- we check to see if the func is passed is actually a function here and don't error when it isn't |
-- this safecall is used for optional functions like OnInitialize OnEnable etc. When they are not |
-- present execution should continue without hinderance |
if type(func) == "function" then |
return Dispatchers[select('#', ...)](func, ...) |
end |
end |
-- local functions that will be implemented further down |
local Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype |
-- used in the addon metatable |
local function addontostring( self ) return self.name end |
-- Check if the addon is queued for initialization |
local function queuedForInitialization(addon) |
for i = 1, #AceAddon.initializequeue do |
if AceAddon.initializequeue[i] == addon then |
return true |
end |
end |
return false |
end |
--- Create a new AceAddon-3.0 addon. |
-- Any libraries you specified will be embeded, and the addon will be scheduled for |
-- its OnInitialize and OnEnable callbacks. |
-- The final addon object, with all libraries embeded, will be returned. |
-- @paramsig [object ,]name[, lib, ...] |
-- @param object Table to use as a base for the addon (optional) |
-- @param name Name of the addon object to create |
-- @param lib List of libraries to embed into the addon |
-- @usage |
-- -- Create a simple addon object |
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceEvent-3.0") |
-- |
-- -- Create a Addon object based on the table of a frame |
-- local MyFrame = CreateFrame("Frame") |
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon(MyFrame, "MyAddon", "AceEvent-3.0") |
function AceAddon:NewAddon(objectorname, ...) |
local object,name |
local i=1 |
if type(objectorname)=="table" then |
object=objectorname |
name=... |
i=2 |
else |
name=objectorname |
end |
if type(name)~="string" then |
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2) |
end |
if self.addons[name] then |
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists."):format(name), 2) |
end |
object = object or {} |
object.name = name |
local addonmeta = {} |
local oldmeta = getmetatable(object) |
if oldmeta then |
for k, v in pairs(oldmeta) do addonmeta[k] = v end |
end |
addonmeta.__tostring = addontostring |
setmetatable( object, addonmeta ) |
self.addons[name] = object |
object.modules = {} |
object.orderedModules = {} |
object.defaultModuleLibraries = {} |
Embed( object ) -- embed NewModule, GetModule methods |
self:EmbedLibraries(object, select(i,...)) |
-- add to queue of addons to be initialized upon ADDON_LOADED |
tinsert(self.initializequeue, object) |
return object |
end |
--- Get the addon object by its name from the internal AceAddon registry. |
-- Throws an error if the addon object cannot be found (except if silent is set). |
-- @param name unique name of the addon object |
-- @param silent if true, the addon is optional, silently return nil if its not found |
-- @usage |
-- -- Get the Addon |
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon") |
function AceAddon:GetAddon(name, silent) |
if not silent and not self.addons[name] then |
error(("Usage: GetAddon(name): 'name' - Cannot find an AceAddon '%s'."):format(tostring(name)), 2) |
end |
return self.addons[name] |
end |
-- - Embed a list of libraries into the specified addon. |
-- This function will try to embed all of the listed libraries into the addon |
-- and error if a single one fails. |
-- |
-- **Note:** This function is for internal use by :NewAddon/:NewModule |
-- @paramsig addon, [lib, ...] |
-- @param addon addon object to embed the libs in |
-- @param lib List of libraries to embed into the addon |
function AceAddon:EmbedLibraries(addon, ...) |
for i=1,select("#", ... ) do |
local libname = select(i, ...) |
self:EmbedLibrary(addon, libname, false, 4) |
end |
end |
-- - Embed a library into the addon object. |
-- This function will check if the specified library is registered with LibStub |
-- and if it has a :Embed function to call. It'll error if any of those conditions |
-- fails. |
-- |
-- **Note:** This function is for internal use by :EmbedLibraries |
-- @paramsig addon, libname[, silent[, offset]] |
-- @param addon addon object to embed the library in |
-- @param libname name of the library to embed |
-- @param silent marks an embed to fail silently if the library doesn't exist (optional) |
-- @param offset will push the error messages back to said offset, defaults to 2 (optional) |
function AceAddon:EmbedLibrary(addon, libname, silent, offset) |
local lib = LibStub:GetLibrary(libname, true) |
if not lib and not silent then |
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Cannot find a library instance of %q."):format(tostring(libname)), offset or 2) |
elseif lib and type(lib.Embed) == "function" then |
lib:Embed(addon) |
tinsert(self.embeds[addon], libname) |
return true |
elseif lib then |
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Library '%s' is not Embed capable"):format(libname), offset or 2) |
end |
end |
--- Return the specified module from an addon object. |
-- Throws an error if the addon object cannot be found (except if silent is set) |
-- @name //addon//:GetModule |
-- @paramsig name[, silent] |
-- @param name unique name of the module |
-- @param silent if true, the module is optional, silently return nil if its not found (optional) |
-- @usage |
-- -- Get the Addon |
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon") |
-- -- Get the Module |
-- MyModule = MyAddon:GetModule("MyModule") |
function GetModule(self, name, silent) |
if not self.modules[name] and not silent then |
error(("Usage: GetModule(name, silent): 'name' - Cannot find module '%s'."):format(tostring(name)), 2) |
end |
return self.modules[name] |
end |
local function IsModuleTrue(self) return true end |
--- Create a new module for the addon. |
-- The new module can have its own embeded libraries and/or use a module prototype to be mixed into the module.\\ |
-- A module has the same functionality as a real addon, it can have modules of its own, and has the same API as |
-- an addon object. |
-- @name //addon//:NewModule |
-- @paramsig name[, prototype|lib[, lib, ...]] |
-- @param name unique name of the module |
-- @param prototype object to derive this module from, methods and values from this table will be mixed into the module (optional) |
-- @param lib List of libraries to embed into the addon |
-- @usage |
-- -- Create a module with some embeded libraries |
-- MyModule = MyAddon:NewModule("MyModule", "AceEvent-3.0", "AceHook-3.0") |
-- |
-- -- Create a module with a prototype |
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end } |
-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0") |
function NewModule(self, name, prototype, ...) |
if type(name) ~= "string" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2) end |
if type(prototype) ~= "string" and type(prototype) ~= "table" and type(prototype) ~= "nil" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'prototype' - table (prototype), string (lib) or nil expected got '%s'."):format(type(prototype)), 2) end |
if self.modules[name] then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists."):format(name), 2) end |
-- modules are basically addons. We treat them as such. They will be added to the initializequeue properly as well. |
-- NewModule can only be called after the parent addon is present thus the modules will be initialized after their parent is. |
local module = AceAddon:NewAddon(fmt("%s_%s", self.name or tostring(self), name)) |
module.IsModule = IsModuleTrue |
module:SetEnabledState(self.defaultModuleState) |
module.moduleName = name |
if type(prototype) == "string" then |
AceAddon:EmbedLibraries(module, prototype, ...) |
else |
AceAddon:EmbedLibraries(module, ...) |
end |
AceAddon:EmbedLibraries(module, unpack(self.defaultModuleLibraries)) |
if not prototype or type(prototype) == "string" then |
prototype = self.defaultModulePrototype or nil |
end |
if type(prototype) == "table" then |
local mt = getmetatable(module) |
mt.__index = prototype |
setmetatable(module, mt) -- More of a Base class type feel. |
end |
safecall(self.OnModuleCreated, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy. |
self.modules[name] = module |
tinsert(self.orderedModules, module) |
return module |
end |
--- Returns the real name of the addon or module, without any prefix. |
-- @name //addon//:GetName |
-- @paramsig |
-- @usage |
-- print(MyAddon:GetName()) |
-- -- prints "MyAddon" |
function GetName(self) |
return self.moduleName or self.name |
end |
--- Enables the Addon, if possible, return true or false depending on success. |
-- This internally calls AceAddon:EnableAddon(), thus dispatching a OnEnable callback |
-- and enabling all modules of the addon (unless explicitly disabled).\\ |
-- :Enable() also sets the internal `enableState` variable to true |
-- @name //addon//:Enable |
-- @paramsig |
-- @usage |
-- -- Enable MyModule |
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon") |
-- MyModule = MyAddon:GetModule("MyModule") |
-- MyModule:Enable() |
function Enable(self) |
self:SetEnabledState(true) |
-- nevcairiel 2013-04-27: don't enable an addon/module if its queued for init still |
-- it'll be enabled after the init process |
if not queuedForInitialization(self) then |
return AceAddon:EnableAddon(self) |
end |
end |
--- Disables the Addon, if possible, return true or false depending on success. |
-- This internally calls AceAddon:DisableAddon(), thus dispatching a OnDisable callback |
-- and disabling all modules of the addon.\\ |
-- :Disable() also sets the internal `enableState` variable to false |
-- @name //addon//:Disable |
-- @paramsig |
-- @usage |
-- -- Disable MyAddon |
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon") |
-- MyAddon:Disable() |
function Disable(self) |
self:SetEnabledState(false) |
return AceAddon:DisableAddon(self) |
end |
--- Enables the Module, if possible, return true or false depending on success. |
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Enable` on the module object. |
-- @name //addon//:EnableModule |
-- @paramsig name |
-- @usage |
-- -- Enable MyModule using :GetModule |
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon") |
-- MyModule = MyAddon:GetModule("MyModule") |
-- MyModule:Enable() |
-- |
-- -- Enable MyModule using the short-hand |
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon") |
-- MyAddon:EnableModule("MyModule") |
function EnableModule(self, name) |
local module = self:GetModule( name ) |
return module:Enable() |
end |
--- Disables the Module, if possible, return true or false depending on success. |
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Disable` on the module object. |
-- @name //addon//:DisableModule |
-- @paramsig name |
-- @usage |
-- -- Disable MyModule using :GetModule |
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon") |
-- MyModule = MyAddon:GetModule("MyModule") |
-- MyModule:Disable() |
-- |
-- -- Disable MyModule using the short-hand |
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon") |
-- MyAddon:DisableModule("MyModule") |
function DisableModule(self, name) |
local module = self:GetModule( name ) |
return module:Disable() |
end |
--- Set the default libraries to be mixed into all modules created by this object. |
-- Note that you can only change the default module libraries before any module is created. |
-- @name //addon//:SetDefaultModuleLibraries |
-- @paramsig lib[, lib, ...] |
-- @param lib List of libraries to embed into the addon |
-- @usage |
-- -- Create the addon object |
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon") |
-- -- Configure default libraries for modules (all modules need AceEvent-3.0) |
-- MyAddon:SetDefaultModuleLibraries("AceEvent-3.0") |
-- -- Create a module |
-- MyModule = MyAddon:NewModule("MyModule") |
function SetDefaultModuleLibraries(self, ...) |
if next(self.modules) then |
error("Usage: SetDefaultModuleLibraries(...): cannot change the module defaults after a module has been registered.", 2) |
end |
self.defaultModuleLibraries = {...} |
end |
--- Set the default state in which new modules are being created. |
-- Note that you can only change the default state before any module is created. |
-- @name //addon//:SetDefaultModuleState |
-- @paramsig state |
-- @param state Default state for new modules, true for enabled, false for disabled |
-- @usage |
-- -- Create the addon object |
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon") |
-- -- Set the default state to "disabled" |
-- MyAddon:SetDefaultModuleState(false) |
-- -- Create a module and explicilty enable it |
-- MyModule = MyAddon:NewModule("MyModule") |
-- MyModule:Enable() |
function SetDefaultModuleState(self, state) |
if next(self.modules) then |
error("Usage: SetDefaultModuleState(state): cannot change the module defaults after a module has been registered.", 2) |
end |
self.defaultModuleState = state |
end |
--- Set the default prototype to use for new modules on creation. |
-- Note that you can only change the default prototype before any module is created. |
-- @name //addon//:SetDefaultModulePrototype |
-- @paramsig prototype |
-- @param prototype Default prototype for the new modules (table) |
-- @usage |
-- -- Define a prototype |
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end } |
-- -- Set the default prototype |
-- MyAddon:SetDefaultModulePrototype(prototype) |
-- -- Create a module and explicitly Enable it |
-- MyModule = MyAddon:NewModule("MyModule") |
-- MyModule:Enable() |
-- -- should print "OnEnable called!" now |
-- @see NewModule |
function SetDefaultModulePrototype(self, prototype) |
if next(self.modules) then |
error("Usage: SetDefaultModulePrototype(prototype): cannot change the module defaults after a module has been registered.", 2) |
end |
if type(prototype) ~= "table" then |
error(("Usage: SetDefaultModulePrototype(prototype): 'prototype' - table expected got '%s'."):format(type(prototype)), 2) |
end |
self.defaultModulePrototype = prototype |
end |
--- Set the state of an addon or module |
-- This should only be called before any enabling actually happend, e.g. in/before OnInitialize. |
-- @name //addon//:SetEnabledState |
-- @paramsig state |
-- @param state the state of an addon or module (enabled=true, disabled=false) |
function SetEnabledState(self, state) |
self.enabledState = state |
end |
--- Return an iterator of all modules associated to the addon. |
-- @name //addon//:IterateModules |
-- @paramsig |
-- @usage |
-- -- Enable all modules |
-- for name, module in MyAddon:IterateModules() do |
-- module:Enable() |
-- end |
local function IterateModules(self) return pairs(self.modules) end |
-- Returns an iterator of all embeds in the addon |
-- @name //addon//:IterateEmbeds |
-- @paramsig |
local function IterateEmbeds(self) return pairs(AceAddon.embeds[self]) end |
--- Query the enabledState of an addon. |
-- @name //addon//:IsEnabled |
-- @paramsig |
-- @usage |
-- if MyAddon:IsEnabled() then |
-- MyAddon:Disable() |
-- end |
local function IsEnabled(self) return self.enabledState end |
local mixins = { |
NewModule = NewModule, |
GetModule = GetModule, |
Enable = Enable, |
Disable = Disable, |
EnableModule = EnableModule, |
DisableModule = DisableModule, |
IsEnabled = IsEnabled, |
SetDefaultModuleLibraries = SetDefaultModuleLibraries, |
SetDefaultModuleState = SetDefaultModuleState, |
SetDefaultModulePrototype = SetDefaultModulePrototype, |
SetEnabledState = SetEnabledState, |
IterateModules = IterateModules, |
IterateEmbeds = IterateEmbeds, |
GetName = GetName, |
} |
local function IsModule(self) return false end |
local pmixins = { |
defaultModuleState = true, |
enabledState = true, |
IsModule = IsModule, |
} |
-- Embed( target ) |
-- target (object) - target object to embed aceaddon in |
-- |
-- this is a local function specifically since it's meant to be only called internally |
function Embed(target, skipPMixins) |
for k, v in pairs(mixins) do |
target[k] = v |
end |
if not skipPMixins then |
for k, v in pairs(pmixins) do |
target[k] = target[k] or v |
end |
end |
end |
-- - Initialize the addon after creation. |
-- This function is only used internally during the ADDON_LOADED event |
-- It will call the **OnInitialize** function on the addon object (if present), |
-- and the **OnEmbedInitialize** function on all embeded libraries. |
-- |
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing. |
-- @param addon addon object to intialize |
function AceAddon:InitializeAddon(addon) |
safecall(addon.OnInitialize, addon) |
local embeds = self.embeds[addon] |
for i = 1, #embeds do |
local lib = LibStub:GetLibrary(embeds[i], true) |
if lib then safecall(lib.OnEmbedInitialize, lib, addon) end |
end |
-- we don't call InitializeAddon on modules specifically, this is handled |
-- from the event handler and only done _once_ |
end |
-- - Enable the addon after creation. |
-- Note: This function is only used internally during the PLAYER_LOGIN event, or during ADDON_LOADED, |
-- if IsLoggedIn() already returns true at that point, e.g. for LoD Addons. |
-- It will call the **OnEnable** function on the addon object (if present), |
-- and the **OnEmbedEnable** function on all embeded libraries.\\ |
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is disabled. |
-- |
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing. |
-- Use :Enable on the addon itself instead. |
-- @param addon addon object to enable |
function AceAddon:EnableAddon(addon) |
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end |
if self.statuses[addon.name] or not addon.enabledState then return false end |
-- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable. |
self.statuses[addon.name] = true |
safecall(addon.OnEnable, addon) |
-- make sure we're still enabled before continueing |
if self.statuses[addon.name] then |
local embeds = self.embeds[addon] |
for i = 1, #embeds do |
local lib = LibStub:GetLibrary(embeds[i], true) |
if lib then safecall(lib.OnEmbedEnable, lib, addon) end |
end |
-- enable possible modules. |
local modules = addon.orderedModules |
for i = 1, #modules do |
self:EnableAddon(modules[i]) |
end |
end |
return self.statuses[addon.name] -- return true if we're disabled |
end |
-- - Disable the addon |
-- Note: This function is only used internally. |
-- It will call the **OnDisable** function on the addon object (if present), |
-- and the **OnEmbedDisable** function on all embeded libraries.\\ |
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is still enabled. |
-- |
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing. |
-- Use :Disable on the addon itself instead. |
-- @param addon addon object to enable |
function AceAddon:DisableAddon(addon) |
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end |
if not self.statuses[addon.name] then return false end |
-- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable. |
self.statuses[addon.name] = false |
safecall( addon.OnDisable, addon ) |
-- make sure we're still disabling... |
if not self.statuses[addon.name] then |
local embeds = self.embeds[addon] |
for i = 1, #embeds do |
local lib = LibStub:GetLibrary(embeds[i], true) |
if lib then safecall(lib.OnEmbedDisable, lib, addon) end |
end |
-- disable possible modules. |
local modules = addon.orderedModules |
for i = 1, #modules do |
self:DisableAddon(modules[i]) |
end |
end |
return not self.statuses[addon.name] -- return true if we're disabled |
end |
--- Get an iterator over all registered addons. |
-- @usage |
-- -- Print a list of all installed AceAddon's |
-- for name, addon in AceAddon:IterateAddons() do |
-- print("Addon: " .. name) |
-- end |
function AceAddon:IterateAddons() return pairs(self.addons) end |
--- Get an iterator over the internal status registry. |
-- @usage |
-- -- Print a list of all enabled addons |
-- for name, status in AceAddon:IterateAddonStatus() do |
-- if status then |
-- print("EnabledAddon: " .. name) |
-- end |
-- end |
function AceAddon:IterateAddonStatus() return pairs(self.statuses) end |
-- Following Iterators are deprecated, and their addon specific versions should be used |
-- e.g. addon:IterateEmbeds() instead of :IterateEmbedsOnAddon(addon) |
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end |
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end |
-- Event Handling |
local function onEvent(this, event, arg1) |
-- 2011-08-17 nevcairiel - ignore the load event of Blizzard_DebugTools, so a potential startup error isn't swallowed up |
if (event == "ADDON_LOADED" and arg1 ~= "Blizzard_DebugTools") or event == "PLAYER_LOGIN" then |
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration |
while(#AceAddon.initializequeue > 0) do |
local addon = tremove(AceAddon.initializequeue, 1) |
-- this might be an issue with recursion - TODO: validate |
if event == "ADDON_LOADED" then addon.baseName = arg1 end |
AceAddon:InitializeAddon(addon) |
tinsert(AceAddon.enablequeue, addon) |
end |
if IsLoggedIn() then |
while(#AceAddon.enablequeue > 0) do |
local addon = tremove(AceAddon.enablequeue, 1) |
AceAddon:EnableAddon(addon) |
end |
end |
end |
end |
AceAddon.frame:RegisterEvent("ADDON_LOADED") |
AceAddon.frame:RegisterEvent("PLAYER_LOGIN") |
AceAddon.frame:SetScript("OnEvent", onEvent) |
-- upgrade embeded |
for name, addon in pairs(AceAddon.addons) do |
Embed(addon, true) |
end |
-- 2010-10-27 nevcairiel - add new "orderedModules" table |
if oldminor and oldminor < 10 then |
for name, addon in pairs(AceAddon.addons) do |
addon.orderedModules = {} |
for module_name, module in pairs(addon.modules) do |
tinsert(addon.orderedModules, module) |
end |
end |
end |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="AceDB-3.0.lua"/> |
</Ui> |
--- **AceDB-3.0** manages the SavedVariables of your addon. |
-- It offers profile management, smart defaults and namespaces for modules.\\ |
-- Data can be saved in different data-types, depending on its intended usage. |
-- The most common data-type is the `profile` type, which allows the user to choose |
-- the active profile, and manage the profiles of all of his characters.\\ |
-- The following data types are available: |
-- * **char** Character-specific data. Every character has its own database. |
-- * **realm** Realm-specific data. All of the players characters on the same realm share this database. |
-- * **class** Class-specific data. All of the players characters of the same class share this database. |
-- * **race** Race-specific data. All of the players characters of the same race share this database. |
-- * **faction** Faction-specific data. All of the players characters of the same faction share this database. |
-- * **factionrealm** Faction and realm specific data. All of the players characters on the same realm and of the same faction share this database. |
-- * **global** Global Data. All characters on the same account share this database. |
-- * **profile** Profile-specific data. All characters using the same profile share this database. The user can control which profile should be used. |
-- |
-- Creating a new Database using the `:New` function will return a new DBObject. A database will inherit all functions |
-- of the DBObjectLib listed here. \\ |
-- If you create a new namespaced child-database (`:RegisterNamespace`), you'll get a DBObject as well, but note |
-- that the child-databases cannot individually change their profile, and are linked to their parents profile - and because of that, |
-- the profile related APIs are not available. Only `:RegisterDefaults` and `:ResetProfile` are available on child-databases. |
-- |
-- For more details on how to use AceDB-3.0, see the [[AceDB-3.0 Tutorial]]. |
-- |
-- You may also be interested in [[libdualspec-1-0|LibDualSpec-1.0]] to do profile switching automatically when switching specs. |
-- |
-- @usage |
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("DBExample") |
-- |
-- -- declare defaults to be used in the DB |
-- local defaults = { |
-- profile = { |
-- setting = true, |
-- } |
-- } |
-- |
-- function MyAddon:OnInitialize() |
-- -- Assuming the .toc says ## SavedVariables: MyAddonDB |
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true) |
-- end |
-- @class file |
-- @name AceDB-3.0.lua |
-- @release $Id: AceDB-3.0.lua 1035 2011-07-09 03:20:13Z kaelten $ |
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 22 |
local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR) |
if not AceDB then return end -- No upgrade needed |
-- Lua APIs |
local type, pairs, next, error = type, pairs, next, error |
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget |
-- WoW APIs |
local _G = _G |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: LibStub |
AceDB.db_registry = AceDB.db_registry or {} |
AceDB.frame = AceDB.frame or CreateFrame("Frame") |
local CallbackHandler |
local CallbackDummy = { Fire = function() end } |
local DBObjectLib = {} |
--[[------------------------------------------------------------------------- |
AceDB Utility Functions |
---------------------------------------------------------------------------]] |
-- Simple shallow copy for copying defaults |
local function copyTable(src, dest) |
if type(dest) ~= "table" then dest = {} end |
if type(src) == "table" then |
for k,v in pairs(src) do |
if type(v) == "table" then |
-- try to index the key first so that the metatable creates the defaults, if set, and use that table |
v = copyTable(v, dest[k]) |
end |
dest[k] = v |
end |
end |
return dest |
end |
-- Called to add defaults to a section of the database |
-- |
-- When a ["*"] default section is indexed with a new key, a table is returned |
-- and set in the host table. These tables must be cleaned up by removeDefaults |
-- in order to ensure we don't write empty default tables. |
local function copyDefaults(dest, src) |
-- this happens if some value in the SV overwrites our default value with a non-table |
--if type(dest) ~= "table" then return end |
for k, v in pairs(src) do |
if k == "*" or k == "**" then |
if type(v) == "table" then |
-- This is a metatable used for table defaults |
local mt = { |
-- This handles the lookup and creation of new subtables |
__index = function(t,k) |
if k == nil then return nil end |
local tbl = {} |
copyDefaults(tbl, v) |
rawset(t, k, tbl) |
return tbl |
end, |
} |
setmetatable(dest, mt) |
-- handle already existing tables in the SV |
for dk, dv in pairs(dest) do |
if not rawget(src, dk) and type(dv) == "table" then |
copyDefaults(dv, v) |
end |
end |
else |
-- Values are not tables, so this is just a simple return |
local mt = {__index = function(t,k) return k~=nil and v or nil end} |
setmetatable(dest, mt) |
end |
elseif type(v) == "table" then |
if not rawget(dest, k) then rawset(dest, k, {}) end |
if type(dest[k]) == "table" then |
copyDefaults(dest[k], v) |
if src['**'] then |
copyDefaults(dest[k], src['**']) |
end |
end |
else |
if rawget(dest, k) == nil then |
rawset(dest, k, v) |
end |
end |
end |
end |
-- Called to remove all defaults in the default table from the database |
local function removeDefaults(db, defaults, blocker) |
-- remove all metatables from the db, so we don't accidentally create new sub-tables through them |
setmetatable(db, nil) |
-- loop through the defaults and remove their content |
for k,v in pairs(defaults) do |
if k == "*" or k == "**" then |
if type(v) == "table" then |
-- Loop through all the actual k,v pairs and remove |
for key, value in pairs(db) do |
if type(value) == "table" then |
-- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables |
if defaults[key] == nil and (not blocker or blocker[key] == nil) then |
removeDefaults(value, v) |
-- if the table is empty afterwards, remove it |
if next(value) == nil then |
db[key] = nil |
end |
-- if it was specified, only strip ** content, but block values which were set in the key table |
elseif k == "**" then |
removeDefaults(value, v, defaults[key]) |
end |
end |
end |
elseif k == "*" then |
-- check for non-table default |
for key, value in pairs(db) do |
if defaults[key] == nil and v == value then |
db[key] = nil |
end |
end |
end |
elseif type(v) == "table" and type(db[k]) == "table" then |
-- if a blocker was set, dive into it, to allow multi-level defaults |
removeDefaults(db[k], v, blocker and blocker[k]) |
if next(db[k]) == nil then |
db[k] = nil |
end |
else |
-- check if the current value matches the default, and that its not blocked by another defaults table |
if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then |
db[k] = nil |
end |
end |
end |
end |
-- This is called when a table section is first accessed, to set up the defaults |
local function initSection(db, section, svstore, key, defaults) |
local sv = rawget(db, "sv") |
local tableCreated |
if not sv[svstore] then sv[svstore] = {} end |
if not sv[svstore][key] then |
sv[svstore][key] = {} |
tableCreated = true |
end |
local tbl = sv[svstore][key] |
if defaults then |
copyDefaults(tbl, defaults) |
end |
rawset(db, section, tbl) |
return tableCreated, tbl |
end |
-- Metatable to handle the dynamic creation of sections and copying of sections. |
local dbmt = { |
__index = function(t, section) |
local keys = rawget(t, "keys") |
local key = keys[section] |
if key then |
local defaultTbl = rawget(t, "defaults") |
local defaults = defaultTbl and defaultTbl[section] |
if section == "profile" then |
local new = initSection(t, section, "profiles", key, defaults) |
if new then |
-- Callback: OnNewProfile, database, newProfileKey |
t.callbacks:Fire("OnNewProfile", t, key) |
end |
elseif section == "profiles" then |
local sv = rawget(t, "sv") |
if not sv.profiles then sv.profiles = {} end |
rawset(t, "profiles", sv.profiles) |
elseif section == "global" then |
local sv = rawget(t, "sv") |
if not sv.global then sv.global = {} end |
if defaults then |
copyDefaults(sv.global, defaults) |
end |
rawset(t, section, sv.global) |
else |
initSection(t, section, section, key, defaults) |
end |
end |
return rawget(t, section) |
end |
} |
local function validateDefaults(defaults, keyTbl, offset) |
if not defaults then return end |
offset = offset or 0 |
for k in pairs(defaults) do |
if not keyTbl[k] or k == "profiles" then |
error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset) |
end |
end |
end |
local preserve_keys = { |
["callbacks"] = true, |
["RegisterCallback"] = true, |
["UnregisterCallback"] = true, |
["UnregisterAllCallbacks"] = true, |
["children"] = true, |
} |
local realmKey = GetRealmName() |
local charKey = UnitName("player") .. " - " .. realmKey |
local _, classKey = UnitClass("player") |
local _, raceKey = UnitRace("player") |
local factionKey = UnitFactionGroup("player") |
local factionrealmKey = factionKey .. " - " .. realmKey |
local factionrealmregionKey = factionrealmKey .. " - " .. string.sub(GetCVar("realmList"), 1, 2):upper() |
local localeKey = GetLocale():lower() |
-- Actual database initialization function |
local function initdb(sv, defaults, defaultProfile, olddb, parent) |
-- Generate the database keys for each section |
-- map "true" to our "Default" profile |
if defaultProfile == true then defaultProfile = "Default" end |
local profileKey |
if not parent then |
-- Make a container for profile keys |
if not sv.profileKeys then sv.profileKeys = {} end |
-- Try to get the profile selected from the char db |
profileKey = sv.profileKeys[charKey] or defaultProfile or charKey |
-- save the selected profile for later |
sv.profileKeys[charKey] = profileKey |
else |
-- Use the profile of the parents DB |
profileKey = parent.keys.profile or defaultProfile or charKey |
-- clear the profileKeys in the DB, namespaces don't need to store them |
sv.profileKeys = nil |
end |
-- This table contains keys that enable the dynamic creation |
-- of each section of the table. The 'global' and 'profiles' |
-- have a key of true, since they are handled in a special case |
local keyTbl= { |
["char"] = charKey, |
["realm"] = realmKey, |
["class"] = classKey, |
["race"] = raceKey, |
["faction"] = factionKey, |
["factionrealm"] = factionrealmKey, |
["factionrealmregion"] = factionrealmregionKey, |
["profile"] = profileKey, |
["locale"] = localeKey, |
["global"] = true, |
["profiles"] = true, |
} |
validateDefaults(defaults, keyTbl, 1) |
-- This allows us to use this function to reset an entire database |
-- Clear out the old database |
if olddb then |
for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end |
end |
-- Give this database the metatable so it initializes dynamically |
local db = setmetatable(olddb or {}, dbmt) |
if not rawget(db, "callbacks") then |
-- try to load CallbackHandler-1.0 if it loaded after our library |
if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end |
db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy |
end |
-- Copy methods locally into the database object, to avoid hitting |
-- the metatable when calling methods |
if not parent then |
for name, func in pairs(DBObjectLib) do |
db[name] = func |
end |
else |
-- hack this one in |
db.RegisterDefaults = DBObjectLib.RegisterDefaults |
db.ResetProfile = DBObjectLib.ResetProfile |
end |
-- Set some properties in the database object |
db.profiles = sv.profiles |
db.keys = keyTbl |
db.sv = sv |
--db.sv_name = name |
db.defaults = defaults |
db.parent = parent |
-- store the DB in the registry |
AceDB.db_registry[db] = true |
return db |
end |
-- handle PLAYER_LOGOUT |
-- strip all defaults from all databases |
-- and cleans up empty sections |
local function logoutHandler(frame, event) |
if event == "PLAYER_LOGOUT" then |
for db in pairs(AceDB.db_registry) do |
db.callbacks:Fire("OnDatabaseShutdown", db) |
db:RegisterDefaults(nil) |
-- cleanup sections that are empty without defaults |
local sv = rawget(db, "sv") |
for section in pairs(db.keys) do |
if rawget(sv, section) then |
-- global is special, all other sections have sub-entrys |
-- also don't delete empty profiles on main dbs, only on namespaces |
if section ~= "global" and (section ~= "profiles" or rawget(db, "parent")) then |
for key in pairs(sv[section]) do |
if not next(sv[section][key]) then |
sv[section][key] = nil |
end |
end |
end |
if not next(sv[section]) then |
sv[section] = nil |
end |
end |
end |
end |
end |
end |
AceDB.frame:RegisterEvent("PLAYER_LOGOUT") |
AceDB.frame:SetScript("OnEvent", logoutHandler) |
--[[------------------------------------------------------------------------- |
AceDB Object Method Definitions |
---------------------------------------------------------------------------]] |
--- Sets the defaults table for the given database object by clearing any |
-- that are currently set, and then setting the new defaults. |
-- @param defaults A table of defaults for this database |
function DBObjectLib:RegisterDefaults(defaults) |
if defaults and type(defaults) ~= "table" then |
error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2) |
end |
validateDefaults(defaults, self.keys) |
-- Remove any currently set defaults |
if self.defaults then |
for section,key in pairs(self.keys) do |
if self.defaults[section] and rawget(self, section) then |
removeDefaults(self[section], self.defaults[section]) |
end |
end |
end |
-- Set the DBObject.defaults table |
self.defaults = defaults |
-- Copy in any defaults, only touching those sections already created |
if defaults then |
for section,key in pairs(self.keys) do |
if defaults[section] and rawget(self, section) then |
copyDefaults(self[section], defaults[section]) |
end |
end |
end |
end |
--- Changes the profile of the database and all of it's namespaces to the |
-- supplied named profile |
-- @param name The name of the profile to set as the current profile |
function DBObjectLib:SetProfile(name) |
if type(name) ~= "string" then |
error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2) |
end |
-- changing to the same profile, dont do anything |
if name == self.keys.profile then return end |
local oldProfile = self.profile |
local defaults = self.defaults and self.defaults.profile |
-- Callback: OnProfileShutdown, database |
self.callbacks:Fire("OnProfileShutdown", self) |
if oldProfile and defaults then |
-- Remove the defaults from the old profile |
removeDefaults(oldProfile, defaults) |
end |
self.profile = nil |
self.keys["profile"] = name |
-- if the storage exists, save the new profile |
-- this won't exist on namespaces. |
if self.sv.profileKeys then |
self.sv.profileKeys[charKey] = name |
end |
-- populate to child namespaces |
if self.children then |
for _, db in pairs(self.children) do |
DBObjectLib.SetProfile(db, name) |
end |
end |
-- Callback: OnProfileChanged, database, newProfileKey |
self.callbacks:Fire("OnProfileChanged", self, name) |
end |
--- Returns a table with the names of the existing profiles in the database. |
-- You can optionally supply a table to re-use for this purpose. |
-- @param tbl A table to store the profile names in (optional) |
function DBObjectLib:GetProfiles(tbl) |
if tbl and type(tbl) ~= "table" then |
error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2) |
end |
-- Clear the container table |
if tbl then |
for k,v in pairs(tbl) do tbl[k] = nil end |
else |
tbl = {} |
end |
local curProfile = self.keys.profile |
local i = 0 |
for profileKey in pairs(self.profiles) do |
i = i + 1 |
tbl[i] = profileKey |
if curProfile and profileKey == curProfile then curProfile = nil end |
end |
-- Add the current profile, if it hasn't been created yet |
if curProfile then |
i = i + 1 |
tbl[i] = curProfile |
end |
return tbl, i |
end |
--- Returns the current profile name used by the database |
function DBObjectLib:GetCurrentProfile() |
return self.keys.profile |
end |
--- Deletes a named profile. This profile must not be the active profile. |
-- @param name The name of the profile to be deleted |
-- @param silent If true, do not raise an error when the profile does not exist |
function DBObjectLib:DeleteProfile(name, silent) |
if type(name) ~= "string" then |
error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2) |
end |
if self.keys.profile == name then |
error("Cannot delete the active profile in an AceDBObject.", 2) |
end |
if not rawget(self.profiles, name) and not silent then |
error("Cannot delete profile '" .. name .. "'. It does not exist.", 2) |
end |
self.profiles[name] = nil |
-- populate to child namespaces |
if self.children then |
for _, db in pairs(self.children) do |
DBObjectLib.DeleteProfile(db, name, true) |
end |
end |
-- Callback: OnProfileDeleted, database, profileKey |
self.callbacks:Fire("OnProfileDeleted", self, name) |
end |
--- Copies a named profile into the current profile, overwriting any conflicting |
-- settings. |
-- @param name The name of the profile to be copied into the current profile |
-- @param silent If true, do not raise an error when the profile does not exist |
function DBObjectLib:CopyProfile(name, silent) |
if type(name) ~= "string" then |
error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2) |
end |
if name == self.keys.profile then |
error("Cannot have the same source and destination profiles.", 2) |
end |
if not rawget(self.profiles, name) and not silent then |
error("Cannot copy profile '" .. name .. "'. It does not exist.", 2) |
end |
-- Reset the profile before copying |
DBObjectLib.ResetProfile(self, nil, true) |
local profile = self.profile |
local source = self.profiles[name] |
copyTable(source, profile) |
-- populate to child namespaces |
if self.children then |
for _, db in pairs(self.children) do |
DBObjectLib.CopyProfile(db, name, true) |
end |
end |
-- Callback: OnProfileCopied, database, sourceProfileKey |
self.callbacks:Fire("OnProfileCopied", self, name) |
end |
--- Resets the current profile to the default values (if specified). |
-- @param noChildren if set to true, the reset will not be populated to the child namespaces of this DB object |
-- @param noCallbacks if set to true, won't fire the OnProfileReset callback |
function DBObjectLib:ResetProfile(noChildren, noCallbacks) |
local profile = self.profile |
for k,v in pairs(profile) do |
profile[k] = nil |
end |
local defaults = self.defaults and self.defaults.profile |
if defaults then |
copyDefaults(profile, defaults) |
end |
-- populate to child namespaces |
if self.children and not noChildren then |
for _, db in pairs(self.children) do |
DBObjectLib.ResetProfile(db, nil, noCallbacks) |
end |
end |
-- Callback: OnProfileReset, database |
if not noCallbacks then |
self.callbacks:Fire("OnProfileReset", self) |
end |
end |
--- Resets the entire database, using the string defaultProfile as the new default |
-- profile. |
-- @param defaultProfile The profile name to use as the default |
function DBObjectLib:ResetDB(defaultProfile) |
if defaultProfile and type(defaultProfile) ~= "string" then |
error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2) |
end |
local sv = self.sv |
for k,v in pairs(sv) do |
sv[k] = nil |
end |
local parent = self.parent |
initdb(sv, self.defaults, defaultProfile, self) |
-- fix the child namespaces |
if self.children then |
if not sv.namespaces then sv.namespaces = {} end |
for name, db in pairs(self.children) do |
if not sv.namespaces[name] then sv.namespaces[name] = {} end |
initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self) |
end |
end |
-- Callback: OnDatabaseReset, database |
self.callbacks:Fire("OnDatabaseReset", self) |
-- Callback: OnProfileChanged, database, profileKey |
self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"]) |
return self |
end |
--- Creates a new database namespace, directly tied to the database. This |
-- is a full scale database in it's own rights other than the fact that |
-- it cannot control its profile individually |
-- @param name The name of the new namespace |
-- @param defaults A table of values to use as defaults |
function DBObjectLib:RegisterNamespace(name, defaults) |
if type(name) ~= "string" then |
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2) |
end |
if defaults and type(defaults) ~= "table" then |
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2) |
end |
if self.children and self.children[name] then |
error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2) |
end |
local sv = self.sv |
if not sv.namespaces then sv.namespaces = {} end |
if not sv.namespaces[name] then |
sv.namespaces[name] = {} |
end |
local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self) |
if not self.children then self.children = {} end |
self.children[name] = newDB |
return newDB |
end |
--- Returns an already existing namespace from the database object. |
-- @param name The name of the new namespace |
-- @param silent if true, the addon is optional, silently return nil if its not found |
-- @usage |
-- local namespace = self.db:GetNamespace('namespace') |
-- @return the namespace object if found |
function DBObjectLib:GetNamespace(name, silent) |
if type(name) ~= "string" then |
error("Usage: AceDBObject:GetNamespace(name): 'name' - string expected.", 2) |
end |
if not silent and not (self.children and self.children[name]) then |
error ("Usage: AceDBObject:GetNamespace(name): 'name' - namespace does not exist.", 2) |
end |
if not self.children then self.children = {} end |
return self.children[name] |
end |
--[[------------------------------------------------------------------------- |
AceDB Exposed Methods |
---------------------------------------------------------------------------]] |
--- Creates a new database object that can be used to handle database settings and profiles. |
-- By default, an empty DB is created, using a character specific profile. |
-- |
-- You can override the default profile used by passing any profile name as the third argument, |
-- or by passing //true// as the third argument to use a globally shared profile called "Default". |
-- |
-- Note that there is no token replacement in the default profile name, passing a defaultProfile as "char" |
-- will use a profile named "char", and not a character-specific profile. |
-- @param tbl The name of variable, or table to use for the database |
-- @param defaults A table of database defaults |
-- @param defaultProfile The name of the default profile. If not set, a character specific profile will be used as the default. |
-- You can also pass //true// to use a shared global profile called "Default". |
-- @usage |
-- -- Create an empty DB using a character-specific default profile. |
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB") |
-- @usage |
-- -- Create a DB using defaults and using a shared default profile |
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true) |
function AceDB:New(tbl, defaults, defaultProfile) |
if type(tbl) == "string" then |
local name = tbl |
tbl = _G[name] |
if not tbl then |
tbl = {} |
_G[name] = tbl |
end |
end |
if type(tbl) ~= "table" then |
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2) |
end |
if defaults and type(defaults) ~= "table" then |
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2) |
end |
if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then |
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2) |
end |
return initdb(tbl, defaults, defaultProfile) |
end |
-- upgrade existing databases |
for db in pairs(AceDB.db_registry) do |
if not db.parent then |
for name,func in pairs(DBObjectLib) do |
db[name] = func |
end |
else |
db.RegisterDefaults = DBObjectLib.RegisterDefaults |
db.ResetProfile = DBObjectLib.ResetProfile |
end |
end |
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info |
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke |
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! |
local LibStub = _G[LIBSTUB_MAJOR] |
if not LibStub or LibStub.minor < LIBSTUB_MINOR then |
LibStub = LibStub or {libs = {}, minors = {} } |
_G[LIBSTUB_MAJOR] = LibStub |
LibStub.minor = LIBSTUB_MINOR |
function LibStub:NewLibrary(major, minor) |
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") |
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") |
local oldminor = self.minors[major] |
if oldminor and oldminor >= minor then return nil end |
self.minors[major], self.libs[major] = minor, self.libs[major] or {} |
return self.libs[major], oldminor |
end |
function LibStub:GetLibrary(major, silent) |
if not self.libs[major] and not silent then |
error(("Cannot find a library instance of %q."):format(tostring(major)), 2) |
end |
return self.libs[major], self.minors[major] |
end |
function LibStub:IterateLibraries() return pairs(self.libs) end |
setmetatable(LibStub, { __call = LibStub.GetLibrary }) |
end |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="core\AddonHandler.lua"/> |
<Script file="AddonData\AddonData.lua"/> |
<Script file="AddonData\Bartender4.lua"/> |
<Script file="AddonData\kgPanels.lua"/> |
<Script file="AddonData\OmniCC.lua"/> |
<Script file="AddonData\Raven.lua"/> |
<Script file="AddonData\Skada.lua"/> |
<Script file="AddonData\xCT+.lua"/> |
</Ui> |
-------------------------------------------------------------------------- |
-- SoopUI Version 3.0.0 Beta 1 |
-- For help please check WoWinterface or TopShelfSargeras.com |
-- You can reach me on Twitter @TrueSteve or Soopie (Sargeras [US] Alliance) |
-- http://www.wowinterface.com/downloads/info22541-SoopUI.html |
-------------------------------------------------------------------------- |
local SoopUI = LibStub("AceAddon-3.0"):NewAddon("SoopUI", "AceEvent-3.0", "AceConsole-3.0"); |
local db, dbc, dbg, suidb |
_G.SoopUI = SoopUI |
local global_defaults = { |
global = { |
install = { |
doneonce = false |
}, |
}, |
} |
local defaults = { |
global = { |
install = { |
stage = -1, |
}, |
tags = { |
firsttime = true, |
uaor = -1, |
}, |
}, |
char = { |
layout = { |
current = 1, -- 1 = tank, 2 = heal |
}, |
}, |
profile = { |
modules = { |
['*'] = true, |
}, |
registeredChars = {}, |
other = { |
uiscaler = true, |
}, |
}, |
} |
-------------------------------------------------------------------------- |
-- Media constants |
-------------------------------------------------------------------------- |
SoopUI.media = { |
logoBG = "Interface\\AddOns\\SoopUI\\media\\logo", |
logoText ="Interface\\AddOns\\SoopUI\\media\\logo_sui", |
plain = "Interface\\AddOns\\SoopUI\\media\\Plain", |
blank = "Interface\\AddOns\\SoopUI\\media\\blank", |
highlight_texture = "Interface\\AddOns\\SoopUI\\media\\raidbg", |
backdrop_edge_texture = "Interface\\AddOns\\SoopUI\\media\\backdrop_edge", |
backdrop_texture = "Interface\\AddOns\\SoopUI\\media\\backdrop", |
powerbar_texture = "Interface\\AddOns\\SoopUI\\media\\Minimalist", |
iconborder = "Interface\\AddOns\\SoopUI\\media\\iconborder", |
---- Font |
express = "Interface\\AddOns\\SoopUI\\media\\expressway.ttf", |
} |
function SoopUI:PLAYER_LOGIN() |
if dbg.tags.firsttime then |
SoopUI:NewInstallProcess() |
end |
end |
function SoopUI:OnEnable() |
if not(suidb.install.doneonce) then |
SoopUI:LoadAddOnData() |
suidb.install.doneonce = true |
end |
end |
-------------------------------------------------------------------------- |
-- SoopUI Scaling |
-------------------------------------------------------------------------- |
function SoopUI:UpdateUIScale() |
local scale = max(0.64, min(1.15, 768/GetScreenHeight())) |
if SoopUI:Round(UIParent:GetScale(), 5) ~= SoopUI:Round(scale, 5) then |
SetCVar("useUiScale", 1); |
SetCVar("uiScale", scale); |
WorldMapFrame.hasTaint = true; |
end |
end |
function SoopUI:VARIABLES_LOADED() |
self:UpdateUIScale() |
function SoopUI:UI_SCALE_CHANGED() |
self:UpdateUIScale() |
end |
-------------------------------------------------------------------------- |
-- Misc fixes inc Blizzard Bug Fixes by Nibelheim |
-------------------------------------------------------------------------- |
------ No Map Emote |
hooksecurefunc("DoEmote", function(emote) |
if emote == "READ" and WorldMapFrame:IsShown() then |
CancelEmote() |
end |
end) |
hooksecurefunc("StaticPopup_Show", function(msg) |
if msg == "ADDON_ACTION_FORBIDDEN" then |
StaticPopup_Hide(msg) |
end |
end) |
------ Fix Regeant shift+clicking in TradeSkill window |
LoadAddOn("Blizzard_TradeSkillUI") |
local function TradeSkillReagent_OnClick(self) |
local link, name = GetTradeSkillReagentItemLink(TradeSkillFrame.selectedSkill, self:GetID()) |
if not link then |
name, link = GameTooltip:GetItem() |
if name ~= self.name:GetText() then |
return |
end |
end |
HandleModifiedItemClick(link) |
end |
for i = 1, 8 do |
_G["TradeSkillReagent"..i]:SetScript("OnClick", TradeSkillReagent_OnClick) |
end |
end |
-------------------------------------------------------------------------- |
-- Initialization for SoopUI |
-------------------------------------------------------------------------- |
function SoopUI:OnInitialize() |
SUI_DB = LibStub("AceDB-3.0"):New("SoopUIDB", global_defaults, "SoopUI"); |
self.db = LibStub("AceDB-3.0"):New("SoopUICharacter", defaults, "SoopUI"); |
suidb = SUI_DB.global |
db = self.db.profile |
dbc = self.db.char |
dbg = self.db.global |
self.realm = GetRealmName() |
self.name = UnitName("player") |
self.key = string.format("%s - %s", self.name, self.realm) |
self.cLayout = dbc.layout.current |
self.ncLayout = self.cLayout == 1 and 2 or 1 |
self.playerClass = UnitClass("player") |
self.version = GetAddOnMetadata("SoopUI","version") |
self.width = GetScreenWidth() |
self.height = GetScreenHeight() |
SoopUI:CheckResolution() |
-------------------------------- Disable Raid Frames |
CompactRaidFrameManagerDisplayFrameHiddenModeToggle:SetAlpha(0) |
CompactRaidFrameManager:UnregisterAllEvents() |
CompactRaidFrameManager.Show = function() end |
CompactRaidFrameManager:Hide() |
CompactRaidFrameContainer:UnregisterAllEvents() |
CompactRaidFrameContainer:Hide() |
--self:RegisterEvent("ADDON_LOADED") |
self:RegisterEvent("PLAYER_LOGIN") |
self:RegisterEvent("UI_SCALE_CHANGED") |
--self:RegisterEvent("PLAYER_ENTERING_WORLD") |
self:RegisterEvent("VARIABLES_LOADED") |
print("This is SoopUI. You are running version: "..GetAddOnMetadata("SoopUI","version")) |
print("Type '/suihelp' to show commands and to get help.") |
end |
-------------------------------------------------------------------------- |
-- Rounding code by Doomkitty |
-------------------------------------------------------------------------- |
function SoopUI:Round(num, idp) |
if(idp and idp > 0) then |
local mult = 10 ^ idp |
return floor(num * mult + 0.5) / mult |
end |
return floor(num + 0.5) |
end |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI"); |
SoopUI.LoadAddOnData_Skada = function() |
SkadaDB = { |
["namespaces"] = { |
}, |
["profileKeys"] = { |
}, |
["profiles"] = { |
["Healing"] = { |
["report"] = { |
["chantype"] = "whisper", |
["set"] = 1, |
["target"] = "cjk", |
["mode"] = "Healing", |
["channel"] = "whisper", |
}, |
["windows"] = { |
{ |
["barheight"] = 10, |
["barbgcolor"] = { |
["a"] = 0.2000000476837158, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["barcolor"] = { |
["r"] = 0.1568627450980392, |
["g"] = 0.1568627450980392, |
["b"] = 0.1568627450980392, |
}, |
["barfontsize"] = 8, |
["classicons"] = false, |
["barslocked"] = true, |
["background"] = { |
["color"] = { |
["a"] = 0.5240960121154785, |
["r"] = 0.1411764705882353, |
["g"] = 0.1411764705882353, |
["b"] = 0.1411764705882353, |
}, |
["height"] = 55.94948577880859, |
}, |
["point"] = "BOTTOMRIGHT", |
["mode"] = "Healing", |
["x"] = -131.459228515625, |
["bartexture"] = "fer28", |
["barwidth"] = 158.0821990966797, |
["barspacing"] = 2, |
["hidden"] = true, |
["name"] = "Healing", |
["y"] = 0, |
["barfont"] = "Expressway", |
["title"] = { |
["color"] = { |
["a"] = 1, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["bordertexture"] = "fer09", |
["font"] = "Expressway", |
["fontsize"] = 12, |
["borderthickness"] = 0, |
["height"] = 17, |
["fontflags"] = "OUTLINE", |
["margin"] = 10, |
["texture"] = "fer01", |
}, |
["classcolorbars"] = false, |
["modeincombat"] = "Healing", |
["buttons"] = { |
["menu"] = false, |
}, |
["barfontflags"] = "OUTLINE", |
["classcolortext"] = true, |
}, -- [1] |
{ |
["barheight"] = 10, |
["classicons"] = false, |
["barslocked"] = true, |
["background"] = { |
["borderthickness"] = 0, |
["height"] = 134.7484283447266, |
["color"] = { |
["a"] = 0.5120473504066467, |
["b"] = 0.1411764705882353, |
["g"] = 0.1372549019607843, |
["r"] = 0.1333333333333333, |
}, |
["bordertexture"] = "None", |
["margin"] = 0, |
["texture"] = "Solid", |
}, |
["wipemode"] = "", |
["set"] = "current", |
["hidden"] = true, |
["y"] = 0, |
["barfont"] = "Expressway", |
["title"] = { |
["color"] = { |
["a"] = 1, |
["b"] = 0.02352941176470588, |
["g"] = 0.02352941176470588, |
["r"] = 0.02352941176470588, |
}, |
["bordertexture"] = "fer09", |
["font"] = "Expressway", |
["borderthickness"] = 0, |
["fontsize"] = 12, |
["fontflags"] = "OUTLINE", |
["height"] = 17, |
["margin"] = 10, |
["texture"] = "fer01", |
}, |
["display"] = "bar", |
["barfontflags"] = "OUTLINE", |
["classcolortext"] = true, |
["barbgcolor"] = { |
["a"] = 0.2100000381469727, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["reversegrowth"] = false, |
["returnaftercombat"] = false, |
["barorientation"] = 1, |
["snapto"] = true, |
["point"] = "BOTTOMRIGHT", |
["bartexture"] = "fer28", |
["buttons"] = { |
["segment"] = true, |
["menu"] = false, |
["mode"] = true, |
["report"] = true, |
["reset"] = true, |
}, |
["barwidth"] = 124.8616104125977, |
["barspacing"] = 2, |
["clickthrough"] = false, |
["mode"] = "Damage", |
["scale"] = 1, |
["enabletitle"] = true, |
["barcolor"] = { |
["a"] = 1, |
["r"] = 0.1450980392156863, |
["g"] = 0.1450980392156863, |
["b"] = 0.1450980392156863, |
}, |
["classcolorbars"] = false, |
["barfontsize"] = 8, |
["name"] = "Damage", |
["modeincombat"] = "Damage", |
["x"] = -0.0003662109375, |
}, -- [2] |
{ |
["barheight"] = 15, |
["classicons"] = true, |
["barslocked"] = true, |
["background"] = { |
["borderthickness"] = 0, |
["height"] = 61.9998664855957, |
["color"] = { |
["a"] = 0.4759032726287842, |
["b"] = 0.1254901960784314, |
["g"] = 0.1137254901960784, |
["r"] = 0.1137254901960784, |
}, |
["bordertexture"] = "None", |
["margin"] = 0, |
["texture"] = "Solid", |
}, |
["wipemode"] = "Threat", |
["set"] = "current", |
["hidden"] = true, |
["y"] = 71.00059509277344, |
["barfont"] = "Expressway", |
["title"] = { |
["color"] = { |
["a"] = 0, |
["b"] = 0.1254901960784314, |
["g"] = 0.1215686274509804, |
["r"] = 0.1176470588235294, |
}, |
["bordertexture"] = "fer09", |
["font"] = "Expressway", |
["fontsize"] = 12, |
["borderthickness"] = 0, |
["height"] = 15, |
["fontflags"] = "OUTLINE", |
["margin"] = 10, |
["texture"] = "fer01", |
}, |
["display"] = "bar", |
["barfontflags"] = "", |
["classcolortext"] = false, |
["scale"] = 1, |
["barcolor"] = { |
["a"] = 1, |
["b"] = 0.8, |
["g"] = 0.3, |
["r"] = 0.3, |
}, |
["barfontsize"] = 11, |
["barorientation"] = 1, |
["snapto"] = true, |
["enabletitle"] = true, |
["modeincombat"] = "Threat", |
["buttons"] = { |
["report"] = false, |
["menu"] = false, |
["mode"] = false, |
["segment"] = true, |
["reset"] = true, |
}, |
["barwidth"] = 160.9998931884766, |
["barspacing"] = 0, |
["x"] = -131.000244140625, |
["returnaftercombat"] = false, |
["barbgcolor"] = { |
["a"] = 0.6, |
["r"] = 0.3, |
["g"] = 0.3, |
["b"] = 0.3, |
}, |
["mode"] = "Threat", |
["reversegrowth"] = false, |
["classcolorbars"] = true, |
["name"] = "Threat", |
["clickthrough"] = false, |
["bartexture"] = "BantoBar", |
["point"] = "BOTTOMRIGHT", |
}, -- [3] |
}, |
["columns"] = { |
["Damage_Percent"] = false, |
["Damage_Damage"] = true, |
}, |
["hidesolo"] = true, |
["onlykeepbosses"] = true, |
["icon"] = { |
["minimapPos"] = 339.2935634710895, |
["hide"] = true, |
}, |
["feed"] = "Damage: Personal DPS", |
["reset"] = { |
["join"] = 2, |
}, |
}, |
["Tank"] = { |
["report"] = { |
["chantype"] = "whisper", |
["set"] = 1, |
["target"] = "cjk", |
["mode"] = "Healing", |
["channel"] = "whisper", |
}, |
["windows"] = { |
{ |
["barheight"] = 10, |
["barbgcolor"] = { |
["a"] = 0.2000000476837158, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["barcolor"] = { |
["r"] = 0.1568627450980392, |
["g"] = 0.1568627450980392, |
["b"] = 0.1568627450980392, |
}, |
["barfontsize"] = 8, |
["classicons"] = false, |
["barslocked"] = true, |
["background"] = { |
["color"] = { |
["a"] = 0.5240960121154785, |
["r"] = 0.1411764705882353, |
["g"] = 0.1411764705882353, |
["b"] = 0.1411764705882353, |
}, |
["height"] = 55.94948577880859, |
}, |
["point"] = "BOTTOMRIGHT", |
["mode"] = "Healing", |
["x"] = -131.459228515625, |
["bartexture"] = "fer28", |
["barwidth"] = 158.0821990966797, |
["barspacing"] = 2, |
["hidden"] = true, |
["name"] = "Healing", |
["y"] = 0, |
["barfont"] = "Expressway", |
["title"] = { |
["color"] = { |
["a"] = 1, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["bordertexture"] = "fer09", |
["font"] = "Expressway", |
["fontsize"] = 12, |
["borderthickness"] = 0, |
["height"] = 17, |
["fontflags"] = "OUTLINE", |
["margin"] = 10, |
["texture"] = "fer01", |
}, |
["classcolorbars"] = false, |
["modeincombat"] = "Healing", |
["buttons"] = { |
["menu"] = false, |
}, |
["barfontflags"] = "OUTLINE", |
["classcolortext"] = true, |
}, -- [1] |
{ |
["barheight"] = 10, |
["classicons"] = false, |
["barslocked"] = true, |
["background"] = { |
["borderthickness"] = 0, |
["height"] = 134.7484283447266, |
["color"] = { |
["a"] = 0.5120473504066467, |
["b"] = 0.1411764705882353, |
["g"] = 0.1372549019607843, |
["r"] = 0.1333333333333333, |
}, |
["bordertexture"] = "None", |
["margin"] = 0, |
["texture"] = "Solid", |
}, |
["wipemode"] = "", |
["set"] = "current", |
["hidden"] = true, |
["y"] = 0, |
["barfont"] = "Expressway", |
["title"] = { |
["color"] = { |
["a"] = 1, |
["b"] = 0.02352941176470588, |
["g"] = 0.02352941176470588, |
["r"] = 0.02352941176470588, |
}, |
["bordertexture"] = "fer09", |
["font"] = "Expressway", |
["borderthickness"] = 0, |
["fontsize"] = 12, |
["fontflags"] = "OUTLINE", |
["height"] = 17, |
["margin"] = 10, |
["texture"] = "fer01", |
}, |
["display"] = "bar", |
["barfontflags"] = "OUTLINE", |
["classcolortext"] = true, |
["barbgcolor"] = { |
["a"] = 0.2100000381469727, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["reversegrowth"] = false, |
["returnaftercombat"] = false, |
["barorientation"] = 1, |
["snapto"] = true, |
["point"] = "BOTTOMRIGHT", |
["bartexture"] = "fer28", |
["buttons"] = { |
["segment"] = true, |
["menu"] = false, |
["mode"] = true, |
["report"] = true, |
["reset"] = true, |
}, |
["barwidth"] = 124.8616104125977, |
["barspacing"] = 2, |
["clickthrough"] = false, |
["mode"] = "Damage", |
["scale"] = 1, |
["enabletitle"] = true, |
["barcolor"] = { |
["a"] = 1, |
["r"] = 0.1450980392156863, |
["g"] = 0.1450980392156863, |
["b"] = 0.1450980392156863, |
}, |
["classcolorbars"] = false, |
["barfontsize"] = 8, |
["name"] = "Damage", |
["modeincombat"] = "Damage", |
["x"] = -0.0003662109375, |
}, -- [2] |
{ |
["barheight"] = 15, |
["classicons"] = true, |
["barslocked"] = true, |
["background"] = { |
["borderthickness"] = 0, |
["height"] = 61.9998664855957, |
["color"] = { |
["a"] = 0.4759032726287842, |
["b"] = 0.1254901960784314, |
["g"] = 0.1137254901960784, |
["r"] = 0.1137254901960784, |
}, |
["bordertexture"] = "None", |
["margin"] = 0, |
["texture"] = "Solid", |
}, |
["wipemode"] = "Threat", |
["set"] = "current", |
["hidden"] = true, |
["y"] = 71.00059509277344, |
["barfont"] = "Expressway", |
["title"] = { |
["color"] = { |
["a"] = 0, |
["b"] = 0.1254901960784314, |
["g"] = 0.1215686274509804, |
["r"] = 0.1176470588235294, |
}, |
["bordertexture"] = "fer09", |
["font"] = "Expressway", |
["fontsize"] = 12, |
["borderthickness"] = 0, |
["height"] = 15, |
["fontflags"] = "OUTLINE", |
["margin"] = 10, |
["texture"] = "fer01", |
}, |
["display"] = "bar", |
["barfontflags"] = "", |
["classcolortext"] = false, |
["scale"] = 1, |
["barcolor"] = { |
["a"] = 1, |
["b"] = 0.8, |
["g"] = 0.3, |
["r"] = 0.3, |
}, |
["barfontsize"] = 11, |
["barorientation"] = 1, |
["snapto"] = true, |
["enabletitle"] = true, |
["modeincombat"] = "Threat", |
["buttons"] = { |
["report"] = false, |
["menu"] = false, |
["mode"] = false, |
["segment"] = true, |
["reset"] = true, |
}, |
["barwidth"] = 160.9998931884766, |
["barspacing"] = 0, |
["x"] = -131.000244140625, |
["returnaftercombat"] = false, |
["barbgcolor"] = { |
["a"] = 0.6, |
["r"] = 0.3, |
["g"] = 0.3, |
["b"] = 0.3, |
}, |
["mode"] = "Threat", |
["reversegrowth"] = false, |
["classcolorbars"] = true, |
["name"] = "Threat", |
["clickthrough"] = false, |
["bartexture"] = "BantoBar", |
["point"] = "BOTTOMRIGHT", |
}, -- [3] |
}, |
["columns"] = { |
["Damage_Percent"] = false, |
["Damage_Damage"] = true, |
}, |
["hidesolo"] = true, |
["onlykeepbosses"] = true, |
["icon"] = { |
["minimapPos"] = 339.2935634710895, |
["hide"] = true, |
}, |
["feed"] = "Damage: Personal DPS", |
["reset"] = { |
["join"] = 2, |
}, |
}, |
}, |
} |
end |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI"); |
SoopUI.LoadAddOnData_kgPanels = function() |
kgPanelsDB = { |
["namespaces"] = { |
["LibDualSpec-1.0"] = { |
}, |
}, |
["global"] = { |
["layouts"] = { |
["SoopUI"] = { |
["World Markers"] = { |
["border_advanced"] = { |
["enable"] = false, |
["show"] = { |
["BOTRIGHTCORNER"] = true, |
["TOPRIGHTCORNER"] = true, |
["BOTLEFTCORNER"] = true, |
["TOPLEFTCORNER"] = true, |
["RIGHT"] = true, |
["LEFT"] = true, |
["TOP"] = true, |
["BOT"] = true, |
}, |
}, |
["parent"] = "SkadaBarWindowThreat", |
["bg_orientation"] = "VERTICAL", |
["anchorFrom"] = "TOP", |
["hflip"] = false, |
["vflip"] = false, |
["tileSize"] = 0, |
["bg_texture"] = "Solid", |
["anchor"] = "SkadaBarWindowThreat", |
["level"] = 0, |
["use_absolute_bg"] = false, |
["bg_blend"] = "ALPHAKEY", |
["text"] = { |
["y"] = 0, |
["font"] = "Blizzard", |
["justifyH"] = "CENTER", |
["x"] = 0, |
["color"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["text"] = "", |
["justifyV"] = "MIDDLE", |
["size"] = 12, |
}, |
["y"] = 82.00003051757813, |
["x"] = -21.99989700317383, |
["bg_alpha"] = 0.655, |
["border_edgeSize"] = 8, |
["height"] = 187.0000152587891, |
["tiling"] = false, |
["strata"] = "MEDIUM", |
["anchorTo"] = "BOTTOMLEFT", |
["absolute_bg"] = { |
["LRy"] = 1, |
["LRx"] = 1, |
["ULx"] = 0, |
["ULy"] = 0, |
["URy"] = 0, |
["URx"] = 1, |
["LLx"] = 0, |
["LLy"] = 1, |
}, |
["crop"] = false, |
["scripts"] = { |
}, |
["bg_style"] = "SOLID", |
["gradient_color"] = { |
["a"] = 0, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["border_color"] = { |
["a"] = 1, |
["b"] = 0, |
["g"] = 0, |
["r"] = 0, |
}, |
["border_texture"] = "fer08", |
["width"] = 29.99996185302734, |
["bg_insets"] = { |
["r"] = -4, |
["t"] = -4, |
["l"] = 4, |
["b"] = 4, |
}, |
["bg_color"] = { |
["a"] = 0.6084332168102264, |
["b"] = 0, |
["g"] = 0, |
["r"] = 0, |
}, |
["mouse"] = false, |
["rotation"] = 0, |
["sub_level"] = 0, |
}, |
["Skada"] = { |
["border_advanced"] = { |
["enable"] = false, |
["show"] = { |
["BOTRIGHTCORNER"] = true, |
["TOPRIGHTCORNER"] = true, |
["BOTLEFTCORNER"] = true, |
["TOPLEFTCORNER"] = true, |
["RIGHT"] = true, |
["LEFT"] = true, |
["TOP"] = true, |
["BOT"] = true, |
}, |
}, |
["parent"] = "SkadaBarWindowThreat", |
["bg_orientation"] = "VERTICAL", |
["anchorFrom"] = "CENTER", |
["hflip"] = false, |
["vflip"] = false, |
["tileSize"] = 0, |
["bg_texture"] = "Solid", |
["anchor"] = "SkadaBarWindowThreat", |
["level"] = 0, |
["use_absolute_bg"] = false, |
["bg_blend"] = "BLEND", |
["text"] = { |
["y"] = 0, |
["font"] = "Blizzard", |
["justifyH"] = "CENTER", |
["x"] = 0, |
["color"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["text"] = "", |
["justifyV"] = "MIDDLE", |
["size"] = 12, |
}, |
["y"] = -29.00010299682617, |
["x"] = 73.00008392333984, |
["bg_alpha"] = 0.665, |
["border_edgeSize"] = 8, |
["height"] = 159.9999847412109, |
["tiling"] = false, |
["strata"] = "BACKGROUND", |
["anchorTo"] = "CENTER", |
["absolute_bg"] = { |
["LRy"] = 1, |
["LRx"] = 1, |
["ULx"] = 0, |
["ULy"] = 0, |
["URy"] = 0, |
["URx"] = 1, |
["LLx"] = 0, |
["LLy"] = 1, |
}, |
["crop"] = false, |
["scripts"] = { |
}, |
["bg_style"] = "SOLID", |
["gradient_color"] = { |
["a"] = 0, |
["r"] = 1, |
["g"] = 1, |
["b"] = 1, |
}, |
["border_color"] = { |
["a"] = 1, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["border_texture"] = "fer09", |
["width"] = "322.00030517578", |
["bg_insets"] = { |
["r"] = -4, |
["t"] = -4, |
["l"] = 4, |
["b"] = 4, |
}, |
["bg_color"] = { |
["a"] = 0.5722883641719818, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["mouse"] = false, |
["rotation"] = 0, |
["sub_level"] = 0, |
}, |
["DataText"] = { |
["border_advanced"] = { |
["enable"] = true, |
["show"] = { |
["BOT"] = true, |
["TOPRIGHTCORNER"] = true, |
["LEFT"] = true, |
["TOPLEFTCORNER"] = true, |
["RIGHT"] = true, |
["BOTLEFTCORNER"] = true, |
["TOP"] = true, |
["BOTRIGHTCORNER"] = true, |
}, |
}, |
["parent"] = "UIParent", |
["bg_orientation"] = "VERTICAL", |
["anchorFrom"] = "CENTER", |
["hflip"] = false, |
["vflip"] = false, |
["tileSize"] = 0, |
["bg_texture"] = "Solid", |
["anchor"] = "UIParent", |
["level"] = 0, |
["use_absolute_bg"] = false, |
["bg_blend"] = "BLEND", |
["text"] = { |
["y"] = 0, |
["font"] = "Blizzard", |
["justifyH"] = "CENTER", |
["x"] = 0, |
["color"] = { |
["a"] = 1, |
["r"] = 1, |
["g"] = 1, |
["b"] = 1, |
}, |
["text"] = "", |
["justifyV"] = "MIDDLE", |
["size"] = 12, |
}, |
["y"] = -530.0003086328507, |
["x"] = -792.0002358555794, |
["bg_alpha"] = 0.665, |
["border_edgeSize"] = 8, |
["height"] = 22.00000190734863, |
["tiling"] = false, |
["strata"] = "BACKGROUND", |
["anchorTo"] = "CENTER", |
["absolute_bg"] = { |
["ULx"] = 0, |
["ULy"] = 0, |
["LLy"] = 1, |
["LLx"] = 0, |
["URx"] = 1, |
["URy"] = 0, |
["LRx"] = 1, |
["LRy"] = 1, |
}, |
["crop"] = false, |
["scripts"] = { |
}, |
["bg_style"] = "SOLID", |
["gradient_color"] = { |
["a"] = 0, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["border_color"] = { |
["a"] = 1, |
["b"] = 0, |
["g"] = 0, |
["r"] = 0, |
}, |
["border_texture"] = "fer08", |
["width"] = 334.9999694824219, |
["sub_level"] = 0, |
["rotation"] = 0, |
["mouse"] = false, |
["bg_color"] = { |
["a"] = 1, |
["b"] = 0, |
["g"] = 0, |
["r"] = 0, |
}, |
["bg_insets"] = { |
["b"] = 4, |
["t"] = -4, |
["l"] = 4, |
["r"] = -4, |
}, |
}, |
["Middle"] = { |
["border_advanced"] = { |
["enable"] = false, |
["show"] = { |
["BOTRIGHTCORNER"] = true, |
["TOPRIGHTCORNER"] = true, |
["TOPLEFTCORNER"] = true, |
["BOTLEFTCORNER"] = true, |
["RIGHT"] = true, |
["LEFT"] = true, |
["TOP"] = true, |
["BOT"] = true, |
}, |
}, |
["parent"] = "UIParent", |
["bg_orientation"] = "VERTICAL", |
["anchorFrom"] = "CENTER", |
["hflip"] = false, |
["vflip"] = false, |
["tileSize"] = 0, |
["bg_texture"] = "Solid", |
["anchor"] = "UIParent", |
["level"] = 0, |
["use_absolute_bg"] = false, |
["bg_blend"] = "BLEND", |
["text"] = { |
["y"] = 0, |
["font"] = "Blizzard", |
["justifyH"] = "CENTER", |
["x"] = 0, |
["color"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["text"] = "", |
["justifyV"] = "MIDDLE", |
["size"] = 12, |
}, |
["y"] = -529.0001041921641, |
["x"] = 0.9997711181640625, |
["bg_alpha"] = 0.665, |
["border_edgeSize"] = 8, |
["height"] = 22.00000190734863, |
["tiling"] = false, |
["strata"] = "BACKGROUND", |
["anchorTo"] = "CENTER", |
["absolute_bg"] = { |
["LRy"] = 1, |
["LRx"] = 1, |
["ULx"] = 0, |
["ULy"] = 0, |
["URy"] = 0, |
["URx"] = 1, |
["LLx"] = 0, |
["LLy"] = 1, |
}, |
["crop"] = false, |
["scripts"] = { |
}, |
["bg_style"] = "SOLID", |
["gradient_color"] = { |
["a"] = 0, |
["r"] = 1, |
["g"] = 1, |
["b"] = 1, |
}, |
["border_color"] = { |
["a"] = 1, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["border_texture"] = "fer08", |
["width"] = "300.99990844727", |
["bg_insets"] = { |
["r"] = -4, |
["t"] = -4, |
["l"] = 4, |
["b"] = 4, |
}, |
["bg_color"] = { |
["a"] = 1, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["mouse"] = false, |
["rotation"] = 0, |
["sub_level"] = 0, |
}, |
["Charms"] = { |
["border_advanced"] = { |
["enable"] = false, |
["show"] = { |
["BOTRIGHTCORNER"] = true, |
["TOPRIGHTCORNER"] = true, |
["BOTLEFTCORNER"] = true, |
["TOPLEFTCORNER"] = true, |
["RIGHT"] = true, |
["LEFT"] = true, |
["TOP"] = true, |
["BOT"] = true, |
}, |
}, |
["parent"] = "UIParent", |
["bg_orientation"] = "HORIZONTAL", |
["anchorFrom"] = "TOP", |
["hflip"] = false, |
["vflip"] = false, |
["tileSize"] = 0, |
["bg_texture"] = "Solid", |
["anchor"] = "SkadaBarWindowThreat", |
["level"] = 0, |
["use_absolute_bg"] = false, |
["bg_blend"] = "BLEND", |
["text"] = { |
["y"] = 0, |
["font"] = "Blizzard", |
["justifyH"] = "CENTER", |
["x"] = 0, |
["color"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["text"] = "", |
["justifyV"] = "MIDDLE", |
["size"] = 12, |
}, |
["y"] = 94.00032043457031, |
["x"] = -1277.999872207642, |
["bg_alpha"] = 0.665, |
["border_edgeSize"] = 8, |
["height"] = 170, |
["tiling"] = false, |
["strata"] = "BACKGROUND", |
["anchorTo"] = "BOTTOMLEFT", |
["absolute_bg"] = { |
["LRy"] = 1, |
["LRx"] = 1, |
["ULx"] = 0, |
["ULy"] = 0, |
["URy"] = 0, |
["URx"] = 1, |
["LLx"] = 0, |
["LLy"] = 1, |
}, |
["crop"] = false, |
["scripts"] = { |
["SHOW"] = "\n", |
["ENTER"] = "", |
["LOAD"] = "self:RegisterEvent(\"PLAYER_REGEN_DISABLED\")\nself:RegisterEvent(\"PLAYER_REGEN_ENABLED\")", |
["HIDE"] = "", |
["UPDATE"] = "if kgPanels:FetchFrame(\"Charms\"):IsVisible() then \nself:Hide()\nelse\nself:Show()\nend", |
["EVENT"] = "if event == \"PLAYER_REGEN_ENABLED\" then\n self:Hide()\nelseif event == \"PLAYER_REGEN_DISABLED\" then\n self:Show()\nend", |
}, |
["bg_style"] = "SOLID", |
["gradient_color"] = { |
["a"] = 0, |
["r"] = 1, |
["g"] = 1, |
["b"] = 1, |
}, |
["border_color"] = { |
["a"] = 1, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["border_texture"] = "fer08", |
["width"] = 26.00019454956055, |
["bg_insets"] = { |
["r"] = -4, |
["t"] = -4, |
["l"] = 4, |
["b"] = 4, |
}, |
["bg_color"] = { |
["a"] = 0.6084332168102264, |
["r"] = 0, |
["g"] = 0, |
["b"] = 0, |
}, |
["mouse"] = false, |
["rotation"] = 0, |
["sub_level"] = 0, |
}, |
}, |
}, |
["layout_deps"] = { |
["SoopUI"] = { |
["Skada"] = "", |
["Mainbar"] = "", |
}, |
}, |
}, |
["profileKeys"] = { |
}, |
["profiles"] = { |
["Healer"] = { |
["layout"] = "SoopUI", |
}, |
["SoopUI3"] = { |
["layout"] = "SoopUI", |
}, |
["Tank"] = { |
["layout"] = "SoopUI", |
}, |
}, |
} |
end |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI"); |
SoopUI.LoadAddOnData_OmniCC = function() |
OmniCC4Config = { |
["groupSettings"] = { |
["base"] = { |
["enabled"] = true, |
["fontFace"] = "Interface\\AddOns\\SoopUI\\media\\express.ttf", |
["styles"] = { |
["minutes"] = { |
["a"] = 1, |
["r"] = 0.4, |
["scale"] = 1.000000007450581, |
["g"] = 0, |
["b"] = 1, |
}, |
["soon"] = { |
["a"] = 1, |
["r"] = 0.5529411764705883, |
["scale"] = 1.500000014901161, |
["g"] = 1, |
["b"] = 0, |
}, |
["hours"] = { |
["a"] = 1, |
["r"] = 1, |
["scale"] = 0.5, |
["g"] = 0, |
["b"] = 0.7137254901960785, |
}, |
["charging"] = { |
["a"] = 0.8, |
["r"] = 1, |
["scale"] = 0.6500000022351742, |
["g"] = 0.98, |
["b"] = 0.4, |
}, |
["seconds"] = { |
["a"] = 1, |
["r"] = 0, |
["scale"] = 1.000000007450581, |
["g"] = 0.6705882352941176, |
["b"] = 1, |
}, |
}, |
["effect"] = "pulse", |
["minDuration"] = 0, |
["mmSSDuration"] = 0, |
["anchor"] = "CENTER", |
["spiralOpacity"] = 1.009999977424741, |
["yOff"] = 0, |
["xOff"] = 2, |
["tenthsDuration"] = 0, |
["fontOutline"] = "OUTLINE", |
["minSize"] = 0.5, |
["minEffectDuration"] = 30, |
["scaleText"] = true, |
["fontSize"] = 22, |
}, |
}, |
["version"] = "5.4.3", |
["groups"] = { |
}, |
["engine"] = "AniUpdater", |
} |
end |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI") |
SoopUI.LoadAddOnData_xCT = function() |
xCTSavedDB = { |
["profileKeys"] = { |
}, |
["profiles"] = { |
["spells"] = { |
["items"] = { |
["Container"] = { |
["Bag"] = false, |
["Mining Bag"] = false, |
["Cooking Bag"] = false, |
["Gem Bag"] = false, |
["Tackle Box"] = false, |
["Engineering Bag"] = false, |
["Herb Bag"] = false, |
["Inscription Bag"] = false, |
["Leatherworking Bag"] = false, |
["Enchanting Bag"] = false, |
}, |
["Quest"] = { |
["Quest"] = false, |
}, |
["Trade Goods"] = { |
["Other"] = false, |
["Elemental"] = false, |
["Jewelcrafting"] = false, |
["Parts"] = false, |
["Enchanting"] = false, |
["Devices"] = false, |
["Cooking"] = false, |
["Leather"] = false, |
["Materials"] = false, |
["Item Enchantment"] = false, |
["Cloth"] = false, |
["Explosives"] = false, |
["Metal & Stone"] = false, |
["Herb"] = false, |
}, |
["Miscellaneous"] = { |
["Other"] = false, |
["Reagent"] = false, |
["Companion Pets"] = false, |
["Mount"] = false, |
["Holiday"] = false, |
["Junk"] = false, |
}, |
["Recipe"] = { |
["Tailoring"] = false, |
["Blacksmithing"] = false, |
["Alchemy"] = false, |
["First Aid"] = false, |
["Book"] = false, |
["Cooking"] = false, |
["Inscription"] = false, |
["Jewelcrafting"] = false, |
["Engineering"] = false, |
["Leatherworking"] = false, |
["Fishing"] = false, |
["Enchanting"] = false, |
}, |
["Consumable"] = { |
["Other"] = false, |
["Elixir"] = false, |
["Food & Drink"] = false, |
["Item Enhancement"] = false, |
["Scroll"] = false, |
["Flask"] = false, |
["Bandage"] = false, |
["Potion"] = false, |
}, |
["version"] = 1, |
["Battle Pets"] = { |
["Dragonkin"] = false, |
["Humanoid"] = false, |
["Elemental"] = false, |
["Critter"] = false, |
["Magic"] = false, |
["Flying"] = false, |
["Aquatic"] = false, |
["Undead"] = false, |
["Beast"] = false, |
["Mechanical"] = false, |
}, |
["Armor"] = { |
["Leather"] = false, |
["Cosmetic"] = false, |
["Shields"] = false, |
["Mail"] = false, |
["Plate"] = false, |
["Cloth"] = false, |
["Miscellaneous"] = false, |
}, |
["Gem"] = { |
["Simple"] = false, |
["Blue"] = false, |
["Meta"] = false, |
["Prismatic"] = false, |
["Purple"] = false, |
["Green"] = false, |
["Cogwheel"] = false, |
["Yellow"] = false, |
["Orange"] = false, |
["Red"] = false, |
}, |
["Glyph"] = { |
["Warrior"] = false, |
["Paladin"] = false, |
["Shaman"] = false, |
["Monk"] = false, |
["Rogue"] = false, |
["Mage"] = false, |
["Warlock"] = false, |
["Priest"] = false, |
["Hunter"] = false, |
["Druid"] = false, |
["Death Knight"] = false, |
}, |
["Weapon"] = { |
["One-Handed Axes"] = false, |
["One-Handed Swords"] = false, |
["Staves"] = false, |
["Crossbows"] = false, |
["Polearms"] = false, |
["One-Handed Maces"] = false, |
["Bows"] = false, |
["Two-Handed Swords"] = false, |
["Miscellaneous"] = false, |
["Fishing Poles"] = false, |
["Two-Handed Maces"] = false, |
["Guns"] = false, |
["Fist Weapons"] = false, |
["Thrown"] = false, |
["Wands"] = false, |
["Daggers"] = false, |
["Two-Handed Axes"] = false, |
}, |
}, |
["merge"] = { |
[119980] = { |
["interval"] = 4, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146137] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Physical Damage (Melee)", |
}, |
[91776] = { |
["interval"] = 4, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146177] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Holy Healing (Priest, Paladin)", |
}, |
[146067] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Fire, Frost Damage (Mages)", |
}, |
[146075] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Nature Damage (Windwalker Monks)", |
}, |
[49184] = { |
["interval"] = 0.5, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146162] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Physical Damage (Hunters)", |
}, |
[146178] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Nature Healing (Druid, Monk)", |
}, |
[148234] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Holy Healing (Priests, Paladins)", |
}, |
[146171] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Nature Damage (Elemental Shamans)", |
}, |
[146061] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Physical Damage (Melee)", |
}, |
[146069] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Physical Damage (Hunters)", |
}, |
[81280] = { |
["interval"] = 0.5, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[148235] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Nature Healing (Monks, Druids)", |
}, |
[146070] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Arcane Damage (Mages)", |
}, |
[146157] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Holy Damage", |
}, |
[55095] = { |
["interval"] = 3, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[148008] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 3.5, |
["class"] = "ITEM", |
["desc"] = "Legedary Cloak for Casters", |
}, |
[149276] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 3.5, |
["class"] = "ITEM", |
["desc"] = "Legedary Cloak for Hunters", |
}, |
[146071] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Nature Damage (Elemental Shamans)", |
}, |
[146158] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Arcane Damage (Balance Druids)", |
}, |
[146166] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Arcane Damage (Mages)", |
}, |
[55050] = { |
["interval"] = 0.5, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[148009] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Legedary Cloak for Healers", |
}, |
[147891] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 3.5, |
["class"] = "ITEM", |
["desc"] = "Legedary Cloak for Melee", |
}, |
[146159] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Shadow Damage (Priests, Warlocks)", |
}, |
[53365] = { |
["interval"] = 4, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146065] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Shadow Damage (Priests, Warlocks)", |
}, |
[48721] = { |
["interval"] = 0.5, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146063] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Holy Damage", |
}, |
[55078] = { |
["interval"] = 3, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146160] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Fire, Frost Damage (Mages)", |
}, |
[146064] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Arcane Damage (Balance Druids)", |
}, |
[52212] = { |
["interval"] = 3, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["enabled"] = true, |
}, |
}, |
}, |
}, |
["Tank"] = { |
["frames"] = { |
["general"] = { |
["font"] = "Expressway", |
["enabledFrame"] = false, |
["fontOutline"] = "2OUTLINE", |
}, |
["power"] = { |
["font"] = "Expressway", |
["fontOutline"] = "2OUTLINE", |
["enabledFrame"] = false, |
}, |
["healing"] = { |
["fontSize"] = 14, |
["Width"] = 145, |
["fontJustify"] = "CENTER", |
["X"] = 22, |
["enabledFrame"] = false, |
["Height"] = 153, |
["fontOutline"] = "2OUTLINE", |
["font"] = "Expressway", |
["Y"] = -277, |
}, |
["outgoing"] = { |
["Y"] = -17, |
["font"] = "Expressway", |
["megaDamage"] = true, |
["fontOutline"] = "2OUTLINE", |
["Height"] = 217, |
["X"] = 451, |
["fontSize"] = 18, |
["Width"] = 126, |
}, |
["critical"] = { |
["enabledFrame"] = false, |
["font"] = "Expressway", |
["megaDamage"] = true, |
["fontOutline"] = "2OUTLINE", |
}, |
["procs"] = { |
["font"] = "Expressway", |
["fontOutline"] = "2OUTLINE", |
["enabledFrame"] = false, |
}, |
["loot"] = { |
["font"] = "Expressway", |
["fontOutline"] = "2OUTLINE", |
["enabledFrame"] = false, |
}, |
["class"] = { |
["font"] = "Expressway", |
["enabledFrame"] = false, |
["fontOutline"] = "2OUTLINE", |
}, |
["damage"] = { |
["font"] = "Expressway", |
["enabledFrame"] = false, |
["fontOutline"] = "2OUTLINE", |
}, |
}, |
["spells"] = { |
["items"] = { |
["Container"] = { |
["Bag"] = false, |
["Mining Bag"] = false, |
["Cooking Bag"] = false, |
["Gem Bag"] = false, |
["Tackle Box"] = false, |
["Engineering Bag"] = false, |
["Herb Bag"] = false, |
["Inscription Bag"] = false, |
["Leatherworking Bag"] = false, |
["Enchanting Bag"] = false, |
}, |
["Quest"] = { |
["Quest"] = false, |
}, |
["Trade Goods"] = { |
["Other"] = false, |
["Elemental"] = false, |
["Jewelcrafting"] = false, |
["Parts"] = false, |
["Enchanting"] = false, |
["Devices"] = false, |
["Cooking"] = false, |
["Leather"] = false, |
["Materials"] = false, |
["Item Enchantment"] = false, |
["Cloth"] = false, |
["Explosives"] = false, |
["Metal & Stone"] = false, |
["Herb"] = false, |
}, |
["Miscellaneous"] = { |
["Other"] = false, |
["Reagent"] = false, |
["Companion Pets"] = false, |
["Mount"] = false, |
["Holiday"] = false, |
["Junk"] = false, |
}, |
["Recipe"] = { |
["Tailoring"] = false, |
["Blacksmithing"] = false, |
["Alchemy"] = false, |
["First Aid"] = false, |
["Book"] = false, |
["Cooking"] = false, |
["Inscription"] = false, |
["Jewelcrafting"] = false, |
["Engineering"] = false, |
["Leatherworking"] = false, |
["Fishing"] = false, |
["Enchanting"] = false, |
}, |
["Consumable"] = { |
["Other"] = false, |
["Elixir"] = false, |
["Food & Drink"] = false, |
["Item Enhancement"] = false, |
["Scroll"] = false, |
["Flask"] = false, |
["Bandage"] = false, |
["Potion"] = false, |
}, |
["version"] = 1, |
["Battle Pets"] = { |
["Dragonkin"] = false, |
["Humanoid"] = false, |
["Elemental"] = false, |
["Critter"] = false, |
["Magic"] = false, |
["Flying"] = false, |
["Aquatic"] = false, |
["Undead"] = false, |
["Beast"] = false, |
["Mechanical"] = false, |
}, |
["Armor"] = { |
["Leather"] = false, |
["Cosmetic"] = false, |
["Shields"] = false, |
["Mail"] = false, |
["Plate"] = false, |
["Cloth"] = false, |
["Miscellaneous"] = false, |
}, |
["Gem"] = { |
["Simple"] = false, |
["Blue"] = false, |
["Meta"] = false, |
["Prismatic"] = false, |
["Purple"] = false, |
["Green"] = false, |
["Cogwheel"] = false, |
["Yellow"] = false, |
["Orange"] = false, |
["Red"] = false, |
}, |
["Glyph"] = { |
["Warrior"] = false, |
["Paladin"] = false, |
["Shaman"] = false, |
["Monk"] = false, |
["Rogue"] = false, |
["Mage"] = false, |
["Warlock"] = false, |
["Priest"] = false, |
["Hunter"] = false, |
["Druid"] = false, |
["Death Knight"] = false, |
}, |
["Weapon"] = { |
["One-Handed Axes"] = false, |
["One-Handed Swords"] = false, |
["Staves"] = false, |
["Crossbows"] = false, |
["Polearms"] = false, |
["One-Handed Maces"] = false, |
["Bows"] = false, |
["Two-Handed Swords"] = false, |
["Miscellaneous"] = false, |
["Fishing Poles"] = false, |
["Two-Handed Maces"] = false, |
["Guns"] = false, |
["Fist Weapons"] = false, |
["Thrown"] = false, |
["Wands"] = false, |
["Daggers"] = false, |
["Two-Handed Axes"] = false, |
}, |
}, |
["merge"] = { |
[117895] = { |
["interval"] = 3, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[114093] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[845] = { |
["enabled"] = true, |
["class"] = "WARRIOR", |
["prep"] = 0, |
["interval"] = 0.5, |
}, |
[46968] = { |
["enabled"] = true, |
["class"] = "WARRIOR", |
["prep"] = 0, |
["interval"] = 0.5, |
}, |
[127722] = { |
["interval"] = 3, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[121253] = { |
["interval"] = 0.5, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[114911] = { |
["interval"] = 5, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146137] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Physical Damage (Melee)", |
}, |
[115181] = { |
["interval"] = 0.5, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[81280] = { |
["enabled"] = true, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["interval"] = 0.5, |
}, |
[77478] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[132120] = { |
["interval"] = 6, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[421] = { |
["interval"] = 0.5, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[148234] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Holy Healing (Priests, Paladins)", |
}, |
[124040] = { |
["interval"] = 5, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[119611] = { |
["interval"] = 6, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[148187] = { |
["interval"] = 2.5, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146171] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Nature Damage (Elemental Shamans)", |
}, |
[148235] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Nature Healing (Monks, Druids)", |
}, |
[58879] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[124255] = { |
["interval"] = 6, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146061] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Physical Damage (Melee)", |
}, |
[8349] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[115175] = { |
["interval"] = 4.5, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[115310] = { |
["interval"] = 3, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[124081] = { |
["interval"] = 6, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[52212] = { |
["enabled"] = true, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["interval"] = 3, |
}, |
[146158] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Arcane Damage (Balance Druids)", |
}, |
[49184] = { |
["enabled"] = true, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["interval"] = 0.5, |
}, |
[146063] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Holy Damage", |
}, |
[107270] = { |
["interval"] = 2.5, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[130654] = { |
["interval"] = 3, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[51490] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[55050] = { |
["enabled"] = true, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["interval"] = 0.5, |
}, |
[146159] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Shadow Damage (Priests, Warlocks)", |
}, |
[146064] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Arcane Damage (Balance Druids)", |
}, |
[124098] = { |
["interval"] = 6, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[25504] = { |
["interval"] = 0.5, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[55078] = { |
["enabled"] = true, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["interval"] = 3, |
}, |
[146160] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Fire, Frost Damage (Mages)", |
}, |
[128591] = { |
["interval"] = 3, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146065] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Shadow Damage (Priests, Warlocks)", |
}, |
[96103] = { |
["enabled"] = true, |
["class"] = "WARRIOR", |
["prep"] = 0, |
["interval"] = 3, |
}, |
[147891] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 3.5, |
["class"] = "ITEM", |
["desc"] = "Legedary Cloak for Melee", |
}, |
[6572] = { |
["enabled"] = true, |
["class"] = "WARRIOR", |
["prep"] = 0, |
["interval"] = 0.5, |
}, |
[146177] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Holy Healing (Priest, Paladin)", |
}, |
[114074] = { |
["interval"] = 0.5, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[115360] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[113344] = { |
["enabled"] = true, |
["class"] = "WARRIOR", |
["prep"] = 0, |
["interval"] = 3, |
}, |
[146178] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Nature Healing (Druid, Monk)", |
}, |
[146067] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Fire, Frost Damage (Mages)", |
}, |
[116670] = { |
["interval"] = 0.5, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[119980] = { |
["enabled"] = true, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["interval"] = 4, |
}, |
[52174] = { |
["enabled"] = true, |
["class"] = "WARRIOR", |
["prep"] = 0, |
["interval"] = 0.5, |
}, |
[132463] = { |
["interval"] = 6, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[148009] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Legedary Cloak for Healers", |
}, |
[50622] = { |
["enabled"] = true, |
["class"] = "WARRIOR", |
["prep"] = 0, |
["interval"] = 3, |
}, |
[48721] = { |
["enabled"] = true, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["interval"] = 0.5, |
}, |
[114083] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[32176] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[1064] = { |
["interval"] = 0.5, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[55095] = { |
["enabled"] = true, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["interval"] = 3, |
}, |
[128531] = { |
["interval"] = 4, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146069] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Physical Damage (Hunters)", |
}, |
[73921] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[149276] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 3.5, |
["class"] = "ITEM", |
["desc"] = "Legedary Cloak for Hunters", |
}, |
[10444] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[132467] = { |
["interval"] = 6, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146162] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Physical Damage (Hunters)", |
}, |
[146157] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Holy Damage", |
}, |
[8050] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146070] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Arcane Damage (Mages)", |
}, |
[148135] = { |
["interval"] = 3, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[146075] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Nature Damage (Windwalker Monks)", |
}, |
[26364] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[53365] = { |
["enabled"] = true, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["interval"] = 4, |
}, |
[1680] = { |
["enabled"] = true, |
["class"] = "WARRIOR", |
["prep"] = 0, |
["interval"] = 3, |
}, |
[146166] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 0.5, |
["class"] = "ITEM", |
["desc"] = "Arcane Damage (Mages)", |
}, |
[115767] = { |
["enabled"] = true, |
["class"] = "WARRIOR", |
["prep"] = 0, |
["interval"] = 3, |
}, |
[146071] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 5, |
["class"] = "ITEM", |
["desc"] = "Nature Damage (Elemental Shamans)", |
}, |
[117640] = { |
["interval"] = 2.5, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[148008] = { |
["enabled"] = true, |
["prep"] = 0, |
["interval"] = 3.5, |
["class"] = "ITEM", |
["desc"] = "Legedary Cloak for Casters", |
}, |
[91776] = { |
["enabled"] = true, |
["class"] = "DEATHKNIGHT", |
["prep"] = 0, |
["interval"] = 4, |
}, |
[120687] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[113656] = { |
["interval"] = 4, |
["class"] = "MONK", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[6343] = { |
["enabled"] = true, |
["class"] = "WARRIOR", |
["prep"] = 0, |
["interval"] = 0.5, |
}, |
[114942] = { |
["interval"] = 4, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[51945] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[52042] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[61295] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
[8187] = { |
["interval"] = 3, |
["class"] = "SHAMAN", |
["prep"] = 0, |
["enabled"] = true, |
}, |
}, |
["mergeDontMergeCriticals"] = false, |
["mergeCriticalsWithOutgoing"] = true, |
}, |
}, |
} |
end |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI"); |
SoopUI.LoadAddOnData_Bartender4 = function() |
Bartender4DB = { |
["namespaces"] = { |
["ActionBars"] = { |
["profiles"] = { |
["Tank"] = { |
["actionbars"] = { |
{ |
["showgrid"] = true, |
["states"] = { |
["alt"] = 7, |
["ctrl"] = 8, |
["default"] = 1, |
["shift"] = 6, |
}, |
["version"] = 3, |
["fadeoutalpha"] = 0, |
["hideequipped"] = true, |
["fadeout"] = true, |
["position"] = { |
["y"] = 50, |
["x"] = -150, |
["point"] = "BOTTOM", |
["scale"] = 0.65, |
}, |
["fadeoutdelay"] = 0.11, |
["hidemacrotext"] = true, |
["visibility"] = { |
["customdata"] = "[combat]show; fade", |
["custom"] = false, |
["nocombat"] = false, |
}, |
}, -- [1] |
{ |
["buttons"] = 9, |
["rows"] = 2, |
["fadeoutalpha"] = 0, |
["fadeout"] = true, |
["position"] = { |
["y"] = 48.00001106262243, |
["x"] = -265.7519987802516, |
["point"] = "BOTTOM", |
["scale"] = 0.6000000238418579, |
}, |
["version"] = 3, |
["hidemacrotext"] = true, |
["visibility"] = { |
["always"] = false, |
["nocombat"] = false, |
["custom"] = false, |
["customdata"] = "[combat]show; fade", |
}, |
["fadeoutdelay"] = 0.13, |
}, -- [2] |
{ |
["rows"] = 3, |
["version"] = 3, |
["hideequipped"] = true, |
["fadeout"] = true, |
["position"] = { |
["y"] = 76.40000113844872, |
["x"] = 262.2854674322225, |
["point"] = "BOTTOM", |
["scale"] = 0.800000011920929, |
}, |
["hidemacrotext"] = true, |
["padding"] = -7, |
["visibility"] = { |
["custom"] = true, |
["customdata"] = "[combat]show; fade", |
}, |
["fadeoutalpha"] = 0, |
}, -- [3] |
{ |
["fadeout"] = true, |
["position"] = { |
["y"] = -40.88331604003906, |
["x"] = -3.375000357627869, |
["point"] = "LEFT", |
["scale"] = 0.6, |
}, |
["padding"] = -1, |
["rows"] = 12, |
["fadeoutalpha"] = 0, |
["version"] = 3, |
}, -- [4] |
{ |
["fadeout"] = true, |
["position"] = { |
["y"] = 20.98675324863871, |
["x"] = -24.29992467164993, |
["point"] = "RIGHT", |
["scale"] = 0.6000000238418579, |
}, |
["padding"] = -1, |
["rows"] = 12, |
["fadeoutalpha"] = 0, |
["version"] = 3, |
}, -- [5] |
{ |
["enabled"] = false, |
["version"] = 3, |
["position"] = { |
["y"] = -135.7666015625, |
["x"] = 382.6889953613281, |
["point"] = "LEFT", |
}, |
["rows"] = 2, |
["padding"] = 6, |
}, -- [6] |
{ |
["rows"] = 2, |
["version"] = 3, |
["position"] = { |
["y"] = 0.5001220703125, |
["x"] = -231.5001831054688, |
["point"] = "CENTER", |
}, |
}, -- [7] |
{ |
["rows"] = 2, |
["version"] = 3, |
["position"] = { |
["y"] = 14.1446533203125, |
["x"] = -290.0333862304688, |
["point"] = "CENTER", |
}, |
}, -- [8] |
{ |
["version"] = 3, |
["position"] = { |
["y"] = 76.50006103515625, |
["x"] = -231.5001831054688, |
["point"] = "CENTER", |
}, |
}, -- [9] |
{ |
["version"] = 3, |
["position"] = { |
["y"] = 114.5001220703125, |
["x"] = -231.5001831054688, |
["point"] = "CENTER", |
}, |
}, -- [10] |
}, |
}, |
["Default"] = { |
}, |
}, |
}, |
["LibDualSpec-1.0"] = { |
}, |
["ExtraActionBar"] = { |
["profiles"] = { |
["Tank"] = { |
["position"] = { |
["y"] = 70, |
["x"] = 144.8998509378944, |
["point"] = "BOTTOM", |
["scale"] = 0.8500000238418579, |
}, |
["version"] = 3, |
}, |
["Default"] = { |
}, |
}, |
}, |
["MicroMenu"] = { |
["profiles"] = { |
["Tank"] = { |
["enabled"] = false, |
["position"] = { |
["y"] = 41.75, |
["x"] = 37.5, |
["point"] = "BOTTOM", |
["scale"] = 1, |
}, |
["version"] = 3, |
}, |
["Default"] = { |
}, |
}, |
}, |
["XPBar"] = { |
["profiles"] = { |
["Tank"] = { |
["enabled"] = false, |
["version"] = 3, |
["position"] = { |
["y"] = 57, |
["x"] = -516, |
["point"] = "BOTTOM", |
}, |
}, |
["Default"] = { |
}, |
}, |
}, |
["BlizzardArt"] = { |
["profiles"] = { |
["Tank"] = { |
["enabled"] = false, |
["version"] = 3, |
["position"] = { |
["y"] = 47, |
["x"] = -512, |
["point"] = "BOTTOM", |
}, |
}, |
["Default"] = { |
}, |
}, |
}, |
["BagBar"] = { |
["profiles"] = { |
["Tank"] = { |
["enabled"] = false, |
["version"] = 3, |
["position"] = { |
["y"] = 1.50006103515625, |
["x"] = 58.4998779296875, |
["point"] = "CENTER", |
}, |
}, |
["Default"] = { |
}, |
}, |
}, |
["StanceBar"] = { |
["profiles"] = { |
["Tank"] = { |
["fadeout"] = true, |
["fadeoutalpha"] = 0, |
["position"] = { |
["y"] = 20, |
["x"] = 148.6968994140625, |
["point"] = "BOTTOM", |
["scale"] = 0.5, |
}, |
["version"] = 3, |
}, |
["Default"] = { |
}, |
}, |
}, |
["Vehicle"] = { |
["profiles"] = { |
["Tank"] = { |
["version"] = 3, |
["position"] = { |
["y"] = 38.0000114440918, |
["x"] = -303.4036254882813, |
["point"] = "BOTTOM", |
}, |
}, |
["Default"] = { |
}, |
}, |
}, |
["PetBar"] = { |
["profiles"] = { |
["Tank"] = { |
["enabled"] = false, |
["version"] = 3, |
["fadeoutalpha"] = 0, |
["position"] = { |
["y"] = 122, |
["x"] = -35, |
["point"] = "RIGHT", |
["scale"] = 0.75, |
}, |
}, |
["Default"] = { |
}, |
}, |
}, |
["RepBar"] = { |
["profiles"] = { |
["Tank"] = { |
["enabled"] = false, |
["version"] = 3, |
["position"] = { |
["y"] = 65, |
["x"] = -516, |
["point"] = "BOTTOM", |
}, |
}, |
["Default"] = { |
}, |
}, |
}, |
}, |
["profileKeys"] = { |
}, |
["profiles"] = { |
["Tank"] = { |
["focuscastmodifier"] = false, |
["minimapIcon"] = { |
["hide"] = true, |
}, |
["onkeydown"] = true, |
["blizzardVehicle"] = true, |
["outofrange"] = "hotkey", |
}, |
["Default"] = { |
}, |
}, |
} |
end |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI") |
SoopUI.LoadAddOnData_Raven = function() |
RavenDB = { |
["profileKeys"] = { |
}, |
["global"] = { |
["FilterBuff"] = { |
["Long Buffs"] = { |
["Guild Champion"] = "Guild Champion", |
}, |
}, |
["DefaultCooldownColor"] = { |
["b"] = 0, |
["g"] = 0, |
["r"] = 0, |
}, |
["DefaultPoisonColor"] = { |
["a"] = 1, |
}, |
["Settings"] = { |
["Debuff Tracker"] = { |
["backdropFill"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["minimumTimeLeft"] = false, |
["barHeight"] = 20, |
["pointYT"] = 0.8379627609775979, |
["pointW"] = 169.9999542236328, |
["useDefaultDimensions"] = false, |
["iconSize"] = 20, |
["iconColors"] = "Debuffs", |
["checkTimeLeft"] = true, |
["pointX"] = 0.8291669845581055, |
["borderColor"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["pointXR"] = 0.08229137261708577, |
["detectAllDebuffs"] = true, |
["sor"] = "T", |
["pointH"] = 20, |
["backdropColor"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["detectDebuffs"] = true, |
["pointY"] = 0.1435187184107709, |
}, |
["Short Buffs"] = { |
["backdropFill"] = { |
["a"] = 1, |
["r"] = 1, |
["g"] = 1, |
["b"] = 1, |
}, |
["showVehicle"] = false, |
["growDirection"] = false, |
["showNoDurationBackground"] = true, |
["showFishing"] = false, |
["detectBuffsCastBy"] = "ours", |
["detectAllBuffs"] = true, |
["spacingX"] = 2, |
["barHeight"] = 5, |
["setDuration"] = true, |
["minimumDuration"] = false, |
["detectCastable"] = true, |
["detectBuffs"] = true, |
["pointW"] = 40.00003433227539, |
["hideLabel"] = true, |
["useDefaultDimensions"] = false, |
["spacingY"] = 15, |
["checkDuration"] = true, |
["iconSize"] = 40, |
["detectEnrageBuffs"] = true, |
["hideValue"] = true, |
["pointX"] = 0.9020833333333334, |
["barWidth"] = 20, |
["detectMagicBuffs"] = true, |
["filterBuffSpells"] = true, |
["detectOtherBuffs"] = true, |
["configuration"] = 9, |
["maxBars"] = 10, |
["pointXR"] = 0.0770833154519399, |
["wrap"] = 5, |
["pointH"] = 40.00003433227539, |
["backdropColor"] = { |
["a"] = 1, |
["r"] = 1, |
["g"] = 1, |
["b"] = 1, |
}, |
["showSecondary"] = false, |
["pointY"] = 0.9370371429485341, |
["borderColor"] = { |
["a"] = 1, |
["r"] = 1, |
["g"] = 1, |
["b"] = 1, |
}, |
["hideBar"] = true, |
["pointYT"] = 0.02592578403905618, |
}, |
}, |
["SpellIDs"] = { |
["Internal Medicine"] = 115451, |
["Acceleration"] = 138703, |
}, |
["DefaultBorderColor"] = { |
["b"] = 0, |
["g"] = 0, |
["r"] = 0, |
}, |
["DefaultBuffColor"] = { |
["b"] = 0, |
["g"] = 0, |
["r"] = 0, |
}, |
["DefaultNotificationColor"] = { |
["b"] = 0, |
["g"] = 0, |
["r"] = 0, |
}, |
["DefaultDebuffColor"] = { |
["b"] = 0, |
["g"] = 0, |
["r"] = 0, |
}, |
["PixelPerfect"] = true, |
["DefaultMagicColor"] = { |
["a"] = 1, |
}, |
["Defaults"] = { |
["texture"] = "fer28", |
["timeFont"] = "Expressway Rg Bold", |
["labelFont"] = "Expressway Rg Bold", |
["bgtexture"] = "fer03", |
["iconFont"] = "Expressway Rg Bold", |
}, |
["Version"] = "7", |
["DefaultDiseaseColor"] = { |
["a"] = 1, |
["g"] = 0, |
["r"] = 0, |
}, |
["DefaultCurseColor"] = { |
["a"] = 1, |
}, |
}, |
["profiles"] = { |
["Tank"] = { |
["Conditions"] = { |
["WARRIOR"] = { |
["Battle Shout!"] = { |
["tests"] = { |
["Player Status"] = { |
["levelOffHand"] = 1, |
["minShards"] = 1, |
["minHealth"] = 100, |
["minFury"] = 1, |
["levelMainHand"] = 1, |
["minChi"] = 1, |
["minEclipsePower"] = 0, |
["minHolyPower"] = 1, |
["minEmbers"] = 1, |
["minComboPoints"] = 5, |
["level"] = 85, |
["minPower"] = 100, |
["minShadowOrbs"] = 1, |
}, |
["Spell Ready"] = { |
["notUsable"] = false, |
["charges"] = 1, |
}, |
}, |
["result"] = false, |
["testResult"] = false, |
}, |
["Commanding Shout!"] = { |
["tests"] = { |
["Player Status"] = { |
["levelOffHand"] = 1, |
["minShards"] = 1, |
["minChi"] = 1, |
["minFury"] = 1, |
["levelMainHand"] = 1, |
["minShadowOrbs"] = 1, |
["minHealth"] = 100, |
["minHolyPower"] = 1, |
["minEclipsePower"] = 0, |
["minComboPoints"] = 5, |
["level"] = 85, |
["minPower"] = 100, |
["minEmbers"] = 1, |
}, |
["Spell Ready"] = { |
["notUsable"] = false, |
["charges"] = 1, |
}, |
}, |
["result"] = false, |
["testResult"] = false, |
}, |
}, |
}, |
["BarGroups"] = { |
["Debuffs"] = { |
["timeMono"] = true, |
["hideBar"] = true, |
["useDefaultFontsAndTextures"] = false, |
["detectDebuffsCastBy"] = "anyone", |
["scale"] = 1.25, |
["hideValue"] = true, |
["configuration"] = 9, |
["showNoDuration"] = true, |
["backdropFill"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["pointH"] = 37.50001668930054, |
["hideLabel"] = true, |
["growDirection"] = false, |
["iconSize"] = 30, |
["fillBars"] = true, |
["borderColor"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["useDefaultDimensions"] = false, |
["detectDebuffs"] = true, |
["backdropColor"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["auto"] = true, |
["iconColors"] = "Debuffs", |
["pointXR"] = 0.07226561630765598, |
["pointX"] = 0.908203125, |
["pointY"] = 0.9467594369121904, |
["maxBars"] = 6, |
["iconHide"] = true, |
["labelOutline"] = true, |
["name"] = "Debuffs", |
["pointYT"] = 0.01851832148794346, |
["timeOutline"] = true, |
["bars"] = { |
}, |
["pointW"] = 37.50001668930054, |
["noHeaders"] = true, |
}, |
["Long Buffs"] = { |
["useDefaultFontsAndTextures"] = false, |
["spacingX"] = 2, |
["barHeight"] = 5, |
["configuration"] = 9, |
["showNoDuration"] = true, |
["backdropFill"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["barColors"] = "Class", |
["hideLabel"] = true, |
["borderColor"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["checkTimeLeft"] = true, |
["useDefaultDimensions"] = false, |
["detectBuffsCastBy"] = "anyone", |
["pointX"] = 0.9760416666666667, |
["name"] = "Long Buffs", |
["timeOutline"] = true, |
["backdropColor"] = { |
["a"] = 1, |
["b"] = 1, |
["g"] = 1, |
["r"] = 1, |
}, |
["showCombat"] = false, |
["checkDuration"] = true, |
["filterBuffSelection"] = "Guild Champion", |
["bgtexture"] = "Blizzard", |
["hideBar"] = true, |
["sor"] = "C", |
["pointH"] = 24.9999885559082, |
["iconSize"] = 25, |
["wrap"] = 3, |
["pointXR"] = 0.01093747119108836, |
["texture"] = "Blizzard", |
["growDirection"] = false, |
["detectBuffs"] = true, |
["auto"] = true, |
["iconColors"] = "Normal", |
["maxBars"] = 6, |
["labelAlign"] = "TOP", |
["pointY"] = 0.8490742265573263, |
["iconHide"] = true, |
["barWidth"] = 20, |
["iconAlign"] = "RIGHT", |
["filterTimeLeft"] = 1080, |
["pointYT"] = 0.1277776332745173, |
["pointW"] = 25.00005531311035, |
["bars"] = { |
}, |
["filterBuffList"] = { |
["Guild Champion"] = "Guild Champion", |
}, |
["timeOffset"] = 16, |
}, |
["Debuff Tracker"] = { |
["backdropColor"] = { |
["a"] = 1, |
["r"] = 1, |
["g"] = 1, |
["b"] = 1, |
}, |
["barHeight"] = 20, |
["detectDebuffs"] = true, |
["backdropFill"] = { |
["a"] = 1, |
["r"] = 1, |
["g"] = 1, |
["b"] = 1, |
}, |
["pointXR"] = 0.08229169050852457, |
["pointH"] = 20, |
["iconSize"] = 20, |
["useDefaultDimensions"] = false, |
["auto"] = true, |
["iconColors"] = "Debuffs", |
["sor"] = "T", |
["pointX"] = 0.8291666666666667, |
["pointY"] = 0.1435185347401411, |
["detectAllDebuffs"] = true, |
["borderColor"] = { |
["a"] = 1, |
["r"] = 1, |
["g"] = 1, |
["b"] = 1, |
}, |
["minimumTimeLeft"] = false, |
["name"] = "Debuff Tracker", |
["pointYT"] = 0.8379629446482279, |
["pointW"] = 169.9999542236328, |
["bars"] = { |
}, |
["checkTimeLeft"] = true, |
["testTimers"] = 6, |
}, |
}, |
["Durations"] = { |
[104277] = 3600, |
[871] = 12, |
[122510] = 10, |
[112071] = 15, |
[12292] = 12, |
[6673] = 300, |
[469] = 300, |
[16886] = 15, |
[50227] = 5, |
[115307] = 10.977, |
[117666] = 3600, |
[29166] = 10, |
[55694] = 5, |
[119085] = 10, |
[113746] = 30, |
[115308] = 12, |
[130895] = 20, |
[142895] = 3, |
[135373] = 4, |
[12880] = 6, |
[148984] = 20, |
[142896] = 4, |
[118895] = 0.25, |
[104934] = 20, |
[144459] = 16, |
[2479] = 30, |
[115804] = 10, |
[116330] = 15, |
[146022] = 5, |
[149624] = 600, |
[104935] = 20, |
[146310] = 10, |
[104282] = 3600.001, |
[143856] = 6.997, |
[115295] = 30, |
[146343] = 15, |
[145674] = 20, |
[126659] = 20, |
[104235] = 20, |
[22812] = 12, |
[104267] = 3600, |
[104283] = 3600, |
[123727] = 15, |
[120954] = 20, |
[131523] = 8, |
[148385] = 3600, |
[105702] = 25, |
[1126] = 3600.003, |
[128939] = 30, |
[146250] = 20, |
[113942] = 60, |
[118038] = 8, |
[142808] = 6, |
[5246] = 8, |
[97463] = 10, |
[144849] = 61, |
[110309] = 3600, |
[114198] = 6, |
[104269] = 20, |
[110660] = 5, |
[116844] = 8, |
[110485] = 3600, |
[146285] = 10, |
[81192] = 3, |
[120032] = 12, |
[84619] = 5, |
[104270] = 20, |
[46916] = 15, |
[46924] = 6, |
[114056] = 10, |
[32216] = 20, |
[112048] = 6, |
[105689] = 7200.022, |
[147531] = 6, |
[131116] = 12, |
[127285] = 600, |
[148010] = 120, |
[139117] = 10, |
[124273] = 9.999000000000001, |
[138703] = 10, |
[146385] = 600, |
[146194] = 3, |
[95809] = 600, |
[147055] = 3600, |
[104272] = 3600.003, |
[137461] = 4, |
[124210] = 3600, |
[116847] = 4.615, |
[147279] = 60, |
[124274] = 7.999000000000001, |
[125565] = 11, |
[105691] = 8100.058, |
[57723] = 600.009, |
[1719] = 12, |
[106898] = 8, |
[146324] = 5, |
[116709] = 2, |
[12968] = 15, |
[29842] = 10, |
[127663] = 4, |
[124974] = 30, |
[44535] = 6, |
[124275] = 2.999, |
[106664] = 10, |
[116660] = 7, |
[114192] = 30, |
[125359] = 20, |
[106498] = 120, |
[119392] = 3, |
[118636] = 30, |
[123725] = 8, |
[145051] = 30, |
[1160] = 10, |
[132365] = 20, |
[125487] = 15, |
[114028] = 5, |
[85739] = 10, |
[137593] = 15, |
[93400] = 12, |
[147898] = 10, |
[23920] = 5, |
[105696] = 3600.026, |
[118604] = 30, |
[132169] = 4, |
[147281] = 3600, |
[93402] = 9.290000000000001, |
[116189] = 1.949, |
[104275] = 3600, |
[105694] = 3600.027, |
[12975] = 20, |
[115798] = 30, |
[18499] = 6, |
[147476] = 3600, |
[339] = 30.001, |
[355] = 3, |
[95223] = 600, |
[113344] = 6.159, |
[1604] = 4, |
[86346] = 6.5, |
[61391] = 6, |
[104993] = 12, |
[137596] = 60.004, |
[8921] = 11.855, |
[81326] = 30, |
[115767] = 16.897, |
[7922] = 1.5, |
[80354] = 600, |
[144442] = 12, |
[324] = 3600.027, |
[102560] = 30, |
[774] = 13.557, |
[48505] = 10, |
[147383] = 120, |
[48391] = 10, |
[137460] = 3, |
[137452] = 4, |
[105697] = 25, |
[122278] = 45, |
[146555] = 40, |
[132404] = 6, |
}, |
}, |
}, |
} |
end |
local SoopUI = LibStub("AceAddon-3.0"):GetAddon("SoopUI") |
SoopUI.AddOns = { |
"Bartender4", |
"kgPanels", |
"OmniCC", |
"Raven", |
"Skada", |
"xCT+", |
} |
function SoopUI:LoadAddOnData() |
for k, a in pairs(self.AddOns) do |
if self["LoadAddOnData_"..a] then |
self["LoadAddOnData_"..a]() |
end |
end |
end |
function SoopUI:LoadSpecificAddOnData(addon) |
if self["LoadAddOnData_"..addon] then |
self["LoadAddOnData_"..addon]() |
else |
print("WARNING: CANNOT LOAD "..addon.." DATA!!") |
end |
print("Loaded "..addon.." Data.") |
end |
## Interface: 50400 |
## Author: Soopie |
## Version: 3.0-b1 |
## Title: SoopUI |
## Notes: User Interface for World of Warcraft |
## SavedVariables: SoopUIDB |
## SavedVariablesPerCharacter: SoopUICharacter |
Libs.xml |
SoopUI.lua |
AddonData.xml |
Core\Media.lua |
Core\Install.lua |
Core\Commands.lua |