This commit is contained in:
Andrew6810
2022-10-21 07:09:01 -07:00
parent cbdabfbcca
commit 60ef8a38af
614 changed files with 138573 additions and 2 deletions
+997
View File
@@ -0,0 +1,997 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local AB = E:GetModule("ActionBars")
--Lua functions
local _G = _G
local pairs, select, unpack = pairs, select, unpack
local ceil = math.ceil
local format, gsub, match, split = string.format, string.gsub, string.match, string.split
--WoW API / Variables
local hooksecurefunc = hooksecurefunc
local CreateFrame = CreateFrame
local UnitHealth = UnitHealth
local UnitHealthMax = UnitHealthMax
local UnitCastingInfo = UnitCastingInfo
local UnitChannelInfo = UnitChannelInfo
local UnitAffectingCombat = UnitAffectingCombat
local UnitExists = UnitExists
local PetDismiss = PetDismiss
local CanExitVehicle = CanExitVehicle
local InCombatLockdown = InCombatLockdown
local ClearOverrideBindings = ClearOverrideBindings
local GetBindingKey = GetBindingKey
local SetOverrideBindingClick = SetOverrideBindingClick
local SetCVar = SetCVar
local SetModifiedClick = SetModifiedClick
local RegisterStateDriver = RegisterStateDriver
local UnregisterStateDriver = UnregisterStateDriver
local NUM_ACTIONBAR_BUTTONS = NUM_ACTIONBAR_BUTTONS
local LEAVE_VEHICLE = LEAVE_VEHICLE
local LAB = E.Libs.LAB
local LSM = E.Libs.LSM
local LBF = E.Libs.LBF
local UIHider
AB.RegisterCooldown = E.RegisterCooldown
AB.handledBars = {} --List of all bars
AB.handledbuttons = {} --List of all buttons that have been modified.
AB.barDefaults = {
bar1 = {
page = 1,
bindButtons = "ACTIONBUTTON",
conditions = "[bonusbar:5] 11; [bar:2] 2; [bar:3] 3; [bar:4] 4; [bar:5] 5; [bar:6] 6;",
position = "BOTTOM,ElvUIParent,BOTTOM,0,4",
},
bar2 = {
page = 5,
bindButtons = "MULTIACTIONBAR2BUTTON",
conditions = "",
position = "BOTTOM,ElvUI_Bar1,TOP,0,2"
},
bar3 = {
page = 6,
bindButtons = "MULTIACTIONBAR1BUTTON",
conditions = "",
position = "LEFT,ElvUI_Bar1,RIGHT,4,0"
},
bar4 = {
page = 4,
bindButtons = "MULTIACTIONBAR4BUTTON",
conditions = "",
position = "RIGHT,ElvUIParent,RIGHT,-4,0"
},
bar5 = {
page = 3,
bindButtons = "MULTIACTIONBAR3BUTTON",
conditions = "",
position = "RIGHT,ElvUI_Bar1,LEFT,-4,0"
},
bar6 = {
page = 2,
bindButtons = "ELVUIBAR6BUTTON",
conditions = "",
position = "BOTTOM,ElvUI_Bar2,TOP,0,2"
}
}
AB.customExitButton = {
func = function()
if UnitExists("vehicle") then
VehicleExit()
else
PetDismiss()
end
end,
texture = "Interface\\Icons\\Spell_Shadow_SacrificialShield",
tooltip = LEAVE_VEHICLE
}
function AB:PositionAndSizeBar(barName)
local buttonSpacing = E:Scale(self.db[barName].buttonspacing)
local backdropSpacing = E:Scale((self.db[barName].backdropSpacing or self.db[barName].buttonspacing))
local buttonsPerRow = self.db[barName].buttonsPerRow
local numButtons = self.db[barName].buttons
local size = E:Scale(self.db[barName].buttonsize)
local point = self.db[barName].point
local numColumns = ceil(numButtons / buttonsPerRow)
local widthMult = self.db[barName].widthMult
local heightMult = self.db[barName].heightMult
local visibility = self.db[barName].visibility
local bar = self.handledBars[barName]
bar.db = self.db[barName]
if visibility and match(visibility, "[\n\r]") then
visibility = gsub(visibility, "[\n\r]","")
end
if numButtons < buttonsPerRow then
buttonsPerRow = numButtons
end
if numColumns < 1 then
numColumns = 1
end
if bar.db.backdrop then
bar.backdrop:Show()
else
bar.backdrop:Hide()
--Set size multipliers to 1 when backdrop is disabled
widthMult = 1
heightMult = 1
end
local sideSpacing = (bar.db.backdrop == true and (E.Border + backdropSpacing) or E.Spacing)
--Size of all buttons + Spacing between all buttons + Spacing between additional rows of buttons + Spacing between backdrop and buttons + Spacing on end borders with non-thin borders
local barWidth = (size * (buttonsPerRow * widthMult)) + ((buttonSpacing * (buttonsPerRow - 1)) * widthMult) + (buttonSpacing * (widthMult - 1)) + (sideSpacing*2)
local barHeight = (size * (numColumns * heightMult)) + ((buttonSpacing * (numColumns - 1)) * heightMult) + (buttonSpacing * (heightMult - 1)) + (sideSpacing*2)
bar:Width(barWidth)
bar:Height(barHeight)
bar.mouseover = bar.db.mouseover
local horizontalGrowth, verticalGrowth
if point == "TOPLEFT" or point == "TOPRIGHT" then
verticalGrowth = "DOWN"
else
verticalGrowth = "UP"
end
if point == "BOTTOMLEFT" or point == "TOPLEFT" then
horizontalGrowth = "RIGHT"
else
horizontalGrowth = "LEFT"
end
if bar.db.mouseover then
bar:SetAlpha(0)
else
bar:SetAlpha(bar.db.alpha)
end
if bar.db.inheritGlobalFade then
bar:SetParent(self.fadeParent)
else
bar:SetParent(E.UIParent)
end
local button, lastButton, lastColumnButton
for i = 1, NUM_ACTIONBAR_BUTTONS do
button = bar.buttons[i]
lastButton = bar.buttons[i - 1]
lastColumnButton = bar.buttons[i-buttonsPerRow]
button:SetParent(bar)
button:ClearAllPoints()
button:Size(size)
button:SetAttribute("showgrid", 1)
if i == 1 then
local x, y
if point == "BOTTOMLEFT" then
x, y = sideSpacing, sideSpacing
elseif point == "TOPRIGHT" then
x, y = -sideSpacing, -sideSpacing
elseif point == "TOPLEFT" then
x, y = sideSpacing, -sideSpacing
else
x, y = -sideSpacing, sideSpacing
end
button:Point(point, bar, point, x, y)
elseif (i - 1) % buttonsPerRow == 0 then
local y = -buttonSpacing
local buttonPoint, anchorPoint = "TOP", "BOTTOM"
if verticalGrowth == "UP" then
y = buttonSpacing
buttonPoint = "BOTTOM"
anchorPoint = "TOP"
end
button:Point(buttonPoint, lastColumnButton, anchorPoint, 0, y)
else
local x = buttonSpacing
local buttonPoint, anchorPoint = "LEFT", "RIGHT"
if horizontalGrowth == "LEFT" then
x = -buttonSpacing
buttonPoint = "RIGHT"
anchorPoint = "LEFT"
end
button:Point(buttonPoint, lastButton, anchorPoint, x, 0)
end
if i > numButtons then
button:Hide()
else
button:Show()
end
self:StyleButton(button, nil, self.LBFGroup and E.private.actionbar.lbf.enable and true or nil)
end
if bar.db.enabled or not bar.initialized then
if not bar.db.mouseover then
bar:SetAlpha(bar.db.alpha)
end
local page = self:GetPage(barName, self.barDefaults[barName].page, self.barDefaults[barName].conditions)
bar:Show()
RegisterStateDriver(bar, "visibility", visibility) -- this is ghetto
RegisterStateDriver(bar, "page", page)
bar:SetAttribute("page", page)
if not bar.initialized then
bar.initialized = true
AB:PositionAndSizeBar(barName)
return
end
E:EnableMover(bar.mover:GetName())
else
E:DisableMover(bar.mover:GetName())
bar:Hide()
UnregisterStateDriver(bar, "visibility")
end
E:SetMoverSnapOffset("ElvAB_"..bar.id, bar.db.buttonspacing / 2)
if self.LBFGroup and E.private.actionbar.lbf.enable then
self.LBFGroup:Skin(E.private.actionbar.lbf.skin)
end
end
function AB:CreateBar(id)
local bar = CreateFrame("Frame", "ElvUI_Bar"..id, E.UIParent, "SecureHandlerStateTemplate")
local point, anchor, attachTo, x, y = split(",", self.barDefaults["bar"..id].position)
bar:Point(point, anchor, attachTo, x, y)
bar.id = id
bar:CreateBackdrop(self.db.transparentBackdrops and "Transparent")
bar:SetFrameStrata("LOW")
--Use this method instead of :SetAllPoints, as the size of the mover would otherwise be incorrect
bar.backdrop:SetPoint("TOPLEFT", bar, "TOPLEFT", E.Spacing, -E.Spacing)
bar.backdrop:SetPoint("BOTTOMRIGHT", bar, "BOTTOMRIGHT", -E.Spacing, E.Spacing)
bar.buttons = {}
bar.bindButtons = self.barDefaults["bar"..id].bindButtons
self:HookScript(bar, "OnEnter", "Bar_OnEnter")
self:HookScript(bar, "OnLeave", "Bar_OnLeave")
for i = 1, 12 do
bar.buttons[i] = LAB:CreateButton(i, format(bar:GetName().."Button%d", i), bar, nil)
bar.buttons[i]:SetState(0, "action", i)
for k = 1, 11 do
bar.buttons[i]:SetState(k, "action", (k - 1) * 12 + i)
end
if i == 12 then
bar.buttons[i]:SetState(11, "custom", AB.customExitButton)
end
if self.LBFGroup and E.private.actionbar.lbf.enable then
self.LBFGroup:AddButton(bar.buttons[i])
end
self:HookScript(bar.buttons[i], "OnEnter", "Button_OnEnter")
self:HookScript(bar.buttons[i], "OnLeave", "Button_OnLeave")
end
self:UpdateButtonConfig(bar, bar.bindButtons)
bar:SetAttribute("_onstate-page", [[
if newstate ~= 0 then
self:SetAttribute("state", newstate)
control:ChildUpdate("state", newstate)
else
local newCondition = self:GetAttribute("newCondition")
if newCondition then
newstate = SecureCmdOptionParse(newCondition)
self:SetAttribute("state", newstate)
control:ChildUpdate("state", newstate)
end
end
]])
self.handledBars["bar"..id] = bar
E:CreateMover(bar, "ElvAB_"..id, L["Bar "]..id, nil, nil, nil,"ALL,ACTIONBARS",nil,"actionbar,bar"..id)
self:PositionAndSizeBar("bar"..id)
return bar
end
function AB:PLAYER_REGEN_ENABLED()
if AB.NeedsUpdateButtonSettings then
self:UpdateButtonSettings()
AB.NeedsUpdateButtonSettings = nil
end
if AB.NeedsUpdateMicroBarVisibility then
self:UpdateMicroBarVisibility()
AB.NeedsUpdateMicroBarVisibility = nil
end
if AB.NeedsAdjustMaxStanceButtons then
AB:AdjustMaxStanceButtons(AB.NeedsAdjustMaxStanceButtons) --sometimes it holds the event, otherwise true. pass it before we nil it.
AB.NeedsAdjustMaxStanceButtons = nil
end
if AB.NeedsPositionAndSizeBarTotem then
self:PositionAndSizeBarTotem()
AB.NeedsPositionAndSizeBarTotem = nil
end
if AB.NeedRecallButtonUpdate then
MultiCastRecallSpellButton_Update(MultiCastRecallSpellButton)
AB.NeedRecallButtonUpdate = nil
end
self:UnregisterEvent("PLAYER_REGEN_ENABLED")
end
local function Vehicle_OnEvent(self, event)
if CanExitVehicle() and not E.db.general.minimap.icons.vehicleLeave.hide then
self:Show()
else
self:Hide()
end
end
function AB:UpdateVehicleLeave()
if not self.vehicle then return end
local pos = E.db.general.minimap.icons.vehicleLeave.position
self.vehicle:ClearAllPoints()
self.vehicle:Point(pos, Minimap, pos, E.db.general.minimap.icons.vehicleLeave.xOffset, E.db.general.minimap.icons.vehicleLeave.yOffset)
self.vehicle:Size(26 * E.db.general.minimap.icons.vehicleLeave.scale)
Vehicle_OnEvent(self.vehicle)
end
function AB:CreateVehicleLeave()
local vehicle = CreateFrame("Button", "ElvUI_LeaveVehicleButton", E.UIParent)
vehicle:Hide()
vehicle:SetFrameStrata("HIGH")
vehicle:SetNormalTexture(E.Media.Textures.ExitVehicle)
vehicle:SetPushedTexture(E.Media.Textures.ExitVehicle)
vehicle:SetHighlightTexture(E.Media.Textures.ExitVehicle)
vehicle:SetTemplate()
vehicle:EnableMouse(true)
vehicle:RegisterForClicks("AnyUp")
vehicle:SetScript("OnClick", VehicleExit)
vehicle:SetScript("OnEvent", Vehicle_OnEvent)
vehicle:RegisterEvent("PLAYER_ENTERING_WORLD")
vehicle:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
vehicle:RegisterEvent("UPDATE_MULTI_CAST_ACTIONBAR")
vehicle:RegisterEvent("UNIT_ENTERED_VEHICLE")
vehicle:RegisterEvent("UNIT_EXITED_VEHICLE")
vehicle:RegisterEvent("VEHICLE_UPDATE")
self.vehicle = vehicle
self:UpdateVehicleLeave()
end
function AB:ReassignBindings(event)
if event == "UPDATE_BINDINGS" then
self:UpdatePetBindings()
self:UpdateStanceBindings()
end
self:UnregisterEvent("PLAYER_REGEN_DISABLED")
if InCombatLockdown() then return end
for _, bar in pairs(self.handledBars) do
if bar then
ClearOverrideBindings(bar)
for i = 1, #bar.buttons do
local button = format(bar.bindButtons.."%d", i)
local real_button = format(bar:GetName().."Button%d", i)
for k = 1, select("#", GetBindingKey(button)) do
local key = select(k, GetBindingKey(button))
if key and key ~= "" then
SetOverrideBindingClick(bar, false, key, real_button)
end
end
end
end
end
end
function AB:RemoveBindings()
if InCombatLockdown() then return end
for _, bar in pairs(self.handledBars) do
if bar then
ClearOverrideBindings(bar)
end
end
self:RegisterEvent("PLAYER_REGEN_DISABLED", "ReassignBindings")
end
function AB:UpdateBar1Paging()
if self.db.bar6.enabled then
AB.barDefaults.bar1.conditions = "[bonusbar:5] 11; [bar:3] 3; [bar:4] 4; [bar:5] 5; [bar:6] 6;"
else
AB.barDefaults.bar1.conditions = "[bonusbar:5] 11; [bar:2] 2; [bar:3] 3; [bar:4] 4; [bar:5] 5; [bar:6] 6;"
end
if (E.private.actionbar.enable ~= true or InCombatLockdown()) or not self.isInitialized then return end
local bar2Option = InterfaceOptionsActionBarsPanelBottomRight
local bar3Option = InterfaceOptionsActionBarsPanelBottomLeft
local bar4Option = InterfaceOptionsActionBarsPanelRightTwo
local bar5Option = InterfaceOptionsActionBarsPanelRight
if (self.db.bar2.enabled and not bar2Option:GetChecked()) or (not self.db.bar2.enabled and bar2Option:GetChecked()) then
bar2Option:Click()
end
if (self.db.bar3.enabled and not bar3Option:GetChecked()) or (not self.db.bar3.enabled and bar3Option:GetChecked()) then
bar3Option:Click()
end
if not self.db.bar5.enabled and not self.db.bar4.enabled then
if bar4Option:GetChecked() then
bar4Option:Click()
end
if bar5Option:GetChecked() then
bar5Option:Click()
end
elseif not self.db.bar5.enabled then
if not bar5Option:GetChecked() then
bar5Option:Click()
end
if not bar4Option:GetChecked() then
bar4Option:Click()
end
elseif (self.db.bar4.enabled and not bar4Option:GetChecked()) or (not self.db.bar4.enabled and bar4Option:GetChecked()) then
bar4Option:Click()
elseif (self.db.bar5.enabled and not bar5Option:GetChecked()) or (not self.db.bar5.enabled and bar5Option:GetChecked()) then
bar5Option:Click()
end
end
function AB:UpdateButtonSettingsForBar(barName)
local bar = self.handledBars[barName]
self:UpdateButtonConfig(bar, bar.bindButtons)
end
function AB:UpdateButtonSettings()
if E.private.actionbar.enable ~= true then return end
if InCombatLockdown() then
AB.NeedsUpdateButtonSettings = true
self:RegisterEvent("PLAYER_REGEN_ENABLED")
return
end
for button in pairs(self.handledbuttons) do
if button then
self:StyleButton(button, button.noBackdrop, button.useMasque)
else
self.handledbuttons[button] = nil
end
end
self:UpdatePetBindings()
self:UpdateStanceBindings()
for barName, bar in pairs(self.handledBars) do
if bar then
self:UpdateButtonConfig(bar, bar.bindButtons)
self:PositionAndSizeBar(barName)
end
end
self:AdjustMaxStanceButtons()
self:PositionAndSizeBarPet()
self:PositionAndSizeBarShapeShift()
end
function AB:GetPage(bar, defaultPage, condition)
local page = self.db[bar].paging[E.myclass]
if not condition then condition = "" end
if not page then
page = ""
elseif match(page, "[\n\r]") then
page = gsub(page, "[\n\r]","")
end
if page then
condition = condition.." "..page
end
condition = condition.." "..defaultPage
return condition
end
function AB:StyleButton(button, noBackdrop, useMasque)
local name = button:GetName()
local icon = _G[name.."Icon"]
local count = _G[name.."Count"]
local flash = _G[name.."Flash"]
local hotkey = _G[name.."HotKey"]
local border = _G[name.."Border"]
local macroText = _G[name.."Name"]
local normal = _G[name.."NormalTexture"]
local normal2 = button:GetNormalTexture()
local buttonCooldown = _G[name.."Cooldown"]
local color = self.db.fontColor
local countPosition = self.db.countTextPosition or "BOTTOMRIGHT"
local countXOffset = self.db.countTextXOffset or 0
local countYOffset = self.db.countTextYOffset or 2
button.noBackdrop = noBackdrop
button.useMasque = useMasque
if flash then flash:SetTexture(nil) end
if normal then normal:SetTexture(nil) normal:Hide() normal:SetAlpha(0) end
if normal2 then normal2:SetTexture(nil) normal2:Hide() normal2:SetAlpha(0) end
if border and not button.useMasque then border:Kill() end
if count then
count:ClearAllPoints()
count:Point(countPosition, countXOffset, countYOffset)
count:FontTemplate(LSM:Fetch("font", self.db.font), self.db.fontSize, self.db.fontOutline)
count:SetTextColor(color.r, color.g, color.b)
end
if macroText then
macroText:ClearAllPoints()
macroText:Point("BOTTOM", 0, 1)
macroText:FontTemplate(LSM:Fetch("font", self.db.font), self.db.fontSize, self.db.fontOutline)
macroText:SetTextColor(color.r, color.g, color.b)
end
if not button.noBackdrop and not button.backdrop and not button.useMasque then
button:CreateBackdrop(self.db.transparentButtons and "Transparent", true)
button.backdrop:SetAllPoints()
end
if icon then
icon:SetTexCoord(unpack(E.TexCoords))
icon:SetInside()
end
if self.db.hotkeytext or self.db.useRangeColorText then
hotkey:FontTemplate(LSM:Fetch("font", self.db.font), self.db.fontSize, self.db.fontOutline)
if button.config and (button.config.outOfRangeColoring ~= "hotkey") then
button.hotkey:SetTextColor(color.r, color.g, color.b)
end
end
self:FixKeybindText(button)
if not button.useMasque then
button:StyleButton()
else
button:StyleButton(true, true, true)
end
if not self.handledbuttons[button] then
buttonCooldown.CooldownOverride = "actionbar"
E:RegisterCooldown(buttonCooldown)
self.handledbuttons[button] = true
end
end
function AB:Bar_OnEnter(bar)
if bar:GetParent() == self.fadeParent then
if not self.fadeParent.mouseLock then
E:UIFrameFadeIn(self.fadeParent, 0.2, self.fadeParent:GetAlpha(), 1)
end
end
if bar.mouseover then
E:UIFrameFadeIn(bar, 0.2, bar:GetAlpha(), bar.db.alpha)
end
end
function AB:Bar_OnLeave(bar)
if bar:GetParent() == self.fadeParent then
if not self.fadeParent.mouseLock then
E:UIFrameFadeOut(self.fadeParent, 0.2, self.fadeParent:GetAlpha(), 1 - self.db.globalFadeAlpha)
end
end
if bar.mouseover then
E:UIFrameFadeOut(bar, 0.2, bar:GetAlpha(), 0)
end
end
function AB:Button_OnEnter(button)
local bar = button:GetParent()
if bar:GetParent() == self.fadeParent then
if not self.fadeParent.mouseLock then
E:UIFrameFadeIn(self.fadeParent, 0.2, self.fadeParent:GetAlpha(), 1)
end
end
if bar.mouseover then
E:UIFrameFadeIn(bar, 0.2, bar:GetAlpha(), bar.db.alpha)
end
end
function AB:Button_OnLeave(button)
local bar = button:GetParent()
if bar:GetParent() == self.fadeParent then
if not self.fadeParent.mouseLock then
E:UIFrameFadeOut(self.fadeParent, 0.2, self.fadeParent:GetAlpha(), 1 - self.db.globalFadeAlpha)
end
end
if bar.mouseover then
E:UIFrameFadeOut(bar, 0.2, bar:GetAlpha(), 0)
end
end
function AB:BlizzardOptionsPanel_OnEvent()
InterfaceOptionsActionBarsPanelBottomRightText:SetFormattedText(L["Remove Bar %d Action Page"], 2)
InterfaceOptionsActionBarsPanelBottomLeftText:SetFormattedText(L["Remove Bar %d Action Page"], 3)
InterfaceOptionsActionBarsPanelRightTwoText:SetFormattedText(L["Remove Bar %d Action Page"], 4)
InterfaceOptionsActionBarsPanelRightText:SetFormattedText(L["Remove Bar %d Action Page"], 5)
InterfaceOptionsActionBarsPanelBottomRight:SetScript("OnEnter", nil)
InterfaceOptionsActionBarsPanelBottomLeft:SetScript("OnEnter", nil)
InterfaceOptionsActionBarsPanelRightTwo:SetScript("OnEnter", nil)
InterfaceOptionsActionBarsPanelRight:SetScript("OnEnter", nil)
end
function AB:FadeParent_OnEvent(event, unit)
if (event == "UNIT_SPELLCAST_START"
or event == "UNIT_SPELLCAST_STOP"
or event == "UNIT_SPELLCAST_CHANNEL_START"
or event == "UNIT_SPELLCAST_CHANNEL_STOP"
or event == "UNIT_HEALTH") and unit ~= "player" then return end
local cur, max = UnitHealth("player"), UnitHealthMax("player")
local cast, channel = UnitCastingInfo("player"), UnitChannelInfo("player")
local target, focus = UnitExists("target"), UnitExists("focus")
local combat = UnitAffectingCombat("player")
if (cast or channel) or (cur ~= max) or (target or focus) or combat then
self.mouseLock = true
E:UIFrameFadeIn(self, 0.2, self:GetAlpha(), 1)
else
self.mouseLock = false
E:UIFrameFadeOut(self, 0.2, self:GetAlpha(), 1 - AB.db.globalFadeAlpha)
end
end
function AB:DisableBlizzard()
UIHider = CreateFrame("Frame")
UIHider:Hide()
MultiBarBottomLeft:SetParent(UIHider)
MultiBarBottomLeft.Show = E.noop
MultiBarBottomLeft.Hide = E.noop
MultiBarBottomRight:SetParent(UIHider)
MultiBarBottomRight.Hide = E.noop
MultiBarBottomRight.Show = E.noop
MultiBarLeft:SetParent(UIHider)
MultiBarLeft.Show = E.noop
MultiBarLeft.Hide = E.noop
MultiBarRight:SetParent(UIHider)
MultiBarRight.Show = E.noop
MultiBarRight.Hide = E.noop
-- Hide MultiBar Buttons, but keep the bars alive
for i = 1, 12 do
_G["ActionButton"..i]:Hide()
_G["ActionButton"..i]:UnregisterAllEvents()
_G["ActionButton"..i]:SetAttribute("statehidden", true)
_G["MultiBarBottomLeftButton"..i]:Hide()
_G["MultiBarBottomLeftButton"..i]:UnregisterAllEvents()
_G["MultiBarBottomLeftButton"..i]:SetAttribute("statehidden", true)
_G["MultiBarBottomRightButton"..i]:Hide()
_G["MultiBarBottomRightButton"..i]:UnregisterAllEvents()
_G["MultiBarBottomRightButton"..i]:SetAttribute("statehidden", true)
_G["MultiBarRightButton"..i]:Hide()
_G["MultiBarRightButton"..i]:UnregisterAllEvents()
_G["MultiBarRightButton"..i]:SetAttribute("statehidden", true)
_G["MultiBarLeftButton"..i]:Hide()
_G["MultiBarLeftButton"..i]:UnregisterAllEvents()
_G["MultiBarLeftButton"..i]:SetAttribute("statehidden", true)
if _G["VehicleMenuBarActionButton"..i] then
_G["VehicleMenuBarActionButton"..i]:Hide()
_G["VehicleMenuBarActionButton"..i]:UnregisterAllEvents()
_G["VehicleMenuBarActionButton"..i]:SetAttribute("statehidden", true)
end
_G["BonusActionButton"..i]:Hide()
_G["BonusActionButton"..i]:UnregisterAllEvents()
_G["BonusActionButton"..i]:SetAttribute("statehidden", true)
end
MultiCastActionBarFrame.ignoreFramePositionManager = true
MainMenuBar:Hide()
MainMenuBar:SetParent(UIHider)
MainMenuExpBar:UnregisterAllEvents()
MainMenuExpBar:Hide()
MainMenuExpBar:SetParent(UIHider)
ReputationWatchBar:UnregisterAllEvents()
ReputationWatchBar:Hide()
ReputationWatchBar:SetParent(UIHider)
MainMenuBarArtFrame:UnregisterAllEvents()
MainMenuBarArtFrame:RegisterEvent("KNOWN_CURRENCY_TYPES_UPDATE")
MainMenuBarArtFrame:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
MainMenuBarArtFrame:Hide()
MainMenuBarArtFrame:SetParent(UIHider)
ShapeshiftBarFrame:UnregisterAllEvents()
ShapeshiftBarFrame:Hide()
ShapeshiftBarFrame:SetParent(UIHider)
BonusActionBarFrame:UnregisterAllEvents()
BonusActionBarFrame:Hide()
BonusActionBarFrame:SetParent(UIHider)
PossessBarFrame:UnregisterAllEvents()
PossessBarFrame:Hide()
PossessBarFrame:SetParent(UIHider)
PetActionBarFrame:UnregisterAllEvents()
PetActionBarFrame:Hide()
PetActionBarFrame:SetParent(UIHider)
VehicleMenuBar:UnregisterAllEvents()
VehicleMenuBar:Hide()
VehicleMenuBar:SetParent(UIHider)
InterfaceOptionsActionBarsPanelAlwaysShowActionBars:EnableMouse(false)
InterfaceOptionsActionBarsPanelAlwaysShowActionBars:SetAlpha(0)
InterfaceOptionsActionBarsPanelLockActionBars:EnableMouse(false)
InterfaceOptionsActionBarsPanelLockActionBars:SetAlpha(0)
InterfaceOptionsStatusTextPanelXP:SetAlpha(0)
InterfaceOptionsStatusTextPanelXP:SetScale(0.0001)
self:SecureHook("BlizzardOptionsPanel_OnEvent")
if PlayerTalentFrame then
PlayerTalentFrame:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
else
hooksecurefunc("TalentFrame_LoadUI", function() PlayerTalentFrame:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED") end)
end
end
function AB:UpdateButtonConfig(bar, buttonName)
if InCombatLockdown() then
AB.NeedsUpdateButtonSettings = true
self:RegisterEvent("PLAYER_REGEN_ENABLED")
return
end
if not bar.buttonConfig then bar.buttonConfig = {hideElements = {}, colors = {}} end
bar.buttonConfig.hideElements.macro = not self.db.macrotext
bar.buttonConfig.hideElements.hotkey = not self.db.hotkeytext
bar.buttonConfig.showGrid = self.db["bar"..bar.id].showGrid
bar.buttonConfig.clickOnDown = self.db.keyDown
bar.buttonConfig.outOfRangeColoring = (self.db.useRangeColorText and "hotkey") or "button"
SetModifiedClick("PICKUPACTION", self.db.movementModifier)
bar.buttonConfig.colors.range = E:SetColorTable(bar.buttonConfig.colors.range, self.db.noRangeColor)
bar.buttonConfig.colors.mana = E:SetColorTable(bar.buttonConfig.colors.mana, self.db.noPowerColor)
bar.buttonConfig.colors.usable = E:SetColorTable(bar.buttonConfig.colors.usable, self.db.usableColor)
bar.buttonConfig.colors.notUsable = E:SetColorTable(bar.buttonConfig.colors.notUsable, self.db.notUsableColor)
for i, button in pairs(bar.buttons) do
bar.buttonConfig.keyBoundTarget = format(buttonName.."%d", i)
button.keyBoundTarget = bar.buttonConfig.keyBoundTarget
button.postKeybind = AB.FixKeybindText
button:SetAttribute("buttonlock", self.db.lockActionBars)
button:SetAttribute("checkselfcast", true)
button:SetAttribute("checkfocuscast", true)
if self.db.rightClickSelfCast then
button:SetAttribute("unit2", "player")
else
button:SetAttribute("unit2", nil)
end
button:UpdateConfig(bar.buttonConfig)
end
end
function AB:FixKeybindText(button)
local hotkey = _G[button:GetName().."HotKey"]
local text = hotkey:GetText()
local hotkeyPosition = E.db.actionbar.hotkeyTextPosition or "TOPRIGHT"
local hotkeyXOffset = E.db.actionbar.hotkeyTextXOffset or 0
local hotkeyYOffset = E.db.actionbar.hotkeyTextYOffset or -3
local justify = "RIGHT"
if hotkeyPosition == "TOPLEFT" or hotkeyPosition == "BOTTOMLEFT" then
justify = "LEFT"
elseif hotkeyPosition == "TOP" or hotkeyPosition == "BOTTOM" then
justify = "CENTER"
end
if text then
text = gsub(text, "SHIFT%-", L["KEY_SHIFT"])
text = gsub(text, "ALT%-", L["KEY_ALT"])
text = gsub(text, "CTRL%-", L["KEY_CTRL"])
text = gsub(text, "BUTTON", L["KEY_MOUSEBUTTON"])
text = gsub(text, "MOUSEWHEELUP", L["KEY_MOUSEWHEELUP"])
text = gsub(text, "MOUSEWHEELDOWN", L["KEY_MOUSEWHEELDOWN"])
text = gsub(text, "NUMPAD", L["KEY_NUMPAD"])
text = gsub(text, "PAGEUP", L["KEY_PAGEUP"])
text = gsub(text, "PAGEDOWN", L["KEY_PAGEDOWN"])
text = gsub(text, "SPACE", L["KEY_SPACE"])
text = gsub(text, "INSERT", L["KEY_INSERT"])
text = gsub(text, "HOME", L["KEY_HOME"])
text = gsub(text, "DELETE", L["KEY_DELETE"])
text = gsub(text, "NMULTIPLY", "*")
text = gsub(text, "NMINUS", "N-")
text = gsub(text, "NPLUS", "N+")
hotkey:SetText(text)
hotkey:SetJustifyH(justify)
end
if not button.useMasque then
hotkey:ClearAllPoints()
hotkey:Point(hotkeyPosition, hotkeyXOffset, hotkeyYOffset)
end
end
function AB:LAB_ButtonUpdate(button)
local color = AB.db.fontColor
button.count:SetTextColor(color.r, color.g, color.b)
if button.config and (button.config.outOfRangeColoring ~= "hotkey") then
button.hotkey:SetTextColor(color.r, color.g, color.b)
end
if button.backdrop then
if AB.db.equippedItem then
if button:IsEquipped() and AB.db.equippedItemColor then
color = AB.db.equippedItemColor
button.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
button.backdrop.isColored = true
elseif button.backdrop.isColored then
button.backdrop.isColored = nil
button.backdrop:SetBackdropBorderColor(unpack(E.media.bordercolor))
end
elseif button.backdrop.isColored then
button.backdrop.isColored = nil
button.backdrop:SetBackdropBorderColor(unpack(E.media.bordercolor))
end
end
end
LAB.RegisterCallback(AB, "OnButtonUpdate", AB.LAB_ButtonUpdate)
local function OnCooldownUpdate(_, button, start, duration)
if button._state_type ~= "action" then return end
if duration and duration > 1.5 then
button.saturationLocked = true --Lock any new actions that are created after we activated desaturation option
button.icon:SetDesaturated(true)
if (E.db.cooldown.enable and AB.db.cooldown.reverse) or (not E.db.cooldown.enable and not AB.db.cooldown.reverse) then
if not button.onCooldownDoneHooked then
AB:HookScript(button.cooldown, "OnHide", function()
button.icon:SetDesaturated(false)
end)
button.onCooldownDoneHooked = true
end
else
if not button.onCooldownTimerDoneHooked then
if button.cooldown.timer then
AB:HookScript(button.cooldown.timer, "OnHide", function()
if (E.db.cooldown.enable and AB.db.cooldown.reverse) or (not E.db.cooldown.enable and not AB.db.cooldown.reverse) then return end
button.icon:SetDesaturated(false)
end)
button.onCooldownTimerDoneHooked = true
end
end
end
end
end
function AB:ToggleDesaturation(value)
value = value or self.db.desaturateOnCooldown
if value then
LAB.RegisterCallback(AB, "OnCooldownUpdate", OnCooldownUpdate)
local start, duration
for button in pairs(LAB.actionButtons) do
button.saturationLocked = true
start, duration = button:GetCooldown()
OnCooldownUpdate(nil, button, start, duration)
end
else
LAB.UnregisterCallback(AB, "OnCooldownUpdate")
for button in pairs(LAB.actionButtons) do
button.saturationLocked = nil
button.icon:SetDesaturated(false)
if (E.db.cooldown.enable and AB.db.cooldown.reverse) or (not E.db.cooldown.enable and not AB.db.cooldown.reverse) then
if button.onCooldownDoneHooked then
AB:Unhook(button.cooldown, "OnHide")
button.onCooldownDoneHooked = nil
end
else
if button.onCooldownTimerDoneHooked then
if button.cooldown.timer then
if (E.db.cooldown.enable and AB.db.cooldown.reverse) or (not E.db.cooldown.enable and not AB.db.cooldown.reverse) then return end
AB:Unhook(button.cooldown.timer, "OnHide")
button.onCooldownTimerDoneHooked = nil
end
end
end
end
end
end
function AB:Initialize()
self.db = E.db.actionbar
if E.private.actionbar.enable ~= true then return end
self.Initialized = true
self.LBFGroup = LBF and LBF:Group("ElvUI", "ActionBars")
self.fadeParent = CreateFrame("Frame", "Elv_ABFade", UIParent)
self.fadeParent:SetAlpha(1 - self.db.globalFadeAlpha)
self.fadeParent:RegisterEvent("PLAYER_REGEN_DISABLED")
self.fadeParent:RegisterEvent("PLAYER_REGEN_ENABLED")
self.fadeParent:RegisterEvent("PLAYER_TARGET_CHANGED")
self.fadeParent:RegisterEvent("UNIT_SPELLCAST_START")
self.fadeParent:RegisterEvent("UNIT_SPELLCAST_STOP")
self.fadeParent:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START")
self.fadeParent:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP")
self.fadeParent:RegisterEvent("UNIT_HEALTH")
self.fadeParent:RegisterEvent("PLAYER_FOCUS_CHANGED")
self.fadeParent:SetScript("OnEvent", self.FadeParent_OnEvent)
self:DisableBlizzard()
self:SetupMicroBar()
self:UpdateBar1Paging()
for i = 1, 6 do
self:CreateBar(i)
end
self:CreateBarPet()
self:CreateBarShapeShift()
self:CreateVehicleLeave()
if self.db.barTotem.enabled then
self:CreateTotemBar()
end
self:UpdateButtonSettings()
self:LoadKeyBinder()
self:RegisterEvent("UPDATE_BINDINGS", "ReassignBindings")
self:ReassignBindings()
--We handle actionbar lock for regular bars, but the lock on PetBar needs to be handled by WoW so make some necessary updates
SetCVar("lockActionBars", (self.db.lockActionBars == true and 1 or 0))
LOCK_ACTIONBAR = (self.db.lockActionBars == true and "1" or "0") --Keep an eye on this, in case it taints
self:ToggleDesaturation()
end
local function InitializeCallback()
AB:Initialize()
end
E:RegisterModule(AB:GetName(), InitializeCallback)
+392
View File
@@ -0,0 +1,392 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local AB = E:GetModule("ActionBars")
local Skins = E:GetModule("Skins")
--Lua functions
local _G = _G
local select, tonumber, pairs = select, tonumber, pairs
local floor = math.floor
local find, format, upper = string.find, string.format, string.upper
--WoW API / Variables
local hooksecurefunc = hooksecurefunc
local CreateFrame = CreateFrame
local IsAddOnLoaded = IsAddOnLoaded
local LoadBindings, SaveBindings = LoadBindings, SaveBindings
local GetCurrentBindingSet = GetCurrentBindingSet
local SetBinding = SetBinding
local GetBindingKey = GetBindingKey
local IsAltKeyDown, IsControlKeyDown = IsAltKeyDown, IsControlKeyDown
local IsShiftKeyDown, IsModifiedClick = IsShiftKeyDown, IsModifiedClick
local InCombatLockdown = InCombatLockdown
local GameTooltip_ShowCompareItem = GameTooltip_ShowCompareItem
local GetMacroInfo = GetMacroInfo
local SecureActionButton_OnClick = SecureActionButton_OnClick
local GameTooltip_Hide = GameTooltip_Hide
local CHARACTER_SPECIFIC_KEYBINDING_TOOLTIP = CHARACTER_SPECIFIC_KEYBINDING_TOOLTIP
local CHARACTER_SPECIFIC_KEYBINDINGS = CHARACTER_SPECIFIC_KEYBINDINGS
local bind = CreateFrame("Frame", "ElvUI_KeyBinder", E.UIParent)
function AB:ActivateBindMode()
if InCombatLockdown() then
return
end
bind.active = true
E:StaticPopupSpecial_Show(ElvUIBindPopupWindow)
AB:RegisterEvent("PLAYER_REGEN_DISABLED", "DeactivateBindMode", false)
end
function AB:DeactivateBindMode(save)
if save then
SaveBindings(GetCurrentBindingSet())
E:Print(L["Binds Saved"])
else
LoadBindings(GetCurrentBindingSet())
E:Print(L["Binds Discarded"])
end
bind.active = false
self:BindHide()
self:UnregisterEvent("PLAYER_REGEN_DISABLED")
E:StaticPopupSpecial_Hide(ElvUIBindPopupWindow)
AB.bindingsChanged = false
end
function AB:BindHide()
bind:ClearAllPoints()
bind:Hide()
GameTooltip:Hide()
end
function AB:BindListener(key)
AB.bindingsChanged = true
if key == "ESCAPE" or key == "RightButton" then
if bind.button.bindings then
for i = 1, #bind.button.bindings do
SetBinding(bind.button.bindings[i])
end
end
E:Print(format(L["All keybindings cleared for |cff00ff00%s|r."], bind.button.name))
self:BindUpdate(bind.button, bind.spellmacro)
if bind.spellmacro ~= "MACRO" then
GameTooltip:Hide()
end
return
end
if key == "LSHIFT"
or key == "RSHIFT"
or key == "LCTRL"
or key == "RCTRL"
or key == "LALT"
or key == "RALT"
or key == "UNKNOWN"
or key == "LeftButton"
then return end
if key == "MiddleButton" then key = "BUTTON3" end
if find(key, "Button%d") then
key = upper(key)
end
local alt = IsAltKeyDown() and "ALT-" or ""
local ctrl = IsControlKeyDown() and "CTRL-" or ""
local shift = IsShiftKeyDown() and "SHIFT-" or ""
local keybind = format("%s%s%s%s", alt, ctrl, shift, key)
if not bind.spellmacro or bind.spellmacro == "PET" or bind.spellmacro == "SHAPESHIFT" then
SetBinding(keybind, bind.button.bindstring)
else
SetBinding(keybind, bind.spellmacro.." "..bind.button.name)
end
E:Print(format("%s%s%s.", keybind, L[" |cff00ff00bound to |r"], bind.button.name))
self:BindUpdate(bind.button, bind.spellmacro)
if bind.spellmacro ~= "MACRO" then
GameTooltip:Hide()
end
end
function AB:BindUpdate(button, spellmacro)
if not bind.active or InCombatLockdown() then return end
bind.button = button
bind.spellmacro = spellmacro
bind:ClearAllPoints()
bind:SetAllPoints(button)
bind:Show()
ShoppingTooltip1:Hide()
if not bind:IsMouseEnabled() then
bind:EnableMouse(true)
end
if spellmacro == "MACRO" then
bind.button.id = bind.button:GetID()
if floor(.5 + select(2, MacroFrameTab1Text:GetTextColor()) * 10) / 10 == .8 then bind.button.id = bind.button.id + MAX_ACCOUNT_MACROS end
bind.button.name = GetMacroInfo(bind.button.id)
GameTooltip:SetOwner(bind, "ANCHOR_TOP")
GameTooltip:SetPoint("BOTTOM", bind, "TOP", 0, 1)
GameTooltip:AddLine(bind.button.name, 1, 1, 1)
bind.button.bindings = {GetBindingKey(spellmacro.." "..bind.button.name)}
if #bind.button.bindings == 0 then
GameTooltip:AddLine(L["No bindings set."], .6, .6, .6)
else
GameTooltip:AddDoubleLine(L["Binding"], L["Key"], .6, .6, .6, .6, .6, .6)
for i = 1, #bind.button.bindings do
GameTooltip:AddDoubleLine(L["Binding"]..i, bind.button.bindings[i], 1, 1, 1)
end
end
GameTooltip:Show()
elseif spellmacro == "SHAPESHIFT" or spellmacro == "PET" then
bind.button.id = tonumber(button:GetID())
bind.button.name = button:GetName()
if not bind.button.name then return end
if not bind.button.id or bind.button.id < 1 or bind.button.id > (spellmacro=="SHAPESHIFT" and 10 or 12) then
bind.button.bindstring = "CLICK "..bind.button.name..":LeftButton"
else
bind.button.bindstring = (spellmacro=="SHAPESHIFT" and "SHAPESHIFTBUTTON" or "BONUSACTIONBUTTON")..bind.button.id
end
GameTooltip:AddLine(L["Trigger"])
GameTooltip:Show()
GameTooltip:SetScript("OnHide", function(tt)
tt:SetOwner(bind, "ANCHOR_NONE")
tt:SetPoint("BOTTOM", bind, "TOP", 0, 1)
tt:AddLine(bind.button.name, 1, 1, 1)
bind.button.bindings = {GetBindingKey(bind.button.bindstring)}
if #bind.button.bindings == 0 then
tt:AddLine(L["No bindings set."], .6, .6, .6)
else
tt:AddDoubleLine(L["Binding"], L["Key"], .6, .6, .6, .6, .6, .6)
for i = 1, #bind.button.bindings do
tt:AddDoubleLine(i, bind.button.bindings[i])
end
end
tt:Show()
tt:SetScript("OnHide", nil)
end)
else
bind.button.action = tonumber(button.action)
bind.button.name = button:GetName()
if not bind.button.name then return end
if (not bind.button.action or bind.button.action < 1 or bind.button.action > 132) and not (bind.button.keyBoundTarget) then
bind.button.bindstring = "CLICK "..bind.button.name..":LeftButton"
elseif bind.button.keyBoundTarget then
bind.button.bindstring = bind.button.keyBoundTarget
else
local modact = 1 + (bind.button.action-1) % 12
if bind.button.action < 25 or bind.button.action > 72 then
bind.button.bindstring = "ACTIONBUTTON"..modact
elseif bind.button.action < 73 and bind.button.action > 60 then
bind.button.bindstring = "MULTIACTIONBAR1BUTTON"..modact
elseif bind.button.action < 61 and bind.button.action > 48 then
bind.button.bindstring = "MULTIACTIONBAR2BUTTON"..modact
elseif bind.button.action < 49 and bind.button.action > 36 then
bind.button.bindstring = "MULTIACTIONBAR4BUTTON"..modact
elseif bind.button.action < 37 and bind.button.action > 24 then
bind.button.bindstring = "MULTIACTIONBAR3BUTTON"..modact
end
end
GameTooltip:AddLine(L["Trigger"])
GameTooltip:Show()
GameTooltip:SetScript("OnHide", function(tt)
tt:SetOwner(bind, "ANCHOR_TOP")
tt:SetPoint("BOTTOM", bind, "TOP", 0, 4)
tt:AddLine(bind.button.name, 1, 1, 1)
bind.button.bindings = {GetBindingKey(bind.button.bindstring)}
if #bind.button.bindings == 0 then
tt:AddLine(L["No bindings set."], .6, .6, .6)
else
tt:AddDoubleLine(L["Binding"], L["Key"], .6, .6, .6, .6, .6, .6)
for i = 1, #bind.button.bindings do
tt:AddDoubleLine(i, bind.button.bindings[i])
end
end
tt:Show()
tt:SetScript("OnHide", nil)
end)
end
end
function AB:RegisterButton(button, override)
local shapeshift = ShapeshiftButton1:GetScript("OnClick")
local pet = PetActionButton1:GetScript("OnClick")
local secureOnClick = SecureActionButton_OnClick
if button.IsProtected and button.GetObjectType and button.GetScript and button:GetObjectType() == "CheckButton" and button:IsProtected() then
local script = button:GetScript("OnClick")
if script == secureOnClick or override then
button:HookScript("OnEnter", function(b) self:BindUpdate(b) end)
if script == shapeshift then
button:HookScript("OnEnter", function(b) self:BindUpdate(b, "SHAPESHIFT") end)
elseif script == pet then
button:HookScript("OnEnter", function(b) self:BindUpdate(b, "PET") end)
end
end
end
end
local elapsed = 0
function AB:Tooltip_OnUpdate(tooltip, e)
elapsed = elapsed + e
if elapsed < .2 then return else elapsed = 0 end
local compareItems = IsModifiedClick("COMPAREITEMS")
if not tooltip.comparing and compareItems and tooltip:GetItem() then
GameTooltip_ShowCompareItem(tooltip)
tooltip.comparing = true
elseif tooltip.comparing and not compareItems then
for _, frame in pairs(tooltip.shoppingTooltips) do frame:Hide() end
tooltip.comparing = false
end
end
function AB:RegisterMacro(addon)
if addon == "Blizzard_MacroUI" then
for i = 1, MAX_ACCOUNT_MACROS do
local button = _G["MacroButton"..i]
button:HookScript("OnEnter", function(b) AB:BindUpdate(b, "MACRO") end)
end
end
end
function AB:ChangeBindingProfile()
if ElvUIBindPopupWindowCheckButton:GetChecked() then
LoadBindings(2)
SaveBindings(2)
else
LoadBindings(1)
SaveBindings(1)
end
end
function AB:LoadKeyBinder()
bind:SetFrameStrata("DIALOG")
bind:SetFrameLevel(99)
bind:EnableMouse(true)
bind:EnableKeyboard(true)
bind:EnableMouseWheel(true)
bind.texture = bind:CreateTexture()
bind.texture:SetAllPoints(bind)
bind.texture:SetTexture(0, 0, 0, .25)
bind:Hide()
self:HookScript(GameTooltip, "OnUpdate", "Tooltip_OnUpdate")
hooksecurefunc(GameTooltip, "Hide", function(tooltip) for _, tt in pairs(tooltip.shoppingTooltips) do tt:Hide() end end)
bind:SetScript("OnEnter", function(self) local db = self.button:GetParent().db if db and db.mouseover then AB:Button_OnEnter(self.button) end end)
bind:SetScript("OnLeave", function(self) AB:BindHide() local db = self.button:GetParent().db if db and db.mouseover then AB:Button_OnLeave(self.button) end end)
bind:SetScript("OnKeyUp", function(_, key) self:BindListener(key) end)
bind:SetScript("OnMouseUp", function(_, key) self:BindListener(key) end)
bind:SetScript("OnMouseWheel", function(_, delta) if delta > 0 then self:BindListener("MOUSEWHEELUP") else self:BindListener("MOUSEWHEELDOWN") end end)
for b, _ in pairs(self.handledbuttons) do
self:RegisterButton(b, true)
end
if not IsAddOnLoaded("Blizzard_MacroUI") then
self:SecureHook("LoadAddOn", "RegisterMacro")
else
self:RegisterMacro("Blizzard_MacroUI")
end
--Special Popup
local f = CreateFrame("Frame", "ElvUIBindPopupWindow", UIParent)
f:SetFrameStrata("DIALOG")
f:SetToplevel(true)
f:EnableMouse(true)
f:SetMovable(true)
f:SetFrameLevel(99)
f:SetClampedToScreen(true)
f:SetWidth(360)
f:SetHeight(130)
f:SetTemplate("Transparent")
f:Hide()
local header = CreateFrame("Button", nil, f)
header:SetTemplate(nil, true)
header:Width(100)
header:Height(25)
header:Point("CENTER", f, "TOP")
header:SetFrameLevel(header:GetFrameLevel() + 2)
header:EnableMouse(true)
header:RegisterForClicks("AnyUp", "AnyDown")
header:SetScript("OnMouseDown", function() f:StartMoving() end)
header:SetScript("OnMouseUp", function() f:StopMovingOrSizing() end)
local title = header:CreateFontString("OVERLAY")
title:FontTemplate()
title:Point("CENTER", header, "CENTER")
title:SetText("Key Binds")
local desc = f:CreateFontString("ARTWORK")
desc:SetFontObject("GameFontHighlight")
desc:SetJustifyV("TOP")
desc:SetJustifyH("LEFT")
desc:Point("TOPLEFT", 18, -32)
desc:Point("BOTTOMRIGHT", -18, 48)
desc:SetText(L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the ESC key to clear the current actionbutton's keybinding."])
local perCharCheck = CreateFrame("CheckButton", f:GetName().."CheckButton", f, "OptionsCheckButtonTemplate")
_G[perCharCheck:GetName().."Text"]:SetText(CHARACTER_SPECIFIC_KEYBINDINGS)
perCharCheck:SetScript("OnShow", function(self)
self:SetChecked(GetCurrentBindingSet() == 2)
end)
perCharCheck:SetScript("OnClick", function()
if ( AB.bindingsChanged ) then
E:StaticPopup_Show("CONFIRM_LOSE_BINDING_CHANGES")
else
AB:ChangeBindingProfile()
end
end)
perCharCheck:SetScript("OnEnter", function(self)
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
GameTooltip:SetText(CHARACTER_SPECIFIC_KEYBINDING_TOOLTIP, nil, nil, nil, nil, 1)
end)
perCharCheck:SetScript("OnLeave", GameTooltip_Hide)
local save = CreateFrame("Button", f:GetName().."SaveButton", f, "OptionsButtonTemplate")
_G[save:GetName().."Text"]:SetText(L["Save"])
save:Width(150)
save:SetScript("OnClick", function()
AB:DeactivateBindMode(true)
end)
local discard = CreateFrame("Button", f:GetName().."DiscardButton", f, "OptionsButtonTemplate")
discard:Width(150)
_G[discard:GetName().."Text"]:SetText(L["Discard"])
discard:SetScript("OnClick", function()
AB:DeactivateBindMode(false)
end)
--position buttons
perCharCheck:Point("BOTTOMLEFT", discard, "TOPLEFT", 0, 2)
save:Point("BOTTOMRIGHT", -14, 10)
discard:Point("BOTTOMLEFT", 14, 10)
Skins:HandleCheckBox(perCharCheck)
Skins:HandleButton(save)
Skins:HandleButton(discard)
end
@@ -0,0 +1,8 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="ActionBars.lua"/>
<Script file="MicroBar.lua"/>
<Script file="PetBar.lua"/>
<Script file="StanceBar.lua"/>
<Script file="TotemBar.lua"/>
<Script file="Bind.lua"/>
</Ui>
+194
View File
@@ -0,0 +1,194 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local AB = E:GetModule("ActionBars")
--Lua functions
local _G = _G
--WoW API / Variables
local CreateFrame = CreateFrame
local InCombatLockdown = InCombatLockdown
local RegisterStateDriver = RegisterStateDriver
local MICRO_BUTTONS = {
"CharacterMicroButton",
"SpellbookMicroButton",
"TalentMicroButton",
"AchievementMicroButton",
"QuestLogMicroButton",
"SocialsMicroButton",
"PVPMicroButton",
"LFDMicroButton",
"MainMenuMicroButton",
"HelpMicroButton"
}
local function onEnter(button)
if AB.db.microbar.mouseover then
E:UIFrameFadeIn(ElvUI_MicroBar, 0.2, ElvUI_MicroBar:GetAlpha(), AB.db.microbar.alpha)
end
if button and button ~= ElvUI_MicroBar and button.backdrop then
button.backdrop:SetBackdropBorderColor(unpack(E.media.rgbvaluecolor))
end
end
local function onLeave(button)
if AB.db.microbar.mouseover then
E:UIFrameFadeOut(ElvUI_MicroBar, 0.2, ElvUI_MicroBar:GetAlpha(), 0)
end
if button and button ~= ElvUI_MicroBar and button.backdrop then
button.backdrop:SetBackdropBorderColor(unpack(E.media.bordercolor))
end
end
function AB:HandleMicroButton(button)
local pushed = button:GetPushedTexture()
local normal = button:GetNormalTexture()
local disabled = button:GetDisabledTexture()
local f = CreateFrame("Frame", nil, button)
f:SetFrameLevel(button:GetFrameLevel() - 1)
f:SetTemplate("Default", true)
f:SetOutside(button)
button.backdrop = f
button:SetParent(ElvUI_MicroBar)
button:GetHighlightTexture():Kill()
button:HookScript("OnEnter", onEnter)
button:HookScript("OnLeave", onLeave)
button:SetHitRectInsets(0, 0, 0, 0)
button:Show()
pushed:SetTexCoord(0.17, 0.87, 0.5, 0.908)
pushed:SetInside(f)
normal:SetTexCoord(0.17, 0.87, 0.5, 0.908)
normal:SetInside(f)
if disabled then
disabled:SetTexCoord(0.17, 0.87, 0.5, 0.908)
disabled:SetInside(f)
end
end
function AB:UpdateMicroButtonsParent()
if CharacterMicroButton:GetParent() == ElvUI_MicroBar then return end
for i = 1, #MICRO_BUTTONS do
_G[MICRO_BUTTONS[i]]:SetParent(ElvUI_MicroBar)
end
AB:UpdateMicroPositionDimensions()
end
function AB:UpdateMicroBarVisibility()
if InCombatLockdown() then
AB.NeedsUpdateMicroBarVisibility = true
self:RegisterEvent("PLAYER_REGEN_ENABLED")
return
end
local visibility = self.db.microbar.visibility
if visibility and string.match(visibility, "[\n\r]") then
visibility = string.gsub(visibility, "[\n\r]", "")
end
RegisterStateDriver(ElvUI_MicroBar.visibility, "visibility", (self.db.microbar.enabled and visibility) or "hide")
end
function AB:UpdateMicroPositionDimensions()
if not ElvUI_MicroBar then return end
local numRows = 1
local prevButton = ElvUI_MicroBar
local offset = E:Scale(E.PixelMode and 1 or 3)
local spacing = E:Scale(offset + self.db.microbar.buttonSpacing)
for i = 1, #MICRO_BUTTONS do
local button = _G[MICRO_BUTTONS[i]]
local lastColumnButton = i - self.db.microbar.buttonsPerRow
lastColumnButton = _G[MICRO_BUTTONS[lastColumnButton]]
button:Size(self.db.microbar.buttonSize, self.db.microbar.buttonSize * 1.4)
button:ClearAllPoints()
if prevButton == ElvUI_MicroBar then
button:Point("TOPLEFT", prevButton, "TOPLEFT", offset, -offset)
elseif (i - 1) % self.db.microbar.buttonsPerRow == 0 then
button:Point("TOP", lastColumnButton, "BOTTOM", 0, -spacing)
numRows = numRows + 1
else
button:Point("LEFT", prevButton, "RIGHT", spacing, 0)
end
prevButton = button
end
if AB.db.microbar.mouseover and not ElvUI_MicroBar:IsMouseOver() then
ElvUI_MicroBar:SetAlpha(0)
else
ElvUI_MicroBar:SetAlpha(self.db.microbar.alpha)
end
AB.MicroWidth = (((CharacterMicroButton:GetWidth() + spacing) * self.db.microbar.buttonsPerRow) - spacing) + (offset * 2)
AB.MicroHeight = (((CharacterMicroButton:GetHeight() + spacing) * numRows) - spacing) + (offset * 2)
ElvUI_MicroBar:Size(AB.MicroWidth, AB.MicroHeight)
if ElvUI_MicroBar.mover then
if self.db.microbar.enabled then
E:EnableMover(ElvUI_MicroBar.mover:GetName())
else
E:DisableMover(ElvUI_MicroBar.mover:GetName())
end
end
self:UpdateMicroBarVisibility()
end
function AB:UpdateMicroButtons()
-- PvP Micro Button
PVPMicroButtonTexture:Point("TOPLEFT", PVPMicroButton, "TOPLEFT")
PVPMicroButtonTexture:Point("BOTTOMRIGHT", PVPMicroButton, "BOTTOMRIGHT")
PVPMicroButtonTexture:SetTexture("Interface\\AddOns\\ElvUI\\media\\textures\\PVP-Icons")
if E.mylevel < PVPMicroButton.minLevel then
PVPMicroButtonTexture:SetDesaturated(true)
else
PVPMicroButtonTexture:SetDesaturated(false)
end
self:UpdateMicroPositionDimensions()
end
function AB:SetupMicroBar()
local microBar = CreateFrame("Frame", "ElvUI_MicroBar", E.UIParent)
microBar:Point("TOPLEFT", E.UIParent, "TOPLEFT", 4, -48)
microBar:SetFrameStrata("LOW")
microBar:EnableMouse(true)
microBar:SetScript("OnEnter", onEnter)
microBar:SetScript("OnLeave", onLeave)
microBar.visibility = CreateFrame("Frame", nil, E.UIParent, "SecureHandlerStateTemplate")
microBar.visibility:SetScript("OnShow", function() microBar:Show() end)
microBar.visibility:SetScript("OnHide", function() microBar:Hide() end)
for i = 1, #MICRO_BUTTONS do
self:HandleMicroButton(_G[MICRO_BUTTONS[i]])
end
MicroButtonPortrait:SetInside(CharacterMicroButton.backdrop)
if E.myfaction == "Alliance" then
PVPMicroButtonTexture:SetTexCoord(0.545, 0.935, 0.070, 0.940)
else
PVPMicroButtonTexture:SetTexCoord(0.100, 0.475, 0.070, 0.940)
end
self:SecureHook("VehicleMenuBar_MoveMicroButtons", "UpdateMicroButtonsParent")
self:SecureHook("UpdateMicroButtons")
self:UpdateMicroPositionDimensions()
MainMenuBarPerformanceBar:Kill()
E:CreateMover(microBar, "MicrobarMover", L["Micro Bar"], nil, nil, nil, "ALL,ACTIONBARS", nil, "actionbar,microbar")
end
+308
View File
@@ -0,0 +1,308 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local AB = E:GetModule("ActionBars")
--Lua functions
local _G = _G
local ceil = math.ceil
--WoW API / Variables
local RegisterStateDriver = RegisterStateDriver
local GetBindingKey = GetBindingKey
local PetHasActionBar = PetHasActionBar
local GetPetActionInfo = GetPetActionInfo
local IsPetAttackAction = IsPetAttackAction
local PetActionButton_StartFlash = PetActionButton_StartFlash
local PetActionButton_StopFlash = PetActionButton_StopFlash
local AutoCastShine_AutoCastStart = AutoCastShine_AutoCastStart
local AutoCastShine_AutoCastStop = AutoCastShine_AutoCastStop
local GetPetActionSlotUsable = GetPetActionSlotUsable
local SetDesaturation = SetDesaturation
local PetActionBar_ShowGrid = PetActionBar_ShowGrid
local PetActionBar_UpdateCooldowns = PetActionBar_UpdateCooldowns
local NUM_PET_ACTION_SLOTS = NUM_PET_ACTION_SLOTS
local bar = CreateFrame("Frame", "ElvUI_BarPet", E.UIParent, "SecureHandlerStateTemplate")
bar:SetFrameStrata("LOW")
function AB:UpdatePet(event, unit)
if (event == "UNIT_FLAGS" or event == "UNIT_AURA") and unit ~= "pet" then return end
if event == "UNIT_PET" and unit ~= "player" then return end
for i = 1, NUM_PET_ACTION_SLOTS, 1 do
local buttonName = "PetActionButton"..i
local button = _G[buttonName]
local icon = _G[buttonName.."Icon"]
local autoCast = _G[buttonName.."AutoCastable"]
local shine = _G[buttonName.."Shine"]
local name, subtext, texture, isToken, isActive, autoCastAllowed, autoCastEnabled = GetPetActionInfo(i)
if not isToken then
icon:SetTexture(texture)
button.tooltipName = name
else
icon:SetTexture(_G[texture])
button.tooltipName = _G[name]
end
button.isToken = isToken
button.tooltipSubtext = subtext
if isActive --[[and name ~= "PET_ACTION_FOLLOW"]] then
button:SetChecked(true)
if IsPetAttackAction(i) then
PetActionButton_StartFlash(button)
end
else
button:SetChecked(false)
if IsPetAttackAction(i) then
PetActionButton_StopFlash(button)
end
end
if autoCastAllowed then
autoCast:Show()
else
autoCast:Hide()
end
if autoCastEnabled then
AutoCastShine_AutoCastStart(shine)
else
AutoCastShine_AutoCastStop(shine)
end
if texture then
if GetPetActionSlotUsable(i) then
SetDesaturation(icon, nil)
SetDesaturation(autoCast, nil)
else
SetDesaturation(icon, 1)
SetDesaturation(autoCast, 1)
end
icon:Show()
else
icon:Hide()
end
if not PetHasActionBar() and texture --[[and name ~= "PET_ACTION_FOLLOW"]] then
PetActionButton_StopFlash(button)
SetDesaturation(icon, 1)
button:SetChecked(0)
end
end
end
function AB:PositionAndSizeBarPet()
local buttonSpacing = E:Scale(self.db.barPet.buttonspacing)
local backdropSpacing = E:Scale((self.db.barPet.backdropSpacing or self.db.barPet.buttonspacing))
local buttonsPerRow = self.db.barPet.buttonsPerRow
local numButtons = self.db.barPet.buttons
local size = E:Scale(self.db.barPet.buttonsize)
local autoCastSize = (size / 2) - (size / 7.5)
local point = self.db.barPet.point
local numColumns = ceil(numButtons / buttonsPerRow)
local widthMult = self.db.barPet.widthMult
local heightMult = self.db.barPet.heightMult
local visibility = self.db.barPet.visibility
bar.db = self.db.barPet
if visibility and string.match(visibility, "[\n\r]") then
visibility = string.gsub(visibility, "[\n\r]","")
end
if numButtons < buttonsPerRow then
buttonsPerRow = numButtons
end
if numColumns < 1 then
numColumns = 1
end
if self.db.barPet.backdrop == true then
bar.backdrop:Show()
else
bar.backdrop:Hide()
--Set size multipliers to 1 when backdrop is disabled
widthMult = 1
heightMult = 1
end
local barWidth = (size * (buttonsPerRow * widthMult)) + ((buttonSpacing * (buttonsPerRow - 1)) * widthMult) + (buttonSpacing * (widthMult-1)) + ((self.db.barPet.backdrop == true and (E.Border + backdropSpacing) or E.Spacing)*2)
local barHeight = (size * (numColumns * heightMult)) + ((buttonSpacing * (numColumns - 1)) * heightMult) + (buttonSpacing * (heightMult-1)) + ((self.db.barPet.backdrop == true and (E.Border + backdropSpacing) or E.Spacing)*2)
bar:Width(barWidth)
bar:Height(barHeight)
if self.db.barPet.enabled then
bar:SetScale(1)
bar:SetAlpha(bar.db.alpha)
E:EnableMover(bar.mover:GetName())
else
bar:SetScale(0.0001)
bar:SetAlpha(0)
E:DisableMover(bar.mover:GetName())
end
local horizontalGrowth, verticalGrowth
if point == "TOPLEFT" or point == "TOPRIGHT" then
verticalGrowth = "DOWN"
else
verticalGrowth = "UP"
end
if point == "BOTTOMLEFT" or point == "TOPLEFT" then
horizontalGrowth = "RIGHT"
else
horizontalGrowth = "LEFT"
end
bar.mouseover = self.db.barPet.mouseover
if bar.mouseover then
bar:SetAlpha(0)
else
bar:SetAlpha(bar.db.alpha)
end
if self.db.barPet.inheritGlobalFade then
bar:SetParent(self.fadeParent)
else
bar:SetParent(E.UIParent)
end
local button, lastButton, lastColumnButton, autoCast, shine
local firstButtonSpacing = (self.db.barPet.backdrop == true and (E.Border + backdropSpacing) or E.Spacing)
for i = 1, NUM_PET_ACTION_SLOTS do
button = _G["PetActionButton"..i]
lastButton = _G["PetActionButton"..i - 1]
autoCast = _G["PetActionButton"..i.."AutoCastable"]
shine = _G["PetActionButton"..i.."Shine"]
lastColumnButton = _G["PetActionButton"..i - buttonsPerRow]
button:SetParent(bar)
button:ClearAllPoints()
button:Size(size)
autoCast:SetOutside(button, autoCastSize, autoCastSize)
shine:Size(size - E.Border*2)
button:SetAttribute("showgrid", 1)
if i == 1 then
local x, y
if point == "BOTTOMLEFT" then
x, y = firstButtonSpacing, firstButtonSpacing
elseif point == "TOPRIGHT" then
x, y = -firstButtonSpacing, -firstButtonSpacing
elseif point == "TOPLEFT" then
x, y = firstButtonSpacing, -firstButtonSpacing
else
x, y = -firstButtonSpacing, firstButtonSpacing
end
button:Point(point, bar, point, x, y)
elseif (i - 1) % buttonsPerRow == 0 then
local x = 0
local y = -buttonSpacing
local buttonPoint, anchorPoint = "TOP", "BOTTOM"
if verticalGrowth == "UP" then
y = buttonSpacing
buttonPoint = "BOTTOM"
anchorPoint = "TOP"
end
button:Point(buttonPoint, lastColumnButton, anchorPoint, x, y)
else
local x = buttonSpacing
local y = 0
local buttonPoint, anchorPoint = "LEFT", "RIGHT"
if horizontalGrowth == "LEFT" then
x = -buttonSpacing
buttonPoint = "RIGHT"
anchorPoint = "LEFT"
end
button:Point(buttonPoint, lastButton, anchorPoint, x, y)
end
if i > numButtons then
button:SetScale(0.0001)
button:SetAlpha(0)
else
button:SetScale(1)
button:SetAlpha(bar.db.alpha)
end
self:StyleButton(button, nil, self.LBFGroup and E.private.actionbar.lbf.enable and true or nil)
end
RegisterStateDriver(bar, "show", visibility)
--Fix issue with mover not updating size when bar is hidden
bar:GetScript("OnSizeChanged")(bar)
if self.LBFGroup and E.private.actionbar.lbf.enable then self.LBFGroup:Skin(E.private.actionbar.lbf.skin) end
end
function AB:UpdatePetBindings()
local color = self.db.fontColor
for i = 1, NUM_PET_ACTION_SLOTS do
if self.db.hotkeytext then
local key = GetBindingKey("BONUSACTIONBUTTON"..i)
_G["PetActionButton"..i.."HotKey"]:Show()
_G["PetActionButton"..i.."HotKey"]:SetText(key)
_G["PetActionButton"..i.."HotKey"]:SetTextColor(color.r, color.g, color.b)
self:FixKeybindText(_G["PetActionButton"..i])
else
_G["PetActionButton"..i.."HotKey"]:Hide()
end
end
end
function AB:CreateBarPet()
bar:CreateBackdrop(self.db.transparentBackdrops and "Transparent")
bar.backdrop:SetAllPoints()
if self.db.bar4.enabled then
bar:Point("RIGHT", ElvUI_Bar4, "LEFT", -4, 0)
else
bar:Point("RIGHT", E.UIParent, "RIGHT", -4, 0)
end
bar:SetAttribute("_onstate-show", [[
if newstate == "hide" then
self:Hide()
else
self:Show()
end
]])
PetActionBarFrame.showgrid = 1
PetActionBar_ShowGrid()
self:HookScript(bar, "OnEnter", "Bar_OnEnter")
self:HookScript(bar, "OnLeave", "Bar_OnLeave")
self:RegisterEvent("SPELLS_CHANGED", "UpdatePet")
self:RegisterEvent("PLAYER_CONTROL_GAINED", "UpdatePet")
self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdatePet")
self:RegisterEvent("PLAYER_CONTROL_LOST", "UpdatePet")
self:RegisterEvent("PET_BAR_UPDATE", "UpdatePet")
self:RegisterEvent("UNIT_PET", "UpdatePet")
self:RegisterEvent("UNIT_FLAGS", "UpdatePet")
self:RegisterEvent("UNIT_AURA", "UpdatePet")
self:RegisterEvent("PLAYER_FARSIGHT_FOCUS_CHANGED", "UpdatePet")
self:RegisterEvent("PET_BAR_UPDATE_COOLDOWN", PetActionBar_UpdateCooldowns)
E:CreateMover(bar, "ElvBar_Pet", L["Pet Bar"], nil, nil, nil,"ALL,ACTIONBARS", nil, "actionbar,barPet")
self:PositionAndSizeBarPet()
self:UpdatePetBindings()
for i = 1, NUM_PET_ACTION_SLOTS do
local button = _G["PetActionButton"..i]
self:HookScript(button, "OnEnter", "Button_OnEnter")
self:HookScript(button, "OnLeave", "Button_OnLeave")
if self.LBFGroup and E.private.actionbar.lbf.enable then
self.LBFGroup:AddButton(button)
end
end
end
+330
View File
@@ -0,0 +1,330 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local AB = E:GetModule("ActionBars")
--Lua functions
local _G = _G
local ceil = math.ceil
local format, gsub, match = string.format, string.gsub, string.match
--WoW API / Variables
local CooldownFrame_SetTimer = CooldownFrame_SetTimer
local CreateFrame = CreateFrame
local GetBindingKey = GetBindingKey
local GetNumShapeshiftForms = GetNumShapeshiftForms
local GetShapeshiftForm = GetShapeshiftForm
local GetShapeshiftFormCooldown = GetShapeshiftFormCooldown
local GetShapeshiftFormInfo = GetShapeshiftFormInfo
local GetSpellInfo = GetSpellInfo
local InCombatLockdown = InCombatLockdown
local RegisterStateDriver = RegisterStateDriver
local NUM_SHAPESHIFT_SLOTS = NUM_SHAPESHIFT_SLOTS
local bar = CreateFrame("Frame", "ElvUI_StanceBar", E.UIParent, "SecureHandlerStateTemplate")
bar:SetFrameStrata("LOW")
function AB:UPDATE_SHAPESHIFT_COOLDOWN()
local numForms = GetNumShapeshiftForms()
local start, duration, enable, cooldown
for i = 1, NUM_SHAPESHIFT_SLOTS do
if i <= numForms then
cooldown = _G["ElvUI_StanceBarButton"..i.."Cooldown"]
start, duration, enable = GetShapeshiftFormCooldown(i)
CooldownFrame_SetTimer(cooldown, start, duration, enable)
end
end
self:StyleShapeShift("UPDATE_SHAPESHIFT_COOLDOWN")
end
function AB:StyleShapeShift()
local numForms = GetNumShapeshiftForms()
local texture, name, isActive, isCastable, _
local buttonName, button, icon, cooldown
local stance = GetShapeshiftForm()
for i = 1, NUM_SHAPESHIFT_SLOTS do
buttonName = "ElvUI_StanceBarButton"..i
button = _G[buttonName]
icon = _G[buttonName.."Icon"]
cooldown = _G[buttonName.."Cooldown"]
if i <= numForms then
texture, name, isActive, isCastable = GetShapeshiftFormInfo(i)
if self.db.stanceBar.style == "darkenInactive" then
if name then
_, _, texture = GetSpellInfo(name)
end
end
if not texture then
texture = "Interface\\Icons\\Spell_Nature_WispSplode"
end
if texture then
cooldown:SetAlpha(1)
else
cooldown:SetAlpha(0)
end
if isActive then
button:GetCheckedTexture():SetTexture(1, 1, 1, 0.5)
if numForms == 1 then
button:SetChecked(true)
else
button:SetChecked(self.db.stanceBar.style ~= "darkenInactive")
end
else
if numForms == 1 or stance == 0 then
button:SetChecked(false)
else
button:SetChecked(self.db.stanceBar.style == "darkenInactive")
button:GetCheckedTexture():SetAlpha(1)
if self.db.stanceBar.style == "darkenInactive" then
button:GetCheckedTexture():SetTexture(0, 0, 0, 0.5)
else
button:GetCheckedTexture():SetTexture(1, 1, 1, 0.5)
end
end
end
icon:SetTexture(texture)
if isCastable then
icon:SetVertexColor(1.0, 1.0, 1.0)
else
icon:SetVertexColor(0.4, 0.4, 0.4)
end
end
end
end
function AB:PositionAndSizeBarShapeShift()
local buttonSpacing = E:Scale(self.db.stanceBar.buttonspacing)
local backdropSpacing = E:Scale((self.db.stanceBar.backdropSpacing or self.db.stanceBar.buttonspacing))
local buttonsPerRow = self.db.stanceBar.buttonsPerRow
local numButtons = self.db.stanceBar.buttons
local size = E:Scale(self.db.stanceBar.buttonsize)
local point = self.db.stanceBar.point
local widthMult = self.db.stanceBar.widthMult
local heightMult = self.db.stanceBar.heightMult
if bar.mover then
bar.mover.positionOverride = point
E:UpdatePositionOverride(bar.mover:GetName())
end
bar.db = self.db.stanceBar
bar.mouseover = self.db.stanceBar.mouseover
if bar.LastButton and numButtons > bar.LastButton then
numButtons = bar.LastButton
end
if bar.LastButton and buttonsPerRow > bar.LastButton then
buttonsPerRow = bar.LastButton
end
if numButtons < buttonsPerRow then
buttonsPerRow = numButtons
end
local numColumns = ceil(numButtons / buttonsPerRow)
if numColumns < 1 then
numColumns = 1
end
if self.db.stanceBar.backdrop then
bar.backdrop:Show()
else
bar.backdrop:Hide()
--Set size multipliers to 1 when backdrop is disabled
widthMult = 1
heightMult = 1
end
local barWidth = (size * (buttonsPerRow * widthMult)) + ((buttonSpacing * (buttonsPerRow - 1)) * widthMult) + (buttonSpacing * (widthMult-1)) + ((self.db.stanceBar.backdrop and (E.Border + backdropSpacing) or E.Spacing)*2)
local barHeight = (size * (numColumns * heightMult)) + ((buttonSpacing * (numColumns - 1)) * heightMult) + (buttonSpacing * (heightMult-1)) + ((self.db.stanceBar.backdrop and (E.Border + backdropSpacing) or E.Spacing)*2)
bar:Width(barWidth)
bar:Height(barHeight)
if self.db.stanceBar.enabled then
bar:SetScale(1)
bar:SetAlpha(bar.db.alpha)
E:EnableMover(bar.mover:GetName())
else
bar:SetScale(0.0001)
bar:SetAlpha(0)
E:DisableMover(bar.mover:GetName())
end
local horizontalGrowth, verticalGrowth
if point == "TOPLEFT" or point == "TOPRIGHT" then
verticalGrowth = "DOWN"
else
verticalGrowth = "UP"
end
if point == "BOTTOMLEFT" or point == "TOPLEFT" then
horizontalGrowth = "RIGHT"
else
horizontalGrowth = "LEFT"
end
if self.db.stanceBar.inheritGlobalFade then
bar:SetParent(self.fadeParent)
else
bar:SetParent(E.UIParent)
end
local button, lastButton, lastColumnButton
local firstButtonSpacing = (self.db.stanceBar.backdrop and (E.Border + backdropSpacing) or E.Spacing)
for i = 1, NUM_SHAPESHIFT_SLOTS do
button = _G["ElvUI_StanceBarButton"..i]
lastButton = _G["ElvUI_StanceBarButton"..i - 1]
lastColumnButton = _G["ElvUI_StanceBarButton"..i - buttonsPerRow]
button:SetParent(bar)
button:ClearAllPoints()
button:Size(size)
if self.db.stanceBar.mouseover then
bar:SetAlpha(0)
else
bar:SetAlpha(bar.db.alpha)
end
if i == 1 then
local x, y
if point == "BOTTOMLEFT" then
x, y = firstButtonSpacing, firstButtonSpacing
elseif point == "TOPRIGHT" then
x, y = -firstButtonSpacing, -firstButtonSpacing
elseif point == "TOPLEFT" then
x, y = firstButtonSpacing, -firstButtonSpacing
else
x, y = -firstButtonSpacing, firstButtonSpacing
end
button:Point(point, bar, point, x, y)
elseif (i - 1) % buttonsPerRow == 0 then
local x = 0
local y = -buttonSpacing
local buttonPoint, anchorPoint = "TOP", "BOTTOM"
if verticalGrowth == "UP" then
y = buttonSpacing
buttonPoint = "BOTTOM"
anchorPoint = "TOP"
end
button:Point(buttonPoint, lastColumnButton, anchorPoint, x, y)
else
local x = buttonSpacing
local y = 0
local buttonPoint, anchorPoint = "LEFT", "RIGHT"
if horizontalGrowth == "LEFT" then
x = -buttonSpacing
buttonPoint = "RIGHT"
anchorPoint = "LEFT"
end
button:Point(buttonPoint, lastButton, anchorPoint, x, y)
end
if i > numButtons then
button:SetScale(0.0001)
button:SetAlpha(0)
else
button:SetScale(1)
button:SetAlpha(bar.db.alpha)
end
self:StyleButton(button, nil, self.LBFGroup and E.private.actionbar.lbf.enable or nil)
end
if self.LBFGroup and E.private.actionbar.lbf.enable then self.LBFGroup:Skin(E.private.actionbar.lbf.skin) end
end
function AB:AdjustMaxStanceButtons(event)
if InCombatLockdown() then
AB.NeedsAdjustMaxStanceButtons = event or true
self:RegisterEvent("PLAYER_REGEN_ENABLED")
return
end
local visibility = self.db.stanceBar.visibility
if visibility and match(visibility, "[\n\r]") then
visibility = gsub(visibility, "[\n\r]", "")
end
for i = 1, #bar.buttons do
bar.buttons[i]:Hide()
end
local numButtons = GetNumShapeshiftForms()
for i = 1, NUM_SHAPESHIFT_SLOTS do
if not bar.buttons[i] then
bar.buttons[i] = CreateFrame("CheckButton", format(bar:GetName().."Button%d", i), bar, "ShapeshiftButtonTemplate")
bar.buttons[i]:SetID(i)
if self.LBFGroup and E.private.actionbar.lbf.enable then
self.LBFGroup:AddButton(bar.buttons[i])
end
self:HookScript(bar.buttons[i], "OnEnter", "Button_OnEnter")
self:HookScript(bar.buttons[i], "OnLeave", "Button_OnLeave")
end
if i <= numButtons then
bar.buttons[i]:Show()
bar.LastButton = i
else
bar.buttons[i]:Hide()
end
end
self:PositionAndSizeBarShapeShift()
-- sometimes after combat lock down `event` may be true because of passing it back with `AB.NeedsAdjustMaxStanceButtons`
if event == "UPDATE_SHAPESHIFT_FORMS" then
self:StyleShapeShift()
end
RegisterStateDriver(bar, "visibility", (numButtons == 0 and "hide") or visibility)
end
function AB:UpdateStanceBindings()
local color = self.db.fontColor
for i = 1, NUM_SHAPESHIFT_SLOTS do
if self.db.hotkeytext then
local key = GetBindingKey("SHAPESHIFTBUTTON"..i)
local hotkey = _G["ElvUI_StanceBarButton"..i.."HotKey"]
hotkey:Show()
hotkey:SetText(key)
hotkey:SetTextColor(color.r, color.g, color.b)
self:FixKeybindText(_G["ElvUI_StanceBarButton"..i])
else
_G["ElvUI_StanceBarButton"..i.."HotKey"]:Hide()
end
end
end
function AB:CreateBarShapeShift()
bar:CreateBackdrop(self.db.transparentBackdrops and "Transparent")
bar.backdrop:SetAllPoints()
bar:Point("TOPLEFT", E.UIParent, "TOPLEFT", 4, -4)
bar.buttons = {}
self:HookScript(bar, "OnEnter", "Bar_OnEnter")
self:HookScript(bar, "OnLeave", "Bar_OnLeave")
self:RegisterEvent("UPDATE_SHAPESHIFT_FORMS", "AdjustMaxStanceButtons")
self:RegisterEvent("UPDATE_SHAPESHIFT_COOLDOWN")
self:RegisterEvent("UPDATE_SHAPESHIFT_USABLE", "StyleShapeShift")
self:RegisterEvent("UPDATE_SHAPESHIFT_FORM", "StyleShapeShift")
self:RegisterEvent("ACTIONBAR_PAGE_CHANGED", "StyleShapeShift")
E:ShapeshiftDelayedUpdate(AB.StyleShapeShift, self)
E:CreateMover(bar, "ShiftAB", L["Stance Bar"], nil, -3, nil, "ALL,ACTIONBARS", nil, "actionbar,stanceBar")
self:AdjustMaxStanceButtons()
self:PositionAndSizeBarShapeShift()
self:StyleShapeShift()
self:UpdateStanceBindings()
end
+347
View File
@@ -0,0 +1,347 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local AB = E:GetModule("ActionBars")
--Lua functions
local _G = _G
local unpack, ipairs, pairs = unpack, ipairs, pairs
local gsub, match = string.gsub, string.match
--WoW API / Variables
local InCombatLockdown = InCombatLockdown
local RegisterStateDriver = RegisterStateDriver
local bar = CreateFrame("Frame", "ElvUI_BarTotem", E.UIParent, "SecureHandlerStateTemplate")
bar:SetFrameStrata("LOW")
local SLOT_BORDER_COLORS = {
["summon"] = {r = 0, g = 0, b = 0},
[EARTH_TOTEM_SLOT] = {r = 0.23, g = 0.45, b = 0.13},
[FIRE_TOTEM_SLOT] = {r = 0.58, g = 0.23, b = 0.10},
[WATER_TOTEM_SLOT] = {r = 0.19, g = 0.48, b = 0.60},
[AIR_TOTEM_SLOT] = {r = 0.42, g = 0.18, b = 0.74}
}
local SLOT_EMPTY_TCOORDS = {
[EARTH_TOTEM_SLOT] = {left = 66/128, right = 96/128, top = 3/256, bottom = 33/256},
[FIRE_TOTEM_SLOT] = {left = 67/128, right = 97/128, top = 100/256, bottom = 130/256},
[WATER_TOTEM_SLOT] = {left = 39/128, right = 69/128, top = 209/256, bottom = 239/256},
[AIR_TOTEM_SLOT] = {left = 66/128, right = 96/128, top = 36/256, bottom = 66/256}
}
local oldMultiCastRecallSpellButton_Update = MultiCastRecallSpellButton_Update
function MultiCastRecallSpellButton_Update(self)
if InCombatLockdown() then AB.NeedRecallButtonUpdate = true; AB:RegisterEvent("PLAYER_REGEN_ENABLED") return end
oldMultiCastRecallSpellButton_Update(self)
end
function AB:MultiCastFlyoutFrameOpenButton_Show(button, type, parent)
local color = type == "page" and SLOT_BORDER_COLORS.summon or SLOT_BORDER_COLORS[parent:GetID()]
button.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
button:ClearAllPoints()
if AB.db.barTotem.flyoutDirection == "UP" then
button:Point("BOTTOM", parent, "TOP")
button.icon:SetRotation(0)
elseif AB.db.barTotem.flyoutDirection == "DOWN" then
button:Point("TOP", parent, "BOTTOM")
button.icon:SetRotation(3.14)
end
end
function AB:MultiCastActionButton_Update(button, _, _, slot)
local color = SLOT_BORDER_COLORS[slot]
if color then
button:SetBackdropBorderColor(color.r, color.g, color.b)
end
if InCombatLockdown() then bar.eventFrame:RegisterEvent("PLAYER_REGEN_ENABLED") return end
button:ClearAllPoints()
button:SetAllPoints(button.slotButton)
end
function AB:StyleTotemSlotButton(button, slot)
local color = SLOT_BORDER_COLORS[slot]
if color then
button:SetBackdropBorderColor(color.r, color.g, color.b)
button.ignoreBorderColors = true
end
end
function AB:SkinSummonButton(button)
local name = button:GetName()
local icon = _G[name.."Icon"]
local highlight = _G[name.."Highlight"]
local normal = _G[name.."NormalTexture"]
button:SetTemplate("Default")
button:StyleButton()
icon:SetTexCoord(unpack(E.TexCoords))
icon:SetDrawLayer("ARTWORK")
icon:SetInside(button)
highlight:SetTexture(nil)
normal:SetTexture(nil)
end
function AB:MultiCastFlyoutFrame_ToggleFlyout(frame, type, parent)
frame.top:SetTexture(nil)
frame.middle:SetTexture(nil)
local color = type == "page" and SLOT_BORDER_COLORS.summon or SLOT_BORDER_COLORS[parent:GetID()]
local numButtons = 0
for i, button in ipairs(frame.buttons) do
if not button.isSkinned then
button:SetTemplate("Default")
button:StyleButton()
AB:HookScript(button, "OnEnter", "TotemOnEnter")
AB:HookScript(button, "OnLeave", "TotemOnLeave")
button.icon:SetDrawLayer("ARTWORK")
button.icon:SetInside(button)
bar.buttons[button] = true
button.isSkinned = true
end
if button:IsShown() then
numButtons = numButtons + 1
button:Size(AB.db.barTotem.buttonsize)
button:ClearAllPoints()
if AB.db.barTotem.flyoutDirection == "UP" then
if i == 1 then
button:Point("BOTTOM", parent, "TOP", 0, AB.db.barTotem.flyoutSpacing)
else
button:Point("BOTTOM", frame.buttons[i - 1], "TOP", 0, AB.db.barTotem.flyoutSpacing)
end
elseif AB.db.barTotem.flyoutDirection == "DOWN" then
if i == 1 then
button:Point("TOP", parent, "BOTTOM", 0, -AB.db.barTotem.flyoutSpacing)
else
button:Point("TOP", frame.buttons[i - 1], "BOTTOM", 0, -AB.db.barTotem.flyoutSpacing)
end
end
button:SetBackdropBorderColor(color.r, color.g, color.b)
button.icon:SetTexCoord(unpack(E.TexCoords))
end
end
if type == "slot" then
local tCoords = SLOT_EMPTY_TCOORDS[parent:GetID()]
frame.buttons[1].icon:SetTexCoord(tCoords.left, tCoords.right, tCoords.top, tCoords.bottom)
end
frame.buttons[1]:SetBackdropBorderColor(color.r, color.g, color.b)
MultiCastFlyoutFrameCloseButton.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
frame:ClearAllPoints()
MultiCastFlyoutFrameCloseButton:ClearAllPoints()
if AB.db.barTotem.flyoutDirection == "UP" then
frame:Point("BOTTOM", parent, "TOP")
MultiCastFlyoutFrameCloseButton:Point("TOP", frame, "TOP")
MultiCastFlyoutFrameCloseButton.icon:SetRotation(3.14)
elseif AB.db.barTotem.flyoutDirection == "DOWN" then
frame:Point("TOP", parent, "BOTTOM")
MultiCastFlyoutFrameCloseButton:Point("BOTTOM", frame, "BOTTOM")
MultiCastFlyoutFrameCloseButton.icon:SetRotation(0)
end
frame:Height(((AB.db.barTotem.buttonsize + AB.db.barTotem.flyoutSpacing) * numButtons) + MultiCastFlyoutFrameCloseButton:GetHeight())
end
function AB:TotemOnEnter()
if bar.mouseover then
E:UIFrameFadeIn(bar, 0.2, bar:GetAlpha(), AB.db.barTotem.alpha)
end
end
function AB:TotemOnLeave()
if bar.mouseover then
E:UIFrameFadeOut(bar, 0.2, bar:GetAlpha(), 0)
end
end
function AB:ShowMultiCastActionBar()
self:PositionAndSizeBarTotem()
end
function AB:PositionAndSizeBarTotem()
if InCombatLockdown() then
AB.NeedsPositionAndSizeBarTotem = true
self:RegisterEvent("PLAYER_REGEN_ENABLED")
return
end
local buttonSpacing = E:Scale(self.db.barTotem.buttonspacing)
local size = E:Scale(self.db.barTotem.buttonsize)
local numActiveSlots = MultiCastActionBarFrame.numActiveSlots
bar:Width((size * (2 + numActiveSlots)) + (buttonSpacing * (2 + numActiveSlots - 1)))
MultiCastActionBarFrame:Width((size * (2 + numActiveSlots)) + (buttonSpacing * (2 + numActiveSlots - 1)))
bar:Height(size + 2)
MultiCastActionBarFrame:Height(size + 2)
bar.db = self.db.barTotem
bar.mouseover = self.db.barTotem.mouseover
if bar.mouseover then
bar:SetAlpha(0)
else
bar:SetAlpha(self.db.barTotem.alpha)
end
local visibility = bar.db.visibility
if visibility and match(visibility, "[\n\r]") then
visibility = gsub(visibility, "[\n\r]","")
end
RegisterStateDriver(bar, "visibility", visibility)
MultiCastSummonSpellButton:ClearAllPoints()
MultiCastSummonSpellButton:Size(size)
MultiCastSummonSpellButton:Point("BOTTOMLEFT", E.Border*2, E.Border*2)
for i = 1, numActiveSlots do
local button = _G["MultiCastSlotButton"..i]
local lastButton = _G["MultiCastSlotButton"..i - 1]
button:ClearAllPoints()
button:Size(size)
if i == 1 then
button:Point("LEFT", MultiCastSummonSpellButton, "RIGHT", buttonSpacing, 0)
else
button:Point("LEFT", lastButton, "RIGHT", buttonSpacing, 0)
end
end
MultiCastRecallSpellButton:Size(size)
MultiCastRecallSpellButton_Update(MultiCastRecallSpellButton)
MultiCastFlyoutFrameCloseButton:Width(size)
MultiCastFlyoutFrameOpenButton:Width(size)
end
function AB:CreateTotemBar()
bar:Point("BOTTOM", E.UIParent, "BOTTOM", 0, 250)
bar.buttons = {}
bar.eventFrame = CreateFrame("Frame")
bar.eventFrame:Hide()
bar.eventFrame:SetScript("OnEvent", function(self)
AB:PositionAndSizeBarTotem()
self:UnregisterEvent("PLAYER_REGEN_ENABLED")
end)
MultiCastActionBarFrame:SetParent(bar)
MultiCastActionBarFrame:ClearAllPoints()
MultiCastActionBarFrame:SetPoint("BOTTOMLEFT", bar, "BOTTOMLEFT", -E.Border, -E.Border)
MultiCastActionBarFrame:SetScript("OnUpdate", nil)
MultiCastActionBarFrame:SetScript("OnShow", nil)
MultiCastActionBarFrame:SetScript("OnHide", nil)
MultiCastActionBarFrame.SetParent = E.noop
MultiCastActionBarFrame.SetPoint = E.noop
self:HookScript(MultiCastActionBarFrame, "OnEnter", "TotemOnEnter")
self:HookScript(MultiCastActionBarFrame, "OnLeave", "TotemOnLeave")
self:HookScript(MultiCastFlyoutFrame, "OnEnter", "TotemOnEnter")
self:HookScript(MultiCastFlyoutFrame, "OnLeave", "TotemOnLeave")
local closeButton = MultiCastFlyoutFrameCloseButton
closeButton:CreateBackdrop("Default", true, true)
closeButton.backdrop:SetPoint("TOPLEFT", 0, -(E.Border + E.Spacing))
closeButton.backdrop:SetPoint("BOTTOMRIGHT", 0, E.Border + E.Spacing)
closeButton.icon = closeButton:CreateTexture(nil, "ARTWORK")
closeButton.icon:Size(16)
closeButton.icon:SetPoint("CENTER")
closeButton.icon:SetTexture(E.Media.Textures.ArrowUp)
closeButton.normalTexture:SetTexture("")
closeButton:StyleButton()
closeButton.hover:SetInside(closeButton.backdrop)
closeButton.pushed:SetInside(closeButton.backdrop)
bar.buttons[closeButton] = true
local openButton = MultiCastFlyoutFrameOpenButton
openButton:CreateBackdrop("Default", true, true)
openButton.backdrop:SetPoint("TOPLEFT", 0, -(E.Border + E.Spacing))
openButton.backdrop:SetPoint("BOTTOMRIGHT", 0, E.Border + E.Spacing)
openButton.icon = openButton:CreateTexture(nil, "ARTWORK")
openButton.icon:Size(16)
openButton.icon:SetPoint("CENTER")
openButton.icon:SetTexture(E.Media.Textures.ArrowUp)
openButton.normalTexture:SetTexture("")
openButton:StyleButton()
openButton.hover:SetInside(openButton.backdrop)
openButton.pushed:SetInside(openButton.backdrop)
bar.buttons[openButton] = true
self:SkinSummonButton(MultiCastSummonSpellButton)
bar.buttons[MultiCastSummonSpellButton] = true
hooksecurefunc(MultiCastRecallSpellButton, "SetPoint", function(self, point, attachTo, anchorPoint, xOffset, yOffset)
if xOffset ~= AB.db.barTotem.buttonspacing then
if InCombatLockdown() then AB.NeedRecallButtonUpdate = true AB:RegisterEvent("PLAYER_REGEN_ENABLED") return end
self:SetPoint(point, attachTo, anchorPoint, AB.db.barTotem.buttonspacing, yOffset)
end
end)
self:SkinSummonButton(MultiCastRecallSpellButton)
bar.buttons[MultiCastRecallSpellButton] = true
for i = 1, 4 do
local button = _G["MultiCastSlotButton"..i]
button:StyleButton()
button:SetTemplate("Default")
button.background:SetTexCoord(unpack(E.TexCoords))
button.background:SetDrawLayer("ARTWORK")
button.background:SetInside(button)
button.overlay:SetTexture(nil)
bar.buttons[button] = true
end
for i = 1, 12 do
local button = _G["MultiCastActionButton"..i]
local icon = _G["MultiCastActionButton"..i.."Icon"]
local normal = _G["MultiCastActionButton"..i.."NormalTexture"]
local cooldown = _G["MultiCastActionButton"..i.."Cooldown"]
button:StyleButton()
icon:SetTexCoord(unpack(E.TexCoords))
icon:SetDrawLayer("ARTWORK")
icon:SetInside()
button.overlay:SetTexture(nil)
normal:SetTexture(nil)
normal:Hide()
normal:SetAlpha(0)
E:RegisterCooldown(cooldown)
bar.buttons[button] = true
end
for button in pairs(bar.buttons) do
button:HookScript("OnEnter", AB.TotemOnEnter)
button:HookScript("OnLeave", AB.TotemOnLeave)
end
self:SecureHook("MultiCastFlyoutFrameOpenButton_Show")
self:SecureHook("MultiCastActionButton_Update")
self:SecureHook("MultiCastSlotButton_Update", "StyleTotemSlotButton")
self:SecureHook("MultiCastFlyoutFrame_ToggleFlyout")
self:SecureHook("ShowMultiCastActionBar")
E:CreateMover(bar, "ElvBar_Totem", TUTORIAL_TITLE47, nil, nil, nil,"ALL,ACTIONBARS", nil, "actionbar,barTotem")
end
+648
View File
@@ -0,0 +1,648 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local A = E:GetModule("Auras")
local LSM = E.Libs.LSM
local LBF = E.Libs.LBF
--Lua functions
local _G = _G
local unpack, pairs, ipairs, next, type = unpack, pairs, ipairs, next, type
local floor, min, max, huge = math.floor, math.min, math.max, math.huge
local wipe, tinsert, tsort, tremove = table.wipe, table.insert, table.sort, table.remove
--WoW API / Variables
local CreateFrame = CreateFrame
local GetTime = GetTime
local UnitAura = UnitAura
local CancelItemTempEnchantment = CancelItemTempEnchantment
local CancelUnitBuff = CancelUnitBuff
local GetInventoryItemQuality = GetInventoryItemQuality
local GetItemQualityColor = GetItemQualityColor
local GetWeaponEnchantInfo = GetWeaponEnchantInfo
local GetInventoryItemTexture = GetInventoryItemTexture
local DebuffTypeColor = DebuffTypeColor
local DIRECTION_TO_POINT = {
DOWN_RIGHT = "TOPLEFT",
DOWN_LEFT = "TOPRIGHT",
UP_RIGHT = "BOTTOMLEFT",
UP_LEFT = "BOTTOMRIGHT",
RIGHT_DOWN = "TOPLEFT",
RIGHT_UP = "BOTTOMLEFT",
LEFT_DOWN = "TOPRIGHT",
LEFT_UP = "BOTTOMRIGHT"
}
local DIRECTION_TO_HORIZONTAL_SPACING_MULTIPLIER = {
DOWN_RIGHT = 1,
DOWN_LEFT = -1,
UP_RIGHT = 1,
UP_LEFT = -1,
RIGHT_DOWN = 1,
RIGHT_UP = 1,
LEFT_DOWN = -1,
LEFT_UP = -1
}
local DIRECTION_TO_VERTICAL_SPACING_MULTIPLIER = {
DOWN_RIGHT = -1,
DOWN_LEFT = -1,
UP_RIGHT = 1,
UP_LEFT = 1,
RIGHT_DOWN = -1,
RIGHT_UP = 1,
LEFT_DOWN = -1,
LEFT_UP = 1
}
local IS_HORIZONTAL_GROWTH = {
RIGHT_DOWN = true,
RIGHT_UP = true,
LEFT_DOWN = true,
LEFT_UP = true
}
local enchantableSlots = {
[1] = 16,
[2] = 17
}
local weaponEnchantTime = {}
A.EnchanData = weaponEnchantTime
function A:UpdateTime(elapsed)
self.timeLeft = self.timeLeft - elapsed
self.statusBar:SetValue(self.timeLeft)
if self.nextUpdate > 0 then
self.nextUpdate = self.nextUpdate - elapsed
return
end
if self.statusBar:IsShown() and A.db.barColorGradient then
self.statusBar:SetStatusBarColor(E.oUF:ColorGradient(self.timeLeft, self.duration or 0, .8, 0, 0, .8, .8, 0, 0, .8, 0))
end
local value, id, nextUpdate, remainder = E:GetTimeInfo(self.timeLeft, self.threshold, self.hhmmThreshold, self.mmssThreshold)
self.nextUpdate = nextUpdate
local style = E.TimeFormats[id]
if style then
local which = (self.textColors and 2 or 1) + (self.showSeconds and 0 or 2)
if self.textColors then
self.text:SetFormattedText(style[which], value, self.textColors[id], remainder)
else
self.text:SetFormattedText(style[which], value, remainder)
end
end
local color = self.timeColors[id]
if color then
self.text:SetTextColor(color.r, color.g, color.b)
end
end
local UpdateTooltip = function(self)
if self.IsWeapon then
GameTooltip:SetInventoryItem("player", enchantableSlots[self:GetID()])
else
GameTooltip:SetUnitAura("player", self:GetID(), self:GetParent().filter)
end
end
local OnEnter = function(self)
if not self:IsVisible() then return end
GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT", -5, -5)
self:UpdateTooltip()
end
local OnLeave = function()
GameTooltip:Hide()
end
local OnClick = function(self)
if self.IsWeapon then
CancelItemTempEnchantment(self:GetID())
else
CancelUnitBuff("player", self:GetID(), self:GetParent().filter)
end
end
function A:CreateIcon(button)
local font = LSM:Fetch("font", self.db.font)
local auraType = button:GetParent().filter
local db = self.db.debuffs
button.auraType = "debuffs" -- used to update cooldown text
if auraType == "HELPFUL" then
db = self.db.buffs
button.auraType = "buffs"
end
button:RegisterForClicks("RightButtonUp")
button.texture = button:CreateTexture(nil, "BORDER")
button.texture:SetInside()
button.texture:SetTexCoord(unpack(E.TexCoords))
button.count = button:CreateFontString(nil, "ARTWORK")
button.count:Point("BOTTOMRIGHT", -1 + self.db.countXOffset, 1 + self.db.countYOffset)
button.count:FontTemplate(font, db.countFontSize, self.db.fontOutline)
button.text = button:CreateFontString(nil, "ARTWORK")
button.text:Point("TOP", button, "BOTTOM", 1 + self.db.timeXOffset, 0 + self.db.timeYOffset)
button.highlight = button:CreateTexture(nil, "HIGHLIGHT")
button.highlight:SetTexture(1, 1, 1, 0.45)
button.highlight:SetInside()
button.statusBar = CreateFrame("StatusBar", "$parentStatusBar", button)
button.statusBar:Hide()
button.statusBar:SetStatusBarTexture(LSM:Fetch("statusbar", self.db.barTexture))
button.statusBar:CreateBackdrop()
E:SetSmoothing(button.statusBar)
E:SetUpAnimGroup(button)
-- support cooldown override
if not button.isRegisteredCooldown then
button.CooldownOverride = "auras"
button.isRegisteredCooldown = true
button.forceEnabled = true
button.showSeconds = true
if not E.RegisteredCooldowns.auras then E.RegisteredCooldowns.auras = {} end
tinsert(E.RegisteredCooldowns.auras, button)
end
button.text:FontTemplate(font, db.durationFontSize, self.db.fontOutline)
A:Update_CooldownOptions(button)
button.UpdateTooltip = UpdateTooltip
button:SetScript("OnEnter", OnEnter)
button:SetScript("OnLeave", OnLeave)
button:SetScript("OnClick", OnClick)
if self.LBFGroup and E.private.auras.lbf.enable then
local ButtonData = {
Icon = button.texture,
Flash = nil,
Cooldown = nil,
AutoCast = nil,
AutoCastable = nil,
HotKey = nil,
Count = false,
Name = nil,
Highlight = button.highlight
}
self.LBFGroup:AddButton(button, ButtonData)
else
button:SetTemplate("Default")
end
end
function A:SetAuraTime(button, expiration, duration)
button.duration = duration
button.statusBar:SetMinMaxValues(0, duration)
button.nextUpdate = 0
if not button.timeLeft then
button.timeLeft = expiration
button:SetScript("OnUpdate", self.UpdateTime)
else
button.timeLeft = expiration
end
end
function A:ClearAuraTime(button, expired)
if not expired then
button.statusBar:SetValue(1)
button.statusBar:SetMinMaxValues(0, 1)
end
button.timeLeft = nil
button.text:SetText("")
button:SetScript("OnUpdate", nil)
end
function A:HasEnchant(index, weapon, expiration)
if not weapon then
if weaponEnchantTime[index] then
weaponEnchantTime[index] = nil
return true
end
return
end
if not weaponEnchantTime[index] or weaponEnchantTime[index] < expiration then
weaponEnchantTime[index] = expiration
return true
end
weaponEnchantTime[index] = expiration
end
function A:Update_CooldownOptions(button)
E:Cooldown_Options(button, self.db.cooldown, button)
end
local buttons = {}
function A:ConfigureAuras(header, auraTable, weaponPosition)
local headerName = header:GetName()
local db = self.db.debuffs
if header.filter == "HELPFUL" then
db = self.db.buffs
end
local xOffset, yOffset, wrapXOffset, wrapYOffset, minWidth, minHeight
local size = db.size
local point = DIRECTION_TO_POINT[db.growthDirection]
local wrapAfter = db.wrapAfter
local maxWraps = db.maxWraps
if IS_HORIZONTAL_GROWTH[db.growthDirection] then
minWidth = ((wrapAfter == 1 and 0 or db.horizontalSpacing) + size) * wrapAfter
minHeight = (db.verticalSpacing + size) * maxWraps
xOffset = DIRECTION_TO_HORIZONTAL_SPACING_MULTIPLIER[db.growthDirection] * (db.horizontalSpacing + size)
yOffset = 0
wrapXOffset = 0
wrapYOffset = DIRECTION_TO_VERTICAL_SPACING_MULTIPLIER[db.growthDirection] * (db.verticalSpacing + size)
else
minWidth = (db.horizontalSpacing + size) * maxWraps
minHeight = ((wrapAfter == 1 and 0 or db.verticalSpacing) + size) * wrapAfter
xOffset = 0
yOffset = DIRECTION_TO_VERTICAL_SPACING_MULTIPLIER[db.growthDirection] * (db.verticalSpacing + size)
wrapXOffset = DIRECTION_TO_HORIZONTAL_SPACING_MULTIPLIER[db.growthDirection] * (db.horizontalSpacing + size)
wrapYOffset = 0
end
wipe(buttons)
local button
for i = 1, #auraTable do
button = _G[headerName.."AuraButton"..i]
if button then
if button:IsShown() then button:Hide() end
else
button = CreateFrame("Button", "$parentAuraButton"..i, header)
self:CreateIcon(button)
end
local buffInfo = auraTable[i]
button:SetID(buffInfo.index)
if buffInfo.duration > 0 and buffInfo.expires then
A:SetAuraTime(button, buffInfo.expires - GetTime(), buffInfo.duration)
else
A:ClearAuraTime(button)
end
if buffInfo.count > 1 then
button.count:SetText(buffInfo.count)
else
button.count:SetText("")
end
if (self.db.barShow and buffInfo.duration > 0) or (self.db.barShow and self.db.barNoDuration and buffInfo.duration == 0) then
button.statusBar:Show()
if not button.timeLeft or not self.db.barColorGradient then
button.statusBar:SetStatusBarColor(self.db.barColor.r, self.db.barColor.g, self.db.barColor.b)
end
else
button.statusBar:Hide()
end
if self.db.showDuration then
button.text:Show()
else
button.text:Hide()
end
if buffInfo.filter == "HARMFUL" then
local color = DebuffTypeColor[buffInfo.dispelType or ""]
button:SetBackdropBorderColor(color.r, color.g, color.b)
button.statusBar.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
else
local cr, cg, cb = unpack(E.media.bordercolor)
button:SetBackdropBorderColor(cr, cg, cb)
button.statusBar.backdrop:SetBackdropBorderColor(cr, cg, cb)
end
button.texture:SetTexture(buffInfo.icon)
buttons[i] = button
end
if weaponPosition then
for weapon = 2, 1, -1 do
button = _G["ElvUIPlayerBuffsTempEnchant"..weapon]
if weaponEnchantTime[weapon] then
if not button then
button = CreateFrame("Button", "$parentTempEnchant"..weapon, header)
button.IsWeapon = true
self:CreateIcon(button)
end
if button then
if button:IsShown() then button:Hide() end
button:SetID(weapon)
local index = enchantableSlots[weapon]
button.texture:SetTexture(GetInventoryItemTexture("player", index))
button:SetBackdropBorderColor(GetItemQualityColor(GetInventoryItemQuality("player", index) or 1))
local duration = 600
local expirationTime = weaponEnchantTime[weapon]
if expirationTime then
expirationTime = expirationTime / 1000
if expirationTime <= 3600 and expirationTime > 1800 then
duration = 3600
elseif expirationTime <= 1800 and expirationTime > 600 then
duration = 1800
end
A:SetAuraTime(button, expirationTime, duration)
else
A:ClearAuraTime(button)
end
if (self.db.barShow and duration > 0) or (self.db.barShow and self.db.barNoDuration and duration == 0) then
button.statusBar:Show()
if not button.timeLeft or not self.db.barColorGradient then
button.statusBar:SetStatusBarColor(self.db.barColor.r, self.db.barColor.g, self.db.barColor.b)
end
else
button.statusBar:Hide()
end
if self.db.showDuration then
button.text:Show()
else
button.text:Hide()
end
if weaponPosition == 0 then
tinsert(buttons, button)
else
tinsert(buttons, weaponPosition, button)
end
end
else
if button and type(button.Hide) == "function" then
button:Hide()
end
end
end
end
local display = #buttons
if wrapAfter and maxWraps then
display = min(display, wrapAfter * maxWraps)
end
local pos, spacing, iconSize = self.db.barPosition, self.db.barSpacing, db.size - (E.Border * 2)
local isOnTop = pos == "TOP" and true or false
local isOnBottom = pos == "BOTTOM" and true or false
local isOnLeft = pos == "LEFT" and true or false
local isOnRight = pos == "RIGHT" and true or false
local left, right, top, bottom = huge, -huge, -huge, huge
for index = 1, display do
button = buttons[index]
local tick, cycle = floor((index - 1) % wrapAfter), floor((index - 1) / wrapAfter)
button:ClearAllPoints()
button:SetPoint(point, header, cycle * wrapXOffset + tick * xOffset, cycle * wrapYOffset + tick * yOffset)
button:SetSize(size, size)
if button.text then
local font = LSM:Fetch("font", self.db.font)
button.text:ClearAllPoints()
button.text:Point("TOP", button, "BOTTOM", 1 + self.db.timeXOffset, 0 + self.db.timeYOffset)
button.text:FontTemplate(font, db.durationFontSize, self.db.fontOutline)
button.count:ClearAllPoints()
button.count:Point("BOTTOMRIGHT", -1 + self.db.countXOffset, 0 + self.db.countYOffset)
button.count:FontTemplate(font, db.countFontSize, self.db.fontOutline)
end
button.statusBar:Width((isOnTop or isOnBottom) and iconSize or (self.db.barWidth + (E.PixelMode and 0 or 2)))
button.statusBar:Height((isOnLeft or isOnRight) and iconSize or (self.db.barHeight + (E.PixelMode and 0 or 2)))
button.statusBar:ClearAllPoints()
button.statusBar:Point(E.InversePoints[pos], button, pos, (isOnTop or isOnBottom) and 0 or ((isOnLeft and -((E.PixelMode and 1 or 3) + spacing)) or ((E.PixelMode and 1 or 3) + spacing)), (isOnLeft or isOnRight) and 0 or ((isOnTop and ((E.PixelMode and 1 or 3) + spacing) or -((E.PixelMode and 1 or 3) + spacing))))
button.statusBar:SetStatusBarTexture(LSM:Fetch("statusbar", self.db.barTexture))
if isOnLeft or isOnRight then
button.statusBar:SetOrientation("VERTICAL")
else
button.statusBar:SetOrientation("HORIZONTAL")
end
button:Show()
left = min(left, button:GetLeft() or huge)
right = max(right, button:GetRight() or -huge)
top = max(top, button:GetTop() or -huge)
bottom = min(bottom, button:GetBottom() or huge)
end
local deadIndex = #(auraTable) + 1
button = _G[headerName.."AuraButton"..deadIndex]
while button do
if button:IsShown() then button:Hide() end
deadIndex = deadIndex + 1
button = _G[headerName.."AuraButton"..deadIndex]
end
if display >= 1 then
header:SetWidth(max(right - left, minWidth))
header:SetHeight(max(top - bottom, minHeight))
else
header:SetWidth(minWidth)
header:SetHeight(minHeight)
end
end
local freshTable
local releaseTable
do
local tableReserve = {}
freshTable = function ()
local t = next(tableReserve) or {}
tableReserve[t] = nil
return t
end
releaseTable = function (t)
tableReserve[t] = wipe(t)
end
end
local function sortFactory(key, separateOwn, reverse)
if separateOwn ~= 0 then
if reverse then
return function(a, b)
if a.filter == b.filter then
local ownA, ownB = a.caster == "player", b.caster == "player"
if ownA ~= ownB then
return ownA == (separateOwn > 0)
end
return a[key] > b[key]
else
return a.filter < b.filter
end
end;
else
return function(a, b)
if a.filter == b.filter then
local ownA, ownB = a.caster == "player", b.caster == "player"
if ownA ~= ownB then
return ownA == (separateOwn > 0)
end
return a[key] < b[key]
else
return a.filter < b.filter
end
end;
end
else
if reverse then
return function(a, b)
if a.filter == b.filter then
return a[key] > b[key]
else
return a.filter < b.filter
end
end;
else
return function(a, b)
if a.filter == b.filter then
return a[key] < b[key]
else
return a.filter < b.filter
end
end;
end
end
end
local sorters = {}
for _, key in ipairs{"index", "name", "expires"} do
local label = string.upper(key)
sorters[label] = {}
for bool in pairs{[true] = true, [false] = false} do
sorters[label][bool] = {}
for sep = -1, 1 do
sorters[label][bool][sep] = sortFactory(key, sep, bool)
end
end
end
sorters.TIME = sorters.EXPIRES
local sortingTable = {}
function A:UpdateHeader(header)
local filter = header.filter
local db = self.db.debuffs
wipe(sortingTable)
local weaponPosition
if filter == "HELPFUL" then
db = self.db.buffs
weaponPosition = 1
end
local i = 1
repeat
local aura, _ = freshTable()
aura.name, _, aura.icon, aura.count, aura.dispelType, aura.duration, aura.expires, aura.caster = UnitAura("player", i, filter)
if aura.name then
aura.filter = filter
aura.index = i
tinsert(sortingTable, aura)
else
releaseTable(aura)
end
i = i + 1
until not aura.name
local sortMethod = (sorters[db.sortMethod] or sorters.INDEX)[db.sortDir == "-"][db.seperateOwn]
tsort(sortingTable, sortMethod)
self:ConfigureAuras(header, sortingTable, weaponPosition)
while sortingTable[1] do
releaseTable(tremove(sortingTable))
end
if self.LBFGroup then
self.LBFGroup:Skin(E.private.auras.lbf.skin)
end
end
function A:CreateAuraHeader(filter)
local name = "ElvUIPlayerDebuffs"
if filter == "HELPFUL" then
name = "ElvUIPlayerBuffs"
end
local header = CreateFrame("Frame", name, UIParent)
header:SetClampedToScreen(true)
header.filter = filter
header:RegisterEvent("UNIT_AURA")
header:SetScript("OnEvent", function(self, _, unit)
if unit ~= "player" then return end
A:UpdateHeader(self)
end)
self:UpdateHeader(header)
return header
end
function A:Initialize()
if E.private.auras.disableBlizzard then
BuffFrame:Kill()
ConsolidatedBuffs:Kill()
TemporaryEnchantFrame:Kill()
end
if not E.private.auras.enable then return end
self.Initialized = true
self.db = E.db.auras
if LBF then
self.LBFGroup = LBF and LBF:Group("ElvUI", "Auras")
end
self.BuffFrame = self:CreateAuraHeader("HELPFUL")
self.BuffFrame:Point("TOPRIGHT", MMHolder, "TOPLEFT", -(6 + E.Border), -E.Border - E.Spacing)
E:CreateMover(self.BuffFrame, "BuffsMover", L["Player Buffs"], nil, nil, nil, nil, nil, "auras,buffs")
self.BuffFrame.nextUpdate = -1
self.BuffFrame:SetScript("OnUpdate", function(bf, elapsed)
if bf.nextUpdate > 0 then
bf.nextUpdate = bf.nextUpdate - elapsed
return
end
bf.nextUpdate = 1
local hasMainHandEnchant, mainHandExpiration, _, hasOffHandEnchant, offHandExpiration = GetWeaponEnchantInfo()
if A:HasEnchant(1, hasMainHandEnchant, mainHandExpiration) or A:HasEnchant(2, hasOffHandEnchant, offHandExpiration) then
A:UpdateHeader(bf)
end
end)
self.DebuffFrame = self:CreateAuraHeader("HARMFUL")
self.DebuffFrame:Point("BOTTOMRIGHT", MMHolder, "BOTTOMLEFT", -(6 + E.Border), E.Border + E.Spacing)
E:CreateMover(self.DebuffFrame, "DebuffsMover", L["Player Debuffs"], nil, nil, nil, nil, nil, "auras,debuffs")
end
local function InitializeCallback()
A:Initialize()
end
E:RegisterModule(A:GetName(), InitializeCallback)
+3
View File
@@ -0,0 +1,3 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="Auras.lua"/>
</Ui>
+181
View File
@@ -0,0 +1,181 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local B = E:GetModule("Bags")
--Lua functions
local _G = _G
local unpack = unpack
local tinsert = table.insert
--WoW API / Variables
local CreateFrame = CreateFrame
local CursorHasItem = CursorHasItem
local PutKeyInKeyRing = PutKeyInKeyRing
local RegisterStateDriver = RegisterStateDriver
local ToggleKeyRing = ToggleKeyRing
local KEYRING = KEYRING
local NUM_BAG_FRAMES = NUM_BAG_FRAMES
local function OnEnter()
if not E.db.bags.bagBar.mouseover then return end
E:UIFrameFadeOut(ElvUIBags, 0.2, ElvUIBags:GetAlpha(), 1)
end
local function OnLeave()
if not E.db.bags.bagBar.mouseover then return end
E:UIFrameFadeOut(ElvUIBags, 0.2, ElvUIBags:GetAlpha(), 0)
end
function B:SkinBag(bag)
local icon = _G[bag:GetName().."IconTexture"]
bag.oldTex = icon:GetTexture()
bag:StripTextures()
bag:SetTemplate(nil, true)
bag:StyleButton(true)
icon:SetTexture(bag.oldTex)
icon:SetInside()
icon:SetTexCoord(unpack(E.TexCoords))
end
function B:SizeAndPositionBagBar()
if not ElvUIBags then return end
local buttonSpacing = E:Scale(E.db.bags.bagBar.spacing)
local backdropSpacing = E:Scale(E.db.bags.bagBar.backdropSpacing)
local bagBarSize = E:Scale(E.db.bags.bagBar.size)
local showBackdrop = E.db.bags.bagBar.showBackdrop
local growthDirection = E.db.bags.bagBar.growthDirection
local sortDirection = E.db.bags.bagBar.sortDirection
local visibility = E.db.bags.bagBar.visibility
if visibility and string.match(visibility, "[\n\r]") then
visibility = string.gsub(visibility, "[\n\r]","")
end
RegisterStateDriver(ElvUIBags, "visibility", visibility)
if E.db.bags.bagBar.mouseover then
ElvUIBags:SetAlpha(0)
else
ElvUIBags:SetAlpha(1)
end
if showBackdrop then
ElvUIBags.backdrop:Show()
else
ElvUIBags.backdrop:Hide()
end
ElvUIKeyRingButton:Size(bagBarSize)
ElvUIKeyRingButton:ClearAllPoints()
local bdpSpacing = (showBackdrop and backdropSpacing + E.Border) or 0
local btnSpacing = (buttonSpacing + E.Border)
for i = 1, #ElvUIBags.buttons do
local button = ElvUIBags.buttons[i]
local prevButton = ElvUIBags.buttons[i-1]
button:SetSize(bagBarSize, bagBarSize)
button:ClearAllPoints()
if growthDirection == "HORIZONTAL" and sortDirection == "ASCENDING" then
if i == 1 then
button:SetPoint("LEFT", ElvUIBags, "LEFT", bdpSpacing, 0)
elseif prevButton then
button:SetPoint("LEFT", prevButton, "RIGHT", btnSpacing, 0)
end
elseif growthDirection == "VERTICAL" and sortDirection == "ASCENDING" then
if i == 1 then
button:SetPoint("TOP", ElvUIBags, "TOP", 0, -bdpSpacing)
elseif prevButton then
button:SetPoint("TOP", prevButton, "BOTTOM", 0, -btnSpacing)
end
elseif growthDirection == "HORIZONTAL" and sortDirection == "DESCENDING" then
if i == 1 then
button:SetPoint("RIGHT", ElvUIBags, "RIGHT", -bdpSpacing, 0)
elseif prevButton then
button:SetPoint("RIGHT", prevButton, "LEFT", -btnSpacing, 0)
end
else
if i == 1 then
button:SetPoint("BOTTOM", ElvUIBags, "BOTTOM", 0, bdpSpacing)
elseif prevButton then
button:SetPoint("BOTTOM", prevButton, "TOP", 0, btnSpacing)
end
end
end
local btnSize = bagBarSize * (NUM_BAG_FRAMES + 2)
local btnSpace = btnSpacing * (NUM_BAG_FRAMES + 1)
local bdpDoubled = bdpSpacing * 2
if growthDirection == 'HORIZONTAL' then
ElvUIBags:SetWidth(btnSize + btnSpace + bdpDoubled)
ElvUIBags:SetHeight(bagBarSize + bdpDoubled)
else
ElvUIBags:SetHeight(btnSize + btnSpace + bdpDoubled)
ElvUIBags:SetWidth(bagBarSize + bdpDoubled)
end
end
function B:LoadBagBar()
if not E.private.bags.bagBar then return end
local ElvUIBags = CreateFrame("Frame", "ElvUIBags", E.UIParent)
ElvUIBags:Point("TOPRIGHT", RightChatPanel, "TOPLEFT", -4, 0)
ElvUIBags.buttons = {}
ElvUIBags:CreateBackdrop(E.db.bags.transparent and "Transparent")
ElvUIBags.backdrop:SetAllPoints()
ElvUIBags:EnableMouse(true)
ElvUIBags:SetScript("OnEnter", OnEnter)
ElvUIBags:SetScript("OnLeave", OnLeave)
MainMenuBarBackpackButton:SetParent(ElvUIBags)
MainMenuBarBackpackButton.SetParent = E.noop
MainMenuBarBackpackButton:ClearAllPoints()
MainMenuBarBackpackButtonCount:FontTemplate(nil, 10)
MainMenuBarBackpackButtonCount:ClearAllPoints()
MainMenuBarBackpackButtonCount:Point("BOTTOMRIGHT", MainMenuBarBackpackButton, "BOTTOMRIGHT", -1, 4)
MainMenuBarBackpackButton:HookScript("OnEnter", OnEnter)
MainMenuBarBackpackButton:HookScript("OnLeave", OnLeave)
tinsert(ElvUIBags.buttons, MainMenuBarBackpackButton)
self:SkinBag(MainMenuBarBackpackButton)
for i = 0, NUM_BAG_FRAMES - 1 do
local b = _G["CharacterBag"..i.."Slot"]
b:SetParent(ElvUIBags)
b.SetParent = E.noop
b:HookScript("OnEnter", OnEnter)
b:HookScript("OnLeave", OnLeave)
self:SkinBag(b)
tinsert(ElvUIBags.buttons, b)
end
local ElvUIKeyRing = CreateFrame("CheckButton", "ElvUIKeyRingButton", UIParent, "ItemButtonTemplate")
ElvUIKeyRing:StripTextures()
ElvUIKeyRing:SetTemplate()
ElvUIKeyRing:StyleButton(true)
ElvUIKeyRing:SetParent(ElvUIBags)
ElvUIKeyRing.SetParent = E.noop
ElvUIKeyRing:RegisterForClicks("anyUp")
_G[ElvUIKeyRing:GetName().."IconTexture"]:SetTexture("Interface\\ContainerFrame\\KeyRing-Bag-Icon")
_G[ElvUIKeyRing:GetName().."IconTexture"]:SetInside()
_G[ElvUIKeyRing:GetName().."IconTexture"]:SetTexCoord(unpack(E.TexCoords))
ElvUIKeyRing:SetScript("OnClick", function() if CursorHasItem() then PutKeyInKeyRing() else ToggleKeyRing() end end)
ElvUIKeyRing:SetScript("OnReceiveDrag", function() if CursorHasItem() then PutKeyInKeyRing() end end)
ElvUIKeyRing:SetScript("OnEnter", function(self) GameTooltip:SetOwner(self, "ANCHOR_LEFT") GameTooltip:SetText(KEYRING, 1, 1, 1) OnEnter() end)
ElvUIKeyRing:SetScript("OnLeave",function() GameTooltip:Hide() OnLeave() end)
tinsert(ElvUIBags.buttons, ElvUIKeyRing)
self:SizeAndPositionBagBar()
E:CreateMover(ElvUIBags, "BagsMover", L["Bags"], nil, nil, nil, nil, nil, "bags,general")
end
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="Bags.lua"/>
<Script file="BagBar.lua"/>
<Script file="Sort.lua"/>
</Ui>
+906
View File
@@ -0,0 +1,906 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local B = E:GetModule("Bags")
local Search = E.Libs.ItemSearch
--Lua functions
local ipairs, pairs, select, unpack, pcall = ipairs, pairs, select, unpack, pcall
local strmatch, gmatch, strfind = strmatch, string.gmatch, strfind
local tinsert, tremove, sort, wipe = tinsert, tremove, sort, wipe
local tonumber, floor, band = tonumber, floor, bit.band
--WoW API / Variables
local ContainerIDToInventoryID = ContainerIDToInventoryID
local GetAuctionItemClasses = GetAuctionItemClasses
local GetAuctionItemSubClasses = GetAuctionItemSubClasses
local GetContainerItemID = GetContainerItemID
local GetContainerItemInfo = GetContainerItemInfo
local GetContainerItemLink = GetContainerItemLink
local GetContainerNumFreeSlots = GetContainerNumFreeSlots
local GetContainerNumSlots = GetContainerNumSlots
local GetCurrentGuildBankTab = GetCurrentGuildBankTab
local GetCursorInfo = GetCursorInfo
local GetGuildBankItemInfo = GetGuildBankItemInfo
local GetGuildBankItemLink = GetGuildBankItemLink
local GetGuildBankTabInfo = GetGuildBankTabInfo
local GetInventoryItemLink = GetInventoryItemLink
local GetItemFamily = GetItemFamily
local GetItemInfo = GetItemInfo
local GetTime = GetTime
local InCombatLockdown = InCombatLockdown
local PickupContainerItem = PickupContainerItem
local PickupGuildBankItem = PickupGuildBankItem
local QueryGuildBankTab = QueryGuildBankTab
local SplitContainerItem = SplitContainerItem
local SplitGuildBankItem = SplitGuildBankItem
local ARMOR, ENCHSLOT_WEAPON = ARMOR, ENCHSLOT_WEAPON
local MAX_MOVE_TIME = 1.25
local guildBags = {51, 52, 53, 54, 55, 56, 57, 58}
local bankBags = {BANK_CONTAINER}
for i = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do
tinsert(bankBags, i)
end
local playerBags = {}
for i = 0, NUM_BAG_SLOTS do
tinsert(playerBags, i)
end
local allBags = {}
for _, i in ipairs(playerBags) do
tinsert(allBags, i)
end
for _, i in ipairs(bankBags) do
tinsert(allBags, i)
end
for _, i in ipairs(guildBags) do
tinsert(allBags, i)
end
local coreGroups = {
guild = guildBags,
bank = bankBags,
bags = playerBags,
all = allBags,
}
local bagCache = {}
local bagIDs = {}
local bagQualities = {}
local bagStacks = {}
local bagMaxStacks = {}
local bagGroups = {}
local initialOrder = {}
local itemTypes, itemSubTypes = {}, {}
local bagSorted, bagLocked = {}, {}
local bagRole
local moves = {}
local targetItems = {}
local sourceUsed = {}
local targetSlots = {}
local specialtyBags = {}
local emptySlots = {}
local moveRetries = 0
local moveTracker = {}
local lastItemID, lockStop, lastDestination, lastMove
local inventorySlots = {
INVTYPE_AMMO = 0,
INVTYPE_HEAD = 1,
INVTYPE_NECK = 2,
INVTYPE_SHOULDER = 3,
INVTYPE_BODY = 4,
INVTYPE_CHEST = 5,
INVTYPE_ROBE = 5,
INVTYPE_WAIST = 6,
INVTYPE_LEGS = 7,
INVTYPE_FEET = 8,
INVTYPE_WRIST = 9,
INVTYPE_HAND = 10,
INVTYPE_FINGER = 11,
INVTYPE_TRINKET = 12,
INVTYPE_CLOAK = 13,
INVTYPE_WEAPON = 14,
INVTYPE_SHIELD = 15,
INVTYPE_2HWEAPON = 16,
INVTYPE_WEAPONMAINHAND = 18,
INVTYPE_WEAPONOFFHAND = 19,
INVTYPE_HOLDABLE = 20,
INVTYPE_RANGED = 21,
INVTYPE_THROWN = 22,
INVTYPE_RANGEDRIGHT = 23,
INVTYPE_RELIC = 24,
INVTYPE_TABARD = 25,
}
local safe = {
[BANK_CONTAINER] = true,
[0] = true
}
local WAIT_TIME = 0.05
do
local t = 0
local frame = CreateFrame("Frame")
frame:SetScript("OnUpdate", function(_, elapsed)
t = t + (elapsed or 0.01)
if t > WAIT_TIME then
t = 0
B:DoMoves()
end
end)
frame:Hide()
B.SortUpdateTimer = frame
end
local function IsGuildBankBag(bagid)
return bagid > 50 and bagid <= 58
end
local function BuildSortOrder()
for i, iType in ipairs({GetAuctionItemClasses()}) do
itemTypes[iType] = i
itemSubTypes[iType] = {}
for ii, isType in ipairs({GetAuctionItemSubClasses(i)}) do
itemSubTypes[iType][isType] = ii
end
end
end
local function UpdateLocation(from, to)
if (bagIDs[from] == bagIDs[to]) and (bagStacks[to] < bagMaxStacks[to]) then
local stackSize = bagMaxStacks[to]
if (bagStacks[to] + bagStacks[from]) > stackSize then
bagStacks[from] = bagStacks[from] - (stackSize - bagStacks[to])
bagStacks[to] = stackSize
else
bagStacks[to] = bagStacks[to] + bagStacks[from]
bagStacks[from] = nil
bagIDs[from] = nil
bagQualities[from] = nil
bagMaxStacks[from] = nil
end
else
bagIDs[from], bagIDs[to] = bagIDs[to], bagIDs[from]
bagQualities[from], bagQualities[to] = bagQualities[to], bagQualities[from]
bagStacks[from], bagStacks[to] = bagStacks[to], bagStacks[from]
bagMaxStacks[from], bagMaxStacks[to] = bagMaxStacks[to], bagMaxStacks[from]
end
end
local function PrimarySort(a, b)
local aName, _, _, aLvl, _, _, _, _, _, _, aPrice = GetItemInfo(bagIDs[a])
local bName, _, _, bLvl, _, _, _, _, _, _, bPrice = GetItemInfo(bagIDs[b])
if aLvl ~= bLvl and aLvl and bLvl then
return aLvl > bLvl
end
if aPrice ~= bPrice and aPrice and bPrice then
return aPrice > bPrice
end
if aName and bName then
return aName < bName
end
end
local function DefaultSort(a, b)
local aID = bagIDs[a]
local bID = bagIDs[b]
if (not aID) or (not bID) then return aID end
local aOrder, bOrder = initialOrder[a], initialOrder[b]
if aID == bID then
local aCount = bagStacks[a]
local bCount = bagStacks[b]
if aCount and bCount and aCount == bCount then
return aOrder < bOrder
elseif aCount and bCount then
return aCount < bCount
end
end
local _, _, _, _, _, aType, aSubType, _, aEquipLoc = GetItemInfo(aID)
local _, _, _, _, _, bType, bSubType, _, bEquipLoc = GetItemInfo(bID)
local aRarity, bRarity = bagQualities[a], bagQualities[b]
if aRarity ~= bRarity and aRarity and bRarity then
return aRarity > bRarity
end
if itemTypes[aType] ~= itemTypes[bType] then
return (itemTypes[aType] or 99) < (itemTypes[bType] or 99)
end
local aItemClassId, aItemSubClassId = itemTypes[aType] or 99, itemSubTypes[aType] and itemSubTypes[aType][aSubType] or 99
local bItemClassId, bItemSubClassId = itemTypes[bType] or 99, itemSubTypes[bType] and itemSubTypes[bType][bSubType] or 99
if aItemClassId ~= bItemClassId then
return aItemClassId < bItemClassId
end
if aItemClassId == ARMOR or aItemClassId == ENCHSLOT_WEAPON then
aEquipLoc = inventorySlots[aEquipLoc] or -1
bEquipLoc = inventorySlots[bEquipLoc] or -1
if aEquipLoc == bEquipLoc then
return PrimarySort(a, b)
end
if aEquipLoc and bEquipLoc then
return aEquipLoc < bEquipLoc
end
end
if (aItemClassId == bItemClassId) and (aItemSubClassId == bItemSubClassId) then
return PrimarySort(a, b)
end
return (aItemSubClassId or 99) < (bItemSubClassId or 99)
end
local function ReverseSort(a, b)
return DefaultSort(b, a)
end
local function UpdateSorted(source, destination)
for i, bs in pairs(bagSorted) do
if bs == source then
bagSorted[i] = destination
elseif bs == destination then
bagSorted[i] = source
end
end
end
local function ShouldMove(source, destination)
if destination == source then return end
if not bagIDs[source] then return end
if bagIDs[source] == bagIDs[destination] and bagStacks[source] == bagStacks[destination] then return end
return true
end
local function IterateForwards(bagList, i)
i = i + 1
local step = 1
for _, bag in ipairs(bagList) do
local slots = B:GetNumSlots(bag, bagRole)
if i > slots + step then
step = step + slots
else
for slot = 1, slots do
if step == i then
return i, bag, slot
end
step = step + 1
end
end
end
bagRole = nil
end
local function IterateBackwards(bagList, i)
i = i + 1
local step = 1
for ii = #bagList, 1, -1 do
local bag = bagList[ii]
local slots = B:GetNumSlots(bag, bagRole)
if i > slots + step then
step = step + slots
else
for slot=slots, 1, -1 do
if step == i then
return i, bag, slot
end
step = step + 1
end
end
end
bagRole = nil
end
function B:IterateBags(bagList, reverse, role)
bagRole = role
return (reverse and IterateBackwards or IterateForwards), bagList, 0
end
function B:GetItemLink(bag, slot)
if IsGuildBankBag(bag) then
return GetGuildBankItemLink(bag - 50, slot)
else
return GetContainerItemLink(bag, slot)
end
end
function B:GetItemID(bag, slot)
if IsGuildBankBag(bag) then
local link = B:GetItemLink(bag, slot)
return link and tonumber(strmatch(link, "item:(%d+)"))
else
return GetContainerItemID(bag, slot)
end
end
function B:GetItemInfo(bag, slot)
if IsGuildBankBag(bag) then
return GetGuildBankItemInfo(bag - 50, slot)
else
return GetContainerItemInfo(bag, slot)
end
end
function B:PickupItem(bag, slot)
if IsGuildBankBag(bag) then
return PickupGuildBankItem(bag - 50, slot)
else
return PickupContainerItem(bag, slot)
end
end
function B:SplitItem(bag, slot, amount)
if IsGuildBankBag(bag) then
return SplitGuildBankItem(bag - 50, slot, amount)
else
return SplitContainerItem(bag, slot, amount)
end
end
function B:GetNumSlots(bag)
if IsGuildBankBag(bag) then
local name, _, canView = GetGuildBankTabInfo(bag - 50)
if name and canView then
return 98
end
else
return GetContainerNumSlots(bag)
end
return 0
end
function B:ConvertLinkToID(link)
if not link then return end
local item = strmatch(link, "item:(%d+)")
if item then return tonumber(item) end
end
local function DefaultCanMove()
return true
end
function B:Encode_BagSlot(bag, slot)
return (bag * 100) + slot
end
function B:Decode_BagSlot(int)
return floor(int / 100), int % 100
end
function B:IsPartial(bag, slot)
local bagSlot = B:Encode_BagSlot(bag, slot)
return ((bagMaxStacks[bagSlot] or 0) - (bagStacks[bagSlot] or 0)) > 0
end
function B:EncodeMove(source, target)
return (source * 10000) + target
end
function B:DecodeMove(move)
local s = floor(move/10000)
local t = move%10000
s = (t > 9000) and (s + 1) or s
t = (t > 9000) and (t - 10000) or t
return s, t
end
function B:AddMove(source, destination)
UpdateLocation(source, destination)
tinsert(moves, 1, B:EncodeMove(source, destination))
end
function B:ScanBags()
for _, bag, slot in B:IterateBags(allBags) do
local bagSlot = B:Encode_BagSlot(bag, slot)
local itemLink = B:GetItemLink(bag, slot)
local itemID = B:ConvertLinkToID(itemLink)
if itemID then
bagMaxStacks[bagSlot] = select(8, GetItemInfo(itemID))
bagIDs[bagSlot] = itemID
bagQualities[bagSlot] = select(3, GetItemInfo(itemLink))
bagStacks[bagSlot] = select(2, B:GetItemInfo(bag, slot))
end
end
end
function B:IsSpecialtyBag(bagID)
if safe[bagID] or IsGuildBankBag(bagID) then return false end
local inventorySlot = ContainerIDToInventoryID(bagID)
if not inventorySlot then return false end
local bag = GetInventoryItemLink("player", inventorySlot)
if not bag then return false end
local family = GetItemFamily(bag)
if family == 0 or family == nil then return false end
return family
end
function B:CanItemGoInBag(bag, slot, targetBag)
if IsGuildBankBag(targetBag) then return true end
local item = bagIDs[B:Encode_BagSlot(bag, slot)]
local itemFamily = GetItemFamily(item)
if itemFamily and itemFamily > 0 then
local equipSlot = select(9, GetItemInfo(item))
if equipSlot == "INVTYPE_QUIVER" then
itemFamily = 1
end
end
local bagFamily = select(2, GetContainerNumFreeSlots(targetBag))
if itemFamily then
return (bagFamily == 0) or band(itemFamily, bagFamily) > 0
else
return false
end
end
function B.Compress(...)
for i = 1, select("#", ...) do
local bags = select(i, ...)
B.Stack(bags, bags, B.IsPartial)
end
end
function B.Stack(sourceBags, targetBags, canMove)
if not canMove then canMove = DefaultCanMove end
for _, bag, slot in B:IterateBags(targetBags, nil, "deposit") do
local bagSlot = B:Encode_BagSlot(bag, slot)
local itemID = bagIDs[bagSlot]
if itemID and (bagStacks[bagSlot] ~= bagMaxStacks[bagSlot]) then
targetItems[itemID] = (targetItems[itemID] or 0) + 1
tinsert(targetSlots, bagSlot)
end
end
for _, bag, slot in B:IterateBags(sourceBags, true, "withdraw") do
local sourceSlot = B:Encode_BagSlot(bag, slot)
local itemID = bagIDs[sourceSlot]
if itemID and targetItems[itemID] and canMove(itemID, bag, slot) then
for i = #targetSlots, 1, -1 do
local targetedSlot = targetSlots[i]
if bagIDs[sourceSlot] and bagIDs[targetedSlot] == itemID and targetedSlot ~= sourceSlot and (bagStacks[targetedSlot] ~= bagMaxStacks[targetedSlot]) and not sourceUsed[targetedSlot] then
B:AddMove(sourceSlot, targetedSlot)
sourceUsed[sourceSlot] = true
if bagStacks[targetedSlot] == bagMaxStacks[targetedSlot] then
targetItems[itemID] = (targetItems[itemID] > 1) and (targetItems[itemID] - 1) or nil
end
if bagStacks[sourceSlot] == 0 then
targetItems[itemID] = (targetItems[itemID] > 1) and (targetItems[itemID] - 1) or nil
break
end
if not targetItems[itemID] then break end
end
end
end
end
wipe(targetItems)
wipe(targetSlots)
wipe(sourceUsed)
end
local blackListedSlots = {}
local blackList = {}
local blackListQueries = {}
function B:BuildBlacklist(...)
for entry in pairs(...) do
local itemName = GetItemInfo(entry)
if itemName then
blackList[itemName] = true
elseif entry ~= "" then
if strfind(entry, "%[") and strfind(entry, "%]") then
--For some reason the entry was not treated as a valid item. Extract the item name.
entry = strmatch(entry, "%[(.*)%]")
end
blackListQueries[#blackListQueries+1] = entry
end
end
end
function B.Sort(bags, sorter, invertDirection)
if not sorter then sorter = invertDirection and ReverseSort or DefaultSort end
if not itemTypes then BuildSortOrder() end
--Wipe tables before we begin
wipe(blackList)
wipe(blackListQueries)
wipe(blackListedSlots)
--Build blacklist of items based on the profile and global list
B:BuildBlacklist(B.db.ignoredItems)
B:BuildBlacklist(E.global.bags.ignoredItems)
for i, bag, slot in B:IterateBags(bags, nil, "both") do
local bagSlot = B:Encode_BagSlot(bag, slot)
local link = B:GetItemLink(bag, slot)
if link then
if blackList[GetItemInfo(link)] then
blackListedSlots[bagSlot] = true
end
if not blackListedSlots[bagSlot] then
for _,itemsearchquery in pairs(blackListQueries) do
local success, result = pcall(Search.Matches, Search, link, itemsearchquery)
if success and result then
blackListedSlots[bagSlot] = result
break
end
end
end
end
if not blackListedSlots[bagSlot] then
initialOrder[bagSlot] = i
tinsert(bagSorted, bagSlot)
end
end
sort(bagSorted, sorter)
local passNeeded = true
while passNeeded do
passNeeded = false
local i = 1
for _, bag, slot in B:IterateBags(bags, nil, "both") do
local destination = B:Encode_BagSlot(bag, slot)
local source = bagSorted[i]
if not blackListedSlots[destination] then
if ShouldMove(source, destination) then
if not (bagLocked[source] or bagLocked[destination]) then
B:AddMove(source, destination)
UpdateSorted(source, destination)
bagLocked[source] = true
bagLocked[destination] = true
else
passNeeded = true
end
end
i = i + 1
end
end
wipe(bagLocked)
end
wipe(bagSorted)
wipe(initialOrder)
end
function B.FillBags(from, to)
B.Stack(from, to)
for _, bag in ipairs(to) do
if B:IsSpecialtyBag(bag) then
tinsert(specialtyBags, bag)
end
end
if #specialtyBags > 0 then
B:Fill(from, specialtyBags)
end
B.Fill(from, to)
wipe(specialtyBags)
end
function B.Fill(sourceBags, targetBags, reverse, canMove)
if not canMove then canMove = DefaultCanMove end
--Wipe tables before we begin
wipe(blackList)
wipe(blackListedSlots)
--Build blacklist of items based on the profile and global list
B:BuildBlacklist(B.db.ignoredItems)
B:BuildBlacklist(E.global.bags.ignoredItems)
for _, bag, slot in B:IterateBags(targetBags, reverse, "deposit") do
local bagSlot = B:Encode_BagSlot(bag, slot)
if not bagIDs[bagSlot] then
tinsert(emptySlots, bagSlot)
end
end
for _, bag, slot in B:IterateBags(sourceBags, not reverse, "withdraw") do
if #emptySlots == 0 then break end
local bagSlot = B:Encode_BagSlot(bag, slot)
local targetBag = B:Decode_BagSlot(emptySlots[1])
local link = B:GetItemLink(bag, slot)
if link and blackList[GetItemInfo(link)] then
blackListedSlots[bagSlot] = true
end
if bagIDs[bagSlot] and B:CanItemGoInBag(bag, slot, targetBag) and canMove(bagIDs[bagSlot], bag, slot) and not blackListedSlots[bagSlot] then
B:AddMove(bagSlot, tremove(emptySlots, 1))
end
end
wipe(emptySlots)
end
function B.SortBags(...)
for i = 1, select("#", ...) do
local bags = select(i, ...)
for _, slotNum in ipairs(bags) do
local bagType = B:IsSpecialtyBag(slotNum)
if bagType == false then bagType = "Normal" end
if not bagCache[bagType] then bagCache[bagType] = {} end
tinsert(bagCache[bagType], slotNum)
end
for bagType, sortedBags in pairs(bagCache) do
if bagType ~= "Normal" then
B.Stack(sortedBags, sortedBags, B.IsPartial)
B.Stack(bagCache.Normal, sortedBags)
B.Fill(bagCache.Normal, sortedBags, B.db.sortInverted)
B.Sort(sortedBags, nil, B.db.sortInverted)
wipe(sortedBags)
end
end
if bagCache.Normal then
B.Stack(bagCache.Normal, bagCache.Normal, B.IsPartial)
B.Sort(bagCache.Normal, nil, B.db.sortInverted)
wipe(bagCache.Normal)
end
wipe(bagCache)
wipe(bagGroups)
end
end
function B:StartStacking()
wipe(bagMaxStacks)
wipe(bagStacks)
wipe(bagIDs)
wipe(bagQualities)
wipe(moveTracker)
if #moves > 0 then
B.SortUpdateTimer:Show()
else
B:StopStacking()
end
end
function B:RegisterUpdateDelayed()
local shouldUpdateFade
for _, bagFrame in pairs(B.BagFrames) do
if bagFrame.registerUpdate then
B:UpdateAllSlots(bagFrame)
bagFrame:RegisterEvent("BAG_UPDATE")
bagFrame:RegisterEvent("BAG_UPDATE_COOLDOWN")
for _, event in pairs(bagFrame.events) do
bagFrame:RegisterEvent(event)
end
bagFrame.registerUpdate = nil
shouldUpdateFade = true -- we should refresh the bag search after sorting
end
end
if shouldUpdateFade then
B:RefreshSearch() -- this will clear the bag lock look during a sort
end
end
function B:StopStacking(message, noUpdate)
wipe(moves)
wipe(moveTracker)
moveRetries, lastItemID, lockStop, lastDestination, lastMove = 0, nil, nil, nil, nil
B.SortUpdateTimer:Hide()
if not noUpdate then
--Add a delayed update call, as BAG_UPDATE fires slightly delayed
-- and we don't want the last few unneeded updates to be catched
E:Delay(0.6, B.RegisterUpdateDelayed)
end
if message then
E:Print(message)
end
end
function B:DoMove(move)
if GetCursorInfo() == "item" then
return false, "cursorhasitem"
end
local source, target = B:DecodeMove(move)
local sourceBag, sourceSlot = B:Decode_BagSlot(source)
local targetBag, targetSlot = B:Decode_BagSlot(target)
local _, sourceCount, sourceLocked = B:GetItemInfo(sourceBag, sourceSlot)
local _, targetCount, targetLocked = B:GetItemInfo(targetBag, targetSlot)
if sourceLocked or targetLocked then
return false, "source/target_locked"
end
local sourceItemID = B:GetItemID(sourceBag, sourceSlot)
local targetItemID = B:GetItemID(targetBag, targetSlot)
if not sourceItemID then
if moveTracker[source] then
return false, "move incomplete"
else
return B:StopStacking(L["Confused.. Try Again!"])
end
end
local stackSize = select(8, GetItemInfo(sourceItemID))
if (sourceItemID == targetItemID) and (targetCount ~= stackSize) and ((targetCount + sourceCount) > stackSize) then
B:SplitItem(sourceBag, sourceSlot, stackSize - targetCount)
else
B:PickupItem(sourceBag, sourceSlot)
end
if GetCursorInfo() == "item" then
B:PickupItem(targetBag, targetSlot)
end
local sourceGuild = IsGuildBankBag(sourceBag)
local targetGuild = IsGuildBankBag(targetBag)
if sourceGuild then
QueryGuildBankTab(sourceBag - 50)
end
if targetGuild then
QueryGuildBankTab(targetBag - 50)
end
return true, sourceItemID, source, targetItemID, target, sourceGuild or targetGuild
end
function B:DoMoves()
if InCombatLockdown() then
return B:StopStacking(L["Confused.. Try Again!"])
end
local cursorType, cursorItemID = GetCursorInfo()
if cursorType == "item" and cursorItemID then
if lastItemID ~= cursorItemID then
return B:StopStacking(L["Confused.. Try Again!"])
end
if moveRetries < 100 then
local targetBag, targetSlot = B:Decode_BagSlot(lastDestination)
local _, _, targetLocked = B:GetItemInfo(targetBag, targetSlot)
if not targetLocked then
B:PickupItem(targetBag, targetSlot)
WAIT_TIME = 0.1
lockStop = GetTime()
moveRetries = moveRetries + 1
return
end
end
end
if lockStop then
for slot, itemID in pairs(moveTracker) do
local actualItemID = B:GetItemID(B:Decode_BagSlot(slot))
if actualItemID ~= itemID then
WAIT_TIME = 0.1
if (GetTime() - lockStop) > MAX_MOVE_TIME then
if lastMove and moveRetries < 100 then
local success, moveID, moveSource, targetID, moveTarget, wasGuild = B:DoMove(lastMove)
WAIT_TIME = wasGuild and 0.5 or 0.1
if not success then
lockStop = GetTime()
moveRetries = moveRetries + 1
return
end
moveTracker[moveSource] = targetID
moveTracker[moveTarget] = moveID
lastDestination = moveTarget
-- lastMove = moves[i] --Where does "i" come from???
lastItemID = moveID
-- tremove(moves, i) --Where does "i" come from???
return
end
B:StopStacking()
return
end
return --give processing time to happen
end
moveTracker[slot] = nil
end
end
lastItemID, lockStop, lastDestination, lastMove = nil, nil, nil, nil
wipe(moveTracker)
local success, moveID, targetID, moveSource, moveTarget, wasGuild
if #moves > 0 then
for i = #moves, 1, -1 do
success, moveID, moveSource, targetID, moveTarget, wasGuild = B:DoMove(moves[i])
if not success then
WAIT_TIME = wasGuild and 0.3 or 0.1
lockStop = GetTime()
return
end
moveTracker[moveSource] = targetID
moveTracker[moveTarget] = moveID
lastDestination = moveTarget
lastMove = moves[i]
lastItemID = moveID
tremove(moves, i)
if moves[i - 1] then
WAIT_TIME = wasGuild and 0.3 or 0
return
end
end
end
B:StopStacking()
end
function B:GetGroup(id)
if strmatch(id, "^[-%d,]+$") then
local bags = {}
for b in gmatch(id, "-?%d+") do
tinsert(bags, tonumber(b))
end
return bags
end
return coreGroups[id]
end
function B:CommandDecorator(func, groupsDefaults)
return function(groups)
if B.SortUpdateTimer:IsShown() then
B:StopStacking(L["Already Running.. Bailing Out!"], true)
return
end
wipe(bagGroups)
if not groups or #groups == 0 then
groups = groupsDefaults
end
for bags in gmatch((groups or ""), "%S+") do
if bags == "guild" then
bags = B:GetGroup(bags)
if bags then
tinsert(bagGroups, {bags[GetCurrentGuildBankTab()]})
end
else
bags = B:GetGroup(bags)
if bags then
tinsert(bagGroups, bags)
end
end
end
B:ScanBags()
if func(unpack(bagGroups)) == false then
return
end
wipe(bagGroups)
B:StartStacking()
end
end
+138
View File
@@ -0,0 +1,138 @@
local E, L = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local B = E:GetModule("Blizzard")
local Misc = E:GetModule("Misc")
--Lua functions
local _G = _G
local pairs = pairs
--WoW API / Variables
local NUM_GROUP_LOOT_FRAMES = NUM_GROUP_LOOT_FRAMES
local POSITION, ANCHOR_POINT, YOFFSET = "TOP", "BOTTOM", -10
function E:PostAlertMove()
local _, y = AlertFrameMover:GetCenter()
local screenHeight = E.UIParent:GetTop()
if y > (screenHeight / 2) then
POSITION = "TOP"
ANCHOR_POINT = "BOTTOM"
YOFFSET = -10
AlertFrameMover:SetText(AlertFrameMover.textString.." [Grow Down]")
else
POSITION = "BOTTOM"
ANCHOR_POINT = "TOP"
YOFFSET = 10
AlertFrameMover:SetText(AlertFrameMover.textString.." [Grow Up]")
end
if E.private.general.lootRoll then
local lastframe, lastShownFrame
for i, frame in pairs(Misc.RollBars) do
frame:ClearAllPoints()
if i ~= 1 then
if POSITION == "TOP" then
frame:Point("TOP", lastframe, "BOTTOM", 0, -4)
else
frame:Point("BOTTOM", lastframe, "TOP", 0, 4)
end
else
if POSITION == "TOP" then
frame:Point("TOP", AlertFrameHolder, "BOTTOM", 0, -4)
else
frame:Point("BOTTOM", AlertFrameHolder, "TOP", 0, 4)
end
end
lastframe = frame
if frame:IsShown() then
lastShownFrame = frame
end
end
AlertFrame:ClearAllPoints()
if lastShownFrame then
AlertFrame:SetAllPoints(lastShownFrame)
else
AlertFrame:SetAllPoints(AlertFrameHolder)
end
elseif E.private.skins.blizzard.enable and E.private.skins.blizzard.lootRoll then
local lastframe, lastShownFrame
for i = 1, NUM_GROUP_LOOT_FRAMES do
local frame = _G["GroupLootFrame"..i]
if frame then
frame:ClearAllPoints()
if i ~= 1 then
if POSITION == "TOP" then
frame:Point("TOP", lastframe, "BOTTOM", 0, -4)
else
frame:Point("BOTTOM", lastframe, "TOP", 0, 4)
end
else
if POSITION == "TOP" then
frame:Point("TOP", AlertFrameHolder, "BOTTOM", 0, -4)
else
frame:Point("BOTTOM", AlertFrameHolder, "TOP", 0, 4)
end
end
lastframe = frame
if frame:IsShown() then
lastShownFrame = frame
end
end
end
AlertFrame:ClearAllPoints()
if lastShownFrame then
AlertFrame:SetAllPoints(lastShownFrame)
else
AlertFrame:SetAllPoints(AlertFrameHolder)
end
else
AlertFrame:ClearAllPoints()
AlertFrame:SetAllPoints(AlertFrameHolder)
end
end
function B:AchievementAlertFrame_FixAnchors()
local alertAnchor
for i = 1, MAX_ACHIEVEMENT_ALERTS do
local frame = _G["AchievementAlertFrame"..i]
if frame then
frame:ClearAllPoints()
if alertAnchor and alertAnchor:IsShown() then
frame:Point(POSITION, alertAnchor, ANCHOR_POINT, 0, YOFFSET)
else
frame:Point(POSITION, AlertFrame, ANCHOR_POINT)
end
alertAnchor = frame
end
end
end
function B:DungeonCompletionAlertFrame_FixAnchors()
for i = MAX_ACHIEVEMENT_ALERTS, 1, -1 do
local frame = _G["AchievementAlertFrame"..i]
if frame and frame:IsShown() then
DungeonCompletionAlertFrame1:ClearAllPoints()
DungeonCompletionAlertFrame1:Point(POSITION, frame, ANCHOR_POINT, 0, YOFFSET)
return
end
DungeonCompletionAlertFrame1:ClearAllPoints()
DungeonCompletionAlertFrame1:Point(POSITION, AlertFrame, ANCHOR_POINT)
end
end
function B:AlertMovers()
local AlertFrameHolder = CreateFrame("Frame", "AlertFrameHolder", E.UIParent)
AlertFrameHolder:Size(250, 20)
AlertFrameHolder:Point("TOP", E.UIParent, "TOP", 0, -18)
self:SecureHook("AlertFrame_FixAnchors", E.PostAlertMove)
self:SecureHook("AchievementAlertFrame_FixAnchors")
self:SecureHook("DungeonCompletionAlertFrame_FixAnchors")
E:CreateMover(AlertFrameHolder, "AlertFrameMover", L["Loot / Alert Frames"], nil, nil, E.PostAlertMove, nil, nil, "general,blizzUIImprovements")
end
+109
View File
@@ -0,0 +1,109 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local B = E:GetModule("Blizzard")
--Lua functions
--WoW API / Variables
local ChatEdit_ChooseBoxForSend = ChatEdit_ChooseBoxForSend
local GetTradeSkillListLink = GetTradeSkillListLink
local Minimap_SetPing = Minimap_SetPing
local UnitIsUnit = UnitIsUnit
local MINIMAPPING_FADE_TIMER = MINIMAPPING_FADE_TIMER
function B:ADDON_LOADED(_, addon)
if addon == "Blizzard_TradeSkillUI" then
TradeSkillLinkButton:SetScript("OnClick", function()
local ChatFrameEditBox = ChatEdit_ChooseBoxForSend()
if not ChatFrameEditBox:IsShown() then
ChatEdit_ActivateChat(ChatFrameEditBox)
end
ChatFrameEditBox:Insert(GetTradeSkillListLink())
end)
self:UnregisterEvent("ADDON_LOADED")
end
end
function B:Initialize()
self.Initialized = true
self:AlertMovers()
self:EnhanceColorPicker()
self:KillBlizzard()
self:PositionCaptureBar()
self:PositionDurabilityFrame()
self:PositionGMFrames()
self:PositionVehicleFrame()
self:MoveWatchFrame()
self:RegisterEvent("ADDON_LOADED")
self:RegisterEvent("ZONE_CHANGED_NEW_AREA", SetMapToCurrentZone)
KBArticle_BeginLoading = E.noop
KBSetup_BeginLoading = E.noop
KnowledgeBaseFrame_OnEvent(nil, "KNOWLEDGE_BASE_SETUP_LOAD_FAILURE")
if GetLocale() == "deDE" then
DAY_ONELETTER_ABBR = "%d d"
MINUTE_ONELETTER_ABBR = "%d m"
end
CreateFrame("Frame"):SetScript("OnUpdate", function()
if LFRBrowseFrame.timeToClear then
LFRBrowseFrame.timeToClear = nil
end
end)
MinimapPing:HookScript("OnUpdate", function(self)
if self.fadeOut or self.timer > MINIMAPPING_FADE_TIMER then
Minimap_SetPing(Minimap:GetPingPosition())
end
end)
QuestLogFrame:HookScript("OnShow", function()
local questFrame = QuestLogFrame:GetFrameLevel()
local controlPanel = QuestLogControlPanel:GetFrameLevel()
local scrollFrame = QuestLogDetailScrollFrame:GetFrameLevel()
if questFrame >= controlPanel then
QuestLogControlPanel:SetFrameLevel(questFrame + 1)
end
if questFrame >= scrollFrame then
QuestLogDetailScrollFrame:SetFrameLevel(questFrame + 1)
end
end)
ReadyCheckFrame:HookScript("OnShow", function(self)
if UnitIsUnit("player", self.initiator) then
self:Hide()
end
end)
-- WORLDMAP_POI_FRAMELEVEL = 300
-- WorldMapFrame:SetToplevel(true)
do
local originalFunc = LFDQueueFrameRandomCooldownFrame_OnEvent
local originalScript = LFDQueueFrameCooldownFrame:GetScript("OnEvent")
LFDQueueFrameRandomCooldownFrame_OnEvent = function(self, event, unit, ...)
if event == "UNIT_AURA" and not unit then return end
originalFunc(self, event, unit, ...)
end
if originalFunc == originalScript then
LFDQueueFrameCooldownFrame:SetScript("OnEvent", LFDQueueFrameRandomCooldownFrame_OnEvent)
else
LFDQueueFrameCooldownFrame:SetScript("OnEvent", function(self, event, unit, ...)
if event == "UNIT_AURA" and not unit then return end
originalScript(self, event, unit, ...)
end)
end
end
end
local function InitializeCallback()
B:Initialize()
end
E:RegisterModule(B:GetName(), InitializeCallback)
+63
View File
@@ -0,0 +1,63 @@
local E, L = unpack(select(2, ...)); --Import: Engine, Locales
local B = E:GetModule("Blizzard")
--Lua functions
local _G = _G
--WoW API / Variables
local numAlwaysUpFrames = 0
local pvpHolder = CreateFrame("Frame", "ElvUI_PvPHolder", E.UIParent)
local function styleAlwaysUpFrame(id)
local frame = _G["AlwaysUpFrame"..id]
local text = _G["AlwaysUpFrame"..id.."Text"]
local icon = _G["AlwaysUpFrame"..id.."Icon"]
local dynamic = _G["AlwaysUpFrame"..id.."DynamicIconButton"]
text:ClearAllPoints()
text:Point("CENTER", frame, "CENTER", 0, 0)
icon:ClearAllPoints()
icon:Point("CENTER", text, "LEFT", -10, -9)
dynamic:ClearAllPoints()
dynamic:Point("LEFT", text, "RIGHT", 5, 0)
if id == 1 then
frame:ClearAllPoints()
frame:Point("CENTER", pvpHolder, "CENTER", 0, 5)
frame.SetPoint = E.noop
end
end
local function repositionCaptureBar(id)
local bar = _G["WorldStateCaptureBar"..id]
bar:ClearAllPoints()
bar:Point("TOP", pvpHolder, "BOTTOM", 0, -75)
bar.SetPoint = E.noop
end
function B:WorldStateAlwaysUpFrame_Update()
if numAlwaysUpFrames < NUM_ALWAYS_UP_UI_FRAMES then
for id = numAlwaysUpFrames + 1, NUM_ALWAYS_UP_UI_FRAMES do
styleAlwaysUpFrame(id)
numAlwaysUpFrames = id
end
end
end
function B:PositionCaptureBar()
pvpHolder:Size(30, 70)
pvpHolder:Point("TOP", E.UIParent, "TOP", 0, -4)
hooksecurefunc("WorldStateAlwaysUpFrame_Update", B.WorldStateAlwaysUpFrame_Update)
hooksecurefunc(ExtendedUI["CAPTUREPOINT"], "create", repositionCaptureBar)
if NUM_EXTENDED_UI_FRAMES > 0 then
for id = 1, NUM_EXTENDED_UI_FRAMES do
repositionCaptureBar(id)
end
end
E:CreateMover(pvpHolder, "PvPMover", L["PvP"], nil, nil, nil, "ALL")
end
+388
View File
@@ -0,0 +1,388 @@
--[[
Credit to Jaslm, most of this code is his from the addon ColorPickerPlus
]]
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local B = E:GetModule("Blizzard")
local S = E:GetModule("Skins")
--Lua functions
local strlen, strjoin, gsub = strlen, strjoin, gsub
local tonumber, floor, strsub, wipe = tonumber, floor, strsub, wipe
--WoW API / Variables
local CreateFrame = CreateFrame
local IsAddOnLoaded = IsAddOnLoaded
local CALENDAR_COPY_EVENT, CALENDAR_PASTE_EVENT = CALENDAR_COPY_EVENT, CALENDAR_PASTE_EVENT
local CLASS, DEFAULT = CLASS, DEFAULT
local colorBuffer = {}
local function alphaValue(num)
return num and floor(((1 - num) * 100) + .05) or 0
end
local function UpdateAlphaText(alpha)
if not alpha then alpha = alphaValue(OpacitySliderFrame:GetValue()) end
ColorPPBoxA:SetText(alpha)
end
local function UpdateAlpha(tbox)
local num = tbox:GetNumber()
if num > 100 then
tbox:SetText(100)
num = 100
end
OpacitySliderFrame:SetValue(1 - (num / 100))
end
local function expandFromThree(r, g, b)
return strjoin("",r,r,g,g,b,b)
end
local function extendToSix(str)
for _=1, 6-strlen(str) do str=str..0 end
return str
end
local function GetHexColor(box)
local rgb, rgbSize = box:GetText(), box:GetNumLetters()
if rgbSize == 3 then
rgb = gsub(rgb, "(%x)(%x)(%x)$", expandFromThree)
elseif rgbSize < 6 then
rgb = gsub(rgb, "(.+)$", extendToSix)
end
local r, g, b = tonumber(strsub(rgb,0,2),16) or 0, tonumber(strsub(rgb,3,4),16) or 0, tonumber(strsub(rgb,5,6),16) or 0
return r/255, g/255, b/255
end
local function UpdateColorTexts(r, g, b, box)
if not (r and g and b) then
r, g, b = ColorPickerFrame:GetColorRGB()
if box then
if box == ColorPPBoxH then
r, g, b = GetHexColor(box)
else
local num = box:GetNumber()
if num > 255 then num = 255 end
local c = num/255
if box == ColorPPBoxR then
r = c
elseif box == ColorPPBoxG then
g = c
elseif box == ColorPPBoxB then
b = c
end
end
end
end
-- we want those /255 values
r, g, b = r*255, g*255, b*255
ColorPPBoxH:SetText(string.format("%.2x%.2x%.2x", r, g, b))
ColorPPBoxR:SetText(r)
ColorPPBoxG:SetText(g)
ColorPPBoxB:SetText(b)
end
local function UpdateColor(box)
if box:GetID() == 4 and box:GetNumLetters() ~= 6 then return else UpdateColorTexts(nil, nil, nil, box) end
local r, g, b = GetHexColor(ColorPPBoxH)
ColorPickerFrame:SetColorRGB(r, g, b)
ColorSwatch:SetTexture(r, g, b)
end
local function ColorPPBoxA_SetFocus()
ColorPPBoxA:SetFocus()
end
local function ColorPPBoxR_SetFocus()
ColorPPBoxR:SetFocus()
end
local delayWait, delayFunc = 0.15
local function delayCall()
if delayFunc then
delayFunc()
delayFunc = nil
end
end
local function onColorSelect(frame, r, g, b)
if frame.noColorCallback then return end
ColorSwatch:SetTexture(r, g, b)
UpdateColorTexts(r, g, b)
if not frame:IsVisible() then
delayCall()
elseif not delayFunc then
delayFunc = ColorPickerFrame.func
E:Delay(delayWait, delayCall)
end
end
local function onValueChanged(frame, value)
local alpha = alphaValue(value)
if frame.lastAlpha ~= alpha then
frame.lastAlpha = alpha
UpdateAlphaText(alpha)
if not ColorPickerFrame:IsVisible() then
delayCall()
else
local opacityFunc = ColorPickerFrame.opacityFunc
if delayFunc and (delayFunc ~= opacityFunc) then
delayFunc = opacityFunc
elseif not delayFunc then
delayFunc = opacityFunc
E:Delay(delayWait, delayCall)
end
end
end
end
function B:EnhanceColorPicker()
if IsAddOnLoaded("ColorPickerPlus") then return end
--Skin the default frame, move default buttons into place
ColorPickerFrame:SetClampedToScreen(true)
ColorPickerFrame:SetTemplate("Transparent")
ColorPickerFrameHeader:SetTexture()
ColorPickerFrameHeader:ClearAllPoints()
ColorPickerFrameHeader:Point("TOP", ColorPickerFrame, 0, 0)
ColorPickerCancelButton:ClearAllPoints()
ColorPickerOkayButton:ClearAllPoints()
ColorPickerCancelButton:Point("BOTTOMRIGHT", ColorPickerFrame, "BOTTOMRIGHT", -6, 6)
ColorPickerCancelButton:Point("BOTTOMLEFT", ColorPickerFrame, "BOTTOM", 0, 6)
ColorPickerOkayButton:Point("BOTTOMLEFT", ColorPickerFrame,"BOTTOMLEFT", 6,6)
ColorPickerOkayButton:Point("RIGHT", ColorPickerCancelButton,"LEFT", -4,0)
S:HandleSliderFrame(OpacitySliderFrame)
S:HandleButton(ColorPickerOkayButton)
S:HandleButton(ColorPickerCancelButton)
ColorPickerFrame:HookScript("OnShow", function(frame)
-- get color that will be replaced
local r, g, b = frame:GetColorRGB()
ColorPPOldColorSwatch:SetTexture(r,g,b)
-- show/hide the alpha box
if frame.hasOpacity then
ColorPPBoxA:Show()
ColorPPBoxLabelA:Show()
ColorPPBoxH:SetScript("OnTabPressed", ColorPPBoxA_SetFocus)
UpdateAlphaText()
UpdateColorTexts()
frame:Width(405)
else
ColorPPBoxA:Hide()
ColorPPBoxLabelA:Hide()
ColorPPBoxH:SetScript("OnTabPressed", ColorPPBoxR_SetFocus)
UpdateColorTexts()
frame:Width(345)
end
-- Memory Fix, Colorpicker will call the self.func() 100x per second, causing fps/memory issues,
-- We overwrite these two scripts and set a limit on how often we allow a call their update functions
OpacitySliderFrame:SetScript("OnValueChanged", onValueChanged)
frame:SetScript("OnColorSelect", onColorSelect)
end)
-- make the Color Picker dialog a bit taller, to make room for edit boxes
ColorPickerFrame:Height(ColorPickerFrame:GetHeight() + 40)
-- move the Color Swatch
ColorSwatch:ClearAllPoints()
ColorSwatch:Point("TOPLEFT", ColorPickerFrame, "TOPLEFT", 215, -45)
-- add Color Swatch for original color
local t = ColorPickerFrame:CreateTexture("ColorPPOldColorSwatch")
local w, h = ColorSwatch:GetSize()
t:Size(w*0.75,h*0.75)
t:SetTexture(0,0,0)
-- OldColorSwatch to appear beneath ColorSwatch
t:SetDrawLayer("BORDER")
t:Point("BOTTOMLEFT", ColorSwatch, "TOPRIGHT", -(w/2), -(h/3))
-- add Color Swatch for the copied color
t = ColorPickerFrame:CreateTexture("ColorPPCopyColorSwatch")
t:SetTexture(0,0,0)
t:Size(w,h)
t:Hide()
-- add copy button to the ColorPickerFrame
local b = CreateFrame("Button", "ColorPPCopy", ColorPickerFrame, "UIPanelButtonTemplate")
S:HandleButton(b)
b:SetText(CALENDAR_COPY_EVENT)
b:Width(60)
b:Height(22)
b:Point("TOPLEFT", ColorSwatch, "BOTTOMLEFT", 0, -5)
-- copy color into buffer on button click
b:SetScript("OnClick", function()
-- copy current dialog colors into buffer
colorBuffer.r, colorBuffer.g, colorBuffer.b = ColorPickerFrame:GetColorRGB()
-- enable Paste button and display copied color into swatch
ColorPPPaste:Enable()
ColorPPCopyColorSwatch:SetTexture(colorBuffer.r, colorBuffer.g, colorBuffer.b)
ColorPPCopyColorSwatch:Show()
colorBuffer.a = (ColorPickerFrame.hasOpacity and OpacitySliderFrame:GetValue()) or nil
end)
--class color button
b = CreateFrame("Button", "ColorPPClass", ColorPickerFrame, "UIPanelButtonTemplate")
b:SetText(CLASS)
S:HandleButton(b)
b:Width(80)
b:Height(22)
b:Point("TOP", ColorPPCopy, "BOTTOMRIGHT", 0, -7)
b:SetScript("OnClick", function()
local color = E.media.herocolor
ColorPickerFrame:SetColorRGB(color.r, color.g, color.b)
ColorSwatch:SetTexture(color.r, color.g, color.b)
if ColorPickerFrame.hasOpacity then
OpacitySliderFrame:SetValue(0)
end
end)
-- add paste button to the ColorPickerFrame
b = CreateFrame("Button", "ColorPPPaste", ColorPickerFrame, "UIPanelButtonTemplate")
b:SetText(CALENDAR_PASTE_EVENT)
S:HandleButton(b)
b:Width(60)
b:Height(22)
b:Point("TOPLEFT", ColorPPCopy, "TOPRIGHT", 2, 0)
b:Disable() -- enable when something has been copied
-- paste color on button click, updating frame components
b:SetScript("OnClick", function()
ColorPickerFrame:SetColorRGB(colorBuffer.r, colorBuffer.g, colorBuffer.b)
ColorSwatch:SetTexture(colorBuffer.r, colorBuffer.g, colorBuffer.b)
if ColorPickerFrame.hasOpacity then
if colorBuffer.a then --color copied had an alpha value
OpacitySliderFrame:SetValue(colorBuffer.a)
end
end
end)
-- add defaults button to the ColorPickerFrame
b = CreateFrame("Button", "ColorPPDefault", ColorPickerFrame, "UIPanelButtonTemplate")
b:SetText(DEFAULT)
S:HandleButton(b)
b:Width(80)
b:Height(22)
b:Point("TOPLEFT", ColorPPClass, "BOTTOMLEFT", 0, -7)
b:Disable() -- enable when something has been copied
b:SetScript("OnHide", function(btn)
if btn.colors then
wipe(btn.colors)
end
end)
b:SetScript("OnShow", function(btn)
if btn.colors then
btn:Enable()
else
btn:Disable()
end
end)
-- paste color on button click, updating frame components
b:SetScript("OnClick", function(btn)
local colors = btn.colors
ColorPickerFrame:SetColorRGB(colors.r, colors.g, colors.b)
ColorSwatch:SetTexture(colors.r, colors.g, colors.b)
if ColorPickerFrame.hasOpacity then
if colors.a then
OpacitySliderFrame:SetValue(colors.a)
end
end
end)
-- position Color Swatch for copy color
ColorPPCopyColorSwatch:Point("BOTTOM", ColorPPPaste, "TOP", 0, 10)
-- move the Opacity Slider Frame to align with bottom of Copy ColorSwatch
OpacitySliderFrame:ClearAllPoints()
OpacitySliderFrame:Point("BOTTOM", ColorPPDefault, "BOTTOM", 0, 0)
OpacitySliderFrame:Point("RIGHT", ColorPickerFrame, "RIGHT", -35, 18)
-- set up edit box frames and interior label and text areas
local boxes = {"R", "G", "B", "H", "A"}
for i = 1, #boxes do
local rgb = boxes[i]
local box = CreateFrame("EditBox", "ColorPPBox"..rgb, ColorPickerFrame, "InputBoxTemplate")
box:Point("TOP", ColorPickerWheel, "BOTTOM", 0, -15)
box:SetFrameStrata("DIALOG")
box:SetAutoFocus(false)
box:SetTextInsets(0,7,0,0)
box:SetJustifyH("RIGHT")
box:Height(24)
box:SetID(i)
S:HandleEditBox(box)
-- hex entry box
if i == 4 then
box:SetMaxLetters(6)
box:Width(56)
box:SetNumeric(false)
else
box:SetMaxLetters(3)
box:Width(40)
box:SetNumeric(true)
end
-- label
local label = box:CreateFontString("ColorPPBoxLabel"..rgb, "ARTWORK", "GameFontNormalSmall")
label:Point("RIGHT", box, "LEFT", -5, 0)
label:SetText(i == 4 and "#" or rgb)
label:SetTextColor(1, 1, 1)
-- set up scripts to handle event appropriately
if i == 5 then
box:SetScript("OnEscapePressed", function(self) self:ClearFocus() UpdateAlphaText() end)
box:SetScript("OnEnterPressed", function(self) self:ClearFocus() UpdateAlphaText() end)
box:SetScript("OnTextChanged", UpdateAlpha)
else
box:SetScript("OnEscapePressed", function(self) self:ClearFocus() UpdateColorTexts() end)
box:SetScript("OnEnterPressed", function(self) self:ClearFocus() UpdateColorTexts() end)
box:SetScript("OnTextChanged", UpdateColor)
end
box:SetScript("OnEditFocusGained", function(eb) eb:SetCursorPosition(0) eb:HighlightText() end)
box:SetScript("OnEditFocusLost", function(eb) eb:HighlightText(0,0) end)
box:SetScript("OnTextSet", box.ClearFocus)
box:Show()
end
-- finish up with placement
ColorPPBoxA:Point("RIGHT", OpacitySliderFrame, "RIGHT", 10, 0)
ColorPPBoxH:Point("RIGHT", ColorPPDefault, "RIGHT", -10, 0)
ColorPPBoxB:Point("RIGHT", ColorPPDefault, "LEFT", -40, 0)
ColorPPBoxG:Point("RIGHT", ColorPPBoxB, "LEFT", -25, 0)
ColorPPBoxR:Point("RIGHT", ColorPPBoxG, "LEFT", -25, 0)
-- define the order of tab cursor movement
ColorPPBoxR:SetScript("OnTabPressed", function() ColorPPBoxG:SetFocus() end)
ColorPPBoxG:SetScript("OnTabPressed", function() ColorPPBoxB:SetFocus() end)
ColorPPBoxB:SetScript("OnTabPressed", function() ColorPPBoxH:SetFocus() end)
ColorPPBoxA:SetScript("OnTabPressed", function() ColorPPBoxR:SetFocus() end)
-- make the color picker movable.
local mover = CreateFrame("Frame", nil, ColorPickerFrame)
mover:Point("TOPLEFT", ColorPickerFrame, "TOP", -60, 0)
mover:Point("BOTTOMRIGHT", ColorPickerFrame, "TOP", 60, -15)
mover:SetScript("OnMouseDown", function() ColorPickerFrame:StartMoving() end)
mover:SetScript("OnMouseUp", function() ColorPickerFrame:StopMovingOrSizing() end)
mover:EnableMouse(true)
ColorPickerFrame:SetUserPlaced(true)
ColorPickerFrame:EnableKeyboard(false)
end
+27
View File
@@ -0,0 +1,27 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales
local B = E:GetModule("Blizzard")
--Lua functions
--WoW API / Variables
function B:PositionDurabilityFrame()
DurabilityFrame:SetFrameStrata("HIGH")
DurabilityFrame:SetScale(0.6)
DurabilityWeapon:Point("RIGHT", DurabilityWrists, "LEFT", 6, 0)
DurabilityShield:Point("LEFT", DurabilityWrists, "RIGHT", -6, 10)
DurabilityOffWeapon:Point("LEFT", DurabilityWrists, "RIGHT", -6, 0)
DurabilityRanged:Point("TOP", DurabilityShield, "BOTTOM", -1, 0)
hooksecurefunc(DurabilityFrame, "SetPoint", function(self, _, point)
if point ~= Minimap then
self:ClearAllPoints()
if DurabilityShield:IsShown() or DurabilityOffWeapon:IsShown() or DurabilityRanged:IsShown() then
self:Point("RIGHT", Minimap, "RIGHT", -7, 0)
else
self:Point("RIGHT", Minimap, "RIGHT", 8, 0)
end
end
end)
end
+12
View File
@@ -0,0 +1,12 @@
local E, L = unpack(select(2, ...)); --Import: Engine, Locales
local B = E:GetModule("Blizzard")
--Lua functions
--WoW API / Variables
function B:PositionGMFrames()
TicketStatusFrame:ClearAllPoints()
TicketStatusFrame:SetPoint("TOPLEFT", E.UIParent, "TOPLEFT", 250, -5)
E:CreateMover(TicketStatusFrame, "GMMover", L["GM Ticket Frame"])
end
+10
View File
@@ -0,0 +1,10 @@
local E, L = unpack(select(2, ...)); --Import: Engine, Locales
local B = E:GetModule("Blizzard")
--Lua functions
--WoW API / Variables
function B:KillBlizzard()
VideoOptionsResolutionPanelUseUIScale:Kill()
VideoOptionsResolutionPanelUIScaleSlider:Kill()
end
+11
View File
@@ -0,0 +1,11 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="Blizzard.lua"/>
<Script file="AlertFrame.lua"/>
<Script file="ColorPicker.lua"/>
<Script file="Kill.lua"/>
<Script file="WatchFrame.lua"/>
<Script file="Vehicle.lua"/>
<Script file="GM.lua"/>
<Script file="Durability.lua"/>
<Script file="CaptureBar.lua"/>
</Ui>
+50
View File
@@ -0,0 +1,50 @@
local E, L = unpack(select(2, ...)); --Import: Engine, Locales
local B = E:GetModule("Blizzard")
--Lua functions
local _G = _G
--WoW API / Variables
local GetVehicleUIIndicator = GetVehicleUIIndicator
local GetVehicleUIIndicatorSeat = GetVehicleUIIndicatorSeat
local function VehicleSeatIndicator_SetPosition(self, _, point)
if point ~= VehicleSeatMover then
self:ClearAllPoints()
self:Point("TOPLEFT", VehicleSeatMover, "TOPLEFT", 0, 0)
end
end
local function VehicleSetUp(vehicleID)
if vehicleID == 0 or vehicleID == VehicleSeatIndicator.currSkin then return end
local _, numSeatIndicators = GetVehicleUIIndicator(vehicleID)
local size = E.db.general.vehicleSeatIndicatorSize
VehicleSeatIndicator:Size(size)
for i = 1, numSeatIndicators do
local _, xOffset, yOffset = GetVehicleUIIndicatorSeat(vehicleID, i)
local button = _G["VehicleSeatIndicatorButton"..i]
button:Size(size / 4)
button:Point("CENTER", button:GetParent(), "TOPLEFT", xOffset * size, -yOffset * size)
end
end
function B:UpdateVehicleFrame()
if VehicleSeatIndicator.currSkin then
VehicleSetUp(VehicleSeatIndicator.currSkin)
end
end
function B:PositionVehicleFrame()
if not self.vehicleFrameHooked then
hooksecurefunc(VehicleSeatIndicator, "SetPoint", VehicleSeatIndicator_SetPosition)
hooksecurefunc("VehicleSeatIndicator_SetUpVehicle", VehicleSetUp)
E:CreateMover(VehicleSeatIndicator, "VehicleSeatMover", L["Vehicle Seat Frame"], nil, nil, nil, nil, nil, "general,blizzUIImprovements")
self.vehicleFrameHooked = true
end
VehicleSeatIndicator:Size(E.db.general.vehicleSeatIndicatorSize)
self:UpdateVehicleFrame()
end
+50
View File
@@ -0,0 +1,50 @@
local E, L = unpack(select(2, ...)); --Import: Engine, Locales
local B = E:GetModule("Blizzard")
--Lua functions
local min = math.min
--WoW API / Variables
local GetScreenHeight = GetScreenHeight
local hideRule = "[@arena1,exists][@arena2,exists][@arena3,exists][@arena4,exists][@arena5,exists][@boss1,exists][@boss2,exists][@boss3,exists][@boss4,exists]"
function B:SetObjectiveFrameAutoHide()
if E.db.general.watchFrameAutoHide then
RegisterStateDriver(WatchFrame, "visibility", hideRule)
else
UnregisterStateDriver(WatchFrame, "visibility")
end
end
function B:SetWatchFrameHeight()
local top = WatchFrame:GetTop() or 0
local screenHeight = GetScreenHeight()
local gapFromTop = screenHeight - top
local maxHeight = screenHeight - gapFromTop
local watchFrameHeight = min(maxHeight, E.db.general.watchFrameHeight)
WatchFrame:Height(watchFrameHeight)
end
function B:MoveWatchFrame()
local WatchFrameHolder = CreateFrame("Frame", "WatchFrameHolder", E.UIParent)
WatchFrameHolder:Size(207, 22)
WatchFrameHolder:Point("TOPRIGHT", E.UIParent, "TOPRIGHT", -135, -300)
E:CreateMover(WatchFrameHolder, "WatchFrameMover", L["Objective Frame"], nil, nil, nil, nil, nil, "general,objectiveFrameGroup")
WatchFrameHolder:SetAllPoints(WatchFrameMover)
WatchFrame:ClearAllPoints()
WatchFrame:SetPoint("TOP", WatchFrameHolder, "TOP")
B:SetWatchFrameHeight()
WatchFrame:SetClampedToScreen(false)
hooksecurefunc(WatchFrame, "SetPoint", function(_, _, parent)
if parent ~= WatchFrameHolder then
WatchFrame:ClearAllPoints()
WatchFrame:SetPoint("TOP", WatchFrameHolder, "TOP")
end
end)
self:SetObjectiveFrameAutoHide()
end
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="Chat.lua"/>
</Ui>
+63
View File
@@ -0,0 +1,63 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local mod = E:GetModule("DataBars")
--Lua functions
--WoW API / Variables
local GetExpansionLevel = GetExpansionLevel
local MAX_PLAYER_LEVEL_TABLE = MAX_PLAYER_LEVEL_TABLE
function mod:OnLeave()
if (self == ElvUI_ExperienceBar and mod.db.experience.mouseover) or (self == ElvUI_ReputationBar and mod.db.reputation.mouseover) then
E:UIFrameFadeOut(self, 1, self:GetAlpha(), 0)
end
GameTooltip:Hide()
end
function mod:CreateBar(name, onEnter, onClick, ...)
local bar = CreateFrame("Button", name, E.UIParent)
bar:Point(...)
bar:SetScript("OnEnter", onEnter)
bar:SetScript("OnLeave", mod.OnLeave)
bar:SetScript("OnClick", onClick)
bar:SetFrameStrata("LOW")
bar:SetTemplate("Transparent")
bar:Hide()
bar.statusBar = CreateFrame("StatusBar", nil, bar)
bar.statusBar:SetInside()
bar.statusBar:SetStatusBarTexture(E.media.normTex)
E:RegisterStatusBar(bar.statusBar)
bar.text = bar.statusBar:CreateFontString(nil, "OVERLAY")
bar.text:FontTemplate()
bar.text:Point("CENTER")
return bar
end
function mod:UpdateDataBarDimensions()
self:UpdateExperienceDimensions()
self:UpdateReputationDimensions()
end
function mod:PLAYER_LEVEL_UP(level)
local maxLevel = MAX_PLAYER_LEVEL_TABLE[GetExpansionLevel()]
if (level ~= maxLevel or not self.db.experience.hideAtMaxLevel) and self.db.experience.enable then
self:UpdateExperience("PLAYER_LEVEL_UP", level)
else
self.expBar:Hide()
end
end
function mod:Initialize()
self.db = E.db.databars
self:LoadExperienceBar()
self:LoadReputationBar()
self:RegisterEvent("PLAYER_LEVEL_UP")
end
local function InitializeCallback()
mod:Initialize()
end
E:RegisterModule(mod:GetName(), InitializeCallback)
+182
View File
@@ -0,0 +1,182 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local mod = E:GetModule("DataBars")
local LSM = LibStub("LibSharedMedia-3.0")
--Lua functions
local min = math.min
local format = string.format
--WoW API / Variables
local GetExpansionLevel = GetExpansionLevel
local GetPetExperience = GetPetExperience
local GetXPExhaustion = GetXPExhaustion
local InCombatLockdown = InCombatLockdown
local IsXPUserDisabled = IsXPUserDisabled
local UnitLevel = UnitLevel
local UnitXP = UnitXP
local UnitXPMax = UnitXPMax
local MAX_PLAYER_LEVEL_TABLE = MAX_PLAYER_LEVEL_TABLE
function mod:GetXP(unit)
if unit == "pet" then
return GetPetExperience()
else
return UnitXP(unit), UnitXPMax(unit)
end
end
function mod:UpdateExperience(event)
if not mod.db.experience.enable then return end
local bar = self.expBar
local hideXP = ((UnitLevel("player") == MAX_PLAYER_LEVEL_TABLE[GetExpansionLevel()] and self.db.experience.hideAtMaxLevel) or IsXPUserDisabled())
if hideXP or (event == "PLAYER_REGEN_DISABLED" and self.db.experience.hideInCombat) then
E:DisableMover(self.expBar.mover:GetName())
bar:Hide()
elseif not hideXP and (not self.db.experience.hideInCombat or not InCombatLockdown()) then
E:EnableMover(self.expBar.mover:GetName())
bar:Show()
if self.db.experience.hideInVehicle then
E:RegisterObjectForVehicleLock(bar, E.UIParent)
else
E:UnregisterObjectForVehicleLock(bar)
end
local cur, max = self:GetXP("player")
if max <= 0 then max = 1 end
bar.statusBar:SetMinMaxValues(0, max)
bar.statusBar:SetValue(cur - 1 >= 0 and cur - 1 or 0)
bar.statusBar:SetValue(cur)
local rested = GetXPExhaustion()
local text = ""
local textFormat = self.db.experience.textFormat
if rested and rested > 0 then
bar.rested:SetMinMaxValues(0, max)
bar.rested:SetValue(min(cur + rested, max))
if textFormat == "PERCENT" then
text = format("%d%% R:%d%%", cur / max * 100, rested / max * 100)
elseif textFormat == "CURMAX" then
text = format("%s - %s R:%s", E:ShortValue(cur), E:ShortValue(max), E:ShortValue(rested))
elseif textFormat == "CURPERC" then
text = format("%s - %d%% R:%s [%d%%]", E:ShortValue(cur), cur / max * 100, E:ShortValue(rested), rested / max * 100)
elseif textFormat == "CUR" then
text = format("%s R:%s", E:ShortValue(cur), E:ShortValue(rested))
elseif textFormat == "REM" then
text = format("%s R:%s", E:ShortValue(max - cur), E:ShortValue(rested))
elseif textFormat == "CURREM" then
text = format("%s - %s R:%s", E:ShortValue(cur), E:ShortValue(max - cur), E:ShortValue(rested))
elseif textFormat == "CURPERCREM" then
text = format("%s - %d%% (%s) R:%s", E:ShortValue(cur), cur / max * 100, E:ShortValue(max - cur), E:ShortValue(rested))
end
else
bar.rested:SetMinMaxValues(0, 1)
bar.rested:SetValue(0)
if textFormat == "PERCENT" then
text = format("%d%%", cur / max * 100)
elseif textFormat == "CURMAX" then
text = format("%s - %s", E:ShortValue(cur), E:ShortValue(max))
elseif textFormat == "CURPERC" then
text = format("%s - %d%%", E:ShortValue(cur), cur / max * 100)
elseif textFormat == "CUR" then
text = format("%s", E:ShortValue(cur))
elseif textFormat == "REM" then
text = format("%s", E:ShortValue(max - cur))
elseif textFormat == "CURREM" then
text = format("%s - %s", E:ShortValue(cur), E:ShortValue(max - cur))
elseif textFormat == "CURPERCREM" then
text = format("%s - %d%% (%s)", E:ShortValue(cur), cur / max * 100, E:ShortValue(max - cur))
end
end
bar.text:SetText(text)
end
end
function mod:ExperienceBar_OnEnter()
if mod.db.experience.mouseover then
E:UIFrameFadeIn(self, 0.4, self:GetAlpha(), 1)
end
GameTooltip:ClearLines()
GameTooltip:SetOwner(self, "ANCHOR_CURSOR", 0, -4)
local cur, max = mod:GetXP("player")
local rested = GetXPExhaustion()
GameTooltip:AddLine(L["Experience"])
GameTooltip:AddLine(" ")
GameTooltip:AddDoubleLine(L["XP:"], format(" %d / %d (%d%%)", cur, max, cur/max * 100), 1, 1, 1)
GameTooltip:AddDoubleLine(L["Remaining:"], format(" %d (%d%% - %d "..L["Bars"]..")", max - cur, (max - cur) / max * 100, 20 * (max - cur) / max), 1, 1, 1)
if rested then
GameTooltip:AddDoubleLine(L["Rested:"], format("+%d (%d%%)", rested, rested / max * 100), 1, 1, 1)
end
GameTooltip:Show()
end
function mod:ExperienceBar_OnClick()
end
function mod:UpdateExperienceDimensions()
self.expBar:Width(self.db.experience.width)
self.expBar:Height(self.db.experience.height)
self.expBar.text:FontTemplate(LSM:Fetch("font", self.db.experience.font), self.db.experience.textSize, self.db.experience.fontOutline)
self.expBar.rested:SetOrientation(self.db.experience.orientation)
self.expBar.statusBar:SetOrientation(self.db.experience.orientation)
if self.db.experience.mouseover then
self.expBar:SetAlpha(0)
else
self.expBar:SetAlpha(1)
end
end
function mod:EnableDisable_ExperienceBar()
local maxLevel = MAX_PLAYER_LEVEL_TABLE[GetExpansionLevel()]
if (UnitLevel("player") ~= maxLevel or not self.db.experience.hideAtMaxLevel) and self.db.experience.enable then
self:RegisterEvent("PLAYER_XP_UPDATE", "UpdateExperience")
self:RegisterEvent("DISABLE_XP_GAIN", "UpdateExperience")
self:RegisterEvent("ENABLE_XP_GAIN", "UpdateExperience")
self:RegisterEvent("UPDATE_EXHAUSTION", "UpdateExperience")
self:UnregisterEvent("UPDATE_EXPANSION_LEVEL")
self:UpdateExperience()
E:EnableMover(self.expBar.mover:GetName())
else
self:UnregisterEvent("PLAYER_XP_UPDATE")
self:UnregisterEvent("DISABLE_XP_GAIN")
self:UnregisterEvent("ENABLE_XP_GAIN")
self:UnregisterEvent("UPDATE_EXHAUSTION")
self:RegisterEvent("UPDATE_EXPANSION_LEVEL", "EnableDisable_ExperienceBar")
self.expBar:Hide()
E:DisableMover(self.expBar.mover:GetName())
end
end
function mod:LoadExperienceBar()
self.expBar = self:CreateBar("ElvUI_ExperienceBar", self.ExperienceBar_OnEnter, self.ExperienceBar_OnClick, "LEFT", LeftChatPanel, "RIGHT", -E.Border + E.Spacing*3, 0)
self.expBar.statusBar:SetStatusBarColor(0, 0.4, 1, .8)
self.expBar.rested = CreateFrame("StatusBar", nil, self.expBar)
self.expBar.rested:SetInside()
self.expBar.rested:SetStatusBarTexture(E.media.normTex)
E:RegisterStatusBar(self.expBar.rested)
self.expBar.rested:SetStatusBarColor(1, 0, 1, 0.2)
self.expBar.eventFrame = CreateFrame("Frame")
self.expBar.eventFrame:Hide()
self.expBar.eventFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
self.expBar.eventFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
self.expBar.eventFrame:SetScript("OnEvent", function(_, event) mod:UpdateExperience(event) end)
self:UpdateExperienceDimensions()
E:CreateMover(self.expBar, "ExperienceBarMover", L["Experience Bar"], nil, nil, nil, nil, nil, "databars,experience")
self:EnableDisable_ExperienceBar()
end
+5
View File
@@ -0,0 +1,5 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="DataBars.lua"/>
<Script file="Experience.lua"/>
<Script file="Reputation.lua"/>
</Ui>
+145
View File
@@ -0,0 +1,145 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local mod = E:GetModule("DataBars")
local LSM = LibStub("LibSharedMedia-3.0")
--Lua functions
local max, min = math.max, math.min
local format = string.format
--WoW API
local GetPetExperience = GetPetExperience
local HasPetUI = HasPetUI
local UnitLevel = UnitLevel
function mod:PetExperienceBar_Update(event)
if E.myclass ~= "HUNTER" or not mod.db.petExperience.enable then return end
local bar = self.petExpBar
local _, hunterPet = HasPetUI()
local hideBar = not hunterPet or (UnitLevel("pet") == self.maxExpansionLevel and self.db.petExperience.hideAtMaxLevel)
if hideBar or (event == "PLAYER_REGEN_DISABLED" and self.db.petExperience.hideInCombat) then
E:DisableMover(self.petExpBar.mover:GetName())
bar:Hide()
elseif not hideBar and (not self.db.petExperience.hideInCombat or not self.inCombatLockdown) then
E:EnableMover(self.petExpBar.mover:GetName())
bar:Show()
local textFormat = self.db.petExperience.textFormat
local curExp, maxExp = GetPetExperience()
maxExp = max(1, maxExp)
bar.statusBar:SetMinMaxValues(min(0, curExp), maxExp)
-- bar.statusBar:SetValue(curExp - 1 >= 0 and curExp - 1 or 0)
bar.statusBar:SetValue(curExp)
if textFormat == "PERCENT" then
bar.text:SetFormattedText("%d%%", curExp / maxExp * 100)
elseif textFormat == "CURMAX" then
bar.text:SetFormattedText("%s - %s", E:ShortValue(curExp), E:ShortValue(maxExp))
elseif textFormat == "CURPERC" then
bar.text:SetFormattedText("%s - %d%%", E:ShortValue(curExp), curExp / maxExp * 100)
elseif textFormat == "CUR" then
bar.text:SetFormattedText("%s", E:ShortValue(curExp))
elseif textFormat == "REM" then
bar.text:SetFormattedText("%s", E:ShortValue(maxExp - curExp))
elseif textFormat == "CURREM" then
bar.text:SetFormattedText("%s - %s", E:ShortValue(curExp), E:ShortValue(maxExp - curExp))
elseif textFormat == "CURPERCREM" then
bar.text:SetFormattedText("%s - %d%% (%s)", E:ShortValue(curExp), curExp / maxExp * 100, E:ShortValue(maxExp - curExp))
end
end
end
function mod:PetExperienceBar_OnEnter()
if mod.db.petExperience.mouseover then
E:UIFrameFadeIn(self, 0.4, self:GetAlpha(), 1)
end
local curExp, maxExp = GetPetExperience()
maxExp = max(1, maxExp)
GameTooltip:ClearLines()
GameTooltip:SetOwner(self, "ANCHOR_CURSOR", 0, -4)
GameTooltip:AddLine(L["Pet Experience"])
GameTooltip:AddLine(" ")
GameTooltip:AddDoubleLine(L["XP:"], format("%d / %d (%d%%)", curExp, maxExp, curExp / maxExp * 100), 1, 1, 1)
GameTooltip:AddDoubleLine(L["Remaining:"], format("%d (%d%% - %d %s)", maxExp - curExp, (maxExp - curExp) / maxExp * 100, 20 * (maxExp - curExp) / maxExp, L["Bars"]), 1, 1, 1)
GameTooltip:Show()
end
function mod:PetExperienceBar_OnClick()
end
function mod:PetExperienceBar_UpdateDimensions()
if E.myclass ~= "HUNTER" then return end
self.petExpBar:Size(self.db.petExperience.width, self.db.petExperience.height)
self.petExpBar:SetAlpha(self.db.petExperience.mouseover and 0 or 1)
self.petExpBar.text:FontTemplate(LSM:Fetch("font", self.db.petExperience.font), self.db.petExperience.textSize, self.db.petExperience.fontOutline)
self.petExpBar.statusBar:SetOrientation(self.db.petExperience.orientation)
self.petExpBar.statusBar:SetRotatesTexture(self.db.petExperience.orientation ~= "HORIZONTAL")
if self.petExpBar.bubbles then
self:UpdateBarBubbles(self.petExpBar, self.db.petExperience)
elseif self.db.petExperience.showBubbles then
local bubbles = self:CreateBarBubbles(self.petExpBar)
bubbles:SetFrameLevel(5)
self:UpdateBarBubbles(self.petExpBar, self.db.petExperience)
end
end
function mod:PetExperienceBar_Toggle()
if E.myclass ~= "HUNTER" then return end
if self.db.petExperience.enable then
self.petExpBar.eventFrame:RegisterEvent("UNIT_PET")
self.petExpBar.eventFrame:RegisterEvent("UNIT_PET_EXPERIENCE")
self.petExpBar.eventFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
self.petExpBar.eventFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
self:PetExperienceBar_Update()
E:EnableMover(self.petExpBar.mover:GetName())
else
self.petExpBar.eventFrame:UnregisterEvent("UNIT_PET")
self.petExpBar.eventFrame:UnregisterEvent("UNIT_PET_EXPERIENCE")
self.petExpBar.eventFrame:UnregisterEvent("PLAYER_REGEN_DISABLED")
self.petExpBar.eventFrame:UnregisterEvent("PLAYER_REGEN_ENABLED")
self.petExpBar:Hide()
E:DisableMover(self.petExpBar.mover:GetName())
end
end
function mod:PetExperienceBar_Load()
if E.myclass ~= "HUNTER" then return end
self.petExpBar = self:CreateBar("ElvUI_PetExperienceBar", self.PetExperienceBar_OnEnter, self.PetExperienceBar_OnClick, "LEFT", LeftChatPanel, "RIGHT", -E.Border + E.Spacing*3, 0)
self.petExpBar.statusBar:SetStatusBarColor(1, 1, 0.41, 0.8)
self.petExpBar.eventFrame = CreateFrame("Frame")
self.petExpBar.eventFrame:Hide()
self.petExpBar.eventFrame:SetScript("OnEvent", function(_, event, arg1)
if event == "UNIT_PET" then
if arg1 == "player" then
self:PetExperienceBar_Toggle()
end
elseif event == "PLAYER_REGEN_DISABLED" then
self.inCombatLockdown = true
elseif event == "PLAYER_REGEN_ENABLED" then
self.inCombatLockdown = false
else
self:PetExperienceBar_Update(event)
end
end)
self:PetExperienceBar_UpdateDimensions()
E:CreateMover(self.petExpBar, "PetExperienceBarMover", L["Pet Experience Bar"], nil, nil, nil, nil, nil, "databars,petExperience")
self:PetExperienceBar_Toggle()
end
+145
View File
@@ -0,0 +1,145 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local mod = E:GetModule("DataBars")
local LSM = LibStub("LibSharedMedia-3.0")
--Lua functions
local _G = _G
local format = string.format
--WoW API / Variables
local GetFactionInfo = GetFactionInfo
local GetNumFactions = GetNumFactions
local GetWatchedFactionInfo = GetWatchedFactionInfo
local InCombatLockdown = InCombatLockdown
local FACTION_BAR_COLORS = FACTION_BAR_COLORS
local REPUTATION = REPUTATION
local STANDING = STANDING
local UNKNOWN = UNKNOWN
function mod:UpdateReputation(event)
if not mod.db.reputation.enable then return end
local bar = self.repBar
local ID, standingLabel
local name, reaction, min, max, value = GetWatchedFactionInfo()
local numFactions = GetNumFactions()
if not name or (event == "PLAYER_REGEN_DISABLED" and self.db.reputation.hideInCombat) then
bar:Hide()
elseif name and (not self.db.reputation.hideInCombat or not InCombatLockdown()) then
bar:Show()
if self.db.reputation.hideInVehicle then
E:RegisterObjectForVehicleLock(bar, E.UIParent)
else
E:UnregisterObjectForVehicleLock(bar)
end
local text = ""
local textFormat = self.db.reputation.textFormat
local color = FACTION_BAR_COLORS[reaction] or FACTION_BAR_COLORS[1]
bar.statusBar:SetStatusBarColor(color.r, color.g, color.b)
bar.statusBar:SetMinMaxValues(min, max)
bar.statusBar:SetValue(value)
for i = 1, numFactions do
local factionName, _, standingID = GetFactionInfo(i)
if factionName == name then
ID = standingID
end
end
if ID then
standingLabel = _G["FACTION_STANDING_LABEL"..ID]
else
standingLabel = UNKNOWN
end
--Prevent a division by zero
local maxMinDiff = max - min
if maxMinDiff == 0 then
maxMinDiff = 1
end
if textFormat == "PERCENT" then
text = format("%s: %d%% [%s]", name, ((value - min) / maxMinDiff * 100), standingLabel)
elseif textFormat == "CURMAX" then
text = format("%s: %s - %s [%s]", name, E:ShortValue(value - min), E:ShortValue(max - min), standingLabel)
elseif textFormat == "CURPERC" then
text = format("%s: %s - %d%% [%s]", name, E:ShortValue(value - min), ((value - min) / maxMinDiff * 100), standingLabel)
elseif textFormat == "CUR" then
text = format("%s: %s [%s]", name, E:ShortValue(value - min), standingLabel)
elseif textFormat == "REM" then
text = format("%s: %s [%s]", name, E:ShortValue((max - min) - (value-min)), standingLabel)
elseif textFormat == "CURREM" then
text = format("%s: %s - %s [%s]", name, E:ShortValue(value - min), E:ShortValue((max - min) - (value-min)), standingLabel)
elseif textFormat == "CURPERCREM" then
text = format("%s: %s - %d%% (%s) [%s]", name, E:ShortValue(value - min), ((value - min) / maxMinDiff * 100), E:ShortValue((max - min) - (value-min)), standingLabel)
end
bar.text:SetText(text)
end
end
function mod:ReputationBar_OnEnter()
if mod.db.reputation.mouseover then
E:UIFrameFadeIn(self, 0.4, self:GetAlpha(), 1)
end
GameTooltip:ClearLines()
GameTooltip:SetOwner(self, "ANCHOR_CURSOR", 0, -4)
local name, reaction, min, max, value = GetWatchedFactionInfo()
if name then
GameTooltip:AddLine(name)
GameTooltip:AddLine(" ")
GameTooltip:AddDoubleLine(STANDING..":", _G["FACTION_STANDING_LABEL"..reaction], 1, 1, 1)
GameTooltip:AddDoubleLine(REPUTATION..":", format("%d / %d (%d%%)", value - min, max - min, (value - min) / ((max - min == 0) and max or (max - min)) * 100), 1, 1, 1)
end
GameTooltip:Show()
end
function mod:ReputationBar_OnClick()
ToggleCharacter("ReputationFrame")
end
function mod:UpdateReputationDimensions()
self.repBar:Width(self.db.reputation.width)
self.repBar:Height(self.db.reputation.height)
self.repBar.statusBar:SetOrientation(self.db.reputation.orientation)
self.repBar.text:FontTemplate(LSM:Fetch("font", self.db.reputation.font), self.db.reputation.textSize, self.db.reputation.fontOutline)
if self.db.reputation.mouseover then
self.repBar:SetAlpha(0)
else
self.repBar:SetAlpha(1)
end
end
function mod:EnableDisable_ReputationBar()
if self.db.reputation.enable then
self:RegisterEvent("UPDATE_FACTION", "UpdateReputation")
self:UpdateReputation()
E:EnableMover(self.repBar.mover:GetName())
else
self:UnregisterEvent("UPDATE_FACTION")
self.repBar:Hide()
E:DisableMover(self.repBar.mover:GetName())
end
end
function mod:LoadReputationBar()
self.repBar = self:CreateBar("ElvUI_ReputationBar", self.ReputationBar_OnEnter, self.ReputationBar_OnClick, "RIGHT", RightChatPanel, "LEFT", E.Border - E.Spacing*3, 0)
E:RegisterStatusBar(self.repBar.statusBar)
self.repBar.eventFrame = CreateFrame("Frame")
self.repBar.eventFrame:Hide()
self.repBar.eventFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
self.repBar.eventFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
self.repBar.eventFrame:SetScript("OnEvent", function(_, event) mod:UpdateReputation(event) end)
self:UpdateReputationDimensions()
E:CreateMover(self.repBar, "ReputationBarMover", L["Reputation Bar"], nil, nil, nil, nil, nil, "databars,reputation")
self:EnableDisable_ReputationBar()
end
+32
View File
@@ -0,0 +1,32 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local join = string.join
--WoW API / Variables
local GetTotalAchievementPoints = GetTotalAchievementPoints
local ToggleAchievementFrame = ToggleAchievementFrame
local ACHIEVEMENTS = ACHIEVEMENTS
local displayNumberString = ""
local lastPanel
local function OnEvent(self)
lastPanel = self
self.text:SetFormattedText(displayNumberString, GetTotalAchievementPoints())
end
local function OnClick()
ToggleAchievementFrame()
end
local function ValueColorUpdate(hex)
displayNumberString = join("", ACHIEVEMENTS, ": ", hex, "%d|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Achievement", {"ACHIEVEMENT_EARNED"}, OnEvent, nil, OnClick, nil, nil, ACHIEVEMENTS)
+58
View File
@@ -0,0 +1,58 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local format, join = string.format, string.join
--WoW API / Variables
local UnitArmor = UnitArmor
local UnitLevel = UnitLevel
local PaperDollFrame_GetArmorReduction = PaperDollFrame_GetArmorReduction
local ARMOR = ARMOR
local chanceString = "%.2f%%"
local displayString = ""
local _, effectiveArmor
local lastPanel
local function OnEvent(self)
_, effectiveArmor = UnitArmor("player")
self.text:SetFormattedText(displayString, effectiveArmor)
lastPanel = self
end
local function OnEnter(self)
DT:SetupTooltip(self)
DT.tooltip:AddLine(L["Mitigation By Level: "])
DT.tooltip:AddLine(" ")
local playerLevel = E.mylevel + 3
local targetLevel = UnitLevel("target")
local armorReduction
for i = 1, 4 do
armorReduction = PaperDollFrame_GetArmorReduction(effectiveArmor, playerLevel)
DT.tooltip:AddDoubleLine(playerLevel, format(chanceString, armorReduction), 1, 1, 1)
playerLevel = playerLevel - 1
end
if targetLevel and targetLevel > 0 and (targetLevel > playerLevel + 3 or targetLevel < playerLevel) then
armorReduction = PaperDollFrame_GetArmorReduction(effectiveArmor, targetLevel)
DT.tooltip:AddDoubleLine(targetLevel, format(chanceString, armorReduction), 1, 1, 1)
end
DT.tooltip:Show()
end
local function ValueColorUpdate(hex)
displayString = join("", ARMOR, ": ", hex, "%d|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Armor", {"UNIT_RESISTANCES"}, OnEvent, nil, nil, OnEnter, nil, ARMOR)
+73
View File
@@ -0,0 +1,73 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local max = math.max
local format, join = string.format, string.join
--WoW API / Variables
local ComputePetBonus = ComputePetBonus
local UnitAttackPower = UnitAttackPower
local UnitRangedAttackPower = UnitRangedAttackPower
local ATTACK_POWER = ATTACK_POWER
local ATTACK_POWER_MAGIC_NUMBER = ATTACK_POWER_MAGIC_NUMBER
local ATTACK_POWER_TOOLTIP = ATTACK_POWER_TOOLTIP
local MELEE_ATTACK_POWER = MELEE_ATTACK_POWER
local MELEE_ATTACK_POWER_TOOLTIP = MELEE_ATTACK_POWER_TOOLTIP
local PET_BONUS_TOOLTIP_RANGED_ATTACK_POWER = PET_BONUS_TOOLTIP_RANGED_ATTACK_POWER
local PET_BONUS_TOOLTIP_SPELLDAMAGE = PET_BONUS_TOOLTIP_SPELLDAMAGE
local RANGED_ATTACK_POWER = RANGED_ATTACK_POWER
local RANGED_ATTACK_POWER_TOOLTIP = RANGED_ATTACK_POWER_TOOLTIP
local apower, base, posBuff, negBuff
local displayNumberString = ""
local lastPanel
local function OnEvent(self)
lastPanel = self
if E.Role == "Ranged" then
base, posBuff, negBuff = UnitRangedAttackPower("player")
apower = base + posBuff + negBuff
else
base, posBuff, negBuff = UnitAttackPower("player")
apower = base + posBuff + negBuff
end
self.text:SetFormattedText(displayNumberString, apower)
end
local function OnEnter(self)
DT:SetupTooltip(self)
if E.Role == "Ranged" then
local petAPBonus = ComputePetBonus("PET_BONUS_RAP_TO_AP", apower)
local petSpellDmgBonus = ComputePetBonus("PET_BONUS_RAP_TO_SPELLDMG", apower)
DT.tooltip:AddDoubleLine(RANGED_ATTACK_POWER, apower, 1, 1, 1, 1, 1, 1)
DT.tooltip:AddLine(format(RANGED_ATTACK_POWER_TOOLTIP, max(0, apower) / ATTACK_POWER_MAGIC_NUMBER), nil, nil, nil, 1)
if petAPBonus > 0 then
DT.tooltip:AddLine(format(PET_BONUS_TOOLTIP_RANGED_ATTACK_POWER, petAPBonus), nil, nil, nil)
end
if petSpellDmgBonus > 0 then
DT.tooltip:AddLine(format(PET_BONUS_TOOLTIP_SPELLDAMAGE, petSpellDmgBonus), nil, nil, nil)
end
else
DT.tooltip:AddDoubleLine(MELEE_ATTACK_POWER, apower, 1, 1, 1, 1, 1, 1)
DT.tooltip:AddLine(format(MELEE_ATTACK_POWER_TOOLTIP, max(0, apower) / ATTACK_POWER_MAGIC_NUMBER), nil, nil, nil, 1)
end
DT.tooltip:Show()
end
local function ValueColorUpdate(hex)
displayNumberString = join("", ATTACK_POWER, ": ", hex, "%d|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Attack Power", {"UNIT_ATTACK_POWER", "UNIT_RANGED_ATTACK_POWER"}, OnEvent, nil, nil, OnEnter, nil, ATTACK_POWER_TOOLTIP)
+122
View File
@@ -0,0 +1,122 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local select = select
local abs = math.abs
local format, join = string.format, string.join
--WoW API / Variables
local GetBlockChance = GetBlockChance
local GetBonusBarOffset = GetBonusBarOffset
local GetDodgeChance = GetDodgeChance
local GetInventoryItemID = GetInventoryItemID
local GetInventorySlotInfo = GetInventorySlotInfo
local GetItemInfo = GetItemInfo
local GetParryChance = GetParryChance
local UnitLevel = UnitLevel
local BLOCK_CHANCE = BLOCK_CHANCE
local BOSS = BOSS
local DEFENSE = DEFENSE
local DODGE_CHANCE = DODGE_CHANCE
local PARRY_CHANCE = PARRY_CHANCE
local displayString = ""
local chanceString = "%.2f%%"
local chanceString2 = "+%.2f%%"
local AVD_DECAY_RATE = 0.2
local targetlvl, playerlvl
local baseMissChance, levelDifference, dodge, parry, block, avoidance, unhittable
local lastPanel
local function IsWearingShield()
local slotID = GetInventorySlotInfo("SecondaryHandSlot")
local itemID = GetInventoryItemID("player", slotID)
if itemID then
return select(9, GetItemInfo(itemID))
end
end
local function OnEvent(self)
targetlvl, playerlvl = UnitLevel("target"), E.mylevel
baseMissChance = E.myrace == "NightElf" and 7 or 5
if targetlvl == -1 then
levelDifference = 3
elseif targetlvl > playerlvl then
levelDifference = (targetlvl - playerlvl)
elseif targetlvl < playerlvl and targetlvl > 0 then
levelDifference = (targetlvl - playerlvl)
else
levelDifference = 0
end
if levelDifference >= 0 then
dodge = (GetDodgeChance() - levelDifference * AVD_DECAY_RATE)
parry = (GetParryChance() - levelDifference * AVD_DECAY_RATE)
block = (GetBlockChance() - levelDifference * AVD_DECAY_RATE)
baseMissChance = (baseMissChance - levelDifference * AVD_DECAY_RATE)
else
dodge = (GetDodgeChance() + abs(levelDifference * AVD_DECAY_RATE))
parry = (GetParryChance() + abs(levelDifference * AVD_DECAY_RATE))
block = (GetBlockChance() + abs(levelDifference * AVD_DECAY_RATE))
baseMissChance = (baseMissChance+ abs(levelDifference * AVD_DECAY_RATE))
end
if dodge <= 0 then dodge = 0 end
if parry <= 0 then parry = 0 end
if block <= 0 then block = 0 end
if GetBonusBarOffset() == 3 then
parry = 0
end
if IsWearingShield() ~= "INVTYPE_SHIELD" then
block = 0
end
avoidance = (dodge + parry + block + baseMissChance)
unhittable = avoidance - 102.4
self.text:SetFormattedText(displayString, avoidance)
lastPanel = self
end
local function OnEnter(self)
DT:SetupTooltip(self)
if targetlvl > 1 then
DT.tooltip:AddDoubleLine(L["Avoidance Breakdown"], join("", " (", L["lvl"], " ", targetlvl, ")"))
elseif targetlvl == -1 then
DT.tooltip:AddDoubleLine(L["Avoidance Breakdown"], join("", " (", BOSS, ")"))
else
DT.tooltip:AddDoubleLine(L["Avoidance Breakdown"], join("", " (", L["lvl"], " ", playerlvl, ")"))
end
DT.tooltip:AddLine(" ")
DT.tooltip:AddDoubleLine(DODGE_CHANCE, format(chanceString, dodge), 1, 1, 1)
DT.tooltip:AddDoubleLine(PARRY_CHANCE, format(chanceString, parry), 1, 1, 1)
DT.tooltip:AddDoubleLine(BLOCK_CHANCE, format(chanceString, block), 1, 1, 1)
DT.tooltip:AddDoubleLine(L["Miss Chance"], format(chanceString, baseMissChance), 1, 1, 1)
DT.tooltip:AddLine(" ")
if unhittable > 0 then
DT.tooltip:AddDoubleLine(L["Unhittable:"], format(chanceString2, unhittable), 1, 1, 1, 0, 1, 0)
else
DT.tooltip:AddDoubleLine(L["Unhittable:"], format(chanceString, unhittable), 1, 1, 1, 1, 0, 0)
end
DT.tooltip:Show()
end
local function ValueColorUpdate(hex)
displayString = join("", DEFENSE, ": ", hex, "%.2f%%|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Avoidance", {"COMBAT_RATING_UPDATE", "PLAYER_TARGET_CHANGED"}, OnEvent, nil, nil, OnEnter, nil, L["Avoidance Breakdown"])
+91
View File
@@ -0,0 +1,91 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local format, join = string.format, string.join
--WoW API / Variables
local ContainerIDToInventoryID = ContainerIDToInventoryID
local GetBackpackCurrencyInfo = GetBackpackCurrencyInfo
local GetContainerNumFreeSlots = GetContainerNumFreeSlots
local GetContainerNumSlots = GetContainerNumSlots
local GetInventoryItemLink = GetInventoryItemLink
local GetItemInfo = GetItemInfo
local GetItemQualityColor = GetItemQualityColor
local BACKPACK_TOOLTIP = BACKPACK_TOOLTIP
local CURRENCY = CURRENCY
local MAX_WATCHED_TOKENS = MAX_WATCHED_TOKENS
local NUM_BAG_SLOTS = NUM_BAG_SLOTS
local currencyString = "|T%s:14:14:0:0:64:64:4:60:4:60|t %s"
local displayString = ""
local lastPanel
local function OnEvent(self)
local free, total = 0, 0
for i = 0, NUM_BAG_SLOTS do
free, total = free + GetContainerNumFreeSlots(i), total + GetContainerNumSlots(i)
end
self.text:SetFormattedText(displayString, total - free, total)
lastPanel = self
end
local function OnClick()
OpenAllBags()
end
local function OnEnter(self)
DT:SetupTooltip(self)
local r, g, b
local _, name, quality, link
local free, total, used
for i = 0, NUM_BAG_SLOTS do
free, total = GetContainerNumFreeSlots(i), GetContainerNumSlots(i)
used = total - free
if i == 0 then
DT.tooltip:AddLine(L["Bags"]..":")
DT.tooltip:AddDoubleLine(BACKPACK_TOOLTIP, format("%d / %d", used, total), 1, 1, 1)
else
link = GetInventoryItemLink("player", ContainerIDToInventoryID(i))
if link then
name, _, quality = GetItemInfo(link)
r, g, b = GetItemQualityColor(quality)
DT.tooltip:AddDoubleLine(name, format("%d / %d", used, total), r, g, b)
end
end
end
local count, currencyType, icon
for i = 1, MAX_WATCHED_TOKENS do
name, count, currencyType, icon = GetBackpackCurrencyInfo(i)
if name and i == 1 then
DT.tooltip:AddLine(" ")
DT.tooltip:AddLine(CURRENCY..":")
end
if name and count then
if currencyType == 1 then
icon = "Interface\\PVPFrame\\PVP-ArenaPoints-Icon"
elseif currencyType == 2 then
icon = "Interface\\PVPFrame\\PVP-Currency-"..E.myfaction
end
DT.tooltip:AddDoubleLine(format(currencyString, icon, name), count, 1, 1, 1)
end
end
DT.tooltip:Show()
end
local function ValueColorUpdate(hex)
displayString = join("", L["Bags"], ": ", hex, "%d/%d|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Bags", {"PLAYER_ENTERING_WORLD", "BAG_UPDATE"}, OnEvent, nil, OnClick, OnEnter, nil, L["Bags"])
+91
View File
@@ -0,0 +1,91 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local select = select
local join = string.join
--WoW API / Variables
local GetBattlefieldScore = GetBattlefieldScore
local GetBattlefieldStatData = GetBattlefieldStatData
local GetBattlefieldStatInfo = GetBattlefieldStatInfo
local GetNumBattlefieldScores = GetNumBattlefieldScores
local GetNumBattlefieldStats = GetNumBattlefieldStats
local displayString = ""
local lastPanel
local dataLayout = {
["LeftChatDataPanel"] = {
["left"] = 11,
["middle"] = 5,
["right"] = 2
},
["RightChatDataPanel"] = {
["left"] = 4,
["middle"] = 3,
["right"] = 12
}
}
local dataStrings = {
[11] = DAMAGE,
[5] = HONOR,
[2] = KILLING_BLOWS,
[4] = DEATHS,
[3] = HONORABLE_KILLS,
[12] = SHOW_COMBAT_HEALING
}
function DT:UPDATE_BATTLEFIELD_SCORE()
lastPanel = self
local pointIndex = dataLayout[self:GetParent():GetName()][self.pointIndex]
for i = 1, GetNumBattlefieldScores() do
local name = GetBattlefieldScore(i)
if name == E.myname then
self.text:SetFormattedText(displayString, dataStrings[pointIndex], E:ShortValue(select(pointIndex, GetBattlefieldScore(i))))
break
end
end
end
function DT:BattlegroundStats()
DT:SetupTooltip(self)
local numStatInfo = GetNumBattlefieldStats()
if numStatInfo then
for i = 1, GetNumBattlefieldScores() do
local name = GetBattlefieldScore(i)
if name and name == E.myname then
local classColor = E.media.herocolor
DT.tooltip:AddDoubleLine(L["Stats For:"], name, 1, 1, 1, classColor.r, classColor.g, classColor.b)
DT.tooltip:AddLine(" ")
-- Add extra statistics to watch based on what BG you are in.
for j = 1, numStatInfo do
DT.tooltip:AddDoubleLine(GetBattlefieldStatInfo(j), GetBattlefieldStatData(i, j), 1, 1, 1)
end
break
end
end
end
DT.tooltip:Show()
end
function DT:HideBattlegroundTexts()
DT.ForceHideBGStats = true
DT:LoadDataTexts()
E:Print(L["Battleground datatexts temporarily hidden, to show type /bgstats or right click the 'C' icon near the minimap."])
end
local function ValueColorUpdate(hex)
displayString = join("", "%s: ", hex, "%s|r")
if lastPanel ~= nil then
DT.UPDATE_BATTLEFIELD_SCORE(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
+42
View File
@@ -0,0 +1,42 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local floor = math.floor
local format, join = string.format, string.join
--WoW API / Variables
local COMBAT = COMBAT
local timer = 0
local displayNumberString = ""
local lastPanel
local function OnUpdate(self, elapsed)
timer = timer + elapsed
self.text:SetFormattedText(displayNumberString, format("%02d:%02d:%02d", floor(timer / 60), timer % 60, (timer - floor(timer)) * 100))
end
local function OnEvent(self, event)
if event == "PLAYER_REGEN_DISABLED" then
timer = 0
self:SetScript("OnUpdate", OnUpdate)
elseif event == "PLAYER_REGEN_ENABLED" then
self:SetScript("OnUpdate", nil)
else
self.text:SetFormattedText(displayNumberString, "00:00:00")
end
lastPanel = self
end
local function ValueColorUpdate(hex)
displayNumberString = join("", COMBAT, ": ", hex, "%s|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Combat Time", {"PLAYER_REGEN_ENABLED", "PLAYER_REGEN_DISABLED"}, OnEvent, nil, nil, nil, nil, L["Combat Time"])
+72
View File
@@ -0,0 +1,72 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local pairs = pairs
local find, join = string.find, string.join
--WoW API / Variables
local GetNumAddOns = GetNumAddOns
local GetAddOnInfo = GetAddOnInfo
local GetAddOnMetadata = GetAddOnMetadata
local IsShiftKeyDown = IsShiftKeyDown
local ReloadUI = ReloadUI
local displayString = ""
local configText = "ElvUI"
local plugins
local lastPanel
local function OnEvent(self, event)
lastPanel = self
if not plugins and event == "PLAYER_ENTERING_WORLD" then
for i = 1, GetNumAddOns() do
local name, title, _, enabled = GetAddOnInfo(i)
if enabled and find(name, "ElvUI") and name ~= "ElvUI" then
plugins = plugins or {}
plugins[title] = GetAddOnMetadata(i, "version")
end
end
self:UnregisterEvent(event)
end
self.text:SetFormattedText(displayString, configText)
end
local function OnEnter(self)
DT:SetupTooltip(self)
DT.tooltip:AddDoubleLine(L["Left Click:"], L["Toggle Configuration"], 1, 1, 1)
DT.tooltip:AddDoubleLine(L["Hold Shift + Right Click:"], L["Reload UI"], 1, 1, 1)
if plugins then
DT.tooltip:AddLine(" ")
DT.tooltip:AddDoubleLine("Plugins:", "Version:")
for plugin, version in pairs(plugins) do
DT.tooltip:AddDoubleLine(plugin, version, 1, 1, 1, 1, 1, 1)
end
end
DT.tooltip:Show()
end
local function OnClick(_, button)
if button == "LeftButton" or (button == "RightButton" and not IsShiftKeyDown()) then
E:ToggleOptionsUI()
elseif button == "RightButton" and IsShiftKeyDown() then
ReloadUI()
end
end
local function ValueColorUpdate(hex)
displayString = join("", hex, "%s|r")
if lastPanel ~= nil then
OnEvent(lastPanel, "ELVUI_COLOR_UPDATE")
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("ElvUI Config", {"PLAYER_ENTERING_WORLD"}, OnEvent, nil, OnClick, OnEnter)
+36
View File
@@ -0,0 +1,36 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local join = string.join
--WoW API / Variables
local GetPlayerMapPosition = GetPlayerMapPosition
local ToggleFrame = ToggleFrame
local displayString = ""
local x, y = 0, 0
local timeSinceUpdate = 0
local function OnUpdate(self, elapsed)
timeSinceUpdate = timeSinceUpdate + elapsed
if timeSinceUpdate > 0.03333 then
timeSinceUpdate = 0
x, y = GetPlayerMapPosition("player")
self.text:SetFormattedText(displayString, x * 100, y * 100)
end
end
local function OnClick()
ToggleFrame(WorldMapFrame)
end
local function ValueColorUpdate(hex)
displayString = join("", hex, "%.2f|r", " , ", hex, "%.2f|r")
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Coords", nil, nil, OnUpdate, OnClick, nil, nil, L["Coords"])
+71
View File
@@ -0,0 +1,71 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local format, join = string.format, string.join
--WoW API / Variables
local GetCombatRating = GetCombatRating
local GetCombatRatingBonus = GetCombatRatingBonus
local GetCritChance = GetCritChance
local GetRangedCritChance = GetRangedCritChance
local GetSpellCritChance = GetSpellCritChance
local COMBAT_RATING_NAME11 = COMBAT_RATING_NAME11
local CRIT_ABBR = CRIT_ABBR
local CR_CRIT_MELEE = CR_CRIT_MELEE
local CR_CRIT_MELEE_TOOLTIP = CR_CRIT_MELEE_TOOLTIP
local CR_CRIT_RANGED = CR_CRIT_RANGED
local CR_CRIT_RANGED_TOOLTIP = CR_CRIT_RANGED_TOOLTIP
local MELEE_CRIT_CHANCE = MELEE_CRIT_CHANCE
local PAPERDOLLFRAME_TOOLTIP_FORMAT = PAPERDOLLFRAME_TOOLTIP_FORMAT
local RANGED_CRIT_CHANCE = RANGED_CRIT_CHANCE
local SPELL_CRIT_CHANCE = SPELL_CRIT_CHANCE
local critRating
local displayModifierString = ""
local lastPanel
local function OnEvent(self)
lastPanel = self
if E.Role == "Caster"then
critRating = GetSpellCritChance(2)
elseif E.Role == "Ranged" then
critRating = GetRangedCritChance()
else
critRating = GetCritChance()
end
self.text:SetFormattedText(displayModifierString, critRating)
end
local function OnEnter(self)
DT:SetupTooltip(self)
local text, tooltip
if E.Role == "Caster" then
text = format("%s %.2f%%", format(PAPERDOLLFRAME_TOOLTIP_FORMAT, SPELL_CRIT_CHANCE), critRating)
tooltip = format("%s %d", COMBAT_RATING_NAME11, GetCombatRating(11))
elseif E.Role == "Ranged" then
text = format("%s %.2f%%", format(PAPERDOLLFRAME_TOOLTIP_FORMAT, RANGED_CRIT_CHANCE), critRating)
tooltip = format(CR_CRIT_RANGED_TOOLTIP, GetCombatRating(CR_CRIT_RANGED), GetCombatRatingBonus(CR_CRIT_RANGED))
else
text = format("%s %.2f%%", format(PAPERDOLLFRAME_TOOLTIP_FORMAT, MELEE_CRIT_CHANCE), critRating)
tooltip = format(CR_CRIT_MELEE_TOOLTIP, GetCombatRating(CR_CRIT_MELEE), GetCombatRatingBonus(CR_CRIT_MELEE))
end
DT.tooltip:AddLine(text, 1, 1, 1)
DT.tooltip:AddLine(tooltip, nil, nil, nil, 1)
DT.tooltip:Show()
end
local function ValueColorUpdate(hex)
displayModifierString = join("", CRIT_ABBR, ": ", hex, "%.2f%%|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Crit Chance", {"ACTIVE_TALENT_GROUP_CHANGED", "PLAYER_TALENT_UPDATE", "PLAYER_DAMAGE_DONE_MODS"}, OnEvent, nil, nil, OnEnter, nil, MELEE_CRIT_CHANCE)
+90
View File
@@ -0,0 +1,90 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local select = select
local time = time
local join = string.join
--WoW API / Variables
local UnitGUID = UnitGUID
local events = {SWING_DAMAGE = true, RANGE_DAMAGE = true, SPELL_DAMAGE = true, SPELL_PERIODIC_DAMAGE = true, DAMAGE_SHIELD = true, DAMAGE_SPLIT = true, SPELL_EXTRA_ATTACKS = true}
local playerID, petID
local dmgTotal, lastDmgAmount = 0, 0
local combatTime = 0
local timeStamp = 0
local lastSegment = 0
local lastPanel
local displayString = ""
local function Reset()
timeStamp = 0
combatTime = 0
dmgTotal = 0
lastDmgAmount = 0
end
local function GetDPS(self)
local dps
if dmgTotal == 0 or combatTime == 0 then
dps = 0
else
dps = dmgTotal / combatTime
end
self.text:SetFormattedText(displayString, E:ShortValue(dps))
end
local function OnEvent(self, event, ...)
lastPanel = self
if event == "PLAYER_REGEN_DISABLED" or event == "PLAYER_LEAVE_COMBAT" then
local now = time()
if now - lastSegment > 20 then
Reset()
end
lastSegment = now
elseif event == "COMBAT_LOG_EVENT_UNFILTERED" then
if not events[select(2, ...)] then return end
local id = select(3, ...)
if id == playerID or id == petID then
if timeStamp == 0 then
timeStamp = ...
end
lastSegment = timeStamp
combatTime = (...) - timeStamp
if select(2, ...) == "SWING_DAMAGE" then
lastDmgAmount = select(9, ...)
else
lastDmgAmount = select(12, ...)
end
dmgTotal = dmgTotal + lastDmgAmount
end
elseif event == "UNIT_PET" then
petID = UnitGUID("pet")
elseif event == "PLAYER_ENTERING_WORLD" then
playerID = E.myguid
self:UnregisterEvent(event)
end
GetDPS(self)
end
local function OnClick(self)
Reset()
GetDPS(self)
end
local function ValueColorUpdate(hex)
displayString = join("", L["DPS"], ": ", hex, "%s")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("DPS", {"PLAYER_ENTERING_WORLD", "COMBAT_LOG_EVENT_UNFILTERED", "PLAYER_LEAVE_COMBAT", "PLAYER_REGEN_DISABLED", "UNIT_PET"}, OnEvent, nil, OnClick, nil, nil, L["DPS"])
+347
View File
@@ -0,0 +1,347 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
local TT = E:GetModule("Tooltip")
local LDB = E.Libs.LDB
local LSM = E.Libs.LSM
--Lua functions
local pairs, type, error = pairs, type, error
local strlen = strlen
--WoW API / Variables
local CreateFrame = CreateFrame
local InCombatLockdown = InCombatLockdown
local IsInInstance = IsInInstance
function DT:Initialize()
--if E.db.datatexts.enable ~= true then return end
self.Initialized = true
self.db = E.db.datatexts
self.tooltip = CreateFrame("GameTooltip", "DatatextTooltip", nil, "GameTooltipTemplate")
self.tooltip:SetParent(E.UIParent)
self.tooltip:SetFrameStrata("TOOLTIP")
TT:HookScript(self.tooltip, "OnShow", "SetStyle")
-- Ignore header font size on DatatextTooltip
local font = LSM:Fetch("font", E.db.tooltip.font)
local fontOutline = E.db.tooltip.fontOutline
local textSize = E.db.tooltip.textFontSize
DatatextTooltipTextLeft1:FontTemplate(font, textSize, fontOutline)
DatatextTooltipTextRight1:FontTemplate(font, textSize, fontOutline)
self:RegisterLDB()
LDB.RegisterCallback(E, "LibDataBroker_DataObjectCreated", DT.SetupObjectLDB)
self:LoadDataTexts()
self:RegisterEvent("PLAYER_ENTERING_WORLD")
end
DT.RegisteredPanels = {}
DT.RegisteredDataTexts = {}
DT.PointLocation = {
[1] = "middle",
[2] = "left",
[3] = "right"
}
function DT:PLAYER_ENTERING_WORLD()
local inInstance, instanceType = IsInInstance()
self.isInPVP = inInstance and instanceType == "pvp"
if (not self.isInPVP and self.ShowingBGStats)
or (self.isInPVP and not self.ShowingBGStats and self.db.battleground)
then
self:LoadDataTexts()
self.ShowingBGStats = not self.ShowingBGStats
end
end
local LDBHex = "|cffFFFFFF"
function DT:SetupObjectLDB(name, obj)
local curFrame = nil
local function OnEnter(dt)
DT:SetupTooltip(dt)
if obj.OnTooltipShow then
obj.OnTooltipShow(DT.tooltip)
end
if obj.OnEnter then
obj.OnEnter(dt)
end
DT.tooltip:Show()
end
local function OnLeave(dt)
if obj.OnLeave then
obj.OnLeave(dt)
end
DT.tooltip:Hide()
end
local function OnClick(dt, button)
if obj.OnClick then
obj.OnClick(dt, button)
end
end
local function textUpdate(_, Name, _, Value)
if Value == nil or (strlen(Value) >= 3) or Value == "n/a" or Name == Value then
curFrame.text:SetText(Value ~= "n/a" and Value or Name)
else
curFrame.text:SetFormattedText("%s: %s%s|r", Name, LDBHex, Value)
end
end
local function OnCallback(newHex)
if name and obj then
LDBHex = newHex
LDB.callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_text", name, nil, obj.text, obj)
end
end
local function OnEvent(dt)
curFrame = dt
LDB:RegisterCallback("LibDataBroker_AttributeChanged_"..name.."_text", textUpdate)
LDB:RegisterCallback("LibDataBroker_AttributeChanged_"..name.."_value", textUpdate)
OnCallback(LDBHex)
end
DT:RegisterDatatext(name, {"PLAYER_ENTERING_WORLD"}, OnEvent, nil, OnClick, OnEnter, OnLeave)
E.valueColorUpdateFuncs[OnCallback] = true
--Update config if it has been loaded
if DT.PanelLayoutOptions then
DT:PanelLayoutOptions()
end
end
function DT:RegisterLDB()
for name, obj in LDB:DataObjectIterator() do
self:SetupObjectLDB(name, obj)
end
end
function DT:GetDataPanelPoint(panel, i, numPoints)
if numPoints == 1 then
return "CENTER", panel, "CENTER"
else
if i == 1 then
return "CENTER", panel, "CENTER"
elseif i == 2 then
return "RIGHT", panel.dataPanels.middle, "LEFT", -4, 0
elseif i == 3 then
return "LEFT", panel.dataPanels.middle, "RIGHT", 4, 0
end
end
end
function DT:UpdateAllDimensions()
for _, panel in pairs(DT.RegisteredPanels) do
local width = (panel:GetWidth() / panel.numPoints) - 4
local height = panel:GetHeight() - 4
for i = 1, panel.numPoints do
local pointIndex = DT.PointLocation[i]
panel.dataPanels[pointIndex]:Width(width)
panel.dataPanels[pointIndex]:Height(height)
panel.dataPanels[pointIndex]:Point(DT:GetDataPanelPoint(panel, i, panel.numPoints))
end
end
end
function DT:Data_OnLeave()
DT.tooltip:Hide()
end
function DT:SetupTooltip(panel)
local parent = panel:GetParent()
self.tooltip:Hide()
self.tooltip:SetOwner(parent, parent.anchor, parent.xOff, parent.yOff)
self.tooltip:ClearLines()
GameTooltip:Hide()
end
function DT:RegisterPanel(panel, numPoints, anchor, xOff, yOff)
DT.RegisteredPanels[panel:GetName()] = panel
panel.dataPanels = {}
panel.numPoints = numPoints
panel.xOff = xOff
panel.yOff = yOff
panel.anchor = anchor
for i = 1, numPoints do
local pointIndex = DT.PointLocation[i]
if not panel.dataPanels[pointIndex] then
panel.dataPanels[pointIndex] = CreateFrame("Button", "DataText"..i, panel)
panel.dataPanels[pointIndex]:RegisterForClicks("AnyUp")
panel.dataPanels[pointIndex].text = panel.dataPanels[pointIndex]:CreateFontString(nil, "OVERLAY")
panel.dataPanels[pointIndex].text:SetAllPoints()
panel.dataPanels[pointIndex].text:FontTemplate()
panel.dataPanels[pointIndex].text:SetJustifyH("CENTER")
panel.dataPanels[pointIndex].text:SetJustifyV("MIDDLE")
end
panel.dataPanels[pointIndex]:Point(DT:GetDataPanelPoint(panel, i, numPoints))
end
panel:SetScript("OnSizeChanged", DT.UpdateAllDimensions)
DT.UpdateAllDimensions(panel)
end
function DT:AssignPanelToDataText(panel, data)
panel.name = ""
if data.name then
panel.name = data.name
end
if data.events then
for _, event in pairs(data.events) do
panel:RegisterEvent(event)
end
end
if data.eventFunc then
panel:SetScript("OnEvent", data.eventFunc)
data.eventFunc(panel, "ELVUI_FORCE_RUN")
end
if data.onUpdate then
panel:SetScript("OnUpdate", data.onUpdate)
data.onUpdate(panel, 20000)
end
if data.onClick then
panel:SetScript("OnClick", function(p, button)
if E.db.datatexts.noCombatClick and InCombatLockdown() then return end
data.onClick(p, button)
end)
end
if data.onEnter then
panel:SetScript("OnEnter", function(p)
if E.db.datatexts.noCombatHover and InCombatLockdown() then return end
data.onEnter(p)
end)
end
if data.onLeave then
panel:SetScript("OnLeave", data.onLeave)
else
panel:SetScript("OnLeave", DT.Data_OnLeave)
end
end
function DT:LoadDataTexts()
LDB:UnregisterAllCallbacks(self)
local fontTemplate = LSM:Fetch("font", self.db.font)
local enableBGPanel = self.isInPVP and not self.ForceHideBGStats and self.db.battleground
local pointIndex, showBGPanel
if ElvConfigToggle then
ElvConfigToggle.text:FontTemplate(fontTemplate, self.db.fontSize, self.db.fontOutline)
end
for panelName, panel in pairs(DT.RegisteredPanels) do
showBGPanel = enableBGPanel and (panelName == "LeftChatDataPanel" or panelName == "RightChatDataPanel")
--Restore Panels
for i = 1, panel.numPoints do
pointIndex = DT.PointLocation[i]
panel.dataPanels[pointIndex]:UnregisterAllEvents()
panel.dataPanels[pointIndex]:SetScript("OnUpdate", nil)
panel.dataPanels[pointIndex]:SetScript("OnEnter", nil)
panel.dataPanels[pointIndex]:SetScript("OnLeave", nil)
panel.dataPanels[pointIndex]:SetScript("OnClick", nil)
panel.dataPanels[pointIndex].text:FontTemplate(fontTemplate, self.db.fontSize, self.db.fontOutline)
panel.dataPanels[pointIndex].text:SetWordWrap(self.db.wordWrap)
panel.dataPanels[pointIndex].text:SetText(nil)
panel.dataPanels[pointIndex].pointIndex = pointIndex
if showBGPanel then
panel.dataPanels[pointIndex]:RegisterEvent("UPDATE_BATTLEFIELD_SCORE")
panel.dataPanels[pointIndex]:SetScript("OnEvent", DT.UPDATE_BATTLEFIELD_SCORE)
panel.dataPanels[pointIndex]:SetScript("OnEnter", DT.BattlegroundStats)
panel.dataPanels[pointIndex]:SetScript("OnLeave", DT.Data_OnLeave)
panel.dataPanels[pointIndex]:SetScript("OnClick", DT.HideBattlegroundTexts)
DT.UPDATE_BATTLEFIELD_SCORE(panel.dataPanels[pointIndex])
else
--Register Panel to Datatext
for name, data in pairs(DT.RegisteredDataTexts) do
for option, value in pairs(self.db.panels) do
if value and type(value) == "table" then
if option == panelName and self.db.panels[option][pointIndex] and self.db.panels[option][pointIndex] == name then
DT:AssignPanelToDataText(panel.dataPanels[pointIndex], data)
end
elseif value and type(value) == "string" and value == name then
if self.db.panels[option] == name and option == panelName then
DT:AssignPanelToDataText(panel.dataPanels[pointIndex], data)
end
end
end
end
end
end
end
if DT.ForceHideBGStats then
DT.ForceHideBGStats = nil
end
end
--[[
DT:RegisterDatatext(name, events, eventFunc, updateFunc, clickFunc, onEnterFunc, onLeaveFunc, localizedName)
name - name of the datatext (required)
events - must be a table with string values of event names to register
eventFunc - function that gets fired when an event gets triggered
updateFunc - onUpdate script target function
click - function to fire when clicking the datatext
onEnterFunc - function to fire OnEnter
onLeaveFunc - function to fire OnLeave, if not provided one will be set for you that hides the tooltip.
localizedName - localized name of the datetext
]]
function DT:RegisterDatatext(name, events, eventFunc, updateFunc, clickFunc, onEnterFunc, onLeaveFunc, localizedName)
if name then
DT.RegisteredDataTexts[name] = {}
else
error("Cannot register datatext no name was provided.")
end
DT.RegisteredDataTexts[name].name = name
if type(events) ~= "table" and events ~= nil then
error("Events must be registered as a table.")
else
DT.RegisteredDataTexts[name].events = events
DT.RegisteredDataTexts[name].eventFunc = eventFunc
end
if updateFunc and type(updateFunc) == "function" then
DT.RegisteredDataTexts[name].onUpdate = updateFunc
end
if clickFunc and type(clickFunc) == "function" then
DT.RegisteredDataTexts[name].onClick = clickFunc
end
if onEnterFunc and type(onEnterFunc) == "function" then
DT.RegisteredDataTexts[name].onEnter = onEnterFunc
end
if onLeaveFunc and type(onLeaveFunc) == "function" then
DT.RegisteredDataTexts[name].onLeave = onLeaveFunc
end
if localizedName and type(localizedName) == "string" then
DT.RegisteredDataTexts[name].localizedName = localizedName
end
end
local function InitializeCallback()
DT:Initialize()
end
E:RegisterModule(DT:GetName(), InitializeCallback)
+94
View File
@@ -0,0 +1,94 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local ipairs = ipairs
local format, join = string.format, string.join
--WoW API / Variables
local GetInventoryItemDurability = GetInventoryItemDurability
local GetInventorySlotInfo = GetInventorySlotInfo
local ToggleCharacter = ToggleCharacter
local DURABILITY = DURABILITY
local displayString = ""
local tooltipString = "%d%%"
local lastPanel
local totalDurability, current, maxDur
local invDurability = {}
local slots = {
"HeadSlot",
"ShoulderSlot",
"ChestSlot",
"WristSlot",
"HandsSlot",
"WaistSlot",
"LegsSlot",
"FeetSlot",
"MainHandSlot",
"SecondaryHandSlot",
"RangedSlot",
}
local slotsLocales = {
["HeadSlot"] = HEADSLOT,
["ShoulderSlot"] = SHOULDERSLOT,
["ChestSlot"] = CHESTSLOT,
["WristSlot"] = WRISTSLOT,
["HandsSlot"] = HANDSSLOT,
["WaistSlot"] = WAISTSLOT,
["LegsSlot"] = LEGSSLOT,
["FeetSlot"] = FEETSLOT,
["MainHandSlot"] = MAINHANDSLOT,
["SecondaryHandSlot"] = SECONDARYHANDSLOT,
["RangedSlot"] = RANGEDSLOT,
}
local function OnEvent(self)
lastPanel = self
totalDurability = 100
for _, sType in ipairs(slots) do
local slot = GetInventorySlotInfo(sType)
current, maxDur = GetInventoryItemDurability(slot)
if current then
invDurability[sType] = (current / maxDur) * 100
if invDurability[sType] < totalDurability then
totalDurability = invDurability[sType]
end
else
invDurability[sType] = nil
end
end
self.text:SetFormattedText(displayString, totalDurability)
end
local function OnClick()
ToggleCharacter("PaperDollFrame")
end
local function OnEnter(self)
DT:SetupTooltip(self)
for _, sType in ipairs(slots) do
if invDurability[sType] then
DT.tooltip:AddDoubleLine(slotsLocales[sType], format(tooltipString, invDurability[sType]), 1, 1, 1, E:ColorGradient(invDurability[sType] * 0.01, 1, 0, 0, 1, 1, 0, 0, 1, 0))
end
end
DT.tooltip:Show()
end
local function ValueColorUpdate(hex)
displayString = join("", DURABILITY, ": ", hex, "%d%%|r")
if lastPanel ~= nil then
OnEvent(lastPanel, "ELVUI_COLOR_UPDATE")
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Durability", {"PLAYER_ENTERING_WORLD", "UPDATE_INVENTORY_DURABILITY", "MERCHANT_SHOW"}, OnEvent, nil, OnClick, OnEnter, nil, DURABILITY)
+292
View File
@@ -0,0 +1,292 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local next = next
local find, format, join = string.find, string.format, string.join
local sort, wipe = table.sort, table.wipe
--WoW API / Variables
local EasyMenu = EasyMenu
local GetFriendInfo = GetFriendInfo
local GetMouseFocus = GetMouseFocus
local GetNumFriends = GetNumFriends
local GetQuestDifficultyColor = GetQuestDifficultyColor
local GetRealZoneText = GetRealZoneText
local InviteUnit = InviteUnit
local SendChatMessage = SendChatMessage
local SetItemRef = SetItemRef
local ToggleFriendsFrame = ToggleFriendsFrame
local UnitInParty = UnitInParty
local UnitInRaid = UnitInRaid
local UnitIsAFK = UnitIsAFK
local UnitIsDND = UnitIsDND
local AFK = AFK
local DND = DND
local FRIENDS = FRIENDS
local tthead = {r=0.4, g=0.78, b=1}
local activezone, inactivezone = {r=0.3, g=1.0, b=0.3}, {r=0.65, g=0.65, b=0.65}
local levelNameFormat = "|cff%02x%02x%02x%d|r |cff%02x%02x%02x%s|r %s"
local levelNameStatusFormat = "|cff%02x%02x%02x%d|r %s%s %s"
local onlineInfoFormat = join("", FRIENDS_LIST_ONLINE, ": %s/%s")
local afkStatusString = format("<%s>", AFK)
local dndStatusString = format("<%s>", DND)
local inGroupStamp = "|cffaaaaaa*|r"
local friendOnlineString = string.gsub(ERR_FRIEND_ONLINE_SS, ".+|h", "")
local friendOfflineString = string.gsub(ERR_FRIEND_OFFLINE_S, "%%s", "")
local onlineStatusString = "|cffFFFFFF[|r|cff%s%s|r|cffFFFFFF]|r"
local onlineStatus = {
[""] = "",
[afkStatusString] = format(onlineStatusString, "FF9900", L["AFK"]),
[dndStatusString] = format(onlineStatusString, "FF3333", L["DND"]),
}
local displayString = ""
local lastPanel
local dataTable = {}
local dataUpdated
local menuFrame = CreateFrame("Frame", "FriendDatatextRightClickMenu", E.UIParent, "UIDropDownMenuTemplate")
local menuList = {
{text = OPTIONS_MENU, isTitle = true, notCheckable = true},
{text = INVITE, hasArrow = true, notCheckable = true, keepShownOnClick = true, noClickSound = true, menuList = {}},
{text = CHAT_MSG_WHISPER_INFORM, hasArrow = true, notCheckable = true, keepShownOnClick = true, noClickSound = true, menuList = {}},
{text = PLAYER_STATUS, hasArrow = true, notCheckable = true, keepShownOnClick = true, noClickSound = true,
menuList = {
{
text = format("|cff2BC226%s|r", AVAILABLE),
notCheckable = true,
func = function()
if UnitIsAFK("player") then
SendChatMessage("", "AFK")
elseif UnitIsDND("player") then
SendChatMessage("", "DND")
end
end
},
{
text = format("|cffE7E716%s|r", DND),
notCheckable = true,
func = function()
if not UnitIsDND("player") then
SendChatMessage("", "DND")
end
end
},
{
text = format("|cffFF0000%s|r", AFK),
notCheckable = true,
func = function()
if not UnitIsAFK("player") then
SendChatMessage("", "AFK")
end
end
}
}
}
}
local function inviteClick(_, playerName)
menuFrame:Hide()
InviteUnit(playerName)
end
local function whisperClick(_, playerName)
menuFrame:Hide()
SetItemRef("player:"..playerName, format("|Hplayer:%1$s|h[%1$s]|h", playerName), "LeftButton")
end
local function sortByName(a, b)
if a[1] and b[1] then
return a[1] < b[1]
end
end
local function BuildDataTable(total)
wipe(dataTable)
if total == 0 then return end
local name, level, class, area, connected, status, note, className
for i = 1, total do
name, level, class, area, connected, status, note = GetFriendInfo(i)
if connected then
className = E:UnlocalizedClassName(class) or ""
status = onlineStatus[status] or ""
dataTable[i] = {name, level, className, area, connected, status, note}
end
end
if next(dataTable) then
sort(dataTable, sortByName)
end
end
local function OnClick(_, btn)
if btn == "RightButton" then
DT.tooltip:Hide()
wipe(menuList[2].menuList)
wipe(menuList[3].menuList)
local menuCountWhispers, menuCountInvites = 0, 0
local classc, levelc, info, grouped, shouldSkip
local db = E.db.datatexts.friends
for i = 1, #dataTable do
info = dataTable[i]
if info[5] then
if (info[6] == onlineStatus[afkStatusString]) and db.hideAFK then
shouldSkip = true
elseif (info[6] == onlineStatus[dndStatusString]) and db.hideDND then
shouldSkip = true
else
shouldSkip = nil
end
if not shouldSkip then
classc = E.media.herocolor
classc = classc or GetQuestDifficultyColor(info[2])
levelc = GetQuestDifficultyColor(info[2])
if UnitInParty(info[1]) or UnitInRaid(info[1]) then
grouped = inGroupStamp
else
grouped = ""
menuCountInvites = menuCountInvites + 1
menuList[2].menuList[menuCountInvites] = {
text = format(levelNameFormat, levelc.r*255, levelc.g*255, levelc.b*255, info[2], classc.r*255, classc.g*255, classc.b*255, info[1], grouped),
arg1 = info[1],
notCheckable = true,
func = inviteClick
}
end
menuCountWhispers = menuCountWhispers + 1
menuList[3].menuList[menuCountWhispers] = {
text = format(levelNameFormat, levelc.r*255, levelc.g*255, levelc.b*255, info[2], classc.r*255, classc.g*255, classc.b*255, info[1], grouped),
arg1 = info[1],
notCheckable = true,
func = whisperClick
}
end
end
end
menuList[2].disabled = menuCountInvites == 0
menuList[3].disabled = menuCountWhispers == 0
EasyMenu(menuList, menuFrame, "cursor", 0, 0, "MENU", 2)
else
ToggleFriendsFrame(1)
end
end
local function OnEnter(self)
local numberOfFriends, onlineFriends = GetNumFriends()
if onlineFriends == 0 then return end
DT:SetupTooltip(self)
if not dataUpdated then
if numberOfFriends > 0 then
BuildDataTable(numberOfFriends)
end
dataUpdated = true
end
DT.tooltip:AddDoubleLine(
L["Friends List"],
format(onlineInfoFormat, onlineFriends, numberOfFriends),
tthead.r, tthead.g, tthead.b,
tthead.r, tthead.g, tthead.b
)
local playerZone = GetRealZoneText()
local db = E.db.datatexts.friends
local zonec, classc, levelc, info, grouped, shouldSkip
for i = 1, #dataTable do
info = dataTable[i]
if info[5] then
if (info[6] == onlineStatus[afkStatusString]) and db.hideAFK then
shouldSkip = true
elseif (info[6] == onlineStatus[dndStatusString]) and db.hideDND then
shouldSkip = true
else
shouldSkip = nil
end
if not shouldSkip then
if playerZone == info[4] then
zonec = activezone
else
zonec = inactivezone
end
classc = E.media.herocolor
classc = classc or GetQuestDifficultyColor(info[2])
levelc = GetQuestDifficultyColor(info[2])
if UnitInParty(info[1]) or UnitInRaid(info[1]) then
grouped = inGroupStamp
else
grouped = ""
end
DT.tooltip:AddDoubleLine(
format(levelNameStatusFormat, levelc.r*255, levelc.g*255, levelc.b*255, info[2], info[1], grouped, info[6]),
info[4],
classc.r, classc.g, classc.b,
zonec.r, zonec.g, zonec.b
)
end
end
end
DT.tooltip:Show()
end
local function OnEvent(self, event, message)
lastPanel = self
-- special handler to detect friend coming online or going offline
if event == "CHAT_MSG_SYSTEM" then
if not (find(message, friendOnlineString) or find(message, friendOfflineString)) then return end
end
local _, onlineFriends = GetNumFriends()
self.text:SetFormattedText(displayString, onlineFriends)
-- force update when showing tooltip
dataUpdated = nil
if GetMouseFocus() == self then
self:GetScript("OnEnter")(self)
end
end
local function ValueColorUpdate(hex)
displayString = join("", FRIENDS, ": ", hex, "%d|r")
if lastPanel ~= nil then
OnEvent(lastPanel, "ELVUI_COLOR_UPDATE")
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Friends", {"PLAYER_ENTERING_WORLD", "CHAT_MSG_SYSTEM", "FRIENDLIST_UPDATE"}, OnEvent, nil, OnClick, OnEnter, nil, FRIENDS)
+164
View File
@@ -0,0 +1,164 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local pairs = pairs
local format = string.format
local tinsert, wipe = tinsert, wipe
--WoW API / Variables
local GetBackpackCurrencyInfo = GetBackpackCurrencyInfo
local GetMoney = GetMoney
local IsLoggedIn = IsLoggedIn
local IsShiftKeyDown = IsShiftKeyDown
local CURRENCY = CURRENCY
local MAX_WATCHED_TOKENS = MAX_WATCHED_TOKENS
local currencyString = "|T%s:14:14:0:0:64:64:4:60:4:60|t %s"
local resetCountersFormatter = string.join("", "|cffaaaaaa", L["Reset Counters: Hold Shift + Left Click"], "|r")
local resetDataFormatter = string.join("", "|cffaaaaaa", L["Reset Data: Hold Shift + Right Click"], "|r")
local dataTable = {}
local dataUpdated
local myDataID
local totalGold = 0
local altGold = 0
local profit = 0
local spent = 0
local function BuildDataTable()
wipe(dataTable)
for charName in pairs(ElvDB.gold[E.myrealm]) do
if ElvDB.gold[E.myrealm][charName] then
local color = E.media.herocolor
tinsert(dataTable,
{
name = charName,
amount = ElvDB.gold[E.myrealm][charName],
amountText = E:FormatMoney(ElvDB.gold[E.myrealm][charName], E.db.datatexts.goldFormat or "BLIZZARD", not E.db.datatexts.goldCoins),
r = color.r, g = color.g, b = color.b,
}
)
if charName == E.myname then
myDataID = #dataTable
else
altGold = altGold + ElvDB.gold[E.myrealm][charName]
end
end
end
end
local function OnEvent(self, event)
if not IsLoggedIn() then return end
local curMoney = GetMoney()
if not dataUpdated and (event == "PLAYER_ENTERING_WORLD" or event == "ELVUI_FORCE_RUN") then
ElvDB.gold = ElvDB.gold or {}
ElvDB.gold[E.myrealm] = ElvDB.gold[E.myrealm] or {}
ElvDB.gold[E.myrealm][E.myname] = ElvDB.gold[E.myrealm][E.myname] or curMoney
ElvDB.class = ElvDB.class or {}
ElvDB.class[E.myrealm] = ElvDB.class[E.myrealm] or {}
ElvDB.class[E.myrealm][E.myname] = E.myclass
BuildDataTable()
dataUpdated = true
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
end
local oldMoney = ElvDB.gold[E.myrealm][E.myname]
if oldMoney > curMoney then
spent = spent - (curMoney - oldMoney)
else
profit = profit + (curMoney - oldMoney)
end
ElvDB.gold[E.myrealm][E.myname] = curMoney
totalGold = altGold + curMoney
local formattedMoney = E:FormatMoney(curMoney, E.db.datatexts.goldFormat or "BLIZZARD", not E.db.datatexts.goldCoins)
dataTable[myDataID].amount = curMoney
dataTable[myDataID].amountText = formattedMoney
self.text:SetText(formattedMoney)
end
local function OnEnter(self)
DT:SetupTooltip(self)
local style = E.db.datatexts.goldFormat or "BLIZZARD"
local textOnly = not E.db.datatexts.goldCoins
DT.tooltip:AddLine(L["Session:"])
DT.tooltip:AddDoubleLine(L["Earned:"], E:FormatMoney(profit, style, textOnly), 1, 1, 1, 1, 1, 1)
DT.tooltip:AddDoubleLine(L["Spent:"], E:FormatMoney(spent, style, textOnly), 1, 1, 1, 1, 1, 1)
if profit < spent then
DT.tooltip:AddDoubleLine(L["Deficit:"], E:FormatMoney(profit - spent, style, textOnly), 1, 0, 0, 1, 1, 1)
elseif (profit - spent) > 0 then
DT.tooltip:AddDoubleLine(L["Profit:"], E:FormatMoney(profit - spent, style, textOnly), 0, 1, 0, 1, 1, 1)
end
DT.tooltip:AddLine(" ")
DT.tooltip:AddLine(L["Character: "])
for _, g in ipairs(dataTable) do
DT.tooltip:AddDoubleLine(g.name == E.myname and g.name.." |TInterface\\FriendsFrame\\StatusIcon-Online:14|t" or g.name, g.amountText, g.r, g.g, g.b, 1, 1, 1)
end
DT.tooltip:AddLine(" ")
DT.tooltip:AddLine(L["Server: "])
DT.tooltip:AddDoubleLine(L["Total: "], E:FormatMoney(totalGold, style, textOnly), 1, 1, 1, 1, 1, 1)
local name, count, currencyType, icon
for i = 1, MAX_WATCHED_TOKENS do
name, count, currencyType, icon = GetBackpackCurrencyInfo(i)
if name and i == 1 then
DT.tooltip:AddLine(" ")
DT.tooltip:AddLine(CURRENCY..":")
end
if name and count then
if currencyType == 1 then
icon = "Interface\\PVPFrame\\PVP-ArenaPoints-Icon"
elseif currencyType == 2 then
icon = "Interface\\PVPFrame\\PVP-Currency-"..E.myfaction
end
DT.tooltip:AddDoubleLine(format(currencyString, icon, name), count, 1, 1, 1)
end
end
DT.tooltip:AddLine(" ")
DT.tooltip:AddLine(resetCountersFormatter)
DT.tooltip:AddLine(resetDataFormatter)
DT.tooltip:Show()
end
local function OnClick(self, btn)
if btn == "RightButton" and IsShiftKeyDown() then
ElvDB.gold = nil
dataUpdated = nil
OnEvent(self, "PLAYER_ENTERING_WORLD")
OnEnter(self)
elseif btn == "LeftButton" then
if IsShiftKeyDown() then
profit = 0
spent = 0
OnEnter(self)
else
OpenAllBags()
end
end
end
DT:RegisterDatatext("Gold", {"PLAYER_ENTERING_WORLD", "PLAYER_MONEY", "SEND_MAIL_MONEY_CHANGED", "SEND_MAIL_COD_CHANGED", "PLAYER_TRADE_MONEY", "TRADE_MONEY_CHANGED"}, OnEvent, nil, OnClick, OnEnter, nil, L["Gold"])
+328
View File
@@ -0,0 +1,328 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local find, format, join = string.find, string.format, string.join
local sort, wipe = table.sort, table.wipe
--WoW API / Variables
local EasyMenu = EasyMenu
local GetGuildInfo = GetGuildInfo
local GetGuildRosterInfo = GetGuildRosterInfo
local GetGuildRosterMOTD = GetGuildRosterMOTD
local GetMouseFocus = GetMouseFocus
local GetNumGuildMembers = GetNumGuildMembers
local GetQuestDifficultyColor = GetQuestDifficultyColor
local GetRealZoneText = GetRealZoneText
local GuildRoster = GuildRoster
local InviteUnit = InviteUnit
local IsInGuild = IsInGuild
local IsShiftKeyDown = IsShiftKeyDown
local SetItemRef = SetItemRef
local ToggleFriendsFrame = ToggleFriendsFrame
local UnitInParty = UnitInParty
local UnitInRaid = UnitInRaid
local GUILD = GUILD
local GUILD_MOTD = GUILD_MOTD
local tthead, ttsubh, ttoff = {r=0.4, g=0.78, b=1}, {r=0.75, g=0.9, b=1}, {r=0.3,g=1,b=0.3}
local activezone, inactivezone = {r=0.3, g=1.0, b=0.3}, {r=0.65, g=0.65, b=0.65}
local levelNameFormat = "|cff%02x%02x%02x%d|r |cff%02x%02x%02x%s|r %s"
local levelNameStatusFormat = "|cff%02x%02x%02x%d|r %s%s"
local onlineInfoFormat = join("", GUILD, ": %d/%d")
local guildMotDFormat = "%s |cffaaaaaa- |cffffffff%s"
local moreMembersOnlineFormat = join("", "+ %d ", FRIENDS_LIST_ONLINE, "...")
local nameRankFormat = "%s |cff999999-|cffffffff %s"
local noteFormat = join("", "|cff999999 ", LABEL_NOTE, ":|r %s")
local officerNoteFormat = join("", "|cff999999 ", GUILD_RANK1_DESC, ":|r %s")
local inGroupStamp = "|cffaaaaaa*|r"
local friendOnlineString = select(2, string.split(" ", ERR_FRIEND_ONLINE_SS, 2))
local friendOfflineString = select(2, string.split(" ", ERR_FRIEND_OFFLINE_S, 2))
local onlineStatusString = "|cffFFFFFF[|r|cffFF0000%s|r|cffFFFFFF]|r"
local onlineStatus = {
[0] = "",
[1] = format(onlineStatusString, L["AFK"]),
[2] = format(onlineStatusString, L["DND"]),
}
local displayString = ""
local noGuildString = ""
local lastPanel
local dataTable = {}
local guildMotD = ""
local currentSortMode = false
local dataUpdated
local rosterDelay
local totalOnline = 0
local totalMembers = 0
local menuFrame = CreateFrame("Frame", "GuildDatatTextRightClickMenu", E.UIParent, "UIDropDownMenuTemplate")
local menuList = {
{text = OPTIONS_MENU, isTitle = true, notCheckable = true},
{text = INVITE, hasArrow = true, notCheckable = true, keepShownOnClick = true, noClickSound = true, menuList = {}},
{text = CHAT_MSG_WHISPER_INFORM, hasArrow = true, notCheckable = true, keepShownOnClick = true, noClickSound = true, menuList = {}}
}
local function inviteClick(_, playerName)
menuFrame:Hide()
InviteUnit(playerName)
end
local function whisperClick(_, playerName)
menuFrame:Hide()
SetItemRef("player:"..playerName, format("|Hplayer:%1$s|h[%1$s]|h", playerName), "LeftButton")
end
local function sortByRank(a, b)
if a and b then
return a[10] < b[10]
end
end
local function sortByName(a, b)
if a and b then
return a[1] < b[1]
end
end
local function SortDataTable(shiftKeyDown)
if currentSortMode == shiftKeyDown and not dataUpdated then return end
if shiftKeyDown then
sort(dataTable, sortByRank)
else
sort(dataTable, sortByName)
end
currentSortMode = shiftKeyDown
dataUpdated = nil
end
local function BuildDataTable()
wipe(dataTable)
totalMembers = GetNumGuildMembers()
totalOnline = 0
local _, name, rank, rankIndex, level, zone, note, officernote, connected, status, englishClass
for i = 1, totalMembers do
name, rank, rankIndex, level, _, zone, note, officernote, connected, status, englishClass = GetGuildRosterInfo(i)
if not name then break end
if connected then
totalOnline = totalOnline + 1
dataTable[#dataTable + 1] = {name, rank, level, zone, note, officernote, connected, onlineStatus[status], englishClass, rankIndex}
end
end
dataUpdated = true
end
local function OnClick(_, btn)
if btn == "RightButton" and IsInGuild() then
if totalOnline <= 1 then return end
DT.tooltip:Hide()
wipe(menuList[2].menuList)
wipe(menuList[3].menuList)
local menuCountWhispers, menuCountInvites = 0, 0
local classc, levelc, info, grouped
for i = 1, #dataTable do
info = dataTable[i]
if info[7] and info[1] ~= E.myname then
classc = E.media.herocolor
levelc = GetQuestDifficultyColor(info[3])
if UnitInParty(info[1]) or UnitInRaid(info[1]) then
grouped = inGroupStamp
else
grouped = ""
menuCountInvites = menuCountInvites + 1
menuList[2].menuList[menuCountInvites] = {
text = format(levelNameFormat, levelc.r*255,levelc.g*255,levelc.b*255, info[3], classc.r*255,classc.g*255,classc.b*255, info[1], grouped),
arg1 = info[1],
notCheckable = true,
func = inviteClick
}
end
menuCountWhispers = menuCountWhispers + 1
menuList[3].menuList[menuCountWhispers] = {
text = format(levelNameFormat, levelc.r*255,levelc.g*255,levelc.b*255, info[3], classc.r*255,classc.g*255,classc.b*255, info[1], grouped),
arg1 = info[1],
notCheckable = true,
func = whisperClick
}
end
end
menuList[2].disabled = menuCountInvites == 0
menuList[3].disabled = menuCountWhispers == 0
EasyMenu(menuList, menuFrame, "cursor", 0, 0, "MENU", 2)
else
ToggleFriendsFrame(3)
end
end
local function OnEnter(self, _, noUpdate)
if not IsInGuild() then return end
DT:SetupTooltip(self)
if totalOnline == 0 then
BuildDataTable()
end
local guildName, guildRank = GetGuildInfo("player")
local playerZone = GetRealZoneText()
local shiftKeyDown = IsShiftKeyDown()
local zonec, classc, levelc, info, grouped
local shown = 0
if totalOnline > 1 then
SortDataTable(shiftKeyDown)
end
if guildName and guildRank then
DT.tooltip:AddDoubleLine(
guildName,
format(onlineInfoFormat, totalOnline, totalMembers),
tthead.r, tthead.g, tthead.b,
tthead.r, tthead.g, tthead.b
)
DT.tooltip:AddLine(guildRank, tthead.r,tthead.g,tthead.b)
end
if guildMotD ~= "" then
DT.tooltip:AddLine(" ")
DT.tooltip:AddLine(format(guildMotDFormat, GUILD_MOTD, guildMotD), ttsubh.r, ttsubh.g, ttsubh.b, 1)
end
DT.tooltip:AddLine(" ")
for i = 1, #dataTable do
info = dataTable[i]
if playerZone == info[4] then
zonec = activezone
else
zonec = inactivezone
end
classc = E.media.herocolor
if shiftKeyDown then
DT.tooltip:AddDoubleLine(
format(nameRankFormat, info[1], info[2]),
info[4],
classc.r, classc.g, classc.b,
zonec.r, zonec.g, zonec.b
)
if info[5] ~= "" then
DT.tooltip:AddLine(format(noteFormat, info[5]), ttsubh.r, ttsubh.g, ttsubh.b, 1)
end
if info[6] ~= "" then
DT.tooltip:AddLine(format(officerNoteFormat, info[6]), ttoff.r, ttoff.g, ttoff.b, 1)
end
else
levelc = GetQuestDifficultyColor(info[3])
if UnitInParty(info[1]) or UnitInRaid(info[1]) then
grouped = inGroupStamp
else
grouped = ""
end
DT.tooltip:AddDoubleLine(
format(levelNameStatusFormat, levelc.r*255, levelc.g*255, levelc.b*255, info[3], info[1], grouped, info[8]),
info[4],
classc.r, classc.g, classc.b,
zonec.r, zonec.g, zonec.b
)
end
shown = shown + 1
if shown == 30 then
if totalOnline > 30 then
DT.tooltip:AddLine(format(moreMembersOnlineFormat, totalOnline - 30), ttsubh.r, ttsubh.g, ttsubh.b)
end
break
end
end
DT.tooltip:Show()
if not noUpdate then
GuildRoster()
end
end
local eventHandlers = {
["ELVUI_FORCE_RUN"] = function(self)
guildMotD = GetGuildRosterMOTD()
GuildRoster()
end,
["GUILD_MOTD"] = function(_, message)
guildMotD = message
end,
["CHAT_MSG_SYSTEM"] = function(_, message)
if rosterDelay then return end
if find(message, friendOnlineString) or find(message, friendOfflineString) then
rosterDelay = E:Delay(10, function()
GuildRoster()
rosterDelay = nil
end)
end
end,
["GUILD_ROSTER_UPDATE"] = function(self)
GuildRoster()
BuildDataTable()
if GetMouseFocus() == self then
self:GetScript("OnEnter")(self, nil, true)
end
end,
["PLAYER_GUILD_UPDATE"] = GuildRoster,
["ELVUI_COLOR_UPDATE"] = E.noop,
}
local function OnEvent(self, event, ...)
lastPanel = self
if IsInGuild() then
eventHandlers[event](self, ...)
self.text:SetFormattedText(displayString, totalOnline)
else
self.text:SetText(noGuildString)
end
end
local function ValueColorUpdate(hex)
displayString = join("", GUILD, ": ", hex, "%d|r")
noGuildString = join("", hex, L["No Guild"])
if lastPanel ~= nil then
OnEvent(lastPanel, "ELVUI_COLOR_UPDATE")
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Guild", {"CHAT_MSG_SYSTEM", "GUILD_ROSTER_UPDATE", "PLAYER_GUILD_UPDATE", "GUILD_MOTD"}, OnEvent, nil, OnClick, OnEnter, nil, GUILD)
+87
View File
@@ -0,0 +1,87 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local select = select
local time = time
local max = math.max
local join = string.join
--WoW API / Variables
local UnitGUID = UnitGUID
local events = {SPELL_HEAL = true, SPELL_PERIODIC_HEAL = true}
local playerID, petID
local healTotal, lastHealAmount = 0, 0
local combatTime = 0
local timeStamp = 0
local lastSegment = 0
local lastPanel
local displayString = ""
local function Reset()
timeStamp = 0
combatTime = 0
healTotal = 0
lastHealAmount = 0
end
local function GetHPS(self)
local hps
if healTotal == 0 or combatTime == 0 then
hps = 0
else
hps = healTotal / combatTime
end
self.text:SetFormattedText(displayString, E:ShortValue(hps))
end
local function OnEvent(self, event, ...)
lastPanel = self
if event == "PLAYER_REGEN_DISABLED" or event == "PLAYER_LEAVE_COMBAT" then
local now = time()
if now - lastSegment > 20 then
Reset()
end
lastSegment = now
elseif event == "COMBAT_LOG_EVENT_UNFILTERED" then
if not events[select(2, ...)] then return end
local id = select(3, ...)
if id == playerID or id == petID then
if timeStamp == 0 then
timeStamp = ...
end
lastSegment = timeStamp
combatTime = (...) - timeStamp
local overHeal = select(13, ...)
lastHealAmount = select(12, ...)
healTotal = healTotal + max(0, lastHealAmount - overHeal)
end
elseif event == "UNIT_PET" then
petID = UnitGUID("pet")
elseif event == "PLAYER_ENTERING_WORLD" then
playerID = E.myguid
self:UnregisterEvent(event)
end
GetHPS(self)
end
local function OnClick(self)
Reset()
GetHPS(self)
end
local function ValueColorUpdate(hex)
displayString = join("", L["HPS"], ": ", hex, "%s")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("HPS", {"PLAYER_ENTERING_WORLD", "COMBAT_LOG_EVENT_UNFILTERED", "PLAYER_LEAVE_COMBAT", "PLAYER_REGEN_DISABLED", "UNIT_PET"}, OnEvent, nil, OnClick, nil, nil, L["HPS"])
+76
View File
@@ -0,0 +1,76 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local format, join = string.format, string.join
--WoW API / Variables
local GetCombatRating = GetCombatRating
local GetCombatRatingBonus = GetCombatRatingBonus
local UnitAttackSpeed = UnitAttackSpeed
local UnitRangedDamage = UnitRangedDamage
local ATTACK_SPEED = ATTACK_SPEED
local CR_HASTE_MELEE = CR_HASTE_MELEE
local CR_HASTE_RANGED = CR_HASTE_RANGED
local CR_HASTE_RATING_TOOLTIP = CR_HASTE_RATING_TOOLTIP
local CR_HASTE_SPELL = CR_HASTE_SPELL
local PAPERDOLLFRAME_TOOLTIP_FORMAT = PAPERDOLLFRAME_TOOLTIP_FORMAT
local SPELL_HASTE = SPELL_HASTE
local SPELL_HASTE_ABBR = SPELL_HASTE_ABBR
local SPELL_HASTE_TOOLTIP = SPELL_HASTE_TOOLTIP
local hasteRating
local displayNumberString = ""
local lastPanel
local function OnEvent(self)
lastPanel = self
if E.Role == "Caster" then
hasteRating = GetCombatRating(CR_HASTE_SPELL)
elseif E.Role == "Ranged" then
hasteRating = GetCombatRating(CR_HASTE_RANGED)
else
hasteRating = GetCombatRating(CR_HASTE_MELEE)
end
self.text:SetFormattedText(displayNumberString, hasteRating)
end
local function OnEnter(self)
DT:SetupTooltip(self)
local text, tooltip
if E.Role == "Caster" then
text = format("%s %d", SPELL_HASTE, hasteRating)
tooltip = format(SPELL_HASTE_TOOLTIP, GetCombatRatingBonus(CR_HASTE_SPELL))
elseif E.Role == "Ranged" then
text = format("%s %.2f", format(PAPERDOLLFRAME_TOOLTIP_FORMAT, ATTACK_SPEED), UnitRangedDamage("player"))
tooltip = format(CR_HASTE_RATING_TOOLTIP, hasteRating, GetCombatRatingBonus(CR_HASTE_RANGED))
else
local speed, offhandSpeed = UnitAttackSpeed("player")
if offhandSpeed then
text = format("%s %.2f / %.2f", format(PAPERDOLLFRAME_TOOLTIP_FORMAT, ATTACK_SPEED), speed, offhandSpeed)
else
text = format("%s %.2f", format(PAPERDOLLFRAME_TOOLTIP_FORMAT, ATTACK_SPEED), speed)
end
tooltip = format(CR_HASTE_RATING_TOOLTIP, hasteRating, GetCombatRatingBonus(CR_HASTE_MELEE))
end
DT.tooltip:AddLine(text, 1, 1, 1)
DT.tooltip:AddLine(tooltip, nil, nil, nil, 1)
DT.tooltip:Show()
end
local function ValueColorUpdate(hex)
displayNumberString = join("", SPELL_HASTE_ABBR, ": ", hex, "%d|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Haste", {"ACTIVE_TALENT_GROUP_CHANGED", "PLAYER_TALENT_UPDATE", "UNIT_ATTACK_SPEED", "UNIT_SPELL_HASTE"}, OnEvent, nil, nil, OnEnter, nil, SPELL_HASTE)
+40
View File
@@ -0,0 +1,40 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local join = string.join
--WoW API / Variables
local GetCombatRatingBonus = GetCombatRatingBonus
local CR_HIT_MELEE = CR_HIT_MELEE
local CR_HIT_RANGED = CR_HIT_RANGED
local CR_HIT_SPELL = CR_HIT_SPELL
local STAT_HIT_CHANCE = STAT_HIT_CHANCE
local hitRatingBonus
local displayString = ""
local lastPanel
local function OnEvent(self)
lastPanel = self
if E.Role == "Caster" then
hitRatingBonus = GetCombatRatingBonus(CR_HIT_SPELL)
elseif E.Role == "Ranged" then
hitRatingBonus = GetCombatRatingBonus(CR_HIT_RANGED)
else
hitRatingBonus = GetCombatRatingBonus(CR_HIT_MELEE)
end
self.text:SetFormattedText(displayString, hitRatingBonus)
end
local function ValueColorUpdate(hex)
displayString = join("", L["Hit"], ": ", hex, "%.2f%%|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Hit", {"ACTIVE_TALENT_GROUP_CHANGED", "PLAYER_TALENT_UPDATE", "COMBAT_RATING_UPDATE"}, OnEvent, nil, nil, nil, nil, STAT_HIT_CHANCE)
@@ -0,0 +1,27 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local join = string.join
--WoW API / Variables
local GetPVPLifetimeStats = GetPVPLifetimeStats
local KILLS = KILLS
local lastPanel
local displayNumberString = ""
local function OnEvent(self)
lastPanel = self
self.text:SetFormattedText(displayNumberString, (GetPVPLifetimeStats()))
end
local function ValueColorUpdate(hex)
displayNumberString = join("", KILLS, ": ", hex, "%d|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Honorable Kills", {"PLAYER_PVP_KILLS_CHANGED", "PLAYER_PVP_RANK_CHANGED"}, OnEvent, nil, nil, nil, nil, HONORABLE_KILLS)
@@ -0,0 +1,27 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="DataTexts.lua"/>
<Script file="System.lua"/>
<Script file="Armor.lua"/>
<Script file="Avoidance.lua"/>
<Script file="Bags.lua"/>
<Script file="CombatTime.lua"/>
<Script file="Coordinates.lua"/>
<Script file="Crit.lua"/>
<Script file="DPS.lua"/>
<Script file="Durability.lua"/>
<Script file="Friends.lua"/>
<Script file="Guild.lua"/>
<Script file="Haste.lua"/>
<Script file="Hit.lua"/>
<Script file="HonorableKills.lua"/>
<Script file="HPS.lua"/>
<Script file="Regen.lua"/>
<Script file="Time.lua"/>
<Script file="Gold.lua"/>
<Script file="AttackPower.lua"/>
<Script file="SpellPower.lua"/>
<Script file="Battleground.lua"/>
<Script file="Resilience.lua"/>
<Script file="Achievement.lua"/>
<Script file="ConfigElvUI.lua"/>
</Ui>
+35
View File
@@ -0,0 +1,35 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local join = string.join
--WoW API / Variables
local InCombatLockdown = InCombatLockdown
local GetManaRegen = GetManaRegen
local MANA_REGEN = MANA_REGEN
local displayNumberString = ""
local lastPanel
local function OnEvent(self)
lastPanel = self
local baseMR, castingMR = GetManaRegen()
if InCombatLockdown() then
self.text:SetFormattedText(displayNumberString, castingMR * 5)
else
self.text:SetFormattedText(displayNumberString, baseMR * 5)
end
end
local function ValueColorUpdate(hex)
displayNumberString = join("", MANA_REGEN, ": ", hex, "%d|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Mana Regen", {"PLAYER_DAMAGE_DONE_MODS", "PLAYER_REGEN_DISABLED", "PLAYER_REGEN_ENABLED"}, OnEvent, nil, nil, nil, nil, MANA_REGEN)
+39
View File
@@ -0,0 +1,39 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local min = math.min
local join = string.join
--WoW API / Variables
local GetCombatRating = GetCombatRating
local CR_CRIT_TAKEN_MELEE = CR_CRIT_TAKEN_MELEE
local CR_CRIT_TAKEN_RANGED = CR_CRIT_TAKEN_RANGED
local CR_CRIT_TAKEN_SPELL = CR_CRIT_TAKEN_SPELL
local STAT_RESILIENCE = STAT_RESILIENCE
local displayNumberString = ""
local lastPanel
local function OnEvent(self)
lastPanel = self
local melee = GetCombatRating(CR_CRIT_TAKEN_MELEE)
local ranged = GetCombatRating(CR_CRIT_TAKEN_RANGED)
local spell = GetCombatRating(CR_CRIT_TAKEN_SPELL)
local minResilience = min(melee, ranged)
minResilience = min(minResilience, spell)
self.text:SetFormattedText(displayNumberString, minResilience)
end
local function ValueColorUpdate(hex)
displayNumberString = join("", STAT_RESILIENCE, ": ", hex, "%d|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Resilience", {"COMBAT_RATING_UPDATE"}, OnEvent, nil, nil, nil, nil, STAT_RESILIENCE)
+34
View File
@@ -0,0 +1,34 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local join = string.join
--WoW API / Variables
local GetSpellBonusDamage = GetSpellBonusDamage
local GetSpellBonusHealing = GetSpellBonusHealing
local displayNumberString = ""
local lastPanel
local function OnEvent(self)
local spellDamage = GetSpellBonusDamage(7)
local spellHealing = GetSpellBonusHealing()
if spellHealing > spellDamage then
self.text:SetFormattedText(displayNumberString, L["HP"], spellHealing)
else
self.text:SetFormattedText(displayNumberString, L["SP"], spellDamage)
end
lastPanel = self
end
local function ValueColorUpdate(hex)
displayNumberString = join("", "%s: ", hex, "%d|r")
if lastPanel ~= nil then
OnEvent(lastPanel)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Spell/Heal Power", {"PLAYER_DAMAGE_DONE_MODS"}, OnEvent, nil, nil, nil, nil, L["Spell/Heal Power"])
+231
View File
@@ -0,0 +1,231 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local collectgarbage = collectgarbage
local floor = math.floor
local format = string.format
local tinsert, sort = table.insert, table.sort
--WoW API / Variables
local CopyTable = CopyTable
local GetAddOnCPUUsage = GetAddOnCPUUsage
local GetAddOnInfo = GetAddOnInfo
local GetAddOnMemoryUsage = GetAddOnMemoryUsage
local GetFramerate = GetFramerate
local GetNetStats = GetNetStats
local GetNumAddOns = GetNumAddOns
local HideUIPanel = HideUIPanel
local IsAddOnLoaded = IsAddOnLoaded
local IsModifierKeyDown = IsModifierKeyDown
local IsShiftKeyDown = IsShiftKeyDown
local PlaySound = PlaySound
local ResetCPUUsage = ResetCPUUsage
local ShowUIPanel = ShowUIPanel
local UpdateAddOnCPUUsage = UpdateAddOnCPUUsage
local UpdateAddOnMemoryUsage = UpdateAddOnMemoryUsage
local cpuProfiling = GetCVar("scriptProfile") == "1"
local int = 5 -- initial delay
local statusColors = {
"|cff0CD809",
"|cffE8DA0F",
"|cffFF9000",
"|cffD80909"
}
local enteredFrame
local homeLatencyString = "%d ms"
local kiloByteString = "%d kb"
local megaByteString = "%.2f mb"
local memoryTable = {}
local cpuTable = {}
local lodTable = {}
local disabledTable = {}
local initialized
local function OnEvent(self, event, addonName)
if event == "ADDON_LOADED" then
if lodTable[addonName] then
tinsert(memoryTable, lodTable[addonName])
if cpuProfiling then
tinsert(cpuTable, CopyTable(lodTable[addonName]))
end
lodTable[addonName] = nil
elseif disabledTable[addonName] then
tinsert(memoryTable, disabledTable[addonName])
if cpuProfiling then
tinsert(cpuTable, CopyTable(disabledTable[addonName]))
end
disabledTable[addonName] = nil
end
elseif not initialized and (event == "PLAYER_ENTERING_WORLD" or event == "ELVUI_FORCE_RUN") then
local _, name, title, enabled, loadable
for i = 1, GetNumAddOns() do
name, title, _, enabled, loadable = GetAddOnInfo(i)
if IsAddOnLoaded(i) then
tinsert(memoryTable, {i, title, 0})
if cpuProfiling then
tinsert(cpuTable, {i, title, 0})
end
elseif loadable then
lodTable[name] = {i, title, 0}
elseif not enabled then
disabledTable[name] = {i, title, 0}
end
end
initialized = true
self:UnregisterEvent(event)
elseif initialized and event == "ELVUI_FORCE_RUN" then
local name
for i = 1, GetNumAddOns() do
name = GetAddOnInfo(i)
if (lodTable[name] or disabledTable[name]) and IsAddOnLoaded(i) then
OnEvent(self, "ADDON_LOADED", name)
end
end
end
end
local function formatMem(memory)
if memory > 999 then
return format(megaByteString, memory / 1024)
else
return format(kiloByteString, memory)
end
end
local function sortByMemoryOrCPU(a, b)
if a and b then
return (a[3] == b[3] and a[2] < b[2]) or a[3] > b[3]
end
end
local function UpdateMemory()
UpdateAddOnMemoryUsage()
local totalMemory = 0
for i = 1, #memoryTable do
memoryTable[i][3] = GetAddOnMemoryUsage(memoryTable[i][1])
totalMemory = totalMemory + memoryTable[i][3]
end
sort(memoryTable, sortByMemoryOrCPU)
return totalMemory
end
local function UpdateCPU()
UpdateAddOnCPUUsage()
local totalCPU = 0
for i = 1, #cpuTable do
cpuTable[i][3] = GetAddOnCPUUsage(cpuTable[i][1])
totalCPU = totalCPU + cpuTable[i][3]
end
sort(cpuTable, sortByMemoryOrCPU)
return totalCPU
end
local function ToggleGameMenuFrame()
if GameMenuFrame:IsShown() then
PlaySound("igMainMenuQuit")
HideUIPanel(GameMenuFrame)
else
PlaySound("igMainMenuOpen")
ShowUIPanel(GameMenuFrame)
end
end
local function OnClick(_, btn)
if IsModifierKeyDown() then
collectgarbage("collect")
ResetCPUUsage()
elseif btn == "LeftButton" then
ToggleGameMenuFrame()
end
end
local function OnEnter(self)
DT:SetupTooltip(self)
local totalMemory = UpdateMemory()
local _, _, homeLatency = GetNetStats()
DT.tooltip:AddDoubleLine(L["Home Latency:"], format(homeLatencyString, homeLatency), 0.69, 0.31, 0.31, 0.84, 0.75, 0.65)
DT.tooltip:AddDoubleLine(L["Total Memory:"], formatMem(totalMemory), 0.69, 0.31, 0.31, 0.84, 0.75, 0.65)
local totalCPU
if cpuProfiling then
totalCPU = UpdateCPU()
DT.tooltip:AddDoubleLine(L["Total CPU:"], format(homeLatencyString, totalCPU), 0.69, 0.31, 0.31, 0.84, 0.75, 0.65)
end
DT.tooltip:AddLine(" ")
local addon, red, green
if IsShiftKeyDown() or not cpuProfiling then
for i = 1, #memoryTable do
addon = memoryTable[i]
red = addon[3] / totalMemory
green = 1 - red
DT.tooltip:AddDoubleLine(addon[2], formatMem(addon[3]), 1, 1, 1, red, green + .5, 0)
end
else
for i = 1, #cpuTable do
addon = cpuTable[i]
red = addon[3] / totalCPU
green = 1 - red
DT.tooltip:AddDoubleLine(addon[2], format(homeLatencyString, addon[3]), 1, 1, 1, red, green + .5, 0)
end
DT.tooltip:AddLine(" ")
DT.tooltip:AddLine(L["(Hold Shift) Memory Usage"])
end
DT.tooltip:AddLine(L["(Modifer Click) Collect Garbage"])
DT.tooltip:Show()
enteredFrame = true
end
local function OnLeave()
enteredFrame = nil
DT.tooltip:Hide()
end
local function OnUpdate(self, t)
int = int - t
if int < 0 then
local framerate = floor(GetFramerate() + 0.5)
local _, _, homeLatency = GetNetStats()
self.text:SetFormattedText("FPS: %s%d|r MS: %s%d|r",
statusColors[framerate >= 30 and 1 or (framerate >= 20 and framerate < 30) and 2 or (framerate >= 10 and framerate < 20) and 3 or 4],
framerate,
statusColors[homeLatency < 150 and 1 or (homeLatency >= 150 and homeLatency < 300) and 2 or (homeLatency >= 300 and homeLatency < 500) and 3 or 4],
homeLatency)
int = 1
if enteredFrame then
OnEnter(self)
end
end
end
DT:RegisterDatatext("System", {"PLAYER_ENTERING_WORLD", "ADDON_LOADED"}, OnEvent, OnUpdate, OnClick, OnEnter, OnLeave, L["System"])
+275
View File
@@ -0,0 +1,275 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local DT = E:GetModule("DataTexts")
--Lua functions
local _G = _G
local date = date
local next = next
local select = select
local time = time
local tonumber = tonumber
local find, format, gsub, join, utf8sub = string.find, string.format, string.gsub, string.join, string.utf8sub
local tinsert, wipe = table.insert, table.wipe
--WoW API / Variables
local GetGameTime = GetGameTime
local GetNumSavedInstances = GetNumSavedInstances
local GetSavedInstanceInfo = GetSavedInstanceInfo
local GetWintergraspWaitTime = GetWintergraspWaitTime
local IsInInstance = IsInInstance
local RequestRaidInfo = RequestRaidInfo
local SecondsToTime = SecondsToTime
local QUEUE_TIME_UNAVAILABLE = QUEUE_TIME_UNAVAILABLE
local TIMEMANAGER_AM = TIMEMANAGER_AM
local TIMEMANAGER_PM = TIMEMANAGER_PM
local TIMEMANAGER_TOOLTIP_LOCALTIME = TIMEMANAGER_TOOLTIP_LOCALTIME
local TIMEMANAGER_TOOLTIP_REALMTIME = TIMEMANAGER_TOOLTIP_REALMTIME
local WINTERGRASP_IN_PROGRESS = WINTERGRASP_IN_PROGRESS
local timeDisplayFormat = ""
local dateDisplayFormat = ""
local lockoutInfoFormat = "%s%s %s |cffaaaaaa(%s)"
local lockoutColorExtended, lockoutColorNormal = {r = 0.3, g = 1, b = 0.3}, {r = .8, g = .8, b = .8}
local lockedInstances = {raids = {}, dungeons = {}}
local timeFormat, realmDiffSeconds, showAMPM, showSecs
local enteredFrame, fullUpdate
local instanceIconByName
local numSavedInstances = 0
local locale = GetLocale()
local krcntw = locale == "koKR" or locale == "zhCN" or locale == "zhTW"
local difficultyTag = { -- Normal, Normal, Heroic, Heroic
(krcntw and PLAYER_DIFFICULTY1) or utf8sub(PLAYER_DIFFICULTY1, 1, 1), -- N
(krcntw and PLAYER_DIFFICULTY1) or utf8sub(PLAYER_DIFFICULTY1, 1, 1), -- N
(krcntw and PLAYER_DIFFICULTY2) or utf8sub(PLAYER_DIFFICULTY2, 1, 1), -- H
(krcntw and PLAYER_DIFFICULTY2) or utf8sub(PLAYER_DIFFICULTY2, 1, 1), -- H
}
local function getRealmTimeDiff()
local hours, minutes = GetGameTime()
local localTime = date("*t")
local diffHours = localTime.hour - hours
local diffMinutes = localTime.min - minutes
return (diffHours * 60 + diffMinutes) * 60
end
local function GetCurrentDate(formatString, forceLocalTime, forceRealmTime)
if timeFormat ~= E.db.datatexts.timeFormat then
timeFormat = E.db.datatexts.timeFormat
showAMPM = find(E.db.datatexts.timeFormat, "%%p") ~= nil
showSecs = find(E.db.datatexts.timeFormat, "%%S") ~= nil
end
if showAMPM then
local localizedAMPM = tonumber(date("%H")) >= 12 and TIMEMANAGER_PM or TIMEMANAGER_AM
formatString = gsub(formatString, "^%%p", localizedAMPM)
formatString = gsub(formatString, "([^%%])%%p", "%1"..localizedAMPM)
end
if realmDiffSeconds ~= 0 and (E.db.datatexts.realmTime or forceRealmTime) and not forceLocalTime then
return date(formatString, time() - realmDiffSeconds)
else
return date(formatString)
end
end
local function GetInstanceImages(...)
local numTextures = select("#", ...) / 4
local argn, title, texture = 1
for i = 1, numTextures do
title, texture = select(argn, ...)
if texture ~= "" then
instanceIconByName[title] = texture
end
argn = argn + 4
end
end
local function OnEvent(self, event)
if event == "UPDATE_INSTANCE_INFO" then
local num = GetNumSavedInstances()
if num ~= numSavedInstances then
numSavedInstances = num or 0
if enteredFrame then
fullUpdate = true
end
end
return
end
if not realmDiffSeconds then
realmDiffSeconds = getRealmTimeDiff()
if realmDiffSeconds < 900 then
realmDiffSeconds = 0
end
end
end
local function OnClick(_, btn)
if btn == "RightButton" then
if not IsAddOnLoaded("Blizzard_TimeManager") then
LoadAddOn("Blizzard_TimeManager")
end
TimeManagerClockButton_OnClick(TimeManagerClockButton)
else
GameTimeFrame:Click()
end
end
local function OnEnter(self, skipRequest)
DT:SetupTooltip(self)
if not skipRequest then
RequestRaidInfo()
end
if not instanceIconByName then
instanceIconByName = {}
GetInstanceImages(CalendarEventGetTextures(1))
GetInstanceImages(CalendarEventGetTextures(2))
end
local wgtime = GetWintergraspWaitTime()
local _, instanceType = IsInInstance()
if instanceType ~= "none" then
wgtime = QUEUE_TIME_UNAVAILABLE
elseif wgtime == nil then
wgtime = WINTERGRASP_IN_PROGRESS
else
wgtime = SecondsToTime(wgtime, false, nil, 3)
end
DT.tooltip:AddDoubleLine(L["Wintergrasp"], wgtime, 1, 1, 1, lockoutColorNormal.r, lockoutColorNormal.g, lockoutColorNormal.b)
if numSavedInstances > 0 then
wipe(lockedInstances.raids)
wipe(lockedInstances.dungeons)
local name, reset, difficulty, locked, extended, isRaid, maxPlayers, difficultyLetter, buttonImg
for i = 1, numSavedInstances do
name, _, reset, difficulty, locked, extended, _, isRaid, maxPlayers = GetSavedInstanceInfo(i)
if name and (locked or extended) then
difficultyLetter = difficultyTag[not isRaid and (difficulty == 2 and 3 or 1) or difficulty]
buttonImg = format("|T%s%s:22:22:0:0:96:96:0:64:0:64|t ", "Interface\\LFGFrame\\LFGIcon-", instanceIconByName[name] or "Raid")
if isRaid then
tinsert(lockedInstances.raids, {name, reset, extended, maxPlayers, difficultyLetter, buttonImg})
elseif difficulty == 2 then
tinsert(lockedInstances.dungeons, {name, reset, extended, maxPlayers, difficultyLetter, buttonImg})
end
end
end
local lockoutColor, info
if next(lockedInstances.raids) then
DT.tooltip:AddLine(" ")
DT.tooltip:AddLine(L["Saved Raid(s)"])
for i = 1, #lockedInstances.raids do
info = lockedInstances.raids[i]
lockoutColor = info[3] and lockoutColorExtended or lockoutColorNormal
DT.tooltip:AddDoubleLine(
format(lockoutInfoFormat, info[6], info[4], info[5], info[1]),
SecondsToTime(info[2], false, nil, 3),
1, 1, 1,
lockoutColor.r, lockoutColor.g, lockoutColor.b
)
end
end
if next(lockedInstances.dungeons) then
DT.tooltip:AddLine(" ")
DT.tooltip:AddLine(L["Saved Dungeon(s)"])
for i = 1, #lockedInstances.dungeons do
info = lockedInstances.dungeons[i]
lockoutColor = info[3] and lockoutColorExtended or lockoutColorNormal
DT.tooltip:AddDoubleLine(
format(lockoutInfoFormat, info[6], info[4], info[5], info[1]),
SecondsToTime(info[2], false, nil, 3),
1, 1, 1,
lockoutColor.r, lockoutColor.g, lockoutColor.b
)
end
end
end
DT.tooltip:AddLine(" ")
if E.db.datatexts.realmTime then
DT.tooltip:AddDoubleLine(TIMEMANAGER_TOOLTIP_LOCALTIME, GetCurrentDate(E.db.datatexts.timeFormat, true), 1, 1, 1, lockoutColorNormal.r, lockoutColorNormal.g, lockoutColorNormal.b)
else
DT.tooltip:AddDoubleLine(TIMEMANAGER_TOOLTIP_REALMTIME, GetCurrentDate(E.db.datatexts.timeFormat, nil, true), 1, 1, 1, lockoutColorNormal.r, lockoutColorNormal.g, lockoutColorNormal.b)
end
DT.tooltip:Show()
enteredFrame = true
end
local function OnLeave()
enteredFrame = nil
DT.tooltip:Hide()
end
local function updateTooltipTime()
if E.db.datatexts.realmTime then
_G["DatatextTooltipTextRight" .. DT.tooltip:NumLines()]:SetText(GetCurrentDate(E.db.datatexts.timeFormat, true))
else
_G["DatatextTooltipTextRight" .. DT.tooltip:NumLines()]:SetText(GetCurrentDate(E.db.datatexts.timeFormat, nil, true))
end
end
local lastPanel
local int = 5
local function OnUpdate(self, elapsed)
int = int - elapsed
if int > 0 then return end
int = 1
lastPanel = self
if GameTimeFrame.flashInvite then
E:Flash(self, 0.53)
else
E:StopFlash(self)
end
self.text:SetText(gsub(gsub(GetCurrentDate(E.db.datatexts.timeFormat.." "..E.db.datatexts.dateFormat), ":", timeDisplayFormat), "%s", dateDisplayFormat))
if enteredFrame then
if fullUpdate then
fullUpdate = nil
OnEnter(self, true)
elseif showSecs then
updateTooltipTime()
end
end
end
local function ValueColorUpdate(hex)
timeDisplayFormat = join("", hex, ":|r")
dateDisplayFormat = join("", hex, " ")
if lastPanel ~= nil then
OnUpdate(lastPanel, 20000)
end
end
E.valueColorUpdateFuncs[ValueColorUpdate] = true
DT:RegisterDatatext("Time", {"UPDATE_INSTANCE_INFO"}, OnEvent, OnUpdate, OnClick, OnEnter, OnLeave)
+15
View File
@@ -0,0 +1,15 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Include file="Auras\Load_Auras.xml"/>
<Include file="Nameplates\Load_Nameplates.xml"/>
<Include file="Tooltip\Load_Tooltip.xml"/>
<Include file="DataTexts\Load_DataTexts.xml"/>
<Include file="DataBars\Load_DataBars.xml"/>
<Include file="Actionbars\Load_Actionbars.xml"/>
<Include file="UnitFrames\Load_UnitFrames.xml"/>
<Include file="Maps\Load_Maps.xml"/>
<Include file="Chat\Load_Chat.xml"/>
<Include file="Bags\Load_Bags.xml"/>
<Include file="Misc\Load_Misc.xml"/>
<Include file="Skins\Load_Skins.xml"/>
<Include file="Blizzard\Load_Blizzard.xml"/>
</Ui>
+4
View File
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="Minimap.lua"/>
<Script file="Worldmap.lua"/>
</Ui>
+533
View File
@@ -0,0 +1,533 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local M = E:GetModule("Minimap")
local Reminder = E:GetModule("ReminderBuffs")
--Lua functions
local match, utf8sub = string.match, string.utf8sub
--WoW API / Variables
local CreateFrame = CreateFrame
local ToggleCharacter = ToggleCharacter
local ToggleFrame = ToggleFrame
local ToggleAchievementFrame = ToggleAchievementFrame
local ToggleFriendsFrame = ToggleFriendsFrame
local IsAddOnLoaded = IsAddOnLoaded
local ToggleHelpFrame = ToggleHelpFrame
local GetZonePVPInfo = GetZonePVPInfo
local IsShiftKeyDown = IsShiftKeyDown
local ToggleDropDownMenu = ToggleDropDownMenu
local Minimap_OnClick = Minimap_OnClick
local GetMinimapZoneText = GetMinimapZoneText
local InCombatLockdown = InCombatLockdown
local menuFrame = CreateFrame("Frame", "MinimapRightClickMenu", E.UIParent, "UIDropDownMenuTemplate")
local menuList = {
{
text = CHARACTER_BUTTON,
notCheckable = 1,
func = function()
ToggleCharacter("PaperDollFrame")
end
},
{
text = SPELLBOOK_ABILITIES_BUTTON,
notCheckable = 1,
func = function()
ToggleFrame(SpellBookFrame)
end
},
{
text = TALENTS_BUTTON,
notCheckable = 1,
func = ToggleTalentFrame
},
{
text = ACHIEVEMENT_BUTTON,
notCheckable = 1,
func = ToggleAchievementFrame
},
{
text = QUESTLOG_BUTTON,
notCheckable = 1,
func = function()
ToggleFrame(QuestLogFrame)
end
},
{
text = SOCIAL_BUTTON,
notCheckable = 1,
func = function()
ToggleFriendsFrame(1)
end
},
{
text = L["Calendar"],
notCheckable = 1,
func = function()
GameTimeFrame:Click()
end
},
{
text = L["Farm Mode"],
notCheckable = 1,
func = FarmMode
},
{
text = BATTLEFIELD_MINIMAP,
notCheckable = 1,
func = ToggleBattlefieldMinimap
},
{
text = TIMEMANAGER_TITLE,
notCheckable = 1,
func = ToggleTimeManager
},
{
text = PLAYER_V_PLAYER,
notCheckable = 1,
func = function()
ToggleFrame(PVPParentFrame)
end
},
{
text = LFG_TITLE,
notCheckable = 1,
func = function()
ToggleFrame(LFDParentFrame)
end
},
{
text = LOOKING_FOR_RAID,
notCheckable = 1,
func = function()
ToggleFrame(LFRParentFrame)
end
},
{
text = MAINMENU_BUTTON,
notCheckable = 1,
func = function()
if GameMenuFrame:IsShown() then
PlaySound("igMainMenuQuit")
HideUIPanel(GameMenuFrame)
else
PlaySound("igMainMenuOpen")
ShowUIPanel(GameMenuFrame)
end
end
},
{
text = HELP_BUTTON,
notCheckable = 1,
func = ToggleHelpFrame
}
}
function M:GetLocTextColor()
local pvpType = GetZonePVPInfo()
if pvpType == "sanctuary" then
return 0.035, 0.58, 0.84
elseif pvpType == "arena" then
return 0.84, 0.03, 0.03
elseif pvpType == "friendly" then
return 0.05, 0.85, 0.03
elseif pvpType == "hostile" then
return 0.84, 0.03, 0.03
elseif pvpType == "contested" then
return 0.9, 0.85, 0.05
else
return 0.84, 0.03, 0.03
end
end
function M:ADDON_LOADED(event, addon)
if addon == "Blizzard_TimeManager" then
self:UnregisterEvent(event)
TimeManagerClockButton:Kill()
end
end
function M:Minimap_OnMouseUp(btn)
local position = self:GetPoint()
if btn == "MiddleButton" or (btn == "RightButton" and IsShiftKeyDown()) then
if match(position, "LEFT") then
EasyMenu(menuList, menuFrame, "cursor", 0, 0, "MENU", 2)
else
EasyMenu(menuList, menuFrame, "cursor", -160, 0, "MENU", 2)
end
elseif btn == "RightButton" then
ToggleDropDownMenu(1, nil, MiniMapTrackingDropDown, "cursor")
else
Minimap_OnClick(self)
end
end
function M:Minimap_OnMouseWheel(d)
local zoomLevel = Minimap:GetZoom()
if d > 0 and zoomLevel < 5 then
Minimap:SetZoom(zoomLevel + 1)
elseif d < 0 and zoomLevel > 0 then
Minimap:SetZoom(zoomLevel - 1)
end
end
function M:Update_ZoneText()
if E.db.general.minimap.locationText == "HIDE" or not E.private.general.minimap.enable then return end
Minimap.location:SetText(utf8sub(GetMinimapZoneText(),1,46))
Minimap.location:SetTextColor(self:GetLocTextColor())
Minimap.location:FontTemplate(E.Libs.LSM:Fetch("font", E.db.general.minimap.locationFont), E.db.general.minimap.locationFontSize, E.db.general.minimap.locationFontOutline)
end
function M:PLAYER_REGEN_ENABLED()
self:UnregisterEvent("PLAYER_REGEN_ENABLED")
self:UpdateSettings()
end
function M:CreateFarmModeMap()
local fm = CreateFrame("Minimap", "FarmModeMap", E.UIParent)
fm:Size(E.db.farmSize)
fm:Point("TOP", E.UIParent, "TOP", 0, -120)
fm:SetClampedToScreen(true)
fm:CreateBackdrop("Default")
fm:EnableMouseWheel(true)
fm:SetScript("OnMouseWheel", M.Minimap_OnMouseWheel)
fm:SetScript("OnMouseUp", M.Minimap_OnMouseUp)
fm:RegisterForDrag("LeftButton", "RightButton")
fm:SetMovable(true)
fm:SetScript("OnDragStart", function(self) self:StartMoving() end)
fm:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() end)
fm:Hide()
self.farmModeMap = fm
fm:SetScript("OnShow", function()
if BuffsMover and not E:HasMoverBeenMoved("BuffsMover") then
BuffsMover:ClearAllPoints()
BuffsMover:Point("TOPRIGHT", E.UIParent, "TOPRIGHT", -3, -3)
end
if DebuffsMover and not E:HasMoverBeenMoved("DebuffsMover") then
DebuffsMover:ClearAllPoints()
DebuffsMover:Point("TOPRIGHT", ElvUIPlayerBuffs, "BOTTOMRIGHT", 0, -3)
end
MinimapCluster:ClearAllPoints()
MinimapCluster:SetAllPoints(fm)
if IsAddOnLoaded("Routes") then
LibStub("AceAddon-3.0"):GetAddon("Routes"):ReparentMinimap(fm)
end
if IsAddOnLoaded("GatherMate") then
LibStub("AceAddon-3.0"):GetAddon("GatherMate"):GetModule("Display"):ReparentMinimapPins(fm)
end
if IsAddOnLoaded("GatherMate2") then
LibStub("AceAddon-3.0"):GetAddon("GatherMate2"):GetModule("Display"):ReparentMinimapPins(fm)
end
end)
fm:SetScript("OnHide", function()
if BuffsMover and not E:HasMoverBeenMoved("BuffsMover") then
E:ResetMovers(L["Player Buffs"])
end
if DebuffsMover and not E:HasMoverBeenMoved("DebuffsMover") then
E:ResetMovers(L["Player Debuffs"])
end
MinimapCluster:ClearAllPoints()
MinimapCluster:SetAllPoints(Minimap)
if IsAddOnLoaded("Routes") then
LibStub("AceAddon-3.0"):GetAddon("Routes"):ReparentMinimap(Minimap)
end
if IsAddOnLoaded("GatherMate") then
LibStub("AceAddon-3.0"):GetAddon("GatherMate"):GetModule("Display"):ReparentMinimapPins(Minimap)
end
if IsAddOnLoaded("GatherMate2") then
LibStub("AceAddon-3.0"):GetAddon("GatherMate2"):GetModule("Display"):ReparentMinimapPins(Minimap)
end
end)
end
local isResetting
local function ResetZoom()
Minimap:SetZoom(0)
isResetting = nil
end
local function SetupZoomReset(self, zoomLevel)
if not isResetting and zoomLevel > 0 and E.db.general.minimap.resetZoom.enable then
isResetting = true
E:Delay(E.db.general.minimap.resetZoom.time, ResetZoom)
end
end
function M:UpdateSettings()
if InCombatLockdown() then
self:RegisterEvent("PLAYER_REGEN_ENABLED")
end
E.MinimapSize = E.private.general.minimap.enable and E.db.general.minimap.size or Minimap:GetWidth() + 10
E.MinimapWidth, E.MinimapHeight = E.MinimapSize, E.MinimapSize
if E.db.general.reminder.enable then
E.RBRWidth = (E.MinimapHeight + ((E.Border - E.Spacing*3) * 5) + E.Border*2) / 8
else
E.RBRWidth = 0
end
if E.private.general.minimap.enable then
Minimap:Size(E.MinimapSize, E.MinimapSize)
end
if LeftMiniPanel and RightMiniPanel then
if E.db.datatexts.minimapPanels and E.private.general.minimap.enable then
LeftMiniPanel:Show()
RightMiniPanel:Show()
else
LeftMiniPanel:Hide()
RightMiniPanel:Hide()
end
end
if BottomMiniPanel then
if E.db.datatexts.minimapBottom and E.private.general.minimap.enable then
BottomMiniPanel:Show()
else
BottomMiniPanel:Hide()
end
end
if BottomLeftMiniPanel then
if E.db.datatexts.minimapBottomLeft and E.private.general.minimap.enable then
BottomLeftMiniPanel:Show()
else
BottomLeftMiniPanel:Hide()
end
end
if BottomRightMiniPanel then
if E.db.datatexts.minimapBottomRight and E.private.general.minimap.enable then
BottomRightMiniPanel:Show()
else
BottomRightMiniPanel:Hide()
end
end
if TopMiniPanel then
if E.db.datatexts.minimapTop and E.private.general.minimap.enable then
TopMiniPanel:Show()
else
TopMiniPanel:Hide()
end
end
if TopLeftMiniPanel then
if E.db.datatexts.minimapTopLeft and E.private.general.minimap.enable then
TopLeftMiniPanel:Show()
else
TopLeftMiniPanel:Hide()
end
end
if TopRightMiniPanel then
if E.db.datatexts.minimapTopRight and E.private.general.minimap.enable then
TopRightMiniPanel:Show()
else
TopRightMiniPanel:Hide()
end
end
if MMHolder then
MMHolder:Width((Minimap:GetWidth() + E.Border*2 + E.Spacing*3) + E.RBRWidth * 2 - 2)
if E.db.datatexts.minimapPanels then
MMHolder:Height(Minimap:GetHeight() + (LeftMiniPanel and (LeftMiniPanel:GetHeight() + E.Border) or 24) + E.Spacing*3)
else
MMHolder:Height(Minimap:GetHeight() + E.Border + E.Spacing*3)
end
end
if Minimap.location then
Minimap.location:Width(E.MinimapSize)
if E.db.general.minimap.locationText ~= "SHOW" or not E.private.general.minimap.enable then
Minimap.location:Hide()
else
Minimap.location:Show()
end
end
if MinimapMover then
MinimapMover:Size(MMHolder:GetSize())
end
if GameTimeFrame then
if E.private.general.minimap.hideCalendar then
GameTimeFrame:Hide()
else
local pos = E.db.general.minimap.icons.calendar.position or "TOPRIGHT"
local scale = E.db.general.minimap.icons.calendar.scale or 1
GameTimeFrame:ClearAllPoints()
GameTimeFrame:Point(pos, Minimap, pos, E.db.general.minimap.icons.calendar.xOffset or 0, E.db.general.minimap.icons.calendar.yOffset or 0)
GameTimeFrame:SetScale(scale)
GameTimeFrame:Show()
end
end
if MiniMapMailFrame then
local pos = E.db.general.minimap.icons.mail.position or "TOPRIGHT"
local scale = E.db.general.minimap.icons.mail.scale or 1
MiniMapMailFrame:ClearAllPoints()
MiniMapMailFrame:Point(pos, Minimap, pos, E.db.general.minimap.icons.mail.xOffset or 3, E.db.general.minimap.icons.mail.yOffset or 4)
MiniMapMailFrame:SetScale(scale)
end
if MiniMapLFGFrame then
local pos = E.db.general.minimap.icons.lfgEye.position or "BOTTOMRIGHT"
local scale = E.db.general.minimap.icons.lfgEye.scale or 1
MiniMapLFGFrame:ClearAllPoints()
MiniMapLFGFrame:Point(pos, Minimap, pos, E.db.general.minimap.icons.lfgEye.xOffset or 3, E.db.general.minimap.icons.lfgEye.yOffset or 0)
MiniMapLFGFrame:SetScale(scale)
LFDSearchStatus:SetScale(scale)
end
if MiniMapBattlefieldFrame then
local pos = E.db.general.minimap.icons.battlefield.position or "BOTTOMRIGHT"
local scale = E.db.general.minimap.icons.battlefield.scale or 1
MiniMapBattlefieldFrame:ClearAllPoints()
MiniMapBattlefieldFrame:Point(pos, Minimap, pos, E.db.general.minimap.icons.battlefield.xOffset or 3, E.db.general.minimap.icons.battlefield.yOffset or 0)
MiniMapBattlefieldFrame:SetScale(scale)
end
if MiniMapInstanceDifficulty then
local pos = E.db.general.minimap.icons.difficulty.position or "TOPLEFT"
local scale = E.db.general.minimap.icons.difficulty.scale or 1
local x = E.db.general.minimap.icons.difficulty.xOffset or 0
local y = E.db.general.minimap.icons.difficulty.yOffset or 0
MiniMapInstanceDifficulty:ClearAllPoints()
MiniMapInstanceDifficulty:Point(pos, Minimap, pos, x, y)
MiniMapInstanceDifficulty:SetScale(scale)
end
if ElvConfigToggle then
if E.db.general.reminder.enable and E.db.datatexts.minimapPanels and E.private.general.minimap.enable then
ElvConfigToggle:Show()
ElvConfigToggle:Width(E.RBRWidth * 2)
else
ElvConfigToggle:Hide()
end
end
if ElvUI_ReminderBuffs then
Reminder:UpdateSettings()
end
end
local function MinimapPostDrag()
MinimapCluster:ClearAllPoints()
MinimapCluster:SetAllPoints(Minimap)
MinimapBackdrop:ClearAllPoints()
MinimapBackdrop:SetAllPoints(Minimap)
end
function M:Initialize()
menuFrame:SetTemplate("Transparent", true)
self:UpdateSettings()
if not E.private.general.minimap.enable then
Minimap:SetMaskTexture("Textures\\MinimapMask")
return
end
--Support for other mods
function GetMinimapShape()
return "SQUARE"
end
local mmholder = CreateFrame("Frame", "MMHolder", Minimap)
mmholder:Point("TOPRIGHT", E.UIParent, "TOPRIGHT", -3, -3)
mmholder:Width((Minimap:GetWidth() + 29) + E.RBRWidth * 2 - 2)
mmholder:Height(Minimap:GetHeight() + 53)
Minimap:ClearAllPoints()
if E.db.general.reminder.position == "LEFT" then
Minimap:Point("TOPRIGHT", mmholder, "TOPRIGHT", -E.Border, -E.Border)
else
Minimap:Point("TOPLEFT", mmholder, "TOPLEFT", E.Border, -E.Border)
end
Minimap:SetMaskTexture("Interface\\ChatFrame\\ChatFrameBackground")
Minimap:CreateBackdrop()
Minimap:SetFrameLevel(Minimap:GetFrameLevel() + 2)
Minimap:HookScript("OnEnter", function(mm)
if E.db.general.minimap.locationText ~= "MOUSEOVER" or not E.private.general.minimap.enable then return end
mm.location:Show()
end)
Minimap:HookScript("OnLeave", function(self)
if E.db.general.minimap.locationText ~= "MOUSEOVER" or not E.private.general.minimap.enable then return end
self.location:Hide()
end)
Minimap.location = Minimap:CreateFontString(nil, "OVERLAY")
Minimap.location:FontTemplate(nil, nil, "OUTLINE")
Minimap.location:Point("TOP", Minimap, "TOP", 0, -2)
Minimap.location:SetJustifyH("CENTER")
Minimap.location:SetJustifyV("MIDDLE")
if E.db.general.minimap.locationText ~= "SHOW" or not E.private.general.minimap.enable then
Minimap.location:Hide()
end
MinimapBorder:Hide()
MinimapBorderTop:Hide()
MinimapZoomIn:Hide()
MinimapZoomOut:Hide()
MiniMapVoiceChatFrame:Hide()
MinimapNorthTag:Kill()
MinimapZoneTextButton:Hide()
MiniMapTracking:Kill()
MiniMapMailBorder:Hide()
MiniMapMailIcon:SetTexture(E.Media.Textures.Mail)
if MiniMapBattlefieldBorder then
MiniMapBattlefieldBorder:Hide()
end
MiniMapLFGFrameBorder:Hide()
MiniMapWorldMapButton:Hide()
MiniMapInstanceDifficulty:SetParent(Minimap)
if TimeManagerClockButton then
TimeManagerClockButton:Kill()
else
self:RegisterEvent("ADDON_LOADED")
end
E:CreateMover(MMHolder, "MinimapMover", L["Minimap"], nil, nil, MinimapPostDrag, nil, nil, "maps,minimap")
Minimap:EnableMouseWheel(true)
Minimap:SetScript("OnMouseWheel", M.Minimap_OnMouseWheel)
Minimap:SetScript("OnMouseUp", M.Minimap_OnMouseUp)
self:RegisterEvent("ZONE_CHANGED_NEW_AREA", "Update_ZoneText")
self:RegisterEvent("ZONE_CHANGED", "Update_ZoneText")
self:RegisterEvent("ZONE_CHANGED_INDOORS", "Update_ZoneText")
self:RegisterEvent("PLAYER_ENTERING_WORLD", "Update_ZoneText")
hooksecurefunc(Minimap, "SetZoom", SetupZoomReset)
self:CreateFarmModeMap()
self.Initialized = true
end
local function InitializeCallback()
M:Initialize()
end
E:RegisterInitialModule(M:GetName(), InitializeCallback)
+259
View File
@@ -0,0 +1,259 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local M = E:GetModule("WorldMap")
--Lua functions
local find = string.find
--WoW API / Variables
local CreateFrame = CreateFrame
local GetCVarBool = GetCVarBool
local GetCursorPosition = GetCursorPosition
local GetPlayerMapPosition = GetPlayerMapPosition
local GetUnitSpeed = GetUnitSpeed
local MOUSE_LABEL = MOUSE_LABEL
local PLAYER = PLAYER
local WORLDMAP_SETTINGS = WORLDMAP_SETTINGS
local INVERTED_POINTS = {
["TOPLEFT"] = "BOTTOMLEFT",
["TOPRIGHT"] = "BOTTOMRIGHT",
["BOTTOMLEFT"] = "TOPLEFT",
["BOTTOMRIGHT"] = "TOPRIGHT",
["TOP"] = "BOTTOM",
["BOTTOM"] = "TOP"
}
local function BlobFrameHide()
M.blobWasVisible = nil
end
local function BlobFrameShow()
M.blobWasVisible = true
end
function M:PLAYER_REGEN_ENABLED()
WorldMapBlobFrame.SetFrameLevel = nil
WorldMapBlobFrame.SetScale = nil
WorldMapBlobFrame.Hide = nil
WorldMapBlobFrame.Show = nil
local frameLevel = WorldMapDetailFrame:GetFrameLevel() + 1
WorldMapBlobFrame:SetParent(WorldMapFrame)
WorldMapBlobFrame:ClearAllPoints()
WorldMapBlobFrame:SetPoint("TOPLEFT", WorldMapDetailFrame)
WorldMapBlobFrame:SetScale(self.blobNewScale or WORLDMAP_SETTINGS.size)
WorldMapBlobFrame:SetFrameLevel(frameLevel)
WorldMapBlobFrame:SetFrameLevel(frameLevel) -- called twice to set frame level above the default limit (256)
if self.blobWasVisible then
WorldMapBlobFrame:Show()
end
if WORLDMAP_SETTINGS.selectedQuest then
WorldMapBlobFrame:DrawQuestBlob(WORLDMAP_SETTINGS.selectedQuest.questId, false)
end
if self.blobWasVisible then
WorldMapBlobFrame_CalculateHitTranslations()
if WORLDMAP_SETTINGS.selectedQuest and not WORLDMAP_SETTINGS.selectedQuest.completed then
WorldMapBlobFrame:DrawQuestBlob(WORLDMAP_SETTINGS.selectedQuest.questId, true)
end
end
end
function M:PLAYER_REGEN_DISABLED()
self.blobWasVisible = WorldMapFrame:IsShown() and WorldMapBlobFrame:IsShown()
WorldMapBlobFrame:SetParent(nil)
WorldMapBlobFrame:ClearAllPoints()
WorldMapBlobFrame:SetPoint("TOP", UIParent, "BOTTOM")
WorldMapBlobFrame:Hide()
WorldMapBlobFrame.Hide = BlobFrameHide
WorldMapBlobFrame.Show = BlobFrameShow
WorldMapBlobFrame.SetFrameLevel = E.noop
WorldMapBlobFrame.SetScale = E.noop
self.blobNewScale = nil
end
local t = 0
local function UpdateCoords(self, elapsed)
t = t + elapsed
if t < 0.03333 then return end
t = 0
local x, y = GetPlayerMapPosition("player")
if self.playerCoords.x ~= x or self.playerCoords.y ~= y then
if x ~= 0 or y ~= 0 then
self.playerCoords.x = x
self.playerCoords.y = y
self.playerCoords:SetFormattedText("%s: %.2f, %.2f", PLAYER, x * 100, y * 100)
else
self.playerCoords.x = nil
self.playerCoords.y = nil
self.playerCoords:SetFormattedText("%s: %s", PLAYER, "N/A")
end
end
if WorldMapDetailFrame:IsMouseOver() then
local curX, curY = GetCursorPosition()
if self.mouseCoords.x ~= curX or self.mouseCoords.y ~= curY then
local scale = WorldMapDetailFrame:GetEffectiveScale()
local width, height = WorldMapDetailFrame:GetSize()
local centerX, centerY = WorldMapDetailFrame:GetCenter()
local adjustedX = (curX / scale - (centerX - (width * 0.5))) / width
local adjustedY = (centerY + (height * 0.5) - curY / scale) / height
if adjustedX >= 0 and adjustedY >= 0 and adjustedX <= 1 and adjustedY <= 1 then
self.mouseCoords.x = curX
self.mouseCoords.y = curY
self.mouseCoords:SetFormattedText("%s: %.2f, %.2f", MOUSE_LABEL, adjustedX * 100, adjustedY * 100)
else
self.mouseCoords.x = nil
self.mouseCoords.y = nil
self.mouseCoords:SetText("")
end
end
elseif self.mouseCoords.x then
self.mouseCoords.x = nil
self.mouseCoords.y = nil
self.mouseCoords:SetText("")
end
end
function M:PositionCoords()
if not self.coordsHolder then return end
local db = E.global.general.WorldMapCoordinates
local position = db.position
local x = find(position, "RIGHT") and -5 or 5
local y = find(position, "TOP") and -5 or 5
self.coordsHolder.playerCoords:ClearAllPoints()
self.coordsHolder.playerCoords:Point(position, WorldMapDetailFrame, position, x + db.xOffset, y + db.yOffset)
self.coordsHolder.mouseCoords:ClearAllPoints()
self.coordsHolder.mouseCoords:Point(position, self.coordsHolder.playerCoords, INVERTED_POINTS[position], 0, y)
end
function M:ToggleMapFramerate()
if WORLDMAP_SETTINGS.size == WORLDMAP_FULLMAP_SIZE or WORLDMAP_SETTINGS.size == WORLDMAP_QUESTLIST_SIZE then
WorldMapFrame:SetAttribute("UIPanelLayout-area", "center")
WorldMapFrame:SetAttribute("UIPanelLayout-allowOtherPanels", true)
WorldMapFrame:SetScale(1)
end
end
function M:CheckMovement()
if not WorldMapFrame:IsShown() then return end
if GetUnitSpeed("player") ~= 0 and not WorldMapPositioningGuide:IsMouseOver() then
WorldMapFrame:SetAlpha(E.global.general.mapAlphaWhenMoving)
WorldMapBlobFrame:SetFillAlpha(128 * E.global.general.mapAlphaWhenMoving)
WorldMapBlobFrame:SetBorderAlpha(192 * E.global.general.mapAlphaWhenMoving)
else
WorldMapFrame:SetAlpha(1)
WorldMapBlobFrame:SetFillAlpha(128)
WorldMapBlobFrame:SetBorderAlpha(192)
end
end
function M:UpdateMapAlpha()
if (not E.global.general.fadeMapWhenMoving or E.global.general.mapAlphaWhenMoving >= 1) and self.MovingTimer then
self:CancelTimer(self.MovingTimer)
self.MovingTimer = nil
WorldMapFrame:SetAlpha(1)
WorldMapBlobFrame:SetFillAlpha(128)
WorldMapBlobFrame:SetBorderAlpha(192)
elseif E.global.general.fadeMapWhenMoving and E.global.general.mapAlphaWhenMoving < 1 and not self.MovingTimer then
self.MovingTimer = self:ScheduleRepeatingTimer("CheckMovement", 0.2)
end
end
function M:Initialize()
self:UpdateMapAlpha()
if not E.private.worldmap.enable then return end
if E.global.general.WorldMapCoordinates.enable then
local coordsHolder = CreateFrame("Frame", "ElvUI_CoordsHolder", WorldMapFrame)
coordsHolder:SetFrameLevel(WORLDMAP_POI_FRAMELEVEL + 100)
coordsHolder:SetFrameStrata(WorldMapDetailFrame:GetFrameStrata())
coordsHolder.playerCoords = coordsHolder:CreateFontString(nil, "OVERLAY")
coordsHolder.playerCoords:SetTextColor(1, 1, 0)
coordsHolder.playerCoords:SetFontObject(NumberFontNormal)
coordsHolder.playerCoords:SetPoint("BOTTOMLEFT", WorldMapDetailFrame, "BOTTOMLEFT", 5, 5)
coordsHolder.playerCoords:SetFormattedText("%s: 0, 0", PLAYER)
coordsHolder.mouseCoords = coordsHolder:CreateFontString(nil, "OVERLAY")
coordsHolder.mouseCoords:SetTextColor(1, 1, 0)
coordsHolder.mouseCoords:SetFontObject(NumberFontNormal)
coordsHolder.mouseCoords:SetPoint("BOTTOMLEFT", coordsHolder.playerCoords, "TOPLEFT", 0, 5)
coordsHolder:SetScript("OnUpdate", UpdateCoords)
self.coordsHolder = coordsHolder
self:PositionCoords()
end
if E.global.general.smallerWorldMap or (E.private.skins.blizzard.enable and E.private.skins.blizzard.worldmap) then
self:RegisterEvent("PLAYER_REGEN_ENABLED")
self:RegisterEvent("PLAYER_REGEN_DISABLED")
end
WorldMapFrame:EnableMouse(false)
WorldMapFrame.EnableMouse = E.noop
if E.global.general.smallerWorldMap then
BlackoutWorld:SetTexture(nil)
WorldMapFrame:SetParent(UIParent)
WorldMapFrame.SetParent = E.noop
WorldMapFrame:EnableKeyboard(false)
WorldMapFrame.EnableKeyboard = E.noop
if not GetCVarBool("miniWorldMap") then
ShowUIPanel(WorldMapFrame)
self:ToggleMapFramerate()
HideUIPanel(WorldMapFrame)
end
self:SecureHook("ToggleMapFramerate")
hooksecurefunc(WorldMapDetailFrame, "SetScale", function(_, scale)
self.blobNewScale = scale
end)
DropDownList1:HookScript("OnShow", function(self)
if self:GetScale() ~= UIParent:GetScale() then
self:SetScale(UIParent:GetScale())
end
end)
self:RawHook("WorldMapQuestPOI_OnLeave", function()
WorldMapPOIFrame.allowBlobTooltip = true
WorldMapTooltip:Hide()
end, true)
-- WorldMapTooltip:SetFrameLevel(WORLDMAP_POI_FRAMELEVEL + 110)
-- WorldMapCompareTooltip1:SetFrameLevel(WORLDMAP_POI_FRAMELEVEL + 110)
-- WorldMapCompareTooltip2:SetFrameLevel(WORLDMAP_POI_FRAMELEVEL + 110)
end
self.Initialized = true
end
local function InitializeCallback()
M:Initialize()
end
E:RegisterInitialModule(M:GetName(), InitializeCallback)
+348
View File
@@ -0,0 +1,348 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local mod = E:GetModule("AFK")
local CH = E:GetModule("Chat")
--Lua functions
local _G = _G
local tostring = tostring
local floor = math.floor
local format, gsub, sub, upper = string.format, string.gsub, string.sub, string.upper
--WoW API / Variables
local ChatHistory_GetAccessID = ChatHistory_GetAccessID
local Chat_GetChatCategory = Chat_GetChatCategory
local CinematicFrame = CinematicFrame
local CreateFrame = CreateFrame
local GetBattlefieldStatus = GetBattlefieldStatus
local GetColoredName = GetColoredName
local GetGuildInfo = GetGuildInfo
local GetScreenHeight = GetScreenHeight
local GetScreenWidth = GetScreenWidth
local GetTime = GetTime
local InCombatLockdown = InCombatLockdown
local IsInGuild = IsInGuild
local IsShiftKeyDown = IsShiftKeyDown
local MoveViewLeftStart = MoveViewLeftStart
local MoveViewLeftStop = MoveViewLeftStop
local MovieFrame = MovieFrame
local Screenshot = Screenshot
local SetCVar = SetCVar
local UnitCastingInfo = UnitCastingInfo
local UnitIsAFK = UnitIsAFK
local AFK, DND = AFK, DND
local CHAT_BN_CONVERSATION_GET_LINK = CHAT_BN_CONVERSATION_GET_LINK
local MAX_WOW_CHAT_CHANNELS = MAX_WOW_CHAT_CHANNELS
local cameraSpeed = 0.035
local ignoreKeys = {
["LALT"] = true,
["LSHIFT"] = true,
["RSHIFT"] = true
}
local printKeys = {
["PRINTSCREEN"] = true,
}
if E.isMacClient then
printKeys[_G["KEY_PRINTSCREEN_MAC"]] = true
end
function mod:UpdateTimer()
local time = GetTime() - self.startTime
self.AFKMode.bottom.time:SetFormattedText("%02d:%02d", floor(time / 60), time % 60)
end
local function StopAnimation(self)
self:SetSequenceTime(0, 0)
self:SetScript("OnUpdate", nil)
self:SetScript("OnAnimFinished", nil)
end
local function UpdateAnimation(self, elapsed)
self.animTime = self.animTime + (elapsed * 1000)
self:SetSequenceTime(67, self.animTime)
if self.animTime >= 3000 then
StopAnimation(self)
end
end
local function OnAnimFinished(self)
if self.animTime > 500 then
StopAnimation(self)
end
end
function mod:SetAFK(status)
if status and not self.isAFK then
if InspectFrame then
InspectFrame:Hide()
end
UIParent:Hide()
self.AFKMode:Show()
E.global.afkEnabled = true
MoveViewLeftStart(cameraSpeed)
if IsInGuild() then
local guildName, guildRankName = GetGuildInfo("player")
self.AFKMode.bottom.guild:SetFormattedText("%s - %s", guildName, guildRankName)
else
self.AFKMode.bottom.guild:SetText(L["No Guild"])
end
self.startTime = GetTime()
self.timer = self:ScheduleRepeatingTimer("UpdateTimer", 1)
self.AFKMode.chat:RegisterEvent("CHAT_MSG_WHISPER")
self.AFKMode.chat:RegisterEvent("CHAT_MSG_BN_WHISPER")
self.AFKMode.chat:RegisterEvent("CHAT_MSG_BN_CONVERSATION")
self.AFKMode.chat:RegisterEvent("CHAT_MSG_GUILD")
self.AFKMode.bottom.model:SetModelScale(1)
self.AFKMode.bottom.model:RefreshUnit()
self.AFKMode.bottom.model:SetModelScale(0.8)
self.AFKMode.bottom.model.animTime = 0
self.AFKMode.bottom.model:SetScript("OnUpdate", UpdateAnimation)
self.AFKMode.bottom.model:SetScript("OnAnimFinished", OnAnimFinished)
self.isAFK = true
elseif not status and self.isAFK then
self.AFKMode:Hide()
UIParent:Show()
E.global.afkEnabled = nil
MoveViewLeftStop()
self:CancelTimer(self.timer)
self.AFKMode.bottom.time:SetText("00:00")
self.AFKMode.chat:UnregisterEvent("CHAT_MSG_WHISPER")
self.AFKMode.chat:UnregisterEvent("CHAT_MSG_BN_WHISPER")
self.AFKMode.chat:UnregisterEvent("CHAT_MSG_BN_CONVERSATION")
self.AFKMode.chat:UnregisterEvent("CHAT_MSG_GUILD")
self.AFKMode.chat:Clear()
self.isAFK = false
end
end
function mod:OnEvent(event, ...)
if event == "PLAYER_REGEN_DISABLED" or event == "LFG_PROPOSAL_SHOW" or event == "UPDATE_BATTLEFIELD_STATUS" then
if event == "UPDATE_BATTLEFIELD_STATUS" then
local status = GetBattlefieldStatus(...)
if status == "confirm" then
self:SetAFK(false)
end
else
self:SetAFK(false)
end
if event == "PLAYER_REGEN_DISABLED" then
self:RegisterEvent("PLAYER_REGEN_ENABLED", "OnEvent")
end
return
end
if event == "PLAYER_REGEN_ENABLED" then
self:ScheduleTimer("OnEvent", 10)
self:UnregisterEvent("PLAYER_REGEN_ENABLED")
return
end
if not E.db.general.afk then return end
if InCombatLockdown() or CinematicFrame:IsShown() or MovieFrame:IsShown() then return end
if UnitCastingInfo("player") ~= nil then
--Don't activate afk if player is crafting stuff, check back in 30 seconds
self:ScheduleTimer("OnEvent", 30)
return
end
self:SetAFK(UnitIsAFK("player"))
end
function mod:Toggle()
if E.db.general.afk then
self:RegisterEvent("PLAYER_FLAGS_CHANGED", "OnEvent")
self:RegisterEvent("PLAYER_REGEN_DISABLED", "OnEvent")
self:RegisterEvent("LFG_PROPOSAL_SHOW", "OnEvent")
self:RegisterEvent("UPDATE_BATTLEFIELD_STATUS", "OnEvent")
SetCVar("autoClearAFK", "1")
else
self:UnregisterEvent("PLAYER_FLAGS_CHANGED")
self:UnregisterEvent("PLAYER_REGEN_DISABLED")
self:UnregisterEvent("LFG_PROPOSAL_SHOW")
self:UnregisterEvent("UPDATE_BATTLEFIELD_STATUS")
self:CancelAllTimers()
end
end
local function OnKeyDown(_, key)
if ignoreKeys[key] then return end
if printKeys[key] then
Screenshot()
else
mod:SetAFK(false)
mod:ScheduleTimer("OnEvent", 60)
end
end
local function Chat_OnMouseWheel(self, delta)
if delta > 0 then
if IsShiftKeyDown() then
self:ScrollToTop()
else
self:ScrollUp()
end
elseif delta < 0 then
if IsShiftKeyDown() then
self:ScrollToBottom()
else
self:ScrollDown()
end
end
end
local function Chat_OnEvent(self, event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13)
local coloredName = GetColoredName(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)
local chatType = sub(event, 10)
local info = ChatTypeInfo[chatType]
local chatGroup = Chat_GetChatCategory(chatType)
local chatTarget
if chatGroup == "BN_CONVERSATION" then
chatTarget = tostring(arg8)
elseif chatGroup == "WHISPER" or chatGroup == "BN_WHISPER" then
chatTarget = upper(arg2)
end
local playerLink
if chatType ~= "BN_WHISPER" and chatType ~= "BN_CONVERSATION" then
playerLink = "|Hplayer:"..arg2..":"..arg11..":"..chatGroup..(chatTarget and ":"..chatTarget or "").."|h"
else
playerLink = "|HBNplayer:"..arg2..":"..arg13..":"..arg11..":"..chatGroup..(chatTarget and ":"..chatTarget or "").."|h"
end
arg1 = gsub(arg1, "%%", "%%%%")
local body = format(_G["CHAT_"..chatType.."_GET"]..arg1, playerLink.."["..coloredName.."]".."|h")
if chatGroup == "BN_CONVERSATION" then
body = format(CHAT_BN_CONVERSATION_GET_LINK, arg8, MAX_WOW_CHAT_CHANNELS + arg8)..body
end
local accessID = ChatHistory_GetAccessID(chatGroup, chatTarget)
local typeID = ChatHistory_GetAccessID(chatType, chatTarget)
if E.db.chat.shortChannels then
body = gsub(body, "|Hchannel:(.-)|h%[(.-)%]|h", CH.ShortChannel)
body = gsub(body, "^(.-|h) "..L["whispers"], "%1")
body = gsub(body, "<"..AFK..">", "[|cffFF0000"..AFK.."|r] ")
body = gsub(body, "<"..DND..">", "[|cffE7E716"..DND.."|r] ")
body = gsub(body, "%[BN_CONVERSATION:", "%[".."")
end
if CH.db ~= nil and CH.db.timeStampFormat ~= "NONE" then
local timeStamp = BetterDate(CH.db.timeStampFormat, time())
if CH.db.useCustomTimeColor then
local color = CH.db.customTimeColor
local hexColor = E:RGBToHex(color.r, color.g, color.b)
body = format("%s[%s]|r %s", hexColor, timeStamp, body)
else
body = format("[%s] %s", timeStamp, body)
end
end
self:AddMessage(body, info.r, info.g, info.b, info.id, false, accessID, typeID)
end
function mod:Initialize()
self.AFKMode = CreateFrame("Frame", "ElvUIAFKFrame")
self.AFKMode:SetFrameLevel(1)
self.AFKMode:SetScale(UIParent:GetScale())
self.AFKMode:SetAllPoints(UIParent)
self.AFKMode:Hide()
self.AFKMode:EnableKeyboard(true)
self.AFKMode:SetScript("OnKeyDown", OnKeyDown)
self.AFKMode.chat = CreateFrame("ScrollingMessageFrame", "AFKChat", self.AFKMode)
self.AFKMode.chat:Size(500, 200)
self.AFKMode.chat:Point("TOPLEFT", self.AFKMode, "TOPLEFT", 4, -3)
self.AFKMode.chat:FontTemplate()
self.AFKMode.chat:SetJustifyH("LEFT")
self.AFKMode.chat:SetMaxLines(500)
self.AFKMode.chat:EnableMouseWheel(true)
self.AFKMode.chat:SetFading(false)
self.AFKMode.chat:SetMovable(true)
self.AFKMode.chat:EnableMouse(true)
self.AFKMode.chat:SetClampedToScreen(true)
self.AFKMode.chat:SetClampRectInsets(-4, 3, 3, -4)
self.AFKMode.chat:RegisterForDrag("LeftButton")
self.AFKMode.chat:SetScript("OnDragStart", self.AFKMode.chat.StartMoving)
self.AFKMode.chat:SetScript("OnDragStop", self.AFKMode.chat.StopMovingOrSizing)
self.AFKMode.chat:SetScript("OnMouseWheel", Chat_OnMouseWheel)
self.AFKMode.chat:SetScript("OnEvent", Chat_OnEvent)
self.AFKMode.bottom = CreateFrame("Frame", nil, self.AFKMode)
self.AFKMode.bottom:SetFrameLevel(0)
self.AFKMode.bottom:SetTemplate("Transparent")
self.AFKMode.bottom:Point("BOTTOM", self.AFKMode, "BOTTOM", 0, -E.Border)
self.AFKMode.bottom:Width(GetScreenWidth() + (E.Border*2))
self.AFKMode.bottom:Height(GetScreenHeight() * 0.1)
self.AFKMode.bottom.logo = self.AFKMode:CreateTexture(nil, "OVERLAY")
self.AFKMode.bottom.logo:Size(320, 150)
self.AFKMode.bottom.logo:Point("CENTER", self.AFKMode.bottom, "CENTER", 0, 50)
self.AFKMode.bottom.logo:SetTexture(E.Media.Textures.Logo)
self.AFKMode.bottom.faction = self.AFKMode.bottom:CreateTexture(nil, "OVERLAY")
self.AFKMode.bottom.faction:Point("BOTTOMLEFT", self.AFKMode.bottom, "BOTTOMLEFT", -20, -16)
self.AFKMode.bottom.faction:SetTexture("Interface\\AddOns\\ElvUI\\media\\textures\\"..E.myfaction.."-Logo")
self.AFKMode.bottom.faction:Size(140)
local classColor = E.media.herocolor
self.AFKMode.bottom.name = self.AFKMode.bottom:CreateFontString(nil, "OVERLAY")
self.AFKMode.bottom.name:FontTemplate(nil, 20)
self.AFKMode.bottom.name:SetFormattedText("%s - %s", E.myname, E.myrealm)
self.AFKMode.bottom.name:Point("TOPLEFT", self.AFKMode.bottom.faction, "TOPRIGHT", -10, -28)
self.AFKMode.bottom.name:SetTextColor(classColor.r, classColor.g, classColor.b)
self.AFKMode.bottom.guild = self.AFKMode.bottom:CreateFontString(nil, "OVERLAY")
self.AFKMode.bottom.guild:FontTemplate(nil, 20)
self.AFKMode.bottom.guild:SetText(L["No Guild"])
self.AFKMode.bottom.guild:Point("TOPLEFT", self.AFKMode.bottom.name, "BOTTOMLEFT", 0, -6)
self.AFKMode.bottom.guild:SetTextColor(0.7, 0.7, 0.7)
self.AFKMode.bottom.time = self.AFKMode.bottom:CreateFontString(nil, "OVERLAY")
self.AFKMode.bottom.time:FontTemplate(nil, 20)
self.AFKMode.bottom.time:SetText("00:00")
self.AFKMode.bottom.time:Point("TOPLEFT", self.AFKMode.bottom.guild, "BOTTOMLEFT", 0, -6)
self.AFKMode.bottom.time:SetTextColor(0.7, 0.7, 0.7)
self.AFKMode.bottom.model = CreateFrame("PlayerModel", "ElvUIAFKPlayerModel", self.AFKMode.bottom)
self.AFKMode.bottom.model:Point("BOTTOMRIGHT", self.AFKMode.bottom, "BOTTOMRIGHT", 120, -100)
self.AFKMode.bottom.model:Size(800)
self.AFKMode.bottom.model:SetFacing(6)
self.AFKMode.bottom.model:SetUnit("player")
if E.db.general.afk then
self:Toggle()
end
self.Initialized = true
end
local function InitializeCallback()
mod:Initialize()
end
E:RegisterModule(mod:GetName(), InitializeCallback)
+262
View File
@@ -0,0 +1,262 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local M = E:GetModule("Misc")
local CH = E:GetModule("Chat")
--Lua functions
local select, unpack = select, unpack
local format, gmatch, gsub, lower, match = string.format, string.gmatch, string.gsub, string.lower, string.match
--WoW API / Variables
local GetPlayerInfoByGUID = GetPlayerInfoByGUID
local WorldFrame = WorldFrame
local WorldGetChildren = WorldFrame.GetChildren
local WorldGetNumChildren = WorldFrame.GetNumChildren
--Message caches
local messageToGUID = {}
local messageToSender = {}
function M:UpdateBubbleBorder()
if not self.text then return end
if E.private.general.chatBubbles == "backdrop" then
if E.PixelMode then
self:SetBackdropBorderColor(self.text:GetTextColor())
else
local r, g, b = self.text:GetTextColor()
self.bordertop:SetTexture(r, g, b)
self.borderbottom:SetTexture(r, g, b)
self.borderleft:SetTexture(r, g, b)
self.borderright:SetTexture(r, g, b)
end
end
local text = self.text:GetText()
if self.Name then
self.Name:SetText("") --Always reset it
if text and E.private.general.chatBubbleName then
M:AddChatBubbleName(self, messageToGUID[text], messageToSender[text])
end
end
if E.private.chat.enable and E.private.general.classColorMentionsSpeech then
if text and match(text, "%s-%S+%s*") then
local classColorTable, lowerCaseWord, isFirstWord, rebuiltString, tempWord, wordMatch, classMatch
for word in gmatch(text, "%s-%S+%s*") do
tempWord = gsub(word, "^[%s%p]-([^%s%p]+)([%-]?[^%s%p]-)[%s%p]*$", "%1%2")
lowerCaseWord = lower(tempWord)
classMatch = CH.ClassNames[lowerCaseWord]
wordMatch = classMatch and lowerCaseWord
if wordMatch and not E.global.chat.classColorMentionExcludedNames[wordMatch] then
classColorTable = E.media.herocolor
word = gsub(word, gsub(tempWord, "%-", "%%-"), format("\124cff%.2x%.2x%.2x%s\124r", classColorTable.r*255, classColorTable.g*255, classColorTable.b*255, tempWord))
end
if not isFirstWord then
rebuiltString = word
isFirstWord = true
else
rebuiltString = format("%s%s", rebuiltString, word)
end
end
if rebuiltString then
self.text:SetText(rebuiltString)
end
end
end
end
function M:AddChatBubbleName(chatBubble, guid, name)
if not name then return end
local color
if guid and guid ~= "" then
local _, class = GetPlayerInfoByGUID(guid)
if class then
color = E:RGBToHex(E.media.herocolor.r, E.media.herocolor.g, E.media.herocolor.b)
end
else
color = "|cffffffff"
end
chatBubble.Name:SetFormattedText("%s%s|r", color, name)
end
function M:SkinBubble(frame)
local mult = E.mult * UIParent:GetScale()
for i = 1, frame:GetNumRegions() do
local region = select(i, frame:GetRegions())
if region:IsObjectType("Texture") then
region:SetTexture(nil)
elseif region:IsObjectType("FontString") then
frame.text = region
end
end
local name = frame:CreateFontString(nil, "OVERLAY")
if E.private.general.chatBubbles == "backdrop" then
name:SetPoint("TOPLEFT", 5, E.PixelMode and 15 or 18)
else
name:SetPoint("TOPLEFT", 5, 6)
end
name:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -5, -5)
name:SetJustifyH("LEFT")
name:FontTemplate(E.Libs.LSM:Fetch("font", E.private.general.chatBubbleFont), E.private.general.chatBubbleFontSize * 0.85, E.private.general.chatBubbleFontOutline)
frame.Name = name
if E.private.general.chatBubbles == "backdrop" then
if E.PixelMode then
frame:SetBackdrop({
bgFile = E.media.blankTex,
edgeFile = E.media.blankTex,
tile = false, tileSize = 0, edgeSize = mult,
insets = {left = 0, right = 0, top = 0, bottom = 0}
})
frame:SetBackdropColor(unpack(E.media.backdropfadecolor))
frame:SetBackdropBorderColor(0, 0, 0)
else
frame:SetBackdrop(nil)
end
local r, g, b = frame.text:GetTextColor()
if not E.PixelMode then
local mult2 = mult * 2
local mult3 = mult * 3
frame.backdrop = frame:CreateTexture(nil, "BACKGROUND")
frame.backdrop:SetAllPoints(frame)
frame.backdrop:SetTexture(unpack(E.media.backdropfadecolor))
frame.bordertop = frame:CreateTexture(nil, "ARTWORK")
frame.bordertop:SetPoint("TOPLEFT", frame, "TOPLEFT", -mult2, mult2)
frame.bordertop:SetPoint("TOPRIGHT", frame, "TOPRIGHT", mult2, mult2)
frame.bordertop:SetHeight(mult)
frame.bordertop:SetTexture(r, g, b)
frame.bordertop.backdrop = frame:CreateTexture(nil, "BORDER")
frame.bordertop.backdrop:SetPoint("TOPLEFT", frame.bordertop, "TOPLEFT", -mult, mult)
frame.bordertop.backdrop:SetPoint("TOPRIGHT", frame.bordertop, "TOPRIGHT", mult, mult)
frame.bordertop.backdrop:SetHeight(mult3)
frame.bordertop.backdrop:SetTexture(0, 0, 0)
frame.borderbottom = frame:CreateTexture(nil, "ARTWORK")
frame.borderbottom:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", -mult2, -mult2)
frame.borderbottom:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", mult2, -mult2)
frame.borderbottom:SetHeight(mult)
frame.borderbottom:SetTexture(r, g, b)
frame.borderbottom.backdrop = frame:CreateTexture(nil, "BORDER")
frame.borderbottom.backdrop:SetPoint("BOTTOMLEFT", frame.borderbottom, "BOTTOMLEFT", -mult, -mult)
frame.borderbottom.backdrop:SetPoint("BOTTOMRIGHT", frame.borderbottom, "BOTTOMRIGHT", mult, -mult)
frame.borderbottom.backdrop:SetHeight(mult3)
frame.borderbottom.backdrop:SetTexture(0, 0, 0)
frame.borderleft = frame:CreateTexture(nil, "ARTWORK")
frame.borderleft:SetPoint("TOPLEFT", frame, "TOPLEFT", -mult2, mult2)
frame.borderleft:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", mult2, -mult2)
frame.borderleft:SetWidth(mult)
frame.borderleft:SetTexture(r, g, b)
frame.borderleft.backdrop = frame:CreateTexture(nil, "BORDER")
frame.borderleft.backdrop:SetPoint("TOPLEFT", frame.borderleft, "TOPLEFT", -mult, mult)
frame.borderleft.backdrop:SetPoint("BOTTOMLEFT", frame.borderleft, "BOTTOMLEFT", -mult, -mult)
frame.borderleft.backdrop:SetWidth(mult3)
frame.borderleft.backdrop:SetTexture(0, 0, 0)
frame.borderright = frame:CreateTexture(nil, "ARTWORK")
frame.borderright:SetPoint("TOPRIGHT", frame, "TOPRIGHT", mult2, mult2)
frame.borderright:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -mult2, -mult2)
frame.borderright:SetWidth(mult)
frame.borderright:SetTexture(r, g, b)
frame.borderright.backdrop = frame:CreateTexture(nil, "BORDER")
frame.borderright.backdrop:SetPoint("TOPRIGHT", frame.borderright, "TOPRIGHT", mult, mult)
frame.borderright.backdrop:SetPoint("BOTTOMRIGHT", frame.borderright, "BOTTOMRIGHT", mult, -mult)
frame.borderright.backdrop:SetWidth(mult3)
frame.borderright.backdrop:SetTexture(0, 0, 0)
else
frame:SetBackdropColor(unpack(E.media.backdropfadecolor))
frame:SetBackdropBorderColor(r, g, b)
end
frame.text:FontTemplate(E.LSM:Fetch("font", E.private.general.chatBubbleFont), E.private.general.chatBubbleFontSize, E.private.general.chatBubbleFontOutline)
elseif E.private.general.chatBubbles == "backdrop_noborder" then
frame:SetBackdrop(nil)
if not frame.backdrop then
frame.backdrop = frame:CreateTexture(nil, "ARTWORK")
frame.backdrop:SetInside(frame, 4, 4)
frame.backdrop:SetTexture(unpack(E.media.backdropfadecolor))
end
frame.text:FontTemplate(E.LSM:Fetch("font", E.private.general.chatBubbleFont), E.private.general.chatBubbleFontSize, E.private.general.chatBubbleFontOutline)
frame:SetClampedToScreen(false)
elseif E.private.general.chatBubbles == "nobackdrop" then
frame:SetBackdrop(nil)
frame.text:FontTemplate(E.LSM:Fetch("font", E.private.general.chatBubbleFont), E.private.general.chatBubbleFontSize, E.private.general.chatBubbleFontOutline)
frame:SetClampedToScreen(false)
end
frame:HookScript("OnShow", M.UpdateBubbleBorder)
frame:SetFrameStrata("DIALOG")
M.UpdateBubbleBorder(frame)
frame.isSkinnedElvUI = true
end
function M:IsChatBubble(frame)
for i = 1, frame:GetNumRegions() do
local region = select(i, frame:GetRegions())
if region.GetTexture and region:GetTexture() and region:GetTexture() == [[Interface\Tooltips\ChatBubble-Background]] then
return true
end
end
end
local function ChatBubble_OnEvent(self, event, msg, sender, _, _, _, _, _, _, _, _, _, guid)
if not E.private.general.chatBubbleName then return end
messageToGUID[msg] = guid
messageToSender[msg] = sender
end
local lastChildern, numChildren = 0, 0
local function findChatBubbles(...)
for i = lastChildern + 1, numChildren do
local frame = select(i, ...)
if not frame.isSkinnedElvUI and M:IsChatBubble(frame) then
M:SkinBubble(frame)
end
end
end
local function ChatBubble_OnUpdate(self, elapsed)
self.lastupdate = self.lastupdate + elapsed
if self.lastupdate < .1 then return end
self.lastupdate = 0
numChildren = WorldGetNumChildren(WorldFrame)
if lastChildern ~= numChildren then
findChatBubbles(WorldGetChildren(WorldFrame))
lastChildern = numChildren
end
end
function M:LoadChatBubbles()
if E.private.general.chatBubbles == "disabled" then return end
self.BubbleFrame = CreateFrame("Frame")
self.BubbleFrame.lastupdate = -2 -- wait 2 seconds before hooking frames
self.BubbleFrame:RegisterEvent("CHAT_MSG_SAY")
self.BubbleFrame:RegisterEvent("CHAT_MSG_YELL")
self.BubbleFrame:RegisterEvent("CHAT_MSG_PARTY")
self.BubbleFrame:RegisterEvent("CHAT_MSG_PARTY_LEADER")
self.BubbleFrame:RegisterEvent("CHAT_MSG_MONSTER_SAY")
self.BubbleFrame:RegisterEvent("CHAT_MSG_MONSTER_YELL")
self.BubbleFrame:SetScript("OnEvent", ChatBubble_OnEvent)
self.BubbleFrame:SetScript("OnUpdate", ChatBubble_OnUpdate)
end
+162
View File
@@ -0,0 +1,162 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local D = E:GetModule("DebugTools")
--Lua functions
local format = string.format
--WoW API / Variables
local GetCVarBool = GetCVarBool
local InCombatLockdown = InCombatLockdown
function D:ModifyErrorFrame()
ScriptErrorsFrameScrollFrameText.cursorOffset = 0
ScriptErrorsFrameScrollFrameText.cursorHeight = 0
ScriptErrorsFrameScrollFrameText:SetScript("OnEditFocusGained", nil)
local Orig_ScriptErrorsFrame_Update = ScriptErrorsFrame_Update
ScriptErrorsFrame_Update = function(...)
if GetCVarBool("scriptErrors") ~= 1 then
Orig_ScriptErrorsFrame_Update(...)
return
end
-- Sometimes the locals table does not have an entry for an index, which can cause an argument #6 error
-- in Blizzard_DebugTools.lua:430 and then cause a C stack overflow, this will prevent that
local index = ScriptErrorsFrame.index
if not index or not ScriptErrorsFrame.order[index] then
index = #(ScriptErrorsFrame.order)
end
if index > 0 then
ScriptErrorsFrame.locals[index] = ScriptErrorsFrame.locals[index] or "No locals to dump"
end
Orig_ScriptErrorsFrame_Update(...)
-- Stop text highlighting again
ScriptErrorsFrameScrollFrameText:HighlightText(0, 0)
end
-- Unhighlight text when focus is hit
ScriptErrorsFrameScrollFrameText:HookScript("OnEscapePressed", function(self)
self:HighlightText(0, 0)
end)
ScriptErrorsFrame:Size(500, 300)
ScriptErrorsFrameScrollFrame:Size(ScriptErrorsFrame:GetWidth() - 45, ScriptErrorsFrame:GetHeight() - 71)
ScriptErrorsFrameScrollFrameText:Width(ScriptErrorsFrameScrollFrame:GetWidth())
local BUTTON_WIDTH = 75
local BUTTON_HEIGHT = 24
local BUTTON_SPACING = 2
-- Add a first button
local firstButton = CreateFrame("Button", nil, ScriptErrorsFrame, "UIPanelButtonTemplate")
firstButton:SetPoint("BOTTOM", -((BUTTON_WIDTH + BUTTON_WIDTH/2) + (BUTTON_SPACING * 4)), 8)
firstButton:SetText("First")
firstButton:SetHeight(BUTTON_HEIGHT)
firstButton:SetWidth(BUTTON_WIDTH)
firstButton:SetScript("OnClick", function()
ScriptErrorsFrame.index = 1
ScriptErrorsFrame_Update()
end)
ScriptErrorsFrame.firstButton = firstButton
-- Also add a Last button for errors
local lastButton = CreateFrame("Button", nil, ScriptErrorsFrame, "UIPanelButtonTemplate")
lastButton:SetPoint("BOTTOMLEFT", ScriptErrorsFrame.next, "BOTTOMRIGHT", BUTTON_SPACING, 0)
lastButton:SetHeight(BUTTON_HEIGHT)
lastButton:SetWidth(BUTTON_WIDTH)
lastButton:SetText("Last")
lastButton:SetScript("OnClick", function()
ScriptErrorsFrame.index = #(ScriptErrorsFrame.order)
ScriptErrorsFrame_Update()
end)
ScriptErrorsFrame.lastButton = lastButton
ScriptErrorsFrame.previous:ClearAllPoints()
ScriptErrorsFrame.previous:SetPoint("BOTTOMLEFT", firstButton, "BOTTOMRIGHT", BUTTON_SPACING, 0)
ScriptErrorsFrame.previous:SetWidth(BUTTON_WIDTH)
ScriptErrorsFrame.previous:SetHeight(BUTTON_HEIGHT)
ScriptErrorsFrame.next:ClearAllPoints()
ScriptErrorsFrame.next:SetPoint("BOTTOMLEFT", ScriptErrorsFrame.previous, "BOTTOMRIGHT", BUTTON_SPACING, 0)
ScriptErrorsFrame.next:SetWidth(BUTTON_WIDTH)
ScriptErrorsFrame.next:SetHeight(BUTTON_HEIGHT)
ScriptErrorsFrame.close:ClearAllPoints()
ScriptErrorsFrame.close:SetPoint("BOTTOMRIGHT", -8, 8)
ScriptErrorsFrame.close:SetSize(75, BUTTON_HEIGHT)
ScriptErrorsFrame.indexLabel:ClearAllPoints()
ScriptErrorsFrame.indexLabel:SetPoint("BOTTOMLEFT", 0, 12)
end
function D:ScriptErrorsFrame_UpdateButtons()
local numErrors = #ScriptErrorsFrame.order
local index = ScriptErrorsFrame.index
if index == 0 then
ScriptErrorsFrame.lastButton:Disable()
ScriptErrorsFrame.firstButton:Disable()
else
if numErrors == 1 then
ScriptErrorsFrame.lastButton:Disable()
ScriptErrorsFrame.firstButton:Disable()
else
ScriptErrorsFrame.lastButton:Enable()
ScriptErrorsFrame.firstButton:Enable()
end
end
end
function D:ScriptErrorsFrame_OnError(_, keepHidden)
if keepHidden or self.MessagePrinted or not InCombatLockdown() or GetCVarBool("scriptErrors") ~= 1 then return end
E:Print(L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."])
self.MessagePrinted = true
end
function D:PLAYER_REGEN_ENABLED()
ScriptErrorsFrame:SetParent(UIParent)
self.MessagePrinted = nil
end
function D:PLAYER_REGEN_DISABLED()
ScriptErrorsFrame:SetParent(self.HideFrame)
end
function D:TaintError(event, addonName, addonFunc)
if GetCVarBool("scriptErrors") ~= 1 or E.db.general.taintLog ~= true then return end
ScriptErrorsFrame_OnError(format(L["%s: %s tried to call the protected function '%s'."], event, addonName or "<name>", addonFunc or "<func>"), false)
end
function D:StaticPopup_Show(name)
if name == "ADDON_ACTION_FORBIDDEN" and E.db.general.taintLog ~= true then
StaticPopup_Hide(name)
end
end
function D:Initialize()
self.Initialized = true
self.HideFrame = CreateFrame("Frame")
self.HideFrame:Hide()
if not IsAddOnLoaded("Blizzard_DebugTools") then
LoadAddOn("Blizzard_DebugTools")
end
self:ModifyErrorFrame()
self:SecureHook("ScriptErrorsFrame_UpdateButtons")
self:SecureHook("ScriptErrorsFrame_OnError")
self:SecureHook("StaticPopup_Show")
self:RegisterEvent("PLAYER_REGEN_DISABLED")
self:RegisterEvent("PLAYER_REGEN_ENABLED")
self:RegisterEvent("ADDON_ACTION_BLOCKED", "TaintError")
self:RegisterEvent("ADDON_ACTION_FORBIDDEN", "TaintError")
end
local function InitializeCallback()
D:Initialize()
end
E:RegisterModule(D:GetName(), InitializeCallback)
+13
View File
@@ -0,0 +1,13 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="Misc.lua"/>
<Script file="DebugTools.lua"/>
<Script file="ChatBubbles.lua"/>
<Script file="Raidmarker.lua"/>
<Script file="Loot.lua"/>
<Script file="LootRoll.lua"/>
<Script file="Raidbuffreminder.lua"/>
<Script file="Threat.lua"/>
<Script file="TotemBar.lua"/>
<Script file="RaidUtility.lua"/>
<Script file="AFK.lua"/>
</Ui>
+352
View File
@@ -0,0 +1,352 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local M = E:GetModule("Misc")
--Lua functions
local unpack, pairs = unpack, pairs
local max = math.max
local find, gsub = string.find, string.gsub
local tinsert = table.insert
--WoW API / Variables
local CloseLoot = CloseLoot
local CreateFrame = CreateFrame
local CursorOnUpdate = CursorOnUpdate
local CursorUpdate = CursorUpdate
local GetCVar = GetCVar
local GetCursorPosition = GetCursorPosition
local GetLootSlotInfo = GetLootSlotInfo
local GetLootSlotLink = GetLootSlotLink
local GetNumLootItems = GetNumLootItems
local GiveMasterLoot = GiveMasterLoot
local HandleModifiedItemClick = HandleModifiedItemClick
local IsFishingLoot = IsFishingLoot
local IsModifiedClick = IsModifiedClick
local LootSlot = LootSlot
local LootSlotIsItem = LootSlotIsItem
local ResetCursor = ResetCursor
local StaticPopup_Hide = StaticPopup_Hide
local ToggleDropDownMenu = ToggleDropDownMenu
local UnitIsDead = UnitIsDead
local UnitIsFriend = UnitIsFriend
local UnitName = UnitName
local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS
local TEXTURE_ITEM_QUEST_BANG = TEXTURE_ITEM_QUEST_BANG
local LOOT = LOOT
-- Credit Haste
local lootFrame, lootFrameHolder
local iconSize = 30
local sq, ss, sn
local OnEnter = function(self)
local slot = self:GetID()
if LootSlotIsItem(slot) then
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
GameTooltip:SetLootItem(slot)
CursorUpdate(self)
end
self.drop:Show()
self.drop:SetVertexColor(1, 1, 1)
end
local OnLeave = function(self)
if self.quality and (self.quality > 1) then
local color = ITEM_QUALITY_COLORS[self.quality]
self.drop:SetVertexColor(color.r, color.g, color.b)
else
self.drop:Hide()
end
GameTooltip:Hide()
ResetCursor()
end
local OnClick = function(self)
LootFrame.selectedQuality = self.quality
LootFrame.selectedItemName = self.name:GetText()
LootFrame.selectedSlot = self:GetID()
LootFrame.selectedLootButton = self:GetName()
if IsModifiedClick() then
HandleModifiedItemClick(GetLootSlotLink(self:GetID()))
else
StaticPopup_Hide("CONFIRM_LOOT_DISTRIBUTION")
ss = self:GetID()
sq = self.quality
sn = self.name:GetText()
LootSlot(ss)
end
end
local OnShow = function(self)
if GameTooltip:IsOwned(self) then
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
GameTooltip:SetLootItem(self:GetID())
CursorOnUpdate(self)
end
end
local function anchorSlots(self)
local shownSlots = 0
for i = 1, #self.slots do
local frame = self.slots[i]
if frame:IsShown() then
shownSlots = shownSlots + 1
frame:Point("TOP", lootFrame, 4, (-8 + iconSize) - (shownSlots * iconSize))
end
end
self:Height(max(shownSlots * iconSize + 16, 20))
end
local function createSlot(id)
local frame = CreateFrame("Button", "ElvLootSlot"..id, lootFrame)
frame:Point("LEFT", 8, 0)
frame:Point("RIGHT", -8, 0)
frame:Height(iconSize - 2)
frame:SetID(id)
frame:RegisterForClicks("LeftButtonUp", "RightButtonUp")
frame:SetScript("OnEnter", OnEnter)
frame:SetScript("OnLeave", OnLeave)
frame:SetScript("OnClick", OnClick)
frame:SetScript("OnShow", OnShow)
local iconFrame = CreateFrame("Frame", nil, frame)
iconFrame:Size(iconSize - 2)
iconFrame:Point("RIGHT", frame)
iconFrame:SetTemplate("Default")
frame.iconFrame = iconFrame
E.frames[iconFrame] = nil
local icon = iconFrame:CreateTexture(nil, "ARTWORK")
icon:SetTexCoord(unpack(E.TexCoords))
icon:SetInside()
frame.icon = icon
local count = iconFrame:CreateFontString(nil, "OVERLAY")
count:SetJustifyH("RIGHT")
count:Point("BOTTOMRIGHT", iconFrame, -2, 2)
count:FontTemplate(nil, nil, "OUTLINE")
count:SetText(1)
frame.count = count
local name = frame:CreateFontString(nil, "OVERLAY")
name:SetJustifyH("LEFT")
name:Point("LEFT", frame)
name:Point("RIGHT", icon, "LEFT")
name:SetNonSpaceWrap(true)
name:FontTemplate(nil, nil, "OUTLINE")
frame.name = name
local drop = frame:CreateTexture(nil, "ARTWORK")
drop:SetTexture(1, 1, 1, 0.15)
drop:Point("LEFT", icon, "RIGHT", 0, 0)
drop:Point("RIGHT", frame)
drop:SetAllPoints(frame)
frame.drop = drop
local questTexture = iconFrame:CreateTexture(nil, "OVERLAY")
questTexture:SetInside()
questTexture:SetTexture(TEXTURE_ITEM_QUEST_BANG)
questTexture:SetTexCoord(unpack(E.TexCoords))
frame.questTexture = questTexture
lootFrame.slots[id] = frame
return frame
end
function M:LOOT_SLOT_CLEARED(_, slot)
if not lootFrame:IsShown() then return end
lootFrame.slots[slot]:Hide()
anchorSlots(lootFrame)
end
function M:LOOT_CLOSED()
StaticPopup_Hide("LOOT_BIND")
lootFrame:Hide()
for _, v in pairs(lootFrame.slots) do
v:Hide()
end
end
function M:OPEN_MASTER_LOOT_LIST()
ToggleDropDownMenu(1, nil, GroupLootDropDown, lootFrame.slots[ss], 0, 0)
end
function M:UPDATE_MASTER_LOOT_LIST()
UIDropDownMenu_Refresh(GroupLootDropDown)
end
function M:LOOT_OPENED(_, autoLoot)
lootFrame:Show()
if not lootFrame:IsShown() then
CloseLoot(autoLoot == 0)
end
local items = GetNumLootItems()
if IsFishingLoot() then
lootFrame.title:SetText(L["Fishy Loot"])
elseif not UnitIsFriend("player", "target") and UnitIsDead("target") then
lootFrame.title:SetText(UnitName("target"))
else
lootFrame.title:SetText(LOOT)
end
-- Blizzard uses strings here
if GetCVar("lootUnderMouse") == "1" then
local x, y = GetCursorPosition()
x = x / lootFrame:GetEffectiveScale()
y = y / lootFrame:GetEffectiveScale()
lootFrame:ClearAllPoints()
lootFrame:Point("TOPLEFT", UIParent, "BOTTOMLEFT", x - 40, y + 20)
lootFrame:GetCenter()
lootFrame:Raise()
E:DisableMover("LootFrameMover")
else
lootFrame:ClearAllPoints()
lootFrame:Point("TOPLEFT", lootFrameHolder, "TOPLEFT")
E:EnableMover("LootFrameMover")
end
local m, w, t = 0, 0, lootFrame.title:GetStringWidth()
if items > 0 then
for i = 1, items do
local slot = lootFrame.slots[i] or createSlot(i)
local texture, item, quantity, quality, _, isQuestItem, questId, isActive = GetLootSlotInfo(i)
local color = ITEM_QUALITY_COLORS[quality]
if texture and find(texture, "INV_Misc_Coin") then
item = gsub(item, "\n", ", ")
end
if quantity and (quantity > 1) then
slot.count:SetText(quantity)
slot.count:Show()
else
slot.count:Hide()
end
if quality and (quality > 1) then
slot.drop:SetVertexColor(color.r, color.g, color.b)
slot.drop:Show()
else
slot.drop:Hide()
end
slot.quality = quality
slot.name:SetText(item)
if color then
slot.name:SetTextColor(color.r, color.g, color.b)
end
slot.icon:SetTexture(texture)
if quality then
m = max(m, quality)
end
w = max(w, slot.name:GetStringWidth())
local questTexture = slot.questTexture
if questId and not isActive then
questTexture:SetTexture(TEXTURE_ITEM_QUEST_BANG)
questTexture:Show()
elseif questId or isQuestItem then
questTexture:SetTexture(TEXTURE_ITEM_QUEST_BORDER)
questTexture:Show()
else
questTexture:Hide()
end
-- Check for FasterLooting scripts or w/e (if bag is full)
if texture then
slot:Enable()
slot:Show()
end
end
else
local slot = lootFrame.slots[1] or createSlot(1)
local color = ITEM_QUALITY_COLORS[0]
slot.name:SetText(L["Empty Slot"])
if color then
slot.name:SetTextColor(color.r, color.g, color.b)
end
slot.icon:SetTexture[[Interface\Icons\INV_Misc_Herb_AncientLichen]]
w = max(w, slot.name:GetStringWidth())
slot.count:Hide()
slot.drop:Hide()
slot:Disable()
slot:Show()
end
anchorSlots(lootFrame)
w = w + 60
t = t + 5
local color = ITEM_QUALITY_COLORS[m]
lootFrame:SetBackdropBorderColor(color.r, color.g, color.b, .8)
lootFrame:Width(max(w, t))
end
function M:LoadLoot()
if not E.private.general.loot then return end
lootFrameHolder = CreateFrame("Frame", "ElvLootFrameHolder", E.UIParent)
lootFrameHolder:Point("TOP", 0, -50)
lootFrameHolder:Size(150, 22)
lootFrame = CreateFrame("Button", "ElvLootFrame", lootFrameHolder)
lootFrame:SetClampedToScreen(true)
lootFrame:SetPoint("TOPLEFT")
lootFrame:Size(256, 64)
lootFrame:SetTemplate("Transparent")
lootFrame:SetFrameStrata("DIALOG")
lootFrame:SetToplevel(true)
lootFrame.title = lootFrame:CreateFontString(nil, "OVERLAY")
lootFrame.title:FontTemplate(nil, nil, "OUTLINE")
lootFrame.title:Point("BOTTOMLEFT", lootFrame, "TOPLEFT", 0, 1)
lootFrame.slots = {}
lootFrame:SetScript("OnHide", function()
StaticPopup_Hide("CONFIRM_LOOT_DISTRIBUTION")
CloseLoot()
end)
E.frames[lootFrame] = nil
self:RegisterEvent("LOOT_OPENED")
self:RegisterEvent("LOOT_SLOT_CLEARED")
self:RegisterEvent("LOOT_CLOSED")
self:RegisterEvent("OPEN_MASTER_LOOT_LIST")
self:RegisterEvent("UPDATE_MASTER_LOOT_LIST")
E:CreateMover(lootFrameHolder, "LootFrameMover", L["Loot Frame"], nil, nil, nil, nil, nil, "general,blizzUIImprovements")
-- Fuzz
LootFrame:UnregisterAllEvents()
tinsert(UISpecialFrames, "ElvLootFrame")
function _G.GroupLootDropDown_GiveLoot(self)
if sq >= MASTER_LOOT_THREHOLD then
local dialog = StaticPopup_Show("CONFIRM_LOOT_DISTRIBUTION", ITEM_QUALITY_COLORS[sq].hex..sn..FONT_COLOR_CODE_CLOSE, self:GetText())
if dialog then
dialog.data = self.value
end
else
GiveMasterLoot(ss, self.value)
end
CloseDropDownMenus()
end
E.PopupDialogs.CONFIRM_LOOT_DISTRIBUTION.OnAccept = function(_, data)
GiveMasterLoot(ss, data)
end
StaticPopupDialogs.CONFIRM_LOOT_DISTRIBUTION.preferredIndex = 3
end
+474
View File
@@ -0,0 +1,474 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local M = E:GetModule("Misc")
--Lua functions
local pairs, ipairs, unpack = pairs, ipairs, unpack
local find, format = string.find, string.format
local tinsert, twipe = table.insert, table.wipe
--WoW API / Variables
local ChatEdit_InsertLink = ChatEdit_InsertLink
local CreateFrame = CreateFrame
local CursorOnUpdate = CursorOnUpdate
local CursorUpdate = CursorUpdate
local DressUpItemLink = DressUpItemLink
local GetLootRollItemInfo = GetLootRollItemInfo
local GetLootRollItemLink = GetLootRollItemLink
local GetLootRollTimeLeft = GetLootRollTimeLeft
local IsModifiedClick = IsModifiedClick
local ResetCursor = ResetCursor
local RollOnLoot = RollOnLoot
local SetDesaturation = SetDesaturation
local UnitClass = UnitClass
local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS
local ROLL_DISENCHANT = ROLL_DISENCHANT
local POSITION = "TOP"
local FRAME_WIDTH, FRAME_HEIGHT = 328, 28
M.RollBars = {}
local locale = GetLocale()
local rollMessages = locale == "deDE" and {
["(.*) passt automatisch bei (.+), weil [ersi]+ den Gegenstand nicht benutzen kann.$"] = 0,
["(.*) würfelt nicht für: (.+|r)$"] = 0,
["(.*) hat für (.+) 'Bedarf' ausgewählt"] = 1,
["(.*) hat für (.+) 'Gier' ausgewählt"] = 2,
["(.*) hat für '(.+)' Entzauberung gewählt."] = 3,
} or locale == "frFR" and {
["(.*) a passé pour : (.+) parce qu'((il)|(elle)) ne peut pas ramasser cette objet.$"] = 0,
["(.*) a passé pour : (.+)"] = 0,
["(.*) a choisi Besoin pour : (.+)"] = 1,
["(.*) a choisi Cupidité pour : (.+)"] = 2,
["(.*) a choisi Désenchantement pour : (.+)"] = 3,
} or locale == "zhCN" and {
["(.*)自动放弃了:(.+),因为他无法拾取该物品$"] = 0,
["(.*)自动放弃了:(.+),因为她无法拾取该物品$"] = 0,
["(.*)放弃了:(.+)"] = 0,
["(.*)选择了需求取向:(.+)"] = 1,
["(.*)选择了贪婪取向:(.+)"] = 2,
["(.*)选择了分解取向:(.+)"] = 3,
} or locale == "zhTW" and {
["(.*)自動放棄:(.+),因為他無法拾取該物品$"] = 0,
["(.*)自動放棄:(.+),因為她無法拾取該物品$"] = 0,
["(.*)放棄了:(.+)"] = 0,
["(.*)選擇了需求:(.+)"] = 1,
["(.*)選擇了貪婪:(.+)"] = 2,
["(.*)選擇了分解:(.+)"] = 3,
} or locale == "ruRU" and {
["(.*) автоматически передает предмет (.+), поскольку не может его забрать"] = 0,
["(.*) пропускает розыгрыш предмета \"(.+)\", поскольку не может его забрать"] = 0,
["(.*) отказывается от предмета (.+)%."] = 0,
["Разыгрывается: (.+)%. (.*): \"Мне это нужно\""] = 1,
["Разыгрывается: (.+)%. (.*): \"Не откажусь\""] = 2,
["Разыгрывается: (.+)%. (.*): \"Распылить\""] = 3,
} or locale == "koKR" and {
["(.*)님이 획득할 수 없는 아이템이어서 자동으로 주사위 굴리기를 포기했습니다: (.+)"] = 0,
["(.*)님이 주사위 굴리기를 포기했습니다: (.+)"] = 0,
["(.*)님이 입찰을 선택했습니다: (.+)"] = 1,
["(.*)님이 차비를 선택했습니다: (.+)"] = 2,
["(.*)님이 마력 추출을 선택했습니다: (.+)"] = 3,
} or locale == "esES" and {
["^(.*) pasó automáticamente de: (.+) porque no puede despojar este objeto.$"] = 0,
["^(.*) pasó de: (.+|r)$"] = 0,
["(.*) eligió Necesidad para: (.+)"] = 1,
["(.*) eligió Codicia para: (.+)"] = 2,
["(.*) eligió Desencantar para: (.+)"] = 3,
} or locale == "esMX" and {
["^(.*) pasó automáticamente de: (.+) porque no puede despojar este objeto.$"] = 0,
["^(.*) pasó de: (.+|r)$"] = 0,
["(.*) eligió Necesidad para: (.+)"] = 1,
["(.*) eligió Codicia para: (.+)"] = 2,
["(.*) eligió Desencantar para: (.+)"] = 3,
} or {
["^(.*) automatically passed on: (.+) because s?he cannot loot that item.$"] = 0,
["^(.*) passed on: (.+|r)$"] = 0,
["(.*) has selected Need for: (.+)"] = 1,
["(.*) has selected Greed for: (.+)"] = 2,
["(.*) has selected Disenchant for: (.+)"] = 3
}
local rollTypes = {
[0] = {
tooltipText = PASS,
normalTexture = "Interface\\Buttons\\UI-GroupLoot-Pass-Up",
pushedTexture = "Interface\\Buttons\\UI-GroupLoot-Pass-Down",
highlightTexture = nil,
},
[1] = {
tooltipText = NEED,
newbieText = NEED_NEWBIE,
normalTexture = "Interface\\Buttons\\UI-GroupLoot-Dice-Up",
pushedTexture = "Interface\\Buttons\\UI-GroupLoot-Dice-Down",
highlightTexture = "Interface\\Buttons\\UI-GroupLoot-Dice-Highlight",
},
[2] = {
tooltipText = GREED,
newbieText = GREED_NEWBIE,
normalTexture = "Interface\\Buttons\\UI-GroupLoot-Coin-Up",
pushedTexture = "Interface\\Buttons\\UI-GroupLoot-Coin-Down",
highlightTexture = "Interface\\Buttons\\UI-GroupLoot-Coin-Highlight",
},
[3] = {
tooltipText = ROLL_DISENCHANT,
newbieText = ROLL_DISENCHANT_NEWBIE,
normalTexture = "Interface\\Buttons\\UI-GroupLoot-DE-Up",
pushedTexture = "Interface\\Buttons\\UI-GroupLoot-DE-Down",
highlightTexture = "Interface\\Buttons\\UI-GroupLoot-DE-Highlight",
},
}
local reasons = {
LOOT_ROLL_INELIGIBLE_REASON1,
LOOT_ROLL_INELIGIBLE_REASON2,
LOOT_ROLL_INELIGIBLE_REASON3,
LOOT_ROLL_INELIGIBLE_REASON4,
LOOT_ROLL_INELIGIBLE_REASON5,
}
local function buttonOnEnter(self)
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
GameTooltip:SetText(self.tooltipText)
if self.newbieText and SHOW_NEWBIE_TIPS == "1" then
GameTooltip:AddLine(self.newbieText, 1, 0.82, 0, true)
end
if self:IsEnabled() == 0 then
GameTooltip:AddLine(self.reason, 1, 0.1, 0.1, true)
end
for playerName, rollData in pairs(self.parent.rollResults) do
if self.rollType == rollData[1] and rollData[2] then
local classColor = E.media.herocolor
GameTooltip:AddLine(playerName, classColor.r, classColor.g, classColor.b)
end
end
GameTooltip:Show()
end
local function buttonOnLeave()
GameTooltip:Hide()
end
local function buttonOnClick(self)
RollOnLoot(self.parent.rollID, self.rollType)
end
local function toggleLootButton(self, state, reason, reasonValue)
if state then
self:Enable()
self:SetAlpha(1)
self.reason = nil
SetDesaturation(self:GetNormalTexture(), false)
else
self:Disable()
self:SetAlpha(0.2)
self.reason = reasonValue and format(reasons[reason], reasonValue) or reasons[reason]
SetDesaturation(self:GetNormalTexture(), true)
end
end
local function increaseRollCount(self, count)
local text = self.text:GetText()
if not text or text == "" then
self.text:SetText(count or 1)
else
self.text:SetText(self.text:GetText() + (count or 1))
end
end
function M:CreateRollButton(parent, rollType)
local data = rollTypes[rollType]
local button = CreateFrame("Button", nil, parent)
button:Size(FRAME_HEIGHT - 4)
button:SetNormalTexture(data.normalTexture)
button:SetPushedTexture(data.highlightTexture)
button:SetHighlightTexture(data.pushedTexture)
button:SetMotionScriptsWhileDisabled(true)
button:SetScript("OnEnter", buttonOnEnter)
button:SetScript("OnLeave", buttonOnLeave)
button:SetScript("OnClick", buttonOnClick)
button.ToggleLootButton = toggleLootButton
button.IncreaseRollCount = increaseRollCount
button.parent = parent
button.rollType = rollType
button.tooltipText = data.tooltipText
button.newbieText = data.newbieText
button.text = button:CreateFontString(nil, nil)
button.text:FontTemplate(E.Media.Fonts.Homespun, nil, "MONOCHROMEOUTLINE")
return button
end
local function itemOnEnter(self)
GameTooltip:SetOwner(self, POSITION == "TOP" and "ANCHOR_BOTTOMLEFT" or "ANCHOR_TOPLEFT")
GameTooltip:SetLootRollItem(self.rollID)
CursorUpdate(self)
end
local function itemOnLeave()
GameTooltip:Hide()
ResetCursor()
end
local function itemOnUpdate(self)
if GameTooltip:IsOwned(self) then
GameTooltip:SetOwner(self, POSITION == "TOP" and "ANCHOR_BOTTOMLEFT" or "ANCHOR_TOPLEFT")
GameTooltip:SetLootRollItem(self.rollID)
end
CursorOnUpdate(self)
end
local function itemOnClick(self)
if IsModifiedClick("CHATLINK") then
ChatEdit_InsertLink(self.link)
elseif IsModifiedClick("DRESSUP") then
DressUpItemLink(self.link)
end
end
local function statusbarOnUpdate(self)
local timeLeft = GetLootRollTimeLeft(self.parent.rollID)
if timeLeft < 0 or timeLeft > self.parent.rollTime then
timeLeft = 0
else
self.spark:Point("CENTER", self, "LEFT", (timeLeft / self.parent.rollTime) * self:GetWidth(), 0)
end
self:SetValue(timeLeft)
end
function M:CreateRollFrame()
self.numFrames = self.numFrames + 1
local frame = CreateFrame("Frame", format("ElvUI_GroupLootFrame%d", self.numFrames), E.UIParent)
frame:Size(FRAME_WIDTH, FRAME_HEIGHT)
frame:SetTemplate()
frame:SetFrameStrata("DIALOG")
frame:Hide()
if POSITION == "TOP" then
frame:Point("TOP", self.numFrames > 1 and self.RollBars[self.numFrames - 1] or AlertFrameHolder, "BOTTOM", 0, -4)
else
frame:Point("BOTTOM", self.numFrames > 1 and self.RollBars[self.numFrames - 1] or AlertFrameHolder, "TOP", 0, 4)
end
local itemButton = CreateFrame("Button", "$parentIconFrame", frame)
itemButton:Size(FRAME_HEIGHT - (E.Border * 2))
itemButton:Point("RIGHT", frame, "LEFT", -(E.Spacing * 3), 0)
itemButton:CreateBackdrop()
itemButton:SetScript("OnEnter", itemOnEnter)
itemButton:SetScript("OnLeave", itemOnLeave)
itemButton:SetScript("OnUpdate", itemOnUpdate)
itemButton:SetScript("OnClick", itemOnClick)
itemButton.hasItem = 1
frame.itemButton = itemButton
itemButton.icon = itemButton:CreateTexture(nil, "OVERLAY")
itemButton.icon:SetAllPoints()
itemButton.icon:SetTexCoord(unpack(E.TexCoords))
local fade = frame:CreateTexture(nil, "BORDER")
fade:Point("TOPLEFT", frame, "TOPLEFT", 4, 0)
fade:Point("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -4, 0)
fade:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
fade:SetBlendMode("ADD")
fade:SetGradientAlpha("VERTICAL", 0.1, 0.1, 0.1, 0, 0.1, 0.1, 0.1, 0)
frame.fade = fade
local status = CreateFrame("StatusBar", "$parentStatusBar", frame)
status:SetInside()
status:SetFrameLevel(status:GetFrameLevel() - 1)
status:SetStatusBarTexture(E.media.normTex)
status:SetStatusBarColor(0.8, 0.8, 0.8, 0.9)
status.parent = frame
E:RegisterStatusBar(status)
status:SetScript("OnUpdate", statusbarOnUpdate)
frame.status = status
status.bg = status:CreateTexture(nil, "BACKGROUND")
status.bg:SetAlpha(0.1)
status.bg:SetAllPoints()
local spark = frame:CreateTexture(nil, "OVERLAY")
spark:Size(14, FRAME_HEIGHT)
spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
spark:SetBlendMode("ADD")
status.spark = spark
frame.passButton = self:CreateRollButton(frame, 0)
frame.needButton = self:CreateRollButton(frame, 1)
frame.greedButton = self:CreateRollButton(frame, 2)
frame.disenchantButton = self:CreateRollButton(frame, 3)
frame.needButton:SetHitRectInsets(0, 0, -2, 0)
frame.greedButton:SetHitRectInsets(0, 0, -3, 1)
frame.disenchantButton:SetHitRectInsets(0, 0, -2, 0)
frame.passButton:SetHitRectInsets(0, 0, 0, -2)
frame.needButton:Point("LEFT", frame.itemButton, "RIGHT", 4, -1)
frame.greedButton:Point("LEFT", frame.needButton, "RIGHT", 1, -1)
frame.disenchantButton:Point("LEFT", frame.greedButton, "RIGHT", 0, 1)
frame.passButton:Point("LEFT", frame.disenchantButton, "RIGHT", 0, 2)
frame.needButton.text:Point("CENTER", -1, 4)
frame.greedButton.text:Point("CENTER", 1, 5)
frame.disenchantButton.text:Point("CENTER", 1, 4)
frame.passButton.text:Point("CENTER", 1, 2)
frame.bindText = frame:CreateFontString()
frame.bindText:Point("LEFT", frame.passButton, "RIGHT", 2, 0)
frame.bindText:FontTemplate(nil, nil, "OUTLINE")
local itemName = frame:CreateFontString(nil, "ARTWORK")
itemName:FontTemplate(nil, nil, "OUTLINE")
itemName:Point("LEFT", frame.bindText, "RIGHT", 1, 0)
itemName:Point("RIGHT", frame, "RIGHT", -5, 0)
itemName:Size(200, 10)
itemName:SetJustifyH("LEFT")
frame.itemName = itemName
frame.rollResults = {}
frame.rollButtons = {
[0] = frame.passButton,
[1] = frame.needButton,
[2] = frame.greedButton,
[3] = frame.disenchantButton,
}
tinsert(self.RollBars, frame)
return frame
end
function M:ReleaseFrame(frame)
frame:Hide()
frame.rollID = nil
frame.rollTime = nil
for i = 0, 3 do
frame.rollButtons[i].text:SetText("")
end
twipe(frame.rollResults)
end
function M:GetFrame()
for _, frame in ipairs(M.RollBars) do
if not frame.rollID then
return frame
end
end
return self:CreateRollFrame()
end
function M:START_LOOT_ROLL(_, rollID, rollTime)
local f = self:GetFrame()
f.rollID = rollID
f.rollTime = rollTime
local texture, name, count, quality, bindOnPickUp, canNeed, canGreed, canDisenchant, reasonNeed, reasonGreed, reasonDisenchant, deSkillRequired = GetLootRollItemInfo(rollID)
f.itemButton.icon:SetTexture(texture)
f.itemButton.rollID = rollID
f.itemButton.link = GetLootRollItemLink(rollID)
if count > 1 then
f.itemName:SetFormattedText("%dx %s", count, name)
else
f.itemName:SetText(name)
end
f.status:SetMinMaxValues(0, rollTime)
f.status:SetValue(rollTime)
local color = ITEM_QUALITY_COLORS[quality]
f.status:SetStatusBarColor(color.r, color.g, color.b, 0.7)
f.status.bg:SetTexture(color.r, color.g, color.b)
f.bindText:SetText(bindOnPickUp and "BoP" or "BoE")
f.bindText:SetVertexColor(bindOnPickUp and 1 or 0.3, bindOnPickUp and 0.3 or 1, bindOnPickUp and 0.1 or 0.3)
f.needButton:ToggleLootButton(canNeed, reasonNeed)
f.greedButton:ToggleLootButton(canGreed, reasonGreed)
f.disenchantButton:ToggleLootButton(canDisenchant, reasonDisenchant, deSkillRequired)
f:Show()
AlertFrame_FixAnchors()
if E.db.general.autoRoll and E.mylevel == MAX_PLAYER_LEVEL and quality == 2 and not bindOnPickUp then
if canDisenchant then
RollOnLoot(rollID, 3)
else
RollOnLoot(rollID, 2)
end
end
end
function M:CANCEL_LOOT_ROLL(_, rollID)
for _, frame in ipairs(self.RollBars) do
if frame.rollID == rollID then
self:ReleaseFrame(frame)
E:StaticPopup_Hide("CONFIRM_LOOT_ROLL", self.rollID)
break
end
end
end
function M:ParseRollChoice(msg)
for regex, rollType in pairs(rollMessages) do
local _, _, playerName, itemName = find(msg, regex)
if playerName and itemName and playerName ~= "Everyone" then
if locale == "ruRU" and rollType ~= 0 then
playerName, itemName = itemName, playerName
end
return playerName, itemName, rollType
end
end
end
function M:CHAT_MSG_LOOT(_, msg)
local playerName, itemName, rollType = self:ParseRollChoice(msg)
if playerName and itemName then
local _, class = UnitClass(playerName)
for _, frame in ipairs(self.RollBars) do
if frame.rollID and frame.itemButton.link == itemName and not frame.rollResults[playerName] then
frame.rollResults[playerName] = {rollType, class}
frame.rollButtons[rollType]:IncreaseRollCount()
break
end
end
end
end
function M:LoadLootRoll()
if not E.private.general.lootRoll then return end
self.numFrames = 0
self:RegisterEvent("CHAT_MSG_LOOT")
self:RegisterEvent("START_LOOT_ROLL")
self:RegisterEvent("CANCEL_LOOT_ROLL")
UIParent:UnregisterEvent("START_LOOT_ROLL")
UIParent:UnregisterEvent("CANCEL_LOOT_ROLL")
for i = 1, NUM_GROUP_LOOT_FRAMES do
_G["GroupLootFrame"..i]:UnregisterEvent("CANCEL_LOOT_ROLL")
end
end
+355
View File
@@ -0,0 +1,355 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local M = E:GetModule("Misc")
local Bags = E:GetModule("Bags")
--Lua functions
local ipairs = ipairs
local format = string.format
--WoW API / Variables
local AcceptGroup = AcceptGroup
local CanGuildBankRepair = CanGuildBankRepair
local CanMerchantRepair = CanMerchantRepair
local GetCVarBool, SetCVar = GetCVarBool, SetCVar
local GetFriendInfo = GetFriendInfo
local GetGuildBankMoney = GetGuildBankMoney
local GetGuildBankWithdrawMoney = GetGuildBankWithdrawMoney
local GetGuildRosterInfo = GetGuildRosterInfo
local GetMoney = GetMoney
local GetNumFriends = GetNumFriends
local GetNumGuildMembers = GetNumGuildMembers
local GetNumPartyMembers = GetNumPartyMembers
local GetNumRaidMembers = GetNumRaidMembers
local GetPartyMember = GetPartyMember
local GetRaidRosterInfo = GetRaidRosterInfo
local GetRepairAllCost = GetRepairAllCost
local GuildRoster = GuildRoster
local HideRepairCursor = HideRepairCursor
local InCombatLockdown = InCombatLockdown
local IsInGuild = IsInGuild
local IsInInstance = IsInInstance
local IsShiftKeyDown = IsShiftKeyDown
local LeaveParty = LeaveParty
local PickupInventoryItem = PickupInventoryItem
local RaidNotice_AddMessage = RaidNotice_AddMessage
local RepairAllItems = RepairAllItems
local SendChatMessage = SendChatMessage
local ShowFriends = ShowFriends
local ShowRepairCursor = ShowRepairCursor
local StaticPopup_Hide = StaticPopup_Hide
local UninviteUnit = UninviteUnit
local UnitGUID = UnitGUID
local UnitName = UnitName
local MAX_PARTY_MEMBERS = MAX_PARTY_MEMBERS
do
local function EventHandler(event)
if event == "PLAYER_REGEN_DISABLED" then
UIErrorsFrame:UnregisterEvent("UI_ERROR_MESSAGE")
else
UIErrorsFrame:RegisterEvent("UI_ERROR_MESSAGE")
end
end
function M:ToggleErrorHandling()
if E.db.general.hideErrorFrame then
self:RegisterEvent("PLAYER_REGEN_ENABLED", EventHandler)
self:RegisterEvent("PLAYER_REGEN_DISABLED", EventHandler)
else
self:UnregisterEvent("PLAYER_REGEN_ENABLED", EventHandler)
self:UnregisterEvent("PLAYER_REGEN_DISABLED", EventHandler)
end
end
end
do
local interruptMsg = INTERRUPTED.." %s's \124cff71d5ff\124Hspell:%d\124h[%s]\124h\124r!"
function M:ToggleInterruptAnnounce()
if E.db.general.interruptAnnounce == "NONE" then
self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
else
self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
end
end
function M:COMBAT_LOG_EVENT_UNFILTERED(_, _, event, sourceGUID, _, _, _, destName, _, _, _, _, spellID, spellName)
if not (event == "SPELL_INTERRUPT" and (sourceGUID == E.myguid or sourceGUID == UnitGUID("pet"))) then return end
if E.db.general.interruptAnnounce == "SAY" then
SendChatMessage(format(interruptMsg, destName, spellID, spellName), "SAY")
elseif E.db.general.interruptAnnounce == "EMOTE" then
SendChatMessage(format(interruptMsg, destName, spellID, spellName), "EMOTE")
else
local _, instanceType = IsInInstance()
local battleground = instanceType == "pvp"
if E.db.general.interruptAnnounce == "PARTY" then
if GetNumPartyMembers() > 0 then
SendChatMessage(format(interruptMsg, destName, spellID, spellName), battleground and "BATTLEGROUND" or "PARTY")
end
elseif E.db.general.interruptAnnounce == "RAID" then
if GetNumRaidMembers() > 0 then
SendChatMessage(format(interruptMsg, destName, spellID, spellName), battleground and "BATTLEGROUND" or "RAID")
elseif GetNumPartyMembers() > 0 then
SendChatMessage(format(interruptMsg, destName, spellID, spellName), battleground and "BATTLEGROUND" or "PARTY")
end
elseif E.db.general.interruptAnnounce == "RAID_ONLY" then
if GetNumRaidMembers() > 0 then
SendChatMessage(format(interruptMsg, destName, spellID, spellName), battleground and "BATTLEGROUND" or "RAID")
end
end
end
end
end
do
local repairInventoryPriority = {
16, -- MainHandSlot
17, -- SecondaryHandSlot
18, -- RangedSlot
1, -- HeadSlot
5, -- ChestSlot
7, -- LegsSlot
3, -- ShoulderSlot
10, -- HandsSlot
6, -- WaistSlot
8, -- FeetSlot
9, -- WristSlot
}
local function RepairInventoryByPriority(playerMoney)
local money = playerMoney
ShowRepairCursor()
for _, slotID in ipairs(repairInventoryPriority) do
local hasItem, _, repairCost = GameTooltip:SetInventoryItem("player", slotID)
if hasItem and repairCost and repairCost > 0 and repairCost <= money then
PickupInventoryItem(slotID)
money = money - repairCost
end
end
HideRepairCursor()
GameTooltip:Hide()
return playerMoney - money
end
local function FullRepairMessage(repairAllCost)
E:Print(format("%s%s", L["Your items have been repaired for: "], E:FormatMoney(repairAllCost, "SMART", true)))
end
function M:AutoRepair(repairMode, greyValue)
if not CanMerchantRepair() or IsShiftKeyDown() then return end
local repairAllCost, canRepair = GetRepairAllCost()
if not canRepair or repairAllCost <= 0 then return end
if repairMode == "GUILD" then
if not CanGuildBankRepair() then
repairMode = "PLAYER"
else
local guildWithdrawMoney = GetGuildBankWithdrawMoney()
local guildMoney = GetGuildBankMoney()
local availableGuildMoney
if guildWithdrawMoney == -1 or guildMoney < guildWithdrawMoney then
availableGuildMoney = guildMoney
else
availableGuildMoney = guildWithdrawMoney
end
if repairAllCost > availableGuildMoney then
repairMode = "PLAYER"
end
end
end
if repairMode == "GUILD" then
RepairAllItems(true)
E:Print(format("%s%s", L["Your items have been repaired using guild bank funds for: "], E:FormatMoney(repairAllCost, "SMART", true)))
else
local playerMoney = GetMoney()
if playerMoney >= repairAllCost then
RepairAllItems()
FullRepairMessage(repairAllCost)
elseif greyValue and playerMoney + greyValue >= repairAllCost then
self.playerMoney = playerMoney
self.repairAllCost = repairAllCost
self:RegisterEvent("MERCHANT_CLOSED")
E.RegisterCallback(M, "VendorGreys_ItemSold")
elseif playerMoney > 0 then
local spent = RepairInventoryByPriority(playerMoney)
if spent > 0 then
E:Print(format("%s%s", L["Your items have been repaired for: "], E:FormatMoney(spent, "SMART", true)))
E:Print(L["You don't have enough money to repair all items."])
else
E:Print(L["You don't have enough money to repair."])
end
else
E:Print(L["You don't have enough money to repair."])
end
end
end
function M:VendorGreys_ItemSold(_, moneyGained)
self.playerMoney = self.playerMoney + moneyGained
if self.playerMoney >= self.repairAllCost then
if self.playerMoney > GetMoney() then
self:RegisterEvent("PLAYER_MONEY")
E.UnregisterCallback(M, "VendorGreys_ItemSold")
else
RepairAllItems()
FullRepairMessage(self.repairAllCost)
end
end
end
function M:PLAYER_MONEY()
if self.playerMoney <= GetMoney() then
RepairAllItems()
FullRepairMessage(self.repairAllCost)
self:MERCHANT_CLOSED()
end
end
function M:MERCHANT_CLOSED()
self.playerMoney = nil
self.repairAllCost = nil
self:UnregisterEvent("PLAYER_MONEY")
self:UnregisterEvent("MERCHANT_CLOSED")
E.UnregisterCallback(M, "VendorGreys_ItemSold")
end
end
function M:MERCHANT_SHOW()
local greyValue
if E.db.bags.vendorGrays.enable then
local itemCount
itemCount, greyValue = Bags:GetGraysInfo()
if itemCount > 0 then
Bags:VendorGrays()
end
end
local repairMode = E.db.general.autoRepair
if repairMode ~= "NONE" then
E:Delay(0.03, self.AutoRepair, self, repairMode, greyValue)
end
end
function M:DisbandRaidGroup()
if InCombatLockdown() then return end -- Prevent user error in combat
local numRaid = GetNumRaidMembers()
if numRaid > 0 then
for i = 1, numRaid do
local name, _, _, _, _, _, _, online = GetRaidRosterInfo(i)
if online and name ~= E.myname then
UninviteUnit(name)
end
end
else
for i = MAX_PARTY_MEMBERS, 1, -1 do
if GetPartyMember(i) then
UninviteUnit(UnitName("party"..i))
end
end
end
LeaveParty()
end
function M:PVPMessageEnhancement(_, msg)
if not E.db.general.enhancedPvpMessages then return end
local _, instanceType = IsInInstance()
if instanceType == "pvp" or instanceType == "arena" then
RaidNotice_AddMessage(RaidBossEmoteFrame, msg, ChatTypeInfo.RAID_BOSS_EMOTE)
end
end
function M:AutoInvite(event, leaderName)
if not E.db.general.autoAcceptInvite then return end
if MiniMapLFGFrame:IsShown() then return end
if GetNumPartyMembers() > 0 or GetNumRaidMembers() > 0 then return end
local numFriends = GetNumFriends()
if numFriends > 0 then
ShowFriends()
for i = 1, numFriends do
if GetFriendInfo(i) == leaderName then
AcceptGroup()
StaticPopup_Hide("PARTY_INVITE")
return
end
end
end
if not IsInGuild() then return end
GuildRoster()
for i = 1, GetNumGuildMembers() do
if GetGuildRosterInfo(i) == leaderName then
AcceptGroup()
StaticPopup_Hide("PARTY_INVITE")
return
end
end
end
function M:ForceCVars(event)
if not GetCVarBool("lockActionBars") then
SetCVar("lockActionBars", 1)
end
if event == "PLAYER_ENTERING_WORLD" then
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
end
end
function M:Initialize()
self:LoadRaidMarker()
self:LoadLoot()
self:LoadLootRoll()
self:LoadChatBubbles()
self:ToggleErrorHandling()
self:ToggleInterruptAnnounce()
self:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE", "PVPMessageEnhancement")
self:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE", "PVPMessageEnhancement")
self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL", "PVPMessageEnhancement")
self:RegisterEvent("PARTY_INVITE_REQUEST", "AutoInvite")
self:RegisterEvent("MERCHANT_SHOW")
if E.private.actionbar.enable then
self:RegisterEvent("CVAR_UPDATE", "ForceCVars")
self:RegisterEvent("PLAYER_ENTERING_WORLD", "ForceCVars")
end
self.Initialized = true
end
local function InitializeCallback()
M:Initialize()
end
E:RegisterModule(M:GetName(), InitializeCallback)
+395
View File
@@ -0,0 +1,395 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local RB = E:GetModule("ReminderBuffs")
local LSM = E.Libs.LSM
--Lua functions
local ipairs, unpack = ipairs, unpack
--WoW API / Variables
local CooldownFrame_SetTimer = CooldownFrame_SetTimer
local CreateFrame = CreateFrame
local GetSpellInfo = GetSpellInfo
local GetTime = GetTime
local UnitAura = UnitAura
RB.Spell1Buffs = {
67016, -- Flask of the North (SP)
67017, -- Flask of the North (AP)
67018, -- Flask of the North (STR)
53755, -- Flask of the Frost Wyrm
53758, -- Flask of Stoneblood
53760, -- Flask of Endless Rage
54212, -- Flask of Pure Mojo
53752, -- Lesser Flask of Toughness (50 Resilience)
17627, -- Flask of Distilled Wisdom
33721, -- Spellpower Elixir
53746, -- Wrath Elixir
28497, -- Elixir of Mighty Agility
53748, -- Elixir of Mighty Strength
60346, -- Elixir of Lightning Speed
60344, -- Elixir of Expertise
60341, -- Elixir of Deadly Strikes
60345, -- Elixir of Armor Piercing
60340, -- Elixir of Accuracy
53749, -- Guru's Elixir
60343, -- Elixir of Mighty Defense
53751, -- Elixir of Mighty Fortitude
53764, -- Elixir of Mighty Mageblood
60347, -- Elixir of Mighty Thoughts
53763, -- Elixir of Protection
53747, -- Elixir of Spirit
}
RB.Spell2Buffs = {
57325, -- 80 AP
57327, -- 46 SP
57329, -- 40 Critical Strike Rating
57332, -- 40 Haste Rating
57334, -- 20 MP5
57356, -- 40 Expertise Rating
57358, -- 40 ARP
57360, -- 40 Hit Rating
57363, -- Tracking Humanoids
57365, -- 40 Spirit
57367, -- 40 AGI
57371, -- 40 STR
57373, -- Tracking Beasts
57399, -- 80 AP, 46 SP
59230, -- 40 Dodge Rating
65247, -- 20 STR
}
RB.Spell3Buffs = {
72588, -- Gift of the Wild
48469, -- Mark of the Wild
}
RB.Spell4Buffs = {
25898, -- Greater Blessing of Kings
20217, -- Blessing of Kings
72586, -- Blessing of Forgotten Kings
}
RB.Spell5Buffs = {
48162, -- Prayer of Fortitude
48161, -- Power Word: Fortitude
72590, -- Fortitude
}
RB.Spell6Buffs = {
20911, -- Blessing of Sanctuary
25899, -- Greater Blessing of Sanctuary
}
RB.CasterSpell7Buffs = {
61316, -- Dalaran Brilliance
43002, -- Arcane Brilliance
42995, -- Arcane Intellect
}
RB.AttackSpell7Buffs = {
48934, -- Greater Blessing of Might
48932, -- Blessing of Might
47436, -- Battle Shout
}
RB.Spell8Buffs = {
6307, -- Blood Pact
469, -- Commanding Shout
}
-- Armor buffs
RB.Spell9Buffs = {
25506, -- Stoneskin Totem
465, -- Devotion Aura
}
-- Concentration / Thorns
RB.CasterSpell10Buffs = {
19746, -- Concentration Aura
}
RB.AttackSpell10Buffs = {
467, -- Thorns
7294, -- Retribution Aura
}
-- SP / Str+Dex totems
RB.CasterSpell11Buffs = {
30706, -- Totem of Wrath
8227, -- Flametongue Totem
47236, -- Demonic Pact
}
RB.AttackSpell11Buffs = {
25527, -- Strength of Earth Totem
}
-- Mana regen
RB.Spell12Buffs = {
48938, -- Greater Blessing of Wisdom
48936, -- Blessing of Wisdom
58777, -- Mana Spring
}
-- Crit % Increase
RB.CasterSpell13Buffs = {
51471, -- Elemental Oath
24907, -- Moonkin Aura
}
RB.AttackSpell13Buffs = {
17007, -- Leader of the Pack
29801, -- Rampage
}
-- Haste % Increase
RB.CasterSpell14Buffs = {
50172, -- Moonkin's Presence
2895, -- Wrath of Air
853648, -- Swift Retribution
}
RB.AttackSpell14Buffs = {
8512, -- Windfury Totem
}
-- Spirit Buff
RB.CasterSpell15Buffs = {
14752, -- Divine Spirit
27681, -- Prayer of Spirit
}
-- Percent AP
RB.AttackSpell15Buffs = {
19506, -- Trueshot Aura
30802, -- Unleashed Rage
53137, -- Abomination's Might
}
-- Percent Damage
RB.Spell16Buffs = {
31579, -- Arcane Empowerment
31869, -- Sanctified Retribution
34455, -- Ferocious Inspiration
}
function RB:CheckFilterForActiveBuff(filter)
for _, spell in ipairs(filter) do
local spellName = GetSpellInfo(spell)
local name, _, texture, _, _, duration, expirationTime = UnitAura("player", spellName)
if name then
return texture, duration, expirationTime
end
end
end
function RB:UpdateReminderTime(elapsed)
self.expiration = self.expiration - elapsed
if self.nextUpdate > 0 then
self.nextUpdate = self.nextUpdate - elapsed
return
end
if self.expiration <= 0 then
self.timer:SetText("")
self:SetScript("OnUpdate", nil)
return
end
local value, id, nextUpdate, remainder = E:GetTimeInfo(self.expiration, 4)
self.nextUpdate = nextUpdate
local style = E.TimeFormats[id]
if style then
self.timer:SetFormattedText(style[1], value, remainder)
end
end
function RB:UpdateReminder(event, unit)
if event == "UNIT_AURA" and unit ~= "player" then return end
for i = 1, 16 do
local texture, duration, expirationTime = self:CheckFilterForActiveBuff(self["Spell"..i.."Buffs"])
local button = self.frame[i]
if texture then
button.t:SetTexture(texture)
if (duration == 0 and expirationTime == 0) or E.db.general.reminder.durations ~= true then
button.t:SetAlpha(E.db.general.reminder.reverse and 1 or 0.3)
button:SetScript("OnUpdate", nil)
button.timer:SetText(nil)
CooldownFrame_SetTimer(button.cd, 0, 0, 0)
else
button.expiration = expirationTime - GetTime()
button.nextUpdate = 0
button.t:SetAlpha(1)
CooldownFrame_SetTimer(button.cd, expirationTime - duration, duration, 1)
button.cd:SetReverse(E.db.general.reminder.reverse)
button:SetScript("OnUpdate", self.UpdateReminderTime)
end
else
CooldownFrame_SetTimer(button.cd, 0, 0, 0)
button.t:SetAlpha(E.db.general.reminder.reverse and 0.3 or 1)
button:SetScript("OnUpdate", nil)
button.timer:SetText(nil)
button.t:SetTexture(self.DefaultIcons[i])
end
end
end
function RB:CreateButton()
local button = CreateFrame("Button", nil, ElvUI_ReminderBuffs)
button:SetTemplate("Default")
button.t = button:CreateTexture(nil, "OVERLAY")
button.t:SetTexCoord(unpack(E.TexCoords))
button.t:SetInside()
button.t:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
button.cd = CreateFrame("Cooldown", nil, button, "CooldownFrameTemplate")
button.cd:SetInside()
button.cd.noOCC = true
button.cd.noCooldownCount = true
button.timer = button.cd:CreateFontString(nil, "OVERLAY")
button.timer:SetPoint("CENTER")
return button
end
function RB:EnableRB()
ElvUI_ReminderBuffs:Show()
self:RegisterEvent("UNIT_AURA", "UpdateReminder")
self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED", "UpdateReminder")
self:RegisterEvent("CHARACTER_POINTS_CHANGED", "UpdateReminder")
E.RegisterCallback(self, "RoleChanged", "UpdateSettings")
self:UpdateReminder()
end
function RB:DisableRB()
ElvUI_ReminderBuffs:Hide()
self:UnregisterEvent("UNIT_AURA")
self:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
self:UnregisterEvent("CHARACTER_POINTS_CHANGED")
E.UnregisterCallback(self, "RoleChanged", "UpdateSettings")
end
function RB:UpdateSettings(isCallback)
local frame = self.frame
frame:Width(E.RBRWidth * 2)
self:UpdateDefaultIcons()
for i = 1, 16 do
local button = frame[i]
button:ClearAllPoints()
button:SetWidth(E.RBRWidth)
button:SetHeight(E.RBRWidth)
if i == 1 then
button:SetPoint("TOPLEFT", ElvUI_ReminderBuffs, "TOPLEFT", 0, -1)
elseif i == 9 then
button:SetPoint("TOPRIGHT", ElvUI_ReminderBuffs, "TOPRIGHT", 0, -1)
else
button:Point("TOP", frame[i - 1], "BOTTOM", 0, E.Border - E.Spacing*3)
end
if E.db.general.reminder.durations then
button.cd:SetAlpha(1)
else
button.cd:SetAlpha(0)
end
button.timer:FontTemplate(LSM:Fetch("font", E.db.general.reminder.font), E.db.general.reminder.fontSize, E.db.general.reminder.fontOutline)
end
if not isCallback then
if E.db.general.reminder.enable then
RB:EnableRB()
else
RB:DisableRB()
end
else
self:UpdateReminder()
end
end
function RB:UpdatePosition()
Minimap:ClearAllPoints()
ElvConfigToggle:ClearAllPoints()
ElvUI_ReminderBuffs:ClearAllPoints()
if E.db.general.reminder.position == "LEFT" then
Minimap:Point("TOPRIGHT", MMHolder, "TOPRIGHT", -E.Border, -E.Border)
ElvConfigToggle:SetPoint("TOPRIGHT", LeftMiniPanel, "TOPLEFT", E.Border - E.Spacing*3, 0)
ElvConfigToggle:SetPoint("BOTTOMRIGHT", LeftMiniPanel, "BOTTOMLEFT", E.Border - E.Spacing*3, 0)
ElvUI_ReminderBuffs:SetPoint("TOPRIGHT", Minimap.backdrop, "TOPLEFT", E.Border - E.Spacing*3, 0)
ElvUI_ReminderBuffs:SetPoint("BOTTOMRIGHT", Minimap.backdrop, "BOTTOMLEFT", E.Border - E.Spacing*3, 0)
else
Minimap:Point("TOPLEFT", MMHolder, "TOPLEFT", E.Border, -E.Border)
ElvConfigToggle:SetPoint("TOPLEFT", RightMiniPanel, "TOPRIGHT", -E.Border + E.Spacing*3, 0)
ElvConfigToggle:SetPoint("BOTTOMLEFT", RightMiniPanel, "BOTTOMRIGHT", -E.Border + E.Spacing*3, 0)
ElvUI_ReminderBuffs:SetPoint("TOPLEFT", Minimap.backdrop, "TOPRIGHT", -E.Border + E.Spacing*3, 0)
ElvUI_ReminderBuffs:SetPoint("BOTTOMLEFT", Minimap.backdrop, "BOTTOMRIGHT", -E.Border + E.Spacing*3, 0)
end
end
function RB:UpdateDefaultIcons()
local isCaster = E.private.general.reminder.classtype == "Caster"
self.DefaultIcons = {
[1] = "Interface\\Icons\\INV_Potion_97",
[2] = "Interface\\Icons\\Spell_Misc_Food",
[3] = "Interface\\Icons\\Spell_Nature_Regeneration",
[4] = "Interface\\Icons\\Spell_Magic_GreaterBlessingofKings",
[5] = "Interface\\Icons\\Spell_Holy_WordFortitude",
[6] = "Interface\\Icons\\spell_nature_lightningshield",
[7] = (isCaster and "Interface\\Icons\\Spell_Holy_MagicalSentry") or "Interface\\Icons\\spell_holy_fistofjustice",
[8] = "Interface\\Icons\\ability_warrior_rallyingcry",
[9] = "Interface\\Icons\\spell_nature_stoneskintotem",
[10] = (isCaster and "Interface\\Icons\\spell_holy_mindsooth") or "Interface\\Icons\\spell_nature_thorns",
[11] = (isCaster and "Interface\\Icons\\spell_fire_totemofwrath") or "Interface\\Icons\\spell_nature_earthbindtotem",
[12] = "Interface\\Icons\\Spell_Holy_GreaterBlessingofWisdom",
[13] = (isCaster and "Interface\\Icons\\spell_nature_moonglow") or "Interface\\Icons\\spell_nature_unyeildingstamina",
[14] = (isCaster and "Interface\\Icons\\spell_nature_forceofnature") or "Interface\\Icons\\spell_nature_windfury",
[15] = (isCaster and "Interface\\Icons\\spell_holy_prayerofspirit") or "Interface\\Icons\\ability_trueshot",
[16] = "Interface\\Icons\\spell_nature_starfall",
}
self.Spell7Buffs = isCaster and self.CasterSpell7Buffs or self.AttackSpell7Buffs
self.Spell10Buffs = isCaster and self.CasterSpell10Buffs or self.AttackSpell10Buffs
self.Spell11Buffs = isCaster and self.CasterSpell11Buffs or self.AttackSpell11Buffs
self.Spell13Buffs = isCaster and self.CasterSpell13Buffs or self.AttackSpell13Buffs
self.Spell14Buffs = isCaster and self.CasterSpell14Buffs or self.AttackSpell14Buffs
self.Spell15Buffs = isCaster and self.CasterSpell15Buffs or self.AttackSpell15Buffs
end
function RB:Initialize()
if not E.private.general.minimap.enable then return end
self.db = E.db.general.reminder
local frame = CreateFrame("Frame", "ElvUI_ReminderBuffs", Minimap)
frame:Width(E.RBRWidth)
if E.db.general.reminder.position == "LEFT" then
frame:Point("TOPRIGHT", Minimap.backdrop, "TOPLEFT", E.Border - E.Spacing*3, 0)
frame:Point("BOTTOMRIGHT", Minimap.backdrop, "BOTTOMLEFT", E.Border - E.Spacing*3, 0)
else
frame:Point("TOPLEFT", Minimap.backdrop, "TOPRIGHT", -E.Border + E.Spacing*3, 0)
frame:Point("BOTTOMLEFT", Minimap.backdrop, "BOTTOMRIGHT", -E.Border + E.Spacing*3, 0)
end
self.frame = frame
for i = 1, 16 do
frame[i] = self:CreateButton()
frame[i]:SetID(i)
end
self:UpdateSettings()
end
local function InitializeCallback()
RB:Initialize()
end
E:RegisterModule(RB:GetName(), InitializeCallback)
+104
View File
@@ -0,0 +1,104 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local M = E:GetModule("Misc")
--Lua functions
local sin, cos, pi = math.sin, math.cos, math.pi
--WoW API / Variables
local CreateFrame = CreateFrame
local GetNumPartyMembers = GetNumPartyMembers
local UnitInRaid = UnitInRaid
local UnitIsPartyLeader = UnitIsPartyLeader
local UnitIsRaidOfficer = UnitIsRaidOfficer
local UnitExists, UnitIsDead = UnitExists, UnitIsDead
local GetCursorPosition = GetCursorPosition
local PlaySound = PlaySound
local SetRaidTarget = SetRaidTarget
local SetRaidTargetIconTexture = SetRaidTargetIconTexture
local UIErrorsFrame = UIErrorsFrame
local ButtonIsDown
function M:RaidMarkCanMark()
if not self.RaidMarkFrame then return false end
if GetNumPartyMembers() > 0 then
if UnitIsPartyLeader("player") or (UnitInRaid("player") and UnitIsRaidOfficer("player") and not UnitIsPartyLeader("player")) then
return true
else
UIErrorsFrame:AddMessage(L["You don't have permission to mark targets."], 1.0, 0.1, 0.1, 1.0)
return false
end
else
return true
end
end
function M:RaidMarkShowIcons()
if not UnitExists("target") or UnitIsDead("target") then return end
local x, y = GetCursorPosition()
local scale = E.UIParent:GetEffectiveScale()
self.RaidMarkFrame:Point("CENTER", E.UIParent, "BOTTOMLEFT", x / scale, y / scale)
self.RaidMarkFrame:Show()
end
function RaidMark_HotkeyPressed(keystate)
ButtonIsDown = (keystate == "down") and M:RaidMarkCanMark()
if ButtonIsDown and M.RaidMarkFrame then
M:RaidMarkShowIcons()
elseif M.RaidMarkFrame then
M.RaidMarkFrame:Hide()
end
end
function M:RaidMark_OnEvent()
if ButtonIsDown and self.RaidMarkFrame then
self:RaidMarkShowIcons()
end
end
M:RegisterEvent("PLAYER_TARGET_CHANGED", "RaidMark_OnEvent")
function M:RaidMarkButton_OnEnter()
self.Texture:ClearAllPoints()
self.Texture:Point("TOPLEFT", -10, 10)
self.Texture:Point("BOTTOMRIGHT", 10, -10)
end
function M:RaidMarkButton_OnLeave()
self.Texture:SetAllPoints()
end
function M:RaidMarkButton_OnClick(button)
PlaySound("UChatScrollButton")
SetRaidTarget("target", (button ~= "RightButton") and self:GetID() or 0)
self:GetParent():Hide()
end
function M:LoadRaidMarker()
local marker = CreateFrame("Frame", nil, E.UIParent)
marker:EnableMouse(true)
marker:Size(100)
marker:SetFrameStrata("DIALOG")
for i = 1, 8 do
local button = CreateFrame("Button", "RaidMarkIconButton"..i, marker)
button:Size(40)
button:SetID(i)
button.Texture = button:CreateTexture(button:GetName().."NormalTexture", "ARTWORK")
button.Texture:SetTexture([[Interface\TargetingFrame\UI-RaidTargetingIcons]])
button.Texture:SetAllPoints()
SetRaidTargetIconTexture(button.Texture, i)
button:RegisterForClicks("LeftbuttonUp","RightbuttonUp")
button:SetScript("OnClick", M.RaidMarkButton_OnClick)
button:SetScript("OnEnter", M.RaidMarkButton_OnEnter)
button:SetScript("OnLeave", M.RaidMarkButton_OnLeave)
if i == 8 then
button:Point("CENTER")
else
local angle = pi / 0.7 * i
button:Point("CENTER", sin(angle) * 60, cos(angle) * 60)
end
end
M.RaidMarkFrame = marker
end
+225
View File
@@ -0,0 +1,225 @@
local E, L = unpack(select(2, ...)); --Import: Engine, Locales
local RU = E:GetModule("RaidUtility")
local S = E:GetModule("Skins")
--Lua functions
local find = string.find
--WoW API / Variables
local CreateFrame = CreateFrame
local IsInInstance = IsInInstance
local GetNumRaidMembers = GetNumRaidMembers
local GetNumPartyMembers = GetNumPartyMembers
local IsPartyLeader = IsPartyLeader
local IsRaidLeader = IsRaidLeader
local IsRaidOfficer = IsRaidOfficer
local InCombatLockdown = InCombatLockdown
local DoReadyCheck = DoReadyCheck
local ToggleFriendsFrame = ToggleFriendsFrame
local PANEL_HEIGHT = 100
local function CheckRaidStatus()
local inInstance, instanceType = IsInInstance()
if (((IsRaidLeader() or IsRaidOfficer()) and GetNumRaidMembers() > 0) or (IsPartyLeader() and GetNumPartyMembers() > 0)) and not (inInstance and (instanceType == "pvp" or instanceType == "arena")) then
return true
else
return false
end
end
-- Function to create buttons in this module
function RU:CreateUtilButton(name, parent, template, width, height, point, relativeto, point2, xOfs, yOfs, text, texture)
local button = CreateFrame("Button", name, parent, template)
button:Width(width)
button:Height(height)
button:Point(point, relativeto, point2, xOfs, yOfs)
S:HandleButton(button)
if text then
button.text = button:CreateFontString(nil, "OVERLAY", button)
button.text:FontTemplate()
button.text:Point("CENTER", button, "CENTER", 0, -1)
button.text:SetJustifyH("CENTER")
button.text:SetText(text)
button:SetFontString(button.text)
elseif texture then
button.texture = button:CreateTexture(nil, "OVERLAY", nil)
button.texture:SetTexture(texture)
button.texture:Point("TOPLEFT", button, "TOPLEFT", E.mult, -E.mult)
button.texture:Point("BOTTOMRIGHT", button, "BOTTOMRIGHT", -E.mult, E.mult)
end
end
function RU:ToggleRaidUtil(event)
if InCombatLockdown() then
self:RegisterEvent("PLAYER_REGEN_ENABLED", "ToggleRaidUtil")
return
end
if CheckRaidStatus() then
if RaidUtilityPanel.toggled == true then
RaidUtility_ShowButton:Hide()
RaidUtilityPanel:Show()
else
RaidUtility_ShowButton:Show()
RaidUtilityPanel:Hide()
end
else
RaidUtility_ShowButton:Hide()
RaidUtilityPanel:Hide()
end
if event == "PLAYER_REGEN_ENABLED" then
self:UnregisterEvent("PLAYER_REGEN_ENABLED", "ToggleRaidUtil")
end
end
function RU:Initialize()
if not E.private.general.raidUtility then return end
self.Initialized = true
--Create main frame
local RaidUtilityPanel = CreateFrame("Frame", "RaidUtilityPanel", E.UIParent, "SecureHandlerClickTemplate")
RaidUtilityPanel:SetTemplate("Transparent")
RaidUtilityPanel:Width(230)
RaidUtilityPanel:Height(PANEL_HEIGHT)
RaidUtilityPanel:Point("TOP", E.UIParent, "TOP", -400, 1)
RaidUtilityPanel:SetFrameLevel(3)
RaidUtilityPanel.toggled = false
RaidUtilityPanel:SetFrameStrata("HIGH")
self:CreateUtilButton("RaidUtility_ShowButton", E.UIParent, "SecureHandlerClickTemplate", 136, 18, "TOP", E.UIParent, "TOP", -400, E.Border, RAID_CONTROL, nil)
RaidUtility_ShowButton:SetFrameRef("RaidUtilityPanel", RaidUtilityPanel)
RaidUtility_ShowButton:SetAttribute("_onclick", ([=[
local raidUtil = self:GetFrameRef("RaidUtilityPanel")
local closeButton = raidUtil:GetFrameRef("RaidUtility_CloseButton")
self:Hide()
raidUtil:Show()
local point = self:GetPoint()
local raidUtilPoint, closeButtonPoint, yOffset
if string.find(point, "BOTTOM") then
raidUtilPoint = "BOTTOM"
closeButtonPoint = "TOP"
yOffset = 1
else
raidUtilPoint = "TOP"
closeButtonPoint = "BOTTOM"
yOffset = -1
end
yOffset = yOffset * (tonumber(%d))
raidUtil:ClearAllPoints()
closeButton:ClearAllPoints()
raidUtil:SetPoint(raidUtilPoint, self, raidUtilPoint)
closeButton:SetPoint(raidUtilPoint, raidUtil, closeButtonPoint, 0, yOffset)
]=]):format(-E.Border + E.Spacing * 3))
RaidUtility_ShowButton:SetScript("OnMouseUp", function()
RaidUtilityPanel.toggled = true
end)
RaidUtility_ShowButton:SetMovable(true)
RaidUtility_ShowButton:SetClampedToScreen(true)
RaidUtility_ShowButton:SetClampRectInsets(0, 0, -1, 1)
RaidUtility_ShowButton:RegisterForDrag("RightButton")
RaidUtility_ShowButton:SetFrameStrata("HIGH")
RaidUtility_ShowButton:SetScript("OnDragStart", function(self)
if InCombatLockdown() then E:Print(ERR_NOT_IN_COMBAT) return end
self:StartMoving()
end)
RaidUtility_ShowButton:SetScript("OnDragStop", function(self)
self:StopMovingOrSizing()
local point = self:GetPoint()
local xOffset = self:GetCenter()
local screenWidth = E.UIParent:GetWidth() / 2
xOffset = xOffset - screenWidth
self:ClearAllPoints()
if find(point, "BOTTOM") then
self:Point("BOTTOM", E.UIParent, "BOTTOM", xOffset, -1)
else
self:Point("TOP", E.UIParent, "TOP", xOffset, 1)
end
end)
self:CreateUtilButton("RaidUtility_CloseButton", RaidUtilityPanel, "SecureHandlerClickTemplate", 136, 18, "TOP", RaidUtilityPanel, "BOTTOM", 0, -1, CLOSE, nil)
RaidUtility_CloseButton:SetFrameRef("RaidUtility_ShowButton", RaidUtility_ShowButton)
RaidUtility_CloseButton:SetAttribute("_onclick", [=[self:GetParent():Hide(); self:GetFrameRef("RaidUtility_ShowButton"):Show();]=])
RaidUtility_CloseButton:SetScript("OnMouseUp", function() RaidUtilityPanel.toggled = false end)
RaidUtilityPanel:SetFrameRef("RaidUtility_CloseButton", RaidUtility_CloseButton)
self:CreateUtilButton("DisbandRaidButton", RaidUtilityPanel, nil, RaidUtilityPanel:GetWidth() * 0.8, 18, "TOP", RaidUtilityPanel, "TOP", 0, -5, L["Disband Group"], nil)
DisbandRaidButton:SetScript("OnMouseUp", function()
if CheckRaidStatus() then
E:StaticPopup_Show("DISBAND_RAID")
end
end)
self:CreateUtilButton("MainTankButton", RaidUtilityPanel, "SecureActionButtonTemplate", (DisbandRaidButton:GetWidth() / 2) - 2, 18, "TOPLEFT", DisbandRaidButton, "BOTTOMLEFT", 0, -5, MAINTANK, nil)
MainTankButton:SetAttribute("type", "maintank")
MainTankButton:SetAttribute("unit", "target")
MainTankButton:SetAttribute("action", "toggle")
self:CreateUtilButton("MainAssistButton", RaidUtilityPanel, "SecureActionButtonTemplate", (DisbandRaidButton:GetWidth() / 2) - 2, 18, "TOPRIGHT", DisbandRaidButton, "BOTTOMRIGHT", 0, -5, MAINASSIST, nil)
MainAssistButton:SetAttribute("type", "mainassist")
MainAssistButton:SetAttribute("unit", "target")
MainAssistButton:SetAttribute("action", "toggle")
self:CreateUtilButton("ReadyCheckButton", RaidUtilityPanel, nil, RaidUtilityPanel:GetWidth() * 0.8, 18, "TOPLEFT", MainTankButton, "BOTTOMLEFT", 0, -5, READY_CHECK, nil)
ReadyCheckButton:SetScript("OnMouseUp", function()
if CheckRaidStatus() then
DoReadyCheck()
end
end)
ReadyCheckButton:SetScript("OnEvent", function(btn)
if not (IsRaidLeader("player") or IsRaidOfficer("player")) then
btn:Disable()
else
btn:Enable()
end
end)
ReadyCheckButton:RegisterEvent("RAID_ROSTER_UPDATE")
ReadyCheckButton:RegisterEvent("PARTY_MEMBERS_CHANGED")
ReadyCheckButton:RegisterEvent("PLAYER_ENTERING_WORLD")
self:CreateUtilButton("RaidControlButton", RaidUtilityPanel, nil, MainTankButton:GetWidth(), 18, "TOPLEFT", ReadyCheckButton, "BOTTOMLEFT", 0, -5, L["Raid Menu"], nil)
RaidControlButton:SetScript("OnMouseUp", function()
if InCombatLockdown() then E:Print(ERR_NOT_IN_COMBAT) return end
ToggleFriendsFrame(5)
end)
self:CreateUtilButton("ConvertRaidButton", RaidUtilityPanel, nil, MainAssistButton:GetWidth(), 18, "TOPRIGHT", ReadyCheckButton, "BOTTOMRIGHT", 0, -5, CONVERT_TO_RAID, nil)
ConvertRaidButton:SetScript("OnMouseUp", function()
if CheckRaidStatus() then
ConvertToRaid()
SetLootMethod("master", "player")
end
end)
ConvertRaidButton:SetScript("OnEvent", function(btn)
if GetNumRaidMembers() == 0 and GetNumPartyMembers() > 0 and IsPartyLeader() then
if not btn:IsShown() then
RaidControlButton:Width(MainAssistButton:GetWidth())
btn:Show()
end
elseif btn:IsShown() then
RaidControlButton:Width(DisbandRaidButton:GetWidth())
btn:Hide()
end
end)
ConvertRaidButton:RegisterEvent("RAID_ROSTER_UPDATE")
ConvertRaidButton:RegisterEvent("PARTY_MEMBERS_CHANGED")
ConvertRaidButton:RegisterEvent("PLAYER_ENTERING_WORLD")
--Automatically show/hide the frame if we have RaidLeader or RaidOfficer
self:RegisterEvent("RAID_ROSTER_UPDATE", "ToggleRaidUtil")
self:RegisterEvent("PLAYER_ENTERING_WORLD", "ToggleRaidUtil")
self:RegisterEvent("PARTY_MEMBERS_CHANGED", "ToggleRaidUtil")
end
local function InitializeCallback()
RU:Initialize()
end
E:RegisterInitialModule(RU:GetName(), InitializeCallback)
+176
View File
@@ -0,0 +1,176 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local THREAT = E:GetModule("Threat")
local DT = E:GetModule("DataTexts")
--Lua functions
local pairs, select = pairs, select
local wipe = table.wipe
--WoW API / Variables
local GetNumPartyMembers = GetNumPartyMembers
local GetNumRaidMembers = GetNumRaidMembers
local GetThreatStatusColor = GetThreatStatusColor
local UnitDetailedThreatSituation = UnitDetailedThreatSituation
local UnitExists = UnitExists
local UnitIsPlayer = UnitIsPlayer
local UnitIsUnit = UnitIsUnit
local UnitName = UnitName
local UnitReaction = UnitReaction
local UNKNOWN = UNKNOWN
local partyUnits, raidUnits = {}, {}
for i = 1, 4 do partyUnits[i] = "party"..i end
for i = 1, 40 do raidUnits[i] = "raid"..i end
function THREAT:UpdatePosition()
if self.db.position == "RIGHTCHAT" then
self.bar:SetInside(RightChatDataPanel)
self.bar:SetParent(RightChatDataPanel)
else
self.bar:SetInside(LeftChatDataPanel)
self.bar:SetParent(LeftChatDataPanel)
end
self.bar.text:FontTemplate(nil, self.db.textSize)
self.bar:SetFrameStrata("MEDIUM")
end
function THREAT:GetLargestThreatOnList(percent)
local largestValue, largestUnit = 0
for unit, threatPercent in pairs(self.list) do
if threatPercent > largestValue then
largestValue = threatPercent
largestUnit = unit
end
end
return (percent - largestValue), largestUnit
end
function THREAT:GetColor(unit)
if UnitIsPlayer(unit) then
local class = E.media.herocolor
if not class then
return 194, 194, 194
end
return class.r*255, class.g*255, class.b*255
end
local unitReaction = UnitReaction(unit, "player")
if unitReaction then
local reaction = ElvUF.colors.reaction[unitReaction]
return reaction[1]*255, reaction[2]*255, reaction[3]*255
else
return 194, 194, 194
end
end
function THREAT:Update()
if not UnitExists("target") or (DT and DT.ShowingBGStats) then
if self.bar:IsShown() then
self.bar:Hide()
end
return
end
local _, status, percent = UnitDetailedThreatSituation("player", "target")
local petExists = HasPetUI()
if percent and percent > 0 and (GetNumPartyMembers() > 0 or petExists == 1) then
local name = UnitName("target")
self.bar:Show()
if percent == 100 then
if petExists == 1 then
self.list.pet = select(3, UnitDetailedThreatSituation("pet", "target"))
end
if GetNumRaidMembers() > 0 then
for i = 1, 40 do
if UnitExists(raidUnits[i]) and not UnitIsUnit(raidUnits[i], "player") then
self.list[raidUnits[i]] = select(3, UnitDetailedThreatSituation(raidUnits[i], "target"))
end
end
else
for i = 1, 4 do
if UnitExists(partyUnits[i]) then
self.list[partyUnits[i]] = select(3, UnitDetailedThreatSituation(partyUnits[i], "target"))
end
end
end
local leadPercent, largestUnit = self:GetLargestThreatOnList(percent)
if leadPercent > 0 and largestUnit then
local r, g, b = self:GetColor(largestUnit)
self.bar.text:SetFormattedText(L["ABOVE_THREAT_FORMAT"], name, percent, leadPercent, r, g, b, UnitName(largestUnit) or UNKNOWN)
if E.Role == "Tank" then
self.bar:SetStatusBarColor(0, 0.839, 0)
self.bar:SetValue(leadPercent)
else
self.bar:SetStatusBarColor(GetThreatStatusColor(status))
self.bar:SetValue(percent)
end
else
self.bar:SetStatusBarColor(GetThreatStatusColor(status))
self.bar:SetValue(percent)
self.bar.text:SetFormattedText("%s: %.0f%%", name, percent)
end
else
self.bar:SetStatusBarColor(GetThreatStatusColor(status))
self.bar:SetValue(percent)
self.bar.text:SetFormattedText("%s: %.0f%%", name, percent)
end
else
self.bar:Hide()
end
wipe(self.list)
end
function THREAT:ToggleEnable()
if self.db.enable then
self:RegisterEvent("PLAYER_TARGET_CHANGED", "Update")
self:RegisterEvent("UNIT_THREAT_LIST_UPDATE", "Update")
self:RegisterEvent("PARTY_MEMBERS_CHANGED", "Update")
self:RegisterEvent("RAID_ROSTER_UPDATE", "Update")
self:RegisterEvent("UNIT_PET", "Update")
self:Update()
else
self.bar:Hide()
self:UnregisterEvent("PLAYER_TARGET_CHANGED")
self:UnregisterEvent("UNIT_THREAT_LIST_UPDATE")
self:UnregisterEvent("PARTY_MEMBERS_CHANGED")
self:UnregisterEvent("RAID_ROSTER_UPDATE")
self:UnregisterEvent("UNIT_PET")
end
end
function THREAT:Initialize()
self.db = E.db.general.threat
self.bar = CreateFrame("StatusBar", "ElvUI_ThreatBar", E.UIParent)
self.bar:CreateBackdrop("Default")
self.bar:SetMinMaxValues(0, 100)
self.bar:SetStatusBarTexture(E.media.normTex)
E:RegisterStatusBar(self.bar)
self.bar.text = self.bar:CreateFontString(nil, "OVERLAY")
self.bar.text:FontTemplate(nil, self.db.textSize)
self.bar.text:Point("CENTER", self.bar, "CENTER")
self.list = {}
self:UpdatePosition()
self:ToggleEnable()
self.Initialized = true
end
local function InitializeCallback()
THREAT:Initialize()
end
E:RegisterModule(THREAT:GetName(), InitializeCallback)
+181
View File
@@ -0,0 +1,181 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local TOTEMS = E:GetModule("Totems")
--Lua functions
local unpack = unpack
--WoW API / Variables
local CooldownFrame_SetTimer = CooldownFrame_SetTimer
local CreateFrame = CreateFrame
local DestroyTotem = DestroyTotem
local GetTotemInfo = GetTotemInfo
local MAX_TOTEMS = MAX_TOTEMS
local TOTEM_PRIORITIES = TOTEM_PRIORITIES
local SLOT_BORDER_COLORS = {
[EARTH_TOTEM_SLOT] = {r = 0.23, g = 0.45, b = 0.13}, -- [2]
[FIRE_TOTEM_SLOT] = {r = 0.58, g = 0.23, b = 0.10}, -- [1]
[WATER_TOTEM_SLOT] = {r = 0.19, g = 0.48, b = 0.60}, -- [3]
[AIR_TOTEM_SLOT] = {r = 0.42, g = 0.18, b = 0.74} -- [4]
}
function TOTEMS:UpdateAllTotems()
for i = 1, MAX_TOTEMS do
self:UpdateTotem(nil, i)
end
end
function TOTEMS:UpdateTotem(event, slot)
local slotID = TOTEM_PRIORITIES[slot]
local _, _, startTime, duration, icon = GetTotemInfo(slot)
if icon ~= "" then
local color = SLOT_BORDER_COLORS[slot]
self.bar[slotID].iconTexture:SetTexture(icon)
self.bar[slotID]:SetBackdropBorderColor(color.r, color.g, color.b)
CooldownFrame_SetTimer(self.bar[slotID].cooldown, startTime, duration, 1)
self.bar[slotID]:Show()
else
self.bar[slotID]:Hide()
end
end
function TOTEMS:ToggleEnable()
if E.db.general.totems.enable then
if self.Initialized then
self.bar:Show()
self:RegisterEvent("PLAYER_TOTEM_UPDATE", "UpdateTotem")
self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdateAllTotems")
self:UpdateAllTotems()
E:EnableMover("TotemBarMover")
else
self:Initialize()
self:UpdateAllTotems()
end
elseif self.Initialized then
self.bar:Hide()
self:UnregisterEvent("PLAYER_TOTEM_UPDATE")
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
E:DisableMover("TotemBarMover")
end
end
function TOTEMS:PositionAndSize()
if not self.Initialized then return end
for i = 1, MAX_TOTEMS do
local button = self.bar[i]
local prevButton = self.bar[i - 1]
button:Size(self.db.size)
button:ClearAllPoints()
if self.db.growthDirection == "HORIZONTAL" and self.db.sortDirection == "ASCENDING" then
if i == 1 then
button:Point("LEFT", self.bar, "LEFT", self.db.spacing, 0)
elseif prevButton then
button:Point("LEFT", prevButton, "RIGHT", self.db.spacing, 0)
end
elseif self.db.growthDirection == "VERTICAL" and self.db.sortDirection == "ASCENDING" then
if i == 1 then
button:Point("TOP", self.bar, "TOP", 0, -self.db.spacing)
elseif prevButton then
button:Point("TOP", prevButton, "BOTTOM", 0, -self.db.spacing)
end
elseif self.db.growthDirection == "HORIZONTAL" and self.db.sortDirection == "DESCENDING" then
if i == 1 then
button:Point("RIGHT", self.bar, "RIGHT", -self.db.spacing, 0)
elseif prevButton then
button:Point("RIGHT", prevButton, "LEFT", -self.db.spacing, 0)
end
else
if i == 1 then
button:Point("BOTTOM", self.bar, "BOTTOM", 0, self.db.spacing)
elseif prevButton then
button:Point("BOTTOM", prevButton, "TOP", 0, self.db.spacing)
end
end
end
if self.db.growthDirection == "HORIZONTAL" then
self.bar:Width(self.db.size*(MAX_TOTEMS) + self.db.spacing*(MAX_TOTEMS) + self.db.spacing)
self.bar:Height(self.db.size + self.db.spacing * 2)
else
self.bar:Height(self.db.size*(MAX_TOTEMS) + self.db.spacing*(MAX_TOTEMS) + self.db.spacing)
self.bar:Width(self.db.size + self.db.spacing * 2)
end
end
local function Button_OnClick(self)
DestroyTotem(self.slot)
end
local function Button_OnEnter(self)
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT")
self:UpdateTooltip()
end
local function Button_OnLeave(self)
GameTooltip:Hide()
end
local function UpdateTooltip(self)
if GameTooltip:IsOwned(self) then
GameTooltip:SetTotem(self.slot)
end
end
function TOTEMS:Initialize()
if not E.db.general.totems.enable then return end
self.db = E.db.general.totems
local bar = CreateFrame("Frame", "ElvUI_TotemBar", E.UIParent)
bar:Point("TOPLEFT", LeftChatPanel, "TOPRIGHT", 14, 0)
self.bar = bar
for i = 1, MAX_TOTEMS do
local frame = CreateFrame("Button", "$parentTotem"..i, bar)
frame.slot = TOTEM_PRIORITIES[i]
frame:SetTemplate("Default")
frame:StyleButton()
frame.ignoreBorderColors = true
frame:Hide()
frame.UpdateTooltip = UpdateTooltip
frame:RegisterForClicks("RightButtonUp")
frame:SetScript("OnClick", Button_OnClick)
frame:SetScript("OnEnter", Button_OnEnter)
frame:SetScript("OnLeave", Button_OnLeave)
frame.holder = CreateFrame("Frame", nil, frame)
frame.holder:SetAlpha(0)
frame.holder:SetAllPoints()
frame.iconTexture = frame:CreateTexture(nil, "ARTWORK")
frame.iconTexture:SetTexCoord(unpack(E.TexCoords))
frame.iconTexture:SetInside()
frame.cooldown = CreateFrame("Cooldown", "$parentCooldown", frame, "CooldownFrameTemplate")
frame.cooldown:SetReverse(true)
frame.cooldown:SetInside()
E:RegisterCooldown(frame.cooldown)
self.bar[i] = frame
end
self.Initialized = true
self:PositionAndSize()
E:CreateMover(bar, "TotemBarMover", TUTORIAL_TITLE47, nil, nil, nil, nil, nil, "general,totems")
self:RegisterEvent("PLAYER_TOTEM_UPDATE", "UpdateTotem")
self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdateAllTotems")
end
local function InitializeCallback()
TOTEMS:Initialize()
end
E:RegisterModule(TOTEMS:GetName(), InitializeCallback)
+463
View File
@@ -0,0 +1,463 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
local LSM = E.Libs.LSM
local LAI = E.Libs.LAI
--Lua functions
local select, unpack, pairs = select, unpack, pairs
local band = bit.band
local tinsert = table.insert
local floor = math.floor
local split = string.split
--WoW API / Variables
local CreateFrame = CreateFrame
local GetSpellInfo = GetSpellInfo
local GetTime = GetTime
local CREATED, VISIBLE, HIDDEN = 2, 1, 0
local positionValues = {
BOTTOMLEFT = "TOP",
BOTTOMRIGHT = "TOP",
LEFT = "RIGHT",
RIGHT = "LEFT",
TOPLEFT = "BOTTOM",
TOPRIGHT = "BOTTOM"
}
local positionValues2 = {
BOTTOMLEFT = "BOTTOM",
BOTTOMRIGHT = "BOTTOM",
LEFT = "LEFT",
RIGHT = "RIGHT",
TOPLEFT = "TOP",
TOPRIGHT = "TOP"
}
local RaidIconBit = {
["STAR"] = 0x00100000,
["CIRCLE"] = 0x00200000,
["DIAMOND"] = 0x00400000,
["TRIANGLE"] = 0x00800000,
["MOON"] = 0x01000000,
["SQUARE"] = 0x02000000,
["CROSS"] = 0x04000000,
["SKULL"] = 0x08000000
}
local ByRaidIcon = {}
function NP:LibAuraInfo_AURA_APPLIED(event, destGUID)
self:UpdateElement_AurasByGUID(destGUID, event)
end
function NP:LibAuraInfo_AURA_REMOVED(event, destGUID)
self:UpdateElement_AurasByGUID(destGUID, event)
end
function NP:LibAuraInfo_AURA_REFRESH(event, destGUID)
self:LibAuraInfo_AURA_APPLIED(event, destGUID)
end
function NP:LibAuraInfo_AURA_APPLIED_DOSE(event, destGUID)
self:LibAuraInfo_AURA_APPLIED(event, destGUID)
end
function NP:LibAuraInfo_AURA_CLEAR(event, destGUID)
self:UpdateElement_AurasByGUID(destGUID, event)
end
function NP:LibAuraInfo_UNIT_AURA(event, destGUID)
self:UpdateElement_AurasByGUID(destGUID, event)
end
function NP:UpdateTime(elapsed)
self.timeLeft = self.timeLeft - elapsed
self:SetValue(self.timeLeft)
if self.nextUpdate > 0 then
self.nextUpdate = self.nextUpdate - elapsed
return
end
if self.timeLeft < 0 then
self:SetScript("OnUpdate", nil)
self:Hide()
return
end
local value, id, nextUpdate, remainder = E:GetTimeInfo(self.timeLeft, self.threshold, self.hhmmThreshold, self.mmssThreshold)
self.nextUpdate = nextUpdate
local style = E.TimeFormats[id]
if style then
local which = (self.textColors and 2 or 1) + (self.showSeconds and 0 or 2)
if self.textColors then
self.text:SetFormattedText(style[which], value, self.textColors[id], remainder)
else
self.text:SetFormattedText(style[which], value, remainder)
end
end
local color = self.timeColors[id]
if color then
self.text:SetTextColor(color.r, color.g, color.b)
end
end
local unstableAffliction = GetSpellInfo(30108)
local vampiricTouch = GetSpellInfo(34914)
function NP:SetAura(frame, guid, index, filter, isDebuff, visible)
local isAura, name, texture, count, debuffType, duration, expiration, caster, spellID, _ = LAI:GUIDAura(guid, index, filter)
if frame.forceShow or frame.forceCreate then
spellID = 47540
name, _, texture = GetSpellInfo(spellID)
if frame.forceShow then
isAura, count, debuffType, duration, expiration = true, 5, "Magic", 0, 0
end
end
if isAura then
local position = visible + 1
local button = frame[position] or NP:Construct_AuraIcon(frame, position)
button.caster = caster
button.filter = filter
button.isDebuff = isDebuff
local filterCheck = not frame.forceCreate
if not (frame.forceShow or frame.forceCreate) then
filterCheck = NP:AuraFilter(guid, button, name, texture, count, debuffType, duration, expiration, caster, spellID)
end
if filterCheck then
if button.icon then button.icon:SetTexture(texture) end
if button.count then button.count:SetText(count > 1 and count) end
if duration > 0 and expiration ~= 0 then
local timeLeft = expiration - GetTime()
if timeLeft > 0 then
button.timeLeft = timeLeft
button.nextUpdate = 0
button:SetMinMaxValues(0, duration)
button:SetValue(timeLeft)
button:SetScript("OnUpdate", NP.UpdateTime)
-- else
-- return HIDDEN
end
else
button.timeLeft = nil
button.text:SetText("")
button:SetScript("OnUpdate", nil)
button:SetMinMaxValues(0, 1)
button:SetValue(0)
end
button:SetID(index)
button:Show()
if isDebuff then
local color = (debuffType and DebuffTypeColor[debuffType]) or DebuffTypeColor.none
if button.name and (button.name == unstableAffliction or button.name == vampiricTouch) then
self:StyleFrameColor(button, 0.05, 0.85, 0.94)
else
self:StyleFrameColor(button, color.r * 0.6, color.g * 0.6, color.b * 0.6)
end
end
return VISIBLE
elseif frame.forceCreate then
button:Hide()
return CREATED
else
return HIDDEN
end
end
end
function NP:Update_AurasPosition(frame, db)
local size = db.size + db.spacing
local anchor = E.InversePoints[db.anchorPoint]
local growthx = (db.growthX == "LEFT" and -1) or 1
local growthy = (db.growthY == "DOWN" and -1) or 1
local cols = db.perrow
for i = frame.anchoredIcons + 1, #frame do
local button = frame[i]
if not button then break end
local col = (i - 1) % cols
local row = floor((i - 1) / cols)
button:SetSize(db.size, db.size)
button:ClearAllPoints()
button:SetPoint(anchor, frame, anchor, col * size * growthx, row * size * growthy)
button.count:FontTemplate(LSM:Fetch("font", db.countFont), db.countFontSize, db.countFontOutline)
button.count:ClearAllPoints()
button.count:SetPoint(db.countPosition, db.countXOffset, db.countYOffset)
button.text:FontTemplate(LSM:Fetch("font", db.durationFont), db.durationFontSize, db.durationFontOutline)
button.text:ClearAllPoints()
button.text:SetPoint(db.durationPosition, db.durationXOffset, db.durationYOffset)
button:SetOrientation(db.cooldownOrientation)
button.bg:ClearAllPoints()
if db.cooldownOrientation == "VERTICAL" then
button.bg:SetPoint("TOPLEFT", button)
button.bg:SetPoint("BOTTOMRIGHT", button:GetStatusBarTexture(), "TOPRIGHT")
else
button.bg:SetPoint("TOPRIGHT", button)
button.bg:SetPoint("BOTTOMLEFT", button:GetStatusBarTexture(), "BOTTOMRIGHT")
end
if db.reverseCooldown then
button:SetStatusBarColor(0, 0, 0, 0.5)
button.bg:SetTexture(0, 0, 0, 0)
else
button:SetStatusBarColor(0, 0, 0, 0)
button.bg:SetTexture(0, 0, 0, 0.5)
end
end
end
function NP:UpdateElement_AuraIcons(frame, guid, filter, limit, isDebuff)
local index, visible, hidden, created = 1, 0, 0, 0
while visible < limit do
local result = NP:SetAura(frame, guid, index, filter, isDebuff, visible)
if not result then
break
elseif result == HIDDEN then
hidden = hidden + 1
elseif result == VISIBLE then
visible = visible + 1
elseif result == CREATED then
visible = visible + 1
created = created + 1
end
index = index + 1
end
visible = visible - created
for i = visible + 1, #frame do
frame[i].timeLeft = nil
frame[i]:SetScript("OnUpdate", nil)
frame[i]:Hide()
end
return visible
end
function NP:UpdateElement_Auras(frame)
if not frame.Health:IsShown() then return end
local guid = frame.guid
if not guid then
if frame.UnitClass == "HERO" then
local name = frame.UnitName
guid = self.GUIDByName[name]
elseif frame.RaidIcon:IsShown() then
guid = ByRaidIcon[frame.RaidIconType]
end
if guid then
frame.guid = guid
elseif not frame.Buffs.forceShow and not frame.Debuffs.forceShow then
return
end
end
local db = NP.db.units[frame.UnitType].buffs
if db.enable then
local buffs = frame.Buffs
buffs.visibleBuffs = NP:UpdateElement_AuraIcons(buffs, guid, buffs.filter or "HELPFUL", db.perrow * db.numrows)
if #buffs > buffs.anchoredIcons then
self:Update_AurasPosition(buffs, db)
buffs.anchoredIcons = #buffs
end
end
db = NP.db.units[frame.UnitType].debuffs
if db.enable then
local debuffs = frame.Debuffs
debuffs.visibleDebuffs = NP:UpdateElement_AuraIcons(debuffs, guid, debuffs.filter or "HARMFUL", db.perrow * db.numrows, true)
if #debuffs > debuffs.anchoredIcons then
self:Update_AurasPosition(debuffs, db)
debuffs.anchoredIcons = #debuffs
end
end
self:StyleFilterUpdate(frame, "UNIT_AURA")
end
function NP:UpdateElement_AurasByGUID(guid, event)
local destName, destFlags = LAI:GetGUIDInfo(guid)
if destName then
destName = split("-", destName)
end
local raidIcon
if destFlags then
for iconName, bitmask in pairs(RaidIconBit) do
if band(destFlags, bitmask) > 0 then
ByRaidIcon[iconName] = guid
raidIcon = iconName
break
end
end
end
local frame = self:SearchForFrame(guid, raidIcon, destName)
if frame then
frame.guid = guid
self.GUIDByName[destName] = guid
self:UpdateElement_Auras(frame)
end
end
function NP:Construct_AuraIcon(parent, index)
local db = NP.db.units[parent:GetParent().UnitType][parent.type]
local button = CreateFrame("StatusBar", "$parentButton"..index, parent)
NP:StyleFrame(button, true)
button:SetStatusBarTexture(E.media.blankTex)
button:SetStatusBarColor(0, 0, 0, 0)
button:SetOrientation("VERTICAL")
button.bg = button:CreateTexture()
button.bg:SetTexture(0, 0, 0, 0.5)
button.bg:SetPoint("TOPLEFT", button)
button.bg:SetPoint("BOTTOMRIGHT", button:GetStatusBarTexture(), "TOPRIGHT")
button.icon = button:CreateTexture(nil, "BORDER")
button.icon:SetTexCoord(unpack(E.TexCoords))
button.icon:SetAllPoints()
button.count = button:CreateFontString(nil, "OVERLAY")
button.count:SetJustifyH("RIGHT")
button.count:FontTemplate(LSM:Fetch("font", db.countFont), db.countFontSize, db.countFontOutline)
button.text = button:CreateFontString(nil, "OVERLAY")
-- support cooldown override
if not button.isRegisteredCooldown then
button.CooldownOverride = "nameplates"
button.isRegisteredCooldown = true
button.forceEnabled = true
if not E.RegisteredCooldowns.nameplates then E.RegisteredCooldowns.nameplates = {} end
tinsert(E.RegisteredCooldowns.nameplates, button)
end
button.text:FontTemplate(LSM:Fetch("font", db.durationFont), db.durationFontSize, db.durationFontOutline)
NP:Update_CooldownOptions(button)
tinsert(parent, button)
return button
end
function NP:Update_CooldownOptions(button)
E:Cooldown_Options(button, self.db.cooldown, button)
end
function NP:Configure_Auras(frame, auraType)
local auras = frame[auraType]
local db = self.db.units[frame.UnitType][auras.type]
auras:SetWidth(db.perrow * db.size + ((db.perrow - 1) * db.spacing))
auras:SetHeight(db.numrows * db.size + ((db.numrows - 1) * db.spacing))
auras:ClearAllPoints()
auras:SetPoint(positionValues[db.anchorPoint], db.attachTo == "BUFFS" and frame.Buffs or frame.Health, positionValues2[db.anchorPoint], db.xOffset, db.yOffset)
end
function NP:ConstructElement_Auras(frame, auraType)
local auras = CreateFrame("Frame", "$parent"..auraType, frame)
auras:Show()
auras:SetSize(150, 27)
auras:SetPoint("TOP", 0, 22)
auras.anchoredIcons = 0
auras.type = string.lower(auraType)
return auras
end
function NP:CheckFilter(name, spellID, isPlayer, allowDuration, noDuration, ...)
for i = 1, select("#", ...) do
local filterName = select(i, ...)
if not filterName then return true end
if G.nameplates.specialFilters[filterName] or E.global.unitframe.aurafilters[filterName] then
local filter = E.global.unitframe.aurafilters[filterName]
if filter then
local filterType = filter.type
local spellList = filter.spells
local spell = spellList and (spellList[spellID] or spellList[name])
if filterType and (filterType == "Whitelist") and (spell and spell.enable) and allowDuration then
return true
elseif filterType and (filterType == "Blacklist") and (spell and spell.enable) then
return false
end
elseif filterName == "Personal" and isPlayer and allowDuration then
return true
elseif filterName == "nonPersonal" and (not isPlayer) and allowDuration then
return true
elseif filterName == "blockNoDuration" and noDuration then
return false
elseif filterName == "blockNonPersonal" and (not isPlayer) then
return false
end
end
end
end
function NP:AuraFilter(guid, button, name, texture, count, debuffType, duration, expiration, caster, spellID)
local parent = button:GetParent()
local parentType = parent.type
local db = NP.db.units[parent:GetParent().UnitType][parentType]
if not db then return true end
local isPlayer = caster == E.myguid
-- keep these same as in `UF:AuraFilter`
button.isPlayer = isPlayer
button.dtype = debuffType
button.duration = duration
button.expiration = expiration
button.stackCount = count
button.name = name
button.spellID = spellID
button.spell = name
button.priority = 0
if not db.filters then return true end
local priority = db.filters.priority
local noDuration = (not duration or duration == 0)
local allowDuration = noDuration or (duration and (duration > 0) and db.filters.maxDuration == 0 or duration <= db.filters.maxDuration) and (db.filters.minDuration == 0 or duration >= db.filters.minDuration)
local filterCheck
if priority ~= "" then
filterCheck = NP:CheckFilter(name, spellID, isPlayer, allowDuration, noDuration, split(",", priority))
else
filterCheck = allowDuration and true -- Allow all auras to be shown when the filter list is empty, while obeying duration sliders
end
return filterCheck
end
@@ -0,0 +1,358 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
local LSM = E.Libs.LSM
--Lua functions
local unpack = unpack
local abs = math.abs
--WoW API / Variables
local CreateFrame = CreateFrame
local GetTime = GetTime
local UnitCastingInfo = UnitCastingInfo
local UnitChannelInfo = UnitChannelInfo
local FAILED = FAILED
local INTERRUPTED = INTERRUPTED
local function resetAttributes(self)
self.casting = nil
self.channeling = nil
self.notInterruptible = nil
self.spellName = nil
end
function NP:Update_CastBarOnUpdate(elapsed)
if self.casting or self.channeling then
local isCasting = self.casting
if isCasting then
self.value = self.value + elapsed
if self.value >= self.max then
resetAttributes(self)
self:Hide()
NP:StyleFilterUpdate(self:GetParent(), "FAKE_Casting")
return
end
else
self.value = self.value - elapsed
if self.value <= 0 then
resetAttributes(self)
self:Hide()
NP:StyleFilterUpdate(self:GetParent(), "FAKE_Casting")
return
end
end
if self.delay ~= 0 then
if self.channeling then
if self.channelTimeFormat == "CURRENT" then
self.Time:SetFormattedText("%.1f |cffaf5050%.2f|r", abs(self.value - self.max), self.delay)
elseif self.channelTimeFormat == "CURRENTMAX" then
self.Time:SetFormattedText("%.1f / %.2f |cffaf5050%.2f|r", abs(self.value - self.max), self.max, self.delay)
elseif self.channelTimeFormat == "REMAINING" then
self.Time:SetFormattedText("%.1f |cffaf5050%.2f|r", self.value, self.delay)
elseif self.channelTimeFormat == "REMAININGMAX" then
self.Time:SetFormattedText("%.1f / %.2f |cffaf5050%.2f|r", self.value, self.max, self.max, self.delay)
end
else
if self.castTimeFormat == "CURRENT" then
self.Time:SetFormattedText("%.1f |cffaf5050%s %.2f|r", self.value, "+", self.delay)
elseif self.castTimeFormat == "CURRENTMAX" then
self.Time:SetFormattedText("%.1f / %.2f |cffaf5050%s %.2f|r", self.value, self.max, "+", self.delay)
elseif self.castTimeFormat == "REMAINING" then
self.Time:SetFormattedText("%.1f |cffaf5050%s %.2f|r", abs(self.value - self.max), "+", self.delay)
elseif self.castTimeFormat == "REMAININGMAX" then
self.Time:SetFormattedText("%.1f / %.2f |cffaf5050%s %.2f|r", abs(self.value - self.max), self.max, "+", self.delay)
end
end
else
if self.channeling then
if self.channelTimeFormat == "CURRENT" then
self.Time:SetFormattedText("%.1f", abs(self.value - self.max))
elseif self.channelTimeFormat == "CURRENTMAX" then
self.Time:SetFormattedText("%.1f / %.2f", abs(self.value - self.max), self.max)
elseif self.channelTimeFormat == "REMAINING" then
self.Time:SetFormattedText("%.1f", self.value)
elseif self.channelTimeFormat == "REMAININGMAX" then
self.Time:SetFormattedText("%.1f / %.2f", self.value, self.max)
end
else
if self.castTimeFormat == "CURRENT" then
self.Time:SetFormattedText("%.1f", self.value)
elseif self.castTimeFormat == "CURRENTMAX" then
self.Time:SetFormattedText("%.1f / %.2f", self.value, self.max)
elseif self.castTimeFormat == "REMAINING" then
self.Time:SetFormattedText("%.1f", abs(self.value - self.max))
elseif self.castTimeFormat == "REMAININGMAX" then
self.Time:SetFormattedText("%.1f / %.2f", abs(self.value - self.max), self.max)
end
end
end
self:SetValue(self.value)
elseif self.holdTime > 0 then
self.holdTime = self.holdTime - elapsed
else
resetAttributes(self)
self:Hide()
NP:StyleFilterUpdate(self:GetParent(), "FAKE_Casting")
end
end
function NP:Update_CastBar(frame, event, unit)
local castBar = frame.CastBar
if unit then
if not event then
if UnitChannelInfo(unit) then
event = "UNIT_SPELLCAST_CHANNEL_START"
elseif UnitCastingInfo(unit) then
event = "UNIT_SPELLCAST_START"
end
end
elseif castBar:IsShown() then
resetAttributes(castBar)
castBar:Hide()
end
if self.db.units[frame.UnitType].castbar.enable ~= true then return end
if self.db.units[frame.UnitType].health.enable ~= true and not (frame.isTarget and self.db.alwaysShowTargetHealth) then return end --Bug
if event == "UNIT_SPELLCAST_START" or event == "UNIT_SPELLCAST_CHANNEL_START" then
local name, _, _, texture, startTime, endTime, _, _, notInterruptible = UnitCastingInfo(unit)
event = "UNIT_SPELLCAST_START"
if not name then
name, _, _, texture, startTime, endTime, _, notInterruptible = UnitChannelInfo(unit)
event = "UNIT_SPELLCAST_CHANNEL_START"
end
if not name then
resetAttributes(castBar)
castBar:Hide()
return
end
endTime = endTime / 1000
startTime = startTime / 1000
castBar.max = endTime - startTime
castBar.startTime = startTime
castBar.delay = 0
castBar.casting = event == "UNIT_SPELLCAST_START"
castBar.channeling = event == "UNIT_SPELLCAST_CHANNEL_START"
castBar.notInterruptible = notInterruptible
castBar.holdTime = 0
castBar.interrupted = nil
castBar.spellName = name
if castBar.casting then
castBar.value = GetTime() - startTime
else
castBar.value = endTime - GetTime()
end
castBar:SetMinMaxValues(0, castBar.max)
castBar:SetValue(castBar.value)
castBar.Icon.texture:SetTexture(texture)
castBar.Spark:Show()
castBar.Name:SetText(name)
castBar.Time:SetText()
castBar:Show()
elseif event == "UNIT_SPELLCAST_STOP" or event == "UNIT_SPELLCAST_CHANNEL_STOP" then
if castBar:IsShown() then
resetAttributes(castBar)
end
elseif event == "UNIT_SPELLCAST_FAILED" or event == "UNIT_SPELLCAST_INTERRUPTED" then
if castBar:IsShown() then
castBar.Spark:Hide()
castBar.Name:SetText(event == "UNIT_SPELLCAST_FAILED" and FAILED or INTERRUPTED)
castBar.holdTime = self.db.units[frame.UnitType].castbar.timeToHold --How long the castbar should stay visible after being interrupted, in seconds
castBar.interrupted = true
resetAttributes(castBar)
castBar:SetValue(castBar.max)
end
elseif event == "UNIT_SPELLCAST_DELAYED" or event == "UNIT_SPELLCAST_CHANNEL_UPDATE" then
if frame:IsShown() then
local name, startTime, endTime, _
if event == "UNIT_SPELLCAST_DELAYED" then
name, _, _, _, startTime, endTime = UnitCastingInfo(unit)
else
name, _, _, _, startTime, endTime = UnitChannelInfo(unit)
end
if not name then
resetAttributes(castBar)
castBar:Hide()
return
end
endTime = endTime / 1000
startTime = startTime / 1000
local delta
if castBar.casting then
delta = startTime - castBar.startTime
castBar.value = GetTime() - startTime
else
delta = castBar.startTime - startTime
castBar.value = endTime - GetTime()
end
if delta < 0 then
delta = 0
end
castBar.Name:SetText(name)
castBar.max = endTime - startTime
castBar.startTime = startTime
castBar.delay = castBar.delay + delta
castBar:SetMinMaxValues(0, castBar.max)
castBar:SetValue(castBar.value)
end
elseif event == "UNIT_SPELLCAST_INTERRUPTIBLE" or event == "UNIT_SPELLCAST_NOT_INTERRUPTIBLE" then
castBar.notInterruptible = event == "UNIT_SPELLCAST_NOT_INTERRUPTIBLE"
end
if not castBar.notInterruptible then
if castBar.interrupted then
castBar:SetStatusBarColor(self.db.colors.castInterruptedColor.r, self.db.colors.castInterruptedColor.g, self.db.colors.castInterruptedColor.b)
else
castBar:SetStatusBarColor(self.db.colors.castColor.r, self.db.colors.castColor.g, self.db.colors.castColor.b)
end
castBar.Icon.texture:SetDesaturated(false)
else
castBar:SetStatusBarColor(self.db.colors.castNoInterruptColor.r, self.db.colors.castNoInterruptColor.g, self.db.colors.castNoInterruptColor.b)
if self.db.colors.castbarDesaturate then
castBar.Icon.texture:SetDesaturated(true)
end
end
self:StyleFilterUpdate(frame, "FAKE_Casting")
end
function NP:Configure_CastBarScale(frame, scale, noPlayAnimation)
if frame.currentScale == scale then return end
local db = self.db.units[frame.UnitType].castbar
if not db.enable then return end
local castBar = frame.CastBar
if noPlayAnimation then
castBar:SetSize(db.width * scale, db.height * scale)
castBar.Icon:SetSize(db.iconSize * scale, db.iconSize * scale)
else
if castBar.scale:IsPlaying() or castBar.Icon.scale:IsPlaying() then
castBar.scale:Stop()
castBar.Icon.scale:Stop()
end
castBar.scale.width:SetChange(db.width * scale)
castBar.scale.height:SetChange(db.height * scale)
castBar.scale:Play()
castBar.Icon.scale.width:SetChange(db.iconSize * scale)
castBar.Icon.scale.height:SetChange(db.iconSize * scale)
castBar.Icon.scale:Play()
end
end
function NP:Configure_CastBar(frame, configuring)
local db = self.db.units[frame.UnitType].castbar
local castBar = frame.CastBar
castBar:SetPoint("TOP", frame.Health, "BOTTOM", db.xOffset, db.yOffset)
if db.showIcon then
castBar.Icon:ClearAllPoints()
castBar.Icon:SetPoint(db.iconPosition == "RIGHT" and "BOTTOMLEFT" or "BOTTOMRIGHT", castBar, db.iconPosition == "RIGHT" and "BOTTOMRIGHT" or "BOTTOMLEFT", db.iconOffsetX, db.iconOffsetY)
castBar.Icon:Show()
else
castBar.Icon:Hide()
end
castBar.Time:ClearAllPoints()
castBar.Name:ClearAllPoints()
castBar.Spark:SetPoint("CENTER", castBar:GetStatusBarTexture(), "RIGHT", 0, 0)
castBar.Spark:SetHeight(db.height * 2)
if db.textPosition == "BELOW" then
castBar.Time:SetPoint("TOPRIGHT", castBar, "BOTTOMRIGHT")
castBar.Name:SetPoint("TOPLEFT", castBar, "BOTTOMLEFT")
elseif db.textPosition == "ABOVE" then
castBar.Time:SetPoint("BOTTOMRIGHT", castBar, "TOPRIGHT")
castBar.Name:SetPoint("BOTTOMLEFT", castBar, "TOPLEFT")
else
castBar.Time:SetPoint("RIGHT", castBar, "RIGHT", -4, 0)
castBar.Name:SetPoint("LEFT", castBar, "LEFT", 4, 0)
end
if configuring then
self:Configure_CastBarScale(frame, frame.currentScale or 1, configuring)
end
castBar.Name:FontTemplate(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline)
castBar.Time:FontTemplate(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline)
if db.hideSpellName then
castBar.Name:Hide()
else
castBar.Name:Show()
end
if db.hideTime then
castBar.Time:Hide()
else
castBar.Time:Show()
end
castBar:SetStatusBarTexture(LSM:Fetch("statusbar", self.db.statusbar))
castBar.castTimeFormat = db.castTimeFormat
castBar.channelTimeFormat = db.channelTimeFormat
end
function NP:Construct_CastBar(parent)
local frame = CreateFrame("StatusBar", "$parentCastBar", parent)
NP:StyleFrame(frame)
frame:SetScript("OnUpdate", NP.Update_CastBarOnUpdate)
frame.Icon = CreateFrame("Frame", nil, frame)
frame.Icon.texture = frame.Icon:CreateTexture(nil, "BORDER")
frame.Icon.texture:SetAllPoints()
frame.Icon.texture:SetTexCoord(unpack(E.TexCoords))
NP:StyleFrame(frame.Icon)
frame.Time = frame:CreateFontString(nil, "OVERLAY")
frame.Time:SetJustifyH("RIGHT")
frame.Time:SetWordWrap(false)
frame.Name = frame:CreateFontString(nil, "OVERLAY")
frame.Name:SetJustifyH("LEFT")
frame.Name:SetWordWrap(false)
frame.Spark = frame:CreateTexture(nil, "OVERLAY")
frame.Spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
frame.Spark:SetBlendMode("ADD")
frame.Spark:SetSize(15, 15)
frame.holdTime = 0
frame.interrupted = nil
frame.scale = CreateAnimationGroup(frame)
frame.scale.width = frame.scale:CreateAnimation("Width")
frame.scale.width:SetDuration(0.2)
frame.scale.height = frame.scale:CreateAnimation("Height")
frame.scale.height:SetDuration(0.2)
frame.Icon.scale = CreateAnimationGroup(frame.Icon)
frame.Icon.scale.width = frame.Icon.scale:CreateAnimation("Width")
frame.Icon.scale.width:SetDuration(0.2)
frame.Icon.scale.height = frame.Icon.scale:CreateAnimation("Height")
frame.Icon.scale.height:SetDuration(0.2)
frame:Hide()
return frame
end
@@ -0,0 +1,119 @@
local E, L, V, P, G = unpack(select(2, ...))
local NP = E:GetModule("NamePlates")
local LSM = E.Libs.LSM
--Lua functions
--WoW API / Variables
local CreateFrame = CreateFrame
local GetComboPoints = GetComboPoints
local MAX_COMBO_POINTS = MAX_COMBO_POINTS
function NP:Update_CPoints(frame)
if frame.UnitType == "FRIENDLY_PLAYER" or frame.UnitType == "FRIENDLY_NPC" then return end
if not self.db.units.TARGET.comboPoints.enable then return end
local numPoints
if frame.isTarget then
numPoints = GetComboPoints("player", "target")
end
if numPoints and numPoints > 0 then
frame.CPoints:Show()
for i = 1, MAX_COMBO_POINTS do
if i <= numPoints then
frame.CPoints[i]:Show()
else
frame.CPoints[i]:Hide()
end
end
else
frame.CPoints:Hide()
end
end
function NP:Configure_CPointsScale(frame, scale, noPlayAnimation)
if frame.UnitType == "FRIENDLY_PLAYER" or frame.UnitType == "FRIENDLY_NPC" then return end
local db = self.db.units.TARGET.comboPoints
if not db.enable then return end
if noPlayAnimation then
frame.CPoints:SetWidth(((db.width * 5) + (db.spacing * 4)) * scale)
frame.CPoints:SetHeight(db.height * scale)
else
if frame.CPoints.scale:IsPlaying() then
frame.CPoints.scale:Stop()
end
frame.CPoints.scale.width:SetChange(((db.width * 5) + (db.spacing * 4)) * scale)
frame.CPoints.scale.height:SetChange(db.height * scale)
frame.CPoints.scale:Play()
end
end
function NP:Configure_CPoints(frame, configuring)
if frame.UnitType == "FRIENDLY_PLAYER" or frame.UnitType == "FRIENDLY_NPC" then return end
local db = self.db.units.TARGET.comboPoints
if not db.enable then return end
local comboBar = frame.CPoints
local healthShown = self.db.units[frame.UnitType].health.enable or (frame.isTarget and self.db.alwaysShowTargetHealth)
comboBar:ClearAllPoints()
if healthShown then
comboBar:Point("CENTER", frame.Health, "BOTTOM", db.xOffset, db.yOffset)
else
comboBar:Point("CENTER", frame, "TOP", db.xOffset, db.yOffset)
end
for i = 1, MAX_COMBO_POINTS do
local comboPoint = comboBar[i]
comboPoint.backdrop:SetTexture(LSM:Fetch("statusbar", self.db.statusbar))
local color = self.db.colors.comboPoints[i]
comboPoint.backdrop:SetVertexColor(color.r, color.g, color.b)
comboPoint:SetWidth(db.width)
comboPoint:ClearAllPoints()
if i == 1 then
comboPoint:SetPoint("TOPLEFT")
comboPoint:SetPoint("BOTTOMLEFT")
else
comboPoint:SetPoint("TOPLEFT", comboBar[i - 1], "TOPRIGHT", db.spacing, 0)
comboPoint:SetPoint("BOTTOMLEFT", comboBar[i - 1], "BOTTOMRIGHT")
end
end
comboBar.spacing = db.spacing * (MAX_COMBO_POINTS - 1)
if configuring then
self:Configure_CPointsScale(frame, frame.currentScale or 1, configuring)
end
end
local function CPoints_OnSizeChanged(self, width)
width = width - self.spacing
for i = 1, MAX_COMBO_POINTS do
self[i]:SetWidth(width * 0.2)
end
end
function NP:Construct_CPoints(parent)
local comboBar = CreateFrame("Frame", "$parentComboPoints", parent)
comboBar:Hide()
comboBar.scale = CreateAnimationGroup(comboBar)
comboBar.scale.width = comboBar.scale:CreateAnimation("Width")
comboBar.scale.width:SetDuration(0.2)
comboBar.scale.height = comboBar.scale:CreateAnimation("Height")
comboBar.scale.height:SetDuration(0.2)
comboBar:SetScript("OnSizeChanged", CPoints_OnSizeChanged)
for i = 1, MAX_COMBO_POINTS do
comboBar[i] = CreateFrame("Frame", "$parentComboPoint"..i, comboBar)
self:StyleFrame(comboBar[i])
end
return comboBar
end
@@ -0,0 +1,61 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
--Lua functions
--WoW API / Variables
function NP:UpdateElement_CutawayHealthFadeOut(frame)
local cutawayHealth = frame.CutawayHealth
cutawayHealth.fading = true
E:UIFrameFadeOut(cutawayHealth, self.db.cutawayHealthFadeOutTime, cutawayHealth:GetAlpha(), 0)
cutawayHealth.isPlaying = nil
end
local function CutawayHealthClosure(frame)
NP:UpdateElement_CutawayHealthFadeOut(frame)
end
function NP:CutawayHealthValueChangeCallback(frame, health, maxHealth)
if self.db.cutawayHealth then
frame.CutawayHealth:SetMinMaxValues(0, maxHealth)
local oldValue = frame.Health:GetValue()
local change = oldValue - health
if change > 0 and not frame.CutawayHealth.isPlaying then
local cutawayHealth = frame.CutawayHealth
if cutawayHealth.fading then
E:UIFrameFadeRemoveFrame(cutawayHealth)
end
cutawayHealth.fading = false
cutawayHealth:SetValue(oldValue)
cutawayHealth:SetAlpha(1)
E:Delay(self.db.cutawayHealthLength, CutawayHealthClosure, frame)
cutawayHealth.isPlaying = true
cutawayHealth:Show()
end
else
if frame.CutawayHealth.isPlaying then
frame.CutawayHealth.isPlaying = nil
frame.CutawayHealth:SetScript("OnUpdate", nil)
end
frame.CutawayHealth:Hide()
end
end
function NP:CutawayHealthColorChangeCallback(frame, r, g, b)
frame.CutawayHealth:SetStatusBarColor(r * 1.5, g * 1.5, b * 1.5, 1)
end
function NP:ConstructElement_CutawayHealth(parent)
local healthBar = parent.Health
local cutawayHealth = CreateFrame("StatusBar", "$parentCutawayHealth", healthBar)
cutawayHealth:SetAllPoints()
cutawayHealth:SetStatusBarTexture(E.media.blankTex)
cutawayHealth:SetFrameLevel(healthBar:GetFrameLevel() - 1)
NP:RegisterHealthBarCallbacks(parent, NP.CutawayHealthValueChangeCallback, NP.CutawayHealthColorChangeCallback)
return cutawayHealth
end
@@ -0,0 +1,53 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
--Lua functions
--WoW API / Variables
function NP:Update_Elite(frame)
local db = self.db.units[frame.UnitType].eliteIcon
if not db then return end
local icon = frame.Elite
if db.enable then
local elite, boss = frame.EliteIcon:IsShown(), frame.BossIcon:IsShown()
if boss then
icon:SetTexCoord(0, 0.15, 0.62, 0.94)
icon:Show()
elseif elite then
icon:SetTexCoord(0, 0.15, 0.35, 0.63)
icon:Show()
else
icon:Hide()
end
else
icon:Hide()
end
end
function NP:Configure_Elite(frame)
local db = self.db.units[frame.UnitType].eliteIcon
if not db then return end
local icon = frame.Elite
icon:Size(db.size)
icon:ClearAllPoints()
if frame.Health:IsShown() then
icon:SetParent(frame.Health)
icon:Point(db.position, frame.Health, db.position, db.xOffset, db.yOffset)
else
icon:SetParent(frame)
icon:Point(db.position, frame, db.position, db.xOffset, db.yOffset)
end
end
function NP:Construct_Elite(frame)
local icon = frame.Health:CreateTexture(nil, "OVERLAY")
icon:SetTexture(E.Media.Textures.Nameplates)
icon:Hide()
return icon
end
+193
View File
@@ -0,0 +1,193 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
local LSM = E.Libs.LSM
--Lua functions
local ipairs = ipairs
--WoW API / Variables
local CreateFrame = CreateFrame
--[[
Target Glow Style Option Variables
style1 - Border
style2 - Background
style3 - Top Arrow Only
style4 - Side Arrows Only
style5 - Border + Top Arrow
style6 - Background + Top Arrow
style7 - Border + Side Arrows
style8 - Background + Side Arrows
]]
function NP:Update_Glow(frame)
local showIndicator
if frame.isTarget then
showIndicator = 1
elseif self.db.lowHealthThreshold > 0 then
local health = frame.oldHealthBar:GetValue()
local _, maxHealth = frame.oldHealthBar:GetMinMaxValues()
local perc = health / maxHealth
if health > 1 and perc <= self.db.lowHealthThreshold then
if perc <= self.db.lowHealthThreshold / 2 then
showIndicator = 2
else
showIndicator = 3
end
end
end
local glowStyle = self.db.units.TARGET.glowStyle
local healthIsShown = frame.Health:IsShown()
if not healthIsShown then
if glowStyle == "style1" then
glowStyle = "none"
elseif glowStyle == "style5" then
glowStyle = "style3"
elseif glowStyle == "style7" then
glowStyle = "style4"
end
end
if showIndicator and glowStyle ~= "none" then
local r, g, b
if showIndicator == 1 then
local color = self.db.colors.glowColor
r, g, b = color.r, color.g, color.b
elseif showIndicator == 2 then
r, g, b = 1, 0, 0
else
r, g, b = 1, 1, 0
end
-- Indicators
frame.TopIndicator:SetVertexColor(r, g, b)
frame.LeftIndicator:SetVertexColor(r, g, b)
frame.RightIndicator:SetVertexColor(r, g, b)
if glowStyle == "style3" or glowStyle == "style5" or glowStyle == "style6" then
frame.LeftIndicator:Hide()
frame.RightIndicator:Hide()
if healthIsShown then
frame.TopIndicator:Show()
end
elseif glowStyle == "style4" or glowStyle == "style7" or glowStyle == "style8" then
frame.TopIndicator:Hide()
if healthIsShown then
frame.LeftIndicator:Show()
frame.RightIndicator:Show()
end
end
-- Spark / Shadow
frame.Shadow:SetBackdropBorderColor(r, g, b)
frame.Spark:SetVertexColor(r, g, b)
if glowStyle == "style1" or glowStyle == "style5" or glowStyle == "style7" then
frame.Spark:Hide()
frame.Shadow:Show()
elseif glowStyle == "style2" or glowStyle == "style6" or glowStyle == "style8" then
frame.Shadow:Hide()
frame.Spark:Show()
end
else
frame.TopIndicator:Hide()
frame.LeftIndicator:Hide()
frame.RightIndicator:Hide()
frame.Shadow:Hide()
frame.Spark:Hide()
end
end
function NP:Configure_Glow(frame)
local glowStyle = self.db.units.TARGET.glowStyle
local healthIsShown = frame.Health:IsShown()
if not healthIsShown then
if glowStyle == "style1" then
glowStyle = "none"
elseif glowStyle == "style5" then
glowStyle = "style3"
elseif glowStyle == "style7" then
glowStyle = "style4"
end
end
if glowStyle ~= "none" then
local color = self.db.colors.glowColor
local r, g, b, a = color.r, color.g, color.b, color.a
-- Indicators
frame.LeftIndicator:SetVertexColor(r, g, b)
frame.RightIndicator:SetVertexColor(r, g, b)
frame.TopIndicator:SetVertexColor(r, g, b)
frame.TopIndicator:ClearAllPoints()
frame.LeftIndicator:ClearAllPoints()
frame.RightIndicator:ClearAllPoints()
if glowStyle == "style3" or glowStyle == "style5" or glowStyle == "style6" then
if healthIsShown then
frame.TopIndicator:SetPoint("BOTTOM", frame.Health, "TOP", 0, 6)
else
frame.TopIndicator:SetPoint("BOTTOM", frame.Name, "TOP", 0, 8)
end
elseif glowStyle == "style4" or glowStyle == "style7" or glowStyle == "style8" then
if healthIsShown then
frame.LeftIndicator:SetPoint("LEFT", frame.Health, "RIGHT", -3, 0)
frame.RightIndicator:SetPoint("RIGHT", frame.Health, "LEFT", 3, 0)
else
frame.LeftIndicator:SetPoint("LEFT", frame.Name, "RIGHT", 20, 0)
frame.RightIndicator:SetPoint("RIGHT", frame.Name, "LEFT", -20, 0)
end
end
-- Spark / Shadow
frame.Shadow:SetBackdropBorderColor(r, g, b)
frame.Shadow:SetAlpha(a)
frame.Spark:SetVertexColor(r, g, b, a)
frame.Spark:ClearAllPoints()
if glowStyle == "style1" or glowStyle == "style5" or glowStyle == "style7" then
frame.Shadow:SetOutside(frame.Health, E:Scale(E.PixelMode and 6 or 8), E:Scale(E.PixelMode and 6 or 8))
elseif glowStyle == "style2" or glowStyle == "style6" or glowStyle == "style8" then
if healthIsShown then
local size = E.Border + 14
frame.Spark:SetPoint("TOPLEFT", frame.Health, -(size * 2), size)
frame.Spark:SetPoint("BOTTOMRIGHT", frame.Health, (size * 2), -size)
else
local nameIsShown = frame.Name:IsShown()
frame.Spark:SetPoint("TOPLEFT", nameIsShown and frame.Name or frame.IconFrame, -20, 8)
frame.Spark:SetPoint("BOTTOMRIGHT", nameIsShown and frame.Name or frame.IconFrame, 20, -8)
end
end
end
end
local Textures = {"Spark", "TopIndicator", "LeftIndicator", "RightIndicator"}
function NP:Construct_Glow(frame)
frame.Shadow = CreateFrame("Frame", "$parentGlow", frame)
frame.Shadow:SetFrameLevel(frame.Health:GetFrameLevel() - 1)
frame.Shadow:SetBackdrop({edgeFile = LSM:Fetch("border", "ElvUI GlowBorder"), edgeSize = E:Scale(6)})
frame.Shadow:Hide()
for _, object in ipairs(Textures) do
frame[object] = frame:CreateTexture(nil, "BACKGROUND")
frame[object]:Hide()
end
frame.Spark:SetTexture(E.Media.Textures.Spark)
frame.TopIndicator:SetTexture(E.Media.Textures.ArrowUp)
frame.TopIndicator:SetRotation(3.14)
frame.LeftIndicator:SetTexture(E.Media.Textures.ArrowUp)
frame.LeftIndicator:SetRotation(1.57)
frame.RightIndicator:SetTexture(E.Media.Textures.ArrowUp)
frame.RightIndicator:SetRotation(-1.57)
end
@@ -0,0 +1,31 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
--Lua functions
--WoW API / Variables
function NP:Update_HealerIcon(frame)
local icon = frame.HealerIcon
if frame.UnitType == "ENEMY_PLAYER" and self.Healers[frame.UnitName] then
icon:ClearAllPoints()
if frame.Health:IsShown() then
icon:SetPoint("RIGHT", frame.Health, "LEFT", -6, 0)
else
icon:SetPoint("BOTTOM", frame.Name, "TOP", 0, 3)
end
icon:Show()
else
icon:Hide()
end
end
function NP:Construct_HealerIcon(frame)
local texture = frame:CreateTexture(nil, "OVERLAY")
texture:SetPoint("RIGHT", frame.Health, "LEFT", -6, 0)
texture:SetSize(40, 40)
texture:SetTexture(E.Media.Textures.Healer)
texture:Hide()
return texture
end
@@ -0,0 +1,213 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
local LSM = E.Libs.LSM
--Lua functions
--WoW API / Variables
function NP:Update_HealthOnValueChanged()
local frame = self:GetParent().UnitFrame
if not frame.UnitType then return end -- Bugs
NP:Update_Health(frame)
NP:Update_HealthColor(frame)
NP:Update_Glow(frame)
NP:StyleFilterUpdate(frame, "UNIT_HEALTH")
end
function NP:Update_HealthColor(frame)
if not frame.Health:IsShown() then return end
local r, g, b
local scale = 1
local classColor = E.media.herocolor
local useClassColor = NP.db.units[frame.UnitType].health.useClassColor
if classColor and ((frame.UnitType == "FRIENDLY_PLAYER" and useClassColor) or (frame.UnitType == "ENEMY_PLAYER" and useClassColor)) then
r, g, b = classColor.r, classColor.g, classColor.b
else
local db = self.db.colors
local status = frame.ThreatStatus
if status then
if status == 3 then
if E.Role == "Tank" then
r, g, b = db.threat.goodColor.r, db.threat.goodColor.g, db.threat.goodColor.b
scale = NP.db.threat.goodScale
else
r, g, b = db.threat.badColor.r, db.threat.badColor.g, db.threat.badColor.b
scale = NP.db.threat.badScale
end
elseif status == 2 then
if E.Role == "Tank" then
r, g, b = db.threat.badTransition.r, db.threat.badTransition.g, db.threat.badTransition.b
else
r, g, b = db.threat.goodTransition.r, db.threat.goodTransition.g, db.threat.goodTransition.b
end
scale = 1
elseif status == 1 then
if E.Role == "Tank" then
r, g, b = db.threat.goodTransition.r, db.threat.goodTransition.g, db.threat.goodTransition.b
else
r, g, b = db.threat.badTransition.r, db.threat.badTransition.g, db.threat.badTransition.b
end
scale = 1
else
if E.Role == "Tank" then
r, g, b = db.threat.badColor.r, db.threat.badColor.g, db.threat.badColor.b
scale = self.db.threat.badScale
else
r, g, b = db.threat.goodColor.r, db.threat.goodColor.g, db.threat.goodColor.b
scale = self.db.threat.goodScale
end
end
end
if (not status) or (status and not NP.db.threat.useThreatColor) then
local reactionType = frame.UnitReaction
if reactionType == 4 then
r, g, b = db.reactions.neutral.r, db.reactions.neutral.g, db.reactions.neutral.b
elseif reactionType and reactionType > 4 then
if frame.UnitType == "FRIENDLY_PLAYER" then
r, g, b = db.reactions.friendlyPlayer.r, db.reactions.friendlyPlayer.g, db.reactions.friendlyPlayer.b
else
r, g, b = db.reactions.good.r, db.reactions.good.g, db.reactions.good.b
end
else
r, g, b = db.reactions.bad.r, db.reactions.bad.g, db.reactions.bad.b
end
end
end
if r ~= frame.Health.r or g ~= frame.Health.g or b ~= frame.Health.b then
if not frame.HealthColorChanged then
frame.Health:SetStatusBarColor(r, g, b)
if frame.HealthColorChangeCallbacks then
for _, cb in ipairs(frame.HealthColorChangeCallbacks) do
cb(self, frame, r, g, b)
end
end
end
frame.Health.r, frame.Health.g, frame.Health.b = r, g, b
end
if frame.ThreatScale ~= scale then
frame.ThreatScale = scale
if frame.isTarget and self.db.useTargetScale then
scale = scale * self.db.targetScale
end
self:SetFrameScale(frame, scale * (frame.ActionScale or 1))
end
end
function NP:Update_Health(frame)
local health = frame.oldHealthBar:GetValue()
local _, maxHealth = frame.oldHealthBar:GetMinMaxValues()
frame.Health:SetMinMaxValues(0, maxHealth)
if frame.HealthValueChangeCallbacks then
for _, cb in ipairs(frame.HealthValueChangeCallbacks) do
cb(self, frame, health, maxHealth)
end
end
frame.Health:SetValue(health)
frame.FlashTexture:Point("TOPRIGHT", frame.Health:GetStatusBarTexture(), "TOPRIGHT") --idk why this fixes this
if self.db.units[frame.UnitType].health.text.enable then
frame.Health.Text:SetText(E:GetFormattedText(self.db.units[frame.UnitType].health.text.format, health, maxHealth))
end
end
function NP:RegisterHealthBarCallbacks(frame, valueChangeCB, colorChangeCB)
if valueChangeCB then
frame.HealthValueChangeCallbacks = frame.HealthValueChangeCallbacks or {}
tinsert(frame.HealthValueChangeCallbacks, valueChangeCB)
end
if colorChangeCB then
frame.HealthColorChangeCallbacks = frame.HealthColorChangeCallbacks or {}
tinsert(frame.HealthColorChangeCallbacks, colorChangeCB)
end
end
function NP:Update_HealthBar(frame)
if self.db.units[frame.UnitType].health.enable or (frame.isTarget and self.db.alwaysShowTargetHealth) then
frame.Health:Show()
else
frame.Health:Hide()
end
end
function NP:Configure_HealthBarScale(frame, scale, noPlayAnimation)
if noPlayAnimation then
frame.Health:SetWidth(self.db.units[frame.UnitType].health.width * scale)
frame.Health:SetHeight(self.db.units[frame.UnitType].health.height * scale)
else
if frame.Health.scale:IsPlaying() then
frame.Health.scale:Stop()
end
frame.Health.scale.width:SetChange(self.db.units[frame.UnitType].health.width * scale)
frame.Health.scale.height:SetChange(self.db.units[frame.UnitType].health.height * scale)
frame.Health.scale:Play()
end
end
function NP:Configure_HealthBar(frame, configuring)
local db = self.db.units[frame.UnitType].health
local healthBar = frame.Health
healthBar:SetPoint("TOP", frame, "TOP", 0, 0)
if configuring then
healthBar:SetStatusBarTexture(LSM:Fetch("statusbar", self.db.statusbar), "BORDER")
self:Configure_HealthBarScale(frame, frame.currentScale or 1, configuring)
E:SetSmoothing(healthBar, self.db.smoothbars)
if db.text.enable then
healthBar.Text:ClearAllPoints()
healthBar.Text:Point(E.InversePoints[db.text.position], db.text.parent == "Nameplate" and frame or frame[db.text.parent], db.text.position, db.text.xOffset, db.text.yOffset)
healthBar.Text:FontTemplate(LSM:Fetch("font", db.text.font), db.text.fontSize, db.text.fontOutline)
healthBar.Text:Show()
else
healthBar.Text:Hide()
end
end
end
local function HealthBar_OnSizeChanged(self, width)
local health = self:GetValue()
local _, maxHealth = self:GetMinMaxValues()
self:GetStatusBarTexture():SetPoint("TOPRIGHT", -(width * ((maxHealth - health) / maxHealth)), 0)
end
function NP:Construct_HealthBar(parent)
local frame = CreateFrame("StatusBar", "$parentHealthBar", parent)
frame:SetStatusBarTexture(LSM:Fetch("statusbar", self.db.statusbar), "BORDER")
self:StyleFrame(frame)
frame:SetScript("OnSizeChanged", HealthBar_OnSizeChanged)
parent.FlashTexture = frame:CreateTexture(nil, "OVERLAY")
parent.FlashTexture:SetTexture(LSM:Fetch("background", "ElvUI Blank"))
parent.FlashTexture:Point("BOTTOMLEFT", frame:GetStatusBarTexture(), "BOTTOMLEFT")
parent.FlashTexture:Point("TOPRIGHT", frame:GetStatusBarTexture(), "TOPRIGHT")
parent.FlashTexture:Hide()
frame.Text = frame:CreateFontString(nil, "OVERLAY")
frame.Text:SetAllPoints(frame)
frame.Text:SetWordWrap(false)
frame.scale = CreateAnimationGroup(frame)
frame.scale.width = frame.scale:CreateAnimation("Width")
frame.scale.width:SetDuration(0.2)
frame.scale.height = frame.scale:CreateAnimation("Height")
frame.scale.height:SetDuration(0.2)
frame:Hide()
return frame
end
@@ -0,0 +1,34 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
local LSM = E.Libs.LSM
--Lua functions
--WoW API / Variables
function NP:Update_Highlight(frame)
if not NP.db.highlight then return end
if frame.isMouseover and ((frame.IconOnlyChanged or frame.NameOnlyChanged) or (not self.db.units[frame.UnitType].health.enable and self.db.units[frame.UnitType].name.enable)) and not frame.isTarget then
frame.Name.NameOnlyGlow:Show()
frame.Health.Highlight:Show()
elseif frame.isMouseover and (not frame.NameOnlyChanged or self.db.units[frame.UnitType].health.enable) and not frame.isTarget then
frame.Health.Highlight:Show()
else
frame.Name.NameOnlyGlow:Hide()
frame.Health.Highlight:Hide()
end
end
function NP:Configure_Highlight(frame)
frame.Health.Highlight:ClearAllPoints()
frame.Health.Highlight:SetPoint("TOPLEFT", frame.Health, "TOPLEFT")
frame.Health.Highlight:SetPoint("BOTTOMRIGHT", frame.Health:GetStatusBarTexture(), "BOTTOMRIGHT")
frame.Health.Highlight:SetTexture(LSM:Fetch("statusbar", self.db.statusbar))
end
function NP:Construct_Highlight(frame)
local highlight = frame.Health:CreateTexture("$parentHighlight", "OVERLAY")
highlight:SetVertexColor(1, 1, 1, 0.3)
highlight:Hide()
return highlight
end
@@ -0,0 +1,82 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
--Lua functions
--WoW API / Variables
function NP:Update_IconFrame(frame, triggered)
local db = self.db.units[frame.UnitType].iconFrame
if not db then return end
if (db and db.enable) or (frame.IconOnlyChanged or frame.IconChanged) then
local totem, unit, icon = self.Totems[frame.UnitName], self.UniqueUnits[frame.UnitName]
if totem then
icon = NP.TriggerConditions.totems[totem][3]
elseif unit then
icon = NP.TriggerConditions.uniqueUnits[unit][3]
end
if icon then
frame.IconFrame.texture:SetTexture(icon)
frame.IconFrame:Show()
self:StyleFrameColor(frame.IconFrame, frame.oldHealthBar:GetStatusBarColor())
if triggered then
frame.IconFrame:ClearAllPoints()
frame.IconFrame:SetPoint("TOP", frame)
end
else
frame.IconFrame:Hide()
end
else
frame.IconFrame:Hide()
end
end
function NP:Configure_IconOnlyGlow(frame)
local glowStyle = self.db.units.TARGET.glowStyle
frame.Shadow:Hide()
frame.Spark:Hide()
frame.TopIndicator:ClearAllPoints()
frame.LeftIndicator:ClearAllPoints()
frame.RightIndicator:ClearAllPoints()
if glowStyle == "style3" or glowStyle == "style5" or glowStyle == "style6" then
frame.TopIndicator:SetPoint("BOTTOM", frame.IconFrame, "TOP", -1, 6)
elseif glowStyle == "style4" or glowStyle == "style7" or glowStyle == "style8" then
frame.LeftIndicator:SetPoint("LEFT", frame.IconFrame, "RIGHT", -3, 0)
frame.RightIndicator:SetPoint("RIGHT", frame.IconFrame, "LEFT", 3, 0)
end
end
function NP:Configure_IconFrame(frame)
local db = self.db.units[frame.UnitType].iconFrame
if db then
if db.enable or frame.IconChanged then
frame.IconFrame:SetSize(db.size, db.size)
frame.IconFrame:ClearAllPoints()
frame.IconFrame:SetPoint(E.InversePoints[db.position], db.parent == "Nameplate" and frame or frame[db.parent], db.position, db.xOffset, db.yOffset)
else
frame.IconFrame:Hide()
end
end
end
function NP:Construct_IconFrame(frame)
local iconFrame = CreateFrame("Frame", nil, frame)
iconFrame:Hide()
iconFrame:SetSize(24, 24)
iconFrame:SetPoint("CENTER")
NP:StyleFrame(iconFrame, true)
iconFrame.texture = iconFrame:CreateTexture()
iconFrame.texture:SetAllPoints()
iconFrame.texture:SetTexCoord(unpack(E.TexCoords))
return iconFrame
end
@@ -0,0 +1,39 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
local LSM = E.Libs.LSM
--Lua functions
--WoW API / Variables
function NP:Update_Level(frame)
if not self.db.units[frame.UnitType].level.enable then return end
local levelText, r, g, b = self:UnitLevel(frame)
local level = frame.Level
level:ClearAllPoints()
if self.db.units[frame.UnitType].health.enable or (frame.isTarget and self.db.alwaysShowTargetHealth) then
level:SetJustifyH("RIGHT")
level:SetPoint("BOTTOMRIGHT", frame.Health, "TOPRIGHT", 0, E.Border*2)
else
level:SetPoint("LEFT", frame.Name, "RIGHT")
level:SetJustifyH("LEFT")
end
if self.db.units[frame.UnitType].health.enable or frame.isTarget then
level:SetText(levelText)
else
level:SetFormattedText(" [%s]", levelText)
end
level:SetTextColor(r, g, b)
end
function NP:Configure_Level(frame)
local db = self.db.units[frame.UnitType].level
frame.Level:FontTemplate(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline)
end
function NP:Construct_Level(frame)
return frame:CreateFontString(nil, "OVERLAY")
end
+124
View File
@@ -0,0 +1,124 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
local LSM = E.Libs.LSM
--Lua functions
local format = string.format
local gmatch = gmatch
local gsub = gsub
local match = string.match
local utf8lower = string.utf8lower
local utf8sub = string.utf8sub
--WoW API / Variables
local UNKNOWN = UNKNOWN
local function abbrev(name)
local letters, lastWord = "", match(name, ".+%s(.+)$")
if lastWord then
for word in gmatch(name, ".-%s") do
local firstLetter = utf8sub(gsub(word, "^[%s%p]*", ""), 1, 1)
if firstLetter ~= utf8lower(firstLetter) then
letters = format("%s%s. ", letters, firstLetter)
end
end
name = format("%s%s", letters, lastWord)
end
return name
end
function NP:Update_Name(frame, triggered)
if not triggered then
if not self.db.units[frame.UnitType].name.enable then return end
end
local name = frame.Name
local nameText = frame.UnitName or UNKNOWN
name:SetText(self.db.units[frame.UnitType].name.abbrev and abbrev(nameText) or nameText)
if not triggered then
name:ClearAllPoints()
if self.db.units[frame.UnitType].health.enable or (self.db.alwaysShowTargetHealth and frame.isTarget) then
name:SetJustifyH("LEFT")
name:SetPoint("BOTTOMLEFT", frame.Health, "TOPLEFT", 0, E.Border*2)
name:SetPoint("BOTTOMRIGHT", frame.Level, "BOTTOMLEFT")
else
name:SetJustifyH("CENTER")
name:SetPoint("TOP", frame)
end
end
local r, g, b = 1, 1, 1
local class = frame.UnitClass
local classColor, useClassColor
if class then
classColor = E.media.herocolor
useClassColor = self.db.units[frame.UnitType].name and self.db.units[frame.UnitType].name.useClassColor
end
if useClassColor and (frame.UnitType == "FRIENDLY_PLAYER" or frame.UnitType == "ENEMY_PLAYER") then
r, g, b = classColor.r, classColor.g, classColor.b
elseif triggered or (not self.db.units[frame.UnitType].health.enable and not frame.isTarget) then
local reactionType = frame.UnitReaction
if reactionType then
local db = self.db.colors
if reactionType == 4 then
r, g, b = db.reactions.neutral.r, db.reactions.neutral.g, db.reactions.neutral.b
elseif reactionType > 4 then
if frame.UnitType == "FRIENDLY_PLAYER" then
r, g, b = db.reactions.friendlyPlayer.r, db.reactions.friendlyPlayer.g, db.reactions.friendlyPlayer.b
else
r, g, b = db.reactions.good.r, db.reactions.good.g, db.reactions.good.b
end
else
r, g, b = db.reactions.bad.r, db.reactions.bad.g, db.reactions.bad.b
end
end
end
-- if for some reason the values failed just default to white
if not (r and g and b) then
r, g, b = 1, 1, 1
end
if triggered or (r ~= frame.Name.r or g ~= frame.Name.g or b ~= frame.Name.b) then
name:SetTextColor(r, g, b)
if not triggered then
frame.Name.r, frame.Name.g, frame.Name.b = r, g, b
end
end
if self.db.nameColoredGlow then
name.NameOnlyGlow:SetVertexColor(r - 0.1, g - 0.1, b - 0.1, 1)
else
name.NameOnlyGlow:SetVertexColor(self.db.colors.glowColor.r, self.db.colors.glowColor.g, self.db.colors.glowColor.b, self.db.colors.glowColor.a)
end
end
function NP:Configure_Name(frame)
local db = self.db.units[frame.UnitType].name
frame.Name:FontTemplate(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline)
end
function NP:Configure_NameOnlyGlow(frame)
local name = frame.Name
name.NameOnlyGlow:ClearAllPoints()
name.NameOnlyGlow:SetPoint("TOPLEFT", frame.IconOnlyChanged and frame.IconFrame or name, -20, 8)
name.NameOnlyGlow:SetPoint("BOTTOMRIGHT", frame.IconOnlyChanged and frame.IconFrame or name, 20, -8)
end
function NP:Construct_Name(frame)
local name = frame:CreateFontString(nil, "OVERLAY")
name:SetJustifyV("BOTTOM")
name:SetWordWrap(false)
local g = frame:CreateTexture(nil, "BACKGROUND")
g:SetTexture(E.Media.Textures.Spark)
g:Hide()
g:SetPoint("TOPLEFT", name, -20, 8)
g:SetPoint("BOTTOMRIGHT", name, 20, -8)
name.NameOnlyGlow = g
return name
end
@@ -0,0 +1,19 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local NP = E:GetModule("NamePlates")
--Lua functions
--WoW API / Variables
function NP:Update_RaidIcon(frame)
local db = self.db.units[frame.UnitType].raidTargetIndicator
local icon = frame.RaidIcon
icon:SetSize(db.size, db.size)
icon:ClearAllPoints()
if frame.Health:IsShown() then
icon:SetPoint(E.InversePoints[db.position], frame.Health, db.position, db.xOffset, db.yOffset)
else
icon:SetPoint("BOTTOM", frame, "TOP", 0, 15)
end
end
@@ -0,0 +1,17 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="Nameplates.lua"/>
<Script file="StyleFilter.lua"/>
<Script file="Elements\Auras.lua"/>
<Script file="Elements\CastBar.lua"/>
<Script file="Elements\ComboPoints.lua"/>
<Script file="Elements\Glow.lua"/>
<Script file="Elements\HealthBar.lua"/>
<Script file="Elements\CutawayHealth.lua"/>
<Script file="Elements\Level.lua"/>
<Script file="Elements\Name.lua"/>
<Script file="Elements\RaidIcon.lua"/>
<Script file="Elements\HealerIcon.lua"/>
<Script file="Elements\Elite.lua"/>
<Script file="Elements\Highlight.lua"/>
<Script file="Elements\IconFrame.lua"/>
</Ui>
File diff suppressed because it is too large Load Diff
+883
View File
@@ -0,0 +1,883 @@
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local mod = E:GetModule("NamePlates")
local LSM = E.Libs.LSM
--Lua functions
local ipairs, next, pairs, rawget, rawset, select, setmetatable, tonumber, type, unpack, tostring = ipairs, next, pairs, rawget, rawset, select, setmetatable, tonumber, type, unpack, tostring
local tinsert, sort, twipe = table.insert, table.sort, table.wipe
local match = string.match
--WoW API / Variables
local GetInstanceInfo = GetInstanceInfo
local GetSpellCooldown = GetSpellCooldown
local GetSpellInfo = GetSpellInfo
local GetTime = GetTime
local UnitAffectingCombat = UnitAffectingCombat
local UnitHealth = UnitHealth
local UnitHealthMax = UnitHealthMax
local UnitPower = UnitPower
local UnitPowerMax = UnitPowerMax
mod.TriggerConditions = {
raidTargets = {
STAR = "star",
CIRCLE = "circle",
DIAMOND = "diamond",
TRIANGLE = "triangle",
MOON = "moon",
SQUARE = "square",
CROSS = "cross",
SKULL = "skull",
},
frameTypes = {
["FRIENDLY_PLAYER"] = "friendlyPlayer",
["FRIENDLY_NPC"] = "friendlyNPC",
["ENEMY_PLAYER"] = "enemyPlayer",
["ENEMY_NPC"] = "enemyNPC",
},
roles = {
["TANK"] = "tank",
["HEALER"] = "healer",
["DAMAGER"] = "damager"
},
difficulties = {
-- dungeons
[1] = "normal",
[2] = "heroic",
-- raids
[14] = "normal",
[15] = "heroic",
},
totems = {},
uniqueUnits = {}
}
local totemTypes = {
air = { -- Air Totems
[8177] = "a1", -- Grounding Totem
[10595] = "a2", -- Nature Resistance Totem I
[10600] = "a2", -- Nature Resistance Totem II
[10601] = "a2", -- Nature Resistance Totem III
[25574] = "a2", -- Nature Resistance Totem IV
[58746] = "a2", -- Nature Resistance Totem V
[58749] = "a2", -- Nature Resistance Totem VI
[6495] = "a3", -- Sentry Totem
[8512] = "a4", -- Windfury Totem
[3738] = "a5", -- Wrath of Air Totem
},
earth = { -- Earth Totems
[2062] = "e1", -- Earth Elemental Totem
[2484] = "e2", -- Earthbind Totem
[5730] = "e3", -- Stoneclaw Totem I
[6390] = "e3", -- Stoneclaw Totem II
[6391] = "e3", -- Stoneclaw Totem III
[6392] = "e3", -- Stoneclaw Totem IV
[10427] = "e3", -- Stoneclaw Totem V
[10428] = "e3", -- Stoneclaw Totem VI
[25525] = "e3", -- Stoneclaw Totem VII
[58580] = "e3", -- Stoneclaw Totem VIII
[58581] = "e3", -- Stoneclaw Totem IX
[58582] = "e3", -- Stoneclaw Totem X
[8071] = "e4", -- Stoneskin Totem I -- Faction Champs
[8154] = "e4", -- Stoneskin Totem II
[8155] = "e4", -- Stoneskin Totem III
[10406] = "e4", -- Stoneskin Totem IV
[10407] = "e4", -- Stoneskin Totem V
[10408] = "e4", -- Stoneskin Totem VI
[25508] = "e4", -- Stoneskin Totem VII
[25509] = "e4", -- Stoneskin Totem VIII
[58751] = "e4", -- Stoneskin Totem IX
[58753] = "e4", -- Stoneskin Totem X
[8075] = "e5", -- Strength of Earth Totem I -- Faction Champs
[8160] = "e5", -- Strength of Earth Totem II
[8161] = "e5", -- Strength of Earth Totem III
[10442] = "e5", -- Strength of Earth Totem IV
[25361] = "e5", -- Strength of Earth Totem V
[25528] = "e5", -- Strength of Earth Totem VI
[57622] = "e5", -- Strength of Earth Totem VII
[58643] = "e5", -- Strength of Earth Totem VIII
[8143] = "e6", -- Tremor Totem
},
fire = { -- Fire Totems
[2894] = "f1", -- Fire Elemental Totem
[8227] = "f2", -- Flametongue Totem I -- Faction Champs
[8249] = "f2", -- Flametongue Totem II
[10526] = "f2", -- Flametongue Totem III
[16387] = "f2", -- Flametongue Totem IV
[25557] = "f2", -- Flametongue Totem V
[58649] = "f2", -- Flametongue Totem VI
[58652] = "f2", -- Flametongue Totem VII
[58656] = "f2", -- Flametongue Totem VIII
[8181] = "f3", -- Frost Resistance Totem I
[10478] = "f3", -- Frost Resistance Totem II
[10479] = "f3", -- Frost Resistance Totem III
[25560] = "f3", -- Frost Resistance Totem IV
[58741] = "f3", -- Frost Resistance Totem V
[58745] = "f3", -- Frost Resistance Totem VI
[8190] = "f4", -- Magma Totem I
[10585] = "f4", -- Magma Totem II
[10586] = "f4", -- Magma Totem III
[10587] = "f4", -- Magma Totem IV
[25552] = "f4", -- Magma Totem V
[58731] = "f4", -- Magma Totem VI
[58734] = "f4", -- Magma Totem VII
[3599] = "f5", -- Searing Totem I -- Faction Champs
[6363] = "f5", -- Searing Totem II
[6364] = "f5", -- Searing Totem III
[6365] = "f5", -- Searing Totem IV
[10437] = "f5", -- Searing Totem V
[10438] = "f5", -- Searing Totem VI
[25533] = "f5", -- Searing Totem VII
[58699] = "f5", -- Searing Totem VIII
[58703] = "f5", -- Searing Totem IX
[58704] = "f5", -- Searing Totem X
[30706] = "f6", -- Totem of Wrath I
[57720] = "f6", -- Totem of Wrath II
[57721] = "f6", -- Totem of Wrath III
[57722] = "f6", -- Totem of Wrath IV
},
water = { -- Water Totems
[8170] = "w1", -- Cleansing Totem
[8184] = "w2", -- Fire Resistance Totem I
[10537] = "w2", -- Fire Resistance Totem II
[10538] = "w2", -- Fire Resistance Totem III
[25563] = "w2", -- Fire Resistance Totem IV
[58737] = "w2", -- Fire Resistance Totem V
[58739] = "w2", -- Fire Resistance Totem VI
[5394] = "w3", -- Healing Stream Totem I -- Faction Champs
[6375] = "w3", -- Healing Stream Totem II
[6377] = "w3", -- Healing Stream Totem III
[10462] = "w3", -- Healing Stream Totem IV
[10463] = "w3", -- Healing Stream Totem V
[25567] = "w3", -- Healing Stream Totem VI
[58755] = "w3", -- Healing Stream Totem VII
[58756] = "w3", -- Healing Stream Totem VIII
[58757] = "w3", -- Healing Stream Totem IX
[5675] = "w4", -- Mana Spring Totem I
[10495] = "w4", -- Mana Spring Totem II
[10496] = "w4", -- Mana Spring Totem III
[10497] = "w4", -- Mana Spring Totem IV
[25570] = "w4", -- Mana Spring Totem V
[58771] = "w4", -- Mana Spring Totem VI
[58773] = "w4", -- Mana Spring Totem VII
[58774] = "w4", -- Mana Spring Totem VIII
[16190] = "w5" -- Mana Tide Totem
},
other = {
[724] = "o1" -- Lightwell
}
}
local totemRanks = {
"",
" II",
" III",
" IV",
" V",
" VI",
" VII",
" VIII",
" IX",
" X"
}
local uniqueUnitTypes = {
pvp = {
[34433] = "u1", -- Shadow Fiend
},
pve = {
[72052] = "u2", -- Kinetic Bomb
}
}
G.nameplates.uniqueUnitTypes = uniqueUnitTypes
for unitType, units in pairs(uniqueUnitTypes) do
for spellID, unit in pairs(units) do
local name, _, texture = GetSpellInfo(spellID)
mod.TriggerConditions.uniqueUnits[unit] = {name, unitType, texture}
mod.UniqueUnits[name] = unit
end
end
for totemSchool, totems in pairs(totemTypes) do
for spellID, totemID in pairs(totems) do
local totemName, rank, texture = GetSpellInfo(spellID)
if not mod.TriggerConditions.totems[totemID] then
mod.TriggerConditions.totems[totemID] = {totemName, totemSchool, texture}
end
rank = totemRanks[tonumber(match(rank, ("%d+")))]
if rank then
totemName = totemName..rank
else
totemName = totemName
end
mod.Totems[totemName] = totemID
end
end
G.nameplates.totemTypes = totemTypes
function mod:StyleFilterAuraCheck(names, icons, mustHaveAll, missing, minTimeLeft, maxTimeLeft)
local total, count = 0, 0
for name, value in pairs(names) do
if value == true then --only if they are turned on
total = total + 1 --keep track of the names
end
for _, icon in ipairs(icons) do
if icon:IsShown() and (value == true) and ((icon.name and icon.name == name) or (icon.spellID and icon.spellID == tonumber(name)))
and (not minTimeLeft or (minTimeLeft == 0 or (icon.expirationTime and (icon.expirationTime - GetTime()) > minTimeLeft))) and (not maxTimeLeft or (maxTimeLeft == 0 or (icon.expirationTime and (icon.expirationTime - GetTime()) < maxTimeLeft))) then
count = count + 1 --keep track of how many matches we have
end
end
end
if total == 0 then
return nil --If no auras are checked just pass nil, we dont need to run the filter here.
else
return ((mustHaveAll and not missing) and total == count) -- [x] Check for all [ ] Missing: total needs to match count
or ((not mustHaveAll and not missing) and count > 0) -- [ ] Check for all [ ] Missing: count needs to be greater than zero
or ((not mustHaveAll and missing) and count == 0) -- [ ] Check for all [x] Missing: count needs to be zero
or ((mustHaveAll and missing) and total ~= count) -- [x] Check for all [x] Missing: count must not match total
end
end
function mod:StyleFilterCooldownCheck(names, mustHaveAll)
local total, count = 0, 0
local _, gcd = GetSpellCooldown(61304)
for name, value in pairs(names) do
if value == "ONCD" or value == "OFFCD" then --only if they are turned on
total = total + 1 --keep track of the names
local _, duration = GetSpellCooldown(name)
if (duration > gcd and value == "ONCD")
or (duration <= gcd and value == "OFFCD") then
count = count + 1
--print(((duration > gcd and value == "ONCD") and name.."passes because it is on cd.") or ((duration <= gcd and value == "OFFCD") and name.." passes because it is off cd."))
end
end
end
if total == 0 then
return nil
else
return (mustHaveAll and total == count) or (not mustHaveAll and count > 0)
end
end
function mod:StyleFilterSetChanges(frame, actions, HealthColorChanged, BorderChanged, FlashingHealth, TextureChanged, ScaleChanged, FrameLevelChanged, AlphaChanged, NameColorChanged, NameOnlyChanged, VisibilityChanged, IconChanged, IconOnlyChanged)
if VisibilityChanged then
frame.StyleChanged = true
frame.VisibilityChanged = true
frame:Hide()
return --We hide it. Lets not do other things (no point)
end
if FrameLevelChanged then
frame.StyleChanged = true
frame.FrameLevelChanged = actions.frameLevel -- we pass this to `ResetNameplateFrameLevel`
end
if HealthColorChanged then
frame.StyleChanged = true
frame.HealthColorChanged = true
frame.Health:SetStatusBarColor(actions.color.healthColor.r, actions.color.healthColor.g, actions.color.healthColor.b, actions.color.healthColor.a)
frame.CutawayHealth:SetStatusBarColor(actions.color.healthColor.r * 1.5, actions.color.healthColor.g * 1.5, actions.color.healthColor.b * 1.5, actions.color.healthColor.a)
end
if BorderChanged then --Lets lock this to the values we want (needed for when the media border color changes)
frame.StyleChanged = true
frame.BorderChanged = true
frame.Health.bordertop:SetTexture(actions.color.borderColor.r, actions.color.borderColor.g, actions.color.borderColor.b, actions.color.borderColor.a)
frame.Health.borderbottom:SetTexture(actions.color.borderColor.r, actions.color.borderColor.g, actions.color.borderColor.b, actions.color.borderColor.a)
frame.Health.borderleft:SetTexture(actions.color.borderColor.r, actions.color.borderColor.g, actions.color.borderColor.b, actions.color.borderColor.a)
frame.Health.borderright:SetTexture(actions.color.borderColor.r, actions.color.borderColor.g, actions.color.borderColor.b, actions.color.borderColor.a)
end
if FlashingHealth then
frame.StyleChanged = true
frame.FlashingHealth = true
if not TextureChanged then
frame.FlashTexture:SetTexture(LSM:Fetch("statusbar", mod.db.statusbar))
end
frame.FlashTexture:SetVertexColor(actions.flash.color.r, actions.flash.color.g, actions.flash.color.b)
frame.FlashTexture:SetAlpha(actions.flash.color.a)
frame.FlashTexture:Show()
E:Flash(frame.FlashTexture, actions.flash.speed * 0.1, true)
end
if TextureChanged then
frame.StyleChanged = true
frame.TextureChanged = true
local tex = LSM:Fetch("statusbar", actions.texture.texture)
frame.Health.Highlight:SetTexture(tex)
frame.Health:SetStatusBarTexture(tex)
if FlashingHealth then
frame.FlashTexture:SetTexture(tex)
end
end
if ScaleChanged then
frame.StyleChanged = true
frame.ScaleChanged = true
local scale = (frame.ThreatScale or 1)
frame.ActionScale = actions.scale
if frame.isTarget and mod.db.useTargetScale then
scale = scale * mod.db.targetScale
end
mod:SetFrameScale(frame, scale * actions.scale)
end
if AlphaChanged then
frame.StyleChanged = true
frame.AlphaChanged = true
mod:PlateFade(frame, mod.db.fadeIn and 1 or 0, frame:GetAlpha(), actions.alpha / 100)
end
if NameColorChanged then
frame.StyleChanged = true
frame.NameColorChanged = true
local nameText = frame.oldName:GetText()
if nameText and nameText ~= "" then
frame.Name:SetTextColor(actions.color.nameColor.r, actions.color.nameColor.g, actions.color.nameColor.b, actions.color.nameColor.a)
if mod.db.nameColoredGlow then
frame.Name.NameOnlyGlow:SetVertexColor(actions.color.nameColor.r - 0.1, actions.color.nameColor.g - 0.1, actions.color.nameColor.b - 0.1, 1)
end
end
end
if NameOnlyChanged then
frame.StyleChanged = true
frame.NameOnlyChanged = true
--hide the bars
if frame.CastBar:IsShown() then frame.CastBar:Hide() end
if frame.Health:IsShown() then frame.Health:Hide() end
--hide the target indicator
mod:Configure_Glow(frame)
mod:Update_Glow(frame)
--position the name and update its color
frame.Name:ClearAllPoints()
frame.Name:SetJustifyH("CENTER")
frame.Name:SetPoint("TOP", frame)
frame.Level:ClearAllPoints()
frame.Level:SetPoint("LEFT", frame.Name, "RIGHT")
frame.Level:SetJustifyH("LEFT")
if not NameColorChanged then
mod:Update_Name(frame, true)
end
end
if IconChanged then
frame.StyleChanged = true
frame.IconChanged = true
mod:Configure_IconFrame(frame)
mod:Update_IconFrame(frame)
end
if IconOnlyChanged then
frame.StyleChanged = true
frame.IconOnlyChanged = true
mod:Update_IconFrame(frame, true)
if frame.Health:IsShown() then frame.Health:Hide() end
frame.Level:Hide()
frame.Name:Hide()
mod:Configure_Glow(frame)
mod:Update_Glow(frame)
mod:Update_RaidIcon(frame)
mod:Configure_IconOnlyGlow(frame)
mod:Configure_NameOnlyGlow(frame)
end
end
function mod:StyleFilterClearChanges(frame, HealthColorChanged, BorderChanged, FlashingHealth, TextureChanged, ScaleChanged, FrameLevelChanged, AlphaChanged, NameColorChanged, NameOnlyChanged, VisibilityChanged, IconChanged, IconOnlyChanged)
frame.StyleChanged = nil
if VisibilityChanged then
frame.VisibilityChanged = nil
mod:PlateFade(frame, mod.db.fadeIn and 1 or 0, 0, 1) -- fade those back in so it looks clean
frame:Show()
end
if FrameLevelChanged then
frame.FrameLevelChanged = nil
end
if HealthColorChanged then
frame.HealthColorChanged = nil
frame.Health:SetStatusBarColor(frame.Health.r, frame.Health.g, frame.Health.b)
frame.CutawayHealth:SetStatusBarColor(frame.Health.r * 1.5, frame.Health.g * 1.5, frame.Health.b * 1.5, 1)
end
if BorderChanged then
frame.BorderChanged = nil
local r, g, b = unpack(E.media.bordercolor)
frame.Health.bordertop:SetTexture(r, g, b)
frame.Health.borderbottom:SetTexture(r, g, b)
frame.Health.borderleft:SetTexture(r, g, b)
frame.Health.borderright:SetTexture(r, g, b)
end
if FlashingHealth then
frame.FlashingHealth = nil
E:StopFlash(frame.FlashTexture)
frame.FlashTexture:Hide()
end
if TextureChanged then
frame.TextureChanged = nil
local tex = LSM:Fetch("statusbar", mod.db.statusbar)
frame.Health.Highlight:SetTexture(tex)
frame.Health:SetStatusBarTexture(tex)
end
if ScaleChanged then
frame.ScaleChanged = nil
frame.ActionScale = nil
local scale = frame.ThreatScale or 1
if frame.isTarget and mod.db.useTargetScale then
scale = scale * mod.db.targetScale
end
mod:SetFrameScale(frame, scale)
end
if AlphaChanged then
frame.AlphaChanged = nil
mod:PlateFade(frame, mod.db.fadeIn and 1 or 0, (frame.FadeObject and frame.FadeObject.endAlpha) or 0.5, 1)
end
if NameColorChanged then
frame.NameColorChanged = nil
frame.Name:SetTextColor(frame.Name.r, frame.Name.g, frame.Name.b)
end
if NameOnlyChanged then
frame.NameOnlyChanged = nil
frame.TopLevelFrame = nil --We can safely clear this here because it is set upon `UpdateElement_Auras` if needed
if mod.db.units[frame.UnitType].health.enable or (frame.isTarget and mod.db.alwaysShowTargetHealth) then
frame.Health:Show()
mod:Configure_Glow(frame)
mod:Update_Glow(frame)
end
if mod.db.units[frame.UnitType].name.enable then
frame.Level:Show()
frame.Name:ClearAllPoints()
frame.Level:ClearAllPoints()
mod:Update_Level(frame)
mod:Update_Name(frame)
else
frame.Name:SetText()
end
end
if IconChanged then
frame.IconChanged = nil
frame.IconFrame:Hide()
end
if IconOnlyChanged then
frame.IconOnlyChanged = nil
mod:Update_IconFrame(frame)
if mod.db.units[frame.UnitType].iconFrame and mod.db.units[frame.UnitType].iconFrame.enable then
mod:Configure_IconFrame(frame)
end
if mod.db.units[frame.UnitType].health.enable or (frame.isTarget and mod.db.alwaysShowTargetHealth) then
frame.Health:Show()
mod:Configure_Glow(frame)
mod:Update_Glow(frame)
end
if mod.db.units[frame.UnitType].name.enable then
frame.Name:Show()
frame.Level:Show()
frame.Name:ClearAllPoints()
frame.Level:ClearAllPoints()
mod:Update_Level(frame)
mod:Update_Name(frame)
else
frame.Name:SetText()
end
mod:Update_RaidIcon(frame)
mod:Configure_IconOnlyGlow(frame)
mod:Configure_NameOnlyGlow(frame)
end
end
function mod:StyleFilterConditionCheck(frame, filter, trigger)
local passed -- skip StyleFilterPass when triggers are empty
-- Name
if trigger.names and next(trigger.names) then
for _, value in pairs(trigger.names) do
if value then -- only run if at least one is selected
local name = trigger.names[frame.UnitName]
if (not trigger.negativeMatch and name) or (trigger.negativeMatch and not name) then passed = true else return end
break -- we can execute this once on the first enabled option then kill the loop
end
end
end
-- Health
if trigger.healthThreshold then
local health = (trigger.healthUsePlayer and UnitHealth("player")) or frame.oldHealthBar:GetValue() or 0
local maxHealth = (trigger.healthUsePlayer and UnitHealthMax("player")) or select(2, frame.oldHealthBar:GetMinMaxValues()) or 0
local percHealth = (maxHealth and (maxHealth > 0) and health/maxHealth) or 0
local underHealthThreshold = trigger.underHealthThreshold and (trigger.underHealthThreshold ~= 0) and (trigger.underHealthThreshold > percHealth)
local overHealthThreshold = trigger.overHealthThreshold and (trigger.overHealthThreshold ~= 0) and (trigger.overHealthThreshold < percHealth)
if underHealthThreshold or overHealthThreshold then passed = true else return end
end
-- Power
if trigger.powerThreshold then
local power, maxPower = UnitPower("player"), UnitPowerMax("player")
local percPower = (maxPower and (maxPower > 0) and power/maxPower) or 0
local underPowerThreshold = trigger.underPowerThreshold and (trigger.underPowerThreshold ~= 0) and (trigger.underPowerThreshold > percPower)
local overPowerThreshold = trigger.overPowerThreshold and (trigger.overPowerThreshold ~= 0) and (trigger.overPowerThreshold < percPower)
if underPowerThreshold or overPowerThreshold then passed = true else return end
end
-- Require Target
if trigger.requireTarget then
if UnitExists("target") then passed = true else return end
end
-- Player Combat
if trigger.inCombat or trigger.outOfCombat then
local inCombat = UnitAffectingCombat("player")
if (trigger.inCombat and inCombat) or (trigger.outOfCombat and not inCombat) then passed = true else return end
end
-- Player Target
if trigger.isTarget or trigger.notTarget then
if (trigger.isTarget and frame.isTarget) or (trigger.notTarget and not frame.isTarget) then passed = true else return end
end
-- Group Role
if trigger.role.tank or trigger.role.healer or trigger.role.damager then
if trigger.role[mod.TriggerConditions.roles[E:GetPlayerRole()]] then passed = true else return end
end
-- Instance Type
if trigger.instanceType.none or trigger.instanceType.party or trigger.instanceType.raid or trigger.instanceType.arena or trigger.instanceType.pvp then
local _, instanceType, difficultyID = GetInstanceInfo()
if trigger.instanceType[instanceType] then
passed = true
-- Instance Difficulty
if instanceType == "raid" or instanceType == "party" then
local D = trigger.instanceDifficulty[(instanceType == "party" and "dungeon") or instanceType]
for _, value in pairs(D) do
if value and not D[mod.TriggerConditions.difficulties[difficultyID]] then return end
end
end
else return end
elseif trigger.instanceType.sanctuary then
if UnitIsPVPSanctuary("player") then passed = true else return end
end
-- Level
if trigger.level then
local myLevel = E.mylevel
local level = mod:UnitLevel(frame)
level = level == "??" and -1 or tonumber(level)
local curLevel = (trigger.curlevel and trigger.curlevel ~= 0 and (trigger.curlevel == level))
local minLevel = (trigger.minlevel and trigger.minlevel ~= 0 and (trigger.minlevel <= level))
local maxLevel = (trigger.maxlevel and trigger.maxlevel ~= 0 and (trigger.maxlevel >= level))
local matchMyLevel = trigger.mylevel and (level == myLevel)
if curLevel or minLevel or maxLevel or matchMyLevel then passed = true else return end
end
-- Unit Type
if trigger.nameplateType and trigger.nameplateType.enable then
if trigger.nameplateType[mod.TriggerConditions.frameTypes[frame.UnitType]] then passed = true else return end
end
-- Reaction Type
if trigger.reactionType and trigger.reactionType.enable then
local reaction = frame.UnitReaction
if ((reaction == 1 or reaction == 2 or reaction == 3) and trigger.reactionType.hostile) or (reaction == 4 and trigger.reactionType.neutral) or (reaction == 5 and trigger.reactionType.friendly) then passed = true else return end
end
-- Raid Target
if trigger.raidTarget.star or trigger.raidTarget.circle or trigger.raidTarget.diamond or trigger.raidTarget.triangle or trigger.raidTarget.moon or trigger.raidTarget.square or trigger.raidTarget.cross or trigger.raidTarget.skull then
if trigger.raidTarget[mod.TriggerConditions.raidTargets[frame.RaidIconType]] then passed = true else return end
end
-- Casting
if trigger.casting then
local b, c = frame.CastBar, trigger.casting
-- Spell
if b.spellName then
if c.spells and next(c.spells) then
for _, value in pairs(c.spells) do
if value then -- only run if at least one is selected
local _, _, _, _, _, _, spellID = GetSpellInfo(b.spellName)
local castingSpell = (spellID and c.spells[tostring(spellID)]) or c.spells[b.spellName]
if (c.notSpell and not castingSpell) or (castingSpell and not c.notSpell) then passed = true else return end
break -- we can execute this once on the first enabled option then kill the loop
end
end
end
end
-- Status
if c.isCasting or c.isChanneling or c.notCasting or c.notChanneling then
if (c.isCasting and b.casting) or (c.isChanneling and b.channeling)
or (c.notCasting and not b.casting) or (c.notChanneling and not b.channeling) then passed = true else return end
end
-- Interruptible
if c.interruptible or c.notInterruptible then
if (b.casting or b.channeling) and ((c.interruptible and not b.notInterruptible)
or (c.notInterruptible and b.notInterruptible)) then passed = true else return end
end
end
-- Cooldown
if trigger.cooldowns and trigger.cooldowns.names and next(trigger.cooldowns.names) then
local cooldown = mod:StyleFilterCooldownCheck(trigger.cooldowns.names, trigger.cooldowns.mustHaveAll)
if cooldown ~= nil then -- ignore if none are set to ONCD or OFFCD
if cooldown then passed = true else return end
end
end
-- Buffs
if frame.Buffs and trigger.buffs and trigger.buffs.names and next(trigger.buffs.names) then
local buff = mod:StyleFilterAuraCheck(trigger.buffs.names, frame.Buffs, trigger.buffs.mustHaveAll, trigger.buffs.missing, trigger.buffs.minTimeLeft, trigger.buffs.maxTimeLeft)
if buff ~= nil then -- ignore if none are selected
if buff then passed = true else return end
end
end
-- Debuffs
if frame.Debuffs and trigger.debuffs and trigger.debuffs.names and next(trigger.debuffs.names) then
local debuff = mod:StyleFilterAuraCheck(trigger.debuffs.names, frame.Debuffs, trigger.debuffs.mustHaveAll, trigger.debuffs.missing, trigger.debuffs.minTimeLeft, trigger.debuffs.maxTimeLeft)
if debuff ~= nil then -- ignore if none are selected
if debuff then passed = true else return end
end
end
-- Totems
if frame.UnitName and trigger.totems.enable then
local totem = mod.Totems[frame.UnitName]
if totem then if trigger.totems[totem] then passed = true else return end end
end
-- Unique Units
if frame.UnitName and trigger.uniqueUnits.enable then
local unit = mod.UniqueUnits[frame.UnitName]
if unit then if trigger.uniqueUnits[unit] then passed = true else return end end
end
-- Plugin Callback
if mod.StyleFilterCustomChecks then
for _, customCheck in pairs(mod.StyleFilterCustomChecks) do
local custom = customCheck(frame, filter, trigger)
if custom ~= nil then -- ignore if nil return
if custom then passed = true else return end
end
end
end
-- Pass it along
if passed then
mod:StyleFilterPass(frame, filter.actions)
end
end
function mod:StyleFilterPass(frame, actions)
local healthBarEnabled = (frame.UnitType and mod.db.units[frame.UnitType].health.enable) or (frame.isTarget and mod.db.alwaysShowTargetHealth)
local healthBarShown = healthBarEnabled and frame.Health:IsShown()
mod:StyleFilterSetChanges(frame, actions,
(healthBarShown and actions.color and actions.color.health), --HealthColorChanged
(healthBarShown and actions.color and actions.color.border and frame.Health.backdrop), --BorderChanged
(healthBarShown and actions.flash and actions.flash.enable and frame.FlashTexture), --FlashingHealth
(healthBarShown and actions.texture and actions.texture.enable), --TextureChanged
(healthBarShown and actions.scale and actions.scale ~= 1), --ScaleChanged
(actions.frameLevel and actions.frameLevel ~= 0), --FrameLevelChanged
(actions.alpha and actions.alpha ~= -1), --AlphaChanged
(actions.color and actions.color.name), --NameColorChanged
(actions.nameOnly), --NameOnlyChanged
(actions.hide), --VisibilityChanged
(actions.icon), --IconChanged
(actions.iconOnly) --IconOnlyChanged
)
end
function mod:StyleFilterClear(frame)
if frame and frame.StyleChanged then
mod:StyleFilterClearChanges(frame, frame.HealthColorChanged, frame.BorderChanged, frame.FlashingHealth, frame.TextureChanged, frame.ScaleChanged, frame.FrameLevelChanged, frame.AlphaChanged, frame.NameColorChanged, frame.NameOnlyChanged, frame.VisibilityChanged, frame.IconChanged, frame.IconOnlyChanged)
end
end
function mod:StyleFilterSort(place)
if self[2] and place[2] then
return self[2] > place[2] --Sort by priority: 1=first, 2=second, 3=third, etc
end
end
function mod:StyleFilterClearVariables(nameplate)
nameplate.ActionScale = nil
nameplate.ThreatScale = nil
end
mod.StyleFilterTriggerList = {}
mod.StyleFilterTriggerEvents = {}
function mod:StyleFilterConfigure()
twipe(mod.StyleFilterTriggerList)
twipe(mod.StyleFilterTriggerEvents)
for filterName, filter in pairs(E.global.nameplates.filters) do
local t = filter.triggers
if t and E.db.nameplates and E.db.nameplates.filters then
if E.db.nameplates.filters[filterName] and E.db.nameplates.filters[filterName].triggers and E.db.nameplates.filters[filterName].triggers.enable then
tinsert(mod.StyleFilterTriggerList, {filterName, t.priority or 1})
mod.StyleFilterTriggerEvents.UpdateElement_All = 1
mod.StyleFilterTriggerEvents.NAME_PLATE_UNIT_ADDED = 1
if t.casting then
if next(t.casting.spells) then
for _, value in pairs(t.casting.spells) do
if value then
mod.StyleFilterTriggerEvents.FAKE_Casting = 0
break
end end end
if (t.casting.interruptible or t.casting.notInterruptible)
or (t.casting.isCasting or t.casting.isChanneling or t.casting.notCasting or t.casting.notChanneling) then
mod.StyleFilterTriggerEvents.FAKE_Casting = 0
end
end
if t.raidTarget and (t.raidTarget.star or t.raidTarget.circle or t.raidTarget.diamond or t.raidTarget.triangle or t.raidTarget.moon or t.raidTarget.square or t.raidTarget.cross or t.raidTarget.skull) then
mod.StyleFilterTriggerEvents.RAID_TARGET_UPDATE = 1
end
-- real events
mod.StyleFilterTriggerEvents.PLAYER_TARGET_CHANGED = true
if t.healthThreshold then
mod.StyleFilterTriggerEvents.UNIT_HEALTH = 1
mod.StyleFilterTriggerEvents.UNIT_MAXHEALTH = 1
end
if t.powerThreshold then
mod.StyleFilterTriggerEvents.UNIT_MANA = 1
mod.StyleFilterTriggerEvents.UNIT_ENERGY = 1
mod.StyleFilterTriggerEvents.UNIT_FOCUS = 1
mod.StyleFilterTriggerEvents.UNIT_RAGE = 1
mod.StyleFilterTriggerEvents.UNIT_RUNIC_POWER = 1
mod.StyleFilterTriggerEvents.UNIT_DISPLAYPOWER = 1
end
if t.names and next(t.names) then
for _, value in pairs(t.names) do
if value then
mod.StyleFilterTriggerEvents.UNIT_NAME_UPDATE = 1
break
end end end
if t.inCombat or t.outOfCombat then
mod.StyleFilterTriggerEvents.PLAYER_REGEN_DISABLED = true
mod.StyleFilterTriggerEvents.PLAYER_REGEN_ENABLED = true
end
if t.cooldowns and t.cooldowns.names and next(t.cooldowns.names) then
for _, value in pairs(t.cooldowns.names) do
if value == "ONCD" or value == "OFFCD" then
mod.StyleFilterTriggerEvents.SPELL_UPDATE_COOLDOWN = 1
break
end end end
if t.buffs and t.buffs.names and next(t.buffs.names) then
for _, value in pairs(t.buffs.names) do
if value then
mod.StyleFilterTriggerEvents.UNIT_AURA = true
break
end end end
if t.debuffs and t.debuffs.names and next(t.debuffs.names) then
for _, value in pairs(t.debuffs.names) do
if value then
mod.StyleFilterTriggerEvents.UNIT_AURA = true
break
end end end
end
end
end
if next(mod.StyleFilterTriggerList) then
sort(mod.StyleFilterTriggerList, mod.StyleFilterSort) -- sort by priority
else
mod:ForEachPlate("StyleFilterClear")
end
end
function mod:StyleFilterUpdate(frame, event)
local hasEvent = mod.StyleFilterTriggerEvents[event]
if not hasEvent then
return
elseif hasEvent == true then -- skip on 1 or 0
if not frame.StyleFilterWaitTime then
frame.StyleFilterWaitTime = GetTime()
elseif GetTime() > (frame.StyleFilterWaitTime + 0.1) then
frame.StyleFilterWaitTime = nil
else
return -- block calls faster than 0.1 second
end
end
mod:StyleFilterClear(frame)
for filterNum in ipairs(mod.StyleFilterTriggerList) do
local filter = E.global.nameplates.filters[mod.StyleFilterTriggerList[filterNum][1]]
if filter then
mod:StyleFilterConditionCheck(frame, filter, filter.triggers)
end
end
end
function mod:StyleFilterAddCustomCheck(name, func)
if not mod.StyleFilterCustomChecks then
mod.StyleFilterCustomChecks = {}
end
mod.StyleFilterCustomChecks[name] = func
end
function mod:StyleFilterRemoveCustomCheck(name)
if not mod.StyleFilterCustomChecks then
return
end
mod.StyleFilterCustomChecks[name] = nil
end
-- Shamelessy taken from AceDB-3.0 and stripped down by Simpy
local function copyDefaults(dest, src)
for k, v in pairs(src) do
if type(v) == "table" then
if not rawget(dest, k) then rawset(dest, k, {}) end
if type(dest[k]) == "table" then copyDefaults(dest[k], v) end
elseif rawget(dest, k) == nil then
rawset(dest, k, v)
end
end
end
local function removeDefaults(db, defaults)
setmetatable(db, nil)
for k, v in pairs(defaults) do
if type(v) == "table" and type(db[k]) == "table" then
removeDefaults(db[k], v)
if next(db[k]) == nil then db[k] = nil end
elseif db[k] == defaults[k] then
db[k] = nil
end
end
end
function mod:StyleFilterClearDefaults()
for filterName, filterTable in pairs(E.global.nameplates.filters) do
if G.nameplates.filters[filterName] then
local defaultTable = E:CopyTable({}, E.StyleFilterDefaults)
E:CopyTable(defaultTable, G.nameplates.filters[filterName])
removeDefaults(filterTable, defaultTable)
else
removeDefaults(filterTable, E.StyleFilterDefaults)
end
end
end
function mod:StyleFilterCopyDefaults(tbl)
copyDefaults(tbl, E.StyleFilterDefaults)
end
function mod:StyleFilterInitialize()
for _, filterTable in pairs(E.global.nameplates.filters) do
mod:StyleFilterCopyDefaults(filterTable)
end
end
+491
View File
@@ -0,0 +1,491 @@
local E, _, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
local select = select
--WoW API / Variables
local hooksecurefunc = hooksecurefunc
-- functions that were overwritten, we need these to
-- finish the function call when our code executes!
local oldRegisterAsWidget, oldRegisterAsContainer
-- these do *not* need to match the current lib minor version
-- these numbers are used to not attempt skinning way older
-- versions of AceGUI and AceConfigDialog.
local minorGUI, minorConfigDialog = 1, 76
function S:Ace3_SkinDropdownPullout()
if self and self.obj then
local pullout = self.obj.pullout
local dropdown = self.obj.dropdown
if pullout and pullout.frame then
if pullout.frame.template and pullout.slider.template then return end
if not pullout.frame.template then
pullout.frame:SetTemplate("Default", true)
end
if not pullout.slider.template then
pullout.slider:SetTemplate("Default")
pullout.slider:Point("TOPRIGHT", pullout.frame, "TOPRIGHT", -10, -10)
pullout.slider:Point("BOTTOMRIGHT", pullout.frame, "BOTTOMRIGHT", -10, 10)
if pullout.slider:GetThumbTexture() then
pullout.slider:SetThumbTexture(E.Media.Textures.Melli)
pullout.slider:GetThumbTexture():SetVertexColor(1, 0.82, 0, 0.8)
pullout.slider:GetThumbTexture():Size(10, 14)
end
end
elseif dropdown then
dropdown:SetTemplate("Default", true)
if dropdown.slider then
dropdown.slider:SetTemplate("Default")
dropdown.slider:Point("TOPRIGHT", dropdown, "TOPRIGHT", -10, -10)
dropdown.slider:Point("BOTTOMRIGHT", dropdown, "BOTTOMRIGHT", -10, 10)
if dropdown.slider:GetThumbTexture() then
dropdown.slider:SetThumbTexture(E.Media.Textures.Melli)
dropdown.slider:GetThumbTexture():SetVertexColor(1, 0.82, 0, 0.8)
dropdown.slider:GetThumbTexture():Size(10, 14)
end
end
if TYPE == "LSM30_Sound" then
local frame = self.obj.frame
local width = frame:GetWidth()
dropdown:Point("TOPLEFT", frame, "BOTTOMLEFT")
dropdown:Point("TOPRIGHT", frame, "BOTTOMRIGHT", width < 160 and (160 - width) or 30, 0)
end
end
end
end
function S:Ace3_CheckBoxIsEnableSwitch(widget)
local text = widget.text and widget.text:GetText()
if text then
local enabled, disabled = text == S.Ace3_L.GREEN_ENABLE, text == S.Ace3_L.RED_ENABLE
local isSwitch = (text == S.Ace3_L.Enable) or enabled or disabled
return isSwitch
end
end
function S:Ace3_RegisterAsWidget(widget)
if not E.private.skins.ace3.enable then
return oldRegisterAsWidget(self, widget)
end
local TYPE = widget.type
if TYPE == "MultiLineEditBox" then
local frame = widget.frame
local scrollBG = widget.scrollBG or select(2, frame:GetChildren()) or frame:GetChildren()
local scrollBar = widget.scrollBar or _G[widget.scrollframe:GetName().."ScrollBar"]
if not scrollBG.template then
scrollBG:SetTemplate()
end
S:HandleButton(widget.button)
S:HandleScrollBar(scrollBar)
scrollBG:Point("TOPRIGHT", scrollBar, "TOPLEFT", -3, 19)
widget.scrollFrame:Point("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -4, 8)
elseif TYPE == "CheckBox" then
local check = widget.check
local checkbg = widget.checkbg
local highlight = widget.highlight
checkbg:CreateBackdrop()
checkbg.backdrop:SetInside(widget.checkbg, 4, 4)
checkbg.backdrop:SetFrameLevel(widget.checkbg.backdrop:GetFrameLevel() + 1)
checkbg:SetTexture()
checkbg.SetTexture = E.noop
check:SetParent(checkbg.backdrop)
highlight:SetTexture()
highlight.SetTexture = E.noop
hooksecurefunc(widget, "SetDisabled", function(w, value)
local isSwitch = S:Ace3_CheckBoxIsEnableSwitch(w)
if value then
if isSwitch then
w:SetLabel(S.Ace3_L.RED_ENABLE)
end
end
end)
hooksecurefunc(widget, "SetValue", function(w, value)
local isSwitch = S:Ace3_CheckBoxIsEnableSwitch(w)
if isSwitch then
w:SetLabel(value and S.Ace3_L.GREEN_ENABLE or S.Ace3_L.RED_ENABLE)
end
end)
if E.private.skins.checkBoxSkin then
checkbg.backdrop:SetInside(widget.checkbg, 5, 5)
check:SetTexture(E.Media.Textures.Melli)
check.SetTexture = E.noop
check:SetInside(widget.checkbg.backdrop)
hooksecurefunc(check, "SetDesaturated", function(chk, value)
if value == true then
chk:SetDesaturated(false)
end
end)
hooksecurefunc(widget, "SetDisabled", function(w, value)
local isSwitch = S:Ace3_CheckBoxIsEnableSwitch(w)
if value then
if isSwitch then
check:SetVertexColor(1.0, 0.2, 0.2, 1.0)
else
check:SetVertexColor(0.6, 0.6, 0.6, 0.8)
end
end
end)
hooksecurefunc(widget, "SetValue", function(w, value)
local isSwitch = S:Ace3_CheckBoxIsEnableSwitch(w)
if value then
if isSwitch then
check:SetVertexColor(0.2, 1.0, 0.2, 1.0)
else
check:SetVertexColor(1, 0.82, 0, 0.8)
end
else
if w.tristate and value == nil then
check:SetVertexColor(0.6, 0.6, 0.6, 0.8)
end
end
end)
else
check:SetOutside(widget.checkbg.backdrop, 3, 3)
end
elseif TYPE == "Dropdown" then
local frame = widget.dropdown
local button = widget.button
local button_cover = widget.button_cover
local text = widget.text
frame:StripTextures()
S:HandleNextPrevButton(button, nil, {1, 0.8, 0})
if not frame.backdrop then
frame:CreateBackdrop()
end
frame.backdrop:Point("TOPLEFT", 15, -2)
frame.backdrop:Point("BOTTOMRIGHT", -21, 0)
widget.label:ClearAllPoints()
widget.label:Point("BOTTOMLEFT", frame.backdrop, "TOPLEFT", 2, 0)
button:ClearAllPoints()
button:Point("TOPLEFT", frame.backdrop, "TOPRIGHT", -22, -2)
button:Point("BOTTOMRIGHT", frame.backdrop, "BOTTOMRIGHT", -2, 2)
button:SetParent(frame.backdrop)
text:ClearAllPoints()
text:SetJustifyH("RIGHT")
text:Point("RIGHT", button, "LEFT", -3, 0)
text:Point("LEFT", frame.backdrop, "LEFT", 2, 0)
text:SetParent(frame.backdrop)
button:HookScript("OnClick", S.Ace3_SkinDropdownPullout)
if button_cover then
button_cover:HookScript("OnClick", S.Ace3_SkinDropdownPullout)
end
elseif TYPE == "LSM30_Font" or TYPE == "LSM30_Sound" or TYPE == "LSM30_Border" or TYPE == "LSM30_Background" or TYPE == "LSM30_Statusbar" then
local frame = widget.frame
local button = frame.dropButton
local text = frame.text
frame:StripTextures()
S:HandleNextPrevButton(button, nil, {1, 0.8, 0})
if not frame.backdrop then
frame:CreateBackdrop()
end
frame.label:ClearAllPoints()
frame.label:Point("BOTTOMLEFT", frame.backdrop, "TOPLEFT", 2, 0)
text:ClearAllPoints()
text:Point("RIGHT", button, "LEFT", -2, 0)
text:Point("LEFT", frame.backdrop, "LEFT", 2, 0)
button:ClearAllPoints()
button:Point("TOPLEFT", frame.backdrop, "TOPRIGHT", -22, -2)
button:Point("BOTTOMRIGHT", frame.backdrop, "BOTTOMRIGHT", -2, 2)
frame.backdrop:Point("TOPLEFT", 0, -21)
frame.backdrop:Point("BOTTOMRIGHT", -4, -1)
if TYPE == "LSM30_Sound" then
widget.soundbutton:SetParent(frame.backdrop)
widget.soundbutton:ClearAllPoints()
widget.soundbutton:Point("LEFT", frame.backdrop, "LEFT", 2, 0)
elseif TYPE == "LSM30_Statusbar" then
widget.bar:SetParent(frame.backdrop)
widget.bar:ClearAllPoints()
widget.bar:Point("TOPLEFT", frame.backdrop, "TOPLEFT", 2, -2)
widget.bar:Point("BOTTOMRIGHT", button, "BOTTOMLEFT", -1, 0)
end
button:SetParent(frame.backdrop)
text:SetParent(frame.backdrop)
button:HookScript("OnClick", S.Ace3_SkinDropdownPullout)
elseif TYPE == "EditBox" then
local frame = widget.editbox
local button = widget.button
S:HandleEditBox(frame)
S:HandleButton(button)
hooksecurefunc(frame, "SetTextInsets", function(fr, l, r, t, b)
if l == 0 then
fr:SetTextInsets(3, r, t, b)
end
end)
button:Point("RIGHT", frame.backdrop, "RIGHT", -2, 0)
hooksecurefunc(frame, "SetPoint", function(fr, a, b, c, d, e)
if d == 7 then
fr:Point(a, b, c, 0, e)
end
end)
frame.backdrop:Point("TOPLEFT", 0, -2)
frame.backdrop:Point("BOTTOMRIGHT", -1, 0)
frame.backdrop:SetParent(widget.frame)
frame:SetParent(frame.backdrop)
elseif TYPE == "Button" or TYPE == "Button-ElvUI" then
local frame = widget.frame
S:HandleButton(frame, true, nil, true)
frame.backdrop:SetInside()
widget.text:SetParent(frame.backdrop)
elseif TYPE == "Slider" or TYPE == "Slider-ElvUI" then
local frame = widget.slider
local editbox = widget.editbox
local lowtext = widget.lowtext
local hightext = widget.hightext
S:HandleSliderFrame(frame)
editbox:SetTemplate()
editbox:Height(15)
editbox:Point("TOP", frame, "BOTTOM", 0, -1)
lowtext:Point("TOPLEFT", frame, "BOTTOMLEFT", 2, -2)
hightext:Point("TOPRIGHT", frame, "BOTTOMRIGHT", -2, -2)
hooksecurefunc(widget, "SetDisabled", function(w, disabled)
local thumbTex = w.slider:GetThumbTexture()
if disabled then
thumbTex:SetVertexColor(0.6, 0.6, 0.6, 0.8)
else
thumbTex:SetVertexColor(1, 0.82, 0, 0.8)
end
end)
elseif TYPE == "Keybinding" then
local button = widget.button
local msgframe = widget.msgframe
local msg = widget.msgframe.msg
S:HandleButton(button)
msgframe:StripTextures()
msgframe:CreateBackdrop("Default", true)
msgframe.backdrop:SetInside()
msgframe:SetToplevel(true)
msg:ClearAllPoints()
msg:Point("LEFT", 10, 0)
msg:Point("RIGHT", -10, 0)
msg:SetJustifyV("MIDDLE")
msg:Width(msg:GetWidth() + 10)
elseif (TYPE == "ColorPicker" or TYPE == "ColorPicker-ElvUI") then
local frame = widget.frame
local colorSwatch = widget.colorSwatch
if not frame.backdrop then
frame:CreateBackdrop()
end
frame.backdrop:Size(24, 16)
frame.backdrop:ClearAllPoints()
frame.backdrop:Point("LEFT", frame, "LEFT", 4, 0)
frame.backdrop:SetBackdropColor(0, 0, 0, 0)
frame.backdrop.SetBackdropColor = E.noop
colorSwatch:SetTexture(E.media.blankTex)
colorSwatch:ClearAllPoints()
colorSwatch:SetParent(frame.backdrop)
colorSwatch:SetInside(frame.backdrop)
if colorSwatch.background then
colorSwatch.background:SetTexture(0, 0, 0, 0)
end
if colorSwatch.checkers then
colorSwatch.checkers:ClearAllPoints()
colorSwatch.checkers:SetDrawLayer("ARTWORK")
colorSwatch.checkers:SetParent(frame.backdrop)
colorSwatch.checkers:SetInside(frame.backdrop)
end
elseif TYPE == "Icon" then
widget.frame:StripTextures()
end
return oldRegisterAsWidget(self, widget)
end
function S:Ace3_RegisterAsContainer(widget)
if not E.private.skins.ace3.enable then
return oldRegisterAsContainer(self, widget)
end
local TYPE = widget.type
if TYPE == "ScrollFrame" then
S:HandleScrollBar(widget.scrollbar)
widget.scrollbar:Point("TOPLEFT", widget.scrollframe, "TOPRIGHT", 8, -16)
widget.scrollbar:Point("BOTTOMLEFT", widget.scrollframe, "BOTTOMRIGHT", 8, 16)
elseif TYPE == "InlineGroup" or TYPE == "TreeGroup" or TYPE == "TabGroup" or TYPE == "Frame" or TYPE == "DropdownGroup" or TYPE == "Window" then
local frame = widget.content:GetParent()
if TYPE == "Frame" then
frame:StripTextures()
for i = 1, frame:GetNumChildren() do
local child = select(i, frame:GetChildren())
if child:IsObjectType("Button") and child:GetText() then
S:HandleButton(child)
else
child:StripTextures()
end
end
elseif TYPE == "Window" then
frame:StripTextures()
S:HandleCloseButton(frame.obj.closebutton)
end
if TYPE == "InlineGroup" then
frame:SetTemplate("Transparent")
frame.ignoreBackdropColors = true
frame:SetBackdropColor(0, 0, 0, 0.25)
else
frame:SetTemplate("Transparent")
end
if widget.treeframe then
widget.treeframe:SetTemplate("Transparent")
frame:Point("TOPLEFT", widget.treeframe, "TOPRIGHT", 1, 0)
local oldRefreshTree = widget.RefreshTree
widget.RefreshTree = function(wdg, scrollToSelection)
oldRefreshTree(wdg, scrollToSelection)
if not wdg.tree then return end
local status = wdg.status or wdg.localstatus
local groupstatus = status.groups
local lines = wdg.lines
local buttons = wdg.buttons
local offset = status.scrollvalue
for i = offset + 1, #lines do
local button = buttons[i - offset]
if button then
button.highlight:SetTexture(E.Media.Textures.Highlight)
button.highlight:SetVertexColor(1, 0.82, 0, 0.35)
button.highlight:Point("TOPLEFT", 0, 0)
button.highlight:Point("BOTTOMRIGHT", 0, 1)
button.toggle:SetHighlightTexture("")
if groupstatus[lines[i].uniquevalue] then
button.toggle:SetNormalTexture(E.Media.Textures.Minus)
button.toggle:SetPushedTexture(E.Media.Textures.Minus)
else
button.toggle:SetNormalTexture(E.Media.Textures.Plus)
button.toggle:SetPushedTexture(E.Media.Textures.Plus)
end
end
end
end
end
if TYPE == "TabGroup" then
local oldCreateTab = widget.CreateTab
widget.CreateTab = function(wdg, id)
local tab = oldCreateTab(wdg, id)
tab:StripTextures()
tab:CreateBackdrop("Transparent")
tab.backdrop:Point("TOPLEFT", 10, -3)
tab.backdrop:Point("BOTTOMRIGHT", -10, 0)
tab:SetHitRectInsets(10, 10, 3, 0)
return tab
end
end
if widget.scrollbar then
S:HandleScrollBar(widget.scrollbar)
widget.scrollbar:Point("TOPRIGHT", -4, -23)
widget.scrollbar:Point("BOTTOMRIGHT", -4, 23)
end
elseif TYPE == "SimpleGroup" then
local frame = widget.content:GetParent()
frame:SetTemplate("Transparent", nil, true)
frame.ignoreBackdropColors = true
frame:SetBackdropColor(0, 0, 0, 0.25)
end
return oldRegisterAsContainer(self, widget)
end
function S:Ace3_StyleTooltip()
if not self then return end
self:SetTemplate("Transparent", nil, true)
end
function S:Ace3_SkinTooltip(lib, minor) -- lib: AceConfigDialog or AceGUI
-- we only check `minor` here when checking an instance of AceConfigDialog
-- we can safely ignore it when checking AceGUI because we minor check that
-- inside of its own function.
if not lib or (minor and minor < minorConfigDialog) then return end
if lib.tooltip and not S:IsHooked(lib.tooltip, "OnShow") then
S:SecureHookScript(lib.tooltip, "OnShow", S.Ace3_StyleTooltip)
end
if lib.popup and not lib.popup.template then -- StaticPopup
lib.popup:SetTemplate("Transparent")
lib.popup:GetChildren():StripTextures()
S:HandleButton(lib.popup.accept, true)
S:HandleButton(lib.popup.cancel, true)
end
end
function S:HookAce3(lib, minor) -- lib: AceGUI
if not lib or (not minor or minor < minorGUI) then return end
if not S.Ace3_L then
S.Ace3_L = E.Libs.ACL:GetLocale("ElvUI", E.global.general.locale or "enUS")
end
if lib.RegisterAsWidget ~= S.Ace3_RegisterAsWidget then
oldRegisterAsWidget = lib.RegisterAsWidget
lib.RegisterAsWidget = S.Ace3_RegisterAsWidget
end
if lib.RegisterAsContainer ~= S.Ace3_RegisterAsContainer then
oldRegisterAsContainer = lib.RegisterAsContainer
lib.RegisterAsContainer = S.Ace3_RegisterAsContainer
end
S:Ace3_SkinTooltip(lib)
end
@@ -0,0 +1,3 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<Script file="Ace3.lua"/>
</Ui>
@@ -0,0 +1,540 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
local _G = _G
local ipairs = ipairs
local unpack = unpack
--WoW API / Variables
local hooksecurefunc = hooksecurefunc
local GetAchievementNumCriteria = GetAchievementNumCriteria
local GetAchievementCriteriaInfo = GetAchievementCriteriaInfo
local CRITERIA_TYPE_ACHIEVEMENT = CRITERIA_TYPE_ACHIEVEMENT
local function skinAchievement(achievement, biggerIcon)
if achievement.isSkinned then return end
_G[achievement:GetName().."Background"]:Kill()
achievement:StripTextures()
achievement:SetTemplate("Default", true)
achievement.icon:SetTemplate()
achievement.icon:SetSize(biggerIcon and 54 or 36, biggerIcon and 54 or 36)
achievement.icon:ClearAllPoints()
achievement.icon:Point("TOPLEFT", 8, -8)
achievement.icon.bling:Kill()
achievement.icon.frame:Kill()
achievement.icon.texture:SetTexCoord(unpack(E.TexCoords))
achievement.icon.texture:SetInside()
if achievement.highlight then
achievement.highlight:StripTextures()
achievement:HookScript("OnEnter", S.SetModifiedBackdrop)
achievement:HookScript("OnLeave", S.SetOriginalBackdrop)
end
if achievement.label then
achievement.label:SetTextColor(1, 1, 1)
end
if achievement.description then
achievement.description:SetTextColor(.6, .6, .6)
achievement.description.SetTextColor = E.noop
end
if achievement.hiddenDescription then
achievement.hiddenDescription:SetTextColor(1, 1, 1)
end
if achievement.tracked then
S:HandleCheckBox(achievement.tracked, true)
achievement.tracked:Size(14, 14)
achievement.tracked:ClearAllPoints()
achievement.tracked:Point("TOPLEFT", achievement.icon, "BOTTOMLEFT", 0, -2)
end
hooksecurefunc(achievement, "Saturate", function(self)
self:SetBackdropBorderColor(unpack(E.media.bordercolor))
end)
hooksecurefunc(achievement, "Desaturate", function(self)
self:SetBackdropBorderColor(unpack(E.media.bordercolor))
end)
achievement.isSkinned = true
end
S:AddCallback("Skin_AchievementUI_HybridScrollButton", function()
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.achievement then return end
hooksecurefunc("HybridScrollFrame_CreateButtons", function(frame, template)
if template == "AchievementCategoryTemplate" then
for _, button in ipairs(frame.buttons) do
if not button.isSkinned then
button:StripTextures(true)
button:StyleButton()
button.isSkinned = true
end
end
elseif template == "AchievementTemplate" then
for _, achievement in ipairs(frame.buttons) do
skinAchievement(achievement, true)
end
elseif template == "ComparisonTemplate" then
for _, achievement in ipairs(frame.buttons) do
skinAchievement(achievement.player)
skinAchievement(achievement.friend)
end
elseif template == "StatTemplate" then
for _, stats in ipairs(frame.buttons) do
if not stats.isSkinned then
-- stats:StripTextures(true)
stats:StyleButton()
stats.isSkinned = true
end
end
end
end)
end)
S:AddCallbackForAddon("Blizzard_AchievementUI", "Skin_Blizzard_AchievementUI", function()
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.achievement then return end
local frames = {
"AchievementFrame",
-- "AchievementFrameCategories",
"AchievementFrameSummary",
"AchievementFrameSummaryCategoriesHeader",
"AchievementFrameSummaryAchievementsHeader",
"AchievementFrameStatsBG",
"AchievementFrameAchievements",
"AchievementFrameComparison",
"AchievementFrameComparisonHeader",
"AchievementFrameComparisonSummaryPlayer",
"AchievementFrameComparisonSummaryFriend"
}
for _, frame in ipairs(frames) do
_G[frame]:StripTextures(true)
end
local nonameFrames = {
"AchievementFrameStats",
"AchievementFrameSummary",
"AchievementFrameAchievements",
"AchievementFrameComparison"
}
for _, frame in ipairs(nonameFrames) do
frame = _G[frame]
for i = 1, frame:GetNumChildren() do
local child = select(i, frame:GetChildren())
if child and not child:GetName() then
child:SetBackdrop(nil)
end
end
end
local function updatePanelInfo(self)
if self == AchievementFrameComparison then
if AchievementFrame.isComparison then
AchievementFrame:Width(863)
else
AchievementFrame:Width(737)
end
end
S:SetUIPanelWindowInfo(AchievementFrame, "xoffset", 11, nil, true)
S:SetUIPanelWindowInfo(AchievementFrame, "yoffset", -12, nil, true)
S:SetUIPanelWindowInfo(AchievementFrame, "width", nil, -11)
end
AchievementFrame:HookScript("OnShow", updatePanelInfo)
AchievementFrameComparison:HookScript("OnShow", updatePanelInfo)
AchievementFrameComparison:HookScript("OnHide", updatePanelInfo)
S:HandleCloseButton(AchievementFrameCloseButton, AchievementFrame.backdrop)
S:HandleDropDownBox(AchievementFrameFilterDropDown)
S:HandleScrollBar(AchievementFrameCategoriesContainerScrollBar)
S:HandleScrollBar(AchievementFrameAchievementsContainerScrollBar)
S:HandleScrollBar(AchievementFrameStatsContainerScrollBar)
S:HandleScrollBar(AchievementFrameComparisonContainerScrollBar)
S:HandleScrollBar(AchievementFrameComparisonStatsContainerScrollBar)
AchievementFrameHeaderTitle:SetParent(AchievementFrame)
AchievementFrameHeaderTitle:ClearAllPoints()
AchievementFrameHeaderTitle:Point("TOPLEFT", AchievementFrame, "TOPLEFT", -29, -9)
AchievementFrameHeaderPoints:SetParent(AchievementFrame)
AchievementFrameHeaderPoints:ClearAllPoints()
AchievementFrameHeaderPoints:Point("LEFT", AchievementFrameHeaderTitle, "RIGHT", 2, 0)
AchievementFrameHeaderShield:SetParent(AchievementFrame)
AchievementFrameHeader:Hide()
AchievementFrameHeader.Show = E.noop
AchievementFrame:Size(737, 485)
AchievementFrame:SetTemplate("Transparent")
AchievementFrameFilterDropDown:Point("TOPRIGHT", AchievementFrame, "TOPRIGHT", -21, -5)
AchievementFrameCategories:SetTemplate("Default")
AchievementFrameCategories:Point("TOPLEFT", 8, -35)
AchievementFrameCategories:Point("BOTTOMLEFT", 21, 8)
AchievementFrameCategoriesContainerScrollBar:Point("TOPLEFT", AchievementFrameCategoriesContainer, "TOPRIGHT", 3, -14)
AchievementFrameCategoriesContainerScrollBar:Point("BOTTOMLEFT", AchievementFrameCategoriesContainer, "BOTTOMRIGHT", 3, 14)
AchievementFrameSummaryAchievements:Point("TOPLEFT", 5, -10)
AchievementFrameSummaryAchievements:Point("TOPRIGHT", -5, -30)
AchievementFrameAchievements:SetTemplate("Transparent")
AchievementFrameAchievementsContainer:Point("TOPLEFT", 2, -2)
AchievementFrameAchievementsContainer:Point("BOTTOMRIGHT", -2, 4)
AchievementFrameAchievementsContainerScrollBar:Point("TOPLEFT", AchievementFrameAchievementsContainer, "TOPRIGHT", 5, -17)
AchievementFrameAchievementsContainerScrollBar:Point("BOTTOMLEFT", AchievementFrameAchievementsContainer, "BOTTOMRIGHT", 5, 15)
AchievementFrameStats:SetTemplate("Transparent")
AchievementFrameStatsContainerScrollBar:Point("TOPLEFT", AchievementFrameStatsContainer, "TOPRIGHT", 3, -16)
AchievementFrameStatsContainerScrollBar:Point("BOTTOMLEFT", AchievementFrameStatsContainer, "BOTTOMRIGHT", 3, 14)
AchievementFrameComparison:SetTemplate("Transparent")
AchievementFrameComparisonHeader:Point("BOTTOMRIGHT", AchievementFrameComparison, "TOPRIGHT", 50, -1)
AchievementFrameComparison:Point("TOPLEFT", AchievementFrameCategories, "TOPRIGHT", 3, 0)
AchievementFrameComparisonSummary:Height(30)
AchievementFrameComparisonSummary:Point("TOPLEFT", 4, -2)
AchievementFrameComparisonContainer:Point("TOPLEFT", AchievementFrameComparisonSummary, "BOTTOMLEFT", 0, -3)
AchievementFrameComparisonContainerScrollBar:Point("TOPLEFT", AchievementFrameComparisonSummary, "TOPRIGHT", 9, -17)
AchievementFrameComparisonContainerScrollBar:Point("BOTTOMLEFT", AchievementFrameComparisonContainer, "BOTTOMRIGHT", 9, 14)
AchievementFrameComparisonStatsContainer:Point("TOPLEFT", 5, -3)
AchievementFrameComparisonStatsContainerScrollBar:Point("TOPLEFT", AchievementFrameComparisonStatsContainer, "TOPRIGHT", 3, -16)
AchievementFrameComparisonStatsContainerScrollBar:Point("BOTTOMLEFT", AchievementFrameComparisonStatsContainer, "BOTTOMRIGHT", 3, 14)
AchievementFrameAchievementsContainerScrollBar.Show = function(self)
AchievementFrameAchievements:SetWidth(500)
for _, button in ipairs(AchievementFrameAchievements.buttons) do
button:SetWidth(496)
end
getmetatable(self).__index.Show(self)
end
AchievementFrameAchievementsContainerScrollBar.Hide = function(self)
AchievementFrameAchievements:SetWidth(521)
for _, button in ipairs(AchievementFrameAchievements.buttons) do
button:SetWidth(517)
end
getmetatable(self).__index.Hide(self)
end
AchievementFrameStatsContainerScrollBar.Show = function(self)
AchievementFrameStats:SetWidth(500)
for _, button in ipairs(AchievementFrameStats.buttons) do
button:SetWidth(494)
end
getmetatable(self).__index.Show(self)
end
AchievementFrameStatsContainerScrollBar.Hide = function(self)
AchievementFrameStats:SetWidth(521)
for _, button in ipairs(AchievementFrameStats.buttons) do
button:SetWidth(515)
end
getmetatable(self).__index.Hide(self)
end
--[[
AchievementFrameComparisonContainerScrollBar.Show = function(self)
AchievementFrameComparison:SetWidth(626)
AchievementFrameComparisonSummaryPlayer:SetWidth(498)
for _, button in ipairs(AchievementFrameComparisonContainer.buttons) do
button:SetWidth(616)
button.player:SetWidth(498)
end
getmetatable(self).__index.Show(self)
end
]]
AchievementFrameComparisonContainerScrollBar.Hide = function(self)
AchievementFrameComparison:SetWidth(647)
AchievementFrameComparisonSummaryPlayer:SetWidth(519)
for _, button in ipairs(AchievementFrameComparisonContainer.buttons) do
button:SetWidth(637)
button.player:SetWidth(519)
end
getmetatable(self).__index.Hide(self)
end
--[[
AchievementFrameComparisonStatsContainerScrollBar.Show = function(self)
AchievementFrameComparison:SetWidth(626)
for _, button in ipairs(AchievementFrameComparisonStatsContainer.buttons) do
button:SetWidth(616)
end
getmetatable(self).__index.Show(self)
end
]]
AchievementFrameComparisonStatsContainerScrollBar.Hide = function(self)
AchievementFrameComparison:SetWidth(647)
for _, button in ipairs(AchievementFrameComparisonStatsContainer.buttons) do
button:SetWidth(637)
end
getmetatable(self).__index.Hide(self)
end
local function categoriesContainerScripts()
AchievementFrameCategoriesContainerScrollBar.Show = function(self)
ACHIEVEMENTUI_CATEGORIESWIDTH = 176
AchievementFrameCategories:SetWidth(176)
AchievementFrameCategoriesContainer:GetScrollChild():SetWidth(176)
AchievementFrameAchievements:SetPoint("TOPLEFT", "$parentCategories", "TOPRIGHT", 24, 0)
AchievementFrameStats:SetPoint("TOPLEFT", "$parentCategories", "TOPRIGHT", 24, 0)
AchievementFrameComparison:SetPoint("TOPLEFT", "$parentCategories", "TOPRIGHT", 24, 0)
for _, button in ipairs(AchievementFrameCategoriesContainer.buttons) do
AchievementFrameCategories_DisplayButton(button, button.element)
end
getmetatable(self).__index.Show(self)
end
AchievementFrameCategoriesContainerScrollBar.Hide = function(self)
ACHIEVEMENTUI_CATEGORIESWIDTH = 197
AchievementFrameCategories:SetWidth(197)
AchievementFrameCategoriesContainer:GetScrollChild():SetWidth(197)
AchievementFrameAchievements:SetPoint("TOPLEFT", "$parentCategories", "TOPRIGHT", 3, 0)
AchievementFrameStats:SetPoint("TOPLEFT", "$parentCategories", "TOPRIGHT", 3, 0)
AchievementFrameComparison:SetPoint("TOPLEFT", "$parentCategories", "TOPRIGHT", 3, 0)
for _, button in ipairs(AchievementFrameCategoriesContainer.buttons) do
AchievementFrameCategories_DisplayButton(button, button.element)
end
getmetatable(self).__index.Hide(self)
end
end
if AchievementFrameCategoriesContainer.update then
categoriesContainerScripts()
else
AchievementFrameCategories:HookScript("OnEvent", categoriesContainerScripts)
end
for i = 1, 2 do
local tab = _G["AchievementFrameTab"..i]
S:HandleTab(tab)
tab.text:SetPoint("CENTER", 0, 2)
tab.text.SetPoint = E.noop
end
AchievementFrameTab1:Point("BOTTOMLEFT", AchievementFrame, "BOTTOMLEFT", 0, -30)
AchievementFrameTab2:Point("LEFT", AchievementFrameTab1, "RIGHT", -15, 0)
local sbcR, sbcG, sbcB = 4/255, 179/255, 30/255
local function skinStatusBar(bar)
bar:StripTextures()
bar:SetStatusBarTexture(E.media.normTex)
bar:SetStatusBarColor(sbcR, sbcG, sbcB)
bar:CreateBackdrop("Default")
E:RegisterStatusBar(bar)
local barName = bar:GetName()
local title = _G[barName.."Title"]
local label = _G[barName.."Label"]
local text = _G[barName.."Text"]
if title then
title:Point("LEFT", 4, 0)
end
if label then
label:Point("LEFT", 4, 0)
end
if text then
text:Point("RIGHT", -4, 0)
end
end
skinStatusBar(AchievementFrameSummaryCategoriesStatusBar)
skinStatusBar(AchievementFrameComparisonSummaryPlayerStatusBar)
skinStatusBar(AchievementFrameComparisonSummaryFriendStatusBar)
AchievementFrameComparisonSummaryFriendStatusBar.text:ClearAllPoints()
AchievementFrameComparisonSummaryFriendStatusBar.text:Point("CENTER")
for i = 1, 8 do
local frame = _G["AchievementFrameSummaryCategoriesCategory"..i]
local button = _G["AchievementFrameSummaryCategoriesCategory"..i.."Button"]
local highlight = _G["AchievementFrameSummaryCategoriesCategory"..i.."ButtonHighlight"]
local middle = _G["AchievementFrameSummaryCategoriesCategory"..i.."ButtonHighlightMiddle"]
skinStatusBar(frame)
button:StripTextures()
highlight:StripTextures()
middle:SetTexture(1, 1, 1, 0.3)
middle:SetAllPoints(frame)
end
for i = 1, 20 do
_G["AchievementFrameStatsContainerButton"..i]:StyleButton()
_G["AchievementFrameStatsContainerButton"..i.."BG"]:SetTexture(1, 1, 1, 0.2)
_G["AchievementFrameStatsContainerButton"..i.."HeaderLeft"]:Kill()
_G["AchievementFrameStatsContainerButton"..i.."HeaderRight"]:Kill()
_G["AchievementFrameStatsContainerButton"..i.."HeaderMiddle"]:Kill()
local frame = _G["AchievementFrameComparisonStatsContainerButton"..i]
frame:StripTextures()
frame:StyleButton()
_G["AchievementFrameComparisonStatsContainerButton"..i.."BG"]:SetTexture(1, 1, 1, 0.2)
_G["AchievementFrameComparisonStatsContainerButton"..i.."HeaderLeft"]:Kill()
_G["AchievementFrameComparisonStatsContainerButton"..i.."HeaderRight"]:Kill()
_G["AchievementFrameComparisonStatsContainerButton"..i.."HeaderMiddle"]:Kill()
end
hooksecurefunc("AchievementFrameSummary_UpdateAchievements", function()
local frame, prevFrame
for i = 1, ACHIEVEMENTUI_MAX_SUMMARY_ACHIEVEMENTS do
frame = _G["AchievementFrameSummaryAchievement"..i]
skinAchievement(frame)
if i ~= 1 then
prevFrame = _G["AchievementFrameSummaryAchievement"..(i-1)]
frame:ClearAllPoints()
frame:Point("TOPLEFT", prevFrame, "BOTTOMLEFT", 0, -1)
frame:Point("TOPRIGHT", prevFrame, "BOTTOMRIGHT", 0, 1)
end
frame:SetBackdropBorderColor(unpack(E.media.bordercolor))
end
end)
hooksecurefunc("AchievementButton_GetProgressBar", function(index)
local frame = _G["AchievementFrameProgressBar"..index]
if frame and not frame.skinned then
frame:StripTextures()
frame:SetStatusBarTexture(E.media.normTex)
E:RegisterStatusBar(frame)
frame:SetStatusBarColor(sbcR, sbcG, sbcB)
frame:GetStatusBarTexture():SetInside()
frame:Height(frame:GetHeight() + (E.Border + E.Spacing))
frame:SetTemplate("Default")
frame.text:ClearAllPoints()
frame.text:Point("CENTER", frame, "CENTER", 0, -1)
frame.text:SetJustifyH("CENTER")
if index > 1 then
frame:ClearAllPoints()
frame:Point("TOP", _G["AchievementFrameProgressBar"..index-1], "BOTTOM", 0, -5)
frame.SetPoint = E.noop
frame.ClearAllPoints = E.noop
end
frame.skinned = true
end
end)
hooksecurefunc("AchievementObjectives_DisplayCriteria", function(objectivesFrame, id)
local numCriteria = GetAchievementNumCriteria(id)
local textStrings, metas = 0, 0
for i = 1, numCriteria do
local _, criteriaType, completed, _, _, _, _, assetID = GetAchievementCriteriaInfo(id, i)
if criteriaType == CRITERIA_TYPE_ACHIEVEMENT and assetID then
metas = metas + 1
local metaCriteria = AchievementButton_GetMeta(metas)
metaCriteria:Height(21)
metaCriteria:StyleButton()
metaCriteria.border:Kill()
metaCriteria.icon:SetTexCoord(unpack(E.TexCoords))
metaCriteria.icon:Point("TOPLEFT", 2, -2)
metaCriteria.label:Point("LEFT", 26, 0)
if objectivesFrame.completed and completed then
metaCriteria.label:SetShadowOffset(0, 0)
metaCriteria.label:SetTextColor(1, 1, 1, 1)
elseif completed then
metaCriteria.label:SetShadowOffset(1, -1)
metaCriteria.label:SetTextColor(0, 1, 0, 1)
else
metaCriteria.label:SetShadowOffset(1, -1)
metaCriteria.label:SetTextColor(.6, .6, .6, 1)
end
elseif criteriaType ~= 1 then
textStrings = textStrings + 1
local criteria = AchievementButton_GetCriteria(textStrings)
if objectivesFrame.completed and completed then
criteria.name:SetTextColor(1, 1, 1, 1)
criteria.name:SetShadowOffset(0, 0)
elseif completed then
criteria.name:SetTextColor(0, 1, 0, 1)
criteria.name:SetShadowOffset(1, -1)
else
criteria.name:SetTextColor(.6, .6, .6, 1)
criteria.name:SetShadowOffset(1, -1)
end
end
end
end)
hooksecurefunc("AchievementObjectives_DisplayProgressiveAchievement", function(objectivesFrame, id)
local mini
for i = 1, 12 do
mini = _G["AchievementFrameMiniAchievement"..i]
if mini and not mini.isSkinned then
local icon = _G["AchievementFrameMiniAchievement"..i.."Icon"]
local points = _G["AchievementFrameMiniAchievement"..i.."Points"]
local border = _G["AchievementFrameMiniAchievement"..i.."Border"]
local shield = _G["AchievementFrameMiniAchievement"..i.."Shield"]
mini:SetTemplate()
mini:SetBackdropColor(0, 0, 0, 0)
mini:Size(32)
local prevFrame = _G["AchievementFrameMiniAchievement"..i - 1]
if i == 1 then
mini:Point("TOPLEFT", 6, -4)
elseif i == 7 then
mini:Point("TOPLEFT", AchievementFrameMiniAchievement1, "BOTTOMLEFT", 0, -20)
else
mini:Point("TOPLEFT", prevFrame, "TOPRIGHT", 10, 0)
end
mini.SetPoint = E.noop
icon:SetTexCoord(unpack(E.TexCoords))
icon:SetInside()
points:Point("BOTTOMRIGHT", -8, -15)
points:SetTextColor(1, 0.80, 0.10)
border:Kill()
shield:Kill()
mini.isSkinned = true
end
end
end)
end)
+73
View File
@@ -0,0 +1,73 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
local _G = _G
local unpack = unpack
local tonumber = tonumber
local match = string.match
--WoW API / Variables
S:AddCallback("Skin_Alerts", function()
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.alertframes then return end
S:RawHook("AchievementAlertFrame_GetAlertFrame", function()
local frame = S.hooks.AchievementAlertFrame_GetAlertFrame()
if frame and not frame.isSkinned then
local name = frame:GetName()
frame:DisableDrawLayer("OVERLAY")
frame:CreateBackdrop("Transparent")
frame.backdrop:Point("TOPLEFT", frame, 0, -6)
frame.backdrop:Point("BOTTOMRIGHT", frame, 0, 6)
S:SetBackdropHitRect(frame)
_G[name.."Background"]:SetTexture(nil)
_G[name.."Unlocked"]:SetTextColor(1, 1, 1)
local icon = _G[name.."Icon"]
icon:DisableDrawLayer("BACKGROUND")
icon:DisableDrawLayer("OVERLAY")
icon.texture:ClearAllPoints()
icon.texture:Point("LEFT", frame, 13, 0)
icon.texture:SetTexCoord(unpack(E.TexCoords))
icon:CreateBackdrop("Default")
icon.backdrop:SetOutside(icon.texture)
frame.isSkinned = true
if tonumber(match(name, ".+(%d+)")) == MAX_ACHIEVEMENT_ALERTS then
S:Unhook("AchievementAlertFrame_GetAlertFrame")
end
end
return frame
end, true)
local frame = DungeonCompletionAlertFrame1
frame:DisableDrawLayer("BORDER")
frame:DisableDrawLayer("OVERLAY")
frame:CreateBackdrop("Transparent")
frame.backdrop:Point("TOPLEFT", frame, 0, -6)
frame.backdrop:Point("BOTTOMRIGHT", frame, 0, 6)
S:SetBackdropHitRect(frame)
frame.dungeonTexture:ClearAllPoints()
frame.dungeonTexture:Point("LEFT", frame, 13, 0)
frame.dungeonTexture:Size(42)
frame.dungeonTexture:SetTexCoord(unpack(E.TexCoords))
frame.dungeonTexture.backdrop = CreateFrame("Frame", "$parentDungeonTextureBackground", frame)
frame.dungeonTexture.backdrop:SetTemplate("Default")
frame.dungeonTexture.backdrop:SetOutside(frame.dungeonTexture)
frame.dungeonTexture.backdrop:SetFrameLevel(0)
frame.glowFrame:DisableDrawLayer("OVERLAY")
end)
+40
View File
@@ -0,0 +1,40 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
--WoW API / Variables
S:AddCallback("Skin_Arena", function()
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.arena then return end
ArenaFrame:StripTextures()
ArenaFrame:CreateBackdrop("Transparent")
ArenaFrame.backdrop:Point("TOPLEFT", 11, -12)
ArenaFrame.backdrop:Point("BOTTOMRIGHT", -32, 76)
S:SetUIPanelWindowInfo(ArenaFrame, "width")
S:SetBackdropHitRect(ArenaFrame)
S:HandleCloseButton(ArenaFrameCloseButton, ArenaFrame.backdrop)
S:HandleButton(ArenaFrameGroupJoinButton)
S:HandleButton(ArenaFrameJoinButton)
S:HandleButton(ArenaFrameCancelButton)
for i = 1, MAX_ARENA_BATTLES do
S:HandleButtonHighlight(_G["ArenaZone"..i])
end
ArenaFrameZoneDescription:SetTextColor(1, 1, 1)
ArenaFrameNameHeader:Point("TOPLEFT", 28, -55)
ArenaZone1:Point("TOPLEFT", 24, -79)
ArenaFrameGroupJoinButton:Width(127)
ArenaFrameCancelButton:Point("CENTER", ArenaFrame, "TOPLEFT", 302, -417)
ArenaFrameJoinButton:Point("RIGHT", ArenaFrameCancelButton, "LEFT", -3, 0)
ArenaFrameGroupJoinButton:Point("RIGHT", ArenaFrameJoinButton, "LEFT", -3, 0)
end)
@@ -0,0 +1,87 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
local _G = _G
local select = select
--WoW API / Variables
S:AddCallback("Skin_ArenaRegistrar", function()
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.arenaregistrar then return end
ArenaRegistrarFrame:StripTextures(true)
ArenaRegistrarFrame:CreateBackdrop("Transparent")
ArenaRegistrarFrame.backdrop:Point("TOPLEFT", 11, -12)
ArenaRegistrarFrame.backdrop:Point("BOTTOMRIGHT", -32, 76)
S:SetUIPanelWindowInfo(ArenaRegistrarFrame, "width")
S:SetBackdropHitRect(ArenaRegistrarFrame)
S:HandleCloseButton(ArenaRegistrarFrameCloseButton, ArenaRegistrarFrame.backdrop)
ArenaRegistrarGreetingFrame:StripTextures()
ArenaRegistrarGreetingFrame:GetRegions():SetTextColor(1, 1, 1)
RegistrationText:SetTextColor(1, 1, 1)
ArenaRegistrarPurchaseText:SetTextColor(1, 1, 1)
for i = 1, 6 do
local button = _G["ArenaRegistrarButton"..i]
S:HandleButtonHighlight(button)
select(3, button:GetRegions()):SetTextColor(1, 1, 1)
end
S:HandleButton(ArenaRegistrarFrameGoodbyeButton)
S:HandleButton(ArenaRegistrarFrameCancelButton)
S:HandleButton(ArenaRegistrarFramePurchaseButton)
select(6, ArenaRegistrarFrameEditBox:GetRegions()):Kill()
select(7, ArenaRegistrarFrameEditBox:GetRegions()):Kill()
S:HandleEditBox(ArenaRegistrarFrameEditBox)
ArenaRegistrarFrameEditBox:Height(18)
ArenaRegistrarFrameGoodbyeButton:Width(80)
ArenaRegistrarFrameGoodbyeButton:Point("BOTTOMRIGHT", -40, 84)
ArenaRegistrarFrameCancelButton:Point("BOTTOMRIGHT", -40, 84)
ArenaRegistrarFramePurchaseButton:Point("BOTTOMLEFT", 19, 84)
-- PVP Banner
PVPBannerFrame:StripTextures()
PVPBannerFrame:CreateBackdrop("Transparent")
PVPBannerFrame.backdrop:Point("TOPLEFT", 11, -12)
PVPBannerFrame.backdrop:Point("BOTTOMRIGHT", -32, 76)
S:SetUIPanelWindowInfo(PVPBannerFrame, "width")
S:SetBackdropHitRect(PVPBannerFrame)
S:HandleCloseButton(PVPBannerFrameCloseButton, PVPBannerFrame.backdrop)
PVPBannerFramePortrait:Kill()
PVPBannerFrameCustomizationFrame:StripTextures()
for i = 1, 2 do
_G["PVPBannerFrameCustomization"..i]:StripTextures()
S:HandleNextPrevButton(_G["PVPBannerFrameCustomization"..i.."LeftButton"])
S:HandleNextPrevButton(_G["PVPBannerFrameCustomization"..i.."RightButton"])
end
S:HandleButton(PVPColorPickerButton1)
S:HandleButton(PVPColorPickerButton2)
S:HandleButton(PVPColorPickerButton3)
S:HandleButton(PVPBannerFrameAcceptButton)
S:HandleButton(PVPBannerFrameCancelButton)
local PVPBannerFrameCancelButton2 = select(4, PVPBannerFrame:GetChildren())
S:HandleButton(PVPBannerFrameCancelButton2)
PVPBannerFrameCustomization1:Point("TOPLEFT", PVPBannerFrameCustomizationBorder, "TOPLEFT", 48, -50)
PVPColorPickerButton1:Point("TOP", PVPBannerFrameCustomization2, "BOTTOM", 1, -7)
PVPColorPickerButton2:Point("TOP", PVPBannerFrameCustomization2, "BOTTOM", 1, -33)
PVPColorPickerButton3:Point("TOP", PVPBannerFrameCustomization2, "BOTTOM", 1, -59)
PVPBannerFrameCancelButton2:Point("CENTER", PVPBannerFrame, "TOPLEFT", 304, -417)
PVPBannerFrameAcceptButton:Point("CENTER", PVPBannerFrame, "TOPLEFT", 221, -417)
end)
@@ -0,0 +1,381 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
local _G = _G
local ipairs, unpack = ipairs, unpack
--WoW API / Variables
local GetAuctionSellItemInfo = GetAuctionSellItemInfo
local GetItemQualityColor = GetItemQualityColor
local PlaySound = PlaySound
local hooksecurefunc = hooksecurefunc
S:AddCallbackForAddon("Blizzard_AuctionUI", "Skin_Blizzard_AuctionUI", function()
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.auctionhouse then return end
AuctionFrame:StripTextures(true)
AuctionFrame:CreateBackdrop("Transparent")
AuctionFrame.backdrop:Point("TOPLEFT", 12, 0)
AuctionFrame.backdrop:Point("BOTTOMRIGHT", 0, 0)
S:HookScript(AuctionFrame, "OnShow", function(self)
S:SetUIPanelWindowInfo(self, "xoffset", -1, nil, true)
S:SetUIPanelWindowInfo(self, "yoffset", -12, nil, true)
S:SetUIPanelWindowInfo(self, "width", nil, 1)
S:SetBackdropHitRect(self)
S:Unhook(self, "OnShow")
end)
local buttons = {
BrowseSearchButton,
BrowseResetButton,
BrowseBidButton,
BrowseBuyoutButton,
BrowseCloseButton,
BidBidButton,
BidBuyoutButton,
BidCloseButton,
AuctionsCreateAuctionButton,
AuctionsCancelAuctionButton,
AuctionsStackSizeMaxButton,
AuctionsNumStacksMaxButton,
AuctionsCloseButton
}
local checkBoxes = {
IsUsableCheckButton,
ShowOnPlayerCheckButton
}
local editBoxes = {
BrowseName,
BrowseMinLevel,
BrowseMaxLevel,
BrowseBidPriceGold,
BrowseBidPriceSilver,
BrowseBidPriceCopper,
BidBidPriceGold,
BidBidPriceSilver,
BidBidPriceCopper,
AuctionsStackSizeEntry,
AuctionsNumStacksEntry,
StartPriceGold,
StartPriceSilver,
StartPriceCopper,
BuyoutPriceGold,
BuyoutPriceSilver,
BuyoutPriceCopper
}
local sortTabs = {
BrowseQualitySort,
BrowseLevelSort,
BrowseDurationSort,
BrowseHighBidderSort,
BrowseCurrentBidSort,
BidQualitySort,
BidLevelSort,
BidDurationSort,
BidBuyoutSort,
BidStatusSort,
BidBidSort,
AuctionsQualitySort,
AuctionsDurationSort,
AuctionsHighBidderSort,
AuctionsBidSort
}
for _, button in ipairs(buttons) do
S:HandleButton(button, true)
end
for _, checkBox in ipairs(checkBoxes) do
S:HandleCheckBox(checkBox)
end
for _, editBox in ipairs(editBoxes) do
S:HandleEditBox(editBox)
editBox:SetTextInsets(1, 1, -1, 1)
end
for _, tab in ipairs(sortTabs) do
tab:StripTextures()
tab:SetNormalTexture([[Interface\Buttons\UI-SortArrow]])
tab:StyleButton()
end
for i = 1, AuctionFrame.numTabs do
local tab = _G["AuctionFrameTab"..i]
S:HandleTab(tab)
if i == 1 then
tab:ClearAllPoints()
tab:Point("BOTTOMLEFT", AuctionFrame, "BOTTOMLEFT", 12, -30)
tab.SetPoint = E.noop
end
end
AuctionFrameTab2:Point("TOPLEFT", AuctionFrameTab1, "TOPRIGHT", -15, 0)
AuctionFrameTab3:Point("TOPLEFT", AuctionFrameTab2, "TOPRIGHT", -15, 0)
for i = 1, NUM_FILTERS_TO_DISPLAY do
local tab = _G["AuctionFilterButton"..i]
tab:StripTextures()
tab:SetHighlightTexture(E.Media.Textures.Highlight)
tab:GetHighlightTexture():SetInside()
tab:GetHighlightTexture():SetAlpha(0.35)
end
S:HandleCloseButton(AuctionFrameCloseButton, AuctionFrame.backdrop)
AuctionFrameMoneyFrame:Point("BOTTOMRIGHT", AuctionFrame, "BOTTOMLEFT", 181, 11)
-- Browse Frame
BrowseTitle:ClearAllPoints()
BrowseTitle:Point("TOP", AuctionFrame, "TOP", 0, -5)
BrowseScrollFrame:StripTextures()
BrowseFilterScrollFrame:StripTextures()
S:HandleScrollBar(BrowseFilterScrollFrameScrollBar)
BrowseFilterScrollFrameScrollBar:Point("TOPLEFT", BrowseFilterScrollFrame, "TOPRIGHT", 5, -19)
BrowseFilterScrollFrameScrollBar:Point("BOTTOMLEFT", BrowseFilterScrollFrame, "BOTTOMRIGHT", 5, 18)
S:HandleScrollBar(BrowseScrollFrameScrollBar)
BrowseScrollFrameScrollBar:ClearAllPoints()
BrowseScrollFrameScrollBar:Point("TOPRIGHT", BrowseScrollFrame, "TOPRIGHT", 25, -19)
BrowseScrollFrameScrollBar:Point("BOTTOMRIGHT", BrowseScrollFrame, "BOTTOMRIGHT", 0, 19)
S:HandleNextPrevButton(BrowsePrevPageButton, nil, nil, true)
BrowsePrevPageButton:Point("TOPLEFT", 640, -50)
BrowsePrevPageButton:Size(32)
BrowsePrevPageButton:SetHitRectInsets(6, 6, 6, 6)
S:HandleNextPrevButton(BrowseNextPageButton, nil, nil, true)
BrowseNextPageButton:Point("TOPRIGHT", 60, -50)
BrowseNextPageButton:Size(32)
BrowseNextPageButton:SetHitRectInsets(6, 6, 6, 6)
BrowseCloseButton:Point("BOTTOMRIGHT", 66, 6)
BrowseBuyoutButton:Point("RIGHT", BrowseCloseButton, "LEFT", -4, 0)
BrowseBidButton:Point("RIGHT", BrowseBuyoutButton, "LEFT", -4, 0)
BrowseResetButton:Point("TOPLEFT", 20, -74)
BrowseSearchButton:Point("TOPRIGHT", 10, -30)
BrowseNameText:Point("TOPLEFT", 18, -30)
BrowseName:Point("TOPLEFT", BrowseNameText, "BOTTOMLEFT", 3, -3)
BrowseName:Size(140, 18)
BrowseLevelText:Point("BOTTOMLEFT", AuctionFrameBrowse, "TOPLEFT", 200, -40)
BrowseMaxLevel:Point("LEFT", BrowseMinLevel, "RIGHT", 8, 0)
BrowseBidText:Point("RIGHT", BrowseBidPrice, "LEFT", -11, 0)
BrowseBidPrice:Point("BOTTOM", 25, 10)
-- Bid Frame
BidTitle:ClearAllPoints()
BidTitle:Point("TOP", AuctionFrame, "TOP", 0, -5)
BidScrollFrame:StripTextures()
BidBidText:ClearAllPoints()
BidBidText:Point("RIGHT", BidBidButton, "LEFT", -270, 2)
BidCloseButton:Point("BOTTOMRIGHT", 66, 6)
BidBuyoutButton:Point("RIGHT", BidCloseButton, "LEFT", -4, 0)
BidBidButton:Point("RIGHT", BidBuyoutButton, "LEFT", -4, 0)
BidBidPrice:Point("BOTTOM", 25, 10)
S:HandleScrollBar(BidScrollFrameScrollBar)
BidScrollFrameScrollBar:ClearAllPoints()
BidScrollFrameScrollBar:Point("TOPRIGHT", BidScrollFrame, "TOPRIGHT", 24, -19)
BidScrollFrameScrollBar:Point("BOTTOMRIGHT", BidScrollFrame, "BOTTOMRIGHT", 0, 17)
-- Auctions Frame
AuctionsTitle:ClearAllPoints()
AuctionsTitle:Point("TOP", AuctionFrame, "TOP", 0, -5)
AuctionsScrollFrame:StripTextures()
S:HandleScrollBar(AuctionsScrollFrameScrollBar)
AuctionsScrollFrameScrollBar:ClearAllPoints()
AuctionsScrollFrameScrollBar:Point("TOPRIGHT", AuctionsScrollFrame, "TOPRIGHT", 24, -21)
AuctionsScrollFrameScrollBar:Point("BOTTOMRIGHT", AuctionsScrollFrame, "BOTTOMRIGHT", 0, 19)
AuctionsCloseButton:Point("BOTTOMRIGHT", 66, 6)
AuctionsCancelAuctionButton:Point("RIGHT", AuctionsCloseButton, "LEFT", -4, 0)
AuctionsCreateAuctionButton:Width(181)
AuctionsCreateAuctionButton:Point("BOTTOMLEFT", AuctionFrameAuctions, "BOTTOMLEFT", 26, 39)
AuctionsStackSizeEntry.backdrop:SetAllPoints()
AuctionsNumStacksEntry.backdrop:SetAllPoints()
AuctionsItemButton:StripTextures()
AuctionsItemButton:SetTemplate("Default", true)
AuctionsItemButton:StyleButton()
AuctionsItemButton:HookScript("OnEvent", function(self, event)
local normalTexture = self:GetNormalTexture()
if event == "NEW_AUCTION_UPDATE" and normalTexture then
normalTexture:SetTexCoord(unpack(E.TexCoords))
normalTexture:SetInside()
local _, _, _, quality = GetAuctionSellItemInfo()
if quality then
self:SetBackdropBorderColor(GetItemQualityColor(quality))
else
self:SetBackdropBorderColor(unpack(E.media.bordercolor))
end
else
self:SetBackdropBorderColor(unpack(E.media.bordercolor))
end
end)
S:HandleDropDownBox(BrowseDropDown, 155)
BrowseDropDown:Point("TOPLEFT", BrowseLevelText, "BOTTOMRIGHT", -5, 0)
S:HandleDropDownBox(PriceDropDown)
S:HandleDropDownBox(DurationDropDown)
-- Progress Frame
AuctionProgressFrame:StripTextures()
AuctionProgressFrame:SetTemplate("Transparent")
S:HandleButton(AuctionProgressFrameCancelButton)
AuctionProgressFrameCancelButton:SetHitRectInsets(0, 0, 0, 0)
AuctionProgressFrameCancelButton:GetNormalTexture():SetTexture(E.Media.Textures.Close)
AuctionProgressFrameCancelButton:GetNormalTexture():SetInside()
AuctionProgressFrameCancelButton:Size(28)
AuctionProgressFrameCancelButton:Point("LEFT", AuctionProgressBar, "RIGHT", 8, 0)
AuctionProgressBarIcon.backdrop = CreateFrame("Frame", nil, AuctionProgressBarIcon:GetParent())
AuctionProgressBarIcon.backdrop:SetTemplate("Default")
AuctionProgressBarIcon.backdrop:SetOutside(AuctionProgressBarIcon)
AuctionProgressBarIcon:SetTexCoord(unpack(E.TexCoords))
AuctionProgressBarIcon:SetParent(AuctionProgressBarIcon.backdrop)
AuctionProgressBarText:ClearAllPoints()
AuctionProgressBarText:SetPoint("CENTER")
AuctionProgressBar:StripTextures()
AuctionProgressBar:CreateBackdrop("Default")
AuctionProgressBar:SetStatusBarTexture(E.media.normTex)
AuctionProgressBar:SetStatusBarColor(1, 1, 0)
local frames = {
["Browse"] = 8, -- NUM_BROWSE_TO_DISPLAY
["Auctions"] = 9, -- NUM_AUCTIONS_TO_DISPLAY
["Bid"] = 9 -- NUM_BIDS_TO_DISPLAY
}
for frameName, numButtons in pairs(frames) do
for i = 1, numButtons do
local button = _G[frameName.."Button"..i]
local itemButton = _G[frameName.."Button"..i.."Item"]
local name = _G[frameName.."Button"..i.."Name"]
if button then
button:StripTextures()
local highlight = _G[frameName.."Button"..i.."Highlight"]
highlight:SetTexture(E.Media.Textures.Highlight)
highlight:SetInside()
hooksecurefunc(name, "SetVertexColor", function(_, r, g, b)
highlight:SetVertexColor(r, g, b, 0.35)
end)
end
if itemButton then
itemButton:SetTemplate()
itemButton:StyleButton()
itemButton:GetNormalTexture():SetTexture("")
itemButton:Point("TOPLEFT", 0, -1)
itemButton:Size(34)
local texture = _G[frameName.."Button"..i.."ItemIconTexture"]
texture:SetTexCoord(unpack(E.TexCoords))
texture:SetInside()
hooksecurefunc(name, "SetVertexColor", function(_, r, g, b)
itemButton:SetBackdropBorderColor(r, g, b)
end)
hooksecurefunc(name, "Hide", function()
itemButton:SetBackdropBorderColor(unpack(E.media.bordercolor))
end)
end
end
end
-- Custom Backdrops
for _, frame in ipairs({AuctionFrameBrowse, AuctionFrameAuctions}) do
frame.LeftBackground = CreateFrame("Frame", nil, frame)
frame.LeftBackground:SetTemplate("Transparent")
frame.LeftBackground:SetFrameLevel(frame:GetFrameLevel() - 1)
frame.RightBackground = CreateFrame("Frame", nil, frame)
frame.RightBackground:SetTemplate("Transparent")
frame.RightBackground:SetFrameLevel(frame:GetFrameLevel() - 1)
end
AuctionFrameAuctions.LeftBackground:Point("TOPLEFT", 20, -72)
AuctionFrameAuctions.LeftBackground:Point("BOTTOMRIGHT", -545, 34)
AuctionFrameAuctions.RightBackground:Point("TOPLEFT", AuctionFrameAuctions.LeftBackground, "TOPRIGHT", 3, 0)
AuctionFrameAuctions.RightBackground:Point("BOTTOMRIGHT", AuctionFrame, -8, 34)
AuctionFrameBrowse.LeftBackground:Point("TOPLEFT", 20, -103)
AuctionFrameBrowse.LeftBackground:Point("BOTTOMRIGHT", -575, 34)
AuctionFrameBrowse.RightBackground:Point("TOPLEFT", AuctionFrameBrowse.LeftBackground, "TOPRIGHT", 4, 0)
AuctionFrameBrowse.RightBackground:Point("BOTTOMRIGHT", AuctionFrame, "BOTTOMRIGHT", -8, 34)
AuctionFrameBid.Background = CreateFrame("Frame", nil, AuctionFrameBid)
AuctionFrameBid.Background:SetTemplate("Transparent")
AuctionFrameBid.Background:Point("TOPLEFT", 20, -72)
AuctionFrameBid.Background:Point("BOTTOMRIGHT", 66, 34)
AuctionFrameBid.Background:SetFrameLevel(AuctionFrameBid:GetFrameLevel() - 1)
-- DressUpFrame
AuctionDressUpFrame:StripTextures()
S:HandleCloseButton(AuctionDressUpFrameCloseButton, AuctionDressUpFrame)
AuctionDressUpModel:CreateBackdrop()
AuctionDressUpModel.backdrop:SetOutside(AuctionDressUpModel)
SetAuctionDressUpBackground()
AuctionDressUpBackgroundTop:SetDesaturated(true)
AuctionDressUpBackgroundBot:SetDesaturated(true)
S:HandleRotateButton(AuctionDressUpModelRotateLeftButton)
S:HandleRotateButton(AuctionDressUpModelRotateRightButton)
S:HandleButton(AuctionDressUpFrameResetButton)
AuctionDressUpFrame:SetTemplate("Transparent")
AuctionDressUpFrame:Size(189, 401)
AuctionDressUpFrame:Point("TOPLEFT", AuctionFrame, "TOPRIGHT", -1, 0)
AuctionDressUpModel:Size(171, 365)
AuctionDressUpModel:Point("BOTTOM", AuctionDressUpFrame, "BOTTOM", 0, 9)
AuctionDressUpBackgroundTop:Point("TOPLEFT", AuctionDressUpFrame, "TOPLEFT", 9, -27)
AuctionDressUpModelRotateLeftButton:Point("TOPLEFT", AuctionDressUpFrame, "TOPLEFT", 12, -30)
AuctionDressUpModelRotateRightButton:Point("TOPLEFT", AuctionDressUpModelRotateLeftButton, "TOPRIGHT", 3, 0)
AuctionDressUpFrameResetButton:Point("BOTTOM", AuctionDressUpModel, "BOTTOM", 0, 7)
AuctionDressUpFrame:SetScript("OnShow", function()
S:SetUIPanelWindowInfo(AuctionFrame, "width", nil, 189)
PlaySound("igCharacterInfoOpen")
end)
AuctionDressUpFrame:SetScript("OnHide", function()
S:SetUIPanelWindowInfo(AuctionFrame, "width", nil, 1)
PlaySound("igCharacterInfoClose")
end)
end)
+75
View File
@@ -0,0 +1,75 @@
local E, L, V, P, G = unpack(ElvUI) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
--WoW API / Variables
S:AddCallbackForAddon("Blizzard_BattlefieldMinimap", "Skin_Blizzard_BattlefieldMinimap", function()
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.bgmap then return end
BattlefieldMinimapCorner:Kill()
BattlefieldMinimapBackground:Kill()
BattlefieldMinimapTab:Kill()
BattlefieldMinimap:SetClampedToScreen(true)
BattlefieldMinimap:SetFrameStrata("LOW")
BattlefieldMinimap:CreateBackdrop("Default")
BattlefieldMinimap.backdrop:Point("BOTTOMRIGHT", E.Border - E:Scale(6), -(E.Border - E:Scale(4)))
S:SetBackdropHitRect(BattlefieldMinimap, nil, true)
S:HandleCloseButton(BattlefieldMinimapCloseButton, BattlefieldMinimap.backdrop)
BattlefieldMinimapCloseButton:SetFrameLevel(BattlefieldMinimap:GetFrameLevel() + 5)
BattlefieldMinimap:EnableMouse(true)
BattlefieldMinimap:SetMovable(true)
BattlefieldMinimap:SetScript("OnMouseUp", function(self, btn)
if btn == "LeftButton" then
if BattlefieldMinimapTab._moved then
BattlefieldMinimapTab:StopMovingOrSizing()
BattlefieldMinimapTab._moved = nil
end
elseif btn == "RightButton" then
ToggleDropDownMenu(1, nil, BattlefieldMinimapTabDropDown, self:GetName(), 0, -4)
end
end)
BattlefieldMinimap:SetScript("OnMouseDown", function(_, btn)
if btn == "LeftButton" then
if BattlefieldMinimapOptions and BattlefieldMinimapOptions.locked then return end
BattlefieldMinimapTab._moved = true
BattlefieldMinimapTab:StartMoving()
end
end)
hooksecurefunc("BattlefieldMinimap_UpdateOpacity", function()
BattlefieldMinimap.backdrop:SetAlpha(1.0 - BattlefieldMinimapOptions.opacity)
end)
local oldAlpha
BattlefieldMinimap:HookScript("OnEnter", function()
oldAlpha = BattlefieldMinimapOptions.opacity or 0
BattlefieldMinimap_UpdateOpacity(0)
end)
BattlefieldMinimap:HookScript("OnLeave", function()
if oldAlpha then
BattlefieldMinimap_UpdateOpacity(oldAlpha)
oldAlpha = nil
end
end)
BattlefieldMinimapCloseButton:HookScript("OnEnter", function()
oldAlpha = BattlefieldMinimapOptions.opacity or 0
BattlefieldMinimap_UpdateOpacity(0)
end)
BattlefieldMinimapCloseButton:HookScript("OnLeave", function()
if oldAlpha then
BattlefieldMinimap_UpdateOpacity(oldAlpha)
oldAlpha = nil
end
end)
end)
+101
View File
@@ -0,0 +1,101 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
local format, split = string.format, string.split
--WoW API / Variables
local FauxScrollFrame_GetOffset = FauxScrollFrame_GetOffset
local GetBattlefieldScore = GetBattlefieldScore
local IsActiveBattlefieldArena = IsActiveBattlefieldArena
S:AddCallback("Skin_WorldStateScore", function()
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.bgscore then return end
WorldStateScoreFrame:StripTextures()
WorldStateScoreFrame:CreateBackdrop("Transparent")
WorldStateScoreFrame.backdrop:Point("TOPLEFT", 10, -15)
WorldStateScoreFrame.backdrop:Point("BOTTOMRIGHT", -113, 67)
WorldStateScoreFrame:EnableMouse(true)
S:SetBackdropHitRect(WorldStateScoreFrame)
S:HandleCloseButton(WorldStateScoreFrameCloseButton, WorldStateScoreFrame.backdrop)
WorldStateScoreScrollFrame:StripTextures()
S:HandleScrollBar(WorldStateScoreScrollFrameScrollBar)
WorldStateScoreFrameKB:StyleButton()
WorldStateScoreFrameDeaths:StyleButton()
WorldStateScoreFrameHK:StyleButton()
WorldStateScoreFrameDamageDone:StyleButton()
WorldStateScoreFrameHealingDone:StyleButton()
WorldStateScoreFrameHonorGained:StyleButton()
WorldStateScoreFrameName:StyleButton()
WorldStateScoreFrameClass:StyleButton()
WorldStateScoreFrameTeam:StyleButton()
-- WorldStateScoreFrameRatingChange:StyleButton()
S:HandleButton(WorldStateScoreFrameLeaveButton)
for i = 1, 3 do
S:HandleTab(_G["WorldStateScoreFrameTab"..i])
_G["WorldStateScoreFrameTab"..i.."Text"]:Point("CENTER", 0, 2)
end
WorldStateScoreFrameTab2:Point("LEFT", WorldStateScoreFrameTab1, "RIGHT", -15, 0)
WorldStateScoreFrameTab3:Point("LEFT", WorldStateScoreFrameTab2, "RIGHT", -15, 0)
WorldStateScoreScrollFrameScrollBar:Point("TOPLEFT", WorldStateScoreScrollFrame, "TOPRIGHT", 8, -21)
WorldStateScoreScrollFrameScrollBar:Point("BOTTOMLEFT", WorldStateScoreScrollFrame, "BOTTOMRIGHT", 8, 38)
for i = 1, 5 do
_G["WorldStateScoreColumn"..i]:StyleButton()
end
local myName = format("> %s <", E.myname)
hooksecurefunc("WorldStateScoreFrame_Update", function()
local inArena = IsActiveBattlefieldArena()
local offset = FauxScrollFrame_GetOffset(WorldStateScoreScrollFrame)
local _, name, faction, classToken, realm, classTextColor, nameText
for i = 1, MAX_WORLDSTATE_SCORE_BUTTONS do
name, _, _, _, _, faction, _, _, _, classToken = GetBattlefieldScore(offset + i)
if name then
name, realm = split("-", name, 2)
if name == E.myname then
name = myName
end
if realm then
local color
if inArena then
if faction == 1 then
color = "|cffffd100"
else
color = "|cff19ff19"
end
else
if faction == 1 then
color = "|cff00adf0"
else
color = "|cffff1919"
end
end
name = format("%s|cffffffff - |r%s%s|r", name, color, realm)
end
classTextColor = E.media.herocolor
nameText = _G["WorldStateScoreButton"..i.."NameText"]
nameText:SetText(name)
nameText:SetTextColor(classTextColor.r, classTextColor.g, classTextColor.b)
end
end
end)
end)
+295
View File
@@ -0,0 +1,295 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
local _G = _G
local select = select
local unpack = unpack
--WoW API / Variables
local ContainerIDToInventoryID = ContainerIDToInventoryID
local GetContainerItemLink = GetContainerItemLink
local GetContainerItemQuestInfo = GetContainerItemQuestInfo
local GetContainerNumFreeSlots = GetContainerNumFreeSlots
local GetInventoryItemLink = GetInventoryItemLink
local GetItemInfo = GetItemInfo
local GetItemQualityColor = GetItemQualityColor
local GetInventoryItemID = GetInventoryItemID
local BANK_CONTAINER = BANK_CONTAINER
S:AddCallback("Skin_Bags", function()
if E.private.bags.enable then return end
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.bags then return end
local professionColors = {
[0x0001] = {E.db.bags.colors.profession.quiver.r, E.db.bags.colors.profession.quiver.g, E.db.bags.colors.profession.quiver.b},
[0x0002] = {E.db.bags.colors.profession.ammoPouch.r, E.db.bags.colors.profession.ammoPouch.g, E.db.bags.colors.profession.ammoPouch.b},
[0x0004] = {E.db.bags.colors.profession.soulBag.r, E.db.bags.colors.profession.soulBag.g, E.db.bags.colors.profession.soulBag.b},
[0x0008] = {E.db.bags.colors.profession.leatherworking.r, E.db.bags.colors.profession.leatherworking.g, E.db.bags.colors.profession.leatherworking.b},
[0x0010] = {E.db.bags.colors.profession.inscription.r, E.db.bags.colors.profession.inscription.g, E.db.bags.colors.profession.inscription.b},
[0x0020] = {E.db.bags.colors.profession.herbs.r, E.db.bags.colors.profession.herbs.g, E.db.bags.colors.profession.herbs.b},
[0x0040] = {E.db.bags.colors.profession.enchanting.r, E.db.bags.colors.profession.enchanting.g, E.db.bags.colors.profession.enchanting.b},
[0x0080] = {E.db.bags.colors.profession.engineering.r, E.db.bags.colors.profession.engineering.g, E.db.bags.colors.profession.engineering.b},
[0x0200] = {E.db.bags.colors.profession.gems.r, E.db.bags.colors.profession.gems.g, E.db.bags.colors.profession.gems.b},
[0x0400] = {E.db.bags.colors.profession.mining.r, E.db.bags.colors.profession.mining.g, E.db.bags.colors.profession.mining.b},
}
local questColors = {
["questStarter"] = {E.db.bags.colors.items.questStarter.r, E.db.bags.colors.items.questStarter.g, E.db.bags.colors.items.questStarter.b},
["questItem"] = {E.db.bags.colors.items.questItem.r, E.db.bags.colors.items.questItem.g, E.db.bags.colors.items.questItem.b}
}
-- ContainerFrame
for i = 1, NUM_CONTAINER_FRAMES do
local frame = _G["ContainerFrame"..i]
local closeButton = _G["ContainerFrame"..i.."CloseButton"]
frame:StripTextures(true)
frame:CreateBackdrop("Transparent")
frame.backdrop:Point("TOPLEFT", 9, -4)
frame.backdrop:Point("BOTTOMRIGHT", -4, 1)
S:HookScript(frame, "OnShow", function(self)
S:SetBackdropHitRect(self)
S:Unhook(self, "OnShow")
end)
S:HandleCloseButton(closeButton, frame.backdrop)
for j = 1, MAX_CONTAINER_ITEMS do
local item = _G["ContainerFrame"..i.."Item"..j]
local icon = _G["ContainerFrame"..i.."Item"..j.."IconTexture"]
local questIcon = _G["ContainerFrame"..i.."Item"..j.."IconQuestTexture"]
local cooldown = _G["ContainerFrame"..i.."Item"..j.."Cooldown"]
item:SetNormalTexture(nil)
item:SetTemplate("Default", true)
item:StyleButton()
icon:SetInside()
icon:SetTexCoord(unpack(E.TexCoords))
questIcon:SetTexture(E.Media.Textures.BagQuestIcon)
questIcon.SetTexture = E.noop
questIcon:SetTexCoord(0, 1, 0, 1)
questIcon:SetInside()
cooldown.CooldownOverride = "bags"
E:RegisterCooldown(cooldown)
end
end
BackpackTokenFrame:StripTextures()
for i = 1, MAX_WATCHED_TOKENS do
local token = _G["BackpackTokenFrameToken"..i]
token:CreateBackdrop("Default")
token.backdrop:SetOutside(token.icon)
token.icon:SetTexCoord(unpack(E.TexCoords))
token.icon:Point("LEFT", token.count, "RIGHT", 2, 0)
token.icon:Size(16)
end
local function setBagIcon(frame, texture)
if not frame.BagIcon then
local portraitButton = _G[frame:GetName().."PortraitButton"]
portraitButton:CreateBackdrop()
portraitButton:Size(32)
portraitButton:Point("TOPLEFT", 12, -7)
portraitButton:StyleButton(nil, true)
portraitButton.hover:SetAllPoints()
frame.BagIcon = portraitButton:CreateTexture()
frame.BagIcon:SetTexCoord(unpack(E.TexCoords))
frame.BagIcon:SetAllPoints()
end
frame.BagIcon:SetTexture(texture)
end
local bagIconCache = {
[-2] = "Interface\\ContainerFrame\\KeyRing-Bag-Icon",
[0] = "Interface\\Buttons\\Button-Backpack-Up"
}
hooksecurefunc("ContainerFrame_GenerateFrame", function(frame)
local id = frame:GetID()
if id > 0 then
local itemID = GetInventoryItemID("player", ContainerIDToInventoryID(id))
if not bagIconCache[itemID] then
bagIconCache[itemID] = select(10, GetItemInfo(itemID))
end
setBagIcon(frame, bagIconCache[itemID])
else
setBagIcon(frame, bagIconCache[id])
end
end)
hooksecurefunc("ContainerFrame_Update", function(frame)
local frameName = frame:GetName()
local id = frame:GetID()
local _, bagType = GetContainerNumFreeSlots(id)
local item, questIcon, link
for i = 1, frame.size do
item = _G[frameName.."Item"..i]
questIcon = _G[frameName.."Item"..i.."IconQuestTexture"]
link = GetContainerItemLink(id, item:GetID())
questIcon:Hide()
if professionColors[bagType] then
item:SetBackdropBorderColor(unpack(professionColors[bagType]))
item.ignoreBorderColors = true
elseif link then
local isQuestItem, questId, isActive = GetContainerItemQuestInfo(id, item:GetID())
local _, _, quality = GetItemInfo(link)
if questId and not isActive then
item:SetBackdropBorderColor(unpack(questColors.questStarter))
item.ignoreBorderColors = true
questIcon:Show()
elseif questId or isQuestItem then
item:SetBackdropBorderColor(unpack(questColors.questItem))
item.ignoreBorderColors = true
elseif quality then
item:SetBackdropBorderColor(GetItemQualityColor(quality))
item.ignoreBorderColors = true
else
item:SetBackdropBorderColor(unpack(E.media.bordercolor))
item.ignoreBorderColors = nil
end
else
item:SetBackdropBorderColor(unpack(E.media.bordercolor))
item.ignoreBorderColors = nil
end
end
end)
-- BankFrame
BankFrame:StripTextures(true)
BankFrame:CreateBackdrop("Transparent")
BankFrame.backdrop:Point("TOPLEFT", 11, -12)
BankFrame.backdrop:Point("BOTTOMRIGHT", -26, 76)
S:SetBackdropHitRect(BankFrame)
S:HandleCloseButton(BankCloseButton)
BankFrameItem1:Point("TOPLEFT", 39, -73)
for i = 1, NUM_BANKGENERIC_SLOTS do
local button = _G["BankFrameItem"..i]
local icon = _G["BankFrameItem"..i.."IconTexture"]
local quest = _G["BankFrameItem"..i.."IconQuestTexture"]
local cooldown = _G["BankFrameItem"..i.."Cooldown"]
button:SetNormalTexture(nil)
button:SetTemplate("Default", true)
button:StyleButton()
icon:SetInside()
icon:SetTexCoord(unpack(E.TexCoords))
quest:SetTexture(E.Media.Textures.BagQuestIcon)
quest.SetTexture = E.noop
quest:SetTexCoord(0, 1, 0, 1)
quest:SetInside()
cooldown.CooldownOverride = "bags"
E:RegisterCooldown(cooldown)
end
BankFrame.itemBackdrop = CreateFrame("Frame", "BankFrameItemBackdrop", BankFrame)
BankFrame.itemBackdrop:SetTemplate("Default")
BankFrame.itemBackdrop:SetOutside(BankFrameItem1, 6, 6, BankFrameItem28)
BankFrame.itemBackdrop:SetFrameLevel(BankFrame:GetFrameLevel())
for i = 1, NUM_BANKBAGSLOTS do
local button = _G["BankFrameBag"..i]
local icon = _G["BankFrameBag"..i.."IconTexture"]
local highlight = _G["BankFrameBag"..i.."HighlightFrameTexture"]
button:SetNormalTexture(nil)
button:SetTemplate("Default", true)
button:StyleButton()
icon:SetInside()
icon:SetTexCoord(unpack(E.TexCoords))
highlight:SetInside()
highlight:SetTexture(unpack(E.media.rgbvaluecolor), 0.3)
end
BankFrame.bagBackdrop = CreateFrame("Frame", "BankFrameBagBackdrop", BankFrame)
BankFrame.bagBackdrop:SetTemplate("Default")
BankFrame.bagBackdrop:SetOutside(BankFrameBag1, 6, 6, BankFrameBag7)
BankFrame.bagBackdrop:SetFrameLevel(BankFrame:GetFrameLevel())
S:HandleButton(BankFramePurchaseButton)
hooksecurefunc("BankFrameItemButton_Update", function(button)
local id = button:GetID()
if button.isBag then
local link = GetInventoryItemLink("player", ContainerIDToInventoryID(id))
if link then
local quality = select(3, GetItemInfo(link))
if quality then
button:SetBackdropBorderColor(GetItemQualityColor(quality))
button.ignoreBorderColors = true
else
button:SetBackdropBorderColor(unpack(E.media.bordercolor))
button.ignoreBorderColors = nil
end
else
button:SetBackdropBorderColor(unpack(E.media.bordercolor))
button.ignoreBorderColors = nil
end
else
local link = GetContainerItemLink(BANK_CONTAINER, id)
local questTexture = _G[button:GetName().."IconQuestTexture"]
if questTexture then
questTexture:Hide()
end
if link then
local isQuestItem, questId, isActive = GetContainerItemQuestInfo(BANK_CONTAINER, id)
if questId and not isActive then
button:SetBackdropBorderColor(unpack(questColors.questStarter))
button.ignoreBorderColors = true
if questTexture then
questTexture:Show()
end
elseif questId or isQuestItem then
button:SetBackdropBorderColor(unpack(questColors.questItem))
button.ignoreBorderColors = true
else
local quality = select(3, GetItemInfo(link))
if quality then
button:SetBackdropBorderColor(GetItemQualityColor(quality))
button.ignoreBorderColors = true
else
button:SetBackdropBorderColor(unpack(E.media.bordercolor))
button.ignoreBorderColors = nil
end
end
else
button:SetBackdropBorderColor(unpack(E.media.bordercolor))
button.ignoreBorderColors = nil
end
end
end)
end)
+29
View File
@@ -0,0 +1,29 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
--WoW API / Variables
S:AddCallbackForAddon("Blizzard_BarbershopUI", "Skin_Blizzard_BarbershopUI", function()
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.barber then return end
BarberShopFrame:CreateBackdrop("Transparent")
BarberShopFrame.backdrop:Point("TOPLEFT", 44, -70)
BarberShopFrame.backdrop:Point("BOTTOMRIGHT", -38, 42)
S:SetBackdropHitRect(BarberShopFrame)
BarberShopFrameBackground:Kill()
for i = 1, 4 do
S:HandleNextPrevButton(_G["BarberShopFrameSelector"..i.."Prev"])
S:HandleNextPrevButton(_G["BarberShopFrameSelector"..i.."Next"])
end
BarberShopFrameMoneyFrame:StripTextures()
BarberShopFrameMoneyFrame:CreateBackdrop()
S:HandleButton(BarberShopFrameOkayButton)
S:HandleButton(BarberShopFrameCancelButton)
S:HandleButton(BarberShopFrameResetButton)
end)
+41
View File
@@ -0,0 +1,41 @@
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local S = E:GetModule("Skins")
--Lua functions
--WoW API / Variables
S:AddCallbackForAddon("Blizzard_BindingUI", "Skin_Blizzard_BindingUI", function()
if not E.private.skins.blizzard.enable or not E.private.skins.blizzard.binding then return end
KeyBindingFrame:StripTextures()
KeyBindingFrame:CreateBackdrop("Transparent")
KeyBindingFrame.backdrop:Point("TOPLEFT", 2, 0)
KeyBindingFrame.backdrop:Point("BOTTOMRIGHT", -42, 13)
S:SetBackdropHitRect(KeyBindingFrame)
local bindingKey1, bindingKey2
for i = 1, KEY_BINDINGS_DISPLAYED do
bindingKey1 = _G["KeyBindingFrameBinding"..i.."Key1Button"]
bindingKey2 = _G["KeyBindingFrameBinding"..i.."Key2Button"]
S:HandleButton(bindingKey1)
S:HandleButton(bindingKey2)
bindingKey2:SetPoint("LEFT", bindingKey1, "RIGHT", 1, 0)
end
S:HandleScrollBar(KeyBindingFrameScrollFrameScrollBar)
S:HandleCheckBox(KeyBindingFrameCharacterButton)
S:HandleButton(KeyBindingFrameDefaultButton)
S:HandleButton(KeyBindingFrameCancelButton)
S:HandleButton(KeyBindingFrameOkayButton)
S:HandleButton(KeyBindingFrameUnbindButton)
KeyBindingFrameScrollFrameScrollBar:Point("TOPLEFT", KeyBindingFrameScrollFrame, "TOPRIGHT", 10, -21)
KeyBindingFrameScrollFrameScrollBar:Point("BOTTOMLEFT", KeyBindingFrameScrollFrame, "BOTTOMRIGHT", 10, 17)
KeyBindingFrameOkayButton:Point("RIGHT", KeyBindingFrameCancelButton, "LEFT", -3, 0)
KeyBindingFrameUnbindButton:Point("RIGHT", KeyBindingFrameOkayButton, "LEFT", -3, 0)
end)

Some files were not shown because too many files have changed in this diff Show More