init
This commit is contained in:
@@ -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)
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="Auras.lua"/>
|
||||
</Ui>
|
||||
@@ -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
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="Chat.lua"/>
|
||||
</Ui>
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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
|
||||
@@ -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"])
|
||||
@@ -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)
|
||||
@@ -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"])
|
||||
@@ -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)
|
||||
@@ -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"])
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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"])
|
||||
@@ -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)
|
||||
@@ -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"])
|
||||
@@ -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)
|
||||
@@ -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>
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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)
|
||||
@@ -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>
|
||||
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="Minimap.lua"/>
|
||||
<Script file="Worldmap.lua"/>
|
||||
</Ui>
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
Reference in New Issue
Block a user