init
This commit is contained in:
@@ -0,0 +1,463 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
local LSM = E.Libs.LSM
|
||||
local LAI = E.Libs.LAI
|
||||
|
||||
--Lua functions
|
||||
local select, unpack, pairs = select, unpack, pairs
|
||||
local band = bit.band
|
||||
local tinsert = table.insert
|
||||
local floor = math.floor
|
||||
local split = string.split
|
||||
--WoW API / Variables
|
||||
local CreateFrame = CreateFrame
|
||||
local GetSpellInfo = GetSpellInfo
|
||||
local GetTime = GetTime
|
||||
|
||||
local CREATED, VISIBLE, HIDDEN = 2, 1, 0
|
||||
|
||||
local positionValues = {
|
||||
BOTTOMLEFT = "TOP",
|
||||
BOTTOMRIGHT = "TOP",
|
||||
LEFT = "RIGHT",
|
||||
RIGHT = "LEFT",
|
||||
TOPLEFT = "BOTTOM",
|
||||
TOPRIGHT = "BOTTOM"
|
||||
}
|
||||
|
||||
local positionValues2 = {
|
||||
BOTTOMLEFT = "BOTTOM",
|
||||
BOTTOMRIGHT = "BOTTOM",
|
||||
LEFT = "LEFT",
|
||||
RIGHT = "RIGHT",
|
||||
TOPLEFT = "TOP",
|
||||
TOPRIGHT = "TOP"
|
||||
}
|
||||
|
||||
|
||||
local RaidIconBit = {
|
||||
["STAR"] = 0x00100000,
|
||||
["CIRCLE"] = 0x00200000,
|
||||
["DIAMOND"] = 0x00400000,
|
||||
["TRIANGLE"] = 0x00800000,
|
||||
["MOON"] = 0x01000000,
|
||||
["SQUARE"] = 0x02000000,
|
||||
["CROSS"] = 0x04000000,
|
||||
["SKULL"] = 0x08000000
|
||||
}
|
||||
|
||||
local ByRaidIcon = {}
|
||||
|
||||
function NP:LibAuraInfo_AURA_APPLIED(event, destGUID)
|
||||
self:UpdateElement_AurasByGUID(destGUID, event)
|
||||
end
|
||||
|
||||
function NP:LibAuraInfo_AURA_REMOVED(event, destGUID)
|
||||
self:UpdateElement_AurasByGUID(destGUID, event)
|
||||
end
|
||||
|
||||
function NP:LibAuraInfo_AURA_REFRESH(event, destGUID)
|
||||
self:LibAuraInfo_AURA_APPLIED(event, destGUID)
|
||||
end
|
||||
|
||||
function NP:LibAuraInfo_AURA_APPLIED_DOSE(event, destGUID)
|
||||
self:LibAuraInfo_AURA_APPLIED(event, destGUID)
|
||||
end
|
||||
|
||||
function NP:LibAuraInfo_AURA_CLEAR(event, destGUID)
|
||||
self:UpdateElement_AurasByGUID(destGUID, event)
|
||||
end
|
||||
|
||||
function NP:LibAuraInfo_UNIT_AURA(event, destGUID)
|
||||
self:UpdateElement_AurasByGUID(destGUID, event)
|
||||
end
|
||||
|
||||
function NP:UpdateTime(elapsed)
|
||||
self.timeLeft = self.timeLeft - elapsed
|
||||
self:SetValue(self.timeLeft)
|
||||
|
||||
if self.nextUpdate > 0 then
|
||||
self.nextUpdate = self.nextUpdate - elapsed
|
||||
return
|
||||
end
|
||||
|
||||
if self.timeLeft < 0 then
|
||||
self:SetScript("OnUpdate", nil)
|
||||
self:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
local value, id, nextUpdate, remainder = E:GetTimeInfo(self.timeLeft, self.threshold, self.hhmmThreshold, self.mmssThreshold)
|
||||
self.nextUpdate = nextUpdate
|
||||
|
||||
local style = E.TimeFormats[id]
|
||||
if style then
|
||||
local which = (self.textColors and 2 or 1) + (self.showSeconds and 0 or 2)
|
||||
if self.textColors then
|
||||
self.text:SetFormattedText(style[which], value, self.textColors[id], remainder)
|
||||
else
|
||||
self.text:SetFormattedText(style[which], value, remainder)
|
||||
end
|
||||
end
|
||||
|
||||
local color = self.timeColors[id]
|
||||
if color then
|
||||
self.text:SetTextColor(color.r, color.g, color.b)
|
||||
end
|
||||
end
|
||||
|
||||
local unstableAffliction = GetSpellInfo(30108)
|
||||
local vampiricTouch = GetSpellInfo(34914)
|
||||
function NP:SetAura(frame, guid, index, filter, isDebuff, visible)
|
||||
local isAura, name, texture, count, debuffType, duration, expiration, caster, spellID, _ = LAI:GUIDAura(guid, index, filter)
|
||||
|
||||
if frame.forceShow or frame.forceCreate then
|
||||
spellID = 47540
|
||||
name, _, texture = GetSpellInfo(spellID)
|
||||
if frame.forceShow then
|
||||
isAura, count, debuffType, duration, expiration = true, 5, "Magic", 0, 0
|
||||
end
|
||||
end
|
||||
|
||||
if isAura then
|
||||
local position = visible + 1
|
||||
local button = frame[position] or NP:Construct_AuraIcon(frame, position)
|
||||
|
||||
button.caster = caster
|
||||
button.filter = filter
|
||||
button.isDebuff = isDebuff
|
||||
|
||||
local filterCheck = not frame.forceCreate
|
||||
if not (frame.forceShow or frame.forceCreate) then
|
||||
filterCheck = NP:AuraFilter(guid, button, name, texture, count, debuffType, duration, expiration, caster, spellID)
|
||||
end
|
||||
|
||||
if filterCheck then
|
||||
if button.icon then button.icon:SetTexture(texture) end
|
||||
if button.count then button.count:SetText(count > 1 and count) end
|
||||
|
||||
if duration > 0 and expiration ~= 0 then
|
||||
local timeLeft = expiration - GetTime()
|
||||
if timeLeft > 0 then
|
||||
button.timeLeft = timeLeft
|
||||
button.nextUpdate = 0
|
||||
|
||||
button:SetMinMaxValues(0, duration)
|
||||
button:SetValue(timeLeft)
|
||||
|
||||
button:SetScript("OnUpdate", NP.UpdateTime)
|
||||
-- else
|
||||
-- return HIDDEN
|
||||
end
|
||||
else
|
||||
button.timeLeft = nil
|
||||
button.text:SetText("")
|
||||
button:SetScript("OnUpdate", nil)
|
||||
button:SetMinMaxValues(0, 1)
|
||||
button:SetValue(0)
|
||||
end
|
||||
|
||||
button:SetID(index)
|
||||
button:Show()
|
||||
|
||||
if isDebuff then
|
||||
local color = (debuffType and DebuffTypeColor[debuffType]) or DebuffTypeColor.none
|
||||
if button.name and (button.name == unstableAffliction or button.name == vampiricTouch) then
|
||||
self:StyleFrameColor(button, 0.05, 0.85, 0.94)
|
||||
else
|
||||
self:StyleFrameColor(button, color.r * 0.6, color.g * 0.6, color.b * 0.6)
|
||||
end
|
||||
end
|
||||
|
||||
return VISIBLE
|
||||
elseif frame.forceCreate then
|
||||
button:Hide()
|
||||
|
||||
return CREATED
|
||||
else
|
||||
return HIDDEN
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_AurasPosition(frame, db)
|
||||
local size = db.size + db.spacing
|
||||
local anchor = E.InversePoints[db.anchorPoint]
|
||||
local growthx = (db.growthX == "LEFT" and -1) or 1
|
||||
local growthy = (db.growthY == "DOWN" and -1) or 1
|
||||
local cols = db.perrow
|
||||
|
||||
for i = frame.anchoredIcons + 1, #frame do
|
||||
local button = frame[i]
|
||||
if not button then break end
|
||||
|
||||
local col = (i - 1) % cols
|
||||
local row = floor((i - 1) / cols)
|
||||
|
||||
button:SetSize(db.size, db.size)
|
||||
button:ClearAllPoints()
|
||||
button:SetPoint(anchor, frame, anchor, col * size * growthx, row * size * growthy)
|
||||
|
||||
button.count:FontTemplate(LSM:Fetch("font", db.countFont), db.countFontSize, db.countFontOutline)
|
||||
button.count:ClearAllPoints()
|
||||
button.count:SetPoint(db.countPosition, db.countXOffset, db.countYOffset)
|
||||
|
||||
button.text:FontTemplate(LSM:Fetch("font", db.durationFont), db.durationFontSize, db.durationFontOutline)
|
||||
button.text:ClearAllPoints()
|
||||
button.text:SetPoint(db.durationPosition, db.durationXOffset, db.durationYOffset)
|
||||
|
||||
button:SetOrientation(db.cooldownOrientation)
|
||||
|
||||
button.bg:ClearAllPoints()
|
||||
if db.cooldownOrientation == "VERTICAL" then
|
||||
button.bg:SetPoint("TOPLEFT", button)
|
||||
button.bg:SetPoint("BOTTOMRIGHT", button:GetStatusBarTexture(), "TOPRIGHT")
|
||||
else
|
||||
button.bg:SetPoint("TOPRIGHT", button)
|
||||
button.bg:SetPoint("BOTTOMLEFT", button:GetStatusBarTexture(), "BOTTOMRIGHT")
|
||||
end
|
||||
|
||||
if db.reverseCooldown then
|
||||
button:SetStatusBarColor(0, 0, 0, 0.5)
|
||||
button.bg:SetTexture(0, 0, 0, 0)
|
||||
else
|
||||
button:SetStatusBarColor(0, 0, 0, 0)
|
||||
button.bg:SetTexture(0, 0, 0, 0.5)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:UpdateElement_AuraIcons(frame, guid, filter, limit, isDebuff)
|
||||
local index, visible, hidden, created = 1, 0, 0, 0
|
||||
|
||||
while visible < limit do
|
||||
local result = NP:SetAura(frame, guid, index, filter, isDebuff, visible)
|
||||
if not result then
|
||||
break
|
||||
elseif result == HIDDEN then
|
||||
hidden = hidden + 1
|
||||
elseif result == VISIBLE then
|
||||
visible = visible + 1
|
||||
elseif result == CREATED then
|
||||
visible = visible + 1
|
||||
created = created + 1
|
||||
end
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
visible = visible - created
|
||||
|
||||
for i = visible + 1, #frame do
|
||||
frame[i].timeLeft = nil
|
||||
frame[i]:SetScript("OnUpdate", nil)
|
||||
frame[i]:Hide()
|
||||
end
|
||||
return visible
|
||||
end
|
||||
|
||||
function NP:UpdateElement_Auras(frame)
|
||||
if not frame.Health:IsShown() then return end
|
||||
|
||||
local guid = frame.guid
|
||||
|
||||
if not guid then
|
||||
if frame.UnitClass == "HERO" then
|
||||
local name = frame.UnitName
|
||||
guid = self.GUIDByName[name]
|
||||
elseif frame.RaidIcon:IsShown() then
|
||||
guid = ByRaidIcon[frame.RaidIconType]
|
||||
end
|
||||
|
||||
if guid then
|
||||
frame.guid = guid
|
||||
elseif not frame.Buffs.forceShow and not frame.Debuffs.forceShow then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local db = NP.db.units[frame.UnitType].buffs
|
||||
if db.enable then
|
||||
local buffs = frame.Buffs
|
||||
buffs.visibleBuffs = NP:UpdateElement_AuraIcons(buffs, guid, buffs.filter or "HELPFUL", db.perrow * db.numrows)
|
||||
|
||||
if #buffs > buffs.anchoredIcons then
|
||||
self:Update_AurasPosition(buffs, db)
|
||||
|
||||
buffs.anchoredIcons = #buffs
|
||||
end
|
||||
end
|
||||
|
||||
db = NP.db.units[frame.UnitType].debuffs
|
||||
if db.enable then
|
||||
local debuffs = frame.Debuffs
|
||||
debuffs.visibleDebuffs = NP:UpdateElement_AuraIcons(debuffs, guid, debuffs.filter or "HARMFUL", db.perrow * db.numrows, true)
|
||||
|
||||
if #debuffs > debuffs.anchoredIcons then
|
||||
self:Update_AurasPosition(debuffs, db)
|
||||
|
||||
debuffs.anchoredIcons = #debuffs
|
||||
end
|
||||
end
|
||||
|
||||
self:StyleFilterUpdate(frame, "UNIT_AURA")
|
||||
end
|
||||
|
||||
function NP:UpdateElement_AurasByGUID(guid, event)
|
||||
local destName, destFlags = LAI:GetGUIDInfo(guid)
|
||||
|
||||
if destName then
|
||||
destName = split("-", destName)
|
||||
end
|
||||
|
||||
local raidIcon
|
||||
if destFlags then
|
||||
for iconName, bitmask in pairs(RaidIconBit) do
|
||||
if band(destFlags, bitmask) > 0 then
|
||||
ByRaidIcon[iconName] = guid
|
||||
raidIcon = iconName
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local frame = self:SearchForFrame(guid, raidIcon, destName)
|
||||
if frame then
|
||||
frame.guid = guid
|
||||
self.GUIDByName[destName] = guid
|
||||
self:UpdateElement_Auras(frame)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_AuraIcon(parent, index)
|
||||
local db = NP.db.units[parent:GetParent().UnitType][parent.type]
|
||||
|
||||
local button = CreateFrame("StatusBar", "$parentButton"..index, parent)
|
||||
NP:StyleFrame(button, true)
|
||||
|
||||
button:SetStatusBarTexture(E.media.blankTex)
|
||||
button:SetStatusBarColor(0, 0, 0, 0)
|
||||
button:SetOrientation("VERTICAL")
|
||||
|
||||
button.bg = button:CreateTexture()
|
||||
button.bg:SetTexture(0, 0, 0, 0.5)
|
||||
|
||||
button.bg:SetPoint("TOPLEFT", button)
|
||||
button.bg:SetPoint("BOTTOMRIGHT", button:GetStatusBarTexture(), "TOPRIGHT")
|
||||
|
||||
button.icon = button:CreateTexture(nil, "BORDER")
|
||||
button.icon:SetTexCoord(unpack(E.TexCoords))
|
||||
button.icon:SetAllPoints()
|
||||
|
||||
button.count = button:CreateFontString(nil, "OVERLAY")
|
||||
button.count:SetJustifyH("RIGHT")
|
||||
button.count:FontTemplate(LSM:Fetch("font", db.countFont), db.countFontSize, db.countFontOutline)
|
||||
|
||||
button.text = button:CreateFontString(nil, "OVERLAY")
|
||||
|
||||
-- support cooldown override
|
||||
if not button.isRegisteredCooldown then
|
||||
button.CooldownOverride = "nameplates"
|
||||
button.isRegisteredCooldown = true
|
||||
button.forceEnabled = true
|
||||
|
||||
if not E.RegisteredCooldowns.nameplates then E.RegisteredCooldowns.nameplates = {} end
|
||||
tinsert(E.RegisteredCooldowns.nameplates, button)
|
||||
end
|
||||
|
||||
button.text:FontTemplate(LSM:Fetch("font", db.durationFont), db.durationFontSize, db.durationFontOutline)
|
||||
|
||||
NP:Update_CooldownOptions(button)
|
||||
|
||||
tinsert(parent, button)
|
||||
|
||||
return button
|
||||
end
|
||||
|
||||
function NP:Update_CooldownOptions(button)
|
||||
E:Cooldown_Options(button, self.db.cooldown, button)
|
||||
end
|
||||
|
||||
function NP:Configure_Auras(frame, auraType)
|
||||
local auras = frame[auraType]
|
||||
local db = self.db.units[frame.UnitType][auras.type]
|
||||
|
||||
auras:SetWidth(db.perrow * db.size + ((db.perrow - 1) * db.spacing))
|
||||
auras:SetHeight(db.numrows * db.size + ((db.numrows - 1) * db.spacing))
|
||||
auras:ClearAllPoints()
|
||||
auras:SetPoint(positionValues[db.anchorPoint], db.attachTo == "BUFFS" and frame.Buffs or frame.Health, positionValues2[db.anchorPoint], db.xOffset, db.yOffset)
|
||||
end
|
||||
|
||||
function NP:ConstructElement_Auras(frame, auraType)
|
||||
local auras = CreateFrame("Frame", "$parent"..auraType, frame)
|
||||
auras:Show()
|
||||
auras:SetSize(150, 27)
|
||||
auras:SetPoint("TOP", 0, 22)
|
||||
auras.anchoredIcons = 0
|
||||
auras.type = string.lower(auraType)
|
||||
|
||||
return auras
|
||||
end
|
||||
|
||||
function NP:CheckFilter(name, spellID, isPlayer, allowDuration, noDuration, ...)
|
||||
for i = 1, select("#", ...) do
|
||||
local filterName = select(i, ...)
|
||||
if not filterName then return true end
|
||||
if G.nameplates.specialFilters[filterName] or E.global.unitframe.aurafilters[filterName] then
|
||||
local filter = E.global.unitframe.aurafilters[filterName]
|
||||
if filter then
|
||||
local filterType = filter.type
|
||||
local spellList = filter.spells
|
||||
local spell = spellList and (spellList[spellID] or spellList[name])
|
||||
|
||||
if filterType and (filterType == "Whitelist") and (spell and spell.enable) and allowDuration then
|
||||
return true
|
||||
elseif filterType and (filterType == "Blacklist") and (spell and spell.enable) then
|
||||
return false
|
||||
end
|
||||
elseif filterName == "Personal" and isPlayer and allowDuration then
|
||||
return true
|
||||
elseif filterName == "nonPersonal" and (not isPlayer) and allowDuration then
|
||||
return true
|
||||
elseif filterName == "blockNoDuration" and noDuration then
|
||||
return false
|
||||
elseif filterName == "blockNonPersonal" and (not isPlayer) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:AuraFilter(guid, button, name, texture, count, debuffType, duration, expiration, caster, spellID)
|
||||
local parent = button:GetParent()
|
||||
local parentType = parent.type
|
||||
local db = NP.db.units[parent:GetParent().UnitType][parentType]
|
||||
if not db then return true end
|
||||
|
||||
local isPlayer = caster == E.myguid
|
||||
|
||||
-- keep these same as in `UF:AuraFilter`
|
||||
button.isPlayer = isPlayer
|
||||
button.dtype = debuffType
|
||||
button.duration = duration
|
||||
button.expiration = expiration
|
||||
button.stackCount = count
|
||||
button.name = name
|
||||
button.spellID = spellID
|
||||
button.spell = name
|
||||
button.priority = 0
|
||||
|
||||
if not db.filters then return true end
|
||||
|
||||
local priority = db.filters.priority
|
||||
local noDuration = (not duration or duration == 0)
|
||||
local allowDuration = noDuration or (duration and (duration > 0) and db.filters.maxDuration == 0 or duration <= db.filters.maxDuration) and (db.filters.minDuration == 0 or duration >= db.filters.minDuration)
|
||||
local filterCheck
|
||||
|
||||
if priority ~= "" then
|
||||
filterCheck = NP:CheckFilter(name, spellID, isPlayer, allowDuration, noDuration, split(",", priority))
|
||||
else
|
||||
filterCheck = allowDuration and true -- Allow all auras to be shown when the filter list is empty, while obeying duration sliders
|
||||
end
|
||||
|
||||
return filterCheck
|
||||
end
|
||||
@@ -0,0 +1,358 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
local unpack = unpack
|
||||
local abs = math.abs
|
||||
--WoW API / Variables
|
||||
local CreateFrame = CreateFrame
|
||||
local GetTime = GetTime
|
||||
local UnitCastingInfo = UnitCastingInfo
|
||||
local UnitChannelInfo = UnitChannelInfo
|
||||
local FAILED = FAILED
|
||||
local INTERRUPTED = INTERRUPTED
|
||||
|
||||
local function resetAttributes(self)
|
||||
self.casting = nil
|
||||
self.channeling = nil
|
||||
self.notInterruptible = nil
|
||||
self.spellName = nil
|
||||
end
|
||||
|
||||
function NP:Update_CastBarOnUpdate(elapsed)
|
||||
if self.casting or self.channeling then
|
||||
local isCasting = self.casting
|
||||
if isCasting then
|
||||
self.value = self.value + elapsed
|
||||
if self.value >= self.max then
|
||||
resetAttributes(self)
|
||||
self:Hide()
|
||||
NP:StyleFilterUpdate(self:GetParent(), "FAKE_Casting")
|
||||
return
|
||||
end
|
||||
else
|
||||
self.value = self.value - elapsed
|
||||
if self.value <= 0 then
|
||||
resetAttributes(self)
|
||||
self:Hide()
|
||||
NP:StyleFilterUpdate(self:GetParent(), "FAKE_Casting")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if self.delay ~= 0 then
|
||||
if self.channeling then
|
||||
if self.channelTimeFormat == "CURRENT" then
|
||||
self.Time:SetFormattedText("%.1f |cffaf5050%.2f|r", abs(self.value - self.max), self.delay)
|
||||
elseif self.channelTimeFormat == "CURRENTMAX" then
|
||||
self.Time:SetFormattedText("%.1f / %.2f |cffaf5050%.2f|r", abs(self.value - self.max), self.max, self.delay)
|
||||
elseif self.channelTimeFormat == "REMAINING" then
|
||||
self.Time:SetFormattedText("%.1f |cffaf5050%.2f|r", self.value, self.delay)
|
||||
elseif self.channelTimeFormat == "REMAININGMAX" then
|
||||
self.Time:SetFormattedText("%.1f / %.2f |cffaf5050%.2f|r", self.value, self.max, self.max, self.delay)
|
||||
end
|
||||
else
|
||||
if self.castTimeFormat == "CURRENT" then
|
||||
self.Time:SetFormattedText("%.1f |cffaf5050%s %.2f|r", self.value, "+", self.delay)
|
||||
elseif self.castTimeFormat == "CURRENTMAX" then
|
||||
self.Time:SetFormattedText("%.1f / %.2f |cffaf5050%s %.2f|r", self.value, self.max, "+", self.delay)
|
||||
elseif self.castTimeFormat == "REMAINING" then
|
||||
self.Time:SetFormattedText("%.1f |cffaf5050%s %.2f|r", abs(self.value - self.max), "+", self.delay)
|
||||
elseif self.castTimeFormat == "REMAININGMAX" then
|
||||
self.Time:SetFormattedText("%.1f / %.2f |cffaf5050%s %.2f|r", abs(self.value - self.max), self.max, "+", self.delay)
|
||||
end
|
||||
end
|
||||
else
|
||||
if self.channeling then
|
||||
if self.channelTimeFormat == "CURRENT" then
|
||||
self.Time:SetFormattedText("%.1f", abs(self.value - self.max))
|
||||
elseif self.channelTimeFormat == "CURRENTMAX" then
|
||||
self.Time:SetFormattedText("%.1f / %.2f", abs(self.value - self.max), self.max)
|
||||
elseif self.channelTimeFormat == "REMAINING" then
|
||||
self.Time:SetFormattedText("%.1f", self.value)
|
||||
elseif self.channelTimeFormat == "REMAININGMAX" then
|
||||
self.Time:SetFormattedText("%.1f / %.2f", self.value, self.max)
|
||||
end
|
||||
else
|
||||
if self.castTimeFormat == "CURRENT" then
|
||||
self.Time:SetFormattedText("%.1f", self.value)
|
||||
elseif self.castTimeFormat == "CURRENTMAX" then
|
||||
self.Time:SetFormattedText("%.1f / %.2f", self.value, self.max)
|
||||
elseif self.castTimeFormat == "REMAINING" then
|
||||
self.Time:SetFormattedText("%.1f", abs(self.value - self.max))
|
||||
elseif self.castTimeFormat == "REMAININGMAX" then
|
||||
self.Time:SetFormattedText("%.1f / %.2f", abs(self.value - self.max), self.max)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:SetValue(self.value)
|
||||
elseif self.holdTime > 0 then
|
||||
self.holdTime = self.holdTime - elapsed
|
||||
else
|
||||
resetAttributes(self)
|
||||
self:Hide()
|
||||
NP:StyleFilterUpdate(self:GetParent(), "FAKE_Casting")
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_CastBar(frame, event, unit)
|
||||
local castBar = frame.CastBar
|
||||
if unit then
|
||||
if not event then
|
||||
if UnitChannelInfo(unit) then
|
||||
event = "UNIT_SPELLCAST_CHANNEL_START"
|
||||
elseif UnitCastingInfo(unit) then
|
||||
event = "UNIT_SPELLCAST_START"
|
||||
end
|
||||
end
|
||||
elseif castBar:IsShown() then
|
||||
resetAttributes(castBar)
|
||||
castBar:Hide()
|
||||
end
|
||||
|
||||
if self.db.units[frame.UnitType].castbar.enable ~= true then return end
|
||||
if self.db.units[frame.UnitType].health.enable ~= true and not (frame.isTarget and self.db.alwaysShowTargetHealth) then return end --Bug
|
||||
|
||||
if event == "UNIT_SPELLCAST_START" or event == "UNIT_SPELLCAST_CHANNEL_START" then
|
||||
local name, _, _, texture, startTime, endTime, _, _, notInterruptible = UnitCastingInfo(unit)
|
||||
event = "UNIT_SPELLCAST_START"
|
||||
if not name then
|
||||
name, _, _, texture, startTime, endTime, _, notInterruptible = UnitChannelInfo(unit)
|
||||
event = "UNIT_SPELLCAST_CHANNEL_START"
|
||||
end
|
||||
|
||||
if not name then
|
||||
resetAttributes(castBar)
|
||||
castBar:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
endTime = endTime / 1000
|
||||
startTime = startTime / 1000
|
||||
|
||||
castBar.max = endTime - startTime
|
||||
castBar.startTime = startTime
|
||||
castBar.delay = 0
|
||||
castBar.casting = event == "UNIT_SPELLCAST_START"
|
||||
castBar.channeling = event == "UNIT_SPELLCAST_CHANNEL_START"
|
||||
castBar.notInterruptible = notInterruptible
|
||||
castBar.holdTime = 0
|
||||
castBar.interrupted = nil
|
||||
castBar.spellName = name
|
||||
|
||||
if castBar.casting then
|
||||
castBar.value = GetTime() - startTime
|
||||
else
|
||||
castBar.value = endTime - GetTime()
|
||||
end
|
||||
|
||||
castBar:SetMinMaxValues(0, castBar.max)
|
||||
castBar:SetValue(castBar.value)
|
||||
|
||||
castBar.Icon.texture:SetTexture(texture)
|
||||
castBar.Spark:Show()
|
||||
castBar.Name:SetText(name)
|
||||
castBar.Time:SetText()
|
||||
|
||||
castBar:Show()
|
||||
elseif event == "UNIT_SPELLCAST_STOP" or event == "UNIT_SPELLCAST_CHANNEL_STOP" then
|
||||
if castBar:IsShown() then
|
||||
resetAttributes(castBar)
|
||||
end
|
||||
elseif event == "UNIT_SPELLCAST_FAILED" or event == "UNIT_SPELLCAST_INTERRUPTED" then
|
||||
if castBar:IsShown() then
|
||||
castBar.Spark:Hide()
|
||||
castBar.Name:SetText(event == "UNIT_SPELLCAST_FAILED" and FAILED or INTERRUPTED)
|
||||
|
||||
castBar.holdTime = self.db.units[frame.UnitType].castbar.timeToHold --How long the castbar should stay visible after being interrupted, in seconds
|
||||
castBar.interrupted = true
|
||||
|
||||
resetAttributes(castBar)
|
||||
castBar:SetValue(castBar.max)
|
||||
end
|
||||
elseif event == "UNIT_SPELLCAST_DELAYED" or event == "UNIT_SPELLCAST_CHANNEL_UPDATE" then
|
||||
if frame:IsShown() then
|
||||
local name, startTime, endTime, _
|
||||
if event == "UNIT_SPELLCAST_DELAYED" then
|
||||
name, _, _, _, startTime, endTime = UnitCastingInfo(unit)
|
||||
else
|
||||
name, _, _, _, startTime, endTime = UnitChannelInfo(unit)
|
||||
end
|
||||
|
||||
if not name then
|
||||
resetAttributes(castBar)
|
||||
castBar:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
endTime = endTime / 1000
|
||||
startTime = startTime / 1000
|
||||
|
||||
local delta
|
||||
if castBar.casting then
|
||||
delta = startTime - castBar.startTime
|
||||
castBar.value = GetTime() - startTime
|
||||
else
|
||||
delta = castBar.startTime - startTime
|
||||
castBar.value = endTime - GetTime()
|
||||
end
|
||||
|
||||
if delta < 0 then
|
||||
delta = 0
|
||||
end
|
||||
|
||||
castBar.Name:SetText(name)
|
||||
castBar.max = endTime - startTime
|
||||
castBar.startTime = startTime
|
||||
castBar.delay = castBar.delay + delta
|
||||
castBar:SetMinMaxValues(0, castBar.max)
|
||||
castBar:SetValue(castBar.value)
|
||||
end
|
||||
elseif event == "UNIT_SPELLCAST_INTERRUPTIBLE" or event == "UNIT_SPELLCAST_NOT_INTERRUPTIBLE" then
|
||||
castBar.notInterruptible = event == "UNIT_SPELLCAST_NOT_INTERRUPTIBLE"
|
||||
end
|
||||
|
||||
if not castBar.notInterruptible then
|
||||
if castBar.interrupted then
|
||||
castBar:SetStatusBarColor(self.db.colors.castInterruptedColor.r, self.db.colors.castInterruptedColor.g, self.db.colors.castInterruptedColor.b)
|
||||
else
|
||||
castBar:SetStatusBarColor(self.db.colors.castColor.r, self.db.colors.castColor.g, self.db.colors.castColor.b)
|
||||
end
|
||||
castBar.Icon.texture:SetDesaturated(false)
|
||||
else
|
||||
castBar:SetStatusBarColor(self.db.colors.castNoInterruptColor.r, self.db.colors.castNoInterruptColor.g, self.db.colors.castNoInterruptColor.b)
|
||||
|
||||
if self.db.colors.castbarDesaturate then
|
||||
castBar.Icon.texture:SetDesaturated(true)
|
||||
end
|
||||
end
|
||||
|
||||
self:StyleFilterUpdate(frame, "FAKE_Casting")
|
||||
end
|
||||
|
||||
function NP:Configure_CastBarScale(frame, scale, noPlayAnimation)
|
||||
if frame.currentScale == scale then return end
|
||||
local db = self.db.units[frame.UnitType].castbar
|
||||
if not db.enable then return end
|
||||
|
||||
local castBar = frame.CastBar
|
||||
|
||||
if noPlayAnimation then
|
||||
castBar:SetSize(db.width * scale, db.height * scale)
|
||||
castBar.Icon:SetSize(db.iconSize * scale, db.iconSize * scale)
|
||||
else
|
||||
if castBar.scale:IsPlaying() or castBar.Icon.scale:IsPlaying() then
|
||||
castBar.scale:Stop()
|
||||
castBar.Icon.scale:Stop()
|
||||
end
|
||||
|
||||
castBar.scale.width:SetChange(db.width * scale)
|
||||
castBar.scale.height:SetChange(db.height * scale)
|
||||
castBar.scale:Play()
|
||||
|
||||
castBar.Icon.scale.width:SetChange(db.iconSize * scale)
|
||||
castBar.Icon.scale.height:SetChange(db.iconSize * scale)
|
||||
castBar.Icon.scale:Play()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_CastBar(frame, configuring)
|
||||
local db = self.db.units[frame.UnitType].castbar
|
||||
local castBar = frame.CastBar
|
||||
|
||||
castBar:SetPoint("TOP", frame.Health, "BOTTOM", db.xOffset, db.yOffset)
|
||||
|
||||
if db.showIcon then
|
||||
castBar.Icon:ClearAllPoints()
|
||||
castBar.Icon:SetPoint(db.iconPosition == "RIGHT" and "BOTTOMLEFT" or "BOTTOMRIGHT", castBar, db.iconPosition == "RIGHT" and "BOTTOMRIGHT" or "BOTTOMLEFT", db.iconOffsetX, db.iconOffsetY)
|
||||
castBar.Icon:Show()
|
||||
else
|
||||
castBar.Icon:Hide()
|
||||
end
|
||||
|
||||
castBar.Time:ClearAllPoints()
|
||||
castBar.Name:ClearAllPoints()
|
||||
|
||||
castBar.Spark:SetPoint("CENTER", castBar:GetStatusBarTexture(), "RIGHT", 0, 0)
|
||||
castBar.Spark:SetHeight(db.height * 2)
|
||||
|
||||
if db.textPosition == "BELOW" then
|
||||
castBar.Time:SetPoint("TOPRIGHT", castBar, "BOTTOMRIGHT")
|
||||
castBar.Name:SetPoint("TOPLEFT", castBar, "BOTTOMLEFT")
|
||||
elseif db.textPosition == "ABOVE" then
|
||||
castBar.Time:SetPoint("BOTTOMRIGHT", castBar, "TOPRIGHT")
|
||||
castBar.Name:SetPoint("BOTTOMLEFT", castBar, "TOPLEFT")
|
||||
else
|
||||
castBar.Time:SetPoint("RIGHT", castBar, "RIGHT", -4, 0)
|
||||
castBar.Name:SetPoint("LEFT", castBar, "LEFT", 4, 0)
|
||||
end
|
||||
|
||||
if configuring then
|
||||
self:Configure_CastBarScale(frame, frame.currentScale or 1, configuring)
|
||||
end
|
||||
|
||||
castBar.Name:FontTemplate(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline)
|
||||
castBar.Time:FontTemplate(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline)
|
||||
|
||||
if db.hideSpellName then
|
||||
castBar.Name:Hide()
|
||||
else
|
||||
castBar.Name:Show()
|
||||
end
|
||||
if db.hideTime then
|
||||
castBar.Time:Hide()
|
||||
else
|
||||
castBar.Time:Show()
|
||||
end
|
||||
|
||||
castBar:SetStatusBarTexture(LSM:Fetch("statusbar", self.db.statusbar))
|
||||
|
||||
castBar.castTimeFormat = db.castTimeFormat
|
||||
castBar.channelTimeFormat = db.channelTimeFormat
|
||||
end
|
||||
|
||||
function NP:Construct_CastBar(parent)
|
||||
local frame = CreateFrame("StatusBar", "$parentCastBar", parent)
|
||||
NP:StyleFrame(frame)
|
||||
frame:SetScript("OnUpdate", NP.Update_CastBarOnUpdate)
|
||||
|
||||
frame.Icon = CreateFrame("Frame", nil, frame)
|
||||
frame.Icon.texture = frame.Icon:CreateTexture(nil, "BORDER")
|
||||
frame.Icon.texture:SetAllPoints()
|
||||
frame.Icon.texture:SetTexCoord(unpack(E.TexCoords))
|
||||
NP:StyleFrame(frame.Icon)
|
||||
|
||||
frame.Time = frame:CreateFontString(nil, "OVERLAY")
|
||||
frame.Time:SetJustifyH("RIGHT")
|
||||
frame.Time:SetWordWrap(false)
|
||||
|
||||
frame.Name = frame:CreateFontString(nil, "OVERLAY")
|
||||
frame.Name:SetJustifyH("LEFT")
|
||||
frame.Name:SetWordWrap(false)
|
||||
|
||||
frame.Spark = frame:CreateTexture(nil, "OVERLAY")
|
||||
frame.Spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
|
||||
frame.Spark:SetBlendMode("ADD")
|
||||
frame.Spark:SetSize(15, 15)
|
||||
|
||||
frame.holdTime = 0
|
||||
frame.interrupted = nil
|
||||
|
||||
frame.scale = CreateAnimationGroup(frame)
|
||||
frame.scale.width = frame.scale:CreateAnimation("Width")
|
||||
frame.scale.width:SetDuration(0.2)
|
||||
frame.scale.height = frame.scale:CreateAnimation("Height")
|
||||
frame.scale.height:SetDuration(0.2)
|
||||
|
||||
frame.Icon.scale = CreateAnimationGroup(frame.Icon)
|
||||
frame.Icon.scale.width = frame.Icon.scale:CreateAnimation("Width")
|
||||
frame.Icon.scale.width:SetDuration(0.2)
|
||||
frame.Icon.scale.height = frame.Icon.scale:CreateAnimation("Height")
|
||||
frame.Icon.scale.height:SetDuration(0.2)
|
||||
|
||||
frame:Hide()
|
||||
|
||||
return frame
|
||||
end
|
||||
@@ -0,0 +1,119 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...))
|
||||
local NP = E:GetModule("NamePlates")
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
--WoW API / Variables
|
||||
local CreateFrame = CreateFrame
|
||||
local GetComboPoints = GetComboPoints
|
||||
local MAX_COMBO_POINTS = MAX_COMBO_POINTS
|
||||
|
||||
function NP:Update_CPoints(frame)
|
||||
if frame.UnitType == "FRIENDLY_PLAYER" or frame.UnitType == "FRIENDLY_NPC" then return end
|
||||
if not self.db.units.TARGET.comboPoints.enable then return end
|
||||
|
||||
local numPoints
|
||||
if frame.isTarget then
|
||||
numPoints = GetComboPoints("player", "target")
|
||||
end
|
||||
|
||||
if numPoints and numPoints > 0 then
|
||||
frame.CPoints:Show()
|
||||
|
||||
for i = 1, MAX_COMBO_POINTS do
|
||||
if i <= numPoints then
|
||||
frame.CPoints[i]:Show()
|
||||
else
|
||||
frame.CPoints[i]:Hide()
|
||||
end
|
||||
end
|
||||
else
|
||||
frame.CPoints:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_CPointsScale(frame, scale, noPlayAnimation)
|
||||
if frame.UnitType == "FRIENDLY_PLAYER" or frame.UnitType == "FRIENDLY_NPC" then return end
|
||||
local db = self.db.units.TARGET.comboPoints
|
||||
if not db.enable then return end
|
||||
|
||||
if noPlayAnimation then
|
||||
frame.CPoints:SetWidth(((db.width * 5) + (db.spacing * 4)) * scale)
|
||||
frame.CPoints:SetHeight(db.height * scale)
|
||||
else
|
||||
if frame.CPoints.scale:IsPlaying() then
|
||||
frame.CPoints.scale:Stop()
|
||||
end
|
||||
|
||||
frame.CPoints.scale.width:SetChange(((db.width * 5) + (db.spacing * 4)) * scale)
|
||||
frame.CPoints.scale.height:SetChange(db.height * scale)
|
||||
frame.CPoints.scale:Play()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_CPoints(frame, configuring)
|
||||
if frame.UnitType == "FRIENDLY_PLAYER" or frame.UnitType == "FRIENDLY_NPC" then return end
|
||||
local db = self.db.units.TARGET.comboPoints
|
||||
if not db.enable then return end
|
||||
|
||||
local comboBar = frame.CPoints
|
||||
local healthShown = self.db.units[frame.UnitType].health.enable or (frame.isTarget and self.db.alwaysShowTargetHealth)
|
||||
|
||||
comboBar:ClearAllPoints()
|
||||
if healthShown then
|
||||
comboBar:Point("CENTER", frame.Health, "BOTTOM", db.xOffset, db.yOffset)
|
||||
else
|
||||
comboBar:Point("CENTER", frame, "TOP", db.xOffset, db.yOffset)
|
||||
end
|
||||
|
||||
for i = 1, MAX_COMBO_POINTS do
|
||||
local comboPoint = comboBar[i]
|
||||
comboPoint.backdrop:SetTexture(LSM:Fetch("statusbar", self.db.statusbar))
|
||||
local color = self.db.colors.comboPoints[i]
|
||||
comboPoint.backdrop:SetVertexColor(color.r, color.g, color.b)
|
||||
|
||||
comboPoint:SetWidth(db.width)
|
||||
|
||||
comboPoint:ClearAllPoints()
|
||||
if i == 1 then
|
||||
comboPoint:SetPoint("TOPLEFT")
|
||||
comboPoint:SetPoint("BOTTOMLEFT")
|
||||
else
|
||||
comboPoint:SetPoint("TOPLEFT", comboBar[i - 1], "TOPRIGHT", db.spacing, 0)
|
||||
comboPoint:SetPoint("BOTTOMLEFT", comboBar[i - 1], "BOTTOMRIGHT")
|
||||
end
|
||||
end
|
||||
|
||||
comboBar.spacing = db.spacing * (MAX_COMBO_POINTS - 1)
|
||||
|
||||
if configuring then
|
||||
self:Configure_CPointsScale(frame, frame.currentScale or 1, configuring)
|
||||
end
|
||||
end
|
||||
|
||||
local function CPoints_OnSizeChanged(self, width)
|
||||
width = width - self.spacing
|
||||
for i = 1, MAX_COMBO_POINTS do
|
||||
self[i]:SetWidth(width * 0.2)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_CPoints(parent)
|
||||
local comboBar = CreateFrame("Frame", "$parentComboPoints", parent)
|
||||
comboBar:Hide()
|
||||
|
||||
comboBar.scale = CreateAnimationGroup(comboBar)
|
||||
comboBar.scale.width = comboBar.scale:CreateAnimation("Width")
|
||||
comboBar.scale.width:SetDuration(0.2)
|
||||
comboBar.scale.height = comboBar.scale:CreateAnimation("Height")
|
||||
comboBar.scale.height:SetDuration(0.2)
|
||||
|
||||
comboBar:SetScript("OnSizeChanged", CPoints_OnSizeChanged)
|
||||
|
||||
for i = 1, MAX_COMBO_POINTS do
|
||||
comboBar[i] = CreateFrame("Frame", "$parentComboPoint"..i, comboBar)
|
||||
self:StyleFrame(comboBar[i])
|
||||
end
|
||||
|
||||
return comboBar
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
|
||||
--Lua functions
|
||||
--WoW API / Variables
|
||||
|
||||
function NP:UpdateElement_CutawayHealthFadeOut(frame)
|
||||
local cutawayHealth = frame.CutawayHealth
|
||||
cutawayHealth.fading = true
|
||||
E:UIFrameFadeOut(cutawayHealth, self.db.cutawayHealthFadeOutTime, cutawayHealth:GetAlpha(), 0)
|
||||
cutawayHealth.isPlaying = nil
|
||||
end
|
||||
|
||||
local function CutawayHealthClosure(frame)
|
||||
NP:UpdateElement_CutawayHealthFadeOut(frame)
|
||||
end
|
||||
|
||||
function NP:CutawayHealthValueChangeCallback(frame, health, maxHealth)
|
||||
if self.db.cutawayHealth then
|
||||
frame.CutawayHealth:SetMinMaxValues(0, maxHealth)
|
||||
local oldValue = frame.Health:GetValue()
|
||||
local change = oldValue - health
|
||||
if change > 0 and not frame.CutawayHealth.isPlaying then
|
||||
local cutawayHealth = frame.CutawayHealth
|
||||
if cutawayHealth.fading then
|
||||
E:UIFrameFadeRemoveFrame(cutawayHealth)
|
||||
end
|
||||
cutawayHealth.fading = false
|
||||
cutawayHealth:SetValue(oldValue)
|
||||
cutawayHealth:SetAlpha(1)
|
||||
|
||||
E:Delay(self.db.cutawayHealthLength, CutawayHealthClosure, frame)
|
||||
|
||||
cutawayHealth.isPlaying = true
|
||||
cutawayHealth:Show()
|
||||
end
|
||||
else
|
||||
if frame.CutawayHealth.isPlaying then
|
||||
frame.CutawayHealth.isPlaying = nil
|
||||
frame.CutawayHealth:SetScript("OnUpdate", nil)
|
||||
end
|
||||
frame.CutawayHealth:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:CutawayHealthColorChangeCallback(frame, r, g, b)
|
||||
frame.CutawayHealth:SetStatusBarColor(r * 1.5, g * 1.5, b * 1.5, 1)
|
||||
end
|
||||
|
||||
function NP:ConstructElement_CutawayHealth(parent)
|
||||
local healthBar = parent.Health
|
||||
|
||||
local cutawayHealth = CreateFrame("StatusBar", "$parentCutawayHealth", healthBar)
|
||||
cutawayHealth:SetAllPoints()
|
||||
cutawayHealth:SetStatusBarTexture(E.media.blankTex)
|
||||
cutawayHealth:SetFrameLevel(healthBar:GetFrameLevel() - 1)
|
||||
|
||||
NP:RegisterHealthBarCallbacks(parent, NP.CutawayHealthValueChangeCallback, NP.CutawayHealthColorChangeCallback)
|
||||
|
||||
return cutawayHealth
|
||||
end
|
||||
@@ -0,0 +1,53 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
|
||||
--Lua functions
|
||||
--WoW API / Variables
|
||||
|
||||
function NP:Update_Elite(frame)
|
||||
local db = self.db.units[frame.UnitType].eliteIcon
|
||||
if not db then return end
|
||||
|
||||
local icon = frame.Elite
|
||||
if db.enable then
|
||||
local elite, boss = frame.EliteIcon:IsShown(), frame.BossIcon:IsShown()
|
||||
|
||||
if boss then
|
||||
icon:SetTexCoord(0, 0.15, 0.62, 0.94)
|
||||
icon:Show()
|
||||
elseif elite then
|
||||
icon:SetTexCoord(0, 0.15, 0.35, 0.63)
|
||||
icon:Show()
|
||||
else
|
||||
icon:Hide()
|
||||
end
|
||||
else
|
||||
icon:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_Elite(frame)
|
||||
local db = self.db.units[frame.UnitType].eliteIcon
|
||||
if not db then return end
|
||||
|
||||
local icon = frame.Elite
|
||||
|
||||
icon:Size(db.size)
|
||||
icon:ClearAllPoints()
|
||||
|
||||
if frame.Health:IsShown() then
|
||||
icon:SetParent(frame.Health)
|
||||
icon:Point(db.position, frame.Health, db.position, db.xOffset, db.yOffset)
|
||||
else
|
||||
icon:SetParent(frame)
|
||||
icon:Point(db.position, frame, db.position, db.xOffset, db.yOffset)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Elite(frame)
|
||||
local icon = frame.Health:CreateTexture(nil, "OVERLAY")
|
||||
icon:SetTexture(E.Media.Textures.Nameplates)
|
||||
icon:Hide()
|
||||
|
||||
return icon
|
||||
end
|
||||
@@ -0,0 +1,193 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
local ipairs = ipairs
|
||||
--WoW API / Variables
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
--[[
|
||||
Target Glow Style Option Variables
|
||||
style1 - Border
|
||||
style2 - Background
|
||||
style3 - Top Arrow Only
|
||||
style4 - Side Arrows Only
|
||||
style5 - Border + Top Arrow
|
||||
style6 - Background + Top Arrow
|
||||
style7 - Border + Side Arrows
|
||||
style8 - Background + Side Arrows
|
||||
]]
|
||||
|
||||
function NP:Update_Glow(frame)
|
||||
local showIndicator
|
||||
|
||||
if frame.isTarget then
|
||||
showIndicator = 1
|
||||
elseif self.db.lowHealthThreshold > 0 then
|
||||
local health = frame.oldHealthBar:GetValue()
|
||||
local _, maxHealth = frame.oldHealthBar:GetMinMaxValues()
|
||||
local perc = health / maxHealth
|
||||
|
||||
if health > 1 and perc <= self.db.lowHealthThreshold then
|
||||
if perc <= self.db.lowHealthThreshold / 2 then
|
||||
showIndicator = 2
|
||||
else
|
||||
showIndicator = 3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local glowStyle = self.db.units.TARGET.glowStyle
|
||||
local healthIsShown = frame.Health:IsShown()
|
||||
|
||||
if not healthIsShown then
|
||||
if glowStyle == "style1" then
|
||||
glowStyle = "none"
|
||||
elseif glowStyle == "style5" then
|
||||
glowStyle = "style3"
|
||||
elseif glowStyle == "style7" then
|
||||
glowStyle = "style4"
|
||||
end
|
||||
end
|
||||
|
||||
if showIndicator and glowStyle ~= "none" then
|
||||
local r, g, b
|
||||
|
||||
if showIndicator == 1 then
|
||||
local color = self.db.colors.glowColor
|
||||
r, g, b = color.r, color.g, color.b
|
||||
elseif showIndicator == 2 then
|
||||
r, g, b = 1, 0, 0
|
||||
else
|
||||
r, g, b = 1, 1, 0
|
||||
end
|
||||
|
||||
-- Indicators
|
||||
frame.TopIndicator:SetVertexColor(r, g, b)
|
||||
frame.LeftIndicator:SetVertexColor(r, g, b)
|
||||
frame.RightIndicator:SetVertexColor(r, g, b)
|
||||
|
||||
if glowStyle == "style3" or glowStyle == "style5" or glowStyle == "style6" then
|
||||
frame.LeftIndicator:Hide()
|
||||
frame.RightIndicator:Hide()
|
||||
|
||||
if healthIsShown then
|
||||
frame.TopIndicator:Show()
|
||||
end
|
||||
elseif glowStyle == "style4" or glowStyle == "style7" or glowStyle == "style8" then
|
||||
frame.TopIndicator:Hide()
|
||||
|
||||
if healthIsShown then
|
||||
frame.LeftIndicator:Show()
|
||||
frame.RightIndicator:Show()
|
||||
end
|
||||
end
|
||||
|
||||
-- Spark / Shadow
|
||||
frame.Shadow:SetBackdropBorderColor(r, g, b)
|
||||
frame.Spark:SetVertexColor(r, g, b)
|
||||
|
||||
if glowStyle == "style1" or glowStyle == "style5" or glowStyle == "style7" then
|
||||
frame.Spark:Hide()
|
||||
frame.Shadow:Show()
|
||||
elseif glowStyle == "style2" or glowStyle == "style6" or glowStyle == "style8" then
|
||||
frame.Shadow:Hide()
|
||||
frame.Spark:Show()
|
||||
end
|
||||
else
|
||||
frame.TopIndicator:Hide()
|
||||
frame.LeftIndicator:Hide()
|
||||
frame.RightIndicator:Hide()
|
||||
frame.Shadow:Hide()
|
||||
frame.Spark:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_Glow(frame)
|
||||
local glowStyle = self.db.units.TARGET.glowStyle
|
||||
local healthIsShown = frame.Health:IsShown()
|
||||
|
||||
if not healthIsShown then
|
||||
if glowStyle == "style1" then
|
||||
glowStyle = "none"
|
||||
elseif glowStyle == "style5" then
|
||||
glowStyle = "style3"
|
||||
elseif glowStyle == "style7" then
|
||||
glowStyle = "style4"
|
||||
end
|
||||
end
|
||||
|
||||
if glowStyle ~= "none" then
|
||||
local color = self.db.colors.glowColor
|
||||
local r, g, b, a = color.r, color.g, color.b, color.a
|
||||
|
||||
-- Indicators
|
||||
frame.LeftIndicator:SetVertexColor(r, g, b)
|
||||
frame.RightIndicator:SetVertexColor(r, g, b)
|
||||
frame.TopIndicator:SetVertexColor(r, g, b)
|
||||
|
||||
frame.TopIndicator:ClearAllPoints()
|
||||
frame.LeftIndicator:ClearAllPoints()
|
||||
frame.RightIndicator:ClearAllPoints()
|
||||
|
||||
if glowStyle == "style3" or glowStyle == "style5" or glowStyle == "style6" then
|
||||
if healthIsShown then
|
||||
frame.TopIndicator:SetPoint("BOTTOM", frame.Health, "TOP", 0, 6)
|
||||
else
|
||||
frame.TopIndicator:SetPoint("BOTTOM", frame.Name, "TOP", 0, 8)
|
||||
end
|
||||
elseif glowStyle == "style4" or glowStyle == "style7" or glowStyle == "style8" then
|
||||
if healthIsShown then
|
||||
frame.LeftIndicator:SetPoint("LEFT", frame.Health, "RIGHT", -3, 0)
|
||||
frame.RightIndicator:SetPoint("RIGHT", frame.Health, "LEFT", 3, 0)
|
||||
else
|
||||
frame.LeftIndicator:SetPoint("LEFT", frame.Name, "RIGHT", 20, 0)
|
||||
frame.RightIndicator:SetPoint("RIGHT", frame.Name, "LEFT", -20, 0)
|
||||
end
|
||||
end
|
||||
|
||||
-- Spark / Shadow
|
||||
frame.Shadow:SetBackdropBorderColor(r, g, b)
|
||||
frame.Shadow:SetAlpha(a)
|
||||
|
||||
frame.Spark:SetVertexColor(r, g, b, a)
|
||||
frame.Spark:ClearAllPoints()
|
||||
|
||||
if glowStyle == "style1" or glowStyle == "style5" or glowStyle == "style7" then
|
||||
frame.Shadow:SetOutside(frame.Health, E:Scale(E.PixelMode and 6 or 8), E:Scale(E.PixelMode and 6 or 8))
|
||||
elseif glowStyle == "style2" or glowStyle == "style6" or glowStyle == "style8" then
|
||||
if healthIsShown then
|
||||
local size = E.Border + 14
|
||||
frame.Spark:SetPoint("TOPLEFT", frame.Health, -(size * 2), size)
|
||||
frame.Spark:SetPoint("BOTTOMRIGHT", frame.Health, (size * 2), -size)
|
||||
else
|
||||
local nameIsShown = frame.Name:IsShown()
|
||||
frame.Spark:SetPoint("TOPLEFT", nameIsShown and frame.Name or frame.IconFrame, -20, 8)
|
||||
frame.Spark:SetPoint("BOTTOMRIGHT", nameIsShown and frame.Name or frame.IconFrame, 20, -8)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Textures = {"Spark", "TopIndicator", "LeftIndicator", "RightIndicator"}
|
||||
|
||||
function NP:Construct_Glow(frame)
|
||||
frame.Shadow = CreateFrame("Frame", "$parentGlow", frame)
|
||||
frame.Shadow:SetFrameLevel(frame.Health:GetFrameLevel() - 1)
|
||||
frame.Shadow:SetBackdrop({edgeFile = LSM:Fetch("border", "ElvUI GlowBorder"), edgeSize = E:Scale(6)})
|
||||
frame.Shadow:Hide()
|
||||
|
||||
for _, object in ipairs(Textures) do
|
||||
frame[object] = frame:CreateTexture(nil, "BACKGROUND")
|
||||
frame[object]:Hide()
|
||||
end
|
||||
|
||||
frame.Spark:SetTexture(E.Media.Textures.Spark)
|
||||
frame.TopIndicator:SetTexture(E.Media.Textures.ArrowUp)
|
||||
frame.TopIndicator:SetRotation(3.14)
|
||||
frame.LeftIndicator:SetTexture(E.Media.Textures.ArrowUp)
|
||||
frame.LeftIndicator:SetRotation(1.57)
|
||||
frame.RightIndicator:SetTexture(E.Media.Textures.ArrowUp)
|
||||
frame.RightIndicator:SetRotation(-1.57)
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
|
||||
--Lua functions
|
||||
--WoW API / Variables
|
||||
|
||||
function NP:Update_HealerIcon(frame)
|
||||
local icon = frame.HealerIcon
|
||||
if frame.UnitType == "ENEMY_PLAYER" and self.Healers[frame.UnitName] then
|
||||
icon:ClearAllPoints()
|
||||
if frame.Health:IsShown() then
|
||||
icon:SetPoint("RIGHT", frame.Health, "LEFT", -6, 0)
|
||||
else
|
||||
icon:SetPoint("BOTTOM", frame.Name, "TOP", 0, 3)
|
||||
end
|
||||
|
||||
icon:Show()
|
||||
else
|
||||
icon:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_HealerIcon(frame)
|
||||
local texture = frame:CreateTexture(nil, "OVERLAY")
|
||||
texture:SetPoint("RIGHT", frame.Health, "LEFT", -6, 0)
|
||||
texture:SetSize(40, 40)
|
||||
texture:SetTexture(E.Media.Textures.Healer)
|
||||
texture:Hide()
|
||||
|
||||
return texture
|
||||
end
|
||||
@@ -0,0 +1,213 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
--WoW API / Variables
|
||||
|
||||
function NP:Update_HealthOnValueChanged()
|
||||
local frame = self:GetParent().UnitFrame
|
||||
if not frame.UnitType then return end -- Bugs
|
||||
|
||||
NP:Update_Health(frame)
|
||||
NP:Update_HealthColor(frame)
|
||||
NP:Update_Glow(frame)
|
||||
NP:StyleFilterUpdate(frame, "UNIT_HEALTH")
|
||||
end
|
||||
|
||||
function NP:Update_HealthColor(frame)
|
||||
if not frame.Health:IsShown() then return end
|
||||
|
||||
local r, g, b
|
||||
local scale = 1
|
||||
|
||||
local classColor = E.media.herocolor
|
||||
local useClassColor = NP.db.units[frame.UnitType].health.useClassColor
|
||||
if classColor and ((frame.UnitType == "FRIENDLY_PLAYER" and useClassColor) or (frame.UnitType == "ENEMY_PLAYER" and useClassColor)) then
|
||||
r, g, b = classColor.r, classColor.g, classColor.b
|
||||
else
|
||||
local db = self.db.colors
|
||||
local status = frame.ThreatStatus
|
||||
if status then
|
||||
if status == 3 then
|
||||
if E.Role == "Tank" then
|
||||
r, g, b = db.threat.goodColor.r, db.threat.goodColor.g, db.threat.goodColor.b
|
||||
scale = NP.db.threat.goodScale
|
||||
else
|
||||
r, g, b = db.threat.badColor.r, db.threat.badColor.g, db.threat.badColor.b
|
||||
scale = NP.db.threat.badScale
|
||||
end
|
||||
elseif status == 2 then
|
||||
if E.Role == "Tank" then
|
||||
r, g, b = db.threat.badTransition.r, db.threat.badTransition.g, db.threat.badTransition.b
|
||||
else
|
||||
r, g, b = db.threat.goodTransition.r, db.threat.goodTransition.g, db.threat.goodTransition.b
|
||||
end
|
||||
scale = 1
|
||||
elseif status == 1 then
|
||||
if E.Role == "Tank" then
|
||||
r, g, b = db.threat.goodTransition.r, db.threat.goodTransition.g, db.threat.goodTransition.b
|
||||
else
|
||||
r, g, b = db.threat.badTransition.r, db.threat.badTransition.g, db.threat.badTransition.b
|
||||
end
|
||||
scale = 1
|
||||
else
|
||||
if E.Role == "Tank" then
|
||||
r, g, b = db.threat.badColor.r, db.threat.badColor.g, db.threat.badColor.b
|
||||
scale = self.db.threat.badScale
|
||||
else
|
||||
r, g, b = db.threat.goodColor.r, db.threat.goodColor.g, db.threat.goodColor.b
|
||||
scale = self.db.threat.goodScale
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (not status) or (status and not NP.db.threat.useThreatColor) then
|
||||
local reactionType = frame.UnitReaction
|
||||
if reactionType == 4 then
|
||||
r, g, b = db.reactions.neutral.r, db.reactions.neutral.g, db.reactions.neutral.b
|
||||
elseif reactionType and reactionType > 4 then
|
||||
if frame.UnitType == "FRIENDLY_PLAYER" then
|
||||
r, g, b = db.reactions.friendlyPlayer.r, db.reactions.friendlyPlayer.g, db.reactions.friendlyPlayer.b
|
||||
else
|
||||
r, g, b = db.reactions.good.r, db.reactions.good.g, db.reactions.good.b
|
||||
end
|
||||
else
|
||||
r, g, b = db.reactions.bad.r, db.reactions.bad.g, db.reactions.bad.b
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if r ~= frame.Health.r or g ~= frame.Health.g or b ~= frame.Health.b then
|
||||
if not frame.HealthColorChanged then
|
||||
frame.Health:SetStatusBarColor(r, g, b)
|
||||
|
||||
if frame.HealthColorChangeCallbacks then
|
||||
for _, cb in ipairs(frame.HealthColorChangeCallbacks) do
|
||||
cb(self, frame, r, g, b)
|
||||
end
|
||||
end
|
||||
end
|
||||
frame.Health.r, frame.Health.g, frame.Health.b = r, g, b
|
||||
end
|
||||
|
||||
if frame.ThreatScale ~= scale then
|
||||
frame.ThreatScale = scale
|
||||
if frame.isTarget and self.db.useTargetScale then
|
||||
scale = scale * self.db.targetScale
|
||||
end
|
||||
self:SetFrameScale(frame, scale * (frame.ActionScale or 1))
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_Health(frame)
|
||||
local health = frame.oldHealthBar:GetValue()
|
||||
local _, maxHealth = frame.oldHealthBar:GetMinMaxValues()
|
||||
frame.Health:SetMinMaxValues(0, maxHealth)
|
||||
|
||||
if frame.HealthValueChangeCallbacks then
|
||||
for _, cb in ipairs(frame.HealthValueChangeCallbacks) do
|
||||
cb(self, frame, health, maxHealth)
|
||||
end
|
||||
end
|
||||
|
||||
frame.Health:SetValue(health)
|
||||
frame.FlashTexture:Point("TOPRIGHT", frame.Health:GetStatusBarTexture(), "TOPRIGHT") --idk why this fixes this
|
||||
|
||||
if self.db.units[frame.UnitType].health.text.enable then
|
||||
frame.Health.Text:SetText(E:GetFormattedText(self.db.units[frame.UnitType].health.text.format, health, maxHealth))
|
||||
end
|
||||
end
|
||||
|
||||
function NP:RegisterHealthBarCallbacks(frame, valueChangeCB, colorChangeCB)
|
||||
if valueChangeCB then
|
||||
frame.HealthValueChangeCallbacks = frame.HealthValueChangeCallbacks or {}
|
||||
tinsert(frame.HealthValueChangeCallbacks, valueChangeCB)
|
||||
end
|
||||
|
||||
if colorChangeCB then
|
||||
frame.HealthColorChangeCallbacks = frame.HealthColorChangeCallbacks or {}
|
||||
tinsert(frame.HealthColorChangeCallbacks, colorChangeCB)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_HealthBar(frame)
|
||||
if self.db.units[frame.UnitType].health.enable or (frame.isTarget and self.db.alwaysShowTargetHealth) then
|
||||
frame.Health:Show()
|
||||
else
|
||||
frame.Health:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_HealthBarScale(frame, scale, noPlayAnimation)
|
||||
if noPlayAnimation then
|
||||
frame.Health:SetWidth(self.db.units[frame.UnitType].health.width * scale)
|
||||
frame.Health:SetHeight(self.db.units[frame.UnitType].health.height * scale)
|
||||
else
|
||||
if frame.Health.scale:IsPlaying() then
|
||||
frame.Health.scale:Stop()
|
||||
end
|
||||
|
||||
frame.Health.scale.width:SetChange(self.db.units[frame.UnitType].health.width * scale)
|
||||
frame.Health.scale.height:SetChange(self.db.units[frame.UnitType].health.height * scale)
|
||||
frame.Health.scale:Play()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_HealthBar(frame, configuring)
|
||||
local db = self.db.units[frame.UnitType].health
|
||||
local healthBar = frame.Health
|
||||
|
||||
healthBar:SetPoint("TOP", frame, "TOP", 0, 0)
|
||||
|
||||
if configuring then
|
||||
healthBar:SetStatusBarTexture(LSM:Fetch("statusbar", self.db.statusbar), "BORDER")
|
||||
|
||||
self:Configure_HealthBarScale(frame, frame.currentScale or 1, configuring)
|
||||
|
||||
E:SetSmoothing(healthBar, self.db.smoothbars)
|
||||
|
||||
if db.text.enable then
|
||||
healthBar.Text:ClearAllPoints()
|
||||
healthBar.Text:Point(E.InversePoints[db.text.position], db.text.parent == "Nameplate" and frame or frame[db.text.parent], db.text.position, db.text.xOffset, db.text.yOffset)
|
||||
healthBar.Text:FontTemplate(LSM:Fetch("font", db.text.font), db.text.fontSize, db.text.fontOutline)
|
||||
healthBar.Text:Show()
|
||||
else
|
||||
healthBar.Text:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function HealthBar_OnSizeChanged(self, width)
|
||||
local health = self:GetValue()
|
||||
local _, maxHealth = self:GetMinMaxValues()
|
||||
self:GetStatusBarTexture():SetPoint("TOPRIGHT", -(width * ((maxHealth - health) / maxHealth)), 0)
|
||||
end
|
||||
|
||||
function NP:Construct_HealthBar(parent)
|
||||
local frame = CreateFrame("StatusBar", "$parentHealthBar", parent)
|
||||
frame:SetStatusBarTexture(LSM:Fetch("statusbar", self.db.statusbar), "BORDER")
|
||||
self:StyleFrame(frame)
|
||||
|
||||
frame:SetScript("OnSizeChanged", HealthBar_OnSizeChanged)
|
||||
|
||||
parent.FlashTexture = frame:CreateTexture(nil, "OVERLAY")
|
||||
parent.FlashTexture:SetTexture(LSM:Fetch("background", "ElvUI Blank"))
|
||||
parent.FlashTexture:Point("BOTTOMLEFT", frame:GetStatusBarTexture(), "BOTTOMLEFT")
|
||||
parent.FlashTexture:Point("TOPRIGHT", frame:GetStatusBarTexture(), "TOPRIGHT")
|
||||
parent.FlashTexture:Hide()
|
||||
|
||||
frame.Text = frame:CreateFontString(nil, "OVERLAY")
|
||||
frame.Text:SetAllPoints(frame)
|
||||
frame.Text:SetWordWrap(false)
|
||||
|
||||
frame.scale = CreateAnimationGroup(frame)
|
||||
frame.scale.width = frame.scale:CreateAnimation("Width")
|
||||
frame.scale.width:SetDuration(0.2)
|
||||
frame.scale.height = frame.scale:CreateAnimation("Height")
|
||||
frame.scale.height:SetDuration(0.2)
|
||||
|
||||
frame:Hide()
|
||||
|
||||
return frame
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
--WoW API / Variables
|
||||
|
||||
function NP:Update_Highlight(frame)
|
||||
if not NP.db.highlight then return end
|
||||
|
||||
if frame.isMouseover and ((frame.IconOnlyChanged or frame.NameOnlyChanged) or (not self.db.units[frame.UnitType].health.enable and self.db.units[frame.UnitType].name.enable)) and not frame.isTarget then
|
||||
frame.Name.NameOnlyGlow:Show()
|
||||
frame.Health.Highlight:Show()
|
||||
elseif frame.isMouseover and (not frame.NameOnlyChanged or self.db.units[frame.UnitType].health.enable) and not frame.isTarget then
|
||||
frame.Health.Highlight:Show()
|
||||
else
|
||||
frame.Name.NameOnlyGlow:Hide()
|
||||
frame.Health.Highlight:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_Highlight(frame)
|
||||
frame.Health.Highlight:ClearAllPoints()
|
||||
frame.Health.Highlight:SetPoint("TOPLEFT", frame.Health, "TOPLEFT")
|
||||
frame.Health.Highlight:SetPoint("BOTTOMRIGHT", frame.Health:GetStatusBarTexture(), "BOTTOMRIGHT")
|
||||
frame.Health.Highlight:SetTexture(LSM:Fetch("statusbar", self.db.statusbar))
|
||||
end
|
||||
|
||||
function NP:Construct_Highlight(frame)
|
||||
local highlight = frame.Health:CreateTexture("$parentHighlight", "OVERLAY")
|
||||
highlight:SetVertexColor(1, 1, 1, 0.3)
|
||||
highlight:Hide()
|
||||
return highlight
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
|
||||
--Lua functions
|
||||
--WoW API / Variables
|
||||
|
||||
function NP:Update_IconFrame(frame, triggered)
|
||||
local db = self.db.units[frame.UnitType].iconFrame
|
||||
if not db then return end
|
||||
|
||||
if (db and db.enable) or (frame.IconOnlyChanged or frame.IconChanged) then
|
||||
local totem, unit, icon = self.Totems[frame.UnitName], self.UniqueUnits[frame.UnitName]
|
||||
if totem then
|
||||
icon = NP.TriggerConditions.totems[totem][3]
|
||||
elseif unit then
|
||||
icon = NP.TriggerConditions.uniqueUnits[unit][3]
|
||||
end
|
||||
|
||||
if icon then
|
||||
frame.IconFrame.texture:SetTexture(icon)
|
||||
frame.IconFrame:Show()
|
||||
|
||||
self:StyleFrameColor(frame.IconFrame, frame.oldHealthBar:GetStatusBarColor())
|
||||
|
||||
if triggered then
|
||||
frame.IconFrame:ClearAllPoints()
|
||||
frame.IconFrame:SetPoint("TOP", frame)
|
||||
end
|
||||
else
|
||||
frame.IconFrame:Hide()
|
||||
end
|
||||
else
|
||||
frame.IconFrame:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_IconOnlyGlow(frame)
|
||||
local glowStyle = self.db.units.TARGET.glowStyle
|
||||
|
||||
frame.Shadow:Hide()
|
||||
frame.Spark:Hide()
|
||||
|
||||
frame.TopIndicator:ClearAllPoints()
|
||||
frame.LeftIndicator:ClearAllPoints()
|
||||
frame.RightIndicator:ClearAllPoints()
|
||||
|
||||
if glowStyle == "style3" or glowStyle == "style5" or glowStyle == "style6" then
|
||||
frame.TopIndicator:SetPoint("BOTTOM", frame.IconFrame, "TOP", -1, 6)
|
||||
elseif glowStyle == "style4" or glowStyle == "style7" or glowStyle == "style8" then
|
||||
frame.LeftIndicator:SetPoint("LEFT", frame.IconFrame, "RIGHT", -3, 0)
|
||||
frame.RightIndicator:SetPoint("RIGHT", frame.IconFrame, "LEFT", 3, 0)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_IconFrame(frame)
|
||||
local db = self.db.units[frame.UnitType].iconFrame
|
||||
|
||||
if db then
|
||||
if db.enable or frame.IconChanged then
|
||||
frame.IconFrame:SetSize(db.size, db.size)
|
||||
frame.IconFrame:ClearAllPoints()
|
||||
frame.IconFrame:SetPoint(E.InversePoints[db.position], db.parent == "Nameplate" and frame or frame[db.parent], db.position, db.xOffset, db.yOffset)
|
||||
else
|
||||
frame.IconFrame:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_IconFrame(frame)
|
||||
local iconFrame = CreateFrame("Frame", nil, frame)
|
||||
iconFrame:Hide()
|
||||
|
||||
iconFrame:SetSize(24, 24)
|
||||
iconFrame:SetPoint("CENTER")
|
||||
NP:StyleFrame(iconFrame, true)
|
||||
|
||||
iconFrame.texture = iconFrame:CreateTexture()
|
||||
iconFrame.texture:SetAllPoints()
|
||||
iconFrame.texture:SetTexCoord(unpack(E.TexCoords))
|
||||
|
||||
return iconFrame
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
--WoW API / Variables
|
||||
|
||||
function NP:Update_Level(frame)
|
||||
if not self.db.units[frame.UnitType].level.enable then return end
|
||||
|
||||
local levelText, r, g, b = self:UnitLevel(frame)
|
||||
|
||||
local level = frame.Level
|
||||
level:ClearAllPoints()
|
||||
|
||||
if self.db.units[frame.UnitType].health.enable or (frame.isTarget and self.db.alwaysShowTargetHealth) then
|
||||
level:SetJustifyH("RIGHT")
|
||||
level:SetPoint("BOTTOMRIGHT", frame.Health, "TOPRIGHT", 0, E.Border*2)
|
||||
else
|
||||
level:SetPoint("LEFT", frame.Name, "RIGHT")
|
||||
level:SetJustifyH("LEFT")
|
||||
end
|
||||
|
||||
if self.db.units[frame.UnitType].health.enable or frame.isTarget then
|
||||
level:SetText(levelText)
|
||||
else
|
||||
level:SetFormattedText(" [%s]", levelText)
|
||||
end
|
||||
level:SetTextColor(r, g, b)
|
||||
end
|
||||
|
||||
function NP:Configure_Level(frame)
|
||||
local db = self.db.units[frame.UnitType].level
|
||||
frame.Level:FontTemplate(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline)
|
||||
end
|
||||
|
||||
function NP:Construct_Level(frame)
|
||||
return frame:CreateFontString(nil, "OVERLAY")
|
||||
end
|
||||
@@ -0,0 +1,124 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
local format = string.format
|
||||
local gmatch = gmatch
|
||||
local gsub = gsub
|
||||
local match = string.match
|
||||
local utf8lower = string.utf8lower
|
||||
local utf8sub = string.utf8sub
|
||||
--WoW API / Variables
|
||||
local UNKNOWN = UNKNOWN
|
||||
|
||||
local function abbrev(name)
|
||||
local letters, lastWord = "", match(name, ".+%s(.+)$")
|
||||
if lastWord then
|
||||
for word in gmatch(name, ".-%s") do
|
||||
local firstLetter = utf8sub(gsub(word, "^[%s%p]*", ""), 1, 1)
|
||||
if firstLetter ~= utf8lower(firstLetter) then
|
||||
letters = format("%s%s. ", letters, firstLetter)
|
||||
end
|
||||
end
|
||||
name = format("%s%s", letters, lastWord)
|
||||
end
|
||||
return name
|
||||
end
|
||||
|
||||
function NP:Update_Name(frame, triggered)
|
||||
if not triggered then
|
||||
if not self.db.units[frame.UnitType].name.enable then return end
|
||||
end
|
||||
|
||||
local name = frame.Name
|
||||
local nameText = frame.UnitName or UNKNOWN
|
||||
name:SetText(self.db.units[frame.UnitType].name.abbrev and abbrev(nameText) or nameText)
|
||||
|
||||
if not triggered then
|
||||
name:ClearAllPoints()
|
||||
if self.db.units[frame.UnitType].health.enable or (self.db.alwaysShowTargetHealth and frame.isTarget) then
|
||||
name:SetJustifyH("LEFT")
|
||||
name:SetPoint("BOTTOMLEFT", frame.Health, "TOPLEFT", 0, E.Border*2)
|
||||
name:SetPoint("BOTTOMRIGHT", frame.Level, "BOTTOMLEFT")
|
||||
else
|
||||
name:SetJustifyH("CENTER")
|
||||
name:SetPoint("TOP", frame)
|
||||
end
|
||||
end
|
||||
|
||||
local r, g, b = 1, 1, 1
|
||||
local class = frame.UnitClass
|
||||
|
||||
local classColor, useClassColor
|
||||
if class then
|
||||
classColor = E.media.herocolor
|
||||
useClassColor = self.db.units[frame.UnitType].name and self.db.units[frame.UnitType].name.useClassColor
|
||||
end
|
||||
|
||||
if useClassColor and (frame.UnitType == "FRIENDLY_PLAYER" or frame.UnitType == "ENEMY_PLAYER") then
|
||||
r, g, b = classColor.r, classColor.g, classColor.b
|
||||
elseif triggered or (not self.db.units[frame.UnitType].health.enable and not frame.isTarget) then
|
||||
local reactionType = frame.UnitReaction
|
||||
if reactionType then
|
||||
local db = self.db.colors
|
||||
if reactionType == 4 then
|
||||
r, g, b = db.reactions.neutral.r, db.reactions.neutral.g, db.reactions.neutral.b
|
||||
elseif reactionType > 4 then
|
||||
if frame.UnitType == "FRIENDLY_PLAYER" then
|
||||
r, g, b = db.reactions.friendlyPlayer.r, db.reactions.friendlyPlayer.g, db.reactions.friendlyPlayer.b
|
||||
else
|
||||
r, g, b = db.reactions.good.r, db.reactions.good.g, db.reactions.good.b
|
||||
end
|
||||
else
|
||||
r, g, b = db.reactions.bad.r, db.reactions.bad.g, db.reactions.bad.b
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- if for some reason the values failed just default to white
|
||||
if not (r and g and b) then
|
||||
r, g, b = 1, 1, 1
|
||||
end
|
||||
|
||||
if triggered or (r ~= frame.Name.r or g ~= frame.Name.g or b ~= frame.Name.b) then
|
||||
name:SetTextColor(r, g, b)
|
||||
if not triggered then
|
||||
frame.Name.r, frame.Name.g, frame.Name.b = r, g, b
|
||||
end
|
||||
end
|
||||
|
||||
if self.db.nameColoredGlow then
|
||||
name.NameOnlyGlow:SetVertexColor(r - 0.1, g - 0.1, b - 0.1, 1)
|
||||
else
|
||||
name.NameOnlyGlow:SetVertexColor(self.db.colors.glowColor.r, self.db.colors.glowColor.g, self.db.colors.glowColor.b, self.db.colors.glowColor.a)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Configure_Name(frame)
|
||||
local db = self.db.units[frame.UnitType].name
|
||||
frame.Name:FontTemplate(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline)
|
||||
end
|
||||
|
||||
function NP:Configure_NameOnlyGlow(frame)
|
||||
local name = frame.Name
|
||||
name.NameOnlyGlow:ClearAllPoints()
|
||||
name.NameOnlyGlow:SetPoint("TOPLEFT", frame.IconOnlyChanged and frame.IconFrame or name, -20, 8)
|
||||
name.NameOnlyGlow:SetPoint("BOTTOMRIGHT", frame.IconOnlyChanged and frame.IconFrame or name, 20, -8)
|
||||
end
|
||||
|
||||
function NP:Construct_Name(frame)
|
||||
local name = frame:CreateFontString(nil, "OVERLAY")
|
||||
name:SetJustifyV("BOTTOM")
|
||||
name:SetWordWrap(false)
|
||||
|
||||
local g = frame:CreateTexture(nil, "BACKGROUND")
|
||||
g:SetTexture(E.Media.Textures.Spark)
|
||||
g:Hide()
|
||||
g:SetPoint("TOPLEFT", name, -20, 8)
|
||||
g:SetPoint("BOTTOMRIGHT", name, 20, -8)
|
||||
|
||||
name.NameOnlyGlow = g
|
||||
|
||||
return name
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule("NamePlates")
|
||||
|
||||
--Lua functions
|
||||
--WoW API / Variables
|
||||
|
||||
function NP:Update_RaidIcon(frame)
|
||||
local db = self.db.units[frame.UnitType].raidTargetIndicator
|
||||
local icon = frame.RaidIcon
|
||||
|
||||
icon:SetSize(db.size, db.size)
|
||||
|
||||
icon:ClearAllPoints()
|
||||
if frame.Health:IsShown() then
|
||||
icon:SetPoint(E.InversePoints[db.position], frame.Health, db.position, db.xOffset, db.yOffset)
|
||||
else
|
||||
icon:SetPoint("BOTTOM", frame, "TOP", 0, 15)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="Nameplates.lua"/>
|
||||
<Script file="StyleFilter.lua"/>
|
||||
<Script file="Elements\Auras.lua"/>
|
||||
<Script file="Elements\CastBar.lua"/>
|
||||
<Script file="Elements\ComboPoints.lua"/>
|
||||
<Script file="Elements\Glow.lua"/>
|
||||
<Script file="Elements\HealthBar.lua"/>
|
||||
<Script file="Elements\CutawayHealth.lua"/>
|
||||
<Script file="Elements\Level.lua"/>
|
||||
<Script file="Elements\Name.lua"/>
|
||||
<Script file="Elements\RaidIcon.lua"/>
|
||||
<Script file="Elements\HealerIcon.lua"/>
|
||||
<Script file="Elements\Elite.lua"/>
|
||||
<Script file="Elements\Highlight.lua"/>
|
||||
<Script file="Elements\IconFrame.lua"/>
|
||||
</Ui>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,883 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local mod = E:GetModule("NamePlates")
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
local ipairs, next, pairs, rawget, rawset, select, setmetatable, tonumber, type, unpack, tostring = ipairs, next, pairs, rawget, rawset, select, setmetatable, tonumber, type, unpack, tostring
|
||||
local tinsert, sort, twipe = table.insert, table.sort, table.wipe
|
||||
local match = string.match
|
||||
--WoW API / Variables
|
||||
local GetInstanceInfo = GetInstanceInfo
|
||||
local GetSpellCooldown = GetSpellCooldown
|
||||
local GetSpellInfo = GetSpellInfo
|
||||
local GetTime = GetTime
|
||||
local UnitAffectingCombat = UnitAffectingCombat
|
||||
local UnitHealth = UnitHealth
|
||||
local UnitHealthMax = UnitHealthMax
|
||||
local UnitPower = UnitPower
|
||||
local UnitPowerMax = UnitPowerMax
|
||||
|
||||
mod.TriggerConditions = {
|
||||
raidTargets = {
|
||||
STAR = "star",
|
||||
CIRCLE = "circle",
|
||||
DIAMOND = "diamond",
|
||||
TRIANGLE = "triangle",
|
||||
MOON = "moon",
|
||||
SQUARE = "square",
|
||||
CROSS = "cross",
|
||||
SKULL = "skull",
|
||||
},
|
||||
frameTypes = {
|
||||
["FRIENDLY_PLAYER"] = "friendlyPlayer",
|
||||
["FRIENDLY_NPC"] = "friendlyNPC",
|
||||
["ENEMY_PLAYER"] = "enemyPlayer",
|
||||
["ENEMY_NPC"] = "enemyNPC",
|
||||
},
|
||||
roles = {
|
||||
["TANK"] = "tank",
|
||||
["HEALER"] = "healer",
|
||||
["DAMAGER"] = "damager"
|
||||
},
|
||||
difficulties = {
|
||||
-- dungeons
|
||||
[1] = "normal",
|
||||
[2] = "heroic",
|
||||
-- raids
|
||||
[14] = "normal",
|
||||
[15] = "heroic",
|
||||
},
|
||||
totems = {},
|
||||
uniqueUnits = {}
|
||||
}
|
||||
|
||||
local totemTypes = {
|
||||
air = { -- Air Totems
|
||||
[8177] = "a1", -- Grounding Totem
|
||||
[10595] = "a2", -- Nature Resistance Totem I
|
||||
[10600] = "a2", -- Nature Resistance Totem II
|
||||
[10601] = "a2", -- Nature Resistance Totem III
|
||||
[25574] = "a2", -- Nature Resistance Totem IV
|
||||
[58746] = "a2", -- Nature Resistance Totem V
|
||||
[58749] = "a2", -- Nature Resistance Totem VI
|
||||
[6495] = "a3", -- Sentry Totem
|
||||
[8512] = "a4", -- Windfury Totem
|
||||
[3738] = "a5", -- Wrath of Air Totem
|
||||
},
|
||||
earth = { -- Earth Totems
|
||||
[2062] = "e1", -- Earth Elemental Totem
|
||||
[2484] = "e2", -- Earthbind Totem
|
||||
[5730] = "e3", -- Stoneclaw Totem I
|
||||
[6390] = "e3", -- Stoneclaw Totem II
|
||||
[6391] = "e3", -- Stoneclaw Totem III
|
||||
[6392] = "e3", -- Stoneclaw Totem IV
|
||||
[10427] = "e3", -- Stoneclaw Totem V
|
||||
[10428] = "e3", -- Stoneclaw Totem VI
|
||||
[25525] = "e3", -- Stoneclaw Totem VII
|
||||
[58580] = "e3", -- Stoneclaw Totem VIII
|
||||
[58581] = "e3", -- Stoneclaw Totem IX
|
||||
[58582] = "e3", -- Stoneclaw Totem X
|
||||
[8071] = "e4", -- Stoneskin Totem I -- Faction Champs
|
||||
[8154] = "e4", -- Stoneskin Totem II
|
||||
[8155] = "e4", -- Stoneskin Totem III
|
||||
[10406] = "e4", -- Stoneskin Totem IV
|
||||
[10407] = "e4", -- Stoneskin Totem V
|
||||
[10408] = "e4", -- Stoneskin Totem VI
|
||||
[25508] = "e4", -- Stoneskin Totem VII
|
||||
[25509] = "e4", -- Stoneskin Totem VIII
|
||||
[58751] = "e4", -- Stoneskin Totem IX
|
||||
[58753] = "e4", -- Stoneskin Totem X
|
||||
[8075] = "e5", -- Strength of Earth Totem I -- Faction Champs
|
||||
[8160] = "e5", -- Strength of Earth Totem II
|
||||
[8161] = "e5", -- Strength of Earth Totem III
|
||||
[10442] = "e5", -- Strength of Earth Totem IV
|
||||
[25361] = "e5", -- Strength of Earth Totem V
|
||||
[25528] = "e5", -- Strength of Earth Totem VI
|
||||
[57622] = "e5", -- Strength of Earth Totem VII
|
||||
[58643] = "e5", -- Strength of Earth Totem VIII
|
||||
[8143] = "e6", -- Tremor Totem
|
||||
},
|
||||
fire = { -- Fire Totems
|
||||
[2894] = "f1", -- Fire Elemental Totem
|
||||
[8227] = "f2", -- Flametongue Totem I -- Faction Champs
|
||||
[8249] = "f2", -- Flametongue Totem II
|
||||
[10526] = "f2", -- Flametongue Totem III
|
||||
[16387] = "f2", -- Flametongue Totem IV
|
||||
[25557] = "f2", -- Flametongue Totem V
|
||||
[58649] = "f2", -- Flametongue Totem VI
|
||||
[58652] = "f2", -- Flametongue Totem VII
|
||||
[58656] = "f2", -- Flametongue Totem VIII
|
||||
[8181] = "f3", -- Frost Resistance Totem I
|
||||
[10478] = "f3", -- Frost Resistance Totem II
|
||||
[10479] = "f3", -- Frost Resistance Totem III
|
||||
[25560] = "f3", -- Frost Resistance Totem IV
|
||||
[58741] = "f3", -- Frost Resistance Totem V
|
||||
[58745] = "f3", -- Frost Resistance Totem VI
|
||||
[8190] = "f4", -- Magma Totem I
|
||||
[10585] = "f4", -- Magma Totem II
|
||||
[10586] = "f4", -- Magma Totem III
|
||||
[10587] = "f4", -- Magma Totem IV
|
||||
[25552] = "f4", -- Magma Totem V
|
||||
[58731] = "f4", -- Magma Totem VI
|
||||
[58734] = "f4", -- Magma Totem VII
|
||||
[3599] = "f5", -- Searing Totem I -- Faction Champs
|
||||
[6363] = "f5", -- Searing Totem II
|
||||
[6364] = "f5", -- Searing Totem III
|
||||
[6365] = "f5", -- Searing Totem IV
|
||||
[10437] = "f5", -- Searing Totem V
|
||||
[10438] = "f5", -- Searing Totem VI
|
||||
[25533] = "f5", -- Searing Totem VII
|
||||
[58699] = "f5", -- Searing Totem VIII
|
||||
[58703] = "f5", -- Searing Totem IX
|
||||
[58704] = "f5", -- Searing Totem X
|
||||
[30706] = "f6", -- Totem of Wrath I
|
||||
[57720] = "f6", -- Totem of Wrath II
|
||||
[57721] = "f6", -- Totem of Wrath III
|
||||
[57722] = "f6", -- Totem of Wrath IV
|
||||
},
|
||||
water = { -- Water Totems
|
||||
[8170] = "w1", -- Cleansing Totem
|
||||
[8184] = "w2", -- Fire Resistance Totem I
|
||||
[10537] = "w2", -- Fire Resistance Totem II
|
||||
[10538] = "w2", -- Fire Resistance Totem III
|
||||
[25563] = "w2", -- Fire Resistance Totem IV
|
||||
[58737] = "w2", -- Fire Resistance Totem V
|
||||
[58739] = "w2", -- Fire Resistance Totem VI
|
||||
[5394] = "w3", -- Healing Stream Totem I -- Faction Champs
|
||||
[6375] = "w3", -- Healing Stream Totem II
|
||||
[6377] = "w3", -- Healing Stream Totem III
|
||||
[10462] = "w3", -- Healing Stream Totem IV
|
||||
[10463] = "w3", -- Healing Stream Totem V
|
||||
[25567] = "w3", -- Healing Stream Totem VI
|
||||
[58755] = "w3", -- Healing Stream Totem VII
|
||||
[58756] = "w3", -- Healing Stream Totem VIII
|
||||
[58757] = "w3", -- Healing Stream Totem IX
|
||||
[5675] = "w4", -- Mana Spring Totem I
|
||||
[10495] = "w4", -- Mana Spring Totem II
|
||||
[10496] = "w4", -- Mana Spring Totem III
|
||||
[10497] = "w4", -- Mana Spring Totem IV
|
||||
[25570] = "w4", -- Mana Spring Totem V
|
||||
[58771] = "w4", -- Mana Spring Totem VI
|
||||
[58773] = "w4", -- Mana Spring Totem VII
|
||||
[58774] = "w4", -- Mana Spring Totem VIII
|
||||
[16190] = "w5" -- Mana Tide Totem
|
||||
},
|
||||
other = {
|
||||
[724] = "o1" -- Lightwell
|
||||
}
|
||||
}
|
||||
|
||||
local totemRanks = {
|
||||
"",
|
||||
" II",
|
||||
" III",
|
||||
" IV",
|
||||
" V",
|
||||
" VI",
|
||||
" VII",
|
||||
" VIII",
|
||||
" IX",
|
||||
" X"
|
||||
}
|
||||
|
||||
local uniqueUnitTypes = {
|
||||
pvp = {
|
||||
[34433] = "u1", -- Shadow Fiend
|
||||
},
|
||||
pve = {
|
||||
[72052] = "u2", -- Kinetic Bomb
|
||||
}
|
||||
}
|
||||
|
||||
G.nameplates.uniqueUnitTypes = uniqueUnitTypes
|
||||
|
||||
for unitType, units in pairs(uniqueUnitTypes) do
|
||||
for spellID, unit in pairs(units) do
|
||||
local name, _, texture = GetSpellInfo(spellID)
|
||||
mod.TriggerConditions.uniqueUnits[unit] = {name, unitType, texture}
|
||||
mod.UniqueUnits[name] = unit
|
||||
end
|
||||
end
|
||||
|
||||
for totemSchool, totems in pairs(totemTypes) do
|
||||
for spellID, totemID in pairs(totems) do
|
||||
local totemName, rank, texture = GetSpellInfo(spellID)
|
||||
|
||||
if not mod.TriggerConditions.totems[totemID] then
|
||||
mod.TriggerConditions.totems[totemID] = {totemName, totemSchool, texture}
|
||||
end
|
||||
|
||||
rank = totemRanks[tonumber(match(rank, ("%d+")))]
|
||||
|
||||
if rank then
|
||||
totemName = totemName..rank
|
||||
else
|
||||
totemName = totemName
|
||||
end
|
||||
|
||||
mod.Totems[totemName] = totemID
|
||||
end
|
||||
end
|
||||
|
||||
G.nameplates.totemTypes = totemTypes
|
||||
|
||||
function mod:StyleFilterAuraCheck(names, icons, mustHaveAll, missing, minTimeLeft, maxTimeLeft)
|
||||
local total, count = 0, 0
|
||||
for name, value in pairs(names) do
|
||||
if value == true then --only if they are turned on
|
||||
total = total + 1 --keep track of the names
|
||||
end
|
||||
for _, icon in ipairs(icons) do
|
||||
if icon:IsShown() and (value == true) and ((icon.name and icon.name == name) or (icon.spellID and icon.spellID == tonumber(name)))
|
||||
and (not minTimeLeft or (minTimeLeft == 0 or (icon.expirationTime and (icon.expirationTime - GetTime()) > minTimeLeft))) and (not maxTimeLeft or (maxTimeLeft == 0 or (icon.expirationTime and (icon.expirationTime - GetTime()) < maxTimeLeft))) then
|
||||
count = count + 1 --keep track of how many matches we have
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if total == 0 then
|
||||
return nil --If no auras are checked just pass nil, we dont need to run the filter here.
|
||||
else
|
||||
return ((mustHaveAll and not missing) and total == count) -- [x] Check for all [ ] Missing: total needs to match count
|
||||
or ((not mustHaveAll and not missing) and count > 0) -- [ ] Check for all [ ] Missing: count needs to be greater than zero
|
||||
or ((not mustHaveAll and missing) and count == 0) -- [ ] Check for all [x] Missing: count needs to be zero
|
||||
or ((mustHaveAll and missing) and total ~= count) -- [x] Check for all [x] Missing: count must not match total
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterCooldownCheck(names, mustHaveAll)
|
||||
local total, count = 0, 0
|
||||
local _, gcd = GetSpellCooldown(61304)
|
||||
|
||||
for name, value in pairs(names) do
|
||||
if value == "ONCD" or value == "OFFCD" then --only if they are turned on
|
||||
total = total + 1 --keep track of the names
|
||||
|
||||
local _, duration = GetSpellCooldown(name)
|
||||
if (duration > gcd and value == "ONCD")
|
||||
or (duration <= gcd and value == "OFFCD") then
|
||||
count = count + 1
|
||||
--print(((duration > gcd and value == "ONCD") and name.."passes because it is on cd.") or ((duration <= gcd and value == "OFFCD") and name.." passes because it is off cd."))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if total == 0 then
|
||||
return nil
|
||||
else
|
||||
return (mustHaveAll and total == count) or (not mustHaveAll and count > 0)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterSetChanges(frame, actions, HealthColorChanged, BorderChanged, FlashingHealth, TextureChanged, ScaleChanged, FrameLevelChanged, AlphaChanged, NameColorChanged, NameOnlyChanged, VisibilityChanged, IconChanged, IconOnlyChanged)
|
||||
if VisibilityChanged then
|
||||
frame.StyleChanged = true
|
||||
frame.VisibilityChanged = true
|
||||
frame:Hide()
|
||||
return --We hide it. Lets not do other things (no point)
|
||||
end
|
||||
if FrameLevelChanged then
|
||||
frame.StyleChanged = true
|
||||
frame.FrameLevelChanged = actions.frameLevel -- we pass this to `ResetNameplateFrameLevel`
|
||||
end
|
||||
if HealthColorChanged then
|
||||
frame.StyleChanged = true
|
||||
frame.HealthColorChanged = true
|
||||
frame.Health:SetStatusBarColor(actions.color.healthColor.r, actions.color.healthColor.g, actions.color.healthColor.b, actions.color.healthColor.a)
|
||||
frame.CutawayHealth:SetStatusBarColor(actions.color.healthColor.r * 1.5, actions.color.healthColor.g * 1.5, actions.color.healthColor.b * 1.5, actions.color.healthColor.a)
|
||||
end
|
||||
if BorderChanged then --Lets lock this to the values we want (needed for when the media border color changes)
|
||||
frame.StyleChanged = true
|
||||
frame.BorderChanged = true
|
||||
frame.Health.bordertop:SetTexture(actions.color.borderColor.r, actions.color.borderColor.g, actions.color.borderColor.b, actions.color.borderColor.a)
|
||||
frame.Health.borderbottom:SetTexture(actions.color.borderColor.r, actions.color.borderColor.g, actions.color.borderColor.b, actions.color.borderColor.a)
|
||||
frame.Health.borderleft:SetTexture(actions.color.borderColor.r, actions.color.borderColor.g, actions.color.borderColor.b, actions.color.borderColor.a)
|
||||
frame.Health.borderright:SetTexture(actions.color.borderColor.r, actions.color.borderColor.g, actions.color.borderColor.b, actions.color.borderColor.a)
|
||||
end
|
||||
if FlashingHealth then
|
||||
frame.StyleChanged = true
|
||||
frame.FlashingHealth = true
|
||||
if not TextureChanged then
|
||||
frame.FlashTexture:SetTexture(LSM:Fetch("statusbar", mod.db.statusbar))
|
||||
end
|
||||
frame.FlashTexture:SetVertexColor(actions.flash.color.r, actions.flash.color.g, actions.flash.color.b)
|
||||
frame.FlashTexture:SetAlpha(actions.flash.color.a)
|
||||
frame.FlashTexture:Show()
|
||||
E:Flash(frame.FlashTexture, actions.flash.speed * 0.1, true)
|
||||
end
|
||||
if TextureChanged then
|
||||
frame.StyleChanged = true
|
||||
frame.TextureChanged = true
|
||||
local tex = LSM:Fetch("statusbar", actions.texture.texture)
|
||||
frame.Health.Highlight:SetTexture(tex)
|
||||
frame.Health:SetStatusBarTexture(tex)
|
||||
if FlashingHealth then
|
||||
frame.FlashTexture:SetTexture(tex)
|
||||
end
|
||||
end
|
||||
if ScaleChanged then
|
||||
frame.StyleChanged = true
|
||||
frame.ScaleChanged = true
|
||||
local scale = (frame.ThreatScale or 1)
|
||||
frame.ActionScale = actions.scale
|
||||
if frame.isTarget and mod.db.useTargetScale then
|
||||
scale = scale * mod.db.targetScale
|
||||
end
|
||||
mod:SetFrameScale(frame, scale * actions.scale)
|
||||
end
|
||||
if AlphaChanged then
|
||||
frame.StyleChanged = true
|
||||
frame.AlphaChanged = true
|
||||
mod:PlateFade(frame, mod.db.fadeIn and 1 or 0, frame:GetAlpha(), actions.alpha / 100)
|
||||
end
|
||||
if NameColorChanged then
|
||||
frame.StyleChanged = true
|
||||
frame.NameColorChanged = true
|
||||
local nameText = frame.oldName:GetText()
|
||||
if nameText and nameText ~= "" then
|
||||
frame.Name:SetTextColor(actions.color.nameColor.r, actions.color.nameColor.g, actions.color.nameColor.b, actions.color.nameColor.a)
|
||||
if mod.db.nameColoredGlow then
|
||||
frame.Name.NameOnlyGlow:SetVertexColor(actions.color.nameColor.r - 0.1, actions.color.nameColor.g - 0.1, actions.color.nameColor.b - 0.1, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
if NameOnlyChanged then
|
||||
frame.StyleChanged = true
|
||||
frame.NameOnlyChanged = true
|
||||
--hide the bars
|
||||
if frame.CastBar:IsShown() then frame.CastBar:Hide() end
|
||||
if frame.Health:IsShown() then frame.Health:Hide() end
|
||||
--hide the target indicator
|
||||
mod:Configure_Glow(frame)
|
||||
mod:Update_Glow(frame)
|
||||
--position the name and update its color
|
||||
frame.Name:ClearAllPoints()
|
||||
frame.Name:SetJustifyH("CENTER")
|
||||
frame.Name:SetPoint("TOP", frame)
|
||||
frame.Level:ClearAllPoints()
|
||||
frame.Level:SetPoint("LEFT", frame.Name, "RIGHT")
|
||||
frame.Level:SetJustifyH("LEFT")
|
||||
if not NameColorChanged then
|
||||
mod:Update_Name(frame, true)
|
||||
end
|
||||
end
|
||||
if IconChanged then
|
||||
frame.StyleChanged = true
|
||||
frame.IconChanged = true
|
||||
mod:Configure_IconFrame(frame)
|
||||
mod:Update_IconFrame(frame)
|
||||
end
|
||||
if IconOnlyChanged then
|
||||
frame.StyleChanged = true
|
||||
frame.IconOnlyChanged = true
|
||||
mod:Update_IconFrame(frame, true)
|
||||
if frame.Health:IsShown() then frame.Health:Hide() end
|
||||
frame.Level:Hide()
|
||||
frame.Name:Hide()
|
||||
mod:Configure_Glow(frame)
|
||||
mod:Update_Glow(frame)
|
||||
mod:Update_RaidIcon(frame)
|
||||
mod:Configure_IconOnlyGlow(frame)
|
||||
mod:Configure_NameOnlyGlow(frame)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterClearChanges(frame, HealthColorChanged, BorderChanged, FlashingHealth, TextureChanged, ScaleChanged, FrameLevelChanged, AlphaChanged, NameColorChanged, NameOnlyChanged, VisibilityChanged, IconChanged, IconOnlyChanged)
|
||||
frame.StyleChanged = nil
|
||||
if VisibilityChanged then
|
||||
frame.VisibilityChanged = nil
|
||||
mod:PlateFade(frame, mod.db.fadeIn and 1 or 0, 0, 1) -- fade those back in so it looks clean
|
||||
frame:Show()
|
||||
end
|
||||
if FrameLevelChanged then
|
||||
frame.FrameLevelChanged = nil
|
||||
end
|
||||
if HealthColorChanged then
|
||||
frame.HealthColorChanged = nil
|
||||
frame.Health:SetStatusBarColor(frame.Health.r, frame.Health.g, frame.Health.b)
|
||||
frame.CutawayHealth:SetStatusBarColor(frame.Health.r * 1.5, frame.Health.g * 1.5, frame.Health.b * 1.5, 1)
|
||||
end
|
||||
if BorderChanged then
|
||||
frame.BorderChanged = nil
|
||||
local r, g, b = unpack(E.media.bordercolor)
|
||||
frame.Health.bordertop:SetTexture(r, g, b)
|
||||
frame.Health.borderbottom:SetTexture(r, g, b)
|
||||
frame.Health.borderleft:SetTexture(r, g, b)
|
||||
frame.Health.borderright:SetTexture(r, g, b)
|
||||
end
|
||||
if FlashingHealth then
|
||||
frame.FlashingHealth = nil
|
||||
E:StopFlash(frame.FlashTexture)
|
||||
frame.FlashTexture:Hide()
|
||||
end
|
||||
if TextureChanged then
|
||||
frame.TextureChanged = nil
|
||||
local tex = LSM:Fetch("statusbar", mod.db.statusbar)
|
||||
frame.Health.Highlight:SetTexture(tex)
|
||||
frame.Health:SetStatusBarTexture(tex)
|
||||
end
|
||||
if ScaleChanged then
|
||||
frame.ScaleChanged = nil
|
||||
frame.ActionScale = nil
|
||||
local scale = frame.ThreatScale or 1
|
||||
if frame.isTarget and mod.db.useTargetScale then
|
||||
scale = scale * mod.db.targetScale
|
||||
end
|
||||
mod:SetFrameScale(frame, scale)
|
||||
end
|
||||
if AlphaChanged then
|
||||
frame.AlphaChanged = nil
|
||||
mod:PlateFade(frame, mod.db.fadeIn and 1 or 0, (frame.FadeObject and frame.FadeObject.endAlpha) or 0.5, 1)
|
||||
end
|
||||
if NameColorChanged then
|
||||
frame.NameColorChanged = nil
|
||||
frame.Name:SetTextColor(frame.Name.r, frame.Name.g, frame.Name.b)
|
||||
end
|
||||
if NameOnlyChanged then
|
||||
frame.NameOnlyChanged = nil
|
||||
frame.TopLevelFrame = nil --We can safely clear this here because it is set upon `UpdateElement_Auras` if needed
|
||||
if mod.db.units[frame.UnitType].health.enable or (frame.isTarget and mod.db.alwaysShowTargetHealth) then
|
||||
frame.Health:Show()
|
||||
mod:Configure_Glow(frame)
|
||||
mod:Update_Glow(frame)
|
||||
end
|
||||
if mod.db.units[frame.UnitType].name.enable then
|
||||
frame.Level:Show()
|
||||
frame.Name:ClearAllPoints()
|
||||
frame.Level:ClearAllPoints()
|
||||
mod:Update_Level(frame)
|
||||
mod:Update_Name(frame)
|
||||
else
|
||||
frame.Name:SetText()
|
||||
end
|
||||
end
|
||||
if IconChanged then
|
||||
frame.IconChanged = nil
|
||||
frame.IconFrame:Hide()
|
||||
end
|
||||
if IconOnlyChanged then
|
||||
frame.IconOnlyChanged = nil
|
||||
mod:Update_IconFrame(frame)
|
||||
if mod.db.units[frame.UnitType].iconFrame and mod.db.units[frame.UnitType].iconFrame.enable then
|
||||
mod:Configure_IconFrame(frame)
|
||||
end
|
||||
if mod.db.units[frame.UnitType].health.enable or (frame.isTarget and mod.db.alwaysShowTargetHealth) then
|
||||
frame.Health:Show()
|
||||
mod:Configure_Glow(frame)
|
||||
mod:Update_Glow(frame)
|
||||
end
|
||||
if mod.db.units[frame.UnitType].name.enable then
|
||||
frame.Name:Show()
|
||||
frame.Level:Show()
|
||||
frame.Name:ClearAllPoints()
|
||||
frame.Level:ClearAllPoints()
|
||||
mod:Update_Level(frame)
|
||||
mod:Update_Name(frame)
|
||||
else
|
||||
frame.Name:SetText()
|
||||
end
|
||||
mod:Update_RaidIcon(frame)
|
||||
mod:Configure_IconOnlyGlow(frame)
|
||||
mod:Configure_NameOnlyGlow(frame)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterConditionCheck(frame, filter, trigger)
|
||||
local passed -- skip StyleFilterPass when triggers are empty
|
||||
|
||||
-- Name
|
||||
if trigger.names and next(trigger.names) then
|
||||
for _, value in pairs(trigger.names) do
|
||||
if value then -- only run if at least one is selected
|
||||
local name = trigger.names[frame.UnitName]
|
||||
if (not trigger.negativeMatch and name) or (trigger.negativeMatch and not name) then passed = true else return end
|
||||
break -- we can execute this once on the first enabled option then kill the loop
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Health
|
||||
if trigger.healthThreshold then
|
||||
local health = (trigger.healthUsePlayer and UnitHealth("player")) or frame.oldHealthBar:GetValue() or 0
|
||||
local maxHealth = (trigger.healthUsePlayer and UnitHealthMax("player")) or select(2, frame.oldHealthBar:GetMinMaxValues()) or 0
|
||||
local percHealth = (maxHealth and (maxHealth > 0) and health/maxHealth) or 0
|
||||
local underHealthThreshold = trigger.underHealthThreshold and (trigger.underHealthThreshold ~= 0) and (trigger.underHealthThreshold > percHealth)
|
||||
local overHealthThreshold = trigger.overHealthThreshold and (trigger.overHealthThreshold ~= 0) and (trigger.overHealthThreshold < percHealth)
|
||||
if underHealthThreshold or overHealthThreshold then passed = true else return end
|
||||
end
|
||||
|
||||
-- Power
|
||||
if trigger.powerThreshold then
|
||||
local power, maxPower = UnitPower("player"), UnitPowerMax("player")
|
||||
local percPower = (maxPower and (maxPower > 0) and power/maxPower) or 0
|
||||
local underPowerThreshold = trigger.underPowerThreshold and (trigger.underPowerThreshold ~= 0) and (trigger.underPowerThreshold > percPower)
|
||||
local overPowerThreshold = trigger.overPowerThreshold and (trigger.overPowerThreshold ~= 0) and (trigger.overPowerThreshold < percPower)
|
||||
if underPowerThreshold or overPowerThreshold then passed = true else return end
|
||||
end
|
||||
|
||||
-- Require Target
|
||||
if trigger.requireTarget then
|
||||
if UnitExists("target") then passed = true else return end
|
||||
end
|
||||
|
||||
-- Player Combat
|
||||
if trigger.inCombat or trigger.outOfCombat then
|
||||
local inCombat = UnitAffectingCombat("player")
|
||||
if (trigger.inCombat and inCombat) or (trigger.outOfCombat and not inCombat) then passed = true else return end
|
||||
end
|
||||
|
||||
-- Player Target
|
||||
if trigger.isTarget or trigger.notTarget then
|
||||
if (trigger.isTarget and frame.isTarget) or (trigger.notTarget and not frame.isTarget) then passed = true else return end
|
||||
end
|
||||
|
||||
-- Group Role
|
||||
if trigger.role.tank or trigger.role.healer or trigger.role.damager then
|
||||
if trigger.role[mod.TriggerConditions.roles[E:GetPlayerRole()]] then passed = true else return end
|
||||
end
|
||||
|
||||
-- Instance Type
|
||||
if trigger.instanceType.none or trigger.instanceType.party or trigger.instanceType.raid or trigger.instanceType.arena or trigger.instanceType.pvp then
|
||||
local _, instanceType, difficultyID = GetInstanceInfo()
|
||||
if trigger.instanceType[instanceType] then
|
||||
passed = true
|
||||
|
||||
-- Instance Difficulty
|
||||
if instanceType == "raid" or instanceType == "party" then
|
||||
local D = trigger.instanceDifficulty[(instanceType == "party" and "dungeon") or instanceType]
|
||||
for _, value in pairs(D) do
|
||||
if value and not D[mod.TriggerConditions.difficulties[difficultyID]] then return end
|
||||
end
|
||||
end
|
||||
else return end
|
||||
elseif trigger.instanceType.sanctuary then
|
||||
if UnitIsPVPSanctuary("player") then passed = true else return end
|
||||
end
|
||||
|
||||
-- Level
|
||||
if trigger.level then
|
||||
local myLevel = E.mylevel
|
||||
local level = mod:UnitLevel(frame)
|
||||
level = level == "??" and -1 or tonumber(level)
|
||||
local curLevel = (trigger.curlevel and trigger.curlevel ~= 0 and (trigger.curlevel == level))
|
||||
local minLevel = (trigger.minlevel and trigger.minlevel ~= 0 and (trigger.minlevel <= level))
|
||||
local maxLevel = (trigger.maxlevel and trigger.maxlevel ~= 0 and (trigger.maxlevel >= level))
|
||||
local matchMyLevel = trigger.mylevel and (level == myLevel)
|
||||
if curLevel or minLevel or maxLevel or matchMyLevel then passed = true else return end
|
||||
end
|
||||
|
||||
-- Unit Type
|
||||
if trigger.nameplateType and trigger.nameplateType.enable then
|
||||
if trigger.nameplateType[mod.TriggerConditions.frameTypes[frame.UnitType]] then passed = true else return end
|
||||
end
|
||||
|
||||
-- Reaction Type
|
||||
if trigger.reactionType and trigger.reactionType.enable then
|
||||
local reaction = frame.UnitReaction
|
||||
if ((reaction == 1 or reaction == 2 or reaction == 3) and trigger.reactionType.hostile) or (reaction == 4 and trigger.reactionType.neutral) or (reaction == 5 and trigger.reactionType.friendly) then passed = true else return end
|
||||
end
|
||||
|
||||
-- Raid Target
|
||||
if trigger.raidTarget.star or trigger.raidTarget.circle or trigger.raidTarget.diamond or trigger.raidTarget.triangle or trigger.raidTarget.moon or trigger.raidTarget.square or trigger.raidTarget.cross or trigger.raidTarget.skull then
|
||||
if trigger.raidTarget[mod.TriggerConditions.raidTargets[frame.RaidIconType]] then passed = true else return end
|
||||
end
|
||||
|
||||
-- Casting
|
||||
if trigger.casting then
|
||||
local b, c = frame.CastBar, trigger.casting
|
||||
|
||||
-- Spell
|
||||
if b.spellName then
|
||||
if c.spells and next(c.spells) then
|
||||
for _, value in pairs(c.spells) do
|
||||
if value then -- only run if at least one is selected
|
||||
local _, _, _, _, _, _, spellID = GetSpellInfo(b.spellName)
|
||||
local castingSpell = (spellID and c.spells[tostring(spellID)]) or c.spells[b.spellName]
|
||||
if (c.notSpell and not castingSpell) or (castingSpell and not c.notSpell) then passed = true else return end
|
||||
break -- we can execute this once on the first enabled option then kill the loop
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Status
|
||||
if c.isCasting or c.isChanneling or c.notCasting or c.notChanneling then
|
||||
if (c.isCasting and b.casting) or (c.isChanneling and b.channeling)
|
||||
or (c.notCasting and not b.casting) or (c.notChanneling and not b.channeling) then passed = true else return end
|
||||
end
|
||||
|
||||
-- Interruptible
|
||||
if c.interruptible or c.notInterruptible then
|
||||
if (b.casting or b.channeling) and ((c.interruptible and not b.notInterruptible)
|
||||
or (c.notInterruptible and b.notInterruptible)) then passed = true else return end
|
||||
end
|
||||
end
|
||||
|
||||
-- Cooldown
|
||||
if trigger.cooldowns and trigger.cooldowns.names and next(trigger.cooldowns.names) then
|
||||
local cooldown = mod:StyleFilterCooldownCheck(trigger.cooldowns.names, trigger.cooldowns.mustHaveAll)
|
||||
if cooldown ~= nil then -- ignore if none are set to ONCD or OFFCD
|
||||
if cooldown then passed = true else return end
|
||||
end
|
||||
end
|
||||
|
||||
-- Buffs
|
||||
if frame.Buffs and trigger.buffs and trigger.buffs.names and next(trigger.buffs.names) then
|
||||
local buff = mod:StyleFilterAuraCheck(trigger.buffs.names, frame.Buffs, trigger.buffs.mustHaveAll, trigger.buffs.missing, trigger.buffs.minTimeLeft, trigger.buffs.maxTimeLeft)
|
||||
if buff ~= nil then -- ignore if none are selected
|
||||
if buff then passed = true else return end
|
||||
end
|
||||
end
|
||||
|
||||
-- Debuffs
|
||||
if frame.Debuffs and trigger.debuffs and trigger.debuffs.names and next(trigger.debuffs.names) then
|
||||
local debuff = mod:StyleFilterAuraCheck(trigger.debuffs.names, frame.Debuffs, trigger.debuffs.mustHaveAll, trigger.debuffs.missing, trigger.debuffs.minTimeLeft, trigger.debuffs.maxTimeLeft)
|
||||
if debuff ~= nil then -- ignore if none are selected
|
||||
if debuff then passed = true else return end
|
||||
end
|
||||
end
|
||||
|
||||
-- Totems
|
||||
if frame.UnitName and trigger.totems.enable then
|
||||
local totem = mod.Totems[frame.UnitName]
|
||||
if totem then if trigger.totems[totem] then passed = true else return end end
|
||||
end
|
||||
|
||||
-- Unique Units
|
||||
if frame.UnitName and trigger.uniqueUnits.enable then
|
||||
local unit = mod.UniqueUnits[frame.UnitName]
|
||||
if unit then if trigger.uniqueUnits[unit] then passed = true else return end end
|
||||
end
|
||||
|
||||
-- Plugin Callback
|
||||
if mod.StyleFilterCustomChecks then
|
||||
for _, customCheck in pairs(mod.StyleFilterCustomChecks) do
|
||||
local custom = customCheck(frame, filter, trigger)
|
||||
if custom ~= nil then -- ignore if nil return
|
||||
if custom then passed = true else return end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Pass it along
|
||||
if passed then
|
||||
mod:StyleFilterPass(frame, filter.actions)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterPass(frame, actions)
|
||||
local healthBarEnabled = (frame.UnitType and mod.db.units[frame.UnitType].health.enable) or (frame.isTarget and mod.db.alwaysShowTargetHealth)
|
||||
local healthBarShown = healthBarEnabled and frame.Health:IsShown()
|
||||
|
||||
mod:StyleFilterSetChanges(frame, actions,
|
||||
(healthBarShown and actions.color and actions.color.health), --HealthColorChanged
|
||||
(healthBarShown and actions.color and actions.color.border and frame.Health.backdrop), --BorderChanged
|
||||
(healthBarShown and actions.flash and actions.flash.enable and frame.FlashTexture), --FlashingHealth
|
||||
(healthBarShown and actions.texture and actions.texture.enable), --TextureChanged
|
||||
(healthBarShown and actions.scale and actions.scale ~= 1), --ScaleChanged
|
||||
(actions.frameLevel and actions.frameLevel ~= 0), --FrameLevelChanged
|
||||
(actions.alpha and actions.alpha ~= -1), --AlphaChanged
|
||||
(actions.color and actions.color.name), --NameColorChanged
|
||||
(actions.nameOnly), --NameOnlyChanged
|
||||
(actions.hide), --VisibilityChanged
|
||||
(actions.icon), --IconChanged
|
||||
(actions.iconOnly) --IconOnlyChanged
|
||||
)
|
||||
end
|
||||
|
||||
function mod:StyleFilterClear(frame)
|
||||
if frame and frame.StyleChanged then
|
||||
mod:StyleFilterClearChanges(frame, frame.HealthColorChanged, frame.BorderChanged, frame.FlashingHealth, frame.TextureChanged, frame.ScaleChanged, frame.FrameLevelChanged, frame.AlphaChanged, frame.NameColorChanged, frame.NameOnlyChanged, frame.VisibilityChanged, frame.IconChanged, frame.IconOnlyChanged)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterSort(place)
|
||||
if self[2] and place[2] then
|
||||
return self[2] > place[2] --Sort by priority: 1=first, 2=second, 3=third, etc
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterClearVariables(nameplate)
|
||||
nameplate.ActionScale = nil
|
||||
nameplate.ThreatScale = nil
|
||||
end
|
||||
|
||||
mod.StyleFilterTriggerList = {}
|
||||
mod.StyleFilterTriggerEvents = {}
|
||||
function mod:StyleFilterConfigure()
|
||||
twipe(mod.StyleFilterTriggerList)
|
||||
twipe(mod.StyleFilterTriggerEvents)
|
||||
|
||||
for filterName, filter in pairs(E.global.nameplates.filters) do
|
||||
local t = filter.triggers
|
||||
if t and E.db.nameplates and E.db.nameplates.filters then
|
||||
if E.db.nameplates.filters[filterName] and E.db.nameplates.filters[filterName].triggers and E.db.nameplates.filters[filterName].triggers.enable then
|
||||
tinsert(mod.StyleFilterTriggerList, {filterName, t.priority or 1})
|
||||
|
||||
mod.StyleFilterTriggerEvents.UpdateElement_All = 1
|
||||
mod.StyleFilterTriggerEvents.NAME_PLATE_UNIT_ADDED = 1
|
||||
|
||||
if t.casting then
|
||||
if next(t.casting.spells) then
|
||||
for _, value in pairs(t.casting.spells) do
|
||||
if value then
|
||||
mod.StyleFilterTriggerEvents.FAKE_Casting = 0
|
||||
break
|
||||
end end end
|
||||
|
||||
if (t.casting.interruptible or t.casting.notInterruptible)
|
||||
or (t.casting.isCasting or t.casting.isChanneling or t.casting.notCasting or t.casting.notChanneling) then
|
||||
mod.StyleFilterTriggerEvents.FAKE_Casting = 0
|
||||
end
|
||||
end
|
||||
|
||||
if t.raidTarget and (t.raidTarget.star or t.raidTarget.circle or t.raidTarget.diamond or t.raidTarget.triangle or t.raidTarget.moon or t.raidTarget.square or t.raidTarget.cross or t.raidTarget.skull) then
|
||||
mod.StyleFilterTriggerEvents.RAID_TARGET_UPDATE = 1
|
||||
end
|
||||
|
||||
-- real events
|
||||
mod.StyleFilterTriggerEvents.PLAYER_TARGET_CHANGED = true
|
||||
|
||||
if t.healthThreshold then
|
||||
mod.StyleFilterTriggerEvents.UNIT_HEALTH = 1
|
||||
mod.StyleFilterTriggerEvents.UNIT_MAXHEALTH = 1
|
||||
end
|
||||
|
||||
if t.powerThreshold then
|
||||
mod.StyleFilterTriggerEvents.UNIT_MANA = 1
|
||||
mod.StyleFilterTriggerEvents.UNIT_ENERGY = 1
|
||||
mod.StyleFilterTriggerEvents.UNIT_FOCUS = 1
|
||||
mod.StyleFilterTriggerEvents.UNIT_RAGE = 1
|
||||
mod.StyleFilterTriggerEvents.UNIT_RUNIC_POWER = 1
|
||||
mod.StyleFilterTriggerEvents.UNIT_DISPLAYPOWER = 1
|
||||
end
|
||||
|
||||
if t.names and next(t.names) then
|
||||
for _, value in pairs(t.names) do
|
||||
if value then
|
||||
mod.StyleFilterTriggerEvents.UNIT_NAME_UPDATE = 1
|
||||
break
|
||||
end end end
|
||||
|
||||
if t.inCombat or t.outOfCombat then
|
||||
mod.StyleFilterTriggerEvents.PLAYER_REGEN_DISABLED = true
|
||||
mod.StyleFilterTriggerEvents.PLAYER_REGEN_ENABLED = true
|
||||
end
|
||||
|
||||
if t.cooldowns and t.cooldowns.names and next(t.cooldowns.names) then
|
||||
for _, value in pairs(t.cooldowns.names) do
|
||||
if value == "ONCD" or value == "OFFCD" then
|
||||
mod.StyleFilterTriggerEvents.SPELL_UPDATE_COOLDOWN = 1
|
||||
break
|
||||
end end end
|
||||
|
||||
if t.buffs and t.buffs.names and next(t.buffs.names) then
|
||||
for _, value in pairs(t.buffs.names) do
|
||||
if value then
|
||||
mod.StyleFilterTriggerEvents.UNIT_AURA = true
|
||||
break
|
||||
end end end
|
||||
|
||||
if t.debuffs and t.debuffs.names and next(t.debuffs.names) then
|
||||
for _, value in pairs(t.debuffs.names) do
|
||||
if value then
|
||||
mod.StyleFilterTriggerEvents.UNIT_AURA = true
|
||||
break
|
||||
end end end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if next(mod.StyleFilterTriggerList) then
|
||||
sort(mod.StyleFilterTriggerList, mod.StyleFilterSort) -- sort by priority
|
||||
else
|
||||
mod:ForEachPlate("StyleFilterClear")
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterUpdate(frame, event)
|
||||
local hasEvent = mod.StyleFilterTriggerEvents[event]
|
||||
if not hasEvent then
|
||||
return
|
||||
elseif hasEvent == true then -- skip on 1 or 0
|
||||
if not frame.StyleFilterWaitTime then
|
||||
frame.StyleFilterWaitTime = GetTime()
|
||||
elseif GetTime() > (frame.StyleFilterWaitTime + 0.1) then
|
||||
frame.StyleFilterWaitTime = nil
|
||||
else
|
||||
return -- block calls faster than 0.1 second
|
||||
end
|
||||
end
|
||||
|
||||
mod:StyleFilterClear(frame)
|
||||
|
||||
for filterNum in ipairs(mod.StyleFilterTriggerList) do
|
||||
local filter = E.global.nameplates.filters[mod.StyleFilterTriggerList[filterNum][1]]
|
||||
if filter then
|
||||
mod:StyleFilterConditionCheck(frame, filter, filter.triggers)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterAddCustomCheck(name, func)
|
||||
if not mod.StyleFilterCustomChecks then
|
||||
mod.StyleFilterCustomChecks = {}
|
||||
end
|
||||
|
||||
mod.StyleFilterCustomChecks[name] = func
|
||||
end
|
||||
|
||||
function mod:StyleFilterRemoveCustomCheck(name)
|
||||
if not mod.StyleFilterCustomChecks then
|
||||
return
|
||||
end
|
||||
|
||||
mod.StyleFilterCustomChecks[name] = nil
|
||||
end
|
||||
|
||||
-- Shamelessy taken from AceDB-3.0 and stripped down by Simpy
|
||||
local function copyDefaults(dest, src)
|
||||
for k, v in pairs(src) do
|
||||
if type(v) == "table" then
|
||||
if not rawget(dest, k) then rawset(dest, k, {}) end
|
||||
if type(dest[k]) == "table" then copyDefaults(dest[k], v) end
|
||||
elseif rawget(dest, k) == nil then
|
||||
rawset(dest, k, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function removeDefaults(db, defaults)
|
||||
setmetatable(db, nil)
|
||||
|
||||
for k, v in pairs(defaults) do
|
||||
if type(v) == "table" and type(db[k]) == "table" then
|
||||
removeDefaults(db[k], v)
|
||||
if next(db[k]) == nil then db[k] = nil end
|
||||
elseif db[k] == defaults[k] then
|
||||
db[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterClearDefaults()
|
||||
for filterName, filterTable in pairs(E.global.nameplates.filters) do
|
||||
if G.nameplates.filters[filterName] then
|
||||
local defaultTable = E:CopyTable({}, E.StyleFilterDefaults)
|
||||
E:CopyTable(defaultTable, G.nameplates.filters[filterName])
|
||||
removeDefaults(filterTable, defaultTable)
|
||||
else
|
||||
removeDefaults(filterTable, E.StyleFilterDefaults)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:StyleFilterCopyDefaults(tbl)
|
||||
copyDefaults(tbl, E.StyleFilterDefaults)
|
||||
end
|
||||
|
||||
function mod:StyleFilterInitialize()
|
||||
for _, filterTable in pairs(E.global.nameplates.filters) do
|
||||
mod:StyleFilterCopyDefaults(filterTable)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user