Nameplate Overhaul (#38)
* ElvUI/NamePlates: initial nameplate conversions * More nameplate work * Modules/Cooldowns: various CD fixes, nameplates cant show 'swipe' texture * ElvUI/NamePlates: final nameplate polish * Modules/Misc: add space before interrupted announcement
This commit is contained in:
+15
-1
@@ -1,5 +1,5 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
|
||||
local ElvUF = E.oUF
|
||||
--Lua functions
|
||||
local _G = _G
|
||||
local wipe, date = wipe, date
|
||||
@@ -210,6 +210,20 @@ function E:ExitVehicleShowFrames(_, unit)
|
||||
end
|
||||
end
|
||||
|
||||
function E:GetThreatStatusColor(status, nothreat)
|
||||
local color = ElvUF.colors.threat[status]
|
||||
if color then
|
||||
return color.r, color.g, color.b, color.a or 1
|
||||
elseif nothreat then
|
||||
if status == -1 then -- how or why?
|
||||
return 1, 1, 1, 1
|
||||
else
|
||||
return .7, .7, .7, 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function E:RequestBGInfo()
|
||||
RequestBattlefieldScoreData()
|
||||
end
|
||||
|
||||
+37
-24
@@ -162,11 +162,13 @@ function E:Cooldown_Options(timer, db, parent)
|
||||
end
|
||||
end
|
||||
|
||||
function E:CreateCooldownTimer(parent)
|
||||
local timer = CreateFrame("Frame", parent:GetName() and "$parentTimer" or nil, parent)
|
||||
function E:CreateCooldownTimer(parent, displayParent)
|
||||
local timer = CreateFrame("Frame", parent:GetName() and parent:GetName().."Timer" or nil, displayParent)
|
||||
hooksecurefunc(parent, "Hide", function() timer:Hide() end)
|
||||
hooksecurefunc(parent, "Show", function() timer:Show() end)
|
||||
timer:SetFrameLevel(parent:GetFrameLevel() + 1)
|
||||
timer:Hide()
|
||||
timer:SetAllPoints()
|
||||
timer:SetAllPoints(parent)
|
||||
timer.parent = parent
|
||||
parent.timer = timer
|
||||
|
||||
@@ -199,9 +201,9 @@ function E:CreateCooldownTimer(parent)
|
||||
end
|
||||
|
||||
E.RegisteredCooldowns = {}
|
||||
function E:OnSetCooldown(start, duration)
|
||||
function E:OnSetCooldown(start, duration, recursive)
|
||||
if (not self.forceDisabled) and (start and duration) and (duration > MIN_DURATION) then
|
||||
local timer = self.timer or E:CreateCooldownTimer(self)
|
||||
local timer = self.timer or E:CreateCooldownTimer(self, self:GetParent())
|
||||
timer.start = start
|
||||
timer.duration = duration
|
||||
timer.endTime = start + duration
|
||||
@@ -213,14 +215,22 @@ function E:OnSetCooldown(start, duration)
|
||||
end
|
||||
end
|
||||
|
||||
function E:RegisterCooldown(cooldown)
|
||||
function E:RegisterCooldown(cooldown, module)
|
||||
if not cooldown.isHooked then
|
||||
hooksecurefunc(cooldown, "SetCooldown", E.OnSetCooldown)
|
||||
if cooldown:GetParent().isNamePlate then
|
||||
cooldown.Show = cooldown.Hide
|
||||
cooldown:Hide()
|
||||
end
|
||||
cooldown.isHooked = true
|
||||
end
|
||||
|
||||
if not cooldown.isRegisteredCooldown then
|
||||
local module = (cooldown.CooldownOverride or "global")
|
||||
if module then
|
||||
cooldown.CooldownOverride = module
|
||||
else
|
||||
module = (cooldown.CooldownOverride or "global")
|
||||
end
|
||||
if not E.RegisteredCooldowns[module] then E.RegisteredCooldowns[module] = {} end
|
||||
|
||||
tinsert(E.RegisteredCooldowns[module], cooldown)
|
||||
@@ -228,23 +238,26 @@ function E:RegisterCooldown(cooldown)
|
||||
end
|
||||
end
|
||||
|
||||
function E:GetCooldownColors(db)
|
||||
if not db then db = E.db.cooldown end -- just incase someone calls this without a first arg use the global
|
||||
local c13 = E:RGBToHex(db.hhmmColorIndicator.r, db.hhmmColorIndicator.g, db.hhmmColorIndicator.b) -- color for timers that are soon to expire
|
||||
local c12 = E:RGBToHex(db.mmssColorIndicator.r, db.mmssColorIndicator.g, db.mmssColorIndicator.b) -- color for timers that are soon to expire
|
||||
local c11 = E:RGBToHex(db.expireIndicator.r, db.expireIndicator.g, db.expireIndicator.b) -- color for timers that are soon to expire
|
||||
local c10 = E:RGBToHex(db.secondsIndicator.r, db.secondsIndicator.g, db.secondsIndicator.b) -- color for timers that have seconds remaining
|
||||
local c9 = E:RGBToHex(db.minutesIndicator.r, db.minutesIndicator.g, db.minutesIndicator.b) -- color for timers that have minutes remaining
|
||||
local c8 = E:RGBToHex(db.hoursIndicator.r, db.hoursIndicator.g, db.hoursIndicator.b) -- color for timers that have hours remaining
|
||||
local c7 = E:RGBToHex(db.daysIndicator.r, db.daysIndicator.g, db.daysIndicator.b) -- color for timers that have days remaining
|
||||
local c6 = db.hhmmColor -- HH:MM color
|
||||
local c5 = db.mmssColor -- MM:SS color
|
||||
local c4 = db.expiringColor -- color for timers that are soon to expire
|
||||
local c3 = db.secondsColor -- color for timers that have seconds remaining
|
||||
local c2 = db.minutesColor -- color for timers that have minutes remaining
|
||||
local c1 = db.hoursColor -- color for timers that have hours remaining
|
||||
local c0 = db.daysColor -- color for timers that have days remaining
|
||||
return c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13
|
||||
do
|
||||
local function HEX(db) return E:RGBToHex(db.r, db.g, db.b) end
|
||||
function E:GetCooldownColors(db)
|
||||
if not db then db = E.db.cooldown end -- just incase someone calls this without a first arg use the global
|
||||
return
|
||||
db.daysColor,
|
||||
db.hoursColor,
|
||||
db.minutesColor,
|
||||
db.secondsColor,
|
||||
db.expiringColor,
|
||||
db.mmssColor,
|
||||
db.hhmmColor,
|
||||
HEX(db.daysIndicator),
|
||||
HEX(db.hoursIndicator),
|
||||
HEX(db.minutesIndicator),
|
||||
HEX(db.secondsIndicator),
|
||||
HEX(db.expireIndicator),
|
||||
HEX(db.mmssColorIndicator),
|
||||
HEX(db.hhmmColorIndicator)
|
||||
end
|
||||
end
|
||||
|
||||
function E:UpdateCooldownOverride(module)
|
||||
|
||||
@@ -60,6 +60,7 @@ E.myname = UnitName("player")
|
||||
E.myrealm = GetRealmName()
|
||||
E.mynameRealm = format('%s - %s', E.myname, E.myrealm) -- contains spaces/dashes in realm (for profile keys)
|
||||
E.version = GetAddOnMetadata("ElvUI", "Version")
|
||||
E.versionNum = tonumber(E.version)
|
||||
E.wowpatch, E.wowbuild = GetBuildInfo()
|
||||
E.wowbuild = tonumber(E.wowbuild)
|
||||
E.resolution = GetCVar("gxResolution")
|
||||
@@ -1134,6 +1135,14 @@ function E:DBConversions()
|
||||
if E.private.skins.blizzard.greeting ~= nil then
|
||||
E.private.skins.blizzard.greeting = nil
|
||||
end
|
||||
|
||||
-- VERSION 7.0 -- nameplate overhaul
|
||||
if not E.db.version or E.db.version < 7 then
|
||||
-- wipe nameplates
|
||||
E:CopyTable(self.db.nameplates, P.nameplates)
|
||||
end
|
||||
|
||||
E.db.version = E.versionNum
|
||||
end
|
||||
|
||||
function E:RefreshModulesDB()
|
||||
@@ -1143,6 +1152,37 @@ function E:RefreshModulesDB()
|
||||
UnitFrames.db = self.db.unitframe --new ref
|
||||
end
|
||||
|
||||
do
|
||||
-- Shamelessly taken from AceDB-3.0 and stripped down by Simpy
|
||||
function E: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 E:CopyDefaults(dest[k], v) end
|
||||
elseif rawget(dest, k) == nil then
|
||||
rawset(dest, k, v)
|
||||
end
|
||||
end
|
||||
|
||||
return dest
|
||||
end
|
||||
|
||||
function E:RemoveDefaults(db, defaults)
|
||||
setmetatable(db, nil)
|
||||
|
||||
for k, v in pairs(defaults) do
|
||||
if type(v) == 'table' and type(db[k]) == 'table' then
|
||||
E: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
|
||||
|
||||
return db
|
||||
end
|
||||
end
|
||||
|
||||
function E:Initialize()
|
||||
twipe(self.db)
|
||||
twipe(self.global)
|
||||
|
||||
@@ -8,8 +8,8 @@ local tonumber, type, gsub, pairs, pcall, loadstring = tonumber, type, gsub, pai
|
||||
local len, format, split, strmatch = strlen, format, strsplit, strmatch
|
||||
|
||||
local CreateFrame = CreateFrame
|
||||
local IsInRaid, UnitInRaid = IsInRaid, UnitInRaid
|
||||
local IsInGroup, UnitInParty = IsInGroup, UnitInParty
|
||||
local IsInRaid, UnitInRaid = GenerateClosure(C_Player, C_Player.IsInRaid, C_Player), UnitInRaid
|
||||
local IsInGroup, UnitInParty = GenerateClosure(C_Player, C_Player.IsInGroup, C_Player), UnitInParty
|
||||
-- local LE_PARTY_CATEGORY_HOME = LE_PARTY_CATEGORY_HOME
|
||||
-- local LE_PARTY_CATEGORY_INSTANCE = LE_PARTY_CATEGORY_INSTANCE
|
||||
local ACCEPT, CANCEL, YES, NO = ACCEPT, CANCEL, YES, NO
|
||||
|
||||
+1267
-607
File diff suppressed because it is too large
Load Diff
+25
-7
@@ -1,5 +1,6 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local LSM = E.Libs.LSM
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
--Lua functions
|
||||
local _G = _G
|
||||
@@ -78,7 +79,7 @@ local function SetInside(obj, anchor, xOffset, yOffset, anchor2)
|
||||
obj:Point("BOTTOMRIGHT", anchor2 or anchor, "BOTTOMRIGHT", -xOffset, yOffset)
|
||||
end
|
||||
|
||||
local function SetTemplate(frame, template, glossTex, ignoreUpdates, forcePixelMode, isUnitFrameElement)
|
||||
local function SetTemplate(frame, template, glossTex, ignoreUpdates, forcePixelMode, isUnitFrameElement, isNamePlateElement)
|
||||
GetTemplate(template, isUnitFrameElement)
|
||||
|
||||
frame.template = template or "Default"
|
||||
@@ -86,10 +87,25 @@ local function SetTemplate(frame, template, glossTex, ignoreUpdates, forcePixelM
|
||||
if ignoreUpdates then frame.ignoreUpdates = ignoreUpdates end
|
||||
if forcePixelMode then frame.forcePixelMode = forcePixelMode end
|
||||
if isUnitFrameElement then frame.isUnitFrameElement = isUnitFrameElement end
|
||||
frame.isNamePlateElement = isNamePlateElement
|
||||
|
||||
local bgFile = glossTex and E.media.glossTex or E.media.blankTex
|
||||
|
||||
if template ~= "NoBackdrop" then
|
||||
if isNamePlateElement then
|
||||
local bg = frame:CreateTexture(nil, "BACKGROUND")
|
||||
bg:SetAllPoints()
|
||||
GetTemplate(template, isUnitFrameElement)
|
||||
--bg:SetTexture(bgFile)
|
||||
bg:SetTexture(backdropr, backdropg, backdropb, backdropa)
|
||||
if not frame.ignoreUpdates then
|
||||
if frame.isUnitFrameElement then
|
||||
E.unitFrameElements[frame] = true
|
||||
else
|
||||
E.frames[frame] = true
|
||||
end
|
||||
end
|
||||
return
|
||||
elseif template ~= "NoBackdrop" then
|
||||
frame:SetBackdrop({
|
||||
bgFile = bgFile,
|
||||
edgeFile = E.media.blankTex,
|
||||
@@ -99,7 +115,8 @@ local function SetTemplate(frame, template, glossTex, ignoreUpdates, forcePixelM
|
||||
|
||||
frame:SetBackdropColor(backdropr, backdropg, backdropb, backdropa)
|
||||
|
||||
if not E.PixelMode and not frame.forcePixelMode then
|
||||
local notPixelMode = not isUnitFrameElement and not isNamePlateElement and not E.PixelMode
|
||||
if notPixelMode and not frame.forcePixelMode then
|
||||
if not frame.iborder then
|
||||
local border = CreateFrame("Frame", nil, frame)
|
||||
border:SetInside(frame, E.mult, E.mult)
|
||||
@@ -139,7 +156,7 @@ local function SetTemplate(frame, template, glossTex, ignoreUpdates, forcePixelM
|
||||
end
|
||||
end
|
||||
|
||||
local function CreateBackdrop(frame, template, glossTex, ignoreUpdates, forcePixelMode, isUnitFrameElement)
|
||||
local function CreateBackdrop(frame, template, glossTex, ignoreUpdates, forcePixelMode, isUnitFrameElement, isNamePlateElement)
|
||||
if not template then template = "Default" end
|
||||
|
||||
local parent = (frame.IsObjectType and frame:IsObjectType("Texture") and frame:GetParent()) or frame
|
||||
@@ -147,12 +164,13 @@ local function CreateBackdrop(frame, template, glossTex, ignoreUpdates, forcePix
|
||||
if not frame.backdrop then frame.backdrop = backdrop end
|
||||
|
||||
if frame.forcePixelMode or forcePixelMode then
|
||||
backdrop:SetOutside(frame, E.mult, E.mult)
|
||||
backdrop:SetOutside(frame, E.twoPixelsPlease and 2 or 1, E.twoPixelsPlease and 2 or 1)
|
||||
else
|
||||
backdrop:SetOutside(frame)
|
||||
local border = isNamePlateElement and NP.BORDER or nil
|
||||
backdrop:SetOutside(frame, border, border)
|
||||
end
|
||||
|
||||
backdrop:SetTemplate(template, glossTex, ignoreUpdates, forcePixelMode, isUnitFrameElement)
|
||||
backdrop:SetTemplate(template, glossTex, ignoreUpdates, forcePixelMode, isUnitFrameElement, isNamePlateElement)
|
||||
|
||||
local frameLevel = parent.GetFrameLevel and parent:GetFrameLevel()
|
||||
local frameLevelMinusOne = frameLevel and (frameLevel - 1)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
## Interface: 30300
|
||||
## Author: Elv, Bunny
|
||||
## Version: 6.18
|
||||
## Version: 7.0
|
||||
## Title: |cff1784d1E|r|cffe5e3e3lvUI|r
|
||||
## Notes: User Interface replacement AddOn for World of Warcraft.
|
||||
## SavedVariables: ElvDB, ElvPrivateDB
|
||||
|
||||
+1
-1
@@ -346,7 +346,7 @@ function AddOn:ToggleOptionsUI(msg)
|
||||
if not IsAddOnLoaded("ElvUI_OptionsUI") then noConfig = true end
|
||||
|
||||
-- version check elvui options if it's actually enabled
|
||||
if (not noConfig) and GetAddOnMetadata("ElvUI_OptionsUI", "Version") ~= "1.06" then
|
||||
if (not noConfig) and GetAddOnMetadata("ElvUI_OptionsUI", "Version") ~= "1.10" then
|
||||
self:StaticPopup_Show("CLIENT_UPDATE_REQUEST")
|
||||
end
|
||||
else
|
||||
|
||||
@@ -14,6 +14,10 @@ local hiddenParent = CreateFrame('Frame', nil, UIParent)
|
||||
hiddenParent:SetAllPoints()
|
||||
hiddenParent:Hide()
|
||||
|
||||
local offScreenParent = CreateFrame('Frame', nil, UIParent)
|
||||
offScreenParent:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", 0, -128)
|
||||
offScreenParent:SetFrameLevel(0)
|
||||
|
||||
local function handleFrame(baseName)
|
||||
local frame
|
||||
if(type(baseName) == 'string') then
|
||||
@@ -51,6 +55,34 @@ local function handleFrame(baseName)
|
||||
end
|
||||
end
|
||||
|
||||
function oUF:DisableBlizzardNamePlate(nameplate)
|
||||
-- we have to preserve the base frame since the unit frame will attach to it
|
||||
local blizzElements = {nameplate:GetRegions()}
|
||||
local healthBar, castBar = nameplate:GetChildren()
|
||||
tinsert(blizzElements, healthBar)
|
||||
|
||||
nameplate.blizzHighlight = blizzElements[6]
|
||||
nameplate.HealthBar = healthBar
|
||||
nameplate.CastBar = castBar
|
||||
|
||||
for _, child in ipairs(blizzElements) do
|
||||
child:SetParent(hiddenParent)
|
||||
child:SetAlpha(0)
|
||||
child:Hide()
|
||||
if child.SetTexture then
|
||||
child:SetTexture()
|
||||
elseif child.SetStatusBarTexture then
|
||||
child:SetStatusBarTexture(nil) -- this needs nil
|
||||
end
|
||||
end
|
||||
|
||||
-- cast bar has to be special because we need onhide / onshow to fire still
|
||||
castBar:SetParent(offScreenParent)
|
||||
castBar:SetStatusBarTexture(nil)
|
||||
castBar:SetAlpha(0)
|
||||
castBar:Hide()
|
||||
end
|
||||
|
||||
function oUF:DisableBlizzard(unit)
|
||||
if(not unit) then return end
|
||||
|
||||
|
||||
@@ -31,15 +31,15 @@ local colors = {
|
||||
}
|
||||
|
||||
for classToken, color in next, RAID_CLASS_COLORS do
|
||||
colors.class[classToken] = {color.r, color.g, color.b}
|
||||
colors.class[classToken] = {color.r, color.g, color.b, r = color.r, g = color.g, b = color.b}
|
||||
end
|
||||
|
||||
for debuffType, color in next, DebuffTypeColor do
|
||||
colors.debuff[debuffType] = {color.r, color.g, color.b}
|
||||
colors.debuff[debuffType] = {color.r, color.g, color.b, r = color.r, g = color.g, b = color.b}
|
||||
end
|
||||
|
||||
for eclass, color in next, FACTION_BAR_COLORS do
|
||||
colors.reaction[eclass] = {color.r, color.g, color.b}
|
||||
colors.reaction[eclass] = {color.r, color.g, color.b, r = color.r, g = color.g, b = color.b}
|
||||
end
|
||||
|
||||
for power, color in next, PowerBarColor do
|
||||
@@ -48,10 +48,10 @@ for power, color in next, PowerBarColor do
|
||||
colors.power[power] = {}
|
||||
|
||||
for index, color in next, color do
|
||||
colors.power[power][index] = {color.r, color.g, color.b}
|
||||
colors.power[power][index] = {color.r, color.g, color.b, r = color.r, g = color.g, b = color.b}
|
||||
end
|
||||
else
|
||||
colors.power[power] = {color.r, color.g, color.b, atlas = color.atlas}
|
||||
colors.power[power] = {color.r, color.g, color.b, atlas = color.atlas, r = color.r, g = color.g, b = color.b}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -356,6 +356,13 @@ local function filterIcons(element, unit, filter, limit, isDebuff, offset, dontH
|
||||
end
|
||||
|
||||
local function UpdateAuras(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
|
||||
if(self.unit ~= unit) then return end
|
||||
|
||||
local auras = self.Auras
|
||||
@@ -502,6 +509,12 @@ local function UpdateAuras(self, event, unit)
|
||||
end
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
|
||||
UpdateAuras(self, event, unit)
|
||||
|
||||
@@ -103,6 +103,7 @@ local function resetAttributes(self)
|
||||
self.channeling = nil
|
||||
self.notInterruptible = nil
|
||||
self.spellName = nil -- ElvUI
|
||||
self.spellID = nil
|
||||
end
|
||||
|
||||
-- ElvUI block
|
||||
@@ -113,13 +114,19 @@ end
|
||||
-- end block
|
||||
|
||||
local function CastStart(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
|
||||
local element = self.Castbar
|
||||
local name, _, _, texture, startTime, endTime, isTradeSkill, castID, notInterruptible = UnitCastingInfo(unit)
|
||||
local name, _, _, texture, startTime, endTime, isTradeSkill, castID, notInterruptible, spellID = UnitCastingInfo(unit)
|
||||
event = 'UNIT_SPELLCAST_START'
|
||||
if(not name) then
|
||||
name, _, _, texture, startTime, endTime, isTradeSkill, notInterruptible = UnitChannelInfo(unit)
|
||||
name, _, _, texture, startTime, endTime, isTradeSkill, notInterruptible, spellID = UnitChannelInfo(unit)
|
||||
event = 'UNIT_SPELLCAST_CHANNEL_START'
|
||||
end
|
||||
|
||||
@@ -141,6 +148,7 @@ local function CastStart(self, event, unit)
|
||||
element.notInterruptible = notInterruptible
|
||||
element.holdTime = 0
|
||||
element.castID = castID
|
||||
element.spellID = spellID
|
||||
element.spellName = name -- ElvUI
|
||||
|
||||
if(element.casting) then
|
||||
@@ -205,6 +213,12 @@ local function CastStart(self, event, unit)
|
||||
end
|
||||
|
||||
local function CastUpdate(self, event, unit, _, _, castID)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
|
||||
local element = self.Castbar
|
||||
@@ -258,6 +272,12 @@ local function CastUpdate(self, event, unit, _, _, castID)
|
||||
end
|
||||
|
||||
local function CastStop(self, event, unit, _, _, castID)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
|
||||
local element = self.Castbar
|
||||
@@ -287,6 +307,12 @@ local function CastStop(self, event, unit, _, _, castID)
|
||||
end
|
||||
|
||||
local function CastFail(self, event, unit, _, _, castID)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
|
||||
local element = self.Castbar
|
||||
@@ -324,6 +350,12 @@ local function CastFail(self, event, unit, _, _, castID)
|
||||
end
|
||||
|
||||
local function CastInterruptible(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
|
||||
local element = self.Castbar
|
||||
@@ -408,22 +440,43 @@ local function ForceUpdate(element)
|
||||
return Update(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function NamePlateCastBarOnShow(self)
|
||||
if C_NamePlateManager.IsNamePlateMoving(self) then return end
|
||||
CastStart(self, "UNIT_SPELLCAST_START", self.unit)
|
||||
end
|
||||
|
||||
local function NamePlateCastBarOnHide(self)
|
||||
if C_NamePlateManager.IsNamePlateMoving(self) then return end
|
||||
CastFail(self, "UNIT_SPELLCAST_FAILED", self.unit, nil, nil, self.Castbar.castID)
|
||||
end
|
||||
|
||||
local function NamePlateCastBarOnValueChanged(self)
|
||||
CastUpdate(self, nil, self.unit, nil, nil, self.Castbar.castID)
|
||||
end
|
||||
|
||||
local function Enable(self, unit)
|
||||
local element = self.Castbar
|
||||
if(element and unit and not unit:match('%wtarget$')) then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
|
||||
self:RegisterEvent('UNIT_SPELLCAST_START', CastStart)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_START', CastStart)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_STOP', CastStop)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', CastStop)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_DELAYED', CastUpdate)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', CastUpdate)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_FAILED', CastFail)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_INTERRUPTED', CastFail)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_INTERRUPTIBLE', CastInterruptible)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_NOT_INTERRUPTIBLE', CastInterruptible)
|
||||
if self.isNamePlate then
|
||||
local castBar = self.nameplateAnchor.CastBar
|
||||
castBar:SetScript("OnShow", GenerateClosure(NamePlateCastBarOnShow, self))
|
||||
castBar:SetScript("OnHide", GenerateClosure(NamePlateCastBarOnHide, self))
|
||||
castBar:SetScript("OnValueChanged", GenerateClosure(NamePlateCastBarOnValueChanged, self))
|
||||
else
|
||||
self:RegisterEvent('UNIT_SPELLCAST_START', CastStart)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_START', CastStart)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_STOP', CastStop)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', CastStop)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_DELAYED', CastUpdate)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', CastUpdate)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_FAILED', CastFail)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_INTERRUPTED', CastFail)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_INTERRUPTIBLE', CastInterruptible)
|
||||
self:RegisterEvent('UNIT_SPELLCAST_NOT_INTERRUPTIBLE', CastInterruptible)
|
||||
end
|
||||
|
||||
-- ElvUI block
|
||||
self:RegisterEvent('UNIT_SPELLCAST_SENT', UNIT_SPELLCAST_SENT, true)
|
||||
@@ -454,7 +507,7 @@ local function Enable(self, unit)
|
||||
|
||||
local safeZone = element.SafeZone
|
||||
if(safeZone and safeZone:IsObjectType('Texture') and not safeZone:GetTexture()) then
|
||||
safeZone:SetColorTexture(1, 0, 0)
|
||||
safeZone:SetTexture(1, 0, 0)
|
||||
end
|
||||
|
||||
element:Hide()
|
||||
@@ -468,16 +521,23 @@ local function Disable(self)
|
||||
if(element) then
|
||||
element:Hide()
|
||||
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_START', CastStart)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_START', CastStart)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_DELAYED', CastUpdate)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', CastUpdate)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_STOP', CastStop)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', CastStop)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_FAILED', CastFail)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_INTERRUPTED', CastFail)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_INTERRUPTIBLE', CastInterruptible)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_NOT_INTERRUPTIBLE', CastInterruptible)
|
||||
if self.isNamePlate then
|
||||
local castBar = self.nameplateAnchor.CastBar
|
||||
castBar:SetScript("OnShow", nil)
|
||||
castBar:SetScript("OnHide", nil)
|
||||
castBar:SetScript("OnValueChanged", nil)
|
||||
else
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_START', CastStart)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_START', CastStart)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_DELAYED', CastUpdate)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', CastUpdate)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_STOP', CastStop)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', CastStop)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_FAILED', CastFail)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_INTERRUPTED', CastFail)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_INTERRUPTIBLE', CastInterruptible)
|
||||
self:UnregisterEvent('UNIT_SPELLCAST_NOT_INTERRUPTIBLE', CastInterruptible)
|
||||
end
|
||||
|
||||
element:SetScript('OnUpdate', nil)
|
||||
|
||||
@@ -501,6 +561,12 @@ end)
|
||||
oUF:AddElement('Castbar', Update, Enable, Disable)
|
||||
|
||||
function CastingBarFrame_SetUnit(self, unit, showTradeSkills, showShield)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then
|
||||
self.unit = unit
|
||||
self.showTradeSkills = showTradeSkills
|
||||
|
||||
@@ -37,6 +37,12 @@ local UnitHasVehicleUI = UnitHasVehicleUI
|
||||
local MAX_COMBO_POINTS = MAX_COMBO_POINTS
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if self.isNamePlate then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(unit == 'pet') then return end
|
||||
|
||||
local element = self.ComboPoints
|
||||
|
||||
@@ -30,6 +30,12 @@ local GetPetHappiness = GetPetHappiness
|
||||
local HasPetUI = HasPetUI
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(not unit or self.unit ~= unit) then return end
|
||||
|
||||
local element = self.HappinessIndicator
|
||||
|
||||
@@ -86,6 +86,12 @@ local oUF = ns.oUF
|
||||
local Private = oUF.Private
|
||||
|
||||
local function UpdateColor(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(not unit or self.unit ~= unit) then return end
|
||||
local element = self.Health
|
||||
|
||||
@@ -146,7 +152,14 @@ local function ColorPath(self, ...)
|
||||
end
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(not unit or self.unit ~= unit) then return end
|
||||
|
||||
local element = self.Health
|
||||
|
||||
--[[ Callback: Health:PreUpdate(unit)
|
||||
@@ -200,7 +213,6 @@ local function Path(self, ...)
|
||||
* unit - the unit accompanying the event (string)
|
||||
--]]
|
||||
(self.Health.Override or Update) (self, ...);
|
||||
|
||||
ColorPath(self, ...)
|
||||
end
|
||||
|
||||
@@ -242,6 +254,23 @@ local function SetColorHappiness(element, state)
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Health:SetColorSelection(state, isForced)
|
||||
Used to toggle coloring by the unit's selection.
|
||||
* self - the Health element
|
||||
* state - the desired state (boolean)
|
||||
* isForced - forces the event update even if the state wasn't changed (boolean)
|
||||
--]]
|
||||
local function SetColorSelection(element, state, isForced)
|
||||
if(element.colorSelection ~= state or isForced) then
|
||||
element.colorSelection = state
|
||||
if(state) then
|
||||
element.__owner:RegisterEvent('UNIT_FLAGS', ColorPath)
|
||||
else
|
||||
element.__owner:UnregisterEvent('UNIT_FLAGS', ColorPath)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Health:SetColorTapping(state)
|
||||
Used to toggle coloring if the unit isn't tapped by the player.
|
||||
|
||||
@@ -320,6 +349,7 @@ local function Enable(self, unit)
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
element.SetColorDisconnected = SetColorDisconnected
|
||||
element.SetColorSelection = SetColorSelection
|
||||
element.SetColorHappiness = SetColorHappiness
|
||||
element.SetColorTapping = SetColorTapping
|
||||
element.SetColorThreat = SetColorThreat
|
||||
@@ -354,6 +384,16 @@ local function Enable(self, unit)
|
||||
|
||||
self:RegisterEvent('UNIT_MAXHEALTH', Path)
|
||||
|
||||
if self.isNamePlate then
|
||||
local healthBar = self.nameplateAnchor.HealthBar
|
||||
healthBar:SetScript("OnValueChanged", function()
|
||||
Path(self, "UNIT_HEALTH", self.unit)
|
||||
end)
|
||||
healthBar:SetScript("OnMinMaxChanged", function()
|
||||
Path(self, "UNIT_MAXHEALTH", self.unit)
|
||||
end)
|
||||
end
|
||||
|
||||
if(element:IsObjectType('StatusBar') and not element:GetStatusBarTexture()) then
|
||||
element:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
|
||||
end
|
||||
|
||||
@@ -43,6 +43,12 @@ local UnitIsUnit = UnitIsUnit
|
||||
local UnitIsVisible = UnitIsVisible
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if self.isNamePlate then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(not unit or not UnitIsUnit(self.unit, unit)) then return end
|
||||
|
||||
local element = self.Portrait
|
||||
|
||||
@@ -100,6 +100,12 @@ local UnitPowerType = UnitPowerType
|
||||
local UnitReaction = UnitReaction
|
||||
|
||||
local function UpdateColor(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
local element = self.Power
|
||||
|
||||
@@ -170,6 +176,12 @@ local function ColorPath(self, ...)
|
||||
end
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
local element = self.Power
|
||||
|
||||
|
||||
@@ -17,6 +17,12 @@ local UnitPowerType = UnitPowerType
|
||||
local UnitReaction = UnitReaction
|
||||
|
||||
local function UpdateColor(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
local element = self.Energy
|
||||
|
||||
@@ -84,6 +90,12 @@ local function ColorPath(self, ...)
|
||||
end
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
local element = self.Energy
|
||||
|
||||
|
||||
@@ -17,6 +17,12 @@ local UnitPowerType = UnitPowerType
|
||||
local UnitReaction = UnitReaction
|
||||
|
||||
local function UpdateColor(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
local element = self.Rage
|
||||
|
||||
@@ -84,6 +90,12 @@ local function ColorPath(self, ...)
|
||||
end
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
local element = self.Rage
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@ local FFA_ICON = [[Interface\TargetingFrame\UI-PVP-FFA]]
|
||||
local FACTION_ICON = [[Interface\TargetingFrame\UI-PVP-]]
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(unit ~= self.unit) then return end
|
||||
|
||||
local element = self.PvPIndicator
|
||||
|
||||
@@ -36,7 +36,14 @@ local UnitExists = UnitExists
|
||||
local UnitThreatSituation = UnitThreatSituation
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if(not unit or self.unit ~= unit) then return end
|
||||
if not unit then return end
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if(self.unit ~= unit) then return end
|
||||
|
||||
local element = self.ThreatIndicator
|
||||
--[[ Callback: ThreatIndicator:PreUpdate(unit)
|
||||
|
||||
+114
-1
@@ -311,6 +311,10 @@ local function togglemenu(self, unit)
|
||||
end
|
||||
|
||||
local function onShow(self)
|
||||
if self.isNamePlate then
|
||||
local nameplate = C_NamePlate.GetNamePlateForUnit(self.unit)
|
||||
if nameplate and C_NamePlateManager.IsNamePlateMoving(nameplate.unitFrame) then return end
|
||||
end
|
||||
if(not updateActiveUnit(self, 'OnShow')) then
|
||||
return self:UpdateAllElements('OnShow')
|
||||
end
|
||||
@@ -417,7 +421,6 @@ local function initObject(unit, style, styleFunc, header, ...)
|
||||
activeElements[object] = {} -- ElvUI: styleFunc on headers break before this is set when they try to enable elements before it's set.
|
||||
|
||||
Private.UpdateUnits(object, objectUnit)
|
||||
|
||||
styleFunc(object, objectUnit, not header)
|
||||
|
||||
object:HookScript('OnAttributeChanged', onAttributeChanged)
|
||||
@@ -761,6 +764,116 @@ function oUF:Spawn(unit, overrideName)
|
||||
return object
|
||||
end
|
||||
|
||||
--[[ oUF:SpawnNamePlates(prefix, callback, variables)
|
||||
Used to create nameplates and apply the currently active style to them.
|
||||
|
||||
* self - the global oUF object
|
||||
* prefix - prefix for the global name of the nameplate. Defaults to an auto-generated prefix (string?)
|
||||
* callback - function to be called after a nameplate unit or the player's target has changed. The arguments passed to
|
||||
the callback are the updated nameplate, if any, the event that triggered the update, and the new unit
|
||||
(function?)
|
||||
* variables - list of console variable-value pairs to be set when the player logs in (table?)
|
||||
--]]
|
||||
local nameplateUnitToFrame = {}
|
||||
function oUF:SpawnNamePlates(namePrefix, nameplateCallback, nameplateCVars)
|
||||
argcheck(nameplateCallback, 3, 'function', 'nil')
|
||||
argcheck(nameplateCVars, 4, 'table', 'nil')
|
||||
if(not style) then return error('Unable to create frame. No styles have been registered.') end
|
||||
if(_G.oUF_NamePlateDriver) then return error('oUF nameplate driver has already been initialized.') end
|
||||
|
||||
local style = style
|
||||
local prefix = namePrefix or generateName()
|
||||
|
||||
local eventHandler = CreateFrame('Frame', 'oUF_NamePlateDriver')
|
||||
eventHandler:RegisterEvent('NAME_PLATE_UNIT_ADDED')
|
||||
eventHandler:RegisterEvent('NAME_PLATE_UNIT_REMOVED')
|
||||
eventHandler:RegisterEvent('PLAYER_TARGET_CHANGED')
|
||||
eventHandler:RegisterEvent('UNIT_FACTION')
|
||||
eventHandler:RegisterEvent('UNIT_FLAGS')
|
||||
|
||||
if(IsLoggedIn()) then
|
||||
if(nameplateCVars) then
|
||||
for cvar, value in next, nameplateCVars do
|
||||
SetCVar(cvar, value)
|
||||
end
|
||||
end
|
||||
else
|
||||
eventHandler:RegisterEvent('PLAYER_LOGIN')
|
||||
end
|
||||
|
||||
C_NamePlateManager.SetEnableResizeNamePlates(true)
|
||||
|
||||
eventHandler:SetScript('OnEvent', function(_, event, unit)
|
||||
if(event == 'PLAYER_LOGIN') then
|
||||
if(nameplateCVars) then
|
||||
for cvar, value in next, nameplateCVars do
|
||||
SetCVar(cvar, value)
|
||||
end
|
||||
end
|
||||
elseif(event == 'PLAYER_TARGET_CHANGED') then
|
||||
local nameplate = C_NamePlate.GetNamePlateForUnit('target')
|
||||
if(nameplateCallback) then
|
||||
nameplateCallback(nameplate and nameplate.unitFrame, event, 'target')
|
||||
end
|
||||
|
||||
-- UAE is called after the callback to reduce the number of
|
||||
-- ForceUpdate calls layout devs have to do themselves
|
||||
if(nameplate) then
|
||||
nameplate.unitFrame:UpdateAllElements(event)
|
||||
end
|
||||
elseif(event == 'UNIT_FACTION' and unit) then
|
||||
local nameplate = C_NamePlate.GetNamePlateForUnit(unit)
|
||||
if(not nameplate) then return end
|
||||
|
||||
if(nameplateCallback) then
|
||||
nameplateCallback(nameplate.unitFrame, event, unit)
|
||||
end
|
||||
elseif(event == 'NAME_PLATE_UNIT_ADDED' and unit) then
|
||||
local nameplate = C_NamePlate.GetNamePlateForUnit(unit)
|
||||
if(not nameplate) then return end
|
||||
nameplateUnitToFrame[unit] = nameplate
|
||||
|
||||
if(not nameplate.unitFrame) then
|
||||
self:DisableBlizzardNamePlate(nameplate)
|
||||
nameplate.style = style
|
||||
nameplate.isNamePlate = true
|
||||
|
||||
nameplate.unitFrame = CreateFrame('Button', prefix..tostring(nameplate), nameplate)
|
||||
nameplate.unitFrame:EnableMouse(false)
|
||||
nameplate.unitFrame.isNamePlate = true
|
||||
nameplate.unitFrame.nameplateAnchor = nameplate
|
||||
|
||||
Private.UpdateUnits(nameplate.unitFrame, unit)
|
||||
walkObject(nameplate.unitFrame, unit)
|
||||
C_NamePlateManager.ApplyFPSIncrease(nameplate.unitFrame)
|
||||
else
|
||||
-- for _, child in ipairs(nameplate.blizzElements) do
|
||||
-- ClearNamePlateElement(child)
|
||||
-- end
|
||||
Private.UpdateUnits(nameplate.unitFrame, unit)
|
||||
end
|
||||
|
||||
nameplate.unitFrame:SetAttribute('unit', unit)
|
||||
|
||||
if(nameplateCallback) then
|
||||
nameplateCallback(nameplate.unitFrame, event, unit)
|
||||
end
|
||||
|
||||
-- UAE is called after the callback to reduce the number of
|
||||
-- ForceUpdate calls layout devs have to do themselves
|
||||
nameplate.unitFrame:UpdateAllElements(event)
|
||||
elseif(event == 'NAME_PLATE_UNIT_REMOVED' and unit) then
|
||||
local nameplate = nameplateUnitToFrame[unit]
|
||||
if(not nameplate) then return end
|
||||
nameplateUnitToFrame[unit] = nil
|
||||
nameplate.unitFrame:SetAttribute('unit', nil)
|
||||
if(nameplateCallback) then
|
||||
nameplateCallback(nameplate.unitFrame, event, unit)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--[[ oUF:AddElement(name, update, enable, disable)
|
||||
Used to register an element with oUF.
|
||||
|
||||
|
||||
@@ -190,6 +190,12 @@ local function sortByTime(a, b)
|
||||
end
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if self.unit ~= unit then return end
|
||||
|
||||
local element = self.AuraBars
|
||||
|
||||
@@ -258,6 +258,12 @@ end
|
||||
|
||||
local found = {}
|
||||
local function Update(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if not unit or self.unit ~= unit then return end
|
||||
|
||||
local guid = UnitGUID(unit)
|
||||
|
||||
@@ -83,6 +83,12 @@ local function Shared_UpdateCheckReturn(self, element, updateType, ...)
|
||||
return (not element.enabled or not self.cur) or element.ready or not maxV
|
||||
elseif (updateType == POST) then
|
||||
local curV, maxV, unit = ...
|
||||
if unit and element.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = element.unit and UnitIsUnit(element.unit, unit)
|
||||
if isUnit then
|
||||
unit = element.unit
|
||||
end
|
||||
end
|
||||
return (not element.enabled or not element.cur) or (not element.ready or not curV or not maxV) or element.unit ~= unit
|
||||
else
|
||||
return false
|
||||
|
||||
@@ -26,6 +26,12 @@ local function GetDebuffType(unit, filterTable)
|
||||
end
|
||||
|
||||
local function Update(object, event, unit)
|
||||
if unit and object.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = object.unit and UnitIsUnit(object.unit, unit)
|
||||
if isUnit then
|
||||
unit = object.unit
|
||||
end
|
||||
end
|
||||
if unit ~= object.unit then return end
|
||||
|
||||
local debuffType, texture, wasFiltered, style, color = GetDebuffType(unit, object.DebuffHighlightFilterTable)
|
||||
|
||||
@@ -62,6 +62,12 @@ local function Update(self, _, unit)
|
||||
end
|
||||
|
||||
unit = unit or self.unit
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if self.unit ~= unit then return end
|
||||
|
||||
-- range fader
|
||||
@@ -129,6 +135,7 @@ local function HoverScript(self)
|
||||
end
|
||||
|
||||
local function TargetScript(self)
|
||||
if self.isNamePlate and C_NamePlateManager.IsNamePlateMoving(self) then return end
|
||||
if self.Fader and self.Fader.TargetHooked == 1 then
|
||||
if self:IsShown() then
|
||||
self.Fader:ForceUpdate()
|
||||
|
||||
@@ -161,6 +161,12 @@ local function UpdateDebuff(self, name, icon, count, debuffType, duration, endTi
|
||||
end
|
||||
|
||||
local function Update(self, event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if unit ~= self.unit then return end
|
||||
|
||||
local element = self.RaidDebuffs
|
||||
|
||||
@@ -37,6 +37,12 @@ local UnitName = UnitName
|
||||
local enabledUF, enabled = {}
|
||||
|
||||
local function Update(self, event, unit, succeeded)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if not unit or self.unit ~= unit then return end
|
||||
|
||||
local element = self.ResurrectIndicator
|
||||
|
||||
@@ -539,7 +539,6 @@ function AB:StyleButton(button, noBackdrop, useMasque)
|
||||
|
||||
if macroText then
|
||||
macroText:ClearAllPoints()
|
||||
macroText:SetWidth(self.db.fontWidth)
|
||||
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)
|
||||
|
||||
@@ -17,6 +17,7 @@ local MICRO_BUTTONS = {
|
||||
"SocialsMicroButton",
|
||||
"PVPMicroButton",
|
||||
"LFDMicroButton",
|
||||
"ChallengesMicroButton",
|
||||
"MainMenuMicroButton",
|
||||
"HelpMicroButton"
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ do
|
||||
end
|
||||
|
||||
do
|
||||
local interruptMsg = INTERRUPTED.." %s's \124cff71d5ff\124Hspell:%d\124h[%s]\124h\124r!"
|
||||
local interruptMsg = " "..INTERRUPTED.." %s's \124cff71d5ff\124Hspell:%d\124h[%s]\124h\124r!"
|
||||
|
||||
function M:ToggleInterruptAnnounce()
|
||||
if E.db.general.interruptAnnounce == "NONE" then
|
||||
|
||||
@@ -1,463 +1,188 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local UF = E:GetModule('UnitFrames')
|
||||
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 _G = _G
|
||||
local wipe = wipe
|
||||
local unpack = unpack
|
||||
local CreateFrame = CreateFrame
|
||||
local GetSpellInfo = GetSpellInfo
|
||||
local GetTime = GetTime
|
||||
|
||||
local CREATED, VISIBLE, HIDDEN = 2, 1, 0
|
||||
function NP:Construct_Auras(nameplate)
|
||||
local frameName = nameplate:GetName()
|
||||
|
||||
local positionValues = {
|
||||
BOTTOMLEFT = "TOP",
|
||||
BOTTOMRIGHT = "TOP",
|
||||
LEFT = "RIGHT",
|
||||
RIGHT = "LEFT",
|
||||
TOPLEFT = "BOTTOM",
|
||||
TOPRIGHT = "BOTTOM"
|
||||
}
|
||||
local Buffs = CreateFrame('Frame', frameName..'Buffs', nameplate)
|
||||
Buffs:Size(1, 1)
|
||||
Buffs.size = 27
|
||||
Buffs.num = 4
|
||||
Buffs.spacing = E.Border * 2
|
||||
Buffs.onlyShowPlayer = false
|
||||
Buffs.disableMouse = true
|
||||
Buffs.isNamePlate = nameplate
|
||||
|
||||
local positionValues2 = {
|
||||
BOTTOMLEFT = "BOTTOM",
|
||||
BOTTOMRIGHT = "BOTTOM",
|
||||
LEFT = "LEFT",
|
||||
RIGHT = "RIGHT",
|
||||
TOPLEFT = "TOP",
|
||||
TOPRIGHT = "TOP"
|
||||
}
|
||||
Buffs.initialAnchor = 'BOTTOMLEFT'
|
||||
Buffs.growthX = 'RIGHT'
|
||||
Buffs.growthY = 'UP'
|
||||
Buffs.type = 'buffs'
|
||||
Buffs.forceShow = nameplate == _G.ElvNP_Test
|
||||
Buffs.tickers = {} -- StyleFilters
|
||||
Buffs.stacks = {}
|
||||
Buffs.rows = {}
|
||||
|
||||
local Debuffs = CreateFrame('Frame', frameName..'Debuffs', nameplate)
|
||||
Debuffs:Size(1, 1)
|
||||
Debuffs.size = 27
|
||||
Debuffs.num = 4
|
||||
Debuffs.spacing = E.Border * 2
|
||||
Debuffs.onlyShowPlayer = false
|
||||
Debuffs.disableMouse = true
|
||||
Debuffs.isNamePlate = nameplate
|
||||
Debuffs.initialAnchor = 'BOTTOMLEFT'
|
||||
Debuffs.growthX = 'RIGHT'
|
||||
Debuffs.growthY = 'UP'
|
||||
Debuffs.type = 'debuffs'
|
||||
Debuffs.forceShow = nameplate == _G.ElvNP_Test
|
||||
Debuffs.tickers = {} -- StyleFilters
|
||||
Debuffs.stacks = {}
|
||||
Debuffs.rows = {}
|
||||
|
||||
local RaidIconBit = {
|
||||
["STAR"] = 0x00100000,
|
||||
["CIRCLE"] = 0x00200000,
|
||||
["DIAMOND"] = 0x00400000,
|
||||
["TRIANGLE"] = 0x00800000,
|
||||
["MOON"] = 0x01000000,
|
||||
["SQUARE"] = 0x02000000,
|
||||
["CROSS"] = 0x04000000,
|
||||
["SKULL"] = 0x08000000
|
||||
}
|
||||
Buffs.PreUpdate = UF.PreUpdateAura
|
||||
Buffs.PreSetPosition = UF.SortAuras
|
||||
Buffs.SetPosition = UF.SetPosition
|
||||
Buffs.PostCreateIcon = NP.Construct_AuraIcon
|
||||
Buffs.PostUpdateIcon = UF.PostUpdateAura
|
||||
Buffs.CustomFilter = UF.AuraFilter
|
||||
|
||||
local ByRaidIcon = {}
|
||||
Debuffs.PreUpdate = UF.PreUpdateAura
|
||||
Debuffs.PreSetPosition = UF.SortAuras
|
||||
Debuffs.SetPosition = UF.SetPosition
|
||||
Debuffs.PostCreateIcon = NP.Construct_AuraIcon
|
||||
Debuffs.PostUpdateIcon = UF.PostUpdateAura
|
||||
Debuffs.CustomFilter = UF.AuraFilter
|
||||
|
||||
function NP:LibAuraInfo_AURA_APPLIED(event, destGUID)
|
||||
self:UpdateElement_AurasByGUID(destGUID, event)
|
||||
nameplate.Buffs_, nameplate.Debuffs_ = Buffs, Debuffs
|
||||
nameplate.Buffs, nameplate.Debuffs = Buffs, Debuffs
|
||||
end
|
||||
|
||||
function NP:LibAuraInfo_AURA_REMOVED(event, destGUID)
|
||||
self:UpdateElement_AurasByGUID(destGUID, event)
|
||||
end
|
||||
function NP:Construct_AuraIcon(button)
|
||||
if not button then return end
|
||||
|
||||
function NP:LibAuraInfo_AURA_REFRESH(event, destGUID)
|
||||
self:LibAuraInfo_AURA_APPLIED(event, destGUID)
|
||||
end
|
||||
button:SetTemplate(nil, nil, nil, nil, nil, true, true)
|
||||
|
||||
function NP:LibAuraInfo_AURA_APPLIED_DOSE(event, destGUID)
|
||||
self:LibAuraInfo_AURA_APPLIED(event, destGUID)
|
||||
end
|
||||
button.cd:SetReverse(true)
|
||||
button.cd:SetInside(button)
|
||||
|
||||
function NP:LibAuraInfo_AURA_CLEAR(event, destGUID)
|
||||
self:UpdateElement_AurasByGUID(destGUID, event)
|
||||
end
|
||||
button.icon:SetDrawLayer('ARTWORK')
|
||||
button.icon:SetInside()
|
||||
|
||||
function NP:LibAuraInfo_UNIT_AURA(event, destGUID)
|
||||
self:UpdateElement_AurasByGUID(destGUID, event)
|
||||
end
|
||||
button.count:ClearAllPoints()
|
||||
button.count:Point('BOTTOMRIGHT', 1, 1)
|
||||
button.count:SetJustifyH('RIGHT')
|
||||
|
||||
function NP:UpdateTime(elapsed)
|
||||
self.timeLeft = self.timeLeft - elapsed
|
||||
self:SetValue(self.timeLeft)
|
||||
button.overlay:SetTexture()
|
||||
button.stealable:SetTexture()
|
||||
|
||||
if self.nextUpdate > 0 then
|
||||
self.nextUpdate = self.nextUpdate - elapsed
|
||||
return
|
||||
button.isNamePlate = true
|
||||
|
||||
E:RegisterCooldown(button.cd, 'nameplates')
|
||||
|
||||
local auras = button:GetParent()
|
||||
if auras and auras.type then
|
||||
local db = NP:PlateDB(auras.__owner)
|
||||
button.db = db[auras.type]
|
||||
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
|
||||
NP:UpdateAuraSettings(button)
|
||||
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)
|
||||
function NP:Configure_Auras(nameplate, auras, db)
|
||||
auras.size = db.size
|
||||
auras.height = not db.keepSizeRatio and db.height
|
||||
auras.numAuras = db.numAuras
|
||||
auras.numRows = db.numRows
|
||||
auras.onlyShowPlayer = false
|
||||
auras.spacing = db.spacing
|
||||
auras.growthY = UF.MatchGrowthY[db.anchorPoint] or db.growthY
|
||||
auras.growthX = UF.MatchGrowthX[db.anchorPoint] or db.growthX
|
||||
auras.xOffset = db.xOffset
|
||||
auras.yOffset = db.yOffset
|
||||
auras.anchorPoint = db.anchorPoint
|
||||
auras.auraSort = UF.SortAuraFuncs[db.sortMethod]
|
||||
auras.initialAnchor = E.InversePoints[db.anchorPoint]
|
||||
auras.filterList = UF:ConvertFilters(auras, db.priority)
|
||||
auras.smartPosition, auras.smartFluid = UF:SetSmartPosition(nameplate)
|
||||
auras.attachTo = UF:GetAuraAnchorFrame(nameplate, db.attachTo) -- keep below SetSmartPosition
|
||||
auras.num = db.numAuras * db.numRows
|
||||
auras.db = db -- for auraSort
|
||||
|
||||
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)
|
||||
local index = 1
|
||||
while auras[index] do
|
||||
local button = auras[index]
|
||||
if button then
|
||||
button.db = db
|
||||
NP:UpdateAuraSettings(button)
|
||||
button:SetBackdropBorderColor(unpack(E.media.bordercolor))
|
||||
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)
|
||||
auras:Point(auras.initialAnchor, auras.attachTo, auras.anchorPoint, auras.xOffset, auras.yOffset)
|
||||
auras:Size(db.numAuras * db.size + ((db.numAuras - 1) * db.spacing), 1)
|
||||
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)
|
||||
function NP:Update_Auras(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
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
|
||||
if db.debuffs.enable or db.buffs.enable then
|
||||
if not nameplate:IsElementEnabled('Auras') then
|
||||
nameplate:EnableElement('Auras')
|
||||
end
|
||||
|
||||
nameplate.Buffs_:ClearAllPoints()
|
||||
nameplate.Debuffs_:ClearAllPoints()
|
||||
|
||||
if db.debuffs.enable then
|
||||
nameplate.Debuffs = nameplate.Debuffs_
|
||||
NP:Configure_Auras(nameplate, nameplate.Debuffs, db.debuffs)
|
||||
nameplate.Debuffs:Show()
|
||||
nameplate.Debuffs:ForceUpdate()
|
||||
elseif nameplate.Debuffs then
|
||||
nameplate.Debuffs:Hide()
|
||||
nameplate.Debuffs = nil
|
||||
end
|
||||
|
||||
if db.buffs.enable then
|
||||
nameplate.Buffs = nameplate.Buffs_
|
||||
NP:Configure_Auras(nameplate, nameplate.Buffs, db.buffs)
|
||||
nameplate.Buffs:Show()
|
||||
nameplate.Buffs:ForceUpdate()
|
||||
elseif nameplate.Buffs then
|
||||
nameplate.Buffs:Hide()
|
||||
nameplate.Buffs = nil
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('Auras') then
|
||||
nameplate:DisableElement('Auras')
|
||||
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
|
||||
function NP:UpdateAuraSettings(button)
|
||||
local db = button.db
|
||||
if db then
|
||||
local point = db.countPosition or 'CENTER'
|
||||
button.count:ClearAllPoints()
|
||||
button.count:SetJustifyH(point:find('RIGHT') and 'RIGHT' or 'LEFT')
|
||||
button.count:Point(point, db.countXOffset, db.countYOffset)
|
||||
button.count:FontTemplate(LSM:Fetch('font', db.countFont), db.countFontSize, db.countFontOutline)
|
||||
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))
|
||||
if button.auraInfo then
|
||||
wipe(button.auraInfo)
|
||||
else
|
||||
filterCheck = allowDuration and true -- Allow all auras to be shown when the filter list is empty, while obeying duration sliders
|
||||
button.auraInfo = {}
|
||||
end
|
||||
|
||||
return filterCheck
|
||||
button.needsButtonTrim = true
|
||||
button.needsUpdateCooldownPosition = true
|
||||
end
|
||||
@@ -0,0 +1,299 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local UF = E:GetModule('UnitFrames')
|
||||
local AB = E:GetModule('ActionBars')
|
||||
|
||||
local _G = _G
|
||||
local wipe = wipe
|
||||
local next = next
|
||||
local pairs = pairs
|
||||
local unpack = unpack
|
||||
local GetTime = GetTime
|
||||
local UnitGUID = UnitGUID
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
NP.BossMods_ActiveUnitGUID = {}
|
||||
NP.BossMods_TextureCache = {}
|
||||
|
||||
local allowHostile = false
|
||||
function NP:BossMods_CreateIcon(element)
|
||||
element.index = not element.index and 1 or (element.index + 1)
|
||||
|
||||
local button = CreateFrame('Button', element:GetName()..'Button'..element.index, element)
|
||||
button:EnableMouse(false)
|
||||
button:SetTemplate(nil, nil, nil, nil, nil, true, true)
|
||||
|
||||
local cooldown = CreateFrame('Cooldown', '$parentCooldown', button, 'CooldownFrameTemplate')
|
||||
cooldown:SetReverse(true)
|
||||
cooldown:SetInside(button)
|
||||
E:RegisterCooldown(cooldown, 'nameplates')
|
||||
|
||||
local icon = button:CreateTexture(nil, 'ARTWORK')
|
||||
icon:SetTexCoord(unpack(E.TexCoords))
|
||||
icon:SetInside()
|
||||
|
||||
button.icon = icon
|
||||
button.cd = cooldown
|
||||
button.db = element.db
|
||||
|
||||
return button
|
||||
end
|
||||
|
||||
function NP:BossMods_GetIcon(plate, texture)
|
||||
local element, unused, avaiableIcon = plate.BossMods
|
||||
|
||||
local activeButton = element.activeIcons[texture]
|
||||
if not activeButton then
|
||||
unused, avaiableIcon = next(element.unusedIcons)
|
||||
if unused then element.unusedIcons[unused] = nil end
|
||||
end
|
||||
|
||||
local button = activeButton or avaiableIcon or NP:BossMods_CreateIcon(element)
|
||||
if not activeButton then
|
||||
element.activeIcons[texture] = button
|
||||
end
|
||||
|
||||
return button
|
||||
end
|
||||
|
||||
function NP:BossMods_PositionIcons(element)
|
||||
if not next(element.activeIcons) then return end
|
||||
|
||||
local index = 1
|
||||
local anchor, inversed, growthX, growthY, width, height, cols, point, middle = UF:GetAuraPosition(element)
|
||||
|
||||
element.currentRow = nil -- clear this for a new update
|
||||
|
||||
for _, button in pairs(element.activeIcons) do
|
||||
UF:SetAuraPosition(element, button, index, anchor, inversed, growthX, growthY, width, height, cols, point, middle)
|
||||
|
||||
button:Size(width, height)
|
||||
button:Show()
|
||||
|
||||
AB:TrimIcon(button)
|
||||
|
||||
index = index + 1
|
||||
end
|
||||
end
|
||||
|
||||
function NP:BossMods_TrackIcons(track, unitGUID, texture, duration, desaturate, startTime)
|
||||
if track then
|
||||
NP.BossMods_TextureCache[texture] = true -- use this to easily populate boss mod style filters
|
||||
|
||||
if not NP.BossMods_ActiveUnitGUID[unitGUID] then
|
||||
NP.BossMods_ActiveUnitGUID[unitGUID] = {}
|
||||
end
|
||||
|
||||
local active = NP.BossMods_ActiveUnitGUID[unitGUID]
|
||||
if not active[texture] then
|
||||
active[texture] = {}
|
||||
end
|
||||
|
||||
local activeTexture = active[texture]
|
||||
activeTexture.duration = duration
|
||||
activeTexture.desaturate = desaturate
|
||||
activeTexture.startTime = startTime
|
||||
else
|
||||
local active = NP.BossMods_ActiveUnitGUID[unitGUID]
|
||||
if active then
|
||||
if active[texture] then
|
||||
active[texture] = nil
|
||||
end
|
||||
|
||||
if not next(active) then
|
||||
NP.BossMods_ActiveUnitGUID[unitGUID] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:BossMods_ClearIcons()
|
||||
if not next(NP.BossMods_ActiveUnitGUID) then return end
|
||||
|
||||
for unitGUID, textures in pairs(NP.BossMods_ActiveUnitGUID) do
|
||||
for texture in pairs(textures) do
|
||||
local plate = NP.PlateGUID[unitGUID]
|
||||
if plate then
|
||||
NP:BossMods_ClearIcon(plate, texture)
|
||||
NP:StyleFilterUpdate(plate, 'FAKE_BossModAuras')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wipe(NP.BossMods_ActiveUnitGUID)
|
||||
end
|
||||
|
||||
function NP:BossMods_AddIcon(unitGUID, texture, duration, desaturate, skip)
|
||||
local active = NP.BossMods_ActiveUnitGUID[unitGUID]
|
||||
local activeTexture = active and active[texture]
|
||||
|
||||
local pastTime = activeTexture and activeTexture.startTime
|
||||
local pastDuration = activeTexture and activeTexture.duration
|
||||
if pastTime and pastDuration and pastDuration ~= duration then
|
||||
pastTime = nil -- reset the cooldown timer if a new duration is given
|
||||
end
|
||||
|
||||
local startTime = duration and (pastTime or GetTime()) or nil
|
||||
NP:BossMods_TrackIcons(true, unitGUID, texture, duration, desaturate, startTime)
|
||||
|
||||
local plate = NP.PlateGUID[unitGUID]
|
||||
if not plate then return end
|
||||
|
||||
local button = NP:BossMods_GetIcon(plate, texture)
|
||||
button.icon:SetDesaturated(desaturate)
|
||||
button.icon:SetTexture(texture)
|
||||
|
||||
if duration then
|
||||
button.cd:SetCooldown(startTime, duration)
|
||||
button.cd:Show()
|
||||
else
|
||||
button.cd:Hide()
|
||||
end
|
||||
|
||||
if desaturate then
|
||||
button:SetBackdropBorderColor(unpack(E.media.bordercolor))
|
||||
else
|
||||
local color = _G.DebuffTypeColor.none
|
||||
button:SetBackdropBorderColor(color.r * 0.6, color.g * 0.6, color.b * 0.6)
|
||||
end
|
||||
|
||||
NP:BossMods_PositionIcons(plate.BossMods)
|
||||
|
||||
if not skip then -- this will happen already during PostUpdateAllElements
|
||||
NP:StyleFilterUpdate(plate, 'FAKE_BossModAuras')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:BossMods_RemoveIcon(unitGUID, texture)
|
||||
NP:BossMods_TrackIcons(false, unitGUID, texture)
|
||||
|
||||
local plate = NP.PlateGUID[unitGUID]
|
||||
if plate then
|
||||
NP:BossMods_ClearIcon(plate, texture)
|
||||
NP:BossMods_PositionIcons(plate.BossMods)
|
||||
NP:StyleFilterUpdate(plate, 'FAKE_BossModAuras')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:BossMods_ClearIcon(plate, texture)
|
||||
local element = plate.BossMods
|
||||
local button = element.activeIcons[texture]
|
||||
if not button then return end
|
||||
|
||||
button:Hide()
|
||||
|
||||
element.activeIcons[texture] = nil
|
||||
element.unusedIcons[texture] = button
|
||||
end
|
||||
|
||||
function NP:BossMods_UpdateIcon(plate, removed)
|
||||
local unitGUID = plate.unitGUID
|
||||
local active = NP.BossMods_ActiveUnitGUID[unitGUID]
|
||||
|
||||
if not active then
|
||||
local element = plate.BossMods
|
||||
if element and next(element.activeIcons) then
|
||||
for texture in pairs(element.activeIcons) do
|
||||
NP:BossMods_ClearIcon(plate, texture)
|
||||
end
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local enabled = allowHostile and NP.db.bossMods.enable
|
||||
for texture, info in pairs(active) do
|
||||
if removed or not enabled then
|
||||
NP:BossMods_ClearIcon(plate, texture)
|
||||
elseif enabled then
|
||||
NP:BossMods_AddIcon(unitGUID, texture, info.duration, info.desaturate, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:BossMods_AddIcon_DBM(isGUID, unit, texture, duration, desaturate)
|
||||
if not (allowHostile and NP.db.bossMods.enable) then return end
|
||||
|
||||
local unitGUID = (isGUID and unit) or UnitGUID(unit)
|
||||
NP:BossMods_AddIcon(unitGUID, texture, duration, desaturate)
|
||||
end
|
||||
|
||||
function NP:BossMods_RemoveIcon_DBM(isGUID, unit, texture)
|
||||
local unitGUID = (isGUID and unit) or UnitGUID(unit)
|
||||
NP:BossMods_RemoveIcon(unitGUID, texture)
|
||||
end
|
||||
|
||||
function NP:BossMods_AddIcon_BW(_, unitGUID, texture, duration, desaturate)
|
||||
if not (allowHostile and NP.db.bossMods.enable) then return end
|
||||
|
||||
NP:BossMods_AddIcon(unitGUID, texture, duration, desaturate)
|
||||
end
|
||||
|
||||
function NP:BossMods_RemoveIcon_BW(_, unitGUID, texture)
|
||||
NP:BossMods_RemoveIcon(unitGUID, texture)
|
||||
end
|
||||
|
||||
function NP:BossMods_DisableHostile()
|
||||
NP:BossMods_ClearIcons()
|
||||
|
||||
allowHostile = false
|
||||
end
|
||||
|
||||
function NP:BossMods_EnableHostile()
|
||||
allowHostile = true
|
||||
end
|
||||
|
||||
function NP:DBM_SupportedNPMod()
|
||||
return _G.DBM.Options.UseNameplateHandoff
|
||||
end
|
||||
|
||||
function NP:BossMods_RegisterCallbacks()
|
||||
local DBM = _G.DBM
|
||||
if DBM and DBM.RegisterCallback and DBM.Nameplate then
|
||||
DBM.Nameplate.SupportedNPMod = NP.DBM_SupportedNPMod
|
||||
|
||||
DBM:RegisterCallback('BossMod_ShowNameplateAura',NP.BossMods_AddIcon_DBM)
|
||||
DBM:RegisterCallback('BossMod_HideNameplateAura',NP.BossMods_RemoveIcon_DBM)
|
||||
DBM:RegisterCallback('BossMod_EnableHostileNameplates',NP.BossMods_EnableHostile)
|
||||
DBM:RegisterCallback('BossMod_DisableHostileNameplates',NP.BossMods_DisableHostile)
|
||||
end
|
||||
|
||||
local BWL = _G.BigWigsLoader
|
||||
if BWL and BWL.RegisterMessage then
|
||||
BWL.RegisterMessage(NP,'BigWigs_AddNameplateIcon',NP.BossMods_AddIcon_BW)
|
||||
BWL.RegisterMessage(NP,'BigWigs_RemoveNameplateIcon',NP.BossMods_RemoveIcon_BW)
|
||||
BWL.RegisterMessage(NP,'BigWigs_EnableHostileNameplates',NP.BossMods_EnableHostile)
|
||||
BWL.RegisterMessage(NP,'BigWigs_DisableHostileNameplates',NP.BossMods_DisableHostile)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_BossMods(plate)
|
||||
local db = NP.db.bossMods
|
||||
if not db.enable then return end
|
||||
|
||||
local anchor = db.anchorPoint
|
||||
local inverse = E.InversePoints[anchor]
|
||||
|
||||
local element = plate.BossMods
|
||||
element:ClearAllPoints()
|
||||
element:SetPoint(inverse or 'TOPRIGHT', plate, anchor or 'TOPRIGHT', db.xOffset, db.yOffset)
|
||||
element:SetSize(plate.width or 150, db.size)
|
||||
|
||||
element.db = db
|
||||
element.spacing = db.spacing
|
||||
element.initialAnchor = inverse
|
||||
element.growthY = UF.MatchGrowthY[anchor] or db.growthY
|
||||
element.growthX = UF.MatchGrowthX[anchor] or db.growthX
|
||||
element.size = db.size + (db.spacing or 0)
|
||||
element.height = not db.keepSizeRatio and db.height
|
||||
element.rows = {}
|
||||
end
|
||||
|
||||
function NP:Construct_BossMods(nameplate)
|
||||
local element = CreateFrame('Frame', '$parentBossMods', nameplate)
|
||||
|
||||
element.activeIcons = {}
|
||||
element.unusedIcons = {}
|
||||
|
||||
return element
|
||||
end
|
||||
@@ -1,358 +1,254 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local UF = E:GetModule('UnitFrames')
|
||||
local CH = E:GetModule('Chat')
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
local _G = _G
|
||||
local abs = abs
|
||||
local next = next
|
||||
local unpack = unpack
|
||||
local abs = math.abs
|
||||
--WoW API / Variables
|
||||
local strjoin = strjoin
|
||||
local strmatch = strmatch
|
||||
local CreateFrame = CreateFrame
|
||||
local GetTime = GetTime
|
||||
local UnitCastingInfo = UnitCastingInfo
|
||||
local UnitChannelInfo = UnitChannelInfo
|
||||
local FAILED = FAILED
|
||||
local UnitCanAttack = UnitCanAttack
|
||||
local UnitName = UnitName
|
||||
|
||||
local INTERRUPTED = INTERRUPTED
|
||||
|
||||
local function resetAttributes(self)
|
||||
self.casting = nil
|
||||
self.channeling = nil
|
||||
self.notInterruptible = nil
|
||||
self.spellName = nil
|
||||
function NP:Castbar_CheckInterrupt(unit)
|
||||
if unit == 'vehicle' then
|
||||
unit = 'player'
|
||||
end
|
||||
|
||||
if self.notInterruptible and UnitCanAttack('player', unit) then
|
||||
self:SetStatusBarColor(NP.db.colors.castNoInterruptColor.r, NP.db.colors.castNoInterruptColor.g, NP.db.colors.castNoInterruptColor.b)
|
||||
|
||||
if self.Icon and NP.db.colors.castbarDesaturate then
|
||||
self.Icon:SetDesaturated(true)
|
||||
end
|
||||
else
|
||||
self:SetStatusBarColor(NP.db.colors.castColor.r, NP.db.colors.castColor.g, NP.db.colors.castColor.b)
|
||||
|
||||
if self.Icon then
|
||||
self.Icon:SetDesaturated(false)
|
||||
end
|
||||
end
|
||||
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
|
||||
function NP:Castbar_CustomDelayText(duration)
|
||||
if self.channeling then
|
||||
if self.channelTimeFormat == 'CURRENT' then
|
||||
self.Time:SetFormattedText('%.1f |cffaf5050%.1f|r', abs(duration - self.max), self.delay)
|
||||
elseif self.channelTimeFormat == 'CURRENTMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f |cffaf5050%.1f|r', duration, self.max, self.delay)
|
||||
elseif self.channelTimeFormat == 'REMAINING' then
|
||||
self.Time:SetFormattedText('%.1f |cffaf5050%.1f|r', duration, self.delay)
|
||||
elseif self.channelTimeFormat == 'REMAININGMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f |cffaf5050%.1f|r', abs(duration - self.max), self.max, self.delay)
|
||||
end
|
||||
else
|
||||
if self.castTimeFormat == 'CURRENT' then
|
||||
self.Time:SetFormattedText('%.1f |cffaf5050%s %.1f|r', duration, '+', self.delay)
|
||||
elseif self.castTimeFormat == 'CURRENTMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f |cffaf5050%s %.1f|r', duration, self.max, '+', self.delay)
|
||||
elseif self.castTimeFormat == 'REMAINING' then
|
||||
self.Time:SetFormattedText('%.1f |cffaf5050%s %.1f|r', abs(duration - self.max), '+', self.delay)
|
||||
elseif self.castTimeFormat == 'REMAININGMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f |cffaf5050%s %.1f|r', abs(duration - self.max), self.max, '+', self.delay)
|
||||
end
|
||||
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)
|
||||
function NP:Castbar_CustomTimeText(duration)
|
||||
if self.channeling then
|
||||
if self.channelTimeFormat == 'CURRENT' then
|
||||
self.Time:SetFormattedText('%.1f', abs(duration - self.max))
|
||||
elseif self.channelTimeFormat == 'CURRENTMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f', abs(duration - self.max), self.max)
|
||||
elseif self.channelTimeFormat == 'REMAINING' then
|
||||
self.Time:SetFormattedText('%.1f', duration)
|
||||
elseif self.channelTimeFormat == 'REMAININGMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f', duration, self.max)
|
||||
end
|
||||
else
|
||||
if self.castTimeFormat == 'CURRENT' then
|
||||
self.Time:SetFormattedText('%.1f', duration)
|
||||
elseif self.castTimeFormat == 'CURRENTMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f', duration, self.max)
|
||||
elseif self.castTimeFormat == 'REMAINING' then
|
||||
self.Time:SetFormattedText('%.1f', abs(duration - self.max))
|
||||
elseif self.castTimeFormat == 'REMAININGMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f', abs(duration - self.max), self.max)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Castbar_PostCastStart(unit)
|
||||
self:CheckInterrupt(unit)
|
||||
|
||||
-- player or NPCs; if used on other players: the cast target doesn't match their target, can be misleading if they mouseover cast
|
||||
local plate = self.__owner
|
||||
local db = NP:PlateDB(plate)
|
||||
if db.castbar and db.castbar.enable then
|
||||
if db.castbar.displayTarget then
|
||||
local frameType = plate.frameType
|
||||
if frameType == 'PLAYER' then
|
||||
if self.curTarget then
|
||||
self.Text:SetText(self.spellName..' > '..self.curTarget)
|
||||
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)
|
||||
elseif frameType == 'ENEMY_NPC' or frameType == 'FRIENDLY_NPC' then
|
||||
local target = self.curTarget or UnitName(unit..'target')
|
||||
if target and target ~= '' and target ~= plate.unitName then
|
||||
self.Text:SetText(self.spellName..' > '..target)
|
||||
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")
|
||||
NP:StyleFilterUpdate(plate, 'FAKE_Cast')
|
||||
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()
|
||||
function NP:Castbar_PostCastFail()
|
||||
NP:StyleFilterUpdate(self.__owner, 'FAKE_Cast')
|
||||
self:SetStatusBarColor(NP.db.colors.castInterruptedColor.r, NP.db.colors.castInterruptedColor.g, NP.db.colors.castInterruptedColor.b)
|
||||
end
|
||||
|
||||
function NP:Castbar_PostCastInterruptible(unit)
|
||||
self:CheckInterrupt(unit)
|
||||
end
|
||||
|
||||
function NP:Castbar_PostCastStop()
|
||||
NP:StyleFilterUpdate(self.__owner, 'FAKE_Cast')
|
||||
end
|
||||
|
||||
function NP:Construct_Castbar(nameplate)
|
||||
local castbar = CreateFrame('StatusBar', nameplate:GetName()..'Castbar', nameplate)
|
||||
castbar:SetParent(nameplate)
|
||||
castbar:CreateBackdrop('Transparent', nil, nil, nil, nil, true, true)
|
||||
castbar:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
|
||||
NP.StatusBars[castbar] = true
|
||||
castbar.ModuleStatusBars = NP.StatusBars -- not oUF
|
||||
|
||||
castbar.Button = CreateFrame('Frame', nil, castbar)
|
||||
castbar.Button:SetTemplate(nil, nil, nil, nil, nil, true, true)
|
||||
|
||||
castbar.Icon = castbar.Button:CreateTexture(nil, 'ARTWORK')
|
||||
castbar.Icon:SetParent(castbar.Button)
|
||||
castbar.Icon:SetTexCoord(unpack(E.TexCoords))
|
||||
castbar.Icon:SetInside()
|
||||
|
||||
castbar.Time = castbar:CreateFontString(nil, 'OVERLAY')
|
||||
castbar.Time:FontTemplate(LSM:Fetch('font', NP.db.font), NP.db.fontSize, NP.db.fontOutline)
|
||||
castbar.Time:Point('RIGHT', castbar, 'RIGHT', -4, 0)
|
||||
castbar.Time:SetJustifyH('RIGHT')
|
||||
|
||||
castbar.Text = castbar:CreateFontString(nil, 'OVERLAY')
|
||||
castbar.Text:FontTemplate(LSM:Fetch('font', NP.db.font), NP.db.fontSize, NP.db.fontOutline)
|
||||
castbar.Text:Point('LEFT', castbar, 'LEFT', 4, 0)
|
||||
castbar.Text:SetJustifyH('LEFT')
|
||||
castbar.Text:SetWordWrap(false)
|
||||
|
||||
castbar.CheckInterrupt = NP.Castbar_CheckInterrupt
|
||||
castbar.CustomDelayText = NP.Castbar_CustomDelayText
|
||||
castbar.CustomTimeText = NP.Castbar_CustomTimeText
|
||||
castbar.PostCastStart = NP.Castbar_PostCastStart
|
||||
castbar.PostCastFail = NP.Castbar_PostCastFail
|
||||
castbar.PostCastInterruptible = NP.Castbar_PostCastInterruptible
|
||||
castbar.PostCastStop = NP.Castbar_PostCastStop
|
||||
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
castbar.Hide = castbar.Show
|
||||
castbar:Show()
|
||||
castbar.Text:SetText('Casting')
|
||||
castbar.Time:SetText('3.1')
|
||||
castbar.Icon:SetTexture([[Interface\Icons\Achievement_Character_Pandaren_Female]])
|
||||
castbar:SetStatusBarColor(NP.db.colors.castColor.r, NP.db.colors.castColor.g, NP.db.colors.castColor.b)
|
||||
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
|
||||
return castbar
|
||||
end
|
||||
|
||||
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"
|
||||
function NP:CASTBAR_COMBAT_LOG_EVENT_UNFILTERED(event, sourceGUID, sourceName, targetGUID)
|
||||
if (event == 'SPELL_INTERRUPT' or event == 'SPELL_PERIODIC_INTERRUPT') and targetGUID and (sourceName and sourceName ~= '') then
|
||||
local plate, classColor = NP.PlateGUID[targetGUID]
|
||||
if plate and plate.Castbar then
|
||||
local db = NP:PlateDB(plate)
|
||||
if db.castbar and db.castbar.enable and db.castbar.sourceInterrupt and (db.castbar.timeToHold > 0) then
|
||||
local name = strmatch(sourceName, '([^%-]+).*')
|
||||
if db.castbar.sourceInterruptClassColor then
|
||||
local data = CH:GetPlayerInfoByGUID(sourceGUID)
|
||||
if data and data.classColor then
|
||||
classColor = data.classColor.colorStr
|
||||
end
|
||||
|
||||
plate.Castbar.Text:SetFormattedText('%s > %s', INTERRUPTED, classColor and strjoin('', '|c', classColor, name) or name)
|
||||
else
|
||||
plate.Castbar.Text:SetFormattedText('%s > %s', INTERRUPTED, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_Castbar(nameplate)
|
||||
local frameDB = NP:PlateDB(nameplate)
|
||||
local db = frameDB.castbar
|
||||
|
||||
local castbar = nameplate.Castbar
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
castbar:SetAlpha((not frameDB.nameOnly and db.enable) and 1 or 0)
|
||||
end
|
||||
|
||||
if db.enable then
|
||||
if not nameplate:IsElementEnabled('Castbar') then
|
||||
nameplate:EnableElement('Castbar')
|
||||
end
|
||||
|
||||
if not name then
|
||||
resetAttributes(castBar)
|
||||
castBar:Hide()
|
||||
return
|
||||
end
|
||||
castbar.timeToHold = db.timeToHold
|
||||
castbar.castTimeFormat = db.castTimeFormat
|
||||
castbar.channelTimeFormat = db.channelTimeFormat
|
||||
|
||||
endTime = endTime / 1000
|
||||
startTime = startTime / 1000
|
||||
castbar:Size(db.width, db.height)
|
||||
castbar:Point('CENTER', nameplate, 'CENTER', db.xOffset, db.yOffset)
|
||||
|
||||
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
|
||||
if db.showIcon then
|
||||
castbar.Button:ClearAllPoints()
|
||||
castbar.Button:Point(db.iconPosition == 'RIGHT' and 'BOTTOMLEFT' or 'BOTTOMRIGHT', castbar, db.iconPosition == 'RIGHT' and 'BOTTOMRIGHT' or 'BOTTOMLEFT', db.iconOffsetX, db.iconOffsetY)
|
||||
castbar.Button:Size(db.iconSize, db.iconSize)
|
||||
castbar.Button:Show()
|
||||
else
|
||||
castBar.value = endTime - GetTime()
|
||||
castbar.Button:Hide()
|
||||
end
|
||||
|
||||
castBar:SetMinMaxValues(0, castBar.max)
|
||||
castBar:SetValue(castBar.value)
|
||||
castbar.Time:ClearAllPoints()
|
||||
castbar.Text:ClearAllPoints()
|
||||
|
||||
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)
|
||||
if db.textPosition == 'BELOW' then
|
||||
castbar.Time:Point('TOPRIGHT', castbar, 'BOTTOMRIGHT', db.timeXOffset, db.timeYOffset)
|
||||
castbar.Text:Point('TOPLEFT', castbar, 'BOTTOMLEFT', db.textXOffset, db.textYOffset)
|
||||
elseif db.textPosition == 'ABOVE' then
|
||||
castbar.Time:Point('BOTTOMRIGHT', castbar, 'TOPRIGHT', db.timeXOffset, db.timeYOffset)
|
||||
castbar.Text:Point('BOTTOMLEFT', castbar, 'TOPLEFT', db.textXOffset, db.textYOffset)
|
||||
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()
|
||||
castbar.Time:Point('RIGHT', castbar, 'RIGHT', db.timeXOffset, db.timeYOffset)
|
||||
castbar.Text:Point('LEFT', castbar, 'LEFT', db.textXOffset, db.textYOffset)
|
||||
end
|
||||
|
||||
castBar.scale.width:SetChange(db.width * scale)
|
||||
castBar.scale.height:SetChange(db.height * scale)
|
||||
castBar.scale:Play()
|
||||
if db.hideTime then
|
||||
castbar.Time:Hide()
|
||||
else
|
||||
castbar.Time:FontTemplate(LSM:Fetch('font', db.font), db.fontSize, db.fontOutline)
|
||||
castbar.Time:Show()
|
||||
end
|
||||
|
||||
castBar.Icon.scale.width:SetChange(db.iconSize * scale)
|
||||
castBar.Icon.scale.height:SetChange(db.iconSize * scale)
|
||||
castBar.Icon.scale:Play()
|
||||
if db.hideSpellName then
|
||||
castbar.Text:Hide()
|
||||
else
|
||||
castbar.Text:FontTemplate(LSM:Fetch('font', db.font), db.fontSize, db.fontOutline)
|
||||
castbar.Text:Show()
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('Castbar') then
|
||||
nameplate:DisableElement('Castbar')
|
||||
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,310 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local UF = E:GetModule('UnitFrames')
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
local _G = _G
|
||||
local max, next, ipairs = max, next, ipairs
|
||||
|
||||
local CreateFrame = CreateFrame
|
||||
local UnitHasVehicleUI = UnitHasVehicleUI
|
||||
local MAX_COMBO_POINTS = MAX_COMBO_POINTS
|
||||
|
||||
local MAX_POINTS = { -- match to UF.classMaxResourceBar
|
||||
DEATHKNIGHT = max(6, MAX_COMBO_POINTS),
|
||||
ROGUE = max(7, MAX_COMBO_POINTS),
|
||||
HERO = max(5, MAX_COMBO_POINTS),
|
||||
DRUID = max(5, MAX_COMBO_POINTS)
|
||||
}
|
||||
|
||||
function NP:ClassPower_SetBarColor(bar, r, g, b)
|
||||
bar:SetStatusBarColor(r, g, b)
|
||||
|
||||
if bar.bg then
|
||||
bar.bg:SetVertexColor(r * NP.multiplier, g * NP.multiplier, b * NP.multiplier)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:ClassPower_UpdateColor(powerType, rune)
|
||||
local isRunes = powerType == 'RUNES'
|
||||
|
||||
local classPower = self.classColor
|
||||
local colors = NP.db.colors.classResources
|
||||
local fallback = NP.db.colors.power[powerType]
|
||||
|
||||
if isRunes and NP.db.colors.chargingRunes then
|
||||
NP:Runes_UpdateCharged(self, rune)
|
||||
elseif isRunes and rune and not classPower then
|
||||
local color = colors.DEATHKNIGHT[rune.runeType or 0]
|
||||
NP:ClassPower_SetBarColor(rune, color.r, color.g, color.b)
|
||||
else
|
||||
local classColor = not classPower and ((isRunes and colors.DEATHKNIGHT) or (powerType == 'COMBO_POINTS' and colors.comboPoints) or (powerType == 'ESSENCE' and colors.EVOKER) or (powerType == 'CHI' and colors.MONK))
|
||||
for i, bar in ipairs(self) do
|
||||
local color = classPower or (isRunes and classColor[bar.runeType or 0]) or (classColor and classColor[i]) or colors[E.myclass] or fallback
|
||||
NP:ClassPower_SetBarColor(bar, color.r, color.g, color.b)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:ClassPower_PostUpdate(Cur, _, needUpdate, powerType, chargedPoints)
|
||||
if Cur and Cur > 0 then
|
||||
self:Show()
|
||||
else
|
||||
self:Hide()
|
||||
end
|
||||
|
||||
if needUpdate then
|
||||
NP:Update_ClassPower(self.__owner)
|
||||
end
|
||||
|
||||
if powerType == 'COMBO_POINTS' and E.myclass == 'ROGUE' then
|
||||
NP.ClassPower_UpdateColor(self, powerType)
|
||||
|
||||
if chargedPoints then
|
||||
local color = NP.db.colors.classResources.chargedComboPoint
|
||||
for _, chargedIndex in next, chargedPoints do
|
||||
self[chargedIndex]:SetStatusBarColor(color.r, color.g, color.b)
|
||||
self[chargedIndex].bg:SetVertexColor(color.r * NP.multiplier, color.g * NP.multiplier, color.b * NP.multiplier)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_ClassPower(nameplate)
|
||||
local frameName = nameplate:GetName()
|
||||
local ClassPower = CreateFrame('Frame', frameName..'ClassPower', nameplate)
|
||||
ClassPower:CreateBackdrop('Transparent', nil, nil, nil, nil, true, true)
|
||||
ClassPower:Hide()
|
||||
|
||||
local texture = LSM:Fetch('statusbar', NP.db.statusbar)
|
||||
local total = MAX_POINTS[E.myclass] or 0
|
||||
|
||||
for i = 1, total do
|
||||
local bar = CreateFrame('StatusBar', frameName..'ClassPower'..i, ClassPower)
|
||||
bar:SetStatusBarTexture(texture)
|
||||
NP.StatusBars[bar] = true
|
||||
|
||||
bar.bg = ClassPower:CreateTexture(frameName..'ClassPower'..i..'bg', 'BORDER')
|
||||
bar.bg:SetTexture(texture)
|
||||
bar.bg:SetAllPoints()
|
||||
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
local combo = NP.db.colors.classResources.comboPoints[i]
|
||||
bar.bg:SetVertexColor(combo.r, combo.g, combo.b)
|
||||
end
|
||||
|
||||
ClassPower[i] = bar
|
||||
end
|
||||
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
ClassPower.Hide = ClassPower.Show
|
||||
ClassPower:Show()
|
||||
end
|
||||
|
||||
ClassPower.UpdateColor = NP.ClassPower_UpdateColor
|
||||
ClassPower.PostUpdate = NP.ClassPower_PostUpdate
|
||||
|
||||
return ClassPower
|
||||
end
|
||||
|
||||
function NP:Update_ClassPower(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
if not db.nameOnly and db.classpower and db.classpower.enable then
|
||||
NP.ClassPower_UpdateColor(nameplate.ClassPower, 'COMBO_POINTS')
|
||||
nameplate.ClassPower:SetAlpha(1)
|
||||
else
|
||||
nameplate.ClassPower:SetAlpha(0)
|
||||
end
|
||||
end
|
||||
|
||||
local target = nameplate.frameType == 'TARGET'
|
||||
if (target or nameplate.frameType == 'PLAYER') and db.classpower and db.classpower.enable then
|
||||
if not nameplate:IsElementEnabled('ClassPower') then
|
||||
nameplate:EnableElement('ClassPower')
|
||||
end
|
||||
|
||||
local anchor = target and NP:GetClassAnchor()
|
||||
nameplate.ClassPower:ClearAllPoints()
|
||||
nameplate.ClassPower:Point('CENTER', anchor or nameplate, 'CENTER', db.classpower.xOffset, db.classpower.yOffset)
|
||||
nameplate.ClassPower:Size(db.classpower.width, db.classpower.height)
|
||||
|
||||
nameplate.ClassPower.classColor = db.classpower.classColor and RAID_CLASS_COLORS[E.myclass]
|
||||
|
||||
for i = 1, #nameplate.ClassPower do
|
||||
nameplate.ClassPower[i]:Hide()
|
||||
nameplate.ClassPower[i].bg:Hide()
|
||||
end
|
||||
|
||||
local maxButtons = nameplate.ClassPower.__max
|
||||
if maxButtons > 0 then
|
||||
local Width = db.classpower.width / maxButtons
|
||||
for i = 1, maxButtons do
|
||||
local button = nameplate.ClassPower[i]
|
||||
button:Show()
|
||||
button.bg:Show()
|
||||
button:ClearAllPoints()
|
||||
|
||||
if i == 1 then
|
||||
local width = Width - (maxButtons == 6 and 2 or 0)
|
||||
button:Point('LEFT', nameplate.ClassPower, 'LEFT', 0, 0)
|
||||
button:Size(width, db.classpower.height)
|
||||
else
|
||||
button:Point('LEFT', nameplate.ClassPower[i - 1], 'RIGHT', 1, 0)
|
||||
button:Size(Width - 1, db.classpower.height)
|
||||
|
||||
if i == maxButtons then
|
||||
button:Point('RIGHT', nameplate.ClassPower)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if nameplate:IsElementEnabled('ClassPower') then
|
||||
nameplate:DisableElement('ClassPower')
|
||||
end
|
||||
|
||||
nameplate.ClassPower:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Runes_UpdateCharged(runes, rune)
|
||||
local colors = NP.db.colors.classResources.DEATHKNIGHT
|
||||
local classColor = (runes and runes.classColor) or (rune and rune.__owner and rune.__owner.classColor)
|
||||
|
||||
if rune then
|
||||
NP:ClassPower_SetBarColor(rune, UF:Runes_GetColor(rune, colors, classColor))
|
||||
elseif runes then
|
||||
for _, bar in ipairs(runes) do
|
||||
NP:ClassPower_SetBarColor(bar, UF:Runes_GetColor(bar, colors, classColor))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Runes_PostUpdate()
|
||||
self:SetShown(not UnitHasVehicleUI('player'))
|
||||
|
||||
if NP.db.colors.chargingRunes then
|
||||
NP:Runes_UpdateCharged(self)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Runes_UpdateChargedColor()
|
||||
if NP.db.colors.chargingRunes then
|
||||
NP:Runes_UpdateCharged(nil, self)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Runes_PostUpdateColor(r, g, b, color, rune)
|
||||
NP.ClassPower_UpdateColor(self, 'RUNES', rune)
|
||||
end
|
||||
|
||||
function NP:Construct_Runes(nameplate)
|
||||
local frameName = nameplate:GetName()
|
||||
local Runes = CreateFrame('Frame', frameName..'Runes', nameplate)
|
||||
Runes:SetFrameStrata("BACKGROUND")
|
||||
Runes:CreateBackdrop('Transparent', nil, nil, nil, nil, true, true)
|
||||
Runes:Hide()
|
||||
|
||||
Runes.PostUpdate = NP.Runes_PostUpdate
|
||||
Runes.PostUpdateColor = NP.Runes_PostUpdateColor
|
||||
|
||||
local texture = LSM:Fetch('statusbar', NP.db.statusbar)
|
||||
local color = NP.db.colors.classResources.DEATHKNIGHT[0]
|
||||
|
||||
for i = 1, 6 do
|
||||
local rune = CreateFrame('StatusBar', frameName..'Runes'..i, Runes)
|
||||
rune:SetStatusBarTexture(texture)
|
||||
rune:SetStatusBarColor(color.r, color.g, color.b)
|
||||
rune.PostUpdateColor = NP.Runes_UpdateChargedColor
|
||||
rune.__owner = Runes
|
||||
NP.StatusBars[rune] = true
|
||||
|
||||
rune.bg = rune:CreateTexture(frameName..'Runes'..i..'bg', 'BORDER')
|
||||
rune.bg:SetVertexColor(color.r * NP.multiplier, color.g * NP.multiplier, color.b * NP.multiplier)
|
||||
rune.bg:SetTexture(texture)
|
||||
rune.bg:SetAllPoints()
|
||||
rune.bg.multiplier = 0.35
|
||||
|
||||
Runes[i] = rune
|
||||
end
|
||||
|
||||
return Runes
|
||||
end
|
||||
|
||||
function NP:Update_Runes(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
local target = nameplate.frameType == 'TARGET'
|
||||
if (target or nameplate.frameType == 'PLAYER') and db.classpower and db.classpower.enable then
|
||||
if not nameplate:IsElementEnabled('Runes') then
|
||||
nameplate:EnableElement('Runes')
|
||||
end
|
||||
|
||||
local anchor = target and NP:GetClassAnchor()
|
||||
nameplate.Runes:ClearAllPoints()
|
||||
nameplate.Runes:Point('CENTER', anchor or nameplate, 'CENTER', db.classpower.xOffset, db.classpower.yOffset)
|
||||
nameplate.Runes:Show()
|
||||
|
||||
nameplate.Runes.classColor = db.classpower.classColor and RAID_CLASS_COLORS[E.myclass]
|
||||
nameplate.Runes.sortOrder = (db.classpower.sortDirection ~= 'NONE') and db.classpower.sortDirection
|
||||
nameplate.Runes.colorSpec = NP.db.colors.runeBySpec
|
||||
|
||||
local width = db.classpower.width / 6
|
||||
nameplate.Runes:Size(db.classpower.width, db.classpower.height)
|
||||
|
||||
for i = 1, 6 do
|
||||
local rune = nameplate.Runes[i]
|
||||
if i == 1 then
|
||||
rune:Size(width, db.classpower.height)
|
||||
rune:ClearAllPoints()
|
||||
rune:Point('LEFT', nameplate.Runes, 'LEFT', 0, 0)
|
||||
else
|
||||
rune:Size(width - 1, db.classpower.height)
|
||||
rune:ClearAllPoints()
|
||||
rune:Point('LEFT', nameplate.Runes[i-1], 'RIGHT', 1, 0)
|
||||
|
||||
if i == 6 then
|
||||
rune:Point('RIGHT', nameplate.Runes)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if nameplate:IsElementEnabled('Runes') then
|
||||
nameplate:DisableElement('Runes')
|
||||
end
|
||||
|
||||
nameplate.Runes:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Stagger(nameplate)
|
||||
local Stagger = CreateFrame('StatusBar', nameplate:GetName()..'Stagger', nameplate)
|
||||
Stagger:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
Stagger:CreateBackdrop('Transparent', nil, nil, nil, nil, true, true)
|
||||
Stagger:Hide()
|
||||
|
||||
NP.StatusBars[Stagger] = true
|
||||
|
||||
return Stagger
|
||||
end
|
||||
|
||||
function NP:Update_Stagger(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
local target = nameplate.frameType == 'TARGET'
|
||||
if (target or nameplate.frameType == 'PLAYER') and db.classpower and db.classpower.enable then
|
||||
if not nameplate:IsElementEnabled('Stagger') then
|
||||
nameplate:EnableElement('Stagger')
|
||||
end
|
||||
|
||||
local anchor = target and NP:GetClassAnchor()
|
||||
nameplate.Stagger:ClearAllPoints()
|
||||
nameplate.Stagger:Point('CENTER', anchor or nameplate, 'CENTER', db.classpower.xOffset, db.classpower.yOffset)
|
||||
|
||||
nameplate.Stagger:Size(db.classpower.width, db.classpower.height)
|
||||
elseif nameplate:IsElementEnabled('Stagger') then
|
||||
nameplate:DisableElement('Stagger')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,302 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local UF = E:GetModule('UnitFrames')
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
local ipairs = ipairs
|
||||
local unpack = unpack
|
||||
local UnitPlayerControlled = UnitPlayerControlled
|
||||
local UnitClass = UnitClass
|
||||
local UnitReaction = UnitReaction
|
||||
local UnitIsConnected = UnitIsConnected
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
function NP:Health_UpdateColor(_, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if not unit or self.unit ~= unit then return end
|
||||
local element = self.Health
|
||||
|
||||
local r, g, b, t
|
||||
if element.colorDisconnected and not UnitIsConnected(unit) then
|
||||
t = self.colors.disconnected
|
||||
elseif (element.colorClass and self.isPlayer) or (element.colorClassNPC and not self.isPlayer) or (element.colorClassPet and UnitPlayerControlled(unit) and not self.isPlayer) then
|
||||
local _, class = UnitClass(unit)
|
||||
t = self.colors.class[class]
|
||||
elseif element.colorReaction and UnitReaction(unit, 'player') then
|
||||
local reaction = UnitReaction(unit, 'player')
|
||||
t = NP.db.colors.reactions[reaction == 4 and 'neutral' or reaction <= 3 and 'bad' or 'good']
|
||||
elseif element.colorSmooth then
|
||||
r, g, b = self:ColorGradient(element.cur or 1, element.max or 1, unpack(element.smoothGradient or self.colors.smooth))
|
||||
elseif element.colorHealth then
|
||||
t = NP.db.colors.health
|
||||
end
|
||||
|
||||
if t then
|
||||
r, g, b = t.r, t.g, t.b
|
||||
element.r, element.g, element.b = r, g, b -- save these for the style filter to switch back
|
||||
end
|
||||
|
||||
local sf = NP:StyleFilterChanges(self)
|
||||
if sf.HealthColor then
|
||||
r, g, b = sf.HealthColor.r, sf.HealthColor.g, sf.HealthColor.b
|
||||
end
|
||||
|
||||
if b then
|
||||
element:SetStatusBarColor(r, g, b)
|
||||
|
||||
if element.bg then
|
||||
element.bg:SetVertexColor(r * NP.multiplier, g * NP.multiplier, b * NP.multiplier)
|
||||
end
|
||||
end
|
||||
|
||||
if element.PostUpdateColor then
|
||||
element:PostUpdateColor(unit, r, g, b)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Health(nameplate)
|
||||
local Health = CreateFrame('StatusBar', nameplate:GetName()..'Health', nameplate)
|
||||
Health:SetParent(nameplate)
|
||||
Health:CreateBackdrop('Transparent', nil, nil, nil, nil, true, true)
|
||||
Health:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
Health.considerSelectionInCombatHostile = true
|
||||
Health.UpdateColor = NP.Health_UpdateColor
|
||||
|
||||
NP.StatusBars[Health] = true
|
||||
|
||||
local statusBarTexture = Health:GetStatusBarTexture()
|
||||
local healthFlashTexture = Health:CreateTexture(nameplate:GetName()..'FlashTexture', 'OVERLAY')
|
||||
healthFlashTexture:SetTexture(LSM:Fetch('background', 'ElvUI Blank'))
|
||||
healthFlashTexture:Point('BOTTOMLEFT', statusBarTexture, 'BOTTOMLEFT')
|
||||
healthFlashTexture:Point('TOPRIGHT', statusBarTexture, 'TOPRIGHT')
|
||||
healthFlashTexture:Hide()
|
||||
nameplate.HealthFlashTexture = healthFlashTexture
|
||||
|
||||
local clipFrame = CreateFrame("Frame", nil, Health)
|
||||
clipFrame:SetScript("OnUpdate", UF.HealthClipFrame_OnUpdate)
|
||||
clipFrame:SetAllPoints()
|
||||
clipFrame:EnableMouse(false)
|
||||
clipFrame.__frame = Health
|
||||
Health.ClipFrame = clipFrame
|
||||
|
||||
return Health
|
||||
end
|
||||
|
||||
function NP:Health_SetColors(nameplate, threatColors)
|
||||
if threatColors then -- managed by ThreatIndicator_PostUpdate
|
||||
nameplate.Health:SetColorTapping(nil)
|
||||
nameplate.Health:SetColorSelection(nil)
|
||||
nameplate.Health.colorReaction = nil
|
||||
nameplate.Health.colorClass = nil
|
||||
else
|
||||
local db = NP:PlateDB(nameplate)
|
||||
nameplate.Health:SetColorTapping(true)
|
||||
nameplate.Health:SetColorSelection(true)
|
||||
nameplate.Health.colorReaction = true
|
||||
nameplate.Health.colorClass = db.health and db.health.useClassColor
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_Health(nameplate, skipUpdate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
NP:Health_SetColors(nameplate)
|
||||
|
||||
if skipUpdate then return end
|
||||
|
||||
if db.health.enable then
|
||||
if not nameplate:IsElementEnabled('Health') then
|
||||
nameplate:EnableElement('Health')
|
||||
end
|
||||
|
||||
nameplate.Health:Point('CENTER')
|
||||
nameplate.Health:Point('LEFT')
|
||||
nameplate.Health:Point('RIGHT')
|
||||
|
||||
E:SetSmoothing(nameplate.Health, NP.db.smoothbars)
|
||||
elseif nameplate:IsElementEnabled('Health') then
|
||||
nameplate:DisableElement('Health')
|
||||
end
|
||||
|
||||
nameplate.Health.width = db.health.width
|
||||
nameplate.Health.height = db.health.height
|
||||
nameplate.Health:Height(db.health.height)
|
||||
end
|
||||
|
||||
function NP:Update_HealComm(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if db.health.enable and db.health.healPrediction then
|
||||
if not nameplate:IsElementEnabled('HealCommBar') then
|
||||
nameplate:EnableElement('HealCommBar')
|
||||
end
|
||||
|
||||
nameplate.HealCommBar.myBar:SetStatusBarColor(NP.db.colors.healPrediction.personal.r, NP.db.colors.healPrediction.personal.g, NP.db.colors.healPrediction.personal.b)
|
||||
nameplate.HealCommBar.otherBar:SetStatusBarColor(NP.db.colors.healPrediction.others.r, NP.db.colors.healPrediction.others.g, NP.db.colors.healPrediction.others.b)
|
||||
elseif nameplate:IsElementEnabled('HealCommBar') then
|
||||
nameplate:DisableElement('HealCommBar')
|
||||
end
|
||||
end
|
||||
|
||||
function NP.HealthClipFrame_HealComm(frame)
|
||||
local pred = frame.HealCommBar
|
||||
if pred then
|
||||
NP:SetAlpha_HealComm(pred, true)
|
||||
NP:SetVisibility_HealComm(pred)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:SetAlpha_HealComm(obj, show)
|
||||
obj.myBar:SetAlpha(show and 1 or 0)
|
||||
obj.otherBar:SetAlpha(show and 1 or 0)
|
||||
end
|
||||
|
||||
function NP:SetVisibility_HealComm(obj)
|
||||
-- the first update is from `HealthClipFrame_HealComm`
|
||||
-- we set this variable to allow `Configure_HealComm` to
|
||||
-- update the elements overflow lock later on by option
|
||||
if not obj.allowClippingUpdate then
|
||||
obj.allowClippingUpdate = true
|
||||
end
|
||||
|
||||
if obj.maxOverflow > 1 then
|
||||
obj.myBar:SetParent(obj.health)
|
||||
obj.otherBar:SetParent(obj.health)
|
||||
else
|
||||
obj.myBar:SetParent(obj.parent)
|
||||
obj.otherBar:SetParent(obj.parent)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_HealComm(frame)
|
||||
local health = frame.Health
|
||||
local parent = health.ClipFrame
|
||||
|
||||
local myBar = CreateFrame("StatusBar", nil, parent)
|
||||
local otherBar = CreateFrame("StatusBar", nil, parent)
|
||||
|
||||
myBar:SetFrameLevel(health:GetFrameLevel()+1)
|
||||
otherBar:SetFrameLevel(health:GetFrameLevel()+1)
|
||||
|
||||
NP.StatusBars[myBar] = true
|
||||
NP.StatusBars[otherBar] = true
|
||||
|
||||
local healPrediction = {
|
||||
myBar = myBar,
|
||||
otherBar = otherBar,
|
||||
PostUpdate = NP.UpdateHealComm,
|
||||
maxOverflow = 1,
|
||||
health = health,
|
||||
parent = parent,
|
||||
frame = frame
|
||||
}
|
||||
|
||||
NP:SetAlpha_HealComm(healPrediction)
|
||||
|
||||
return healPrediction
|
||||
end
|
||||
|
||||
function NP:Configure_HealComm(frame)
|
||||
local db = NP:PlateDB(frame)
|
||||
|
||||
if db.health.enable and db.health.healPrediction then
|
||||
if not frame:IsElementEnabled('HealComm4') then
|
||||
frame:EnableElement('HealComm4')
|
||||
end
|
||||
|
||||
local healPrediction = frame.HealCommBar
|
||||
local c = db.colors.healPrediction
|
||||
healPrediction.maxOverflow = 1 + (c.maxOverflow or 0)
|
||||
|
||||
if healPrediction.allowClippingUpdate then
|
||||
NP:SetVisibility_HealComm(healPrediction)
|
||||
end
|
||||
|
||||
local health = frame.Health
|
||||
local orientation = health:GetOrientation()
|
||||
|
||||
local myBar = healPrediction.myBar
|
||||
local otherBar = healPrediction.otherBar
|
||||
|
||||
myBar:SetOrientation(orientation)
|
||||
otherBar:SetOrientation(orientation)
|
||||
|
||||
if orientation == "HORIZONTAL" then
|
||||
local width = health:GetWidth()
|
||||
width = (width > 0 and width) or health.WIDTH
|
||||
local healthTexture = health:GetStatusBarTexture()
|
||||
|
||||
myBar:Size(width, 0)
|
||||
myBar:ClearAllPoints()
|
||||
myBar:Point("TOP", health, "TOP")
|
||||
myBar:Point("BOTTOM", health, "BOTTOM")
|
||||
myBar:Point("LEFT", healthTexture, "RIGHT")
|
||||
|
||||
otherBar:Size(width, 0)
|
||||
otherBar:ClearAllPoints()
|
||||
otherBar:Point("TOP", health, "TOP")
|
||||
otherBar:Point("BOTTOM", health, "BOTTOM")
|
||||
otherBar:Point("LEFT", myBar:GetStatusBarTexture(), "RIGHT")
|
||||
else
|
||||
local height = health:GetHeight()
|
||||
height = (height > 0 and height) or health.HEIGHT
|
||||
local healthTexture = health:GetStatusBarTexture()
|
||||
|
||||
myBar:Size(0, height)
|
||||
myBar:ClearAllPoints()
|
||||
myBar:Point("LEFT", health, "LEFT")
|
||||
myBar:Point("RIGHT", health, "RIGHT")
|
||||
myBar:Point("BOTTOM", healthTexture, "TOP")
|
||||
|
||||
otherBar:Size(0, height)
|
||||
otherBar:ClearAllPoints()
|
||||
otherBar:Point("LEFT", health, "LEFT")
|
||||
otherBar:Point("RIGHT", health, "RIGHT")
|
||||
otherBar:Point("BOTTOM", myBar:GetStatusBarTexture(), "TOP")
|
||||
end
|
||||
|
||||
frame.HealCommBar.myBar:SetStatusBarColor(NP.db.colors.healPrediction.personal.r, NP.db.colors.healPrediction.personal.g, NP.db.colors.healPrediction.personal.b)
|
||||
frame.HealCommBar.otherBar:SetStatusBarColor(NP.db.colors.healPrediction.others.r, NP.db.colors.healPrediction.others.g, NP.db.colors.healPrediction.others.b)
|
||||
elseif frame:IsElementEnabled('HealComm4') then
|
||||
frame:DisableElement('HealComm4')
|
||||
end
|
||||
end
|
||||
|
||||
local function UpdateFillBar(frame, previousTexture, bar, amount)
|
||||
if amount == 0 then
|
||||
bar:Hide()
|
||||
return previousTexture
|
||||
end
|
||||
|
||||
local orientation = frame:GetOrientation()
|
||||
bar:ClearAllPoints()
|
||||
if orientation == "HORIZONTAL" then
|
||||
bar:SetPoint("TOPLEFT", previousTexture, "TOPRIGHT")
|
||||
bar:SetPoint("BOTTOMLEFT", previousTexture, "BOTTOMRIGHT")
|
||||
else
|
||||
bar:SetPoint("BOTTOMRIGHT", previousTexture, "TOPRIGHT")
|
||||
bar:SetPoint("BOTTOMLEFT", previousTexture, "TOPLEFT")
|
||||
end
|
||||
|
||||
local totalWidth, totalHeight = frame:GetSize()
|
||||
if orientation == "HORIZONTAL" then
|
||||
bar:Width(totalWidth)
|
||||
else
|
||||
bar:Height(totalHeight)
|
||||
end
|
||||
|
||||
return bar:GetStatusBarTexture()
|
||||
end
|
||||
|
||||
function NP:UpdateHealComm(_, myIncomingHeal, allIncomingHeal)
|
||||
local health = self.health
|
||||
local previousTexture = health:GetStatusBarTexture()
|
||||
|
||||
previousTexture = UpdateFillBar(health, previousTexture, self.myBar, myIncomingHeal)
|
||||
UpdateFillBar(health, previousTexture, self.otherBar, allIncomingHeal)
|
||||
end
|
||||
@@ -0,0 +1,313 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
local strfind = strfind
|
||||
local ipairs, unpack = ipairs, unpack
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
local targetIndicators = {'Spark', 'TopIndicator', 'LeftIndicator', 'RightIndicator'}
|
||||
|
||||
function NP:Construct_QuestIcons(nameplate)
|
||||
local QuestIcons = CreateFrame('Frame', nameplate:GetName() .. 'QuestIcons', nameplate)
|
||||
QuestIcons:Size(20)
|
||||
QuestIcons:Hide()
|
||||
|
||||
for _, object in ipairs(NP.QuestIcons.iconTypes) do
|
||||
local icon = QuestIcons:CreateTexture(nil, 'BORDER', nil, 1)
|
||||
icon.Text = QuestIcons:CreateFontString(nil, 'OVERLAY')
|
||||
icon.Text:FontTemplate()
|
||||
icon:Hide()
|
||||
|
||||
QuestIcons[object] = icon
|
||||
end
|
||||
|
||||
QuestIcons.Item:SetTexCoord(unpack(E.TexCoords))
|
||||
QuestIcons.Chat:SetTexture([[Interface\WorldMap\ChatBubble_64.PNG]])
|
||||
QuestIcons.Chat:SetTexCoord(0, 0.5, 0.5, 1)
|
||||
|
||||
return QuestIcons
|
||||
end
|
||||
|
||||
function NP:Update_QuestIcons(nameplate)
|
||||
local plateDB = NP:PlateDB(nameplate)
|
||||
local db = plateDB.questIcon
|
||||
|
||||
if db and db.enable and (nameplate.frameType == 'FRIENDLY_NPC' or nameplate.frameType == 'ENEMY_NPC') then
|
||||
if not nameplate:IsElementEnabled('QuestIcons') then
|
||||
nameplate:EnableElement('QuestIcons')
|
||||
end
|
||||
|
||||
nameplate.QuestIcons:ClearAllPoints()
|
||||
nameplate.QuestIcons:Point(E.InversePoints[db.position], nameplate, db.position, db.xOffset, db.yOffset)
|
||||
|
||||
for _, object in ipairs(NP.QuestIcons.iconTypes) do
|
||||
local icon = nameplate.QuestIcons[object]
|
||||
icon:Size(db.size, db.size)
|
||||
icon:SetAlpha(db.hideIcon and 0 or 1)
|
||||
|
||||
local xoffset = strfind(db.textPosition, 'LEFT') and -2 or 2
|
||||
local yoffset = strfind(db.textPosition, 'BOTTOM') and 2 or -2
|
||||
icon.Text:ClearAllPoints()
|
||||
icon.Text:Point('CENTER', icon, db.textPosition, xoffset, yoffset)
|
||||
icon.Text:FontTemplate(LSM:Fetch('font', db.font), db.fontSize, db.fontOutline)
|
||||
icon.Text:SetJustifyH('CENTER')
|
||||
|
||||
icon.size, icon.position = db.size, db.position
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('QuestIcons') then
|
||||
nameplate:DisableElement('QuestIcons')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_ClassificationIndicator(nameplate)
|
||||
return nameplate:CreateTexture(nameplate:GetName() .. 'ClassificationIndicator', 'OVERLAY')
|
||||
end
|
||||
|
||||
function NP:Update_ClassificationIndicator(nameplate)
|
||||
local plateDB = NP:PlateDB(nameplate)
|
||||
local db = plateDB.eliteIcon
|
||||
|
||||
if db and db.enable and (nameplate.frameType == 'FRIENDLY_NPC' or nameplate.frameType == 'ENEMY_NPC') then
|
||||
if not nameplate:IsElementEnabled('ClassificationIndicator') then
|
||||
nameplate:EnableElement('ClassificationIndicator')
|
||||
end
|
||||
|
||||
nameplate.ClassificationIndicator:ClearAllPoints()
|
||||
nameplate.ClassificationIndicator:Size(db.size, db.size)
|
||||
nameplate.ClassificationIndicator:Point(E.InversePoints[db.position], nameplate, db.position, db.xOffset, db.yOffset)
|
||||
elseif nameplate:IsElementEnabled('ClassificationIndicator') then
|
||||
nameplate:DisableElement('ClassificationIndicator')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_TargetIndicator(nameplate)
|
||||
local TargetIndicator = CreateFrame('Frame', nameplate:GetName() .. 'TargetIndicator', nameplate)
|
||||
TargetIndicator:SetFrameLevel(nameplate:GetFrameLevel()-1)
|
||||
|
||||
TargetIndicator.Shadow = CreateFrame('Frame', nil, TargetIndicator)
|
||||
TargetIndicator.Shadow:Hide()
|
||||
|
||||
for _, object in ipairs(targetIndicators) do
|
||||
local indicator = TargetIndicator:CreateTexture(nil, 'BACKGROUND')
|
||||
indicator:Hide()
|
||||
|
||||
TargetIndicator[object] = indicator
|
||||
end
|
||||
|
||||
return TargetIndicator
|
||||
end
|
||||
|
||||
function NP:Update_TargetIndicator(nameplate)
|
||||
local enabled = nameplate:IsElementEnabled('TargetIndicator')
|
||||
if nameplate.frameType == 'PLAYER' then
|
||||
if enabled then
|
||||
nameplate:DisableElement('TargetIndicator')
|
||||
end
|
||||
|
||||
return
|
||||
elseif not enabled then
|
||||
nameplate:EnableElement('TargetIndicator')
|
||||
end
|
||||
|
||||
local tdb = NP.db.units.TARGET
|
||||
local indicator = nameplate.TargetIndicator
|
||||
indicator.arrow = E.Media.Textures[NP.db.units.TARGET.arrow] or E.Media.Textures.TopIndicator
|
||||
indicator.lowHealthThreshold = NP.db.lowHealthThreshold
|
||||
indicator.preferGlowColor = NP.db.colors.preferGlowColor
|
||||
indicator.style = tdb.glowStyle
|
||||
|
||||
if indicator.style ~= 'none' then
|
||||
local style, color, size, spacing = tdb.glowStyle, NP.db.colors.glowColor, tdb.arrowSize, tdb.arrowSpacing
|
||||
local r, g, b, a = color.r, color.g, color.b, color.a
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
-- background glow is 2, 6, and 8; 2 is background glow only
|
||||
if not db.health.enable and (style ~= 'style2' and style ~= 'style6' and style ~= 'style8') then
|
||||
style = 'style2'
|
||||
indicator.style = style
|
||||
end
|
||||
|
||||
-- top arrow is 3, 5, 6
|
||||
if indicator.TopIndicator and (style == 'style3' or style == 'style5' or style == 'style6') then
|
||||
indicator.TopIndicator:Point('BOTTOM', nameplate.Health, 'TOP', 0, spacing)
|
||||
indicator.TopIndicator:SetVertexColor(r, g, b, a)
|
||||
indicator.TopIndicator:SetSize(size, size)
|
||||
end
|
||||
|
||||
-- side arrows are 4, 7, 8
|
||||
if indicator.LeftIndicator and indicator.RightIndicator and (style == 'style4' or style == 'style7' or style == 'style8') then
|
||||
indicator.LeftIndicator:Point('LEFT', nameplate.Health, 'RIGHT', spacing, 0)
|
||||
indicator.RightIndicator:Point('RIGHT', nameplate.Health, 'LEFT', -spacing, 0)
|
||||
indicator.LeftIndicator:SetVertexColor(r, g, b, a)
|
||||
indicator.RightIndicator:SetVertexColor(r, g, b, a)
|
||||
indicator.LeftIndicator:SetSize(size, size)
|
||||
indicator.RightIndicator:SetSize(size, size)
|
||||
end
|
||||
|
||||
-- border glow is 1, 5, 7
|
||||
if indicator.Shadow and (style == 'style1' or style == 'style5' or style == 'style7') then
|
||||
indicator.Shadow:SetOutside(nameplate.Health, E.PixelMode and 6 or 8, E.PixelMode and 6 or 8, nil, true)
|
||||
indicator.Shadow:SetBackdropBorderColor(r, g, b)
|
||||
indicator.Shadow:SetAlpha(a)
|
||||
end
|
||||
|
||||
-- background glow is 2, 6, and 8
|
||||
if indicator.Spark and (style == 'style2' or style == 'style6' or style == 'style8') then
|
||||
local size
|
||||
if db.health.enable and not (db.nameOnly or nameOnlySF) then
|
||||
parent = nameplate.Health
|
||||
size = E.Border + 14
|
||||
else
|
||||
parent = nameplate
|
||||
size = -(E.Border + 4)
|
||||
end
|
||||
indicator.Spark:Point('TOPLEFT', parent, 'TOPLEFT', -(size * 2), size)
|
||||
indicator.Spark:Point('BOTTOMRIGHT', parent, 'BOTTOMRIGHT', (size * 2), -size)
|
||||
indicator.Spark:SetVertexColor(r, g, b, a)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Highlight(nameplate)
|
||||
Highlight = nameplate.nameplateAnchor.blizzHighlight
|
||||
return Highlight
|
||||
end
|
||||
|
||||
function NP:Update_Highlight(nameplate, nameOnlySF)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if NP.db.highlight and db.enable then
|
||||
if not nameplate:IsElementEnabled('Highlight') then
|
||||
nameplate:EnableElement('Highlight')
|
||||
end
|
||||
|
||||
local highlight = nameplate.Highlight
|
||||
if highlight:GetParent() ~= nameplate then
|
||||
highlight:SetParent(nameplate)
|
||||
end
|
||||
|
||||
if highlight:GetDrawLayer() ~= "OVERLAY" then
|
||||
Highlight:SetDrawLayer("OVERLAY")
|
||||
end
|
||||
|
||||
highlight:SetTexture(E.Media.Textures.Spark)
|
||||
highlight:SetAllPoints(nameplate)
|
||||
|
||||
if db.health.enable and not (db.nameOnly or nameOnlySF) then
|
||||
highlight:SetAlpha(0.75)
|
||||
else
|
||||
highlight:SetAlpha(0.50)
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('Highlight') then
|
||||
nameplate:DisableElement('Highlight')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_PVPRole(nameplate)
|
||||
local texture = nameplate:CreateTexture(nameplate:GetName() .. 'PVPRole', 'OVERLAY', nil, 1)
|
||||
texture:Size(40)
|
||||
texture.HealerTexture = E.Media.Textures.Healer
|
||||
texture.TankTexture = E.Media.Textures.Tank
|
||||
texture:SetTexture(texture.HealerTexture)
|
||||
|
||||
texture:Hide()
|
||||
|
||||
return texture
|
||||
end
|
||||
|
||||
function NP:Update_PVPRole(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if (nameplate.frameType == 'FRIENDLY_PLAYER' or nameplate.frameType == 'ENEMY_PLAYER') and (db.markHealers or db.markTanks) then
|
||||
if not nameplate:IsElementEnabled('PVPRole') then
|
||||
nameplate:EnableElement('PVPRole')
|
||||
end
|
||||
|
||||
nameplate.PVPRole.ShowHealers = db.markHealers
|
||||
nameplate.PVPRole.ShowTanks = db.markTanks
|
||||
|
||||
nameplate.PVPRole:Point('RIGHT', nameplate.Health, 'LEFT', -6, 0)
|
||||
elseif nameplate:IsElementEnabled('PVPRole') then
|
||||
nameplate:DisableElement('PVPRole')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_Fader(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
local vis = db.visibility
|
||||
|
||||
if not vis or vis.showAlways then
|
||||
if nameplate:IsElementEnabled('Fader') then
|
||||
nameplate:DisableElement('Fader')
|
||||
|
||||
NP:PlateFade(nameplate, 0.5, nameplate:GetAlpha(), 1)
|
||||
end
|
||||
elseif db.enable then
|
||||
if not nameplate.Fader then
|
||||
nameplate.Fader = {}
|
||||
end
|
||||
|
||||
if not nameplate:IsElementEnabled('Fader') then
|
||||
nameplate:EnableElement('Fader')
|
||||
|
||||
nameplate.Fader:SetOption('MinAlpha', 0)
|
||||
nameplate.Fader:SetOption('Smooth', 0.3)
|
||||
nameplate.Fader:SetOption('Hover', true)
|
||||
--nameplate.Fader:SetOption('Power', true)
|
||||
nameplate.Fader:SetOption('Health', true)
|
||||
nameplate.Fader:SetOption('Casting', true)
|
||||
end
|
||||
|
||||
nameplate.Fader:SetOption('Combat', vis.showInCombat)
|
||||
nameplate.Fader:SetOption('PlayerTarget', vis.showWithTarget)
|
||||
nameplate.Fader:SetOption('DelayAlpha', (vis.alphaDelay > 0 and vis.alphaDelay) or nil)
|
||||
nameplate.Fader:SetOption('Delay', (vis.hideDelay > 0 and vis.hideDelay) or nil)
|
||||
|
||||
nameplate.Fader:ForceUpdate()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Cutaway(nameplate)
|
||||
local frameName = nameplate:GetName()
|
||||
local Cutaway = {}
|
||||
|
||||
Cutaway.Health = nameplate.Health.ClipFrame:CreateTexture(frameName .. 'CutawayHealth')
|
||||
local healthTexture = nameplate.Health:GetStatusBarTexture()
|
||||
Cutaway.Health:Point('TOPLEFT', healthTexture, 'TOPRIGHT')
|
||||
Cutaway.Health:Point('BOTTOMLEFT', healthTexture, 'BOTTOMRIGHT')
|
||||
|
||||
-- Cutaway.Power = nameplate.Power.ClipFrame:CreateTexture(frameName .. 'CutawayPower')
|
||||
-- local powerTexture = nameplate.Power:GetStatusBarTexture()
|
||||
-- Cutaway.Power:Point('TOPLEFT', powerTexture, 'TOPRIGHT')
|
||||
-- Cutaway.Power:Point('BOTTOMLEFT', powerTexture, 'BOTTOMRIGHT')
|
||||
|
||||
return Cutaway
|
||||
end
|
||||
|
||||
function NP:Update_Cutaway(nameplate)
|
||||
local eitherEnabled = NP.db.cutaway.health.enabled or NP.db.cutaway.power.enabled
|
||||
if not eitherEnabled then
|
||||
if nameplate:IsElementEnabled('Cutaway') then
|
||||
nameplate:DisableElement('Cutaway')
|
||||
end
|
||||
else
|
||||
if not nameplate:IsElementEnabled('Cutaway') then
|
||||
nameplate:EnableElement('Cutaway')
|
||||
end
|
||||
|
||||
nameplate.Cutaway:UpdateConfigurationValues(NP.db.cutaway)
|
||||
|
||||
if NP.db.cutaway.health.forceBlankTexture then
|
||||
nameplate.Cutaway.Health:SetTexture(E.media.blankTex)
|
||||
else
|
||||
nameplate.Cutaway.Health:SetTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
end
|
||||
|
||||
-- if NP.db.cutaway.power.forceBlankTexture then
|
||||
-- nameplate.Cutaway.Power:SetTexture(E.media.blankTex)
|
||||
-- else
|
||||
-- nameplate.Cutaway.Power:SetTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
-- end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,66 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
local _G = _G
|
||||
local unpack = unpack
|
||||
local hooksecurefunc = hooksecurefunc
|
||||
|
||||
function NP:Portrait_PostUpdate()
|
||||
local nameplate = self.__owner
|
||||
local db = NP:PlateDB(nameplate)
|
||||
local sf = NP:StyleFilterChanges(nameplate)
|
||||
|
||||
if sf.Portrait or (db.portrait and db.portrait.enable) then
|
||||
if db.portrait.classicon and nameplate.isPlayer then
|
||||
self:SetTexture([[Interface\WorldStateFrame\Icons-Classes]])
|
||||
self:SetTexCoord(unpack(_G.CLASS_ICON_TCOORDS[nameplate.classFile]))
|
||||
self.backdrop:Hide()
|
||||
else
|
||||
self:SetTexCoord(.18, .82, .18, .82)
|
||||
self.backdrop:Show()
|
||||
end
|
||||
else
|
||||
self.backdrop:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_PortraitBackdrop()
|
||||
if self.backdrop then
|
||||
self.backdrop:SetShown(self:IsShown())
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Portrait(nameplate)
|
||||
local Portrait = nameplate:CreateTexture(nameplate:GetName() .. 'Portrait', 'OVERLAY', nil, 2)
|
||||
Portrait:SetTexCoord(.18, .82, .18, .82)
|
||||
Portrait:CreateBackdrop(nil, nil, nil, nil, nil, true, true)
|
||||
Portrait:Hide()
|
||||
|
||||
Portrait.PostUpdate = NP.Portrait_PostUpdate
|
||||
hooksecurefunc(Portrait, 'Hide', NP.Update_PortraitBackdrop)
|
||||
hooksecurefunc(Portrait, 'Show', NP.Update_PortraitBackdrop)
|
||||
|
||||
return Portrait
|
||||
end
|
||||
|
||||
function NP:Update_Portrait(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
local sf = NP:StyleFilterChanges(nameplate)
|
||||
|
||||
if sf.Portrait or (db.portrait and db.portrait.enable) then
|
||||
if not nameplate:IsElementEnabled('Portrait') then
|
||||
nameplate:EnableElement('Portrait')
|
||||
nameplate.Portrait:ForceUpdate()
|
||||
end
|
||||
|
||||
nameplate.Portrait:Size(db.portrait.width, db.portrait.height)
|
||||
|
||||
-- These values are forced in name only mode inside of DisablePlate
|
||||
if not (db.nameOnly or sf.NameOnly) then
|
||||
nameplate.Portrait:ClearAllPoints()
|
||||
nameplate.Portrait:Point(E.InversePoints[db.portrait.position], nameplate, db.portrait.position, db.portrait.xOffset, db.portrait.yOffset)
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('Portrait') then
|
||||
nameplate:DisableElement('Portrait')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,148 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local UF = E:GetModule('UnitFrames')
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
local unpack = unpack
|
||||
local UnitPlayerControlled = UnitPlayerControlled
|
||||
local UnitClass = UnitClass
|
||||
local UnitReaction = UnitReaction
|
||||
local UnitIsConnected = UnitIsConnected
|
||||
local CreateFrame = CreateFrame
|
||||
local UnitPowerType = UnitPowerType
|
||||
local POWERTYPE_ALTERNATE = 10
|
||||
|
||||
function NP:Power_UpdateColor(_, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if self.unit ~= unit then return end
|
||||
|
||||
local element = self.Power
|
||||
local ptype, ptoken, altR, altG, altB = UnitPowerType(unit)
|
||||
element.token = ptoken
|
||||
|
||||
local sf = NP:StyleFilterChanges(self)
|
||||
if sf.PowerColor then return end
|
||||
|
||||
local Selection = element.colorSelection and NP:UnitSelectionType(unit, element.considerSelectionInCombatHostile)
|
||||
|
||||
local r, g, b, t, atlas
|
||||
if element.colorDisconnected and not UnitIsConnected(unit) then
|
||||
t = self.colors.disconnected
|
||||
elseif element.colorPower then
|
||||
if element.displayType ~= POWERTYPE_ALTERNATE then
|
||||
t = NP.db.colors.power[ptoken or ptype]
|
||||
if not t then
|
||||
if element.GetAlternativeColor then
|
||||
r, g, b = element:GetAlternativeColor(unit, ptype, ptoken, altR, altG, altB)
|
||||
elseif altR then
|
||||
r, g, b = altR, altG, altB
|
||||
if r > 1 or g > 1 or b > 1 then -- BUG: As of 7.0.3, altR, altG, altB may be in 0-1 or 0-255 range.
|
||||
r, g, b = r / 255, g / 255, b / 255
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
t = NP.db.colors.power.ALT_POWER
|
||||
end
|
||||
|
||||
if element.useAtlas and t and t.atlas then
|
||||
atlas = t.atlas
|
||||
end
|
||||
elseif (element.colorClass and self.isPlayer) or (element.colorClassNPC and not self.isPlayer) or (element.colorClassPet and UnitPlayerControlled(unit) and not self.isPlayer) then
|
||||
local _, class = UnitClass(unit)
|
||||
t = self.colors.class[class]
|
||||
elseif Selection then
|
||||
t = NP.db.colors.selection[Selection]
|
||||
elseif element.colorReaction and UnitReaction(unit, 'player') then
|
||||
local reaction = UnitReaction(unit, 'player')
|
||||
t = NP.db.colors.reactions[reaction == 4 and 'neutral' or reaction <= 3 and 'bad' or 'good']
|
||||
elseif element.colorSmooth then
|
||||
local adjust = 0 - (element.min or 0)
|
||||
r, g, b = self:ColorGradient((element.cur or 1) + adjust, (element.max or 1) + adjust, unpack(element.smoothGradient or self.colors.smooth))
|
||||
end
|
||||
|
||||
if t then
|
||||
r, g, b = t[1] or t.r, t[2] or t.g, t[3] or t.b
|
||||
end
|
||||
|
||||
if atlas then
|
||||
element:SetStatusBarTexture(atlas)
|
||||
element:SetStatusBarColor(1, 1, 1)
|
||||
elseif b then
|
||||
element:SetStatusBarColor(r, g, b)
|
||||
end
|
||||
|
||||
if element.bg and b then element.bg:SetVertexColor(r * NP.multiplier, g * NP.multiplier, b * NP.multiplier) end
|
||||
|
||||
if element.PostUpdateColor then
|
||||
element:PostUpdateColor(unit, r, g, b)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Power_PostUpdate(_, cur) --unit, cur, min, max
|
||||
local db = NP:PlateDB(self.__owner)
|
||||
if not db.enable then return end
|
||||
|
||||
if self.__owner.frameType ~= 'PLAYER' and db.power.displayAltPower and not self.displayType then
|
||||
self:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
if db.power and db.power.enable and db.power.hideWhenEmpty and (cur == 0) then
|
||||
self:Hide()
|
||||
else
|
||||
self:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Power(nameplate)
|
||||
local Power = CreateFrame('StatusBar', nameplate:GetName()..'Power', nameplate)
|
||||
Power:CreateBackdrop('Transparent', nil, nil, nil, nil, true, true)
|
||||
|
||||
NP.StatusBars[Power] = true
|
||||
|
||||
--Power.frequentUpdates = true
|
||||
Power.colorTapping = false
|
||||
Power.colorClass = false
|
||||
|
||||
Power.PostUpdate = NP.Power_PostUpdate
|
||||
Power.UpdateColor = NP.Power_UpdateColor
|
||||
|
||||
local clipFrame = CreateFrame('Frame', nil, Power)
|
||||
clipFrame:SetAllPoints()
|
||||
clipFrame:EnableMouse(false)
|
||||
clipFrame.__frame = Power
|
||||
Power.ClipFrame = clipFrame
|
||||
|
||||
return Power
|
||||
end
|
||||
|
||||
function NP:Update_Power(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if db.power.enable then
|
||||
if not nameplate:IsElementEnabled('Power') then
|
||||
nameplate:EnableElement('Power')
|
||||
end
|
||||
|
||||
nameplate.Power:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
nameplate.Power:Point('CENTER', nameplate, 'CENTER', db.power.xOffset, db.power.yOffset)
|
||||
|
||||
E:SetSmoothing(nameplate.Power, NP.db.smoothbars)
|
||||
elseif nameplate:IsElementEnabled('Power') then
|
||||
nameplate:DisableElement('Power')
|
||||
end
|
||||
|
||||
nameplate.Power.displayAltPower = db.power.displayAltPower
|
||||
nameplate.Power.useAtlas = db.power.useAtlas
|
||||
nameplate.Power.colorClass = db.power.useClassColor
|
||||
nameplate.Power.colorPower = not db.power.useClassColor
|
||||
nameplate.Power.width = db.power.width
|
||||
nameplate.Power.height = db.power.height
|
||||
nameplate.Power:Size(db.power.width, db.power.height)
|
||||
end
|
||||
@@ -0,0 +1,64 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
local strlower = strlower
|
||||
|
||||
function NP:PvPIndicator_PostUpdate(_, status)
|
||||
if status and status ~= 'FFA' and (not self.Badge or not self.Badge:IsShown()) then
|
||||
self:SetAtlas('bfa-landingbutton-'..strlower(status)..'-up')
|
||||
self:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_PvPIndicator(nameplate)
|
||||
local PvPIndicator = nameplate:CreateTexture(nil, 'OVERLAY')
|
||||
PvPIndicator.Badge_ = nameplate:CreateTexture(nil, 'ARTWORK')
|
||||
PvPIndicator.PostUpdate = NP.PvPIndicator_PostUpdate
|
||||
|
||||
return PvPIndicator
|
||||
end
|
||||
|
||||
function NP:Update_PvPIndicator(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if db.pvpindicator and db.pvpindicator.enable then
|
||||
if not nameplate:IsElementEnabled('PvPIndicator') then
|
||||
nameplate:EnableElement('PvPIndicator')
|
||||
end
|
||||
|
||||
nameplate.PvPIndicator:Size(db.pvpindicator.size, db.pvpindicator.size)
|
||||
nameplate.PvPIndicator.Badge_:Size(db.pvpindicator.size + 14, db.pvpindicator.size + 16)
|
||||
|
||||
nameplate.PvPIndicator.Badge = nil
|
||||
|
||||
if db.pvpindicator.showBadge then
|
||||
nameplate.PvPIndicator.Badge = nameplate.PvPIndicator.Badge_
|
||||
end
|
||||
|
||||
nameplate.PvPIndicator:ClearAllPoints()
|
||||
nameplate.PvPIndicator:Point(E.InversePoints[db.pvpindicator.position], nameplate, db.pvpindicator.position, db.pvpindicator.xOffset, db.pvpindicator.yOffset)
|
||||
elseif nameplate:IsElementEnabled('PvPIndicator') then
|
||||
nameplate:DisableElement('PvPIndicator')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_PvPClassificationIndicator(nameplate)
|
||||
local PvPClassificationIndicator = nameplate:CreateTexture(nil, 'OVERLAY')
|
||||
return PvPClassificationIndicator
|
||||
end
|
||||
|
||||
function NP:Update_PvPClassificationIndicator(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if (nameplate.frameType == 'ENEMY_PLAYER' or nameplate.frameType == 'FRIENDLY_PLAYER' or nameplate.frameType == 'PLAYER') and db.pvpclassificationindicator and db.pvpclassificationindicator.enable then
|
||||
if not nameplate:IsElementEnabled('PvPClassificationIndicator') then
|
||||
nameplate:EnableElement('PvPClassificationIndicator')
|
||||
end
|
||||
|
||||
nameplate.PvPClassificationIndicator:ClearAllPoints()
|
||||
nameplate.PvPClassificationIndicator:Point(E.InversePoints[db.pvpclassificationindicator.position], nameplate, db.pvpclassificationindicator.position, db.pvpclassificationindicator.xOffset, db.pvpclassificationindicator.yOffset)
|
||||
nameplate.PvPClassificationIndicator:Size(db.pvpclassificationindicator.size)
|
||||
elseif nameplate:IsElementEnabled('PvPClassificationIndicator') then
|
||||
nameplate:DisableElement('PvPClassificationIndicator')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
local GetRaidTargetIndex = GetRaidTargetIndex
|
||||
local SetRaidTargetIconTexture = SetRaidTargetIconTexture
|
||||
|
||||
function NP:RaidTargetIndicator_Override()
|
||||
local element = self.RaidTargetIndicator
|
||||
local index = self.unit and GetRaidTargetIndex(self.unit)
|
||||
|
||||
if index then
|
||||
SetRaidTargetIconTexture(element, index)
|
||||
element:Show()
|
||||
else
|
||||
element:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_RaidTargetIndicator(nameplate)
|
||||
local RaidTargetIndicator = nameplate:CreateTexture(nil, 'OVERLAY', nil, 7)
|
||||
RaidTargetIndicator.Override = NP.RaidTargetIndicator_Override
|
||||
RaidTargetIndicator:Hide()
|
||||
|
||||
return RaidTargetIndicator
|
||||
end
|
||||
|
||||
function NP:Update_RaidTargetIndicator(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if db.raidTargetIndicator and db.raidTargetIndicator.enable then
|
||||
if not nameplate:IsElementEnabled('RaidTargetIndicator') then
|
||||
nameplate:EnableElement('RaidTargetIndicator')
|
||||
end
|
||||
|
||||
nameplate.RaidTargetIndicator:ClearAllPoints()
|
||||
nameplate.RaidTargetIndicator:Point(E.InversePoints[db.raidTargetIndicator.position], nameplate, db.raidTargetIndicator.position, db.raidTargetIndicator.xOffset, db.raidTargetIndicator.yOffset)
|
||||
nameplate.RaidTargetIndicator:Size(db.raidTargetIndicator.size)
|
||||
elseif nameplate:IsElementEnabled('RaidTargetIndicator') then
|
||||
nameplate:DisableElement('RaidTargetIndicator')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
function NP:Construct_TagText(nameplate)
|
||||
local Text = nameplate:CreateFontString(nil, 'OVERLAY')
|
||||
Text:FontTemplate(E.LSM:Fetch('font', NP.db.font), NP.db.fontSize, NP.db.fontOutline)
|
||||
|
||||
return Text
|
||||
end
|
||||
|
||||
function NP:Update_TagText(nameplate, element, db, hide)
|
||||
if not db then return end
|
||||
|
||||
if db.enable and not hide then
|
||||
nameplate:Tag(element, db.format or '')
|
||||
element:FontTemplate(LSM:Fetch('font', db.font), db.fontSize, db.fontOutline)
|
||||
element:UpdateTag()
|
||||
|
||||
element:ClearAllPoints()
|
||||
element:Point(E.InversePoints[db.position], db.parent == 'Nameplate' and nameplate or nameplate[db.parent], db.position, db.xOffset, db.yOffset)
|
||||
element:Show()
|
||||
else
|
||||
nameplate:Untag(element)
|
||||
element:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_Tags(nameplate, nameOnlySF)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
local hide = db.nameOnly or nameOnlySF
|
||||
|
||||
NP:Update_TagText(nameplate, nameplate.Name, db.name)
|
||||
NP:Update_TagText(nameplate, nameplate.Title, db.title)
|
||||
NP:Update_TagText(nameplate, nameplate.Level, db.level, hide)
|
||||
NP:Update_TagText(nameplate, nameplate.Health.Text, db.health and db.health.text, hide)
|
||||
--NP:Update_TagText(nameplate, nameplate.Power.Text, db.power and db.power.text, hide)
|
||||
end
|
||||
@@ -0,0 +1,96 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
local UnitName = UnitName
|
||||
local UnitExists = UnitExists
|
||||
local UnitIsUnit = UnitIsUnit
|
||||
|
||||
NP.ThreatPets = {
|
||||
}
|
||||
|
||||
function NP:ThreatIndicator_PreUpdate(unit, pass)
|
||||
local nameplate, db, unitTarget, imTank = self.__owner, NP.db.threat, unit..'target', E.myrole == 'TANK' or NP.GroupRoles[E.myname] == 'TANK'
|
||||
local unitRole = NP.IsInGroup and (UnitExists(unitTarget) and not UnitIsUnit(unitTarget, 'player')) and NP.GroupRoles[UnitName(unitTarget)] or 'NONE'
|
||||
local unitTank = unitRole == 'TANK' or (db.beingTankedByPet and NP.ThreatPets[NP:UnitNPCID(unitTarget)])
|
||||
local isTank, offTank, feedbackUnit = unitTank or imTank, db.beingTankedByTank and (unitTank and imTank) or false, (unitTank and unitTarget) or 'player'
|
||||
|
||||
nameplate.ThreatScale = nil
|
||||
|
||||
if pass then
|
||||
return isTank, offTank, feedbackUnit
|
||||
else
|
||||
self.feedbackUnit = feedbackUnit
|
||||
self.offTank = offTank
|
||||
self.isTank = isTank
|
||||
end
|
||||
end
|
||||
|
||||
function NP:ThreatIndicator_PostUpdate(unit, status)
|
||||
local nameplate, colors, db = self.__owner, NP.db.colors.threat, NP.db.threat
|
||||
local sf = NP:StyleFilterChanges(nameplate)
|
||||
if not status and not sf.Scale then
|
||||
nameplate.ThreatScale = 1
|
||||
NP:ScalePlate(nameplate, 1)
|
||||
elseif status and db.enable and db.useThreatColor then
|
||||
NP:Health_SetColors(nameplate, true)
|
||||
nameplate.ThreatStatus = status
|
||||
|
||||
local Color, Scale
|
||||
if status == 3 then -- securely tanking
|
||||
Color = self.offTank and colors.offTankColor or self.isTank and colors.goodColor or colors.badColor
|
||||
Scale = self.isTank and db.goodScale or db.badScale
|
||||
elseif status == 2 then -- insecurely tanking
|
||||
Color = self.offTank and colors.offTankColorBadTransition or self.isTank and colors.badTransition or colors.goodTransition
|
||||
Scale = 1
|
||||
elseif status == 1 then -- not tanking but threat higher than tank
|
||||
Color = self.offTank and colors.offTankColorGoodTransition or self.isTank and colors.goodTransition or colors.badTransition
|
||||
Scale = 1
|
||||
else -- not tanking at all
|
||||
Color = self.isTank and colors.badColor or colors.goodColor
|
||||
Scale = self.isTank and db.badScale or db.goodScale
|
||||
end
|
||||
|
||||
if sf.HealthColor then
|
||||
self.r, self.g, self.b = Color.r, Color.g, Color.b
|
||||
else
|
||||
nameplate.Health:SetStatusBarColor(Color.r, Color.g, Color.b)
|
||||
end
|
||||
|
||||
if Scale then
|
||||
nameplate.ThreatScale = Scale
|
||||
|
||||
if not sf.Scale then
|
||||
NP:ScalePlate(nameplate, Scale)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_ThreatIndicator(nameplate)
|
||||
local ThreatIndicator = nameplate:CreateTexture(nil, 'OVERLAY')
|
||||
ThreatIndicator:Size(16, 16)
|
||||
ThreatIndicator:Hide()
|
||||
ThreatIndicator:Point('CENTER', nameplate, 'TOPRIGHT')
|
||||
|
||||
ThreatIndicator.PreUpdate = NP.ThreatIndicator_PreUpdate
|
||||
ThreatIndicator.PostUpdate = NP.ThreatIndicator_PostUpdate
|
||||
|
||||
return ThreatIndicator
|
||||
end
|
||||
|
||||
function NP:Update_ThreatIndicator(nameplate)
|
||||
local db = NP.db.threat
|
||||
if nameplate.frameType == 'ENEMY_NPC' and db.enable then
|
||||
if not nameplate:IsElementEnabled('ThreatIndicator') then
|
||||
nameplate:EnableElement('ThreatIndicator')
|
||||
end
|
||||
|
||||
if db.indicator then
|
||||
nameplate.ThreatIndicator:SetAlpha(1)
|
||||
else
|
||||
nameplate.ThreatIndicator:SetAlpha(0)
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('ThreatIndicator') then
|
||||
nameplate:DisableElement('ThreatIndicator')
|
||||
end
|
||||
end
|
||||
@@ -1,17 +1,19 @@
|
||||
<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 xmlns='http://www.blizzard.com/wow/ui/'>
|
||||
<Script file='Nameplates.lua'/>
|
||||
<Script file='StyleFilter.lua'/>
|
||||
<Script file='Elements\Auras.lua'/>
|
||||
<Script file='Elements\BossMods.lua'/>
|
||||
<Script file='Elements\CastBar.lua'/>
|
||||
<Script file='Elements\ClassPower.lua'/>
|
||||
<Script file='Elements\Health.lua'/>
|
||||
<Script file='Elements\Plugins.lua'/>
|
||||
<Script file='Elements\Power.lua'/>
|
||||
<Script file='Elements\Portraits.lua'/>
|
||||
<Script file='Elements\PvP.lua'/>
|
||||
<Script file='Elements\RaidTargetIndicator.lua'/>
|
||||
<Script file='Elements\Tags.lua'/>
|
||||
<Script file='Elements\Threat.lua'/>
|
||||
<Script file='Plugins\ClassificationIndicator.lua'/>
|
||||
<Script file='Plugins\QuestIcons.lua'/>
|
||||
<Script file='Plugins\TargetIndicator.lua'/>
|
||||
</Ui>
|
||||
+640
-1048
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,60 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local oUF = E.oUF
|
||||
|
||||
local function Update(self)
|
||||
local element = self.ClassificationIndicator
|
||||
|
||||
if element.PreUpdate then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
local classification = self.classification
|
||||
if classification == 'elite' or classification == 'worldboss' then
|
||||
element:SetAtlas('nameplates-icon-elite-gold')
|
||||
element:Show()
|
||||
elseif classification == 'rareelite' or classification == 'rare' then
|
||||
element:SetAtlas('nameplates-icon-elite-silver')
|
||||
element:Show()
|
||||
else
|
||||
element:Hide()
|
||||
end
|
||||
|
||||
if element.PostUpdate then
|
||||
return element:PostUpdate(classification)
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
return (self.ClassificationIndicator.Override or Update) (self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
local element = self.ClassificationIndicator
|
||||
if element then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
|
||||
if element:IsObjectType('Texture') and not element:GetTexture() then
|
||||
element:SetTexture([[Interface\TARGETINGFRAME\Nameplates]])
|
||||
end
|
||||
|
||||
self:RegisterEvent('UNIT_CLASSIFICATION_CHANGED', Path)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
local element = self.ClassificationIndicator
|
||||
if element then
|
||||
element:Hide()
|
||||
|
||||
self:UnregisterEvent('UNIT_CLASSIFICATION_CHANGED', Path)
|
||||
end
|
||||
end
|
||||
|
||||
oUF:AddElement('ClassificationIndicator', Path, Enable, Disable)
|
||||
@@ -0,0 +1,77 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local oUF = E.oUF
|
||||
|
||||
local UnitExists = UnitExists
|
||||
local UnitIsUnit = UnitIsUnit
|
||||
|
||||
local function MouseOnUnit(frame)
|
||||
if frame and frame:IsVisible() and UnitExists('mouseover') then
|
||||
return frame.unit and UnitIsUnit('mouseover', frame.unit)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function OnUpdate(self, elapsed)
|
||||
if self.elapsed and self.elapsed > 0.1 then
|
||||
if not MouseOnUnit(self) then
|
||||
self:Hide()
|
||||
self:ForceUpdate()
|
||||
end
|
||||
|
||||
self.elapsed = 0
|
||||
else
|
||||
self.elapsed = (self.elapsed or 0) + elapsed
|
||||
end
|
||||
end
|
||||
|
||||
local function Update(self)
|
||||
local element = self.Highlight
|
||||
|
||||
if element.PreUpdate then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
if MouseOnUnit(self) then
|
||||
element:Show()
|
||||
else
|
||||
element:Hide()
|
||||
end
|
||||
|
||||
if element.PostUpdate then
|
||||
return element:PostUpdate(element:IsShown())
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
return (self.Highlight.Override or Update)(self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
local element = self.Highlight
|
||||
if element then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
element:SetScript('OnUpdate', OnUpdate)
|
||||
|
||||
self:RegisterEvent('UPDATE_MOUSEOVER_UNIT', Path, true)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
local element = self.Highlight
|
||||
if element then
|
||||
element:Hide()
|
||||
element:SetScript('OnUpdate', nil)
|
||||
|
||||
self:UnregisterEvent('UPDATE_MOUSEOVER_UNIT', Path)
|
||||
end
|
||||
end
|
||||
|
||||
oUF:AddElement('Highlight', Path, Enable, Disable)
|
||||
@@ -0,0 +1,315 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local oUF = E.oUF
|
||||
|
||||
local _G = _G
|
||||
local pairs, ipairs, ceil, floor, tonumber = pairs, ipairs, ceil, floor, tonumber
|
||||
local wipe, strmatch, strlower, strfind = wipe, strmatch, strlower, strfind
|
||||
|
||||
local IsInInstance = IsInInstance
|
||||
local UnitIsPlayer = UnitIsPlayer
|
||||
local GetQuestLogSpecialItemInfo = GetQuestLogSpecialItemInfo
|
||||
local GetQuestLogTitle = GetQuestLogTitle
|
||||
local GetNumQuestLogEntries = GetNumQuestLogEntries
|
||||
local C_Quest_GetQuestID = GenerateClosure(C_Quest.GetQuestID, C_Quest)
|
||||
local ThreatTooltip = THREAT_TOOLTIP:gsub('%%d', '%%d-')
|
||||
|
||||
local questIcons = {
|
||||
iconTypes = { 'Default', 'Item', 'Skull', 'Chat' },
|
||||
indexByID = {}, --[questID] = questIndex
|
||||
activeQuests = {} --[questTitle] = questID
|
||||
}
|
||||
|
||||
NP.QuestIcons = questIcons
|
||||
|
||||
local typesLocalized = {
|
||||
enUS = {
|
||||
--- short matching applies here so,
|
||||
-- kill: killed, destory: destoryed, etc ...
|
||||
KILL = {'slain', 'destroy', 'eliminate', 'repel', 'kill', 'defeat'},
|
||||
CHAT = {'speak', 'talk'}
|
||||
},
|
||||
deDE = {
|
||||
KILL = {'besiegen', 'besiegt', 'getötet', 'töten', 'tötet', 'vernichtet', 'zerstört', 'genährt'},
|
||||
CHAT = {'befragt', 'sprecht'}
|
||||
},
|
||||
ruRU = {
|
||||
KILL = {'убит', 'уничтож', 'разбомблен', 'разбит', 'сразит'},
|
||||
CHAT = {'поговорит', 'спрашивать'}
|
||||
},
|
||||
esMX = {
|
||||
-- asesinad: asesinado, asesinados, asesinada, asesinadas
|
||||
-- derrota: derrotar, derrotado, derrotados, derrotada, derrotadas
|
||||
-- destrui: destruir, destruido, destruidos, destruida, destruidas
|
||||
-- elimin: eliminar, elimine, eliminadas, eliminada, eliminados, eliminado
|
||||
-- repel: repele, repelido, repelidos, repelida, repelidas
|
||||
KILL = {'asesinad', 'destrui', 'elimin', 'repel', 'derrota'},
|
||||
CHAT = {'habla', 'pídele'}
|
||||
},
|
||||
ptBR = {
|
||||
-- destrui: above but also destruição
|
||||
-- repel: repelir, repelido, repelidos, repelida, repelidas
|
||||
KILL = {'morto', 'morta', 'matar', 'destrui', 'elimin', 'repel', 'derrota'},
|
||||
CHAT = {'falar', 'pedir'}
|
||||
},
|
||||
frFR = {
|
||||
-- tué: tués, tuée, tuées
|
||||
-- abattu: abattus, abattue
|
||||
-- détrui: détruite, détruire, détruit, détruits, détruites
|
||||
-- repouss: repousser, repoussés, repoussée, repoussées
|
||||
-- élimin: éliminer, éliminé, éliminés, éliminée, éliminées
|
||||
KILL = {'tué', 'tuer', 'attaqué', 'attaque', 'abattre', 'abattu', 'détrui', 'élimin', 'repouss', 'vaincu', 'vaincre'},
|
||||
-- demande: demander, demandez
|
||||
-- parle: parler, parlez
|
||||
CHAT = {'parle', 'demande'}
|
||||
},
|
||||
koKR = {
|
||||
KILL = {'쓰러뜨리기', '물리치기', '공격', '파괴'},
|
||||
CHAT = {'대화'}
|
||||
},
|
||||
zhCN = {
|
||||
KILL = {'消灭', '摧毁', '击败', '毁灭', '击退'},
|
||||
CHAT = {'交谈', '谈一谈'}
|
||||
},
|
||||
zhTW = {
|
||||
KILL = {'毀滅', '擊退', '殺死'},
|
||||
CHAT = {'交談', '說話'}
|
||||
},
|
||||
}
|
||||
|
||||
local questTypes = typesLocalized[E.locale] or typesLocalized.enUS
|
||||
|
||||
local function CheckTextForQuest(text)
|
||||
local x, y = strmatch(text, '(%d+)/(%d+)')
|
||||
if x and y then
|
||||
local diff = floor(y - x)
|
||||
if diff > 0 then
|
||||
return diff
|
||||
end
|
||||
elseif not strmatch(text, ThreatTooltip) then
|
||||
local progress = tonumber(strmatch(text, '([%d%.]+)%%'))
|
||||
if progress and progress <= 100 then
|
||||
return ceil(100 - progress), true
|
||||
end
|
||||
end
|
||||
end
|
||||
NP.QuestIcons.CheckTextForQuest = CheckTextForQuest
|
||||
|
||||
local function GetQuests(unitID)
|
||||
if IsInInstance() then return end
|
||||
|
||||
E.ScanTooltip:SetOwner(_G.UIParent, 'ANCHOR_NONE')
|
||||
E.ScanTooltip:SetUnit(unitID)
|
||||
E.ScanTooltip:Show()
|
||||
|
||||
local QuestList, notMyQuest, activeID
|
||||
for i = 3, E.ScanTooltip:NumLines() do
|
||||
local str = _G['ElvUI_ScanTooltipTextLeft' .. i]
|
||||
local text = str and str:GetText()
|
||||
if not text or text == '' then return end
|
||||
|
||||
if UnitIsPlayer(text) then
|
||||
notMyQuest = text ~= E.myname
|
||||
elseif text and not notMyQuest then
|
||||
local count, percent = CheckTextForQuest(text)
|
||||
|
||||
-- this line comes from one line up in the tooltip
|
||||
local activeQuest = questIcons.activeQuests[text]
|
||||
if activeQuest then activeID = activeQuest end
|
||||
|
||||
if count then
|
||||
local type, index, texture, _
|
||||
if activeID then
|
||||
index = questIcons.indexByID[activeID]
|
||||
_, texture = GetQuestLogSpecialItemInfo(index)
|
||||
end
|
||||
|
||||
if texture then
|
||||
type = 'QUEST_ITEM'
|
||||
else
|
||||
local lowerText = strlower(text)
|
||||
|
||||
-- check kill type first
|
||||
for _, listText in ipairs(questTypes.KILL) do
|
||||
if strfind(lowerText, listText, nil, true) then
|
||||
type = 'KILL'
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- check chat type if kill type doesn't exist
|
||||
if not type then
|
||||
for _, listText in ipairs(questTypes.CHAT) do
|
||||
if strfind(lowerText, listText, nil, true) then
|
||||
type = 'CHAT'
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not QuestList then QuestList = {} end
|
||||
QuestList[#QuestList + 1] = {
|
||||
isPercent = percent,
|
||||
itemTexture = texture,
|
||||
objectiveCount = count,
|
||||
questType = type or 'DEFAULT',
|
||||
-- below keys are currently unused
|
||||
questLogIndex = index,
|
||||
questID = activeID
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
E.ScanTooltip:Hide()
|
||||
return QuestList
|
||||
end
|
||||
|
||||
local function hideIcons(element)
|
||||
for _, object in pairs(questIcons.iconTypes) do
|
||||
local icon = element[object]
|
||||
icon:Hide()
|
||||
|
||||
if icon.Text then
|
||||
icon.Text:SetText('')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Update(self, event, arg1)
|
||||
local element = self.QuestIcons
|
||||
if not element then return end
|
||||
|
||||
local unit = (event == 'UNIT_NAME_UPDATE' and arg1) or self.unit
|
||||
if unit ~= self.unit then return end
|
||||
|
||||
if element.PreUpdate then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
hideIcons(element)
|
||||
|
||||
local QuestList = GetQuests(unit)
|
||||
if QuestList then
|
||||
element:Show()
|
||||
else
|
||||
element:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
local shownCount
|
||||
for i = 1, #QuestList do
|
||||
local quest = QuestList[i]
|
||||
local objectiveCount = quest.objectiveCount
|
||||
local questType = quest.questType
|
||||
local isPercent = quest.isPercent
|
||||
|
||||
if isPercent or objectiveCount > 0 then
|
||||
local icon
|
||||
if questType == 'DEFAULT' then
|
||||
icon = element.Default
|
||||
elseif questType == 'KILL' then
|
||||
icon = element.Skull
|
||||
elseif questType == 'CHAT' then
|
||||
icon = element.Chat
|
||||
elseif questType == 'QUEST_ITEM' then
|
||||
icon = element.Item
|
||||
end
|
||||
|
||||
if icon and not icon:IsShown() then
|
||||
shownCount = (shownCount and shownCount + 1) or 0
|
||||
|
||||
local size = icon.size or 25
|
||||
local setPosition = icon.position or 'TOPLEFT'
|
||||
local newPosition = E.InversePoints[setPosition]
|
||||
local offset = shownCount * (5 + size)
|
||||
|
||||
icon:Show()
|
||||
icon:ClearAllPoints()
|
||||
icon:Point(newPosition, element, newPosition, (strmatch(setPosition, 'LEFT') and -offset) or offset, 0)
|
||||
|
||||
if questType ~= 'CHAT' and icon.Text and (isPercent or objectiveCount > 1) then
|
||||
icon.Text:SetText((isPercent and objectiveCount..'%') or objectiveCount)
|
||||
end
|
||||
|
||||
if questType == 'QUEST_ITEM' then
|
||||
element.Item:SetTexture(quest.itemTexture)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if element.PostUpdate then
|
||||
return element:PostUpdate()
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
return (self.QuestIcons.Override or Update) (self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
local element = self.QuestIcons
|
||||
if element then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
|
||||
if element.Default:IsObjectType('Texture') and not element.Default:GetAtlas() then
|
||||
element.Default:SetAtlas('SmallQuestBang')
|
||||
end
|
||||
if element.Skull:IsObjectType('Texture') and not element.Skull:GetTexture() then
|
||||
element.Skull:SetTexture(E.Media.Textures.SkullIcon)
|
||||
end
|
||||
if element.Chat:IsObjectType('StatusBar') and not element.Chat:GetTexture() then
|
||||
element.Chat:SetTexture([[Interface\WorldMap\ChatBubble_64.PNG]])
|
||||
end
|
||||
|
||||
self:RegisterEvent('QUEST_LOG_UPDATE', Path, true)
|
||||
self:RegisterEvent('UNIT_NAME_UPDATE', Path, true)
|
||||
self:RegisterEvent('PLAYER_ENTERING_WORLD', Path, true)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
local element = self.QuestIcons
|
||||
if element then
|
||||
element:Hide()
|
||||
hideIcons(element)
|
||||
|
||||
self:UnregisterEvent('QUEST_LOG_UPDATE', Path)
|
||||
self:UnregisterEvent('UNIT_NAME_UPDATE', Path)
|
||||
self:UnregisterEvent('PLAYER_ENTERING_WORLD', Path)
|
||||
end
|
||||
end
|
||||
|
||||
local frame = CreateFrame('Frame')
|
||||
frame:RegisterEvent('QUEST_ACCEPTED')
|
||||
frame:RegisterEvent('QUEST_REMOVED')
|
||||
frame:RegisterEvent('PLAYER_ENTERING_WORLD')
|
||||
frame:SetScript('OnEvent', function(self, event)
|
||||
wipe(questIcons.indexByID)
|
||||
wipe(questIcons.activeQuests)
|
||||
|
||||
for i = 1, GetNumQuestLogEntries() do
|
||||
local id = C_Quest_GetQuestID(i)
|
||||
if id and id > 0 then
|
||||
questIcons.indexByID[id] = i
|
||||
|
||||
local title = GetQuestLogTitle(i)
|
||||
if title then questIcons.activeQuests[title] = id end
|
||||
end
|
||||
end
|
||||
|
||||
if event == 'PLAYER_ENTERING_WORLD' then
|
||||
self:UnregisterEvent(event)
|
||||
end
|
||||
end)
|
||||
|
||||
oUF:AddElement('QuestIcons', Path, Enable, Disable)
|
||||
@@ -0,0 +1,152 @@
|
||||
local E, L, V, P, G = unpack(ElvUI)
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local ElvUF = E.oUF
|
||||
|
||||
local UnitHealth = UnitHealth
|
||||
local UnitIsUnit = UnitIsUnit
|
||||
local UnitHealthMax = UnitHealthMax
|
||||
|
||||
--[[ 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'
|
||||
]]
|
||||
|
||||
local function HideIndicators(element)
|
||||
if element.TopIndicator then element.TopIndicator:Hide() end
|
||||
if element.LeftIndicator then element.LeftIndicator:Hide() end
|
||||
if element.RightIndicator then element.RightIndicator:Hide() end
|
||||
if element.Shadow then element.Shadow:Hide() end
|
||||
if element.Spark then element.Spark:Hide() end
|
||||
end
|
||||
|
||||
local function ShowIndicators(element, isTarget, color)
|
||||
if isTarget then
|
||||
if element.TopIndicator and (element.style == 'style3' or element.style == 'style5' or element.style == 'style6') then
|
||||
element.TopIndicator:SetVertexColor(color.r, color.g, color.b)
|
||||
element.TopIndicator:SetTexture(element.arrow)
|
||||
element.TopIndicator:Show()
|
||||
end
|
||||
|
||||
if element.LeftIndicator and element.RightIndicator and (element.style == 'style4' or element.style == 'style7' or element.style == 'style8') then
|
||||
element.LeftIndicator:SetVertexColor(color.r, color.g, color.b)
|
||||
element.RightIndicator:SetVertexColor(color.r, color.g, color.b)
|
||||
element.LeftIndicator:SetTexture(element.arrow)
|
||||
element.RightIndicator:SetTexture(element.arrow)
|
||||
element.RightIndicator:Show()
|
||||
element.LeftIndicator:Show()
|
||||
end
|
||||
end
|
||||
|
||||
if element.Shadow and (element.style == 'style1' or element.style == 'style5' or element.style == 'style7') then
|
||||
element.Shadow:SetBackdropBorderColor(color.r, color.g, color.b)
|
||||
element.Shadow:Show()
|
||||
end
|
||||
|
||||
if element.Spark and (element.style == 'style2' or element.style == 'style6' or element.style == 'style8') then
|
||||
element.Spark:SetVertexColor(color.r, color.g, color.b)
|
||||
element.Spark:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local function Update(self)
|
||||
local element = self.TargetIndicator
|
||||
if element.PreUpdate then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
HideIndicators(element)
|
||||
|
||||
if element.style ~= 'none' then
|
||||
local isTarget = UnitIsUnit(self.unit, 'target')
|
||||
local lowHealth = element.lowHealthThreshold > 0
|
||||
if isTarget and (element.preferGlowColor or not lowHealth) then
|
||||
ShowIndicators(element, isTarget, NP.db.colors.glowColor)
|
||||
elseif lowHealth then
|
||||
local health, maxHealth = UnitHealth(self.unit), UnitHealthMax(self.unit)
|
||||
local perc = (maxHealth > 0 and health/maxHealth) or 0
|
||||
|
||||
-- color tables are class updated in UpdateMedia
|
||||
if perc <= element.lowHealthThreshold * 0.5 then
|
||||
ShowIndicators(element, isTarget, NP.db.colors.lowHealthHalf)
|
||||
elseif perc <= element.lowHealthThreshold then
|
||||
ShowIndicators(element, isTarget, NP.db.colors.lowHealthColor)
|
||||
elseif isTarget then
|
||||
ShowIndicators(element, isTarget, NP.db.colors.glowColor)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if element.PostUpdate then
|
||||
return element:PostUpdate(self.unit)
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
return (self.TargetIndicator.Override or Update) (self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
local element = self.TargetIndicator
|
||||
if element then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
|
||||
if not element.style then element.style = 'style1' end
|
||||
if not element.preferGlowColor then element.preferGlowColor = true end
|
||||
if not element.lowHealthThreshold then element.lowHealthThreshold = .4 end
|
||||
|
||||
if element.Shadow and element.Shadow:IsObjectType('Frame') and not element.Shadow:GetBackdrop() then
|
||||
element.Shadow:SetBackdrop({edgeFile = E.Media.Textures.GlowTex, edgeSize = 5})
|
||||
end
|
||||
|
||||
if element.Spark and element.Spark:IsObjectType('Texture') and not element.Spark:GetTexture() then
|
||||
element.Spark:SetTexture(E.Media.Textures.Spark)
|
||||
end
|
||||
|
||||
if element.TopIndicator and element.TopIndicator:IsObjectType('Texture') and not element.TopIndicator:GetTexture() then
|
||||
element.TopIndicator:SetTexture(E.Media.Textures.ArrowUp)
|
||||
element.TopIndicator:SetTexCoord(1, 1, 1, 0, 0, 1, 0, 0) --Rotates texture 180 degress (Up arrow to face down)
|
||||
end
|
||||
|
||||
if element.LeftIndicator and element.LeftIndicator:IsObjectType('Texture') and not element.LeftIndicator:GetTexture() then
|
||||
element.LeftIndicator:SetTexture(E.Media.Textures.ArrowUp)
|
||||
element.LeftIndicator:SetTexCoord(1, 0, 0, 0, 1, 1, 0, 1) --Rotates texture 90 degrees clockwise (Up arrow to face right)
|
||||
end
|
||||
|
||||
if element.RightIndicator and element.RightIndicator:IsObjectType('Texture') and not element.RightIndicator:GetTexture() then
|
||||
element.RightIndicator:SetTexture(E.Media.Textures.ArrowUp)
|
||||
element.RightIndicator:SetTexCoord(1, 1, 0, 1, 1, 0, 0, 0) --Flips texture horizontally (Right facing arrow to face left)
|
||||
end
|
||||
|
||||
self:RegisterEvent('UNIT_HEALTH', Path)
|
||||
|
||||
self:RegisterEvent('UNIT_MAXHEALTH', Path)
|
||||
self:RegisterEvent('PLAYER_TARGET_CHANGED', Path, true)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
local element = self.TargetIndicator
|
||||
if element then
|
||||
HideIndicators(element)
|
||||
|
||||
self:UnregisterEvent('UNIT_HEALTH', Path)
|
||||
|
||||
self:UnregisterEvent('UNIT_MAXHEALTH', Path)
|
||||
self:UnregisterEvent('PLAYER_TARGET_CHANGED', Path)
|
||||
end
|
||||
end
|
||||
|
||||
ElvUF:AddElement('TargetIndicator', Path, Enable, Disable)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -137,6 +137,9 @@ S:AddCallback("Skin_BlizzardOptions", function()
|
||||
"InterfaceOptionsCombatPanelTargetOfTarget",
|
||||
"InterfaceOptionsCombatPanelEnemyCastBarsOnPortrait",
|
||||
"InterfaceOptionsCombatPanelEnemyCastBarsOnNameplates",
|
||||
"InterfaceOptionsCombatPanelAoEIndicatorsSelf",
|
||||
"InterfaceOptionsCombatPanelAoEIndicatorsEnemies",
|
||||
"InterfaceOptionsCombatPanelAoEIndicatorsFriendly",
|
||||
"InterfaceOptionsDisplayPanelShowCloak",
|
||||
"InterfaceOptionsDisplayPanelShowHelm",
|
||||
"InterfaceOptionsDisplayPanelShowAggroPercentage",
|
||||
@@ -257,7 +260,11 @@ S:AddCallback("Skin_BlizzardOptions", function()
|
||||
"InterfaceOptionsAscensionLoseControlPanelEnableSlow",
|
||||
"InterfaceOptionsAscensionLoseControlPanelEnableStun",
|
||||
"InterfaceOptionsAscensionLoseControlPanelEnablePacify",
|
||||
|
||||
"InterfaceOptionsDraftPanelAutoPopupDraft",
|
||||
"InterfaceOptionsDraftPanelAutoRevealDraft",
|
||||
"InterfaceOptionsDraftPanelSkipDraftConfirmation",
|
||||
"InterfaceOptionsDraftPanelSkipDraftSacrificeConfirmation",
|
||||
"InterfaceOptionsDraftPanelShowBuildDraftSpellCards",
|
||||
|
||||
"AudioOptionsSoundPanelEnableSound",
|
||||
"AudioOptionsSoundPanelSoundEffects",
|
||||
@@ -306,6 +313,8 @@ S:AddCallback("Skin_BlizzardOptions", function()
|
||||
"InterfaceOptionsCombatPanelSpellActivationOverlayAlpha",
|
||||
"InterfaceOptionsMousePanelMouseLookSpeedSlider",
|
||||
"InterfaceOptionsMousePanelMouseSensitivitySlider",
|
||||
"InterfaceOptionsCombatPanelNameplateDistance",
|
||||
"InterfaceOptionsCombatPanelNameplateZ",
|
||||
|
||||
"AudioOptionsSoundPanelSoundQuality",
|
||||
"AudioOptionsSoundPanelSoundChannels",
|
||||
|
||||
@@ -21,7 +21,6 @@ S:AddCallback("Skin_LFD", function()
|
||||
AscensionLFGFrameContent:StripTextures(true)
|
||||
AscensionLFGFrameMenu:StripTextures(true)
|
||||
AscensionLFGFrameInset:StripTextures(true)
|
||||
AscensionLFGFrameInset:CreateBackdrop("Transparent")
|
||||
AscensionLFGFrameInsetNineSlice:StripTextures(true)
|
||||
AscensionLFGFrameNineSlice:StripTextures(true)
|
||||
AscensionLFGFrameMenuNineSlice:StripTextures(true)
|
||||
|
||||
@@ -77,47 +77,29 @@ local function createConfigEnv()
|
||||
__newindex = function(_, key, value) _G[key] = value end,
|
||||
})
|
||||
|
||||
overrideFuncs["namecolor"] = ElvUF.Tags.Methods["namecolor"]
|
||||
overrideFuncs["name:veryshort"] = ElvUF.Tags.Methods["name:veryshort"]
|
||||
overrideFuncs["name:short"] = ElvUF.Tags.Methods["name:short"]
|
||||
overrideFuncs["name:medium"] = ElvUF.Tags.Methods["name:medium"]
|
||||
overrideFuncs["name:long"] = ElvUF.Tags.Methods["name:long"]
|
||||
overrideFuncs['classcolor'] = ElvUF.Tags.Methods['classcolor']
|
||||
overrideFuncs['name:veryshort'] = ElvUF.Tags.Methods['name:veryshort']
|
||||
overrideFuncs['name:short'] = ElvUF.Tags.Methods['name:short']
|
||||
overrideFuncs['name:medium'] = ElvUF.Tags.Methods['name:medium']
|
||||
overrideFuncs['name:long'] = ElvUF.Tags.Methods['name:long']
|
||||
|
||||
overrideFuncs["healthcolor"] = ElvUF.Tags.Methods["healthcolor"]
|
||||
overrideFuncs["health:current"] = ElvUF.Tags.Methods["health:current"]
|
||||
overrideFuncs["health:deficit"] = ElvUF.Tags.Methods["health:deficit"]
|
||||
overrideFuncs["health:current-percent"] = ElvUF.Tags.Methods["health:current-percent"]
|
||||
overrideFuncs["health:current-max"] = ElvUF.Tags.Methods["health:current-max"]
|
||||
overrideFuncs["health:current-max-percent"] = ElvUF.Tags.Methods["health:current-max-percent"]
|
||||
overrideFuncs["health:max"] = ElvUF.Tags.Methods["health:max"]
|
||||
overrideFuncs["health:percent"] = ElvUF.Tags.Methods["health:percent"]
|
||||
overrideFuncs['healthcolor'] = ElvUF.Tags.Methods['healthcolor']
|
||||
overrideFuncs['health:current'] = ElvUF.Tags.Methods['health:current']
|
||||
overrideFuncs['health:deficit'] = ElvUF.Tags.Methods['health:deficit']
|
||||
overrideFuncs['health:current-percent'] = ElvUF.Tags.Methods['health:current-percent']
|
||||
overrideFuncs['health:current-max'] = ElvUF.Tags.Methods['health:current-max']
|
||||
overrideFuncs['health:current-max-percent'] = ElvUF.Tags.Methods['health:current-max-percent']
|
||||
overrideFuncs['health:max'] = ElvUF.Tags.Methods['health:max']
|
||||
overrideFuncs['health:percent'] = ElvUF.Tags.Methods['health:percent']
|
||||
|
||||
overrideFuncs["powercolor"] = ElvUF.Tags.Methods["powercolor"]
|
||||
overrideFuncs["power:current"] = ElvUF.Tags.Methods["power:current"]
|
||||
overrideFuncs["power:deficit"] = ElvUF.Tags.Methods["power:deficit"]
|
||||
overrideFuncs["power:current-percent"] = ElvUF.Tags.Methods["power:current-percent"]
|
||||
overrideFuncs["power:current-max"] = ElvUF.Tags.Methods["power:current-max"]
|
||||
overrideFuncs["power:current-max-percent"] = ElvUF.Tags.Methods["power:current-max-percent"]
|
||||
overrideFuncs["power:max"] = ElvUF.Tags.Methods["power:max"]
|
||||
overrideFuncs["power:percent"] = ElvUF.Tags.Methods["power:percent"]
|
||||
|
||||
overrideFuncs["energycolor"] = ElvUF.Tags.Methods["energycolor"]
|
||||
overrideFuncs["energy:current"] = ElvUF.Tags.Methods["energy:current"]
|
||||
overrideFuncs["energy:deficit"] = ElvUF.Tags.Methods["energy:deficit"]
|
||||
overrideFuncs["energy:current-percent"] = ElvUF.Tags.Methods["energy:current-percent"]
|
||||
overrideFuncs["energy:current-max"] = ElvUF.Tags.Methods["energy:current-max"]
|
||||
overrideFuncs["energy:current-max-percent"] = ElvUF.Tags.Methods["energy:current-max-percent"]
|
||||
overrideFuncs["energy:max"] = ElvUF.Tags.Methods["energy:max"]
|
||||
overrideFuncs["energy:percent"] = ElvUF.Tags.Methods["energy:percent"]
|
||||
|
||||
overrideFuncs["ragecolor"] = ElvUF.Tags.Methods["ragecolor"]
|
||||
overrideFuncs["rage:current"] = ElvUF.Tags.Methods["rage:current"]
|
||||
overrideFuncs["rage:deficit"] = ElvUF.Tags.Methods["rage:deficit"]
|
||||
overrideFuncs["rage:current-percent"] = ElvUF.Tags.Methods["rage:current-percent"]
|
||||
overrideFuncs["rage:current-max"] = ElvUF.Tags.Methods["rage:current-max"]
|
||||
overrideFuncs["rage:current-max-percent"] = ElvUF.Tags.Methods["rage:current-max-percent"]
|
||||
overrideFuncs["rage:max"] = ElvUF.Tags.Methods["rage:max"]
|
||||
overrideFuncs["rage:percent"] = ElvUF.Tags.Methods["rage:percent"]
|
||||
overrideFuncs['powercolor'] = ElvUF.Tags.Methods['powercolor']
|
||||
overrideFuncs['power:current'] = ElvUF.Tags.Methods['power:current']
|
||||
overrideFuncs['power:deficit'] = ElvUF.Tags.Methods['power:deficit']
|
||||
overrideFuncs['power:current-percent'] = ElvUF.Tags.Methods['power:current-percent']
|
||||
overrideFuncs['power:current-max'] = ElvUF.Tags.Methods['power:current-max']
|
||||
overrideFuncs['power:current-max-percent'] = ElvUF.Tags.Methods['power:current-max-percent']
|
||||
overrideFuncs['power:max'] = ElvUF.Tags.Methods['power:max']
|
||||
overrideFuncs['power:percent'] = ElvUF.Tags.Methods['power:percent']
|
||||
end
|
||||
|
||||
function UF:ForceShow(frame)
|
||||
|
||||
@@ -173,6 +173,33 @@ function UF.SortAuraBarName(a, b)
|
||||
return a.name > b.name
|
||||
end
|
||||
|
||||
function UF:ConvertFilters(auras, priority)
|
||||
if not priority or priority == '' then return end
|
||||
|
||||
local list = auras.filterList or {}
|
||||
if next(list) then wipe(list) end
|
||||
|
||||
local special, filters = G.unitframe.specialFilters, E.global.unitframe.aurafilters
|
||||
|
||||
for _, name in next, { strsplit(',', priority) } do
|
||||
local friend, enemy = strmatch(name, '^Friendly:([^,]*)'), strmatch(name, '^Enemy:([^,]*)')
|
||||
local real = friend or enemy or name
|
||||
local custom = filters[real]
|
||||
|
||||
if special[real] or custom then
|
||||
tinsert(list, {
|
||||
name = real,
|
||||
custom = custom,
|
||||
status = (friend and 1) or (enemy and 2)
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
if next(list) then
|
||||
return list
|
||||
end
|
||||
end
|
||||
|
||||
function UF:CheckFilter(name, caster, spellID, isFriend, isPlayer, isUnit, allowDuration, noDuration, canDispell, ...)
|
||||
for i = 1, select("#", ...) do
|
||||
local filterName = select(i, ...)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local UF = E:GetModule("UnitFrames")
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
@@ -16,6 +17,58 @@ local UnitCanAttack = UnitCanAttack
|
||||
local UnitIsFriend = UnitIsFriend
|
||||
local UnitIsUnit = UnitIsUnit
|
||||
|
||||
UF.MatchGrowthY = { TOP = 'TOP', BOTTOM = 'BOTTOM' }
|
||||
UF.MatchGrowthX = { LEFT = 'LEFT', RIGHT = 'RIGHT' }
|
||||
|
||||
UF.SortAuraFuncs = {
|
||||
TIME_REMAINING = function(a, b, dir)
|
||||
local A = a.noTime and huge or a.expiration or -huge
|
||||
local B = b.noTime and huge or b.expiration or -huge
|
||||
if dir == 'DESCENDING' then return A < B else return A > B end
|
||||
end,
|
||||
DURATION = function(a, b, dir)
|
||||
local A = a.noTime and huge or a.duration or -huge
|
||||
local B = b.noTime and huge or b.duration or -huge
|
||||
if dir == 'DESCENDING' then return A < B else return A > B end
|
||||
end,
|
||||
NAME = function(a, b, dir)
|
||||
local A, B = a.name or '', b.name or ''
|
||||
if dir == 'DESCENDING' then return A < B else return A > B end
|
||||
end,
|
||||
PLAYER = function(a, b, dir)
|
||||
local A, B = a.isPlayer or false, b.isPlayer or false
|
||||
if dir == 'DESCENDING' then return A and not B else return not A and B end
|
||||
end,
|
||||
}
|
||||
|
||||
UF.SmartPosition = {
|
||||
BUFFS_ON_DEBUFFS = {
|
||||
from = 'BUFFS', to = 'Debuffs',
|
||||
warning = format(L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."], L["Buffs"], L["Debuffs"], L["Frame"]),
|
||||
func = function(db, buffs, debuffs)
|
||||
db.buffs.attachTo = 'DEBUFFS'
|
||||
buffs.attachTo = debuffs
|
||||
|
||||
buffs.PostUpdate = nil
|
||||
debuffs.PostUpdate = UF.UpdateAuraSmartPoisition
|
||||
end
|
||||
},
|
||||
DEBUFFS_ON_BUFFS = {
|
||||
from = 'DEBUFFS', to = 'Buffs',
|
||||
warning = format(L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."], L["Debuffs"], L["Buffs"], L["Frame"]),
|
||||
func = function(db, buffs, debuffs)
|
||||
db.debuffs.attachTo = 'BUFFS'
|
||||
debuffs.attachTo = buffs
|
||||
|
||||
debuffs.PostUpdate = nil
|
||||
buffs.PostUpdate = UF.UpdateAuraSmartPoisition
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
UF.SmartPosition.FLUID_BUFFS_ON_DEBUFFS = E:CopyTable({fluid = true}, UF.SmartPosition.BUFFS_ON_DEBUFFS)
|
||||
UF.SmartPosition.FLUID_DEBUFFS_ON_BUFFS = E:CopyTable({fluid = true}, UF.SmartPosition.DEBUFFS_ON_BUFFS)
|
||||
|
||||
function UF:Construct_Buffs(frame)
|
||||
local buffs = CreateFrame("Frame", frame:GetName().."Buffs", frame)
|
||||
buffs.spacing = E.Spacing
|
||||
@@ -134,6 +187,48 @@ function UF:UpdateAuraCooldownPosition(button)
|
||||
button.needsUpdateCooldownPosition = nil
|
||||
end
|
||||
|
||||
function UF:GetAuraElements(frame)
|
||||
if frame.isNamePlate then
|
||||
return frame.Buffs_, frame.Debuffs_
|
||||
else
|
||||
return frame.Buffs, frame.Debuffs
|
||||
end
|
||||
end
|
||||
|
||||
function UF:SetSmartPosition(frame, db)
|
||||
if frame.isNamePlate then db = NP:PlateDB(frame) end
|
||||
|
||||
local position, fluid = db.smartAuraPosition
|
||||
local buffs, debuffs = UF:GetAuraElements(frame)
|
||||
local info = UF.SmartPosition[position]
|
||||
if info then
|
||||
local TO = db[strlower(info.to)]
|
||||
if TO.attachTo == info.from then
|
||||
TO.attachTo = 'FRAME'
|
||||
|
||||
E:Print(info.warning)
|
||||
|
||||
local element = (info.to == 'Debuffs' and debuffs) or buffs
|
||||
element.attachTo = frame
|
||||
element:ClearAllPoints()
|
||||
element:Point(element.initialAnchor, element.attachTo, element.anchorPoint, element.xOffset, element.yOffset)
|
||||
end
|
||||
|
||||
fluid = info.fluid
|
||||
info.func(db, buffs, debuffs, info.isFuild)
|
||||
else
|
||||
buffs.PostUpdate = nil
|
||||
debuffs.PostUpdate = nil
|
||||
end
|
||||
|
||||
if db.debuffs.attachTo == 'BUFFS' and db.buffs.attachTo == 'DEBUFFS' then
|
||||
E:Print(format(L["%s frame has a conflicting anchor point. Forcing the Buffs to be attached to the main unitframe."], E:StringTitle(frame:GetName())))
|
||||
db.buffs.attachTo = 'FRAME'
|
||||
end
|
||||
|
||||
return position, fluid
|
||||
end
|
||||
|
||||
function UF:Configure_Auras(frame, auraType)
|
||||
if not frame.VARIABLES_SET then return end
|
||||
|
||||
@@ -382,6 +477,31 @@ function UF:PostUpdateAura(unit, button)
|
||||
end
|
||||
end
|
||||
|
||||
function UF:GetSmartAuraElements(auras)
|
||||
local Buffs, Debuffs = UF:GetAuraElements(auras:GetParent())
|
||||
if auras == Buffs then
|
||||
return Debuffs, Buffs, auras.visibleBuffs
|
||||
else
|
||||
return Buffs, Debuffs, auras.visibleDebuffs
|
||||
end
|
||||
end
|
||||
|
||||
function UF:UpdateAuraSmartPoisition()
|
||||
local element, other, visible = UF:GetSmartAuraElements(self)
|
||||
|
||||
if visible == 0 then
|
||||
if self.smartFluid then
|
||||
element:ClearAllPoints()
|
||||
element:Point(other.initialAnchor, other.attachTo, other.anchorPoint, other.xOffset, other.yOffset)
|
||||
else
|
||||
other:Height(UF:GetAuraPosition(other, true))
|
||||
end
|
||||
else
|
||||
element:ClearAllPoints()
|
||||
element:Point(element.initialAnchor, element.attachTo, element.anchorPoint, element.xOffset, element.yOffset)
|
||||
end
|
||||
end
|
||||
|
||||
function UF:AuraFilter(unit, button, name, _, _, _, debuffType, duration, expiration, caster, isStealable, _, spellID)
|
||||
if not name then return end -- checking for an aura that is not there, pass nil to break while loop
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ function UF:Construct_Cutaway(frame)
|
||||
|
||||
if frame.Power then
|
||||
local powerTexture = frame.Power:GetStatusBarTexture()
|
||||
local cutawayPower = frame.Power.ClipFrame:CreateTexture(frameName.."CutawayPower")
|
||||
local cutawayPower = frame.Power:CreateTexture(frameName.."CutawayPower")
|
||||
cutawayPower:SetPoint("TOPLEFT", powerTexture, "TOPRIGHT")
|
||||
cutawayPower:SetPoint("BOTTOMLEFT", powerTexture, "BOTTOMRIGHT")
|
||||
cutawayPower:SetTexture(E.media.blankTex)
|
||||
@@ -18,7 +18,7 @@ function UF:Construct_Cutaway(frame)
|
||||
end
|
||||
|
||||
local healthTexture = frame.Health:GetStatusBarTexture()
|
||||
local cutawayHealth = frame.Health.ClipFrame:CreateTexture(frameName.."CutawayHealth")
|
||||
local cutawayHealth = frame.Health:CreateTexture(frameName.."CutawayHealth")
|
||||
cutawayHealth:SetPoint("TOPLEFT", healthTexture, "TOPRIGHT")
|
||||
cutawayHealth:SetPoint("BOTTOMLEFT", healthTexture, "BOTTOMRIGHT")
|
||||
cutawayHealth:SetTexture(E.media.blankTex)
|
||||
|
||||
@@ -65,6 +65,12 @@ function UF:Configure_Happiness(frame)
|
||||
end
|
||||
|
||||
function UF:HappinessOverride(event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if not unit or self.unit ~= unit then return end
|
||||
|
||||
local db = self.db
|
||||
|
||||
@@ -60,7 +60,7 @@ function UF:Configure_Energy(frame)
|
||||
local energy = frame.Energy
|
||||
energy.origParent = frame
|
||||
|
||||
if frame.USE_ENERGYBAR then
|
||||
if frame.USE_ENERGYBAR and C_Player:IsHero() then
|
||||
if not frame:IsElementEnabled("Energy") then
|
||||
frame:EnableElement("Energy")
|
||||
energy:Show()
|
||||
|
||||
@@ -60,7 +60,7 @@ function UF:Configure_Rage(frame)
|
||||
local rage = frame.Rage
|
||||
rage.origParent = frame
|
||||
|
||||
if frame.USE_RAGEBAR then
|
||||
if frame.USE_RAGEBAR and C_Player:IsHero() then
|
||||
if not frame:IsElementEnabled("Rage") then
|
||||
frame:EnableElement("Rage")
|
||||
rage:Show()
|
||||
|
||||
@@ -30,6 +30,12 @@ function UF:Configure_PVPIcon(frame)
|
||||
end
|
||||
|
||||
function UF:UpdateOverridePvP(event, unit)
|
||||
if unit and self.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = self.unit and UnitIsUnit(self.unit, unit)
|
||||
if isUnit then
|
||||
unit = self.unit
|
||||
end
|
||||
end
|
||||
if not unit or self.unit ~= unit then return end
|
||||
|
||||
local element = self.PvPIndicator
|
||||
|
||||
@@ -95,7 +95,12 @@ end
|
||||
|
||||
function UF:UpdateThreat(unit, status, r, g, b)
|
||||
local parent = self:GetParent()
|
||||
|
||||
if unit and parent.isNamePlate and unit:sub(1, 9) ~= "nameplate" then
|
||||
local isUnit = parent.unit and UnitIsUnit(parent.unit, unit)
|
||||
if isUnit then
|
||||
unit = parent.unit
|
||||
end
|
||||
end
|
||||
if (parent.unit ~= unit) or not unit then return end
|
||||
|
||||
local db = parent.db
|
||||
|
||||
@@ -461,6 +461,21 @@ function UF:Configure_Fader(frame)
|
||||
end
|
||||
end
|
||||
|
||||
function UF:Construct_ClipFrame(frame, bar)
|
||||
|
||||
local clipFrame = CreateFrame('ScrollFrame', nil, bar)
|
||||
clipFrame:SetAllPoints()
|
||||
clipFrame:EnableMouse(false)
|
||||
|
||||
local child = CreateFrame("Frame", nil, clipFrame)
|
||||
child:SetPoint("CENTER")
|
||||
child:SetSize(clipFrame:GetSize())
|
||||
child.__frame = frame
|
||||
bar.ClipFrame = child
|
||||
|
||||
return child
|
||||
end
|
||||
|
||||
function UF:Configure_FontString(obj)
|
||||
UF.fontstrings[obj] = true
|
||||
obj:FontTemplate() --This is temporary.
|
||||
|
||||
@@ -6,37 +6,50 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
|
||||
G.nameplates.filters = {
|
||||
ElvUI_Boss = {
|
||||
["Non-Target Alpha"] = {
|
||||
actions = {
|
||||
alpha = 40,
|
||||
},
|
||||
triggers = {
|
||||
requireTarget = true,
|
||||
notTarget = true,
|
||||
enable = true,
|
||||
},
|
||||
},
|
||||
["Enlarge Boss Nameplates"] = {
|
||||
triggers = {
|
||||
level = true,
|
||||
curlevel = -1,
|
||||
nameplateType = {
|
||||
enable = true,
|
||||
enemyNPC = true
|
||||
}
|
||||
},
|
||||
enable = true,
|
||||
},
|
||||
actions = {
|
||||
scale = 1.15
|
||||
}
|
||||
},
|
||||
ElvUI_Totem = {
|
||||
triggers = {
|
||||
totems = {
|
||||
enable = true
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
iconOnly = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
E.StyleFilterDefaults = {
|
||||
triggers = {
|
||||
priority = 1,
|
||||
targetMe = false,
|
||||
isTarget = false,
|
||||
notTarget = false,
|
||||
requireTarget = false,
|
||||
noTarget = false,
|
||||
level = false,
|
||||
names = {},
|
||||
items = {},
|
||||
slots = {},
|
||||
known = {
|
||||
notKnown = false,
|
||||
playerSpell = false,
|
||||
spells = {} -- new talents
|
||||
},
|
||||
class = {}, -- this can stay empty we only will accept values that exist
|
||||
casting = {
|
||||
isCasting = false,
|
||||
isChanneling = false,
|
||||
@@ -51,6 +64,25 @@ E.StyleFilterDefaults = {
|
||||
healer = false,
|
||||
damager = false
|
||||
},
|
||||
faction = {
|
||||
Alliance = false,
|
||||
Horde = false,
|
||||
Neutral = false,
|
||||
},
|
||||
unitRole = {
|
||||
tank = false,
|
||||
healer = false,
|
||||
damager = false
|
||||
},
|
||||
classification = {
|
||||
worldboss = false,
|
||||
rareelite = false,
|
||||
elite = false,
|
||||
rare = false,
|
||||
normal = false,
|
||||
trivial = false,
|
||||
minus = false
|
||||
},
|
||||
raidTarget = {
|
||||
star = false,
|
||||
circle = false,
|
||||
@@ -61,6 +93,16 @@ E.StyleFilterDefaults = {
|
||||
cross = false,
|
||||
skull = false
|
||||
},
|
||||
threat = {
|
||||
enable = false,
|
||||
good = false,
|
||||
goodTransition = false,
|
||||
badTransition = false,
|
||||
bad = false,
|
||||
offTank = false,
|
||||
offTankGoodTransition = false,
|
||||
offTankBadTransition = false
|
||||
},
|
||||
curlevel = 0,
|
||||
maxlevel = 0,
|
||||
minlevel = 0,
|
||||
@@ -69,103 +111,207 @@ E.StyleFilterDefaults = {
|
||||
underHealthThreshold = 0,
|
||||
overHealthThreshold = 0,
|
||||
powerThreshold = false,
|
||||
powerUsePlayer = false,
|
||||
underPowerThreshold = 0,
|
||||
overPowerThreshold = 0,
|
||||
names = {},
|
||||
creatureType = {
|
||||
enable = false,
|
||||
Aberration = false,
|
||||
Beast = false,
|
||||
Critter = false,
|
||||
Demon = false,
|
||||
Dragonkin = false,
|
||||
Elemental = false,
|
||||
['Gas Cloud'] = false,
|
||||
Giant = false,
|
||||
Humanoid = false,
|
||||
Mechanical = false,
|
||||
['Not specified'] = false,
|
||||
Totem = false,
|
||||
Undead = false,
|
||||
['Wild Pet'] = false,
|
||||
['Non-combat Pet'] = false
|
||||
},
|
||||
nameplateType = {
|
||||
enable = false,
|
||||
friendlyPlayer = false,
|
||||
friendlyNPC = false,
|
||||
enemyPlayer = false,
|
||||
enemyNPC = false
|
||||
enemyNPC = false,
|
||||
player = false
|
||||
},
|
||||
reactionType = {
|
||||
enabled = false,
|
||||
reputation = false,
|
||||
hated = false,
|
||||
hostile = false,
|
||||
unfriendly = false,
|
||||
neutral = false,
|
||||
friendly = false
|
||||
friendly = false,
|
||||
honored = false,
|
||||
revered = false,
|
||||
exalted = false
|
||||
},
|
||||
instanceType = {
|
||||
none = false,
|
||||
sanctuary = false,
|
||||
scenario = false,
|
||||
party = false,
|
||||
raid = false,
|
||||
arena = false,
|
||||
pvp = false
|
||||
},
|
||||
location = {
|
||||
mapIDEnabled = false,
|
||||
mapIDs = {},
|
||||
instanceIDEnabled = false,
|
||||
instanceIDs = {},
|
||||
zoneNamesEnabled = false,
|
||||
zoneNames = {},
|
||||
subZoneNamesEnabled = false,
|
||||
subZoneNames = {}
|
||||
},
|
||||
keyMod = {
|
||||
enable = false,
|
||||
Modifier = false,
|
||||
Shift = false,
|
||||
Alt = false,
|
||||
Control = false,
|
||||
LeftShift = false,
|
||||
LeftAlt = false,
|
||||
LeftControl = false,
|
||||
RightShift = false,
|
||||
RightAlt = false,
|
||||
RightControl = false
|
||||
},
|
||||
instanceDifficulty = {
|
||||
dungeon = {
|
||||
normal = false,
|
||||
heroic = false
|
||||
heroic = false,
|
||||
mythic = false,
|
||||
},
|
||||
raid = {
|
||||
normal = false,
|
||||
heroic = false
|
||||
heroic = false,
|
||||
mythic = false,
|
||||
ascended = false,
|
||||
}
|
||||
},
|
||||
cooldowns = {
|
||||
names = {},
|
||||
mustHaveAll = false
|
||||
mustHaveAll = false,
|
||||
names = {}
|
||||
},
|
||||
buffs = {
|
||||
mustHaveAll = false,
|
||||
missing = false,
|
||||
names = {},
|
||||
minTimeLeft = 0,
|
||||
maxTimeLeft = 0
|
||||
maxTimeLeft = 0,
|
||||
hasStealable = false,
|
||||
hasNoStealable = false,
|
||||
onMe = false,
|
||||
onPet = false,
|
||||
fromMe = false,
|
||||
fromPet = false,
|
||||
names = {}
|
||||
},
|
||||
debuffs = {
|
||||
mustHaveAll = false,
|
||||
missing = false,
|
||||
names = {},
|
||||
minTimeLeft = 0,
|
||||
maxTimeLeft = 0
|
||||
maxTimeLeft = 0,
|
||||
hasDispellable = false,
|
||||
hasNoDispellable = false,
|
||||
onMe = false,
|
||||
onPet = false,
|
||||
fromMe = false,
|
||||
fromPet = false,
|
||||
names = {}
|
||||
},
|
||||
totems = {
|
||||
enable = false,
|
||||
a1 = true, a2 = true, a3 = true, a4 = true, a5 = true,
|
||||
e1 = true, e2 = true, e3 = true, e4 = true, e5 = true, e6 = true,
|
||||
f1 = true, f2 = true, f3 = true, f4 = true, f5 = true, f6 = true,
|
||||
w1 = true, w2 = true, w3 = true, w4 = true, w5 = true,
|
||||
o1 = true
|
||||
},
|
||||
uniqueUnits = {
|
||||
enable = false,
|
||||
u1 = true, u2 = true
|
||||
bossMods = {
|
||||
hasAura = false,
|
||||
missingAura = false,
|
||||
missingAuras = false,
|
||||
auras = {}
|
||||
},
|
||||
inRaid = false,
|
||||
notInRaid = false,
|
||||
inParty = false,
|
||||
notInParty = false,
|
||||
inMyGuild = false,
|
||||
notMyGuild = false,
|
||||
isTrivial = false,
|
||||
notTrivial = false,
|
||||
isPossessed = false,
|
||||
notPossessed = false,
|
||||
isCharmed = false,
|
||||
notCharmed = false,
|
||||
isDeadOrGhost = false,
|
||||
notDeadOrGhost = false,
|
||||
isConnected = false,
|
||||
notConnected = false,
|
||||
isResting = false,
|
||||
notResting = false,
|
||||
isPet = false,
|
||||
isNotPet = false,
|
||||
isPlayerControlled = false,
|
||||
isNotPlayerControlled = false,
|
||||
isOwnedByPlayer = false,
|
||||
isNotOwnedByPlayer = false,
|
||||
isPvP = false,
|
||||
isNotPvP = false,
|
||||
playerCanAttack = false,
|
||||
playerCanNotAttack = false,
|
||||
hasTitleNPC = false,
|
||||
noTitleNPC = false,
|
||||
isQuest = false,
|
||||
notQuest = false,
|
||||
-- combat
|
||||
inCombat = false,
|
||||
outOfCombat = false
|
||||
outOfCombat = false,
|
||||
inCombatUnit = false,
|
||||
outOfCombatUnit = false,
|
||||
-- vehicle
|
||||
inVehicle = false,
|
||||
outOfVehicle = false,
|
||||
inVehicleUnit = false,
|
||||
outOfVehicleUnit = false
|
||||
},
|
||||
actions = {
|
||||
color = {
|
||||
health = false,
|
||||
power = false,
|
||||
border = false,
|
||||
name = false,
|
||||
healthClass = false,
|
||||
healthColor = {r = 1, g = 1, b = 1, a = 1},
|
||||
borderColor = {r = 1, g = 1, b = 1, a = 1},
|
||||
nameColor = {r = 1, g = 1, b = 1, a = 1}
|
||||
powerClass = false,
|
||||
powerColor = {r = 1, g = 1, b = 1, a = 1},
|
||||
borderClass = false,
|
||||
borderColor = {r = 1, g = 1, b = 1, a = 1}
|
||||
},
|
||||
texture = {
|
||||
enable = false,
|
||||
texture = "ElvUI Norm"
|
||||
texture = 'ElvUI Norm'
|
||||
},
|
||||
flash = {
|
||||
enable = false,
|
||||
class = false,
|
||||
color = {r = 1, g = 1, b = 1, a = 1},
|
||||
speed = 4
|
||||
},
|
||||
tags = {
|
||||
name = '',
|
||||
level = '',
|
||||
title = '',
|
||||
health = '',
|
||||
power = ''
|
||||
},
|
||||
hide = false,
|
||||
usePortrait = false,
|
||||
nameOnly = false,
|
||||
icon = false,
|
||||
iconOnly = false,
|
||||
scale = 1.0,
|
||||
scale = 1,
|
||||
alpha = -1
|
||||
}
|
||||
}
|
||||
|
||||
G.nameplates.specialFilters = {
|
||||
Personal = true,
|
||||
nonPersonal = true,
|
||||
blockNonPersonal = true,
|
||||
blockNoDuration = true
|
||||
}
|
||||
+497
-635
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,7 @@ S:AddCallbackForAddon("GnomishVendorShrinker", "GnomishVendorShrinker", function
|
||||
if not GVS then return end
|
||||
|
||||
GVS:Size(304, 294)
|
||||
GVS:Point("TOPLEFT", 19, -44)
|
||||
GVS:Point("TOPLEFT", 19, -54)
|
||||
GVS:SetTemplate("Transparent")
|
||||
|
||||
MerchantBuyBackItem:ClearAllPoints()
|
||||
@@ -84,7 +84,7 @@ S:AddCallbackForAddon("GnomishVendorShrinker", "GnomishVendorShrinker", function
|
||||
end
|
||||
|
||||
child:Height(18)
|
||||
child:Point("TOPLEFT", GVS, "BOTTOMLEFT", 1, -3)
|
||||
child:Point("TOPLEFT", GVS, "BOTTOMLEFT", 1, -61)
|
||||
S:HandleEditBox(child)
|
||||
elseif objType == "Slider" then
|
||||
for _, child2 in ipairs({child:GetChildren()}) do
|
||||
@@ -112,8 +112,4 @@ S:AddCallbackForAddon("GnomishVendorShrinker", "GnomishVendorShrinker", function
|
||||
S:HandleScrollBar(child)
|
||||
end
|
||||
end
|
||||
MerchantBuyBackItem:ClearAllPoints()
|
||||
MerchantBuyBackItem:Point("TOPLEFT", MerchantItem10, "BOTTOMLEFT", 0, -24)
|
||||
MerchantBuyBackItemItemButton:ClearAllPoints()
|
||||
MerchantBuyBackItemItemButton:Point("TOPLEFT", MerchantBuyBackItem, "TOPLEFT", 4, -4)
|
||||
end)
|
||||
@@ -2861,6 +2861,13 @@ do -- CharacterFrame
|
||||
E.private.enhanced.character.player.collapsedName2 = table.copy(E.private.enhanced.character.player.collapsedName)
|
||||
end
|
||||
|
||||
if C_Player:IsDefaultClass() then
|
||||
-- default class has no primary stat
|
||||
PAPERDOLL_STATCATEGORIES["PRIMARY_STAT"] = nil
|
||||
PAPERDOLL_STATINFO["PRIMARY_STAT"] = nil
|
||||
table.RemoveItem(PAPERDOLL_STATCATEGORY_DEFAULTORDER, "PRIMARY_STAT")
|
||||
end
|
||||
|
||||
local activeSpec = GetActiveTalentGroup()
|
||||
if activeSpec == 1 then
|
||||
self:PaperDoll_InitStatCategories(PAPERDOLL_STATCATEGORY_DEFAULTORDER, E.private.enhanced.character.player.orderName, E.private.enhanced.character.player.collapsedName, "player")
|
||||
|
||||
@@ -244,15 +244,8 @@ local function BuildABConfig()
|
||||
desc = L["Set the font outline."],
|
||||
values = C.Values.FontFlags
|
||||
},
|
||||
fontWidth = {
|
||||
order = 4,
|
||||
type = "range",
|
||||
name = "Font Width",
|
||||
min = 5, max = 150, step = 1,
|
||||
softMax = 60, softMin = 15
|
||||
},
|
||||
fontColor = {
|
||||
order = 5,
|
||||
order = 4,
|
||||
type = "color",
|
||||
name = L["COLOR"],
|
||||
width = "full",
|
||||
@@ -268,7 +261,7 @@ local function BuildABConfig()
|
||||
end
|
||||
},
|
||||
textPosition = {
|
||||
order = 6,
|
||||
order = 5,
|
||||
type = "group",
|
||||
name = L["Text Position"],
|
||||
guiInline = true,
|
||||
@@ -785,11 +778,11 @@ local function BuildABConfig()
|
||||
disabled = function() return not E.db.actionbar.microbar.enabled end
|
||||
},
|
||||
buttonsPerRow = {
|
||||
order = 8,
|
||||
order = 11,
|
||||
type = "range",
|
||||
name = L["Buttons Per Row"],
|
||||
desc = L["The amount of buttons to display per row."],
|
||||
min = 1, max = 10, step = 1,
|
||||
min = 1, max = 11, step = 1,
|
||||
disabled = function() return not E.db.actionbar.microbar.enabled end
|
||||
},
|
||||
alpha = {
|
||||
@@ -914,8 +907,7 @@ local function BuildABConfig()
|
||||
type = "range",
|
||||
name = L["Button Size"],
|
||||
desc = L["The size of the action buttons."],
|
||||
min = 15, softMax = 60, max = 150, step = 1,
|
||||
|
||||
min = 15, max = 60, step = 1,
|
||||
disabled = function() return not E.db.actionbar["bar"..i].enabled end
|
||||
},
|
||||
buttonspacing = {
|
||||
|
||||
@@ -22,6 +22,7 @@ E:AddLib("AceConfig", "AceConfig-3.0-ElvUI")
|
||||
E:AddLib("AceConfigDialog", "AceConfigDialog-3.0-ElvUI")
|
||||
E:AddLib("AceConfigRegistry", "AceConfigRegistry-3.0-ElvUI")
|
||||
E:AddLib("AceDBOptions", "AceDBOptions-3.0")
|
||||
E:AddLib('ACH', 'LibAceConfigHelper')
|
||||
|
||||
local UnitName = UnitName
|
||||
local UnitExists = UnitExists
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Interface: 30300
|
||||
## Author: Elv, Bunny
|
||||
## Version: 1.06
|
||||
## Version: 1.10
|
||||
## Title: |cff1784d1E|r|cffe5e3e3lvUI|r |cff1784d1O|r|cffe5e3e3ptionsUI|r
|
||||
## Notes: Options for ElvUI.
|
||||
## RequiredDeps: ElvUI
|
||||
@@ -18,6 +18,7 @@ Cooldown.lua
|
||||
DataTexts.lua
|
||||
Filters.lua
|
||||
Nameplates.lua
|
||||
StyleFilters.lua
|
||||
Skins.lua
|
||||
Tooltip.lua
|
||||
UnitFrames.lua
|
||||
|
||||
@@ -196,8 +196,7 @@ E.Options.args.maps = {
|
||||
type = "range",
|
||||
name = L["Size"],
|
||||
desc = L["Adjust the size of the minimap."],
|
||||
min = 50, max = 600, step = 1,
|
||||
softMin = 120, softMax = 250,
|
||||
min = 120, max = 250, step = 1,
|
||||
get = function(info) return E.db.general.minimap[info[#info]] end,
|
||||
set = function(info, value) E.db.general.minimap[info[#info]] = value MM:UpdateSettings() end,
|
||||
disabled = function() return not E.private.general.minimap.enable end
|
||||
|
||||
+539
-4128
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,797 @@
|
||||
local E, _, V, P, G = unpack(ElvUI)
|
||||
local C, L = unpack(select(2, ...))
|
||||
local D = E:GetModule('Distributor')
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local LibDeflate = E.Libs.Deflate
|
||||
local ACH = E.Libs.ACH
|
||||
local LCS = E.Libs.LCS
|
||||
|
||||
local _G = _G
|
||||
local wipe, pairs, strmatch, strsplit, tostring = wipe, pairs, strmatch, strsplit, tostring
|
||||
local next, sort, tonumber, format = next, sort, tonumber, format
|
||||
|
||||
local GetClassInfo = GetClassInfo
|
||||
local GetDifficultyInfo = GetDifficultyInfo
|
||||
local GetInstanceInfo = GetInstanceInfo
|
||||
local GetRealZoneText = GetRealZoneText
|
||||
local GetSpellInfo = GetSpellInfo
|
||||
local GetSpellTexture = GetSpellTexture
|
||||
local tIndexOf = tIndexOf
|
||||
|
||||
local GetMapInfo = GetMapInfo
|
||||
|
||||
local MAX_PLAYER_LEVEL = GetMaxLevel()
|
||||
|
||||
local filters = {}
|
||||
local exportList = {}
|
||||
local raidTargetIcon = [[|TInterface\TargetingFrame\UI-RaidTargetingIcon_%s:0|t %s]]
|
||||
local sortedClasses = E:CopyTable({}, CLASS_SORT_ORDER)
|
||||
sort(sortedClasses)
|
||||
|
||||
C.StyleFilterSelected = nil
|
||||
|
||||
E.Options.args.nameplates.args.stylefilters = ACH:Group(L["Style Filter"], nil, 10, 'tab', nil, nil, function() return not E.NamePlates.Initialized end)
|
||||
local StyleFilters = E.Options.args.nameplates.args.stylefilters.args
|
||||
local StyleFallback = NP:StyleFilterCopyDefaults()
|
||||
|
||||
local function GetFilter(collect, profile)
|
||||
local setting = (profile and E.db.nameplates.filters[C.StyleFilterSelected]) or E.global.nameplates.filters[C.StyleFilterSelected] or StyleFallback
|
||||
|
||||
if collect and setting then
|
||||
return setting.triggers, setting.actions
|
||||
else
|
||||
return setting
|
||||
end
|
||||
end
|
||||
C.StyleFilterGetFilter = GetFilter
|
||||
|
||||
local function DisabledFilter()
|
||||
local profileTriggers = GetFilter(true, true)
|
||||
return not (profileTriggers and profileTriggers.enable)
|
||||
end
|
||||
C.StyleFilterDisabledFilter = DisabledFilter
|
||||
|
||||
local function GetFilters(info)
|
||||
wipe(filters)
|
||||
|
||||
local list = E.global.nameplates.filters
|
||||
if not (list and next(list)) then
|
||||
return filters
|
||||
end
|
||||
|
||||
local profile, priority, name = E.db.nameplates.filters
|
||||
for filter, content in pairs(list) do
|
||||
if info[#info] == 'selectFilter' then
|
||||
priority = (content.triggers and content.triggers.priority) or '?'
|
||||
name = (content.triggers and profile[filter] and profile[filter].triggers and profile[filter].triggers.enable and filter) or (content.triggers and format('|cFF666666%s|r', filter)) or filter
|
||||
filters[filter] = format('|cFFffff00(%s)|r %s', priority, name)
|
||||
else
|
||||
filters[filter] = filter
|
||||
end
|
||||
end
|
||||
|
||||
return filters
|
||||
end
|
||||
|
||||
local function GetSpellFilterInfo(name)
|
||||
local spell, stacks = strmatch(name, NP.StyleFilterStackPattern)
|
||||
local spellID = tonumber(spell)
|
||||
if spellID then
|
||||
local spellName = GetSpellInfo(spellID)
|
||||
if spellName then
|
||||
if DisabledFilter() then
|
||||
spell = format('%s (%d)', spellName, spellID)
|
||||
else
|
||||
spell = format('|cFFffff00%s|r |cFFffffff(%d)|r', spellName, spellID)
|
||||
|
||||
if stacks ~= '' then
|
||||
spell = format('%s|cFF999999%s|r', spell, ' x'..stacks)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local spellTexture = GetSpellTexture(spellID or spell)
|
||||
local spellDescription = spellTexture and E:TextureString(spellTexture, ':32:32:0:0:32:32:4:28:4:28')
|
||||
|
||||
return spell, spellDescription
|
||||
end
|
||||
|
||||
local spellTypes = { casting = true, known = true, debuffs = true, buffs = true, cooldowns = true }
|
||||
local cdOptions = { DISABLED = _G.DISABLE, ONCD = L["On Cooldown"], OFFCD = L["Off Cooldown"] }
|
||||
local subTypes = { casting = 'spells', known = 'spells', debuffs = 'names', buffs = 'names', cooldowns = 'names', names = 'list', items = 'list' }
|
||||
local function GetFilterOption(which)
|
||||
local option
|
||||
if which == 'cooldowns' then
|
||||
option = ACH:Select('', nil, nil, cdOptions)
|
||||
else
|
||||
option = ACH:Toggle('', nil)
|
||||
option.textWidth = true
|
||||
end
|
||||
|
||||
return option
|
||||
end
|
||||
|
||||
local function UpdateFilterList(which, initial, opt, add)
|
||||
local filter = GetFilter()
|
||||
local spell, desc
|
||||
|
||||
local subType, isSpell = subTypes[which], spellTypes[which]
|
||||
local setting = StyleFilters.triggers.args[which].args[subType]
|
||||
local triggers = filter.triggers[which][subType] or filter.triggers[which]
|
||||
setting.hidden = not next(triggers)
|
||||
|
||||
if initial and filter.triggers[which] then
|
||||
setting.args = {}
|
||||
|
||||
for name in next, triggers do
|
||||
if isSpell then
|
||||
spell, desc = GetSpellFilterInfo(name)
|
||||
else
|
||||
spell, desc = nil, nil
|
||||
end
|
||||
|
||||
local option = GetFilterOption(which)
|
||||
option.name, option.desc = spell or name, spell and desc or nil
|
||||
|
||||
setting.args[name] = option
|
||||
end
|
||||
elseif not initial then
|
||||
if isSpell then
|
||||
spell, desc = GetSpellFilterInfo(opt)
|
||||
end
|
||||
|
||||
local option = GetFilterOption(which)
|
||||
option.name, option.desc = spell or opt, spell and desc or nil
|
||||
|
||||
setting.args[opt] = add and option or nil
|
||||
end
|
||||
end
|
||||
|
||||
local function UpdateBossModAuras(initial, opt, add)
|
||||
local filter = GetFilter()
|
||||
local setting = StyleFilters.triggers.args.bossModAuras.args
|
||||
setting.auras.hidden = not filter or not next(filter.triggers.bossMods.auras)
|
||||
|
||||
if initial then
|
||||
setting.auras.args = {}
|
||||
setting.seenList.hidden = true
|
||||
|
||||
if filter and filter.triggers and filter.triggers.bossMods and filter.triggers.bossMods.auras then
|
||||
|
||||
for aura in next, filter.triggers.bossMods.auras do
|
||||
setting.auras.args[aura] = ACH:Toggle(aura, E:TextureString(aura, ':32:32:0:0:32:32:4:28:4:28'))
|
||||
end
|
||||
end
|
||||
|
||||
if filter and filter.triggers and filter.triggers.bossMods and next(NP.BossMods_TextureCache) then
|
||||
setting.seenList.hidden = false
|
||||
|
||||
for texture in next, NP.BossMods_TextureCache do
|
||||
setting.seenList.args[texture] = ACH:Toggle(texture, E:TextureString(texture, ':32:32:0:0:32:32:4:28:4:28'))
|
||||
end
|
||||
end
|
||||
elseif not initial then
|
||||
setting.auras.args[opt] = add and ACH:Toggle(opt, E:TextureString(opt, ':32:32:0:0:32:32:4:28:4:28')) or nil
|
||||
end
|
||||
end
|
||||
|
||||
local function UpdateFilterGroup()
|
||||
UpdateFilterList('names', true)
|
||||
UpdateFilterList('items', true)
|
||||
UpdateFilterList('cooldowns', true)
|
||||
UpdateFilterList('buffs', true)
|
||||
UpdateFilterList('debuffs', true)
|
||||
UpdateFilterList('casting', true)
|
||||
UpdateFilterList('known', true)
|
||||
end
|
||||
|
||||
function C:StyleFilterSetConfig(filter)
|
||||
C.StyleFilterSelected = filter
|
||||
UpdateFilterGroup()
|
||||
|
||||
E.Libs.AceConfigDialog:SelectGroup('ElvUI', 'nameplates', 'stylefilters', filter and 'triggers' or 'import')
|
||||
end
|
||||
|
||||
local function validateCreateFilter(_, value) return not (strmatch(value, '^[%s%p]-$') or E.global.nameplates.filters[value]) end
|
||||
local function validateString(_, value) return not strmatch(value, '^[%s%p]-$') end
|
||||
|
||||
StyleFilters.addFilter = ACH:Input(L["Create Filter"], nil, 1, nil, nil, nil, function(_, value) E.global.nameplates.filters[value] = NP:StyleFilterCopyDefaults() C:StyleFilterSetConfig(value) end, nil, nil, validateCreateFilter)
|
||||
StyleFilters.selectFilter = ACH:Select(L["Select Filter"], nil, 2, GetFilters, nil, nil, function() return C.StyleFilterSelected end, function(_, value) C:StyleFilterSetConfig(value) end)
|
||||
StyleFilters.selectFilter.sortByValue = true
|
||||
StyleFilters.removeFilter = ACH:Select(L["Delete Filter"], L["Delete a created filter, you cannot delete pre-existing filters, only custom ones."], 3, function() wipe(filters) for filterName in next, E.global.nameplates.filters do if not G.nameplates.filters[filterName] then filters[filterName] = filterName end end return filters end, true, nil, nil, function(_, value) for profile in pairs(E.data.profiles) do if E.data.profiles[profile].nameplates and E.data.profiles[profile].nameplates.filters then E.data.profiles[profile].nameplates.filters[value] = nil end end E.global.nameplates.filters[value] = nil exportList[value] = nil NP:ConfigureAll() C:StyleFilterSetConfig() end)
|
||||
|
||||
StyleFilters.triggers = ACH:Group(L["Triggers"], nil, 5, nil, nil, nil, function() return not C.StyleFilterSelected end)
|
||||
-- UpdateBossModAuras needed here in get to update the list once every time you load the config with a selected filter.
|
||||
StyleFilters.triggers.args.enable = ACH:Toggle(L["Enable"], nil, 0, nil, nil, nil, function() UpdateBossModAuras(true) local profileTriggers = GetFilter(true, true) return profileTriggers and profileTriggers.enable end, function(_, value) E.db.nameplates = E.db.nameplates or {} E.db.nameplates.filters = E.db.nameplates.filters or {} E.db.nameplates.filters[C.StyleFilterSelected] = E.db.nameplates.filters[C.StyleFilterSelected] or {} local profileFilter = GetFilter(nil, true) if not profileFilter.triggers then profileFilter.triggers = {} end profileFilter.triggers.enable = value NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.priority = ACH:Range(L["Filter Priority"], L["Lower numbers mean a higher priority. Filters are processed in order from 1 to 100."], 1, { min = 1, max = 100, step = 1 }, nil, function() local triggers = GetFilter(true) return triggers.priority or 1 end, function(_, value) local triggers = GetFilter(true) if triggers then triggers.priority = value NP:ConfigureAll() end end, DisabledFilter)
|
||||
StyleFilters.triggers.args.resetFilter = ACH:Execute(L["Clear Filter"], L["Return filter to its default state."], 2, function() E.global.nameplates.filters[C.StyleFilterSelected] = E:CopyTable(NP:StyleFilterCopyDefaults(), G.nameplates.filters[C.StyleFilterSelected]) UpdateFilterGroup() NP:ConfigureAll() end)
|
||||
|
||||
StyleFilters.triggers.args.names = ACH:Group(L["Name"], nil, 6, nil, nil, nil, DisabledFilter)
|
||||
StyleFilters.triggers.args.names.args.addName = ACH:Input(L["Add Name or NPC ID"], L["Add a Name or NPC ID to the list."], 1, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.names[value] = true UpdateFilterList('names', nil, value, true) NP:ConfigureAll() end, nil, nil, validateString)
|
||||
StyleFilters.triggers.args.names.args.removeName = ACH:Select(L["Remove Name or NPC ID"], L["Remove a Name or NPC ID from the list."], 2, function() local triggers, values = GetFilter(true), {} for name in next, triggers.names do values[name] = name end return values end, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.names[value] = nil UpdateFilterList('names', nil, value) NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.names.args.negativeMatch = ACH:Toggle(L["Negative Match"], L["Match if Name or NPC ID is NOT in the list."], 3, nil, nil, nil, function(info) local triggers = GetFilter(true) return triggers[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers[info[#info]] = value NP:ConfigureAll() end)
|
||||
|
||||
StyleFilters.triggers.args.names.args.list = ACH:Group('', nil, 50, nil, function(info) local triggers = GetFilter(true) return triggers.names and triggers.names[info[#info]] end, function(info, value) local triggers = GetFilter(true) if not triggers.names then triggers.names = {} end triggers.names[info[#info]] = value NP:ConfigureAll() end, nil, true)
|
||||
StyleFilters.triggers.args.names.args.list.inline = true
|
||||
|
||||
StyleFilters.triggers.args.targeting = ACH:Group(L["Targeting"], nil, 7, nil, function(info) local triggers = GetFilter(true) return triggers[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.targeting.args.types = ACH:Group('', nil, 1)
|
||||
StyleFilters.triggers.args.targeting.args.types.inline = true
|
||||
StyleFilters.triggers.args.targeting.args.types.args.isTarget = ACH:Toggle(L["Is Targeted"], L["If enabled then the filter will only activate when you are targeting the unit."], 1)
|
||||
StyleFilters.triggers.args.targeting.args.types.args.notTarget = ACH:Toggle(L["Not Targeted"], L["If enabled then the filter will only activate when you are not targeting the unit."], 2)
|
||||
StyleFilters.triggers.args.targeting.args.types.args.requireTarget = ACH:Toggle(L["Require Target"], L["If enabled then the filter will only activate when you have a target."], 3)
|
||||
StyleFilters.triggers.args.targeting.args.types.args.noTarget = ACH:Toggle(L["No Target"], nil, 4)
|
||||
StyleFilters.triggers.args.targeting.args.types.args.targetMe = ACH:Toggle(L["Is Targeting Player"], L["If enabled then the filter will only activate when the unit is targeting you."], 5)
|
||||
StyleFilters.triggers.args.targeting.args.types.args.notTargetMe = ACH:Toggle(L["Not Targeting Player"], L["If enabled then the filter will only activate when the unit is not targeting you."], 6)
|
||||
StyleFilters.triggers.args.targeting.args.types.args.isFocus = ACH:Toggle(L["Is Focused"], L["If enabled then the filter will only activate when you are focusing the unit."], 7)
|
||||
StyleFilters.triggers.args.targeting.args.types.args.notFocus = ACH:Toggle(L["Not Focused"], L["If enabled then the filter will only activate when you are not focusing the unit."], 8)
|
||||
|
||||
StyleFilters.triggers.args.casting = ACH:Group(L["Casting"], nil, 8, nil, function(info) local triggers = GetFilter(true) return triggers.casting[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.casting[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.casting.args.types = ACH:Group('', nil, 1)
|
||||
StyleFilters.triggers.args.casting.args.types.inline = true
|
||||
StyleFilters.triggers.args.casting.args.types.args.interruptible = ACH:Toggle(L["Interruptible"], L["If enabled then the filter will only activate if the unit is casting interruptible spells."], 1)
|
||||
StyleFilters.triggers.args.casting.args.types.args.notInterruptible = ACH:Toggle(L["Non-Interruptible"], L["If enabled then the filter will only activate if the unit is casting not interruptible spells."], 2)
|
||||
StyleFilters.triggers.args.casting.args.types.args.spacer1 = ACH:Spacer(3, 'full')
|
||||
StyleFilters.triggers.args.casting.args.types.args.isCasting = ACH:Toggle(L["Is Casting Anything"], L["If enabled then the filter will activate if the unit is casting anything."], 4)
|
||||
StyleFilters.triggers.args.casting.args.types.args.notCasting = ACH:Toggle(L["Not Casting Anything"], L["If enabled then the filter will activate if the unit is not casting anything."], 5)
|
||||
StyleFilters.triggers.args.casting.args.types.args.spacer2 = ACH:Spacer(6, 'full')
|
||||
StyleFilters.triggers.args.casting.args.types.args.isChanneling = ACH:Toggle(L["Is Channeling Anything"], L["If enabled then the filter will activate if the unit is channeling anything."], 7)
|
||||
StyleFilters.triggers.args.casting.args.types.args.notChanneling = ACH:Toggle(L["Not Channeling Anything"], L["If enabled then the filter will activate if the unit is not channeling anything."], 8)
|
||||
|
||||
StyleFilters.triggers.args.casting.args.addSpell = ACH:Input(L["Add Spell ID or Name"], nil, 2, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.casting.spells[value] = true UpdateFilterList('casting', nil, value, true) NP:ConfigureAll() end, nil, nil, validateString)
|
||||
StyleFilters.triggers.args.casting.args.removeSpell = ACH:Select(L["Remove Spell ID or Name"], L["If the aura is listed with a number then you need to use that to remove it from the list."], 3, function() local triggers, values = GetFilter(true), {} for spell in next, triggers.casting.spells do values[spell] = spell end return values end, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.casting.spells[value] = nil UpdateFilterList('casting', nil, value) NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.casting.args.notSpell = ACH:Toggle(L["Not Spell"], L["If enabled then the filter will only activate if the unit is not casting or channeling one of the selected spells."], 4)
|
||||
StyleFilters.triggers.args.casting.args.description1 = ACH:Description(L["You do not need to use Is Casting Anything or Is Channeling Anything for these spells to trigger."], 10)
|
||||
StyleFilters.triggers.args.casting.args.description2 = ACH:Description(L["If this list is empty, and if Interruptible is checked, then the filter will activate on any type of cast that can be interrupted."], 11)
|
||||
|
||||
StyleFilters.triggers.args.casting.args.spells = ACH:Group('', nil, 50, nil, function(info) local triggers = GetFilter(true) return triggers.casting.spells and triggers.casting.spells[info[#info]] end, function(info, value) local triggers = GetFilter(true) if not triggers.casting.spells then triggers.casting.spells = {} end triggers.casting.spells[info[#info]] = value NP:ConfigureAll() end, nil, true)
|
||||
StyleFilters.triggers.args.casting.args.spells.inline = true
|
||||
|
||||
StyleFilters.triggers.args.known = ACH:Group(L["Known Spells"], nil, 9, nil, function(info) local triggers = GetFilter(true) return triggers.known[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.known[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.known.args.types = ACH:Group('', nil, 1)
|
||||
StyleFilters.triggers.args.known.args.types.inline = true
|
||||
StyleFilters.triggers.args.known.args.types.args.notKnown = ACH:Toggle(L["Not Known"], L["Match this trigger if the spell is not known."], 1)
|
||||
StyleFilters.triggers.args.known.args.types.args.playerSpell = ACH:Toggle(L["Player Spell"], L["This uses the IsPlayerSpell API which is only required sometimes."], 2)
|
||||
|
||||
StyleFilters.triggers.args.known.args.addSpell = ACH:Input(L["Add Spell ID or Name"], nil, 2, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.known.spells[value] = true UpdateFilterList('known', nil, value, true) NP:ConfigureAll() end, nil, nil, validateString)
|
||||
StyleFilters.triggers.args.known.args.removeSpell = ACH:Select(L["Remove Spell ID or Name"], L["If the aura is listed with a number then you need to use that to remove it from the list."], 3, function() local triggers, values = GetFilter(true), {} for spell in next, triggers.known.spells do values[spell] = spell end return values end, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.known.spells[value] = nil UpdateFilterList('known', nil, value) NP:ConfigureAll() end)
|
||||
|
||||
StyleFilters.triggers.args.known.args.spells = ACH:Group('', nil, 50, nil, function(info) local triggers = GetFilter(true) return triggers.known.spells and triggers.known.spells[info[#info]] end, function(info, value) local triggers = GetFilter(true) if not triggers.known.spells then triggers.known.spells = {} end triggers.known.spells[info[#info]] = value NP:ConfigureAll() end, nil, true)
|
||||
StyleFilters.triggers.args.known.args.spells.inline = true
|
||||
|
||||
StyleFilters.triggers.args.combat = ACH:Group(L["Unit Conditions"], nil, 10, nil, function(info) local triggers = GetFilter(true) return triggers[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
|
||||
StyleFilters.triggers.args.combat.args.playerGroup = ACH:Group(L["Player"], nil, 1)
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.inline = true
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.args.inCombat = ACH:Toggle(L["In Combat"], L["If enabled then the filter will only activate when you are in combat."], 1)
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.args.outOfCombat = ACH:Toggle(L["Out of Combat"], L["If enabled then the filter will only activate when you are out of combat."], 2)
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.args.inVehicle = ACH:Toggle(L["In Vehicle"], L["If enabled then the filter will only activate when you are in a Vehicle."], 3, nil, nil, nil, nil, nil, nil, not E.Retail)
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.args.outOfVehicle = ACH:Toggle(L["Out of Vehicle"], L["If enabled then the filter will only activate when you are not in a Vehicle."], 4, nil, nil, nil, nil, nil, nil, not E.Retail)
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.args.isResting = ACH:Toggle(L["Is Resting"], L["If enabled then the filter will only activate when you are resting at an Inn."], 5)
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.args.notResting = ACH:Toggle(L["Not Resting"], nil, 6)
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.args.playerCanAttack = ACH:Toggle(L["Can Attack"], L["If enabled then the filter will only activate when the unit can be attacked by the active player."], 7)
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.args.playerCanNotAttack = ACH:Toggle(L["Can Not Attack"], L["If enabled then the filter will only activate when the unit can not be attacked by the active player."], 8)
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.args.inPetBattle = ACH:Toggle(L["In Pet Battle"], nil, 9, nil, nil, nil, nil, nil, nil, not E.Retail)
|
||||
StyleFilters.triggers.args.combat.args.playerGroup.args.notPetBattle = ACH:Toggle(L["Not Pet Battle"], nil, 10, nil, nil, nil, nil, nil, nil, not E.Retail)
|
||||
|
||||
StyleFilters.triggers.args.combat.args.unitGroup = ACH:Group(L["Unit"], nil, 2)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.inline = true
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.inCombatUnit = ACH:Toggle(L["In Combat"], L["If enabled then the filter will only activate when the unit is in combat."], 1)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.outOfCombatUnit = ACH:Toggle(L["Out of Combat"], L["If enabled then the filter will only activate when the unit is out of combat."], 2)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.inVehicleUnit = ACH:Toggle(L["In Vehicle"], L["If enabled then the filter will only activate when the unit is in a Vehicle."], 3, nil, nil, nil, nil, nil, nil, not E.Retail)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.outOfVehicleUnit = ACH:Toggle(L["Out of Vehicle"], L["If enabled then the filter will only activate when the unit is not in a Vehicle."], 4, nil, nil, nil, nil, nil, nil, not E.Retail)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.inParty = ACH:Toggle(L["In Party"], L["If enabled then the filter will only activate when the unit is in your Party."], 5)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.notInParty = ACH:Toggle(L["Not in Party"], L["If enabled then the filter will only activate when the unit is not in your Party."], 6)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.inRaid = ACH:Toggle(L["In Raid"], L["If enabled then the filter will only activate when the unit is in your Raid."], 7)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.notInRaid = ACH:Toggle(L["Not in Raid"], L["If enabled then the filter will only activate when the unit is not in your Raid."], 8)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isPet = ACH:Toggle(L["Is Pet"], L["If enabled then the filter will only activate when the unit is the active player's pet."], 9)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isNotPet= ACH:Toggle(L["Not Pet"], L["If enabled then the filter will only activate when the unit is not the active player's pet."], 10)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isPlayerControlled = ACH:Toggle(L["Player Controlled"], L["If enabled then the filter will only activate when the unit is controlled by the player."], 11)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isNotPlayerControlled = ACH:Toggle(L["Not Player Controlled"], L["If enabled then the filter will only activate when the unit is not controlled by the player."], 12)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isOwnedByPlayer = ACH:Toggle(L["Owned By Player"], L["If enabled then the filter will only activate when the unit is owned by the player."], 13)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isNotOwnedByPlayer = ACH:Toggle(L["Not Owned By Player"], L["If enabled then the filter will only activate when the unit is not owned by the player."], 14)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isPvP = ACH:Toggle(L["Is PvP"], L["If enabled then the filter will only activate when the unit is pvp-flagged."], 15)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isNotPvP = ACH:Toggle(L["Not PvP"], L["If enabled then the filter will only activate when the unit is not pvp-flagged."], 16)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.inMyGuild = ACH:Toggle(L["My Guild"], nil, 19)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.notMyGuild = ACH:Toggle(L["Not My Guild"], nil, 20)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isTrivial = ACH:Toggle(L["Is Trivial"], nil, 21)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.notTrivial = ACH:Toggle(L["Not Trivial"], nil, 22)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isPossessed = ACH:Toggle(L["Is Possessed"], nil, 23)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.notPossessed = ACH:Toggle(L["Not Possessed"], nil, 24)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isCharmed = ACH:Toggle(L["Is Charmed"], nil, 25)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.notCharmed = ACH:Toggle(L["Not Charmed"], nil, 26)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isDeadOrGhost = ACH:Toggle(L["Dead or Ghost"], nil, 27)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.notDeadOrGhost = ACH:Toggle(L["Alive"], nil, 28)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.isConnected = ACH:Toggle(L["Connected"], nil, 29)
|
||||
StyleFilters.triggers.args.combat.args.unitGroup.args.notConnected = ACH:Toggle(L["Disconnected"], nil, 30)
|
||||
|
||||
StyleFilters.triggers.args.combat.args.npcGroup = ACH:Group('', nil, 3)
|
||||
StyleFilters.triggers.args.combat.args.npcGroup.inline = true
|
||||
StyleFilters.triggers.args.combat.args.npcGroup.args.hasTitleNPC = ACH:Toggle(L["Has NPC Title"], nil, 1)
|
||||
StyleFilters.triggers.args.combat.args.npcGroup.args.noTitleNPC = ACH:Toggle(L["No NPC Title"], nil, 2)
|
||||
|
||||
StyleFilters.triggers.args.combat.args.questGroup = ACH:Group('', nil, 4, nil, nil, nil, nil, not E.Retail)
|
||||
StyleFilters.triggers.args.combat.args.questGroup.inline = true
|
||||
StyleFilters.triggers.args.combat.args.questGroup.args.isQuest = ACH:Toggle(L["Quest Unit"], nil, 1)
|
||||
StyleFilters.triggers.args.combat.args.questGroup.args.notQuest = ACH:Toggle(L["Not Quest Unit"], nil, 2)
|
||||
|
||||
StyleFilters.triggers.args.faction = ACH:Group(L["Unit Faction"], nil, 11, nil, function(info) local triggers = GetFilter(true) return triggers.faction[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.faction[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.faction.args.types = ACH:Group('', nil, 2)
|
||||
StyleFilters.triggers.args.faction.args.types.inline = true
|
||||
StyleFilters.triggers.args.faction.args.types.args.Alliance = ACH:Toggle(L["Alliance"], nil, 1)
|
||||
StyleFilters.triggers.args.faction.args.types.args.Horde = ACH:Toggle(L["Horde"], nil, 2)
|
||||
StyleFilters.triggers.args.faction.args.types.args.Neutral = ACH:Toggle(L["Neutral"], nil, 3)
|
||||
|
||||
StyleFilters.triggers.args.class = ACH:Group(L["CLASS"], nil, 12, nil, nil, nil, DisabledFilter)
|
||||
|
||||
for index = 1, _G.MAX_CLASSES do
|
||||
local className, classTag = GetClassInfo(index)
|
||||
if classTag then
|
||||
local coloredName = RAID_CLASS_COLORS[classTag]
|
||||
coloredName = (coloredName and coloredName.colorStr) or 'ff666666'
|
||||
StyleFilters.triggers.args.class.args[classTag] = ACH:Toggle(format('|c%s%s|r', coloredName, className), nil, tIndexOf(sortedClasses, classTag), nil, nil, nil, function() local triggers = GetFilter(true) local tagTrigger = triggers.class[classTag] return tagTrigger and tagTrigger.enabled end, function(_, value) local triggers = GetFilter(true) local tagTrigger = triggers.class[classTag] if not tagTrigger then triggers.class[classTag] = {} end if value then triggers.class[classTag].enabled = value else triggers.class[classTag] = nil end NP:ConfigureAll() end)
|
||||
|
||||
local group = ACH:Group(className, nil, tIndexOf(sortedClasses, classTag) + 13, nil, nil, nil, nil, function() local triggers = GetFilter(true) local tagTrigger = triggers.class[classTag] return not tagTrigger or not tagTrigger.enabled end)
|
||||
group.inline = true
|
||||
for k = 1, #SPEC_SWAP_SPELLS do
|
||||
local specID, name = k, "Talent Specialization" .. " " .. k
|
||||
|
||||
local tagID = format('%s%s', classTag, specID)
|
||||
group.args[tagID] = ACH:Toggle(format('|c%s%s|r', coloredName, name), nil, k, nil, nil, nil, function() local triggers = GetFilter(true) local tagTrigger = triggers.class[classTag] return tagTrigger and tagTrigger.specs and tagTrigger.specs[specID] end, function(_, value) local triggers = GetFilter(true) local tagTrigger = triggers.class[classTag] if not tagTrigger.specs then triggers.class[classTag].specs = {} end triggers.class[classTag].specs[specID] = value or nil if not next(triggers.class[classTag].specs) then triggers.class[classTag].specs = nil end NP:ConfigureAll() end)
|
||||
end
|
||||
|
||||
StyleFilters.triggers.args.class.args[format('%s%s', classTag, 'spec')] = group
|
||||
end
|
||||
end
|
||||
|
||||
StyleFilters.triggers.args.slots = ACH:Group(L["Slots"], nil, 13, nil, nil, nil, DisabledFilter)
|
||||
StyleFilters.triggers.args.slots.args.types = ACH:MultiSelect(L["Equipped"], nil, 1, nil, nil, nil, function(_, key) local triggers = GetFilter(true) return triggers.slots[key] end, function(_, key, value) local triggers = GetFilter(true) triggers.slots[key] = value or nil NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.slots.args.types.sortByValue = true
|
||||
StyleFilters.triggers.args.slots.args.types.values = {
|
||||
[_G.INVSLOT_AMMO] = INVTYPE_AMMO, -- 0
|
||||
[_G.INVSLOT_HEAD] = INVTYPE_HEAD, -- 1
|
||||
[_G.INVSLOT_NECK] = INVTYPE_NECK, -- 2
|
||||
[_G.INVSLOT_SHOULDER] = INVTYPE_SHOULDER, -- 3
|
||||
[_G.INVSLOT_BODY] = INVTYPE_BODY, -- 4 (shirt)
|
||||
[_G.INVSLOT_CHEST] = INVTYPE_CHEST, -- 5
|
||||
[_G.INVSLOT_WAIST] = INVTYPE_WAIST, -- 6
|
||||
[_G.INVSLOT_LEGS] = INVTYPE_LEGS, -- 7
|
||||
[_G.INVSLOT_FEET] = INVTYPE_FEET, -- 8
|
||||
[_G.INVSLOT_WRIST] = INVTYPE_WRIST, -- 9
|
||||
[_G.INVSLOT_HAND] = INVTYPE_HAND, -- 10
|
||||
[_G.INVSLOT_FINGER1] = INVTYPE_FINGER1, -- 11 (no real global)
|
||||
[_G.INVSLOT_FINGER2] = INVTYPE_FINGER2, -- 12 (no real global)
|
||||
[_G.INVSLOT_TRINKET1] = INVTYPE_TRINKET1, -- 13 (no real global)
|
||||
[_G.INVSLOT_TRINKET2] = INVTYPE_TRINKET2, -- 14 (no real global)
|
||||
[_G.INVSLOT_BACK] = INVTYPE_CLOAK, -- 15
|
||||
[_G.INVSLOT_MAINHAND] = INVTYPE_WEAPONMAINHAND, -- 16
|
||||
[_G.INVSLOT_OFFHAND] = INVTYPE_WEAPONOFFHAND, -- 17
|
||||
[_G.INVSLOT_RANGED] = INVTYPE_RANGED, -- 18
|
||||
[_G.INVSLOT_TABARD] = INVTYPE_TABARD, -- 19
|
||||
}
|
||||
|
||||
StyleFilters.triggers.args.items = ACH:Group(L["Items"], nil, 14, nil, nil, nil, DisabledFilter)
|
||||
StyleFilters.triggers.args.items.args.addItem = ACH:Input(L["Add Item Name or ID"], L["Add a Item Name or ID to the list."], 1, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.items[value] = true UpdateFilterList('items', nil, value, true) NP:ConfigureAll() end, nil, nil, validateString)
|
||||
StyleFilters.triggers.args.items.args.removeItem = ACH:Select(L["Remove Item Name or ID"], L["Remove a Item Name or ID from the list."], 2, function() local triggers, values = GetFilter(true), {} for name in next, triggers.items do values[name] = name end return values end, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.items[value] = nil UpdateFilterList('items', nil, value) NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.items.args.negativeMatch = ACH:Toggle(L["Negative Match"], L["Match if Item Name or ID is NOT in the list."], 3, nil, nil, nil, function(info) local triggers = GetFilter(true) return triggers[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers[info[#info]] = value NP:ConfigureAll() end)
|
||||
|
||||
StyleFilters.triggers.args.items.args.list = ACH:Group('', nil, 50, nil, function(info) local triggers = GetFilter(true) return triggers.items and triggers.items[info[#info]] end, function(info, value) local triggers = GetFilter(true) if not triggers.items then triggers.items = {} end triggers.items[info[#info]] = value NP:ConfigureAll() end, nil, true)
|
||||
StyleFilters.triggers.args.items.args.list.inline = true
|
||||
|
||||
StyleFilters.triggers.args.role = ACH:Group(L["ROLE"], nil, 15, nil, nil, nil, DisabledFilter)
|
||||
|
||||
for option, name in next, { myRole = L["Player"], unitRole = L["Unit"] } do
|
||||
StyleFilters.triggers.args.role.args[option] = ACH:Group(name, nil, nil, nil, function(info) local triggers = GetFilter(true) return triggers[option] and triggers[option][info[#info]] end, function(info, value) local triggers = GetFilter(true) if not triggers[option] then triggers[option] = {} end triggers[option][info[#info]] = value NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.role.args[option].inline = true
|
||||
|
||||
for role, roleLocale in next, { tank = L["Tank"], healer = L["Healer"], damager = L["DAMAGER"] } do
|
||||
StyleFilters.triggers.args.role.args[option].args[role] = ACH:Toggle(roleLocale)
|
||||
end
|
||||
end
|
||||
|
||||
StyleFilters.triggers.args.classification = ACH:Group(L["Classification"], nil, 16, nil, function(info) local triggers = GetFilter(true) return triggers.classification[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.classification[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.classification.args.types = ACH:Group('', nil, 2)
|
||||
StyleFilters.triggers.args.classification.args.types.inline = true
|
||||
StyleFilters.triggers.args.classification.args.types.args.worldboss = ACH:Toggle(L["Boss"], nil, 1)
|
||||
StyleFilters.triggers.args.classification.args.types.args.rareelite = ACH:Toggle(L["Rare Elite"], nil, 2)
|
||||
StyleFilters.triggers.args.classification.args.types.args.normal = ACH:Toggle(PLAYER_DIFFICULTY1, nil, 3)
|
||||
StyleFilters.triggers.args.classification.args.types.args.rare = ACH:Toggle(ITEM_QUALITY3_DESC, nil, 4)
|
||||
StyleFilters.triggers.args.classification.args.types.args.trivial = ACH:Toggle(L["Trivial"], nil, 5)
|
||||
StyleFilters.triggers.args.classification.args.types.args.elite = ACH:Toggle(L["Elite"], nil, 6)
|
||||
|
||||
StyleFilters.triggers.args.health = ACH:Group(L["Health Threshold"], nil, 17, nil, function(info) local triggers = GetFilter(true) return triggers[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.health.args.healthThreshold = ACH:Toggle(L["Enable"], nil, 1)
|
||||
StyleFilters.triggers.args.health.args.healthUsePlayer = ACH:Toggle(L["Player Health"], L["Enabling this will check your health amount."], 2, nil, nil, nil, nil, nil, function() local triggers = GetFilter(true) return not triggers.healthThreshold end)
|
||||
StyleFilters.triggers.args.health.args.underHealthThreshold = ACH:Range(L["Under Health Threshold"], L["If this threshold is used then the health of the unit needs to be lower than this value in order for the filter to activate. Set to 0 to disable."], 4, { min = 0, max = 1, step = 0.01, isPercent = true }, nil, function() local triggers = GetFilter(true) return triggers.underHealthThreshold or 0 end, nil, function() local triggers = GetFilter(true) return not triggers.healthThreshold end)
|
||||
StyleFilters.triggers.args.health.args.overHealthThreshold = ACH:Range(L["Over Health Threshold"], L["If this threshold is used then the health of the unit needs to be higher than this value in order for the filter to activate. Set to 0 to disable."], 5, { min = 0, max = 1, step = 0.01, isPercent = true }, nil, function() local triggers = GetFilter(true) return triggers.overHealthThreshold or 0 end, nil, function() local triggers = GetFilter(true) return not triggers.healthThreshold end)
|
||||
|
||||
StyleFilters.triggers.args.power = ACH:Group(L["Power Threshold"], nil, 18, nil, function(info) local triggers = GetFilter(true) return triggers[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.power.args.powerThreshold = ACH:Toggle(L["Enable"], nil, 1)
|
||||
StyleFilters.triggers.args.power.args.powerUsePlayer = ACH:Toggle(L["Player Power"], L["Enabling this will check your power amount."], 2, nil, nil, nil, nil, nil, function() local triggers = GetFilter(true) return not triggers.powerThreshold end)
|
||||
StyleFilters.triggers.args.power.args.underPowerThreshold = ACH:Range(L["Under Power Threshold"], L["If this threshold is used then the power of the unit needs to be lower than this value in order for the filter to activate. Set to 0 to disable."], 4, { min = 0, max = 1, step = 0.01, isPercent = true }, nil, function() local triggers = GetFilter(true) return triggers.underPowerThreshold or 0 end, nil, function() local triggers = GetFilter(true) return not triggers.powerThreshold end)
|
||||
StyleFilters.triggers.args.power.args.overPowerThreshold = ACH:Range(L["Over Power Threshold"], L["If this threshold is used then the power of the unit needs to be higher than this value in order for the filter to activate. Set to 0 to disable."], 4, { min = 0, max = 1, step = 0.01, isPercent = true }, nil, function() local triggers = GetFilter(true) return triggers.overPowerThreshold or 0 end, nil, function() local triggers = GetFilter(true) return not triggers.powerThreshold end)
|
||||
|
||||
StyleFilters.triggers.args.keyMod = ACH:Group(L["Key Modifiers"], nil, 19, nil, function(info) local triggers = GetFilter(true) return triggers.keyMod and triggers.keyMod[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.keyMod[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.keyMod.args.enable = ACH:Toggle(L["Enable"], nil, 0)
|
||||
StyleFilters.triggers.args.keyMod.args.types = ACH:Group('', nil, 1, nil, nil, nil, function() local triggers = GetFilter(true) return DisabledFilter() or not triggers.keyMod.enable end)
|
||||
StyleFilters.triggers.args.keyMod.args.types.inline = true
|
||||
StyleFilters.triggers.args.keyMod.args.types.args.Shift = ACH:Toggle(SHIFT_KEY_TEXT, nil, 1)
|
||||
StyleFilters.triggers.args.keyMod.args.types.args.Alt = ACH:Toggle(L["ALT_KEY_TEXT"], nil, 2)
|
||||
StyleFilters.triggers.args.keyMod.args.types.args.Control = ACH:Toggle(CTRL_KEY_TEXT, nil, 3)
|
||||
StyleFilters.triggers.args.keyMod.args.types.args.Modifier = ACH:Toggle(L["Any"], nil, 4)
|
||||
StyleFilters.triggers.args.keyMod.args.types.args.LeftShift = ACH:Toggle(L["Left Shift"], nil, 6)
|
||||
StyleFilters.triggers.args.keyMod.args.types.args.LeftAlt = ACH:Toggle(L["Left Alt"], nil, 7)
|
||||
StyleFilters.triggers.args.keyMod.args.types.args.LeftControl = ACH:Toggle(L["Left Control"], nil, 8)
|
||||
StyleFilters.triggers.args.keyMod.args.types.args.RightShift = ACH:Toggle(L["Right Shift"], nil, 10)
|
||||
StyleFilters.triggers.args.keyMod.args.types.args.RightAlt = ACH:Toggle(L["Right Alt"], nil, 11)
|
||||
StyleFilters.triggers.args.keyMod.args.types.args.RightControl = ACH:Toggle(L["Right Control"], nil, 12)
|
||||
|
||||
StyleFilters.triggers.args.levels = ACH:Group(L["Level"], nil, 20, nil, function(info) local triggers = GetFilter(true) return triggers[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.levels.args.level = ACH:Toggle(L["Enable"], nil, 1)
|
||||
StyleFilters.triggers.args.levels.args.mylevel = ACH:Toggle(L["Match Player Level"], L["If enabled then the filter will only activate if the level of the unit matches your own."], 2, nil, nil, nil, nil, nil, function() local triggers = GetFilter(true) return not triggers.level end)
|
||||
StyleFilters.triggers.args.levels.args.spacer1 = ACH:Description(L["LEVEL_BOSS"], 3)
|
||||
StyleFilters.triggers.args.levels.args.minlevel = ACH:Range(L["Minimum Level"], L["If enabled then the filter will only activate if the level of the unit is equal to or higher than this value."], 4, { min = -1, max = MAX_PLAYER_LEVEL + 3, step = 1 }, nil, function(info) local triggers = GetFilter(true) return triggers[info[#info]] or 0 end, nil, function() local triggers = GetFilter(true) return not (triggers.level and not triggers.mylevel) end)
|
||||
StyleFilters.triggers.args.levels.args.maxlevel = ACH:Range(L["Maximum Level"], L["If enabled then the filter will only activate if the level of the unit is equal to or lower than this value."], 5, { min = -1, max = MAX_PLAYER_LEVEL + 3, step = 1 }, nil, function(info) local triggers = GetFilter(true) return triggers[info[#info]] or 0 end, nil, function() local triggers = GetFilter(true) return not (triggers.level and not triggers.mylevel) end)
|
||||
StyleFilters.triggers.args.levels.args.curlevel = ACH:Range(L["Current Level"], L["If enabled then the filter will only activate if the level of the unit matches this value."], 6, { min = -1, max = MAX_PLAYER_LEVEL + 3, step = 1 }, nil, function(info) local triggers = GetFilter(true) return triggers[info[#info]] or 0 end, nil, function() local triggers = GetFilter(true) return not (triggers.level and not triggers.mylevel) end)
|
||||
|
||||
StyleFilters.triggers.args.buffs = ACH:Group(L["Buffs"], nil, 21, nil, function(info) local triggers = GetFilter(true) return triggers.buffs and triggers.buffs[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.buffs[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.debuffs = ACH:Group(L["Debuffs"], nil, 22, nil, function(info) local triggers = GetFilter(true) return triggers.debuffs and triggers.debuffs[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.debuffs[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
|
||||
do
|
||||
local stackThreshold
|
||||
for _, auraType in next, { 'buffs', 'debuffs' } do
|
||||
local option = StyleFilters.triggers.args[auraType].args
|
||||
option.minTimeLeft = ACH:Range(L["Minimum Time Left"], nil, 1, { min = 0, max = 10800, step = 1 })
|
||||
option.maxTimeLeft = ACH:Range(L["Maximum Time Left"], nil, 2, { min = 0, max = 10800, step = 1 })
|
||||
option.spacer1 = ACH:Spacer(3, 'full')
|
||||
option.mustHaveAll = ACH:Toggle(L["Require All"], L["If enabled then it will require all auras to activate the filter. Otherwise it will only require any one of the auras to activate it."], 4)
|
||||
option.missing = ACH:Toggle(L["Missing"], L["If enabled then it checks if auras are missing instead of being present on the unit."], 5, nil, nil, nil, nil, nil, DisabledFilter)
|
||||
option.hasStealable = ACH:Toggle(L["Has Stealable"], L["If enabled then the filter will only activate when the unit has a stealable buff(s)."], 6)
|
||||
option.hasNoStealable = ACH:Toggle(L["Has No Stealable"], L["If enabled then the filter will only activate when the unit has no stealable buff(s)."], 7)
|
||||
option.fromMe = ACH:Toggle(L["From Me"], nil, 8)
|
||||
option.fromPet = ACH:Toggle(L["From Pet"], nil, 9)
|
||||
option.onMe = ACH:Toggle(L["On Me"], nil, 10)
|
||||
option.onPet = ACH:Toggle(L["On Pet"], nil, 11)
|
||||
|
||||
option.changeList = ACH:Group(L["Add / Remove"], nil, 10)
|
||||
option.changeList.inline = true
|
||||
option.changeList.args.addSpell = ACH:Input(L["Add Spell ID or Name"], nil, 1, nil, nil, nil, function(_, value) if stackThreshold then value = value .. '\n' .. stackThreshold end local triggers = GetFilter(true) triggers[auraType].names[value] = true stackThreshold = nil UpdateFilterList(auraType, nil, value, true) NP:ConfigureAll() end, nil, nil, validateString)
|
||||
option.changeList.args.removeSpell = ACH:Select(L["Remove Spell ID or Name"], L["If the aura is listed with a number then you need to use that to remove it from the list."], 2, function() local triggers, values = GetFilter(true), {} for name in pairs(triggers[auraType].names) do local n, v = strsplit('\n', name) values[name] = format('%s (%d)', n, v or 0) end return values end, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers[auraType].names[value] = nil UpdateFilterList(auraType, nil, value) end)
|
||||
option.changeList.args.stackThreshold = ACH:Range(L["Stack Threshold"], L["Allows you to tie a stack count to an aura when you add it to the list, which allows the trigger to act when an aura reaches X number of stacks."], 3, { min = 1, max = 250, softMax = 100, step = 1 }, nil, function() return stackThreshold or 1 end, function(_, value) stackThreshold = (value > 1 and value) or nil end)
|
||||
|
||||
option.names = ACH:Group('', nil, 50, nil, function(info) local triggers = GetFilter(true) return triggers[auraType].names and triggers[auraType].names[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers[auraType].names[info[#info]] = value NP:ConfigureAll() end, nil, true)
|
||||
option.names.inline = true
|
||||
end
|
||||
end
|
||||
|
||||
StyleFilters.triggers.args.buffs.args.minTimeLeft.desc = L["Apply this filter if a buff has remaining time greater than this. Set to zero to disable."]
|
||||
StyleFilters.triggers.args.buffs.args.maxTimeLeft.desc = L["Apply this filter if a buff has remaining time less than this. Set to zero to disable."]
|
||||
StyleFilters.triggers.args.debuffs.args.minTimeLeft.desc = L["Apply this filter if a debuff has remaining time greater than this. Set to zero to disable."]
|
||||
StyleFilters.triggers.args.debuffs.args.maxTimeLeft.desc = L["Apply this filter if a debuff has remaining time less than this. Set to zero to disable."]
|
||||
|
||||
StyleFilters.triggers.args.cooldowns = ACH:Group(L["Cooldowns"], nil, 23, nil, nil, nil, DisabledFilter)
|
||||
StyleFilters.triggers.args.cooldowns.args.addCooldown = ACH:Input(L["Add Spell ID or Name"], nil, 1, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.cooldowns.names[value] = 'ONCD' UpdateFilterList('cooldowns', nil, value, true) NP:ConfigureAll() end, nil, nil, validateString)
|
||||
StyleFilters.triggers.args.cooldowns.args.removeCooldown = ACH:Select(L["Remove Spell ID or Name"], L["If the aura is listed with a number then you need to use that to remove it from the list."], 2, function() local values = {} local triggers = GetFilter(true) for item in next, triggers.cooldowns.names do values[item] = item end return values end, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.cooldowns.names[value] = nil UpdateFilterList('cooldowns', nil, value) NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.cooldowns.args.mustHaveAll = ACH:Toggle(L["Require All"], L["If enabled then it will require all cooldowns to activate the filter. Otherwise it will only require any one of the cooldowns to activate it."], 3, nil, nil, nil, function() local triggers = GetFilter(true) return triggers.cooldowns and triggers.cooldowns.mustHaveAll end, function(_, value) local triggers = GetFilter(true) triggers.cooldowns.mustHaveAll = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.cooldowns.args.names = ACH:Group('', nil, 50, nil, function(info) local triggers = GetFilter(true) return triggers.cooldowns.names and triggers.cooldowns.names[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.cooldowns.names[info[#info]] = value NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.cooldowns.args.names.inline = true
|
||||
|
||||
StyleFilters.triggers.args.bossModAuras = ACH:Group(L["Boss Mod Auras"], nil, 24, nil, function(info) local triggers = GetFilter(true) return triggers.bossMods and triggers.bossMods[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.bossMods[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.bossModAuras.args.enable = ACH:Toggle(L["Enable"], nil, 0)
|
||||
StyleFilters.triggers.args.bossModAuras.args.hasAura = ACH:Toggle(L["Has Aura"], nil, 1, nil, nil, nil, nil, nil, function() local triggers = GetFilter(true) return DisabledFilter() or not triggers.bossMods.enable end)
|
||||
StyleFilters.triggers.args.bossModAuras.args.missingAura = ACH:Toggle(L["Missing Aura"], nil, 2, nil, nil, nil, nil, nil, function() local triggers = GetFilter(true) return DisabledFilter() or not triggers.bossMods.enable end)
|
||||
|
||||
StyleFilters.triggers.args.bossModAuras.args.seenList = ACH:Group(L["Seen Textures"], nil, 3, nil, function(info) local triggers = GetFilter(true) return triggers.bossMods and triggers.bossMods.auras and triggers.bossMods.auras[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.bossMods.auras[info[#info]] = value NP:ConfigureAll() end, function() local triggers = GetFilter(true) return DisabledFilter() or triggers.bossMods.missingAura or triggers.bossMods.hasAura or not triggers.bossMods.enable end)
|
||||
StyleFilters.triggers.args.bossModAuras.args.seenList.inline = true
|
||||
StyleFilters.triggers.args.bossModAuras.args.seenList.args.desc = ACH:Description(L["This list will display any textures Boss Mods have sent to the Boss Mod Auras element during the current session."], 0, 'medium')
|
||||
|
||||
StyleFilters.triggers.args.bossModAuras.args.changeList = ACH:Group(L["Texture Matching"], nil, 5, nil, nil, nil, function() local triggers = GetFilter(true) return DisabledFilter() or triggers.bossMods.missingAura or triggers.bossMods.hasAura or not triggers.bossMods.enable end)
|
||||
StyleFilters.triggers.args.bossModAuras.args.changeList.inline = true
|
||||
StyleFilters.triggers.args.bossModAuras.args.changeList.args.addAura = ACH:Input(L["Add Texture"], nil, 1, nil, nil, nil, function(_, value) local triggers = GetFilter(true) local textureID = tonumber(value) or value triggers.bossMods.auras[textureID] = true UpdateBossModAuras(nil, textureID, true) NP:ConfigureAll() end, nil, nil, validateString)
|
||||
StyleFilters.triggers.args.bossModAuras.args.changeList.args.removeAura = ACH:Select(L["Remove Texture"], nil, 2, function() local triggers, values = GetFilter(true), {} for textureID in next, triggers.bossMods.auras do values[tostring(textureID)] = tostring(textureID) end return values end, nil, nil, nil, function(_, value) local triggers = GetFilter(true) local textureID = tonumber(value) or value triggers.bossMods.auras[textureID] = nil UpdateBossModAuras(nil, textureID) NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.bossModAuras.args.changeList.args.missingAuras = ACH:Toggle(L["Missing Aura"], nil, 2, nil, nil, nil, function(info) local triggers = GetFilter(true) return triggers.bossMods[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.bossMods[info[#info]] = value NP:ConfigureAll() end)
|
||||
|
||||
StyleFilters.triggers.args.bossModAuras.args.auras = ACH:Group('', nil, 50, nil, function(info) local triggers = GetFilter(true) return triggers.bossMods and triggers.bossMods.auras and triggers.bossMods.auras[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.bossMods.auras[info[#info]] = value NP:ConfigureAll() end, function() local triggers = GetFilter(true) return DisabledFilter() or triggers.bossMods.missingAura or triggers.bossMods.hasAura or not triggers.bossMods.enable end)
|
||||
StyleFilters.triggers.args.bossModAuras.args.auras.inline = true
|
||||
|
||||
StyleFilters.triggers.args.threat = ACH:Group(L["Threat"], nil, 25, nil, nil, nil, DisabledFilter)
|
||||
StyleFilters.triggers.args.threat.args.enable = ACH:Toggle(L["Enable"], nil, 0, nil, nil, nil, function() local triggers = GetFilter(true) return triggers.threat and triggers.threat.enable end, function(_, value) local triggers = GetFilter(true) triggers.threat.enable = value NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.threat.args.types = ACH:Group('', nil, 1, nil, function(info) local triggers = GetFilter(true) return triggers.threat[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.threat[info[#info]] = value NP:ConfigureAll() end, function() local triggers = GetFilter(true) return DisabledFilter() or not triggers.threat.enable end)
|
||||
StyleFilters.triggers.args.threat.args.types.inline = true
|
||||
StyleFilters.triggers.args.threat.args.types.args.good = ACH:Toggle(L["Good"], nil, 1)
|
||||
StyleFilters.triggers.args.threat.args.types.args.goodTransition = ACH:Toggle(L["Good Transition"], nil, 2)
|
||||
StyleFilters.triggers.args.threat.args.types.args.badTransition = ACH:Toggle(L["Bad Transition"], nil, 3)
|
||||
StyleFilters.triggers.args.threat.args.types.args.bad = ACH:Toggle(L["Bad"], nil, 4)
|
||||
StyleFilters.triggers.args.threat.args.types.args.spacer1 = ACH:Spacer(5, 'full')
|
||||
StyleFilters.triggers.args.threat.args.types.args.offTank = ACH:Toggle(L["Off Tank"], nil, 6)
|
||||
StyleFilters.triggers.args.threat.args.types.args.offTankGoodTransition = ACH:Toggle(L["Off Tank Good Transition"], nil, 7, nil, nil, 200)
|
||||
StyleFilters.triggers.args.threat.args.types.args.offTankBadTransition = ACH:Toggle(L["Off Tank Bad Transition"], nil, 8, nil, nil, 200)
|
||||
|
||||
StyleFilters.triggers.args.nameplateType = ACH:Group(L["Unit Type"], nil, 26, nil, nil, nil, DisabledFilter)
|
||||
StyleFilters.triggers.args.nameplateType.args.enable = ACH:Toggle(L["Enable"], nil, 0, nil, nil, nil, function() local triggers = GetFilter(true) return triggers.nameplateType and triggers.nameplateType.enable end, function(_, value) local triggers = GetFilter(true) triggers.nameplateType.enable = value NP:ConfigureAll() end)
|
||||
StyleFilters.triggers.args.nameplateType.args.types = ACH:Group('', nil, 1, nil, function(info) local triggers = GetFilter(true) return triggers.nameplateType[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.nameplateType[info[#info]] = value NP:ConfigureAll() end, function() local triggers = GetFilter(true) return DisabledFilter() or not triggers.nameplateType.enable end)
|
||||
StyleFilters.triggers.args.nameplateType.args.types.inline = true
|
||||
|
||||
for frameType, keyName in next, E.NamePlates.TriggerConditions.frameTypes do
|
||||
StyleFilters.triggers.args.nameplateType.args.types.args[keyName] = ACH:Toggle(L[frameType == 'PLAYER' and 'Player' or frameType])
|
||||
end
|
||||
|
||||
StyleFilters.triggers.args.reactionType = ACH:Group(L["Reaction Type"], nil, 27, nil, function(info) local triggers = GetFilter(true) return triggers.reactionType and triggers.reactionType[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.reactionType[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.reactionType.args.enable = ACH:Toggle(L["Enable"], nil, 0)
|
||||
StyleFilters.triggers.args.reactionType.args.reputation = ACH:Toggle(L["Reputation"], L["If this is enabled then the reaction check will use your reputation with the faction the unit belongs to."], 1, nil, nil, nil, nil, nil, function() local triggers = GetFilter(true) return DisabledFilter() or not triggers.reactionType.enable end)
|
||||
StyleFilters.triggers.args.reactionType.args.types = ACH:Group('', nil, 2, nil, nil, nil, function() local triggers = GetFilter(true) return DisabledFilter() or not triggers.reactionType.enable end)
|
||||
StyleFilters.triggers.args.reactionType.args.types.inline = true
|
||||
|
||||
for i, reactionType in next, E.NamePlates.TriggerConditions.reactions do
|
||||
StyleFilters.triggers.args.reactionType.args.types.args[reactionType] = ACH:Toggle(L["FACTION_STANDING_LABEL"..i], nil, i)
|
||||
end
|
||||
|
||||
StyleFilters.triggers.args.creatureType = ACH:Group(L["Creature Type"], nil, 28, nil, function(info) local triggers = GetFilter(true) return triggers.creatureType[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.creatureType[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.creatureType.args.enable = ACH:Toggle(L["Enable"], nil, 1, nil, nil, 'full')
|
||||
StyleFilters.triggers.args.creatureType.args.types = ACH:Group('', nil, 2, nil, nil, nil, function() local triggers = GetFilter(true) return DisabledFilter() or not triggers.creatureType.enable end)
|
||||
StyleFilters.triggers.args.creatureType.args.types.inline = true
|
||||
|
||||
do -- build creatureType options
|
||||
local creatureTypeOrder = {
|
||||
Aberration = 2,
|
||||
Beast = 3,
|
||||
Critter = 4,
|
||||
Demon = 5,
|
||||
Dragonkin = 6,
|
||||
Elemental = 7,
|
||||
['Gas Cloud'] = 8,
|
||||
Giant = 9,
|
||||
Humanoid = 10,
|
||||
Mechanical = 11,
|
||||
['Not specified'] = 12,
|
||||
Totem = 13,
|
||||
Undead = 14,
|
||||
['Wild Pet'] = 15,
|
||||
['Non-combat Pet'] = 16
|
||||
}
|
||||
|
||||
for k, v in next, E.CreatureTypes do
|
||||
StyleFilters.triggers.args.creatureType.args.types.args[v] = ACH:Toggle(k, nil, creatureTypeOrder[v], nil, nil, nil, nil, nil, function() local triggers = GetFilter(true) return DisabledFilter() or not triggers.creatureType.enable end)
|
||||
end
|
||||
end
|
||||
|
||||
StyleFilters.triggers.args.instanceType = ACH:Group(L["Instance Type"], nil, 29, nil, function(info) local triggers = GetFilter(true) return triggers.instanceType[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.instanceType[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.instanceType.args.types = ACH:Group('', nil, 2)
|
||||
StyleFilters.triggers.args.instanceType.args.types.inline = true
|
||||
StyleFilters.triggers.args.instanceType.args.types.args.none = ACH:Toggle(L["None"], nil, 1)
|
||||
StyleFilters.triggers.args.instanceType.args.types.args.scenario = ACH:Toggle(L["SCENARIOS"], nil, 2, nil, nil, nil, nil, nil, nil, not E.Retail)
|
||||
StyleFilters.triggers.args.instanceType.args.types.args.party = ACH:Toggle(L["Party"], nil, 5)
|
||||
StyleFilters.triggers.args.instanceType.args.types.args.raid = ACH:Toggle(L["Raid"], nil, 5)
|
||||
StyleFilters.triggers.args.instanceType.args.types.args.arena = ACH:Toggle(L["Arena"], nil, 7, nil, nil, nil, nil, nil, nil, E.Classic)
|
||||
StyleFilters.triggers.args.instanceType.args.types.args.pvp = ACH:Toggle(L["BATTLEFIELDS"], nil, 8)
|
||||
|
||||
StyleFilters.triggers.args.instanceType.args.dungeonDifficulty = ACH:MultiSelect(L["DUNGEON_DIFFICULTY"], L["Check these to only have the filter active in certain difficulties. If none are checked, it is active in all difficulties."], 10, { normal = GetDifficultyInfo(1), heroic = GetDifficultyInfo(2), mythic = GetDifficultyInfo(3) }, nil, nil, function(_, key) local triggers = GetFilter(true) return triggers.instanceDifficulty.dungeon[key] end, function(_, key, value) local triggers = GetFilter(true) triggers.instanceDifficulty.dungeon[key] = value NP:ConfigureAll() end, nil, function() local filter = GetFilter() return not filter.triggers.instanceType.party end)
|
||||
StyleFilters.triggers.args.instanceType.args.raidDifficulty = ACH:MultiSelect(L["Raid Difficulty"], L["Check these to only have the filter active in certain difficulties. If none are checked, it is active in all difficulties."], 11, { normal = GetDifficultyInfo(1), heroic = GetDifficultyInfo(2), mythic = GetDifficultyInfo(3), ascended = GetDifficultyInfo(4) }, nil, nil, function(_, key) local triggers = GetFilter(true) return triggers.instanceDifficulty.raid[key] end, function(_, key, value) local triggers = GetFilter(true) triggers.instanceDifficulty.raid[key] = value NP:ConfigureAll() end, nil, function() local filter = GetFilter() return not filter.triggers.instanceType.raid end)
|
||||
|
||||
local removeLocationTable = { removeMapID = 'mapIDs', removeInstanceID = 'instanceIDs', removeZoneName = 'zoneNames', removeSubZoneName = 'subZoneNames' }
|
||||
local function removeLocationList(info)
|
||||
local vals = {}
|
||||
local triggers = GetFilter(true)
|
||||
local idTable = removeLocationTable[info[#info]]
|
||||
local ids = triggers.location[idTable]
|
||||
if not (ids and next(ids)) then return vals end
|
||||
|
||||
for value in pairs(ids) do
|
||||
local infoTable
|
||||
if idTable == 'instanceIDs' or idTable == 'mapIDs' then
|
||||
infoTable = tonumber(value) and (idTable == 'instanceIDs' and GetRealZoneText(value) or GetMapInfo(value))
|
||||
if infoTable then
|
||||
infoTable = '|cFF999999('..value..')|r '..(infoTable.name or infoTable)
|
||||
end
|
||||
end
|
||||
vals[value] = infoTable or value
|
||||
end
|
||||
return vals
|
||||
end
|
||||
|
||||
StyleFilters.triggers.args.location = ACH:Group(L["Location"], nil, 30, nil, function(info) local triggers = GetFilter(true) return triggers.location[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.location[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
|
||||
StyleFilters.triggers.args.location.args.map = ACH:Group('', nil, 1)
|
||||
StyleFilters.triggers.args.location.args.map.inline = true
|
||||
StyleFilters.triggers.args.location.args.map.args.mapIDEnabled = ACH:Toggle(L["Use Map ID or Name"], L["If enabled, the style filter will only activate when you are in one of the maps specified in Map ID."], 1, nil, nil, 200)
|
||||
StyleFilters.triggers.args.location.args.map.args.mapIDs = ACH:Input(L["Add Map ID"], nil, 2, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.location.mapIDs[value] = true NP:ConfigureAll() end, function () local triggers = GetFilter(true) return not triggers.location.mapIDEnabled end, nil, function(_, value) local triggers = GetFilter(true) return not (strmatch(value, '^[%s%p]-$') or triggers.location.mapIDs[value]) end)
|
||||
StyleFilters.triggers.args.location.args.map.args.removeMapID = ACH:Select(L["Remove Map ID"], nil, 3, removeLocationList, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.location.mapIDs[value] = nil NP:ConfigureAll() end, function() local triggers = GetFilter(true) local ids = triggers.location.mapIDs return not (triggers.location.mapIDEnabled and ids and next(ids)) end)
|
||||
|
||||
StyleFilters.triggers.args.location.args.instance = ACH:Group('', nil, 2)
|
||||
StyleFilters.triggers.args.location.args.instance.inline = true
|
||||
StyleFilters.triggers.args.location.args.instance.args.instanceIDEnabled = ACH:Toggle(L["Use Instance ID or Name"], L["If enabled, the style filter will only activate when you are in one of the instances specified in Instance ID."], 1, nil, nil, 200)
|
||||
StyleFilters.triggers.args.location.args.instance.args.instanceIDs = ACH:Input(L["Add Instance ID"], nil, 2, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.location.instanceIDs[value] = true NP:ConfigureAll() end, function() local triggers = GetFilter(true) return not triggers.location.instanceIDEnabled end, nil, function(_, value) local triggers = GetFilter(true) return not (strmatch(value, '^[%s%p]-$') or triggers.location.instanceIDs[value]) end)
|
||||
StyleFilters.triggers.args.location.args.instance.args.removeInstanceID = ACH:Select(L["Remove Instance ID"], nil, 3, removeLocationList, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.location.instanceIDs[value] = nil NP:ConfigureAll() end, function() local triggers = GetFilter(true) local ids = triggers.location.instanceIDs return not (triggers.location.instanceIDEnabled and ids and next(ids)) end)
|
||||
|
||||
StyleFilters.triggers.args.location.args.zoneName = ACH:Group('', nil, 3)
|
||||
StyleFilters.triggers.args.location.args.zoneName.inline = true
|
||||
StyleFilters.triggers.args.location.args.zoneName.args.zoneNamesEnabled = ACH:Toggle(L["Use Zone Names"], L["If enabled, the style filter will only activate when you are in one of the zones specified in Add Zone Name."], 1, nil, nil, 200)
|
||||
StyleFilters.triggers.args.location.args.zoneName.args.zoneNames = ACH:Input(L["Add Zone Name"], nil, 2, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.location.zoneNames[value] = true NP:ConfigureAll() end, function () local triggers = GetFilter(true) return not triggers.location.zoneNamesEnabled end, nil, function(_, value) local triggers = GetFilter(true) return not (strmatch(value, '^[%s%p]-$') or triggers.location.zoneNames[value]) end)
|
||||
StyleFilters.triggers.args.location.args.zoneName.args.removeZoneName = ACH:Select(L["Remove Zone Name"], nil, 3, removeLocationList, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.location.zoneNames[value] = nil NP:ConfigureAll() end, function() local triggers = GetFilter(true) local zone = triggers.location.zoneNames return not (triggers.location.zoneNamesEnabled and zone and next(zone)) end)
|
||||
|
||||
StyleFilters.triggers.args.location.args.subZoneName = ACH:Group('', nil, 4)
|
||||
StyleFilters.triggers.args.location.args.subZoneName.inline = true
|
||||
StyleFilters.triggers.args.location.args.subZoneName.args.subZoneNamesEnabled = ACH:Toggle(L["Use Subzone Names"], L["If enabled, the style filter will only activate when you are in one of the subzones specified in Add Subzone Name."], 1, nil, nil, 200)
|
||||
StyleFilters.triggers.args.location.args.subZoneName.args.subZoneNames = ACH:Input(L["Add Subzone Name"], nil, 2, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.location.subZoneNames[value] = true NP:ConfigureAll() end, function () local triggers = GetFilter(true) return not triggers.location.subZoneNamesEnabled end)
|
||||
StyleFilters.triggers.args.location.args.subZoneName.args.removeSubZoneName = ACH:Select(L["Remove Subzone Name"], nil, 3, removeLocationList, nil, nil, nil, function(_, value) local triggers = GetFilter(true) triggers.location.subZoneNames[value] = nil NP:ConfigureAll() end, function() local triggers = GetFilter(true) local zone = triggers.location.subZoneNames return not (triggers.location.subZoneNamesEnabled and zone and next(zone)) end)
|
||||
|
||||
StyleFilters.triggers.args.location.args.btns = ACH:Group(L["Add Current"], nil, 5)
|
||||
StyleFilters.triggers.args.location.args.btns.inline = true
|
||||
StyleFilters.triggers.args.location.args.btns.args.mapID = ACH:Execute(L["Map ID"], nil, 1, function() local mapID = E.MapInfo.mapID if not mapID then return end mapID = tostring(mapID) local triggers = GetFilter(true) if triggers.location.mapIDs[mapID] then return end triggers.location.mapIDs[mapID] = true NP:ConfigureAll() E:Print(format(L["Added Map ID: %s"], E.MapInfo.name..' ('..mapID..')')) end, nil, nil, 130)
|
||||
StyleFilters.triggers.args.location.args.btns.args.instanceID = ACH:Execute(L["Instance ID"], nil, 2, function() local instanceName, _, _, _, _, _, _, instanceID = GetInstanceInfo() if not instanceID then return end instanceID = tostring(instanceID) local triggers = GetFilter(true) if triggers.location.instanceIDs[instanceID] then return end triggers.location.instanceIDs[instanceID] = true NP:ConfigureAll() E:Print(format(L["Added Instance ID: %s"], instanceName..' ('..instanceID..')')) end, nil, nil, 130)
|
||||
StyleFilters.triggers.args.location.args.btns.args.zoneName = ACH:Execute(L["Zone Name"], nil, 3, function() local zone = E.MapInfo.realZoneText if not zone then return end local triggers = GetFilter(true) if triggers.location.zoneNames[zone] then return end triggers.location.zoneNames[zone] = true NP:ConfigureAll() E:Print(format(L["Added Zone Name: %s"], zone)) end, nil, nil, 130)
|
||||
StyleFilters.triggers.args.location.args.btns.args.subZoneName = ACH:Execute(L["Subzone Name"], nil, 4, function() local subZone = E.MapInfo.subZoneText if not subZone then return end local triggers = GetFilter(true) if triggers.location.subZoneNames[subZone] then return end triggers.location.subZoneNames[subZone] = true NP:ConfigureAll() E:Print(format(L["Added Subzone Name: %s"], subZone)) end, nil, nil, 130)
|
||||
|
||||
StyleFilters.triggers.args.raidTarget = ACH:Group(L["BINDING_HEADER_RAID_TARGET"], nil, 31, nil, function(info) local triggers = GetFilter(true) return triggers.raidTarget[info[#info]] end, function(info, value) local triggers = GetFilter(true) triggers.raidTarget[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.triggers.args.raidTarget.args.types = ACH:Group('')
|
||||
StyleFilters.triggers.args.raidTarget.args.types.inline = true
|
||||
|
||||
for i, iconName in next, E.NamePlates.TriggerConditions.raidTargets do
|
||||
StyleFilters.triggers.args.raidTarget.args.types.args[iconName] = ACH:Toggle(format(raidTargetIcon, i, L["RAID_TARGET_"..i]), nil, i)
|
||||
end
|
||||
|
||||
local actionDefaults = {
|
||||
color = {
|
||||
healthColor = { r = 0.53, g = 1.00, b = 0.40, a = 1 },
|
||||
powerColor = { r = 0.40, g = 0.53, b = 1.00, a = 1 },
|
||||
borderColor = { r = 0, g = 0, b = 0, a = 1}
|
||||
},
|
||||
flash = {
|
||||
color = { r = 0.41, g = 0.54, b = 0.85, a = 1 },
|
||||
speed = 4
|
||||
},
|
||||
}
|
||||
|
||||
local function actionHidePlate() local _, actions = GetFilter(true) return actions.hide end
|
||||
local function actionSubGroup(info, ...)
|
||||
local _, actions = GetFilter(true)
|
||||
if not actions then return end
|
||||
|
||||
if info.type == 'color' then
|
||||
local t = actions[info[#info-1]][info[#info]]
|
||||
local r, g, b, a = ...
|
||||
if r then
|
||||
t.r, t.g, t.b, t.a = r, g, b, a
|
||||
else
|
||||
local d = actionDefaults[info[#info-1]][info[#info]]
|
||||
return t.r, t.g, t.b, t.a, d.r, d.g, d.b, d.a
|
||||
end
|
||||
else
|
||||
local value = ...
|
||||
if value ~= nil then
|
||||
actions[info[#info-1]][info[#info]] = value
|
||||
else
|
||||
return actions[info[#info-1]][info[#info]]
|
||||
end
|
||||
end
|
||||
|
||||
NP:ConfigureAll()
|
||||
end
|
||||
|
||||
StyleFilters.actions = ACH:Group(L["Actions"], nil, 10, nil, function(info) local _, actions = GetFilter(true) return actions[info[#info]] end, function(info, value) local _, actions = GetFilter(true) actions[info[#info]] = value NP:ConfigureAll() end, DisabledFilter)
|
||||
StyleFilters.actions.args.hide = ACH:Toggle(L["Hide Frame"], nil, 1)
|
||||
StyleFilters.actions.args.usePortrait = ACH:Toggle(L["Use Portrait"], nil, 2, nil, nil, nil, nil, nil, actionHidePlate)
|
||||
StyleFilters.actions.args.nameOnly = ACH:Toggle(L["Name Only"], nil, 3, nil, nil, nil, nil, nil, actionHidePlate)
|
||||
StyleFilters.actions.args.spacer1 = ACH:Spacer(4, 'full')
|
||||
StyleFilters.actions.args.scale = ACH:Range(L["Scale"], nil, 5, { min = .25, max = 1.5, softMin = .5, softMax = 1.25, step = .01 }, nil, nil, nil, actionHidePlate)
|
||||
StyleFilters.actions.args.alpha = ACH:Range(L["Alpha"], L["Change the alpha level of the frame."], 6, { min = -1, max = 100, step = 1 }, nil, nil, nil, actionHidePlate)
|
||||
|
||||
StyleFilters.actions.args.color = ACH:Group(L["COLOR"], nil, 10, nil, actionSubGroup, actionSubGroup, actionHidePlate)
|
||||
StyleFilters.actions.args.color.inline = true
|
||||
StyleFilters.actions.args.color.args.health = ACH:Toggle(L["Health"], nil, 1)
|
||||
StyleFilters.actions.args.color.args.healthColor = ACH:Color(L["Health Color"], nil, 2, true)
|
||||
StyleFilters.actions.args.color.args.healthClass = ACH:Toggle(L["Unit Class Color"], nil, 3)
|
||||
StyleFilters.actions.args.color.args.spacer1 = ACH:Spacer(4, 'full')
|
||||
StyleFilters.actions.args.color.args.power = ACH:Toggle(L["Power"], nil, 10)
|
||||
StyleFilters.actions.args.color.args.powerColor = ACH:Color(L["Power Color"], nil, 11, true)
|
||||
StyleFilters.actions.args.color.args.powerClass = ACH:Toggle(L["Unit Class Color"], nil, 12)
|
||||
StyleFilters.actions.args.color.args.spacer2 = ACH:Spacer(13, 'full')
|
||||
StyleFilters.actions.args.color.args.border = ACH:Toggle(L["Border"], nil, 20)
|
||||
StyleFilters.actions.args.color.args.borderColor = ACH:Color(L["Border Color"], nil, 21, true)
|
||||
StyleFilters.actions.args.color.args.borderClass = ACH:Toggle(L["Unit Class Color"], nil, 22)
|
||||
|
||||
StyleFilters.actions.args.texture = ACH:Group(L["Texture"], nil, 20, nil, actionSubGroup, actionSubGroup, actionHidePlate)
|
||||
StyleFilters.actions.args.texture.inline = true
|
||||
StyleFilters.actions.args.texture.args.enable = ACH:Toggle(L["Enable"], nil, 1)
|
||||
StyleFilters.actions.args.texture.args.texture = ACH:SharedMediaStatusbar(L["Texture"], nil, 2, nil, nil, nil, function() local _, actions = GetFilter(true) return not actions.texture.enable end)
|
||||
|
||||
StyleFilters.actions.args.flash = ACH:Group(L["Flash"], nil, 30, nil, actionSubGroup, actionSubGroup, actionHidePlate)
|
||||
StyleFilters.actions.args.flash.inline = true
|
||||
StyleFilters.actions.args.flash.args.enable = ACH:Toggle(L["Enable"], nil, 1)
|
||||
StyleFilters.actions.args.flash.args.color = ACH:Color(L["COLOR"], nil, 2, true)
|
||||
StyleFilters.actions.args.flash.args.class = ACH:Toggle(L["Unit Class Color"], nil, 3)
|
||||
StyleFilters.actions.args.flash.args.speed = ACH:Range(L["SPEED"], nil, nil, { min = 1, max = 10, step = 1 })
|
||||
|
||||
StyleFilters.actions.args.text_format = ACH:Group(L["Text Format"], nil, 40, nil, function(info) local _, actions = GetFilter(true) return actions.tags[info[#info]] end, function(info, value) local _, actions = GetFilter(true) actions.tags[info[#info]] = value NP:ConfigureAll() end)
|
||||
StyleFilters.actions.args.text_format.inline = true
|
||||
StyleFilters.actions.args.text_format.args.info = ACH:Description(L["Controls the text displayed. Tags are available in the Available Tags section of the config."], 1, 'medium')
|
||||
StyleFilters.actions.args.text_format.args.name = ACH:Input(L["Name"], nil, 1, nil, 'full')
|
||||
StyleFilters.actions.args.text_format.args.level = ACH:Input(L["Level"], nil, 2, nil, 'full')
|
||||
StyleFilters.actions.args.text_format.args.title = ACH:Input(L["Title"], nil, 3, nil, 'full')
|
||||
StyleFilters.actions.args.text_format.args.health = ACH:Input(L["Health"], nil, 4, nil, 'full')
|
||||
StyleFilters.actions.args.text_format.args.power = ACH:Input(L["Power"], nil, 5, nil, 'full')
|
||||
|
||||
-- Import / Export
|
||||
local function DecodeString(text)
|
||||
local profileType, profileKey, profileData = D:Decode(text)
|
||||
if profileType == 'styleFilters' then
|
||||
local decodedText = (profileData and E:TableToLuaString(profileData)) or nil
|
||||
return D:CreateProfileExport(decodedText, profileType, profileKey)
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
local function DecodeLabel(label, text)
|
||||
if not validateString(nil, text) then
|
||||
label.name = ''
|
||||
return text
|
||||
end
|
||||
|
||||
local decode = DecodeString(text)
|
||||
if decode then
|
||||
return decode
|
||||
else
|
||||
label.name = L["Error decoding data. Import string may be corrupted!"]
|
||||
return text
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local importText = ''
|
||||
local label = ACH:Description('', 1)
|
||||
local function Import_Set(_, val) importText = val end
|
||||
local function Import_Get() return importText end
|
||||
local function Import_Decode() importText = DecodeLabel(label, importText) end
|
||||
local function Import_Button()
|
||||
if not validateString(nil, importText) then return end
|
||||
label.name = (D:Decode(importText) == 'styleFilters' and D:ImportProfile(importText) and L["Profile imported successfully!"]) or L["Error decoding data. Import string may be corrupted!"]
|
||||
end
|
||||
|
||||
StyleFilters.import = ACH:Group(L["Import"], nil, 15)
|
||||
StyleFilters.import.args.label = label
|
||||
StyleFilters.import.args.text = ACH:Input('', nil, 1, 10, 'full', Import_Get, Import_Set)
|
||||
StyleFilters.import.args.importButton = ACH:Execute(L["Import"], nil, 2, Import_Button)
|
||||
StyleFilters.import.args.importDecode = ACH:Execute(L["Decode"], nil, 3, Import_Decode)
|
||||
end
|
||||
|
||||
do
|
||||
local exportText = ''
|
||||
local exportPrefix = '!E1!'
|
||||
local label = ACH:Description('', 5)
|
||||
local function Filters_Empty() if not next(exportList) then StyleFilters.export.args.text.hidden = true return true end end
|
||||
local function Filters_Get(_, key) Filters_Empty() return exportList[key] end
|
||||
local function Filters_Set(_, key, value) exportList[key] = value or nil end
|
||||
local function Export_Get() label.name = '' return exportText end
|
||||
local function Export_Set() end
|
||||
local function Export_Decode() exportText = DecodeLabel(label, exportText) end
|
||||
local function Export_Button()
|
||||
local data = {nameplates = {filters = {}}}
|
||||
|
||||
if Filters_Empty() then return end
|
||||
|
||||
for key in pairs(exportList) do
|
||||
data.nameplates.filters[key] = E:CopyTable({}, E.global.nameplates.filters[key])
|
||||
end
|
||||
|
||||
NP:StyleFilterClearDefaults(data.nameplates.filters)
|
||||
data = E:RemoveTableDuplicates(data, G, D.GeneratedKeys.global)
|
||||
|
||||
local serialData = D:Serialize(data)
|
||||
local exportString = D:CreateProfileExport(serialData, 'styleFilters', 'styleFilters')
|
||||
local compressedData = LibDeflate:CompressDeflate(exportString, LibDeflate.compressLevel)
|
||||
local printableString = LibDeflate:EncodeForPrint(compressedData)
|
||||
|
||||
exportText = printableString and format('%s%s', exportPrefix, printableString) or nil
|
||||
StyleFilters.export.args.text.hidden = not exportText
|
||||
end
|
||||
|
||||
StyleFilters.export = ACH:Group(L["Export"], nil, 20)
|
||||
StyleFilters.export.args.filters = ACH:MultiSelect(L["Filters"], nil, 2, GetFilters, nil, nil, Filters_Get, Filters_Set)
|
||||
StyleFilters.export.args.filters.sortByValue = true
|
||||
StyleFilters.export.args.exportButton = ACH:Execute(L["Export"], nil, 3, Export_Button)
|
||||
StyleFilters.export.args.exportDecode = ACH:Execute(L["Decode"], nil, 4, Export_Decode)
|
||||
StyleFilters.export.args.label = label
|
||||
StyleFilters.export.args.text = ACH:Input('', nil, -1, 10, 'full', Export_Get, Export_Set, nil, true)
|
||||
end
|
||||
+65
-66
@@ -1,72 +1,71 @@
|
||||
local E, _, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local _, L = unpack(select(2, ...))
|
||||
local E, _, V, P, G = unpack(ElvUI)
|
||||
local C, L = unpack(select(2, ...))
|
||||
local ACH = E.Libs.ACH
|
||||
|
||||
local _G = _G
|
||||
local format = format
|
||||
|
||||
E.Options.args.tagGroup = {
|
||||
order = 925,
|
||||
type = "group",
|
||||
name = L["Available Tags"],
|
||||
childGroups = "tab",
|
||||
args = {
|
||||
link = {
|
||||
order = 1,
|
||||
type = "input",
|
||||
width = "full",
|
||||
name = L["Guide:"],
|
||||
get = function() return "https://www.tukui.org/forum/viewtopic.php?f=9&t=6" end,
|
||||
},
|
||||
header = {
|
||||
order = 2,
|
||||
type = "header",
|
||||
name = L["Available Tags"],
|
||||
},
|
||||
Colors = {
|
||||
type = "group",
|
||||
name = "Colors",
|
||||
args = {
|
||||
header = {
|
||||
order = 0,
|
||||
type = "header",
|
||||
name = E.InfoColor.."Colors",
|
||||
},
|
||||
customTagColorInfo = {
|
||||
order = 1,
|
||||
type = "input",
|
||||
width = "full",
|
||||
name = "Custom color your Text: replace the XXXXXX with a Hex color code",
|
||||
get = function() return "||cffXXXXXX [tags] or text here ||r" end
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
local TagGroup = ACH:Group(L["Available Tags"], nil, 19)
|
||||
TagGroup.args.GuideLink = ACH:Input(L["Guide:"], nil, 1, nil, 310, function() return 'https://github.com/tukui-org/ElvUI/wiki/custom-texts' end)
|
||||
TagGroup.args.WikiLink = ACH:Input(L["Wiki:"], nil, 2, nil, 290, function() return 'https://github.com/tukui-org/ElvUI/wiki' end)
|
||||
TagGroup.args.ColorWheel = ACH:Execute(L["Color Picker"], nil, 3, function() _G.ColorPickerFrame:Show() _G.ColorPickerFrame:SetFrameStrata('FULLSCREEN_DIALOG') _G.ColorPickerFrame:SetClampedToScreen(true) _G.ColorPickerFrame:Raise() end, nil, nil, 120)
|
||||
TagGroup.args.description = ACH:Description(L["|cffFF3333This is for information. This will not change the tags in the UI.|r"], 4, 'large')
|
||||
TagGroup.args.spacer = ACH:Spacer(5)
|
||||
|
||||
for Tag in next, E.oUF.Tags.Methods do
|
||||
if not E.TagInfo[Tag] then
|
||||
E.TagInfo[Tag] = {category = "Miscellaneous", description = ""}
|
||||
--E:Print("['"..Tag.."'] = { category = 'Miscellaneous', description = '' }")
|
||||
TagGroup.args.Colors = ACH:Group(L["Colors"])
|
||||
TagGroup.args.Colors.args.customTagColorInfo = ACH:Input('Color your tag or text by replacing the XXXXXX with a hex color code. (Name tag as red text. Ex: ||cffFF0000[name]||r)', nil, 1, nil, 'full', function() return '||cffXXXXXX [tag] or text here ||r' end)
|
||||
|
||||
TagGroup.args.Names = ACH:Group(L["Names"])
|
||||
TagGroup.args.Names.args.nameHealthInfo1 = ACH:Input('|cFF666666[1/5]|r White name text, missing hp red', nil, 1, nil, 'full', function() return '[name:health]' end)
|
||||
TagGroup.args.Names.args.nameHealthInfo2 = ACH:Input('|cFF666666[2/5]|r Class color name text, missing hp red', nil, 2, nil, 'full', function() return '[name:health{class}]' end)
|
||||
TagGroup.args.Names.args.nameHealthInfo3 = ACH:Input('|cFF666666[3/5]|r Class color name text, missing hp based on hex code', nil, 3, nil, 'full', function() return '[name:health{class:00ff00}]' end)
|
||||
TagGroup.args.Names.args.nameHealthInfo4 = ACH:Input('|cFF666666[4/5]|r Name text based on hex code, missing hp red', nil, 4, nil, 'full', function() return '[name:health{00ff00}]' end)
|
||||
TagGroup.args.Names.args.nameHealthInfo5 = ACH:Input('|cFF666666[5/5]|r Name text based on hex code, missing hp class color', nil, 5, nil, 'full', function() return '[name:health{00ff00:class}]' end)
|
||||
|
||||
local getTag = function(info) return format('[%s]', info[#info]) end
|
||||
local groups = {}
|
||||
|
||||
for _, which in pairs({'Events','OnUpdateThrottle'}) do
|
||||
for Tag in next, E.oUF.Tags[which] do
|
||||
local info = E.TagInfo[Tag] or E:AddTagInfo(Tag, 'Miscellaneous')
|
||||
|
||||
local group = TagGroup.args[info.category]
|
||||
if not group then
|
||||
group = { name = info.category, type = 'group', args = {} }
|
||||
TagGroup.args[info.category] = group
|
||||
groups[info.category] = group
|
||||
end
|
||||
|
||||
local input = group.args[Tag] or {}
|
||||
input.name = info.description ~= '' and info.description or getTag
|
||||
input.order = info.order or nil
|
||||
input.width = 'full'
|
||||
input.type = 'input'
|
||||
input.hidden = info.hidden
|
||||
input.get = getTag
|
||||
|
||||
group.args[Tag] = input
|
||||
end
|
||||
|
||||
if not E.Options.args.tagGroup.args[E.TagInfo[Tag].category] then
|
||||
E.Options.args.tagGroup.args[E.TagInfo[Tag].category] = {
|
||||
type = "group",
|
||||
name = E.TagInfo[Tag].category,
|
||||
args = {
|
||||
header = {
|
||||
order = 0,
|
||||
type = "header",
|
||||
name = E.InfoColor..E.TagInfo[Tag].category,
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
E.Options.args.tagGroup.args[E.TagInfo[Tag].category].args[Tag] = {
|
||||
type = "input",
|
||||
name = E.TagInfo[Tag].description,
|
||||
order = E.TagInfo[Tag].order or nil,
|
||||
width = "full",
|
||||
get = function() return format("[%s]", Tag) end,
|
||||
}
|
||||
end
|
||||
|
||||
-- hide groups when all their inputs are hidden
|
||||
for _, group in pairs(groups) do
|
||||
local hide = true
|
||||
for _, section in pairs(group.args) do
|
||||
if section.type ~= 'input' or not section.hidden then
|
||||
hide = false
|
||||
break
|
||||
end
|
||||
end
|
||||
if hide then
|
||||
group.hidden = true
|
||||
end
|
||||
end
|
||||
|
||||
E.Options.args.tagGroup = TagGroup
|
||||
|
||||
--[[ THIS SHOULD BE EXECUTED IN THE LAST LOADED CONFIG FILE, AT THE BOTTOM
|
||||
NOTE: This is used to make sure Plugins use no less than the options order we want. ]]
|
||||
E.OriginalOptions = {'plugins'}
|
||||
for key in pairs(E.Options.args) do table.insert(E.OriginalOptions, key) end
|
||||
setmetatable(E.OriginalOptions, {__newindex = E.noop})
|
||||
|
||||
@@ -4205,8 +4205,6 @@ E.Options.args.unitframe.args.player = {
|
||||
health = GetOptionsTable_Health(false, UF.CreateAndUpdateUF, "player"),
|
||||
infoPanel = GetOptionsTable_InformationPanel(UF.CreateAndUpdateUF, "player"),
|
||||
power = GetOptionsTable_Power(true, UF.CreateAndUpdateUF, "player", nil, true),
|
||||
energy = GetOptionsTable_Energy(true, UF.CreateAndUpdateUF, "player", nil, true),
|
||||
rage = GetOptionsTable_Rage(true, UF.CreateAndUpdateUF, "player", nil, true),
|
||||
name = GetOptionsTable_Name(UF.CreateAndUpdateUF, "player"),
|
||||
portrait = GetOptionsTable_Portrait(UF.CreateAndUpdateUF, "player"),
|
||||
fader = GetOptionsTable_Fader(UF.CreateAndUpdateUF, "player"),
|
||||
@@ -4703,6 +4701,11 @@ E.Options.args.unitframe.args.player = {
|
||||
}
|
||||
}
|
||||
|
||||
if C_Player:IsHero() then
|
||||
E.Options.args.unitframe.args.player.args.energy = GetOptionsTable_Energy(true, UF.CreateAndUpdateUF, "player", nil, true)
|
||||
E.Options.args.unitframe.args.player.args.rage = GetOptionsTable_Rage(true, UF.CreateAndUpdateUF, "player", nil, true)
|
||||
end
|
||||
|
||||
--Target Frame
|
||||
E.Options.args.unitframe.args.target = {
|
||||
order = 400,
|
||||
|
||||
Reference in New Issue
Block a user