initial commit
This commit is contained in:
164
Modules/Nameplates/Elements/Auras.lua
Normal file
164
Modules/Nameplates/Elements/Auras.lua
Normal file
@@ -0,0 +1,164 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local UF = E:GetModule('UnitFrames')
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
local _G = _G
|
||||
local floor = floor
|
||||
local unpack = unpack
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
function NP:Construct_Auras(nameplate)
|
||||
local frameName = nameplate:GetName()
|
||||
|
||||
local Buffs = CreateFrame('Frame', frameName..'Buffs', nameplate)
|
||||
Buffs:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
Buffs:SetFrameLevel(5)
|
||||
Buffs:Size(300, 27)
|
||||
Buffs.disableMouse = true
|
||||
Buffs.size = 27
|
||||
Buffs.num = 4
|
||||
Buffs.spacing = E.Border * 2
|
||||
Buffs.onlyShowPlayer = false
|
||||
Buffs.initialAnchor = 'BOTTOMLEFT'
|
||||
Buffs['growth-x'] = 'RIGHT'
|
||||
Buffs['growth-y'] = 'UP'
|
||||
Buffs.type = 'buffs'
|
||||
Buffs.forceShow = nameplate == _G.ElvNP_Test
|
||||
|
||||
local Debuffs = CreateFrame('Frame', frameName..'Debuffs', nameplate)
|
||||
Debuffs:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
Debuffs:SetFrameLevel(5)
|
||||
Debuffs:Size(300, 27)
|
||||
Debuffs.disableMouse = true
|
||||
Debuffs.size = 27
|
||||
Debuffs.num = 4
|
||||
Debuffs.spacing = E.Border * 2
|
||||
Debuffs.onlyShowPlayer = false
|
||||
Debuffs.initialAnchor = 'BOTTOMLEFT'
|
||||
Debuffs['growth-x'] = 'RIGHT'
|
||||
Debuffs['growth-y'] = 'UP'
|
||||
Debuffs.type = 'debuffs'
|
||||
Debuffs.forceShow = nameplate == _G.ElvNP_Test
|
||||
|
||||
Buffs.PostCreateIcon = NP.Construct_AuraIcon
|
||||
Buffs.PostUpdateIcon = UF.PostUpdateAura
|
||||
Buffs.CustomFilter = UF.AuraFilter
|
||||
Debuffs.PostCreateIcon = NP.Construct_AuraIcon
|
||||
Debuffs.PostUpdateIcon = UF.PostUpdateAura
|
||||
Debuffs.CustomFilter = UF.AuraFilter
|
||||
|
||||
nameplate.Buffs_, nameplate.Debuffs_ = Buffs, Debuffs
|
||||
nameplate.Buffs, nameplate.Debuffs = Buffs, Debuffs
|
||||
end
|
||||
|
||||
function NP:Construct_AuraIcon(button)
|
||||
if not button then return end
|
||||
button:SetTemplate(nil, nil, nil, nil, nil, true)
|
||||
|
||||
button.cd:SetReverse(true)
|
||||
button.cd:SetInside(button)
|
||||
|
||||
button.icon:SetDrawLayer('ARTWORK')
|
||||
button.icon:SetInside()
|
||||
|
||||
button.count:ClearAllPoints()
|
||||
button.count:Point('BOTTOMRIGHT', 1, 1)
|
||||
button.count:SetJustifyH('RIGHT')
|
||||
|
||||
button.overlay:SetTexture()
|
||||
button.stealable:SetTexture()
|
||||
|
||||
button.cd.CooldownOverride = 'nameplates'
|
||||
E:RegisterCooldown(button.cd)
|
||||
|
||||
local auras = button:GetParent()
|
||||
button.db = auras and NP.db.units and NP.db.units[auras.__owner.frameType] and NP.db.units[auras.__owner.frameType][auras.type]
|
||||
|
||||
NP:UpdateAuraSettings(button)
|
||||
end
|
||||
|
||||
function NP:Configure_Auras(nameplate, auras, db)
|
||||
auras.size = db.size
|
||||
auras.num = db.numAuras
|
||||
auras.onlyShowPlayer = false
|
||||
auras.spacing = db.spacing
|
||||
auras['growth-y'] = db.growthY
|
||||
auras['growth-x'] = db.growthX
|
||||
auras.initialAnchor = E.InversePoints[db.anchorPoint]
|
||||
|
||||
local index = 1
|
||||
while auras[index] do
|
||||
local button = auras[index]
|
||||
if button then
|
||||
button.db = db
|
||||
NP:UpdateAuraSettings(button)
|
||||
end
|
||||
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
local mult = floor((nameplate.width or 150) / db.size) < db.numAuras
|
||||
auras:Size((nameplate.width or 150), (mult and 1 or 2) * db.size)
|
||||
auras:ClearAllPoints()
|
||||
auras:Point(E.InversePoints[db.anchorPoint] or 'TOPRIGHT', db.attachTo == 'BUFFS' and nameplate.Buffs or nameplate, db.anchorPoint or 'TOPRIGHT', db.xOffset, db.yOffset)
|
||||
end
|
||||
|
||||
function NP:Update_Auras(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if db.debuffs.enable or db.buffs.enable then
|
||||
nameplate:SetAuraUpdateMethod(E.global.nameplate.effectiveAura)
|
||||
nameplate:SetAuraUpdateSpeed(E.global.nameplate.effectiveAuraSpeed)
|
||||
|
||||
if not nameplate:IsElementEnabled('Auras') then
|
||||
nameplate:EnableElement('Auras')
|
||||
end
|
||||
|
||||
if db.debuffs.enable then
|
||||
nameplate.Debuffs = nameplate.Debuffs_
|
||||
NP:Configure_Auras(nameplate, nameplate.Debuffs, db.debuffs)
|
||||
nameplate.Debuffs:Show()
|
||||
nameplate.Debuffs:ForceUpdate()
|
||||
elseif nameplate.Debuffs then
|
||||
nameplate.Debuffs:Hide()
|
||||
nameplate.Debuffs = nil
|
||||
end
|
||||
|
||||
if db.buffs.enable then
|
||||
nameplate.Buffs = nameplate.Buffs_
|
||||
NP:Configure_Auras(nameplate, nameplate.Buffs, db.buffs)
|
||||
nameplate.Buffs:Show()
|
||||
nameplate.Buffs:ForceUpdate()
|
||||
elseif nameplate.Buffs then
|
||||
nameplate.Buffs:Hide()
|
||||
nameplate.Buffs = nil
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('Auras') then
|
||||
nameplate:DisableElement('Auras')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:UpdateAuraSettings(button)
|
||||
if button.db then
|
||||
button.count:FontTemplate(LSM:Fetch('font', button.db.countFont), button.db.countFontSize, button.db.countFontOutline)
|
||||
button.count:ClearAllPoints()
|
||||
|
||||
local point = (button.db and button.db.countPosition) or 'CENTER'
|
||||
if point == 'CENTER' then
|
||||
button.count:Point(point, 1, 0)
|
||||
else
|
||||
local bottom, right = point:find('BOTTOM'), point:find('RIGHT')
|
||||
button.count:SetJustifyH(right and 'RIGHT' or 'LEFT')
|
||||
button.count:Point(point, right and -1 or 1, bottom and 1 or -1)
|
||||
end
|
||||
end
|
||||
|
||||
if button.icon then
|
||||
button.icon:SetTexCoord(unpack(E.TexCoords))
|
||||
end
|
||||
|
||||
button:Size((button.db and button.db.size) or 26)
|
||||
|
||||
button.needsUpdateCooldownPosition = true
|
||||
end
|
||||
233
Modules/Nameplates/Elements/CastBar.lua
Normal file
233
Modules/Nameplates/Elements/CastBar.lua
Normal file
@@ -0,0 +1,233 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local CH = E:GetModule('Chat')
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
local _G = _G
|
||||
local abs = abs
|
||||
local unpack = unpack
|
||||
local strjoin = strjoin
|
||||
local strmatch = strmatch
|
||||
local CreateFrame = CreateFrame
|
||||
local UnitCanAttack = UnitCanAttack
|
||||
local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo
|
||||
local INTERRUPTED = INTERRUPTED
|
||||
|
||||
function NP:Castbar_CheckInterrupt(unit)
|
||||
if unit == 'vehicle' then
|
||||
unit = 'player'
|
||||
end
|
||||
|
||||
if self.notInterruptible and UnitCanAttack('player', unit) then
|
||||
self:SetStatusBarColor(NP.db.colors.castNoInterruptColor.r, NP.db.colors.castNoInterruptColor.g, NP.db.colors.castNoInterruptColor.b)
|
||||
|
||||
if self.Icon and NP.db.colors.castbarDesaturate then
|
||||
self.Icon:SetDesaturated(true)
|
||||
end
|
||||
else
|
||||
self:SetStatusBarColor(NP.db.colors.castColor.r, NP.db.colors.castColor.g, NP.db.colors.castColor.b)
|
||||
|
||||
if self.Icon then
|
||||
self.Icon:SetDesaturated(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Castbar_CustomDelayText(duration)
|
||||
if self.channeling then
|
||||
if self.channelTimeFormat == 'CURRENT' then
|
||||
self.Time:SetFormattedText('%.1f |cffaf5050%.1f|r', abs(duration - self.max), self.delay)
|
||||
elseif self.channelTimeFormat == 'CURRENTMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f |cffaf5050%.1f|r', duration, self.max, self.delay)
|
||||
elseif self.channelTimeFormat == 'REMAINING' then
|
||||
self.Time:SetFormattedText('%.1f |cffaf5050%.1f|r', duration, self.delay)
|
||||
elseif self.channelTimeFormat == 'REMAININGMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f |cffaf5050%.1f|r', abs(duration - self.max), self.max, self.delay)
|
||||
end
|
||||
else
|
||||
if self.castTimeFormat == 'CURRENT' then
|
||||
self.Time:SetFormattedText('%.1f |cffaf5050%s %.1f|r', duration, '+', self.delay)
|
||||
elseif self.castTimeFormat == 'CURRENTMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f |cffaf5050%s %.1f|r', duration, self.max, '+', self.delay)
|
||||
elseif self.castTimeFormat == 'REMAINING' then
|
||||
self.Time:SetFormattedText('%.1f |cffaf5050%s %.1f|r', abs(duration - self.max), '+', self.delay)
|
||||
elseif self.castTimeFormat == 'REMAININGMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f |cffaf5050%s %.1f|r', abs(duration - self.max), self.max, '+', self.delay)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Castbar_CustomTimeText(duration)
|
||||
if self.channeling then
|
||||
if self.channelTimeFormat == 'CURRENT' then
|
||||
self.Time:SetFormattedText('%.1f', abs(duration - self.max))
|
||||
elseif self.channelTimeFormat == 'CURRENTMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f', abs(duration - self.max), self.max)
|
||||
elseif self.channelTimeFormat == 'REMAINING' then
|
||||
self.Time:SetFormattedText('%.1f', duration)
|
||||
elseif self.channelTimeFormat == 'REMAININGMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f', duration, self.max)
|
||||
end
|
||||
else
|
||||
if self.castTimeFormat == 'CURRENT' then
|
||||
self.Time:SetFormattedText('%.1f', duration)
|
||||
elseif self.castTimeFormat == 'CURRENTMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f', duration, self.max)
|
||||
elseif self.castTimeFormat == 'REMAINING' then
|
||||
self.Time:SetFormattedText('%.1f', abs(duration - self.max))
|
||||
elseif self.castTimeFormat == 'REMAININGMAX' then
|
||||
self.Time:SetFormattedText('%.1f / %.1f', abs(duration - self.max), self.max)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Castbar_PostCastStart(unit)
|
||||
self:CheckInterrupt(unit)
|
||||
NP:StyleFilterUpdate(self.__owner, 'FAKE_Casting')
|
||||
end
|
||||
|
||||
function NP:Castbar_PostCastFail()
|
||||
self:SetStatusBarColor(NP.db.colors.castInterruptedColor.r, NP.db.colors.castInterruptedColor.g, NP.db.colors.castInterruptedColor.b)
|
||||
NP:StyleFilterUpdate(self.__owner, 'FAKE_Casting')
|
||||
end
|
||||
|
||||
function NP:Castbar_PostCastInterruptible(unit)
|
||||
self:CheckInterrupt(unit)
|
||||
end
|
||||
|
||||
function NP:Castbar_PostCastStop()
|
||||
NP:StyleFilterUpdate(self.__owner, 'FAKE_Casting')
|
||||
end
|
||||
|
||||
function NP:Construct_Castbar(nameplate)
|
||||
local Castbar = CreateFrame('StatusBar', nameplate:GetName()..'Castbar', nameplate)
|
||||
Castbar:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
Castbar:SetFrameLevel(5)
|
||||
Castbar:CreateBackdrop('Transparent', nil, nil, nil, nil, true)
|
||||
Castbar:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
|
||||
NP.StatusBars[Castbar] = true
|
||||
|
||||
Castbar.Button = CreateFrame('Frame', nil, Castbar, 'BackdropTemplate')
|
||||
Castbar.Button:SetTemplate()
|
||||
|
||||
Castbar.Icon = Castbar.Button:CreateTexture(nil, 'ARTWORK')
|
||||
Castbar.Icon:SetTexCoord(unpack(E.TexCoords))
|
||||
Castbar.Icon:SetInside()
|
||||
|
||||
Castbar.Time = Castbar:CreateFontString(nil, 'OVERLAY')
|
||||
Castbar.Time:Point('RIGHT', Castbar, 'RIGHT', -4, 0)
|
||||
Castbar.Time:SetJustifyH('RIGHT')
|
||||
Castbar.Time:FontTemplate(LSM:Fetch('font', NP.db.font), NP.db.fontSize, NP.db.fontOutline)
|
||||
|
||||
Castbar.Text = Castbar:CreateFontString(nil, 'OVERLAY')
|
||||
Castbar.Text:SetJustifyH('LEFT')
|
||||
Castbar.Text:FontTemplate(LSM:Fetch('font', NP.db.font), NP.db.fontSize, NP.db.fontOutline)
|
||||
Castbar.Text:SetWordWrap(false)
|
||||
|
||||
Castbar.CheckInterrupt = NP.Castbar_CheckInterrupt
|
||||
Castbar.CustomDelayText = NP.Castbar_CustomDelayText
|
||||
Castbar.CustomTimeText = NP.Castbar_CustomTimeText
|
||||
Castbar.PostCastStart = NP.Castbar_PostCastStart
|
||||
Castbar.PostCastFail = NP.Castbar_PostCastFail
|
||||
Castbar.PostCastInterruptible = NP.Castbar_PostCastInterruptible
|
||||
Castbar.PostCastStop = NP.Castbar_PostCastStop
|
||||
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
Castbar.Hide = Castbar.Show
|
||||
Castbar:Show()
|
||||
Castbar.Text:SetText('Casting')
|
||||
Castbar.Time:SetText('3.1')
|
||||
Castbar.Icon:SetTexture([[Interface\Icons\Achievement_Character_Pandaren_Female]])
|
||||
Castbar:SetStatusBarColor(NP.db.colors.castColor.r, NP.db.colors.castColor.g, NP.db.colors.castColor.b)
|
||||
end
|
||||
|
||||
return Castbar
|
||||
end
|
||||
|
||||
function NP:COMBAT_LOG_EVENT_UNFILTERED()
|
||||
local _, event, _, sourceGUID, sourceName, _, _, targetGUID = CombatLogGetCurrentEventInfo()
|
||||
if (event == 'SPELL_INTERRUPT' or event == 'SPELL_PERIODIC_INTERRUPT') and targetGUID and (sourceName and sourceName ~= '') then
|
||||
local plate, classColor = NP.PlateGUID[targetGUID]
|
||||
if plate and plate.Castbar then
|
||||
local db = plate.frameType and self.db and self.db.units and self.db.units[plate.frameType]
|
||||
if db and db.castbar and db.castbar.enable and db.castbar.sourceInterrupt then
|
||||
if db.castbar.timeToHold > 0 then
|
||||
local name = strmatch(sourceName, '([^%-]+).*')
|
||||
if db.castbar.sourceInterruptClassColor then
|
||||
local data = CH:GetPlayerInfoByGUID(sourceGUID)
|
||||
if data and data.classColor then
|
||||
classColor = data.classColor.colorStr
|
||||
end
|
||||
|
||||
plate.Castbar.Text:SetFormattedText('%s > %s', INTERRUPTED, classColor and strjoin('', '|c', classColor, name) or name)
|
||||
else
|
||||
plate.Castbar.Text:SetFormattedText('%s > %s', INTERRUPTED, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_Castbar(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
nameplate.Castbar:SetAlpha((not db.nameOnly and db.castbar.enable) and 1 or 0)
|
||||
end
|
||||
|
||||
if db.castbar.enable then
|
||||
if not nameplate:IsElementEnabled('Castbar') then
|
||||
nameplate:EnableElement('Castbar')
|
||||
end
|
||||
|
||||
nameplate.Castbar.timeToHold = db.castbar.timeToHold
|
||||
nameplate.Castbar.castTimeFormat = db.castbar.castTimeFormat
|
||||
nameplate.Castbar.channelTimeFormat = db.castbar.channelTimeFormat
|
||||
|
||||
nameplate.Castbar:Size(db.castbar.width, db.castbar.height)
|
||||
nameplate.Castbar:Point('CENTER', nameplate, 'CENTER', db.castbar.xOffset, db.castbar.yOffset)
|
||||
|
||||
if db.castbar.showIcon then
|
||||
nameplate.Castbar.Button:ClearAllPoints()
|
||||
nameplate.Castbar.Button:Point(db.castbar.iconPosition == 'RIGHT' and 'BOTTOMLEFT' or 'BOTTOMRIGHT', nameplate.Castbar, db.castbar.iconPosition == 'RIGHT' and 'BOTTOMRIGHT' or 'BOTTOMLEFT', db.castbar.iconOffsetX, db.castbar.iconOffsetY)
|
||||
nameplate.Castbar.Button:Size(db.castbar.iconSize, db.castbar.iconSize)
|
||||
nameplate.Castbar.Button:Show()
|
||||
else
|
||||
nameplate.Castbar.Button:Hide()
|
||||
end
|
||||
|
||||
nameplate.Castbar.Time:ClearAllPoints()
|
||||
nameplate.Castbar.Text:ClearAllPoints()
|
||||
|
||||
if db.castbar.textPosition == 'BELOW' then
|
||||
nameplate.Castbar.Time:Point('TOPRIGHT', nameplate.Castbar, 'BOTTOMRIGHT')
|
||||
nameplate.Castbar.Text:Point('TOPLEFT', nameplate.Castbar, 'BOTTOMLEFT')
|
||||
elseif db.castbar.textPosition == 'ABOVE' then
|
||||
nameplate.Castbar.Time:Point('BOTTOMRIGHT', nameplate.Castbar, 'TOPRIGHT')
|
||||
nameplate.Castbar.Text:Point('BOTTOMLEFT', nameplate.Castbar, 'TOPLEFT')
|
||||
else
|
||||
nameplate.Castbar.Time:Point('RIGHT', nameplate.Castbar, 'RIGHT', -1, 0)
|
||||
nameplate.Castbar.Text:Point('LEFT', nameplate.Castbar, 'LEFT', 1, 0)
|
||||
end
|
||||
|
||||
nameplate.Castbar.Text:Point('RIGHT', nameplate.Castbar, 'RIGHT', -20, 0)
|
||||
|
||||
if db.castbar.hideTime then
|
||||
nameplate.Castbar.Time:Hide()
|
||||
else
|
||||
nameplate.Castbar.Time:FontTemplate(LSM:Fetch('font', db.castbar.font), db.castbar.fontSize, db.castbar.fontOutline)
|
||||
nameplate.Castbar.Time:Show()
|
||||
end
|
||||
|
||||
if db.castbar.hideSpellName then
|
||||
nameplate.Castbar.Text:Hide()
|
||||
else
|
||||
nameplate.Castbar.Text:FontTemplate(LSM:Fetch('font', db.castbar.font), db.castbar.fontSize, db.castbar.fontOutline)
|
||||
nameplate.Castbar.Text:Show()
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('Castbar') then
|
||||
nameplate:DisableElement('Castbar')
|
||||
end
|
||||
end
|
||||
269
Modules/Nameplates/Elements/ClassPower.lua
Normal file
269
Modules/Nameplates/Elements/ClassPower.lua
Normal file
@@ -0,0 +1,269 @@
|
||||
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 oUF = E.oUF
|
||||
|
||||
local _G = _G
|
||||
local unpack, max = unpack, max
|
||||
local CreateFrame = CreateFrame
|
||||
local UnitHasVehicleUI = UnitHasVehicleUI
|
||||
|
||||
local MAX_POINTS = {
|
||||
DRUID = 5,
|
||||
DEATHKNIGHT = 6,
|
||||
MAGE = 4,
|
||||
MONK = 6,
|
||||
PALADIN = 5,
|
||||
ROGUE = 6,
|
||||
WARLOCK = 5
|
||||
}
|
||||
|
||||
function NP:ClassPower_UpdateColor(powerType)
|
||||
local color, r, g, b = NP.db.colors.classResources[E.myclass] or NP.db.colors.power[powerType]
|
||||
if color then
|
||||
r, g, b = color.r, color.g, color.b
|
||||
else
|
||||
color = oUF.colors.power[powerType]
|
||||
r, g, b = unpack(color)
|
||||
end
|
||||
|
||||
local db = NP.db.units[self.__owner.frameType]
|
||||
local ClassColor = db and db.classpower.classColor and E:ClassColor(E.myclass)
|
||||
for i = 1, #self do
|
||||
local classColor = ClassColor or (powerType == 'COMBO_POINTS' and NP.db.colors.classResources.comboPoints[i] or powerType == 'CHI' and NP.db.colors.classResources.MONK[i])
|
||||
if classColor then r, g, b = classColor.r, classColor.g, classColor.b end
|
||||
|
||||
self[i]:SetStatusBarColor(r, g, b)
|
||||
|
||||
if self[i].bg then self[i].bg:SetVertexColor(r * NP.multiplier, g * NP.multiplier, b * NP.multiplier) end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:ClassPower_PostUpdate(Cur, _, needUpdate)
|
||||
if Cur and Cur > 0 then
|
||||
self:Show()
|
||||
else
|
||||
self:Hide()
|
||||
end
|
||||
|
||||
if needUpdate then
|
||||
NP:Update_ClassPower(self.__owner)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_ClassPower(nameplate)
|
||||
local frameName = nameplate:GetName()
|
||||
local ClassPower = CreateFrame('Frame', frameName..'ClassPower', nameplate)
|
||||
ClassPower:CreateBackdrop('Transparent', nil, nil, nil, nil, true)
|
||||
ClassPower:Hide()
|
||||
ClassPower:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
ClassPower:SetFrameLevel(5)
|
||||
|
||||
local Max = max(MAX_POINTS[E.myclass] or 0, _G.MAX_COMBO_POINTS)
|
||||
local texture = LSM:Fetch('statusbar', NP.db.statusbar)
|
||||
|
||||
for i = 1, Max do
|
||||
ClassPower[i] = CreateFrame('StatusBar', frameName..'ClassPower'..i, ClassPower)
|
||||
ClassPower[i]:SetStatusBarTexture(texture)
|
||||
ClassPower[i]:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
ClassPower[i]:SetFrameLevel(6)
|
||||
NP.StatusBars[ClassPower[i]] = true
|
||||
|
||||
ClassPower[i].bg = ClassPower:CreateTexture(frameName..'ClassPower'..i..'bg', 'BORDER')
|
||||
ClassPower[i].bg:SetAllPoints(ClassPower[i])
|
||||
ClassPower[i].bg:SetTexture(texture)
|
||||
end
|
||||
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
ClassPower.Hide = ClassPower.Show
|
||||
ClassPower:Show()
|
||||
|
||||
for i = 1, Max do
|
||||
ClassPower[i]:SetStatusBarTexture(texture)
|
||||
ClassPower[i].bg:SetTexture(texture)
|
||||
ClassPower[i].bg:SetVertexColor(NP.db.colors.classResources.comboPoints[i].r, NP.db.colors.classResources.comboPoints[i].g, NP.db.colors.classResources.comboPoints[i].b)
|
||||
end
|
||||
end
|
||||
|
||||
ClassPower.UpdateColor = NP.ClassPower_UpdateColor
|
||||
ClassPower.PostUpdate = NP.ClassPower_PostUpdate
|
||||
|
||||
return ClassPower
|
||||
end
|
||||
|
||||
function NP:Update_ClassPower(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
if not db.nameOnly and db.classpower and db.classpower.enable then
|
||||
NP.ClassPower_UpdateColor(nameplate.ClassPower, 'COMBO_POINTS')
|
||||
nameplate.ClassPower:SetAlpha(1)
|
||||
else
|
||||
nameplate.ClassPower:SetAlpha(0)
|
||||
end
|
||||
end
|
||||
|
||||
if (nameplate.frameType == 'PLAYER' or nameplate.frameType == 'TARGET') and db.classpower and db.classpower.enable then
|
||||
if not nameplate:IsElementEnabled('ClassPower') then
|
||||
nameplate:EnableElement('ClassPower')
|
||||
end
|
||||
|
||||
nameplate.ClassPower:ClearAllPoints()
|
||||
nameplate.ClassPower:Point('CENTER', nameplate, 'CENTER', db.classpower.xOffset, db.classpower.yOffset)
|
||||
|
||||
local maxClassBarButtons = nameplate.ClassPower.__max
|
||||
|
||||
local Width = db.classpower.width / maxClassBarButtons
|
||||
nameplate.ClassPower:Size(db.classpower.width, db.classpower.height)
|
||||
|
||||
for i = 1, #nameplate.ClassPower do
|
||||
nameplate.ClassPower[i]:Hide()
|
||||
nameplate.ClassPower[i].bg:Hide()
|
||||
end
|
||||
|
||||
for i = 1, maxClassBarButtons do
|
||||
nameplate.ClassPower[i]:Show()
|
||||
nameplate.ClassPower[i].bg:Show()
|
||||
nameplate.ClassPower[i]:ClearAllPoints()
|
||||
|
||||
if i == 1 then
|
||||
nameplate.ClassPower[i]:Size(Width - (maxClassBarButtons == 6 and 2 or 0), db.classpower.height)
|
||||
nameplate.ClassPower[i].bg:Size(Width - (maxClassBarButtons == 6 and 2 or 0), db.classpower.height)
|
||||
|
||||
nameplate.ClassPower[i]:ClearAllPoints()
|
||||
nameplate.ClassPower[i]:Point('LEFT', nameplate.ClassPower, 'LEFT', 0, 0)
|
||||
else
|
||||
nameplate.ClassPower[i]:Size(Width - 1, db.classpower.height)
|
||||
nameplate.ClassPower[i].bg:Size(Width - 1, db.classpower.height)
|
||||
|
||||
nameplate.ClassPower[i]:ClearAllPoints()
|
||||
nameplate.ClassPower[i]:Point('LEFT', nameplate.ClassPower[i - 1], 'RIGHT', 1, 0)
|
||||
|
||||
if i == maxClassBarButtons then
|
||||
nameplate.ClassPower[i]:Point('RIGHT', nameplate.ClassPower)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if nameplate:IsElementEnabled('ClassPower') then
|
||||
nameplate:DisableElement('ClassPower')
|
||||
end
|
||||
|
||||
nameplate.ClassPower:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Runes_PostUpdate()
|
||||
if UnitHasVehicleUI('player') then
|
||||
self:Hide()
|
||||
else
|
||||
self:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Runes(nameplate)
|
||||
local frameName = nameplate:GetName()
|
||||
local Runes = CreateFrame('Frame', frameName..'Runes', nameplate)
|
||||
Runes:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
Runes:SetFrameLevel(5)
|
||||
Runes:CreateBackdrop('Transparent', nil, nil, nil, nil, true)
|
||||
Runes:Hide()
|
||||
|
||||
Runes.UpdateColor = E.noop
|
||||
Runes.PostUpdate = NP.Runes_PostUpdate
|
||||
|
||||
local texture = LSM:Fetch('statusbar', NP.db.statusbar)
|
||||
local color = NP.db.colors.classResources.DEATHKNIGHT
|
||||
|
||||
for i = 1, 6 do
|
||||
Runes[i] = CreateFrame('StatusBar', frameName..'Runes'..i, Runes)
|
||||
Runes[i]:SetStatusBarTexture(texture)
|
||||
Runes[i]:SetStatusBarColor(color.r, color.g, color.b)
|
||||
NP.StatusBars[Runes[i]] = true
|
||||
|
||||
Runes[i].bg = Runes[i]:CreateTexture(frameName..'Runes'..i..'bg', 'BORDER')
|
||||
Runes[i].bg:SetVertexColor(color.r * NP.multiplier, color.g * NP.multiplier, color.b * NP.multiplier)
|
||||
Runes[i].bg:SetTexture(texture)
|
||||
Runes[i].bg:SetAllPoints()
|
||||
end
|
||||
|
||||
return Runes
|
||||
end
|
||||
|
||||
function NP:Update_Runes(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if (nameplate.frameType == 'PLAYER' or nameplate.frameType == 'TARGET') and db.classpower and db.classpower.enable then
|
||||
if not nameplate:IsElementEnabled('Runes') then
|
||||
nameplate:EnableElement('Runes')
|
||||
end
|
||||
|
||||
nameplate.Runes:Show()
|
||||
nameplate.Runes:ClearAllPoints()
|
||||
nameplate.Runes:Point('CENTER', nameplate, 'CENTER', db.classpower.xOffset, db.classpower.yOffset)
|
||||
|
||||
nameplate.Runes.sortOrder = db.classpower.sortDirection
|
||||
|
||||
local width = db.classpower.width / 6
|
||||
nameplate.Runes:Size(db.classpower.width, db.classpower.height)
|
||||
|
||||
local runeColor = (db.classpower.classColor and E:ClassColor(E.myclass)) or NP.db.colors.classResources.DEATHKNIGHT
|
||||
|
||||
for i = 1, 6 do
|
||||
nameplate.Runes[i]:SetStatusBarColor(runeColor.r, runeColor.g, runeColor.b)
|
||||
|
||||
if i == 1 then
|
||||
nameplate.Runes[i]:Size(width, db.classpower.height)
|
||||
nameplate.Runes[i].bg:Size(width, db.classpower.height)
|
||||
|
||||
nameplate.Runes[i]:ClearAllPoints()
|
||||
nameplate.Runes[i]:Point('LEFT', nameplate.Runes, 'LEFT', 0, 0)
|
||||
else
|
||||
nameplate.Runes[i]:Size(width - 1, db.classpower.height)
|
||||
nameplate.Runes[i].bg:Size(width - 1, db.classpower.height)
|
||||
|
||||
nameplate.Runes[i]:ClearAllPoints()
|
||||
nameplate.Runes[i]:Point('LEFT', nameplate.Runes[i-1], 'RIGHT', 1, 0)
|
||||
|
||||
if i == 6 then
|
||||
nameplate.Runes[6]:Point('RIGHT', nameplate.Runes)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if nameplate:IsElementEnabled('Runes') then
|
||||
nameplate:DisableElement('Runes')
|
||||
end
|
||||
|
||||
nameplate.Runes:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Stagger(nameplate)
|
||||
local Stagger = CreateFrame('StatusBar', nameplate:GetName()..'Stagger', nameplate)
|
||||
Stagger:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
Stagger:SetFrameLevel(5)
|
||||
Stagger:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
Stagger:CreateBackdrop('Transparent', nil, nil, nil, nil, true)
|
||||
Stagger:Hide()
|
||||
|
||||
NP.StatusBars[Stagger] = true
|
||||
|
||||
return Stagger
|
||||
end
|
||||
|
||||
function NP:Update_Stagger(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if (nameplate.frameType == 'PLAYER' or nameplate.frameType == 'TARGET') and db.classpower and db.classpower.enable then
|
||||
if not nameplate:IsElementEnabled('Stagger') then
|
||||
nameplate:EnableElement('Stagger')
|
||||
end
|
||||
|
||||
nameplate.Stagger:ClearAllPoints()
|
||||
nameplate.Stagger:Point('CENTER', nameplate, 'CENTER', db.classpower.xOffset, db.classpower.yOffset)
|
||||
nameplate.Stagger:Size(db.classpower.width, db.classpower.height)
|
||||
elseif nameplate:IsElementEnabled('Stagger') then
|
||||
nameplate:DisableElement('Stagger')
|
||||
end
|
||||
end
|
||||
185
Modules/Nameplates/Elements/Health.lua
Normal file
185
Modules/Nameplates/Elements/Health.lua
Normal file
@@ -0,0 +1,185 @@
|
||||
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 ipairs = ipairs
|
||||
local unpack = unpack
|
||||
local UnitPlayerControlled = UnitPlayerControlled
|
||||
local UnitIsTapDenied = UnitIsTapDenied
|
||||
local UnitClass = UnitClass
|
||||
local UnitReaction = UnitReaction
|
||||
local UnitIsConnected = UnitIsConnected
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
function NP:Health_UpdateColor(_, unit)
|
||||
if not unit or self.unit ~= unit then return end
|
||||
local element = self.Health
|
||||
local Selection = element.colorSelection and NP:UnitSelectionType(unit, element.considerSelectionInCombatHostile)
|
||||
|
||||
local r, g, b, t
|
||||
if element.colorDisconnected and not UnitIsConnected(unit) then
|
||||
t = self.colors.disconnected
|
||||
elseif element.colorTapping and not UnitPlayerControlled(unit) and UnitIsTapDenied(unit) then
|
||||
t = NP.db.colors.tapped
|
||||
elseif (element.colorClass and self.isPlayer) or (element.colorClassNPC and not self.isPlayer) or (element.colorClassPet and UnitPlayerControlled(unit) and not self.isPlayer) then
|
||||
local _, class = UnitClass(unit)
|
||||
t = self.colors.class[class]
|
||||
elseif Selection then
|
||||
if Selection == 3 then Selection = UnitPlayerControlled(unit) and 5 or 3 end
|
||||
t = NP.db.colors.selection[Selection]
|
||||
elseif element.colorReaction and UnitReaction(unit, 'player') then
|
||||
local reaction = UnitReaction(unit, 'player')
|
||||
if reaction <= 3 then reaction = 'bad' elseif reaction == 4 then reaction = 'neutral' else reaction = 'good' end
|
||||
t = NP.db.colors.reactions[reaction]
|
||||
elseif element.colorSmooth then
|
||||
r, g, b = self:ColorGradient(element.cur or 1, element.max or 1, unpack(element.smoothGradient or self.colors.smooth))
|
||||
elseif element.colorHealth then
|
||||
t = NP.db.colors.health
|
||||
end
|
||||
|
||||
if t then
|
||||
r, g, b = t[1] or t.r, t[2] or t.g, t[3] or t.b
|
||||
element.r, element.g, element.b = r, g, b -- save these for the style filter to switch back
|
||||
end
|
||||
|
||||
local sf = NP:StyleFilterChanges(self)
|
||||
if sf.HealthColor then
|
||||
r, g, b = sf.HealthColor.r, sf.HealthColor.g, sf.HealthColor.b
|
||||
end
|
||||
|
||||
if b then
|
||||
element:SetStatusBarColor(r, g, b)
|
||||
|
||||
if element.bg then
|
||||
element.bg:SetVertexColor(r * NP.multiplier, g * NP.multiplier, b * NP.multiplier)
|
||||
end
|
||||
end
|
||||
|
||||
if element.PostUpdateColor then
|
||||
element:PostUpdateColor(unit, r, g, b)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Health(nameplate)
|
||||
local Health = CreateFrame('StatusBar', nameplate:GetName()..'Health', nameplate)
|
||||
Health:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
Health:SetFrameLevel(5)
|
||||
Health:CreateBackdrop('Transparent', nil, nil, nil, nil, true)
|
||||
Health:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
|
||||
local clipFrame = CreateFrame('Frame', nil, Health)
|
||||
clipFrame:SetClipsChildren(true)
|
||||
clipFrame:SetAllPoints()
|
||||
clipFrame:EnableMouse(false)
|
||||
Health.ClipFrame = clipFrame
|
||||
|
||||
--[[Health.bg = Health:CreateTexture(nil, 'BACKGROUND')
|
||||
Health.bg:SetAllPoints()
|
||||
Health.bg:SetTexture(E.media.blankTex)
|
||||
Health.bg.multiplier = 0.2]]
|
||||
|
||||
NP.StatusBars[Health] = true
|
||||
|
||||
local statusBarTexture = Health:GetStatusBarTexture()
|
||||
local healthFlashTexture = Health:CreateTexture(nameplate:GetName()..'FlashTexture', 'OVERLAY')
|
||||
healthFlashTexture:SetTexture(LSM:Fetch('background', 'ElvUI Blank'))
|
||||
healthFlashTexture:Point('BOTTOMLEFT', statusBarTexture, 'BOTTOMLEFT')
|
||||
healthFlashTexture:Point('TOPRIGHT', statusBarTexture, 'TOPRIGHT')
|
||||
healthFlashTexture:Hide()
|
||||
nameplate.HealthFlashTexture = healthFlashTexture
|
||||
|
||||
Health.colorTapping = true
|
||||
Health.colorSelection = true
|
||||
Health.UpdateColor = NP.Health_UpdateColor
|
||||
|
||||
return Health
|
||||
end
|
||||
|
||||
function NP:Update_Health(nameplate, skipUpdate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
nameplate.Health.colorTapping = true
|
||||
nameplate.Health.colorSelection = true
|
||||
nameplate.Health.colorClass = db.health.useClassColor
|
||||
nameplate.Health.considerSelectionInCombatHostile = true
|
||||
if skipUpdate then return end
|
||||
|
||||
if db.health.enable then
|
||||
if not nameplate:IsElementEnabled('Health') then
|
||||
nameplate:EnableElement('Health')
|
||||
end
|
||||
|
||||
nameplate.Health:Point('CENTER')
|
||||
nameplate.Health:Point('LEFT')
|
||||
nameplate.Health:Point('RIGHT')
|
||||
|
||||
nameplate:SetHealthUpdateMethod(E.global.nameplate.effectiveHealth)
|
||||
nameplate:SetHealthUpdateSpeed(E.global.nameplate.effectiveHealthSpeed)
|
||||
|
||||
E:SetSmoothing(nameplate.Health, NP.db.smoothbars)
|
||||
elseif nameplate:IsElementEnabled('Health') then
|
||||
nameplate:DisableElement('Health')
|
||||
end
|
||||
|
||||
nameplate.Health.width = db.health.width
|
||||
nameplate.Health.height = db.health.height
|
||||
nameplate.Health:Height(db.health.height)
|
||||
end
|
||||
|
||||
local bars = { 'myBar', 'otherBar', 'absorbBar', 'healAbsorbBar' }
|
||||
function NP:Construct_HealthPrediction(nameplate)
|
||||
local HealthPrediction = CreateFrame('Frame', nameplate:GetName()..'HealthPrediction', nameplate)
|
||||
|
||||
for _, name in ipairs(bars) do
|
||||
local bar = CreateFrame('StatusBar', nil, nameplate.Health.ClipFrame)
|
||||
bar:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
bar:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
bar:Point('TOP')
|
||||
bar:Point('BOTTOM')
|
||||
bar:Width(150)
|
||||
HealthPrediction[name] = bar
|
||||
NP.StatusBars[bar] = true
|
||||
end
|
||||
|
||||
local healthTexture = nameplate.Health:GetStatusBarTexture()
|
||||
local healthFrameLevel = nameplate.Health:GetFrameLevel()
|
||||
HealthPrediction.myBar:Point('LEFT', healthTexture, 'RIGHT')
|
||||
HealthPrediction.myBar:SetFrameLevel(healthFrameLevel + 2)
|
||||
HealthPrediction.myBar:SetStatusBarColor(NP.db.colors.healPrediction.personal.r, NP.db.colors.healPrediction.personal.g, NP.db.colors.healPrediction.personal.b)
|
||||
HealthPrediction.myBar:SetMinMaxValues(0, 1)
|
||||
|
||||
HealthPrediction.otherBar:Point('LEFT', HealthPrediction.myBar:GetStatusBarTexture(), 'RIGHT')
|
||||
HealthPrediction.otherBar:SetFrameLevel(healthFrameLevel + 1)
|
||||
HealthPrediction.otherBar:SetStatusBarColor(NP.db.colors.healPrediction.others.r, NP.db.colors.healPrediction.others.g, NP.db.colors.healPrediction.others.b)
|
||||
|
||||
HealthPrediction.absorbBar:Point('LEFT', HealthPrediction.otherBar:GetStatusBarTexture(), 'RIGHT')
|
||||
HealthPrediction.absorbBar:SetFrameLevel(healthFrameLevel)
|
||||
HealthPrediction.absorbBar:SetStatusBarColor(NP.db.colors.healPrediction.absorbs.r, NP.db.colors.healPrediction.absorbs.g, NP.db.colors.healPrediction.absorbs.b)
|
||||
|
||||
HealthPrediction.healAbsorbBar:Point('RIGHT', healthTexture)
|
||||
HealthPrediction.healAbsorbBar:SetFrameLevel(healthFrameLevel + 3)
|
||||
HealthPrediction.healAbsorbBar:SetStatusBarColor(NP.db.colors.healPrediction.healAbsorbs.r, NP.db.colors.healPrediction.healAbsorbs.g, NP.db.colors.healPrediction.healAbsorbs.b)
|
||||
HealthPrediction.healAbsorbBar:SetReverseFill(true)
|
||||
|
||||
HealthPrediction.maxOverflow = 1
|
||||
HealthPrediction.frequentUpdates = true
|
||||
|
||||
return HealthPrediction
|
||||
end
|
||||
|
||||
function NP:Update_HealthPrediction(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if db.health.enable and db.health.healPrediction then
|
||||
if not nameplate:IsElementEnabled('HealthPrediction') then
|
||||
nameplate:EnableElement('HealthPrediction')
|
||||
end
|
||||
|
||||
nameplate.HealthPrediction.myBar:SetStatusBarColor(NP.db.colors.healPrediction.personal.r, NP.db.colors.healPrediction.personal.g, NP.db.colors.healPrediction.personal.b)
|
||||
nameplate.HealthPrediction.otherBar:SetStatusBarColor(NP.db.colors.healPrediction.others.r, NP.db.colors.healPrediction.others.g, NP.db.colors.healPrediction.others.b)
|
||||
nameplate.HealthPrediction.absorbBar:SetStatusBarColor(NP.db.colors.healPrediction.absorbs.r, NP.db.colors.healPrediction.absorbs.g, NP.db.colors.healPrediction.absorbs.b)
|
||||
nameplate.HealthPrediction.healAbsorbBar:SetStatusBarColor(NP.db.colors.healPrediction.healAbsorbs.r, NP.db.colors.healPrediction.healAbsorbs.g, NP.db.colors.healPrediction.healAbsorbs.b)
|
||||
elseif nameplate:IsElementEnabled('HealthPrediction') then
|
||||
nameplate:DisableElement('HealthPrediction')
|
||||
end
|
||||
end
|
||||
294
Modules/Nameplates/Elements/Plugins.lua
Normal file
294
Modules/Nameplates/Elements/Plugins.lua
Normal file
@@ -0,0 +1,294 @@
|
||||
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 strfind = strfind
|
||||
local ipairs, unpack = ipairs, unpack
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
local targetIndicators = {'Spark', 'TopIndicator', 'LeftIndicator', 'RightIndicator'}
|
||||
|
||||
function NP:Construct_QuestIcons(nameplate)
|
||||
local QuestIcons = CreateFrame('Frame', nameplate:GetName() .. 'QuestIcons', nameplate)
|
||||
QuestIcons:Size(20)
|
||||
QuestIcons:Hide()
|
||||
|
||||
for _, object in ipairs(NP.QuestIcons.iconTypes) do
|
||||
local icon = QuestIcons:CreateTexture(nil, 'BORDER', nil, 1)
|
||||
icon.Text = QuestIcons:CreateFontString(nil, 'OVERLAY')
|
||||
icon.Text:FontTemplate()
|
||||
icon:Hide()
|
||||
|
||||
QuestIcons[object] = icon
|
||||
end
|
||||
|
||||
QuestIcons.Item:SetTexCoord(unpack(E.TexCoords))
|
||||
QuestIcons.Chat:SetTexture([[Interface\WorldMap\ChatBubble_64.PNG]])
|
||||
QuestIcons.Chat:SetTexCoord(0, 0.5, 0.5, 1)
|
||||
|
||||
return QuestIcons
|
||||
end
|
||||
|
||||
function NP:Update_QuestIcons(nameplate)
|
||||
local frameType = nameplate.frameType
|
||||
local db = frameType and NP.db.units[frameType].questIcon
|
||||
|
||||
if db and db.enable and (frameType == 'FRIENDLY_NPC' or frameType == 'ENEMY_NPC') then
|
||||
if not nameplate:IsElementEnabled('QuestIcons') then
|
||||
nameplate:EnableElement('QuestIcons')
|
||||
end
|
||||
|
||||
nameplate.QuestIcons:ClearAllPoints()
|
||||
nameplate.QuestIcons:Point(E.InversePoints[db.position], nameplate, db.position, db.xOffset, db.yOffset)
|
||||
|
||||
for _, object in ipairs(NP.QuestIcons.iconTypes) do
|
||||
local icon = nameplate.QuestIcons[object]
|
||||
icon:Size(db.size, db.size)
|
||||
icon:SetAlpha(db.hideIcon and 0 or 1)
|
||||
|
||||
local xoffset = strfind(db.textPosition, 'LEFT') and -2 or 2
|
||||
local yoffset = strfind(db.textPosition, 'BOTTOM') and 2 or -2
|
||||
icon.Text:ClearAllPoints()
|
||||
icon.Text:Point('CENTER', icon, db.textPosition, xoffset, yoffset)
|
||||
icon.Text:FontTemplate(LSM:Fetch('font', db.font), db.fontSize, db.fontOutline)
|
||||
icon.Text:SetJustifyH('CENTER')
|
||||
|
||||
icon.size, icon.position = db.size, db.position
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('QuestIcons') then
|
||||
nameplate:DisableElement('QuestIcons')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_ClassificationIndicator(nameplate)
|
||||
return nameplate:CreateTexture(nameplate:GetName() .. 'ClassificationIndicator', 'OVERLAY')
|
||||
end
|
||||
|
||||
function NP:Update_ClassificationIndicator(nameplate)
|
||||
local frameType = nameplate.frameType
|
||||
local db = frameType and NP.db.units[frameType].eliteIcon
|
||||
|
||||
if db and db.enable and (frameType == 'FRIENDLY_NPC' or frameType == 'ENEMY_NPC') then
|
||||
if not nameplate:IsElementEnabled('ClassificationIndicator') then
|
||||
nameplate:EnableElement('ClassificationIndicator')
|
||||
end
|
||||
|
||||
nameplate.ClassificationIndicator:ClearAllPoints()
|
||||
nameplate.ClassificationIndicator:Size(db.size, db.size)
|
||||
nameplate.ClassificationIndicator:Point(E.InversePoints[db.position], nameplate, db.position, db.xOffset, db.yOffset)
|
||||
elseif nameplate:IsElementEnabled('ClassificationIndicator') then
|
||||
nameplate:DisableElement('ClassificationIndicator')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_TargetIndicator(nameplate)
|
||||
local TargetIndicator = CreateFrame('Frame', nameplate:GetName() .. 'TargetIndicator', nameplate)
|
||||
TargetIndicator:SetFrameLevel(0)
|
||||
|
||||
TargetIndicator.Shadow = CreateFrame('Frame', nil, TargetIndicator, 'BackdropTemplate')
|
||||
TargetIndicator.Shadow:Hide()
|
||||
|
||||
for _, object in ipairs(targetIndicators) do
|
||||
local indicator = TargetIndicator:CreateTexture(nil, 'BACKGROUND', nil, -5)
|
||||
indicator:Hide()
|
||||
|
||||
TargetIndicator[object] = indicator
|
||||
end
|
||||
|
||||
return TargetIndicator
|
||||
end
|
||||
|
||||
function NP:Update_TargetIndicator(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if nameplate.frameType == 'PLAYER' then
|
||||
if nameplate:IsElementEnabled('TargetIndicator') then
|
||||
nameplate:DisableElement('TargetIndicator')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not nameplate:IsElementEnabled('TargetIndicator') then
|
||||
nameplate:EnableElement('TargetIndicator')
|
||||
end
|
||||
|
||||
nameplate.TargetIndicator.arrow = E.Media.Textures[NP.db.units.TARGET.arrow]
|
||||
nameplate.TargetIndicator.style = NP.db.units.TARGET.glowStyle
|
||||
nameplate.TargetIndicator.lowHealthThreshold = NP.db.lowHealthThreshold
|
||||
|
||||
if nameplate.TargetIndicator.style ~= 'none' then
|
||||
local GlowStyle, Color = NP.db.units.TARGET.glowStyle, NP.db.colors.glowColor
|
||||
|
||||
if not db.health.enable and (GlowStyle ~= 'style2' and GlowStyle ~= 'style6' and GlowStyle ~= 'style8') then
|
||||
GlowStyle = 'style2'
|
||||
nameplate.TargetIndicator.style = 'style2'
|
||||
end
|
||||
|
||||
if nameplate.TargetIndicator.TopIndicator and (GlowStyle == 'style3' or GlowStyle == 'style5' or GlowStyle == 'style6') then
|
||||
nameplate.TargetIndicator.TopIndicator:Point('BOTTOM', nameplate.Health, 'TOP', 0, 9)
|
||||
nameplate.TargetIndicator.TopIndicator:SetVertexColor(Color.r, Color.g, Color.b, Color.a)
|
||||
end
|
||||
|
||||
if nameplate.TargetIndicator.LeftIndicator and nameplate.TargetIndicator.RightIndicator and (GlowStyle == 'style4' or GlowStyle == 'style7' or GlowStyle == 'style8') then
|
||||
nameplate.TargetIndicator.LeftIndicator:Point('LEFT', nameplate.Health, 'RIGHT', 3, 0)
|
||||
nameplate.TargetIndicator.RightIndicator:Point('RIGHT', nameplate.Health, 'LEFT', -3, 0)
|
||||
nameplate.TargetIndicator.LeftIndicator:SetVertexColor(Color.r, Color.g, Color.b, Color.a)
|
||||
nameplate.TargetIndicator.RightIndicator:SetVertexColor(Color.r, Color.g, Color.b, Color.a)
|
||||
end
|
||||
|
||||
if nameplate.TargetIndicator.Shadow and (GlowStyle == 'style1' or GlowStyle == 'style5' or GlowStyle == 'style7') then
|
||||
nameplate.TargetIndicator.Shadow:SetOutside(nameplate.Health, E.PixelMode and 6 or 8, E.PixelMode and 6 or 8)
|
||||
nameplate.TargetIndicator.Shadow:SetBackdropBorderColor(Color.r, Color.g, Color.b)
|
||||
nameplate.TargetIndicator.Shadow:SetAlpha(Color.a)
|
||||
end
|
||||
|
||||
if nameplate.TargetIndicator.Spark and (GlowStyle == 'style2' or GlowStyle == 'style6' or GlowStyle == 'style8') then
|
||||
local size = E.Border + 14
|
||||
nameplate.TargetIndicator.Spark:Point('TOPLEFT', nameplate.Health, 'TOPLEFT', -(size * 2), size)
|
||||
nameplate.TargetIndicator.Spark:Point('BOTTOMRIGHT', nameplate.Health, 'BOTTOMRIGHT', (size * 2), -size)
|
||||
nameplate.TargetIndicator.Spark:SetVertexColor(Color.r, Color.g, Color.b, Color.a)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Highlight(nameplate)
|
||||
local Highlight = CreateFrame('Frame', nameplate:GetName() .. 'Highlight', nameplate)
|
||||
Highlight:Hide()
|
||||
Highlight:EnableMouse(false)
|
||||
Highlight:SetFrameLevel(9)
|
||||
|
||||
Highlight.texture = Highlight:CreateTexture(nil, 'ARTWORK')
|
||||
|
||||
return Highlight
|
||||
end
|
||||
|
||||
function NP:Update_Highlight(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if NP.db.highlight and db.enable then
|
||||
if not nameplate:IsElementEnabled('Highlight') then
|
||||
nameplate:EnableElement('Highlight')
|
||||
end
|
||||
|
||||
local sf = NP:StyleFilterChanges(nameplate)
|
||||
if db.health.enable and not (db.nameOnly or sf.NameOnly) then
|
||||
nameplate.Highlight.texture:SetColorTexture(1, 1, 1, 0.25)
|
||||
nameplate.Highlight.texture:SetAllPoints(nameplate.HealthFlashTexture)
|
||||
nameplate.Highlight.texture:SetAlpha(0.75)
|
||||
else
|
||||
nameplate.Highlight.texture:SetTexture(E.Media.Textures.Spark)
|
||||
nameplate.Highlight.texture:SetAllPoints(nameplate)
|
||||
nameplate.Highlight.texture:SetAlpha(0.50)
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('Highlight') then
|
||||
nameplate:DisableElement('Highlight')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_PVPRole(nameplate)
|
||||
local texture = nameplate:CreateTexture(nameplate:GetName() .. 'PVPRole', 'OVERLAY', nil, 1)
|
||||
texture:Size(40)
|
||||
texture.HealerTexture = E.Media.Textures.Healer
|
||||
texture.TankTexture = E.Media.Textures.Tank
|
||||
texture:SetTexture(texture.HealerTexture)
|
||||
|
||||
texture:Hide()
|
||||
|
||||
return texture
|
||||
end
|
||||
|
||||
function NP:Update_PVPRole(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if (nameplate.frameType == 'FRIENDLY_PLAYER' or nameplate.frameType == 'ENEMY_PLAYER') and (db.markHealers or db.markTanks) then
|
||||
if not nameplate:IsElementEnabled('PVPRole') then
|
||||
nameplate:EnableElement('PVPRole')
|
||||
end
|
||||
|
||||
nameplate.PVPRole.ShowHealers = db.markHealers
|
||||
nameplate.PVPRole.ShowTanks = db.markTanks
|
||||
|
||||
nameplate.PVPRole:Point('RIGHT', nameplate.Health, 'LEFT', -6, 0)
|
||||
elseif nameplate:IsElementEnabled('PVPRole') then
|
||||
nameplate:DisableElement('PVPRole')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_Fader(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
local vis = db.visibility
|
||||
|
||||
if not vis or vis.showAlways then
|
||||
if nameplate:IsElementEnabled('Fader') then
|
||||
nameplate:DisableElement('Fader')
|
||||
|
||||
NP:PlateFade(nameplate, 1, nameplate:GetAlpha(), 1)
|
||||
end
|
||||
else
|
||||
if not nameplate.Fader then
|
||||
nameplate.Fader = {}
|
||||
end
|
||||
|
||||
if not nameplate:IsElementEnabled('Fader') then
|
||||
nameplate:EnableElement('Fader')
|
||||
|
||||
nameplate.Fader:SetOption('MinAlpha', 0)
|
||||
nameplate.Fader:SetOption('Smooth', 0.3)
|
||||
nameplate.Fader:SetOption('Hover', true)
|
||||
nameplate.Fader:SetOption('Power', true)
|
||||
nameplate.Fader:SetOption('Health', true)
|
||||
nameplate.Fader:SetOption('Casting', true)
|
||||
end
|
||||
|
||||
nameplate.Fader:SetOption('Combat', vis.showInCombat)
|
||||
nameplate.Fader:SetOption('PlayerTarget', vis.showWithTarget)
|
||||
nameplate.Fader:SetOption('DelayAlpha', (vis.alphaDelay > 0 and vis.alphaDelay) or nil)
|
||||
nameplate.Fader:SetOption('Delay', (vis.hideDelay > 0 and vis.hideDelay) or nil)
|
||||
|
||||
nameplate.Fader:ForceUpdate()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Cutaway(nameplate)
|
||||
local frameName = nameplate:GetName()
|
||||
local Cutaway = {}
|
||||
|
||||
Cutaway.Health = nameplate.Health.ClipFrame:CreateTexture(frameName .. 'CutawayHealth')
|
||||
local healthTexture = nameplate.Health:GetStatusBarTexture()
|
||||
Cutaway.Health:Point('TOPLEFT', healthTexture, 'TOPRIGHT')
|
||||
Cutaway.Health:Point('BOTTOMLEFT', healthTexture, 'BOTTOMRIGHT')
|
||||
|
||||
Cutaway.Power = nameplate.Power.ClipFrame:CreateTexture(frameName .. 'CutawayPower')
|
||||
local powerTexture = nameplate.Power:GetStatusBarTexture()
|
||||
Cutaway.Power:Point('TOPLEFT', powerTexture, 'TOPRIGHT')
|
||||
Cutaway.Power:Point('BOTTOMLEFT', powerTexture, 'BOTTOMRIGHT')
|
||||
|
||||
return Cutaway
|
||||
end
|
||||
|
||||
function NP:Update_Cutaway(nameplate)
|
||||
local eitherEnabled = NP.db.cutaway.health.enabled or NP.db.cutaway.power.enabled
|
||||
if not eitherEnabled then
|
||||
if nameplate:IsElementEnabled('Cutaway') then
|
||||
nameplate:DisableElement('Cutaway')
|
||||
end
|
||||
else
|
||||
if not nameplate:IsElementEnabled('Cutaway') then
|
||||
nameplate:EnableElement('Cutaway')
|
||||
end
|
||||
|
||||
nameplate.Cutaway:UpdateConfigurationValues(NP.db.cutaway)
|
||||
|
||||
if NP.db.cutaway.health.forceBlankTexture then
|
||||
nameplate.Cutaway.Health:SetTexture(E.media.blankTex)
|
||||
else
|
||||
nameplate.Cutaway.Health:SetTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
end
|
||||
|
||||
if NP.db.cutaway.power.forceBlankTexture then
|
||||
nameplate.Cutaway.Power:SetTexture(E.media.blankTex)
|
||||
else
|
||||
nameplate.Cutaway.Power:SetTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
end
|
||||
end
|
||||
end
|
||||
66
Modules/Nameplates/Elements/Portraits.lua
Normal file
66
Modules/Nameplates/Elements/Portraits.lua
Normal file
@@ -0,0 +1,66 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
local _G = _G
|
||||
local unpack = unpack
|
||||
local hooksecurefunc = hooksecurefunc
|
||||
|
||||
function NP:Portrait_PostUpdate()
|
||||
local nameplate = self.__owner
|
||||
local db = NP:PlateDB(nameplate)
|
||||
local sf = NP:StyleFilterChanges(nameplate)
|
||||
|
||||
if sf.Portrait or (db.portrait and db.portrait.enable) then
|
||||
if db.portrait.classicon and nameplate.isPlayer then
|
||||
self:SetTexture([[Interface\WorldStateFrame\Icons-Classes]])
|
||||
self:SetTexCoord(unpack(_G.CLASS_ICON_TCOORDS[nameplate.classFile]))
|
||||
self.backdrop:Hide()
|
||||
else
|
||||
self:SetTexCoord(.18, .82, .18, .82)
|
||||
self.backdrop:Show()
|
||||
end
|
||||
else
|
||||
self.backdrop:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_PortraitBackdrop()
|
||||
if self.backdrop then
|
||||
self.backdrop:SetShown(self:IsShown())
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Portrait(nameplate)
|
||||
local Portrait = nameplate:CreateTexture(nameplate:GetName() .. 'Portrait', 'OVERLAY', nil, 2)
|
||||
Portrait:SetTexCoord(.18, .82, .18, .82)
|
||||
Portrait:CreateBackdrop(nil, nil, nil, nil, nil, true)
|
||||
Portrait:Hide()
|
||||
|
||||
Portrait.PostUpdate = NP.Portrait_PostUpdate
|
||||
hooksecurefunc(Portrait, 'Hide', NP.Update_PortraitBackdrop)
|
||||
hooksecurefunc(Portrait, 'Show', NP.Update_PortraitBackdrop)
|
||||
|
||||
return Portrait
|
||||
end
|
||||
|
||||
function NP:Update_Portrait(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
local sf = NP:StyleFilterChanges(nameplate)
|
||||
|
||||
if sf.Portrait or (db.portrait and db.portrait.enable) then
|
||||
if not nameplate:IsElementEnabled('Portrait') then
|
||||
nameplate:EnableElement('Portrait')
|
||||
nameplate.Portrait:ForceUpdate()
|
||||
end
|
||||
|
||||
nameplate.Portrait:Size(db.portrait.width, db.portrait.height)
|
||||
|
||||
-- These values are forced in name only mode inside of DisablePlate
|
||||
if not (db.nameOnly or sf.NameOnly) then
|
||||
nameplate.Portrait:ClearAllPoints()
|
||||
nameplate.Portrait:Point(E.InversePoints[db.portrait.position], nameplate, db.portrait.position, db.portrait.xOffset, db.portrait.yOffset)
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('Portrait') then
|
||||
nameplate:DisableElement('Portrait')
|
||||
end
|
||||
end
|
||||
151
Modules/Nameplates/Elements/Power.lua
Normal file
151
Modules/Nameplates/Elements/Power.lua
Normal file
@@ -0,0 +1,151 @@
|
||||
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 unpack = unpack
|
||||
local UnitPlayerControlled = UnitPlayerControlled
|
||||
local UnitIsTapDenied = UnitIsTapDenied
|
||||
local UnitClass = UnitClass
|
||||
local UnitReaction = UnitReaction
|
||||
local UnitIsConnected = UnitIsConnected
|
||||
local CreateFrame = CreateFrame
|
||||
local UnitPowerType = UnitPowerType
|
||||
local ALTERNATE_POWER_INDEX = Enum.PowerType.Alternate or 10
|
||||
|
||||
function NP:Power_UpdateColor(_, unit)
|
||||
if self.unit ~= unit then return end
|
||||
|
||||
local element = self.Power
|
||||
local ptype, ptoken, altR, altG, altB = UnitPowerType(unit)
|
||||
element.token = ptoken
|
||||
|
||||
local sf = NP:StyleFilterChanges(self)
|
||||
if sf.PowerColor then return end
|
||||
|
||||
local Selection = element.colorSelection and NP:UnitSelectionType(unit, element.considerSelectionInCombatHostile)
|
||||
|
||||
local r, g, b, t, atlas
|
||||
if element.colorDisconnected and not UnitIsConnected(unit) then
|
||||
t = self.colors.disconnected
|
||||
elseif element.colorTapping and not UnitPlayerControlled(unit) and UnitIsTapDenied(unit) then
|
||||
t = self.colors.tapped
|
||||
elseif element.colorPower then
|
||||
if element.displayType ~= ALTERNATE_POWER_INDEX then
|
||||
t = NP.db.colors.power[ptoken or ptype]
|
||||
if not t then
|
||||
if element.GetAlternativeColor then
|
||||
r, g, b = element:GetAlternativeColor(unit, ptype, ptoken, altR, altG, altB)
|
||||
elseif altR then
|
||||
r, g, b = altR, altG, altB
|
||||
if r > 1 or g > 1 or b > 1 then -- BUG: As of 7.0.3, altR, altG, altB may be in 0-1 or 0-255 range.
|
||||
r, g, b = r / 255, g / 255, b / 255
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
t = NP.db.colors.power.ALT_POWER
|
||||
end
|
||||
|
||||
if element.useAtlas and t and t.atlas then
|
||||
atlas = t.atlas
|
||||
end
|
||||
elseif (element.colorClass and self.isPlayer) or (element.colorClassNPC and not self.isPlayer) or (element.colorClassPet and UnitPlayerControlled(unit) and not self.isPlayer) then
|
||||
local _, class = UnitClass(unit)
|
||||
t = self.colors.class[class]
|
||||
elseif Selection then
|
||||
t = NP.db.colors.selection[Selection]
|
||||
elseif element.colorReaction and UnitReaction(unit, 'player') then
|
||||
local reaction = UnitReaction(unit, 'player')
|
||||
if reaction <= 3 then reaction = 'bad' elseif reaction == 4 then reaction = 'neutral' else reaction = 'good' end
|
||||
t = NP.db.colors.reactions[reaction]
|
||||
elseif element.colorSmooth then
|
||||
local adjust = 0 - (element.min or 0)
|
||||
r, g, b = self:ColorGradient((element.cur or 1) + adjust, (element.max or 1) + adjust, unpack(element.smoothGradient or self.colors.smooth))
|
||||
end
|
||||
|
||||
if t then
|
||||
r, g, b = t[1] or t.r, t[2] or t.g, t[3] or t.b
|
||||
end
|
||||
|
||||
if atlas then
|
||||
element:SetStatusBarAtlas(atlas)
|
||||
element:SetStatusBarColor(1, 1, 1)
|
||||
elseif b then
|
||||
element:SetStatusBarColor(r, g, b)
|
||||
end
|
||||
|
||||
if element.bg and b then element.bg:SetVertexColor(r * NP.multiplier, g * NP.multiplier, b * NP.multiplier) end
|
||||
|
||||
if element.PostUpdateColor then
|
||||
element:PostUpdateColor(unit, r, g, b)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Power_PostUpdate(_, cur) --unit, cur, min, max
|
||||
local db = NP.db.units[self.__owner.frameType]
|
||||
|
||||
if not db then return end
|
||||
|
||||
if self.__owner.frameType ~= 'PLAYER' and db.power.displayAltPower and not self.displayType then
|
||||
self:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
if db.power and db.power.enable and db.power.hideWhenEmpty and (cur == 0) then
|
||||
self:Hide()
|
||||
else
|
||||
self:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_Power(nameplate)
|
||||
local Power = CreateFrame('StatusBar', nameplate:GetName()..'Power', nameplate)
|
||||
Power:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
Power:SetFrameLevel(5)
|
||||
Power:CreateBackdrop('Transparent', nil, nil, nil, nil, true)
|
||||
|
||||
local clipFrame = CreateFrame('Frame', nil, Power)
|
||||
clipFrame:SetClipsChildren(true)
|
||||
clipFrame:SetAllPoints()
|
||||
clipFrame:EnableMouse(false)
|
||||
Power.ClipFrame = clipFrame
|
||||
|
||||
NP.StatusBars[Power] = true
|
||||
|
||||
Power.frequentUpdates = true
|
||||
Power.colorTapping = false
|
||||
Power.colorClass = false
|
||||
|
||||
Power.PostUpdate = NP.Power_PostUpdate
|
||||
Power.UpdateColor = NP.Power_UpdateColor
|
||||
|
||||
return Power
|
||||
end
|
||||
|
||||
function NP:Update_Power(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if db.power.enable then
|
||||
if not nameplate:IsElementEnabled('Power') then
|
||||
nameplate:EnableElement('Power')
|
||||
end
|
||||
|
||||
nameplate.Power:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar))
|
||||
nameplate.Power:Point('CENTER', nameplate, 'CENTER', db.power.xOffset, db.power.yOffset)
|
||||
|
||||
nameplate:SetPowerUpdateMethod(E.global.nameplate.effectivePower)
|
||||
nameplate:SetPowerUpdateSpeed(E.global.nameplate.effectivePowerSpeed)
|
||||
|
||||
E:SetSmoothing(nameplate.Power, NP.db.smoothbars)
|
||||
elseif nameplate:IsElementEnabled('Power') then
|
||||
nameplate:DisableElement('Power')
|
||||
end
|
||||
|
||||
nameplate.Power.displayAltPower = db.power.displayAltPower
|
||||
nameplate.Power.useAtlas = db.power.useAtlas
|
||||
nameplate.Power.colorClass = db.power.useClassColor
|
||||
nameplate.Power.colorPower = not db.power.useClassColor
|
||||
nameplate.Power.width = db.power.width
|
||||
nameplate.Power.height = db.power.height
|
||||
nameplate.Power:Size(db.power.width, db.power.height)
|
||||
end
|
||||
64
Modules/Nameplates/Elements/PvP.lua
Normal file
64
Modules/Nameplates/Elements/PvP.lua
Normal file
@@ -0,0 +1,64 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
local strlower = strlower
|
||||
|
||||
function NP:PvPIndicator_PostUpdate(_, status)
|
||||
if status and status ~= 'FFA' and (not self.Badge or not self.Badge:IsShown()) then
|
||||
self:SetAtlas('bfa-landingbutton-'..strlower(status)..'-up')
|
||||
self:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_PvPIndicator(nameplate)
|
||||
local PvPIndicator = nameplate:CreateTexture(nil, 'OVERLAY')
|
||||
PvPIndicator.Badge_ = nameplate:CreateTexture(nil, 'ARTWORK')
|
||||
PvPIndicator.PostUpdate = NP.PvPIndicator_PostUpdate
|
||||
|
||||
return PvPIndicator
|
||||
end
|
||||
|
||||
function NP:Update_PvPIndicator(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if db.pvpindicator and db.pvpindicator.enable then
|
||||
if not nameplate:IsElementEnabled('PvPIndicator') then
|
||||
nameplate:EnableElement('PvPIndicator')
|
||||
end
|
||||
|
||||
nameplate.PvPIndicator:Size(db.pvpindicator.size, db.pvpindicator.size)
|
||||
nameplate.PvPIndicator.Badge_:Size(db.pvpindicator.size + 14, db.pvpindicator.size + 16)
|
||||
|
||||
nameplate.PvPIndicator.Badge = nil
|
||||
|
||||
if db.pvpindicator.showBadge then
|
||||
nameplate.PvPIndicator.Badge = nameplate.PvPIndicator.Badge_
|
||||
end
|
||||
|
||||
nameplate.PvPIndicator:ClearAllPoints()
|
||||
nameplate.PvPIndicator:Point(E.InversePoints[db.pvpindicator.position], nameplate, db.pvpindicator.position, db.pvpindicator.xOffset, db.pvpindicator.yOffset)
|
||||
elseif nameplate:IsElementEnabled('PvPIndicator') then
|
||||
nameplate:DisableElement('PvPIndicator')
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_PvPClassificationIndicator(nameplate)
|
||||
local PvPClassificationIndicator = nameplate:CreateTexture(nil, 'OVERLAY')
|
||||
return PvPClassificationIndicator
|
||||
end
|
||||
|
||||
function NP:Update_PvPClassificationIndicator(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if (nameplate.frameType == 'ENEMY_PLAYER' or nameplate.frameType == 'FRIENDLY_PLAYER' or nameplate.frameType == 'PLAYER') and db.pvpclassificationindicator and db.pvpclassificationindicator.enable then
|
||||
if not nameplate:IsElementEnabled('PvPClassificationIndicator') then
|
||||
nameplate:EnableElement('PvPClassificationIndicator')
|
||||
end
|
||||
|
||||
nameplate.PvPClassificationIndicator:ClearAllPoints()
|
||||
nameplate.PvPClassificationIndicator:Point(E.InversePoints[db.pvpclassificationindicator.position], nameplate, db.pvpclassificationindicator.position, db.pvpclassificationindicator.xOffset, db.pvpclassificationindicator.yOffset)
|
||||
nameplate.PvPClassificationIndicator:Size(db.pvpclassificationindicator.size)
|
||||
elseif nameplate:IsElementEnabled('PvPClassificationIndicator') then
|
||||
nameplate:DisableElement('PvPClassificationIndicator')
|
||||
end
|
||||
end
|
||||
42
Modules/Nameplates/Elements/RaidTargetIndicator.lua
Normal file
42
Modules/Nameplates/Elements/RaidTargetIndicator.lua
Normal file
@@ -0,0 +1,42 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
local GetRaidTargetIndex = GetRaidTargetIndex
|
||||
local SetRaidTargetIconTexture = SetRaidTargetIconTexture
|
||||
|
||||
function NP:RaidTargetIndicator_Override()
|
||||
local element = self.RaidTargetIndicator
|
||||
|
||||
if self.unit then
|
||||
local index = GetRaidTargetIndex(self.unit)
|
||||
if index and not self.isMe then
|
||||
SetRaidTargetIconTexture(element, index)
|
||||
element:Show()
|
||||
else
|
||||
element:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_RaidTargetIndicator(nameplate)
|
||||
local RaidTargetIndicator = nameplate:CreateTexture(nil, 'OVERLAY', 7)
|
||||
RaidTargetIndicator.Override = NP.RaidTargetIndicator_Override
|
||||
|
||||
return RaidTargetIndicator
|
||||
end
|
||||
|
||||
function NP:Update_RaidTargetIndicator(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
|
||||
if db.raidTargetIndicator and db.raidTargetIndicator.enable then
|
||||
if not nameplate:IsElementEnabled('RaidTargetIndicator') then
|
||||
nameplate:EnableElement('RaidTargetIndicator')
|
||||
end
|
||||
|
||||
nameplate.RaidTargetIndicator:ClearAllPoints()
|
||||
nameplate.RaidTargetIndicator:Point(E.InversePoints[db.raidTargetIndicator.position], nameplate, db.raidTargetIndicator.position, db.raidTargetIndicator.xOffset, db.raidTargetIndicator.yOffset)
|
||||
nameplate.RaidTargetIndicator:Size(db.raidTargetIndicator.size)
|
||||
elseif nameplate:IsElementEnabled('RaidTargetIndicator') then
|
||||
nameplate:DisableElement('RaidTargetIndicator')
|
||||
end
|
||||
end
|
||||
39
Modules/Nameplates/Elements/Tags.lua
Normal file
39
Modules/Nameplates/Elements/Tags.lua
Normal file
@@ -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
|
||||
|
||||
function NP:Construct_TagText(nameplate)
|
||||
local Text = nameplate:CreateFontString(nil, 'OVERLAY')
|
||||
Text:FontTemplate(E.LSM:Fetch('font', NP.db.font), NP.db.fontSize, NP.db.fontOutline)
|
||||
|
||||
return Text
|
||||
end
|
||||
|
||||
function NP:Update_TagText(nameplate, element, db, hide)
|
||||
if not db then return end
|
||||
|
||||
if db.enable and not hide then
|
||||
nameplate:Tag(element, db.format or '')
|
||||
element:FontTemplate(LSM:Fetch('font', db.font), db.fontSize, db.fontOutline)
|
||||
element:UpdateTag()
|
||||
|
||||
element:ClearAllPoints()
|
||||
element:Point(E.InversePoints[db.position], db.parent == 'Nameplate' and nameplate or nameplate[db.parent], db.position, db.xOffset, db.yOffset)
|
||||
element:Show()
|
||||
else
|
||||
nameplate:Untag(element)
|
||||
element:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Update_Tags(nameplate)
|
||||
local db = NP:PlateDB(nameplate)
|
||||
local sf = NP:StyleFilterChanges(nameplate)
|
||||
local hide = db.nameOnly or sf.NameOnly
|
||||
|
||||
NP:Update_TagText(nameplate, nameplate.Name, db.name)
|
||||
NP:Update_TagText(nameplate, nameplate.Title, db.title)
|
||||
NP:Update_TagText(nameplate, nameplate.Level, db.level, hide)
|
||||
NP:Update_TagText(nameplate, nameplate.Health.Text, db.health and db.health.text, hide)
|
||||
NP:Update_TagText(nameplate, nameplate.Power.Text, db.power and db.power.text, hide)
|
||||
end
|
||||
104
Modules/Nameplates/Elements/Threat.lua
Normal file
104
Modules/Nameplates/Elements/Threat.lua
Normal file
@@ -0,0 +1,104 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
local UnitName = UnitName
|
||||
local UnitExists = UnitExists
|
||||
local UnitIsUnit = UnitIsUnit
|
||||
local UnitIsTapDenied = UnitIsTapDenied
|
||||
|
||||
function NP:ThreatIndicator_PreUpdate(unit, pass)
|
||||
local ROLE = NP.IsInGroup and (UnitExists(unit..'target') and not UnitIsUnit(unit..'target', 'player')) and NP.GroupRoles[UnitName(unit..'target')] or 'NONE'
|
||||
|
||||
local unitTank, imTank = ROLE == 'TANK', E.myrole == 'TANK'
|
||||
local isTank, offTank, feedbackUnit = unitTank or imTank, (unitTank and imTank) or false, (unitTank and unit..'target') or 'player'
|
||||
|
||||
self.__owner.ThreatScale = nil
|
||||
|
||||
if pass then
|
||||
return isTank, offTank, feedbackUnit, ROLE
|
||||
else
|
||||
self.feedbackUnit = feedbackUnit
|
||||
self.offTank = offTank
|
||||
self.isTank = isTank
|
||||
end
|
||||
end
|
||||
|
||||
function NP:ThreatIndicator_PostUpdate(unit, status)
|
||||
local sf = NP:StyleFilterChanges(self.__owner)
|
||||
if not status and not sf.Scale then
|
||||
self.__owner.ThreatScale = 1
|
||||
NP:ScalePlate(self.__owner, 1)
|
||||
elseif status and NP.db.threat and NP.db.threat.enable and NP.db.threat.useThreatColor and not UnitIsTapDenied(unit) then
|
||||
self.__owner.Health.colorTapping = false
|
||||
self.__owner.Health.colorDisconnected = false
|
||||
self.__owner.Health.colorClass = false
|
||||
self.__owner.Health.colorClassNPC = false
|
||||
self.__owner.Health.colorClassPet = false
|
||||
self.__owner.Health.colorSelection = false
|
||||
self.__owner.Health.colorThreat = false
|
||||
self.__owner.Health.colorReaction = false
|
||||
self.__owner.Health.colorSmooth = false
|
||||
self.__owner.Health.colorHealth = false
|
||||
|
||||
self.__owner.ThreatStatus = status
|
||||
|
||||
local Color, Scale
|
||||
if status == 3 then -- securely tanking
|
||||
Color = self.offTank and NP.db.colors.threat.offTankColor or self.isTank and NP.db.colors.threat.goodColor or NP.db.colors.threat.badColor
|
||||
Scale = self.isTank and NP.db.threat.goodScale or NP.db.threat.badScale
|
||||
elseif status == 2 then -- insecurely tanking
|
||||
Color = self.offTank and NP.db.colors.threat.offTankColorBadTransition or self.isTank and NP.db.colors.threat.badTransition or NP.db.colors.threat.goodTransition
|
||||
Scale = 1
|
||||
elseif status == 1 then -- not tanking but threat higher than tank
|
||||
Color = self.offTank and NP.db.colors.threat.offTankColorGoodTransition or self.isTank and NP.db.colors.threat.goodTransition or NP.db.colors.threat.badTransition
|
||||
Scale = 1
|
||||
else -- not tanking at all
|
||||
Color = self.isTank and NP.db.colors.threat.badColor or NP.db.colors.threat.goodColor
|
||||
Scale = self.isTank and NP.db.threat.badScale or NP.db.threat.goodScale
|
||||
end
|
||||
|
||||
if sf.HealthColor then
|
||||
self.r, self.g, self.b = Color.r, Color.g, Color.b
|
||||
else
|
||||
self.__owner.Health:SetStatusBarColor(Color.r, Color.g, Color.b)
|
||||
end
|
||||
|
||||
if Scale then
|
||||
self.__owner.ThreatScale = Scale
|
||||
|
||||
if not sf.Scale then
|
||||
NP:ScalePlate(self.__owner, Scale)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Construct_ThreatIndicator(nameplate)
|
||||
local ThreatIndicator = nameplate:CreateTexture(nil, 'OVERLAY')
|
||||
ThreatIndicator:Size(16, 16)
|
||||
ThreatIndicator:Hide()
|
||||
ThreatIndicator:Point('CENTER', nameplate, 'TOPRIGHT')
|
||||
|
||||
ThreatIndicator.PreUpdate = NP.ThreatIndicator_PreUpdate
|
||||
ThreatIndicator.PostUpdate = NP.ThreatIndicator_PostUpdate
|
||||
|
||||
return ThreatIndicator
|
||||
end
|
||||
|
||||
function NP:Update_ThreatIndicator(nameplate)
|
||||
local db = NP.db.threat
|
||||
|
||||
if nameplate.frameType == 'ENEMY_NPC' and db.enable then
|
||||
if not nameplate:IsElementEnabled('ThreatIndicator') then
|
||||
nameplate:EnableElement('ThreatIndicator')
|
||||
end
|
||||
|
||||
if db.indicator then
|
||||
nameplate.ThreatIndicator:SetAlpha(1)
|
||||
else
|
||||
nameplate.ThreatIndicator:SetAlpha(0)
|
||||
end
|
||||
elseif nameplate:IsElementEnabled('ThreatIndicator') then
|
||||
nameplate:DisableElement('ThreatIndicator')
|
||||
end
|
||||
end
|
||||
143
Modules/Nameplates/Elements/WidgetContainer.lua
Normal file
143
Modules/Nameplates/Elements/WidgetContainer.lua
Normal file
@@ -0,0 +1,143 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
local ipairs = ipairs
|
||||
local CreateFrame = CreateFrame
|
||||
local UIWidgetSetLayoutDirection = Enum.UIWidgetSetLayoutDirection
|
||||
local UIWidgetLayoutDirection = Enum.UIWidgetLayoutDirection
|
||||
|
||||
function NP:Construct_WidgetContainer(nameplate)
|
||||
local WidgetContainer = CreateFrame('Frame', nil, nameplate, 'UIWidgetContainerNoResizeTemplate')
|
||||
WidgetContainer:Point('BOTTOM', nameplate, 'TOP')
|
||||
WidgetContainer:Hide()
|
||||
|
||||
return WidgetContainer
|
||||
end
|
||||
|
||||
function NP.Widget_DefaultLayout(widgetContainerFrame, sortedWidgets)
|
||||
local horizontalRowContainer = nil
|
||||
local horizontalRowHeight = 0
|
||||
local horizontalRowWidth = 0
|
||||
local totalWidth = 0
|
||||
local totalHeight = 0
|
||||
|
||||
widgetContainerFrame.horizontalRowContainerPool:ReleaseAll()
|
||||
|
||||
for index, widgetFrame in ipairs(sortedWidgets) do
|
||||
widgetFrame:ClearAllPoints()
|
||||
|
||||
if widgetFrame.Bar and not widgetFrame.Bar.backdrop then
|
||||
widgetFrame.Bar:CreateBackdrop('Transparent')
|
||||
end
|
||||
|
||||
local widgetSetUsesVertical = widgetContainerFrame.widgetSetLayoutDirection == UIWidgetSetLayoutDirection.Vertical
|
||||
local widgetUsesVertical = widgetFrame.layoutDirection == UIWidgetLayoutDirection.Vertical
|
||||
|
||||
local useOverlapLayout = widgetFrame.layoutDirection == UIWidgetLayoutDirection.Overlap
|
||||
local useVerticalLayout = widgetUsesVertical or (widgetFrame.layoutDirection == UIWidgetLayoutDirection.Default and widgetSetUsesVertical)
|
||||
|
||||
if useOverlapLayout then
|
||||
-- This widget uses overlap layout
|
||||
|
||||
if index == 1 then
|
||||
if widgetSetUsesVertical then
|
||||
widgetFrame:Point(widgetContainerFrame.verticalAnchorPoint, widgetContainerFrame)
|
||||
else
|
||||
widgetFrame:Point(widgetContainerFrame.horizontalAnchorPoint, widgetContainerFrame)
|
||||
end
|
||||
else
|
||||
local relative = sortedWidgets[index - 1]
|
||||
if widgetSetUsesVertical then
|
||||
widgetFrame:Point(widgetContainerFrame.verticalAnchorPoint, relative, widgetContainerFrame.verticalAnchorPoint, 0, 0)
|
||||
else
|
||||
widgetFrame:Point(widgetContainerFrame.horizontalAnchorPoint, relative, widgetContainerFrame.horizontalAnchorPoint, 0, 0)
|
||||
end
|
||||
end
|
||||
|
||||
local width, height = widgetFrame:GetSize()
|
||||
if width > totalWidth then
|
||||
totalWidth = width
|
||||
end
|
||||
if height > totalHeight then
|
||||
totalHeight = height
|
||||
end
|
||||
|
||||
widgetFrame:SetParent(widgetContainerFrame)
|
||||
elseif useVerticalLayout then
|
||||
if index == 1 then
|
||||
widgetFrame:Point(widgetContainerFrame.verticalAnchorPoint, widgetContainerFrame)
|
||||
else
|
||||
local relative = horizontalRowContainer or sortedWidgets[index - 1]
|
||||
widgetFrame:Point(widgetContainerFrame.verticalAnchorPoint, relative, widgetContainerFrame.verticalRelativePoint, 0, widgetContainerFrame.verticalAnchorYOffset)
|
||||
|
||||
if horizontalRowContainer then
|
||||
horizontalRowContainer:Size(horizontalRowWidth, horizontalRowHeight)
|
||||
totalWidth = totalWidth + horizontalRowWidth
|
||||
totalHeight = totalHeight + horizontalRowHeight
|
||||
horizontalRowHeight = 0
|
||||
horizontalRowWidth = 0
|
||||
horizontalRowContainer = nil
|
||||
end
|
||||
|
||||
totalHeight = totalHeight + widgetContainerFrame.verticalAnchorYOffset
|
||||
end
|
||||
|
||||
widgetFrame:SetParent(widgetContainerFrame)
|
||||
|
||||
local width, height = widgetFrame:GetSize()
|
||||
if width > totalWidth then
|
||||
totalWidth = width
|
||||
end
|
||||
totalHeight = totalHeight + height
|
||||
else
|
||||
local forceNewRow = widgetFrame.layoutDirection == UIWidgetLayoutDirection.HorizontalForceNewRow
|
||||
local needNewRowContainer = not horizontalRowContainer or forceNewRow
|
||||
if needNewRowContainer then
|
||||
if horizontalRowContainer then
|
||||
--horizontalRowContainer:Layout()
|
||||
horizontalRowContainer:Size(horizontalRowWidth, horizontalRowHeight)
|
||||
totalWidth = totalWidth + horizontalRowWidth
|
||||
totalHeight = totalHeight + horizontalRowHeight
|
||||
horizontalRowHeight = 0
|
||||
horizontalRowWidth = 0
|
||||
end
|
||||
|
||||
local newHorizontalRowContainer = widgetContainerFrame.horizontalRowContainerPool:Acquire()
|
||||
newHorizontalRowContainer:Show()
|
||||
|
||||
if index == 1 then
|
||||
newHorizontalRowContainer:Point(widgetContainerFrame.verticalAnchorPoint, widgetContainerFrame, widgetContainerFrame.verticalAnchorPoint)
|
||||
else
|
||||
local relative = horizontalRowContainer or sortedWidgets[index - 1]
|
||||
newHorizontalRowContainer:Point(widgetContainerFrame.verticalAnchorPoint, relative, widgetContainerFrame.verticalRelativePoint, 0, widgetContainerFrame.verticalAnchorYOffset)
|
||||
|
||||
totalHeight = totalHeight + widgetContainerFrame.verticalAnchorYOffset
|
||||
end
|
||||
widgetFrame:Point('TOPLEFT', newHorizontalRowContainer)
|
||||
widgetFrame:SetParent(newHorizontalRowContainer)
|
||||
|
||||
horizontalRowWidth = horizontalRowWidth + widgetFrame:GetWidth()
|
||||
horizontalRowContainer = newHorizontalRowContainer
|
||||
else
|
||||
local relative = sortedWidgets[index - 1]
|
||||
widgetFrame:SetParent(horizontalRowContainer)
|
||||
widgetFrame:Point(widgetContainerFrame.horizontalAnchorPoint, relative, widgetContainerFrame.horizontalRelativePoint, widgetContainerFrame.horizontalAnchorXOffset, 0)
|
||||
|
||||
horizontalRowWidth = horizontalRowWidth + widgetFrame:GetWidth() + widgetContainerFrame.horizontalAnchorXOffset
|
||||
end
|
||||
|
||||
local widgetHeight = widgetFrame:GetHeight()
|
||||
if widgetHeight > horizontalRowHeight then
|
||||
horizontalRowHeight = widgetHeight
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if horizontalRowContainer then
|
||||
horizontalRowContainer:Size(horizontalRowWidth, horizontalRowHeight)
|
||||
totalWidth = totalWidth + horizontalRowWidth
|
||||
totalHeight = totalHeight + horizontalRowHeight
|
||||
end
|
||||
|
||||
widgetContainerFrame:Size(totalWidth, totalHeight)
|
||||
end
|
||||
21
Modules/Nameplates/Load_Nameplates.xml
Normal file
21
Modules/Nameplates/Load_Nameplates.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<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\ClassPower.lua'/>
|
||||
<Script file='Elements\Health.lua'/>
|
||||
<Script file='Elements\Plugins.lua'/>
|
||||
<Script file='Elements\Power.lua'/>
|
||||
<Script file='Elements\Portraits.lua'/>
|
||||
<Script file='Elements\PvP.lua'/>
|
||||
<Script file='Elements\RaidTargetIndicator.lua'/>
|
||||
<Script file='Elements\Tags.lua'/>
|
||||
<Script file='Elements\Threat.lua'/>
|
||||
<Script file='Elements\WidgetContainer.lua'/>
|
||||
<Script file='Plugins\ClassificationIndicator.lua'/>
|
||||
<Script file='Plugins\PVPRole.lua'/>
|
||||
<Script file='Plugins\Highlight.lua'/>
|
||||
<Script file='Plugins\QuestIcons.lua'/>
|
||||
<Script file='Plugins\TargetIndicator.lua'/>
|
||||
</Ui>
|
||||
859
Modules/Nameplates/Nameplates.lua
Normal file
859
Modules/Nameplates/Nameplates.lua
Normal file
@@ -0,0 +1,859 @@
|
||||
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 ElvUF = E.oUF
|
||||
assert(ElvUF, 'ElvUI was unable to locate oUF.')
|
||||
|
||||
local _G = _G
|
||||
local pairs, ipairs, wipe, tinsert = pairs, ipairs, wipe, tinsert
|
||||
local format, select, strsplit, tostring = format, select, strsplit, tostring
|
||||
|
||||
local CreateFrame = CreateFrame
|
||||
local GetCVar = GetCVar
|
||||
local GetCVarDefault = GetCVarDefault
|
||||
local GetInstanceInfo = GetInstanceInfo
|
||||
local GetNumGroupMembers = GetNumGroupMembers
|
||||
local GetNumSubgroupMembers = GetNumSubgroupMembers
|
||||
local InCombatLockdown = InCombatLockdown
|
||||
local IsInGroup, IsInRaid = IsInGroup, IsInRaid
|
||||
local SetCVar = SetCVar
|
||||
local UnitClass = UnitClass
|
||||
local UnitClassification = UnitClassification
|
||||
local UnitCreatureType = UnitCreatureType
|
||||
local UnitExists = UnitExists
|
||||
local UnitFactionGroup = UnitFactionGroup
|
||||
local UnitGroupRolesAssigned = UnitGroupRolesAssigned
|
||||
local UnitGUID = UnitGUID
|
||||
local UnitIsEnemy = UnitIsEnemy
|
||||
local UnitIsFriend = UnitIsFriend
|
||||
local UnitIsPlayer = UnitIsPlayer
|
||||
local UnitIsPVPSanctuary = UnitIsPVPSanctuary
|
||||
local UnitIsUnit = UnitIsUnit
|
||||
local UnitName = UnitName
|
||||
local UnitReaction = UnitReaction
|
||||
local UnitWidgetSet = UnitWidgetSet
|
||||
local UnitSelectionType = UnitSelectionType
|
||||
local UnitThreatSituation = UnitThreatSituation
|
||||
local UnitNameplateShowsWidgetsOnly = UnitNameplateShowsWidgetsOnly
|
||||
local ShowBossFrameWhenUninteractable = ShowBossFrameWhenUninteractable
|
||||
local C_NamePlate_SetNamePlateEnemyClickThrough = C_NamePlate.SetNamePlateEnemyClickThrough
|
||||
local C_NamePlate_SetNamePlateEnemySize = C_NamePlate.SetNamePlateEnemySize
|
||||
local C_NamePlate_SetNamePlateFriendlyClickThrough = C_NamePlate.SetNamePlateFriendlyClickThrough
|
||||
local C_NamePlate_SetNamePlateFriendlySize = C_NamePlate.SetNamePlateFriendlySize
|
||||
local C_NamePlate_SetNamePlateSelfClickThrough = C_NamePlate.SetNamePlateSelfClickThrough
|
||||
local C_NamePlate_SetNamePlateSelfSize = C_NamePlate.SetNamePlateSelfSize
|
||||
local hooksecurefunc = hooksecurefunc
|
||||
|
||||
do -- credit: oUF/private.lua
|
||||
local selectionTypes = {[0]=0,[1]=1,[2]=2,[3]=3,[4]=4,[5]=5,[6]=6,[7]=7,[8]=8,[9]=9,[13]=13}
|
||||
-- 10 and 11 are unavailable to players, 12 is inconsistent due to bugs and its reliance on cvars
|
||||
|
||||
function NP:UnitExists(unit)
|
||||
return unit and UnitExists(unit) or ShowBossFrameWhenUninteractable(unit)
|
||||
end
|
||||
|
||||
function NP:UnitSelectionType(unit, considerHostile)
|
||||
if considerHostile and UnitThreatSituation('player', unit) then
|
||||
return 0
|
||||
else
|
||||
return selectionTypes[UnitSelectionType(unit, true)]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Blacklist = {
|
||||
PLAYER = {
|
||||
enable = true,
|
||||
health = {
|
||||
enable = true,
|
||||
},
|
||||
},
|
||||
ENEMY_PLAYER = {},
|
||||
FRIENDLY_PLAYER = {},
|
||||
ENEMY_NPC = {},
|
||||
FRIENDLY_NPC = {},
|
||||
}
|
||||
|
||||
function NP:ResetSettings(unit)
|
||||
E:CopyTable(NP.db.units[unit], P.nameplates.units[unit])
|
||||
end
|
||||
|
||||
function NP:CopySettings(from, to)
|
||||
if from == to then
|
||||
E:Print(L["You cannot copy settings from the same unit."])
|
||||
return
|
||||
end
|
||||
|
||||
E:CopyTable(NP.db.units[to], E:FilterTableFromBlacklist(NP.db.units[from], Blacklist[to]))
|
||||
end
|
||||
|
||||
do
|
||||
local empty = {}
|
||||
function NP:PlateDB(nameplate)
|
||||
return (nameplate and NP.db.units[nameplate.frameType]) or empty
|
||||
end
|
||||
end
|
||||
|
||||
function NP:SetCVar(cvar, value)
|
||||
if GetCVar(cvar) ~= tostring(value) then
|
||||
SetCVar(cvar, value)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:CVarReset()
|
||||
NP:SetCVar('nameplateMinAlpha', 1)
|
||||
NP:SetCVar('nameplateMaxAlpha', 1)
|
||||
NP:SetCVar('nameplateClassResourceTopInset', GetCVarDefault('nameplateClassResourceTopInset'))
|
||||
NP:SetCVar('nameplateGlobalScale', 1)
|
||||
NP:SetCVar('NamePlateHorizontalScale', 1)
|
||||
NP:SetCVar('nameplateLargeBottomInset', GetCVarDefault('nameplateLargeBottomInset'))
|
||||
NP:SetCVar('nameplateLargerScale', 1)
|
||||
NP:SetCVar('nameplateLargeTopInset', GetCVarDefault('nameplateLargeTopInset'))
|
||||
NP:SetCVar('nameplateMaxAlphaDistance', GetCVarDefault('nameplateMaxAlphaDistance'))
|
||||
NP:SetCVar('nameplateMaxScale', 1)
|
||||
NP:SetCVar('nameplateMaxScaleDistance', 40)
|
||||
NP:SetCVar('nameplateMinAlphaDistance', GetCVarDefault('nameplateMinAlphaDistance'))
|
||||
NP:SetCVar('nameplateMinScale', 1)
|
||||
NP:SetCVar('nameplateMinScaleDistance', 0)
|
||||
NP:SetCVar('nameplateMotionSpeed', GetCVarDefault('nameplateMotionSpeed'))
|
||||
NP:SetCVar('nameplateOccludedAlphaMult', GetCVarDefault('nameplateOccludedAlphaMult'))
|
||||
NP:SetCVar('nameplateOtherAtBase', GetCVarDefault('nameplateOtherAtBase'))
|
||||
NP:SetCVar('nameplateOverlapH', GetCVarDefault('nameplateOverlapH'))
|
||||
NP:SetCVar('nameplateOverlapV', GetCVarDefault('nameplateOverlapV'))
|
||||
NP:SetCVar('nameplateResourceOnTarget', GetCVarDefault('nameplateResourceOnTarget'))
|
||||
NP:SetCVar('nameplateSelectedAlpha', 1)
|
||||
NP:SetCVar('nameplateSelectedScale', 1)
|
||||
NP:SetCVar('nameplateSelfAlpha', 1)
|
||||
NP:SetCVar('nameplateSelfBottomInset', GetCVarDefault('nameplateSelfBottomInset'))
|
||||
NP:SetCVar('nameplateSelfScale', 1)
|
||||
NP:SetCVar('nameplateSelfTopInset', GetCVarDefault('nameplateSelfTopInset'))
|
||||
NP:SetCVar('nameplateTargetBehindMaxDistance', 40)
|
||||
end
|
||||
|
||||
function NP:SetCVars()
|
||||
if NP.db.units.ENEMY_NPC.questIcon.enable or NP.db.units.FRIENDLY_NPC.questIcon.enable then
|
||||
NP:SetCVar('showQuestTrackingTooltips', 1)
|
||||
end
|
||||
|
||||
if NP.db.clampToScreen then
|
||||
NP:SetCVar('nameplateOtherTopInset', 0.08)
|
||||
NP:SetCVar('nameplateOtherBottomInset', 0.1)
|
||||
elseif GetCVar('nameplateOtherTopInset') == '0.08' and GetCVar('nameplateOtherBottomInset') == '0.1' then
|
||||
NP:SetCVar('nameplateOtherTopInset', -1)
|
||||
NP:SetCVar('nameplateOtherBottomInset', -1)
|
||||
end
|
||||
|
||||
NP:SetCVar('nameplateMotion', NP.db.motionType == 'STACKED' and 1 or 0)
|
||||
|
||||
NP:SetCVar('NameplatePersonalShowAlways', NP.db.units.PLAYER.visibility.showAlways and 1 or 0)
|
||||
NP:SetCVar('NameplatePersonalShowInCombat', NP.db.units.PLAYER.visibility.showInCombat and 1 or 0)
|
||||
NP:SetCVar('NameplatePersonalShowWithTarget', NP.db.units.PLAYER.visibility.showWithTarget and 1 or 0)
|
||||
NP:SetCVar('NameplatePersonalHideDelayAlpha', NP.db.units.PLAYER.visibility.alphaDelay)
|
||||
NP:SetCVar('NameplatePersonalHideDelaySeconds', NP.db.units.PLAYER.visibility.hideDelay)
|
||||
|
||||
-- the order of these is important !!
|
||||
NP:SetCVar('nameplateShowAll', NP.db.visibility.showAll and 1 or 0)
|
||||
NP:SetCVar('nameplateShowSelf', (NP.db.units.PLAYER.useStaticPosition or not NP.db.units.PLAYER.enable) and 0 or 1)
|
||||
NP:SetCVar('nameplateShowEnemyMinions', NP.db.visibility.enemy.minions and 1 or 0)
|
||||
NP:SetCVar('nameplateShowEnemyGuardians', NP.db.visibility.enemy.guardians and 1 or 0)
|
||||
NP:SetCVar('nameplateShowEnemyMinus', NP.db.visibility.enemy.minus and 1 or 0)
|
||||
NP:SetCVar('nameplateShowEnemyPets', NP.db.visibility.enemy.pets and 1 or 0)
|
||||
NP:SetCVar('nameplateShowEnemyTotems', NP.db.visibility.enemy.totems and 1 or 0)
|
||||
NP:SetCVar('nameplateShowFriendlyMinions', NP.db.visibility.friendly.minions and 1 or 0)
|
||||
NP:SetCVar('nameplateShowFriendlyGuardians', NP.db.visibility.friendly.guardians and 1 or 0)
|
||||
NP:SetCVar('nameplateShowFriendlyNPCs', NP.db.visibility.friendly.npcs and 1 or 0)
|
||||
NP:SetCVar('nameplateShowFriendlyPets', NP.db.visibility.friendly.pets and 1 or 0)
|
||||
NP:SetCVar('nameplateShowFriendlyTotems', NP.db.visibility.friendly.totems and 1 or 0)
|
||||
end
|
||||
|
||||
function NP:PLAYER_REGEN_DISABLED()
|
||||
if NP.db.showFriendlyCombat == 'TOGGLE_ON' then
|
||||
NP:SetCVar('nameplateShowFriends', 1)
|
||||
elseif NP.db.showFriendlyCombat == 'TOGGLE_OFF' then
|
||||
NP:SetCVar('nameplateShowFriends', 0)
|
||||
end
|
||||
|
||||
if NP.db.showEnemyCombat == 'TOGGLE_ON' then
|
||||
NP:SetCVar('nameplateShowEnemies', 1)
|
||||
elseif NP.db.showEnemyCombat == 'TOGGLE_OFF' then
|
||||
NP:SetCVar('nameplateShowEnemies', 0)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:PLAYER_REGEN_ENABLED()
|
||||
if NP.db.showFriendlyCombat == 'TOGGLE_ON' then
|
||||
NP:SetCVar('nameplateShowFriends', 0)
|
||||
elseif NP.db.showFriendlyCombat == 'TOGGLE_OFF' then
|
||||
NP:SetCVar('nameplateShowFriends', 1)
|
||||
end
|
||||
|
||||
if NP.db.showEnemyCombat == 'TOGGLE_ON' then
|
||||
NP:SetCVar('nameplateShowEnemies', 0)
|
||||
elseif NP.db.showEnemyCombat == 'TOGGLE_OFF' then
|
||||
NP:SetCVar('nameplateShowEnemies', 1)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:Style(frame, unit)
|
||||
frame.isNamePlate = true
|
||||
|
||||
if frame:GetName() == 'ElvNP_TargetClassPower' then
|
||||
NP:StyleTargetPlate(frame, unit)
|
||||
else
|
||||
NP:StylePlate(frame, unit)
|
||||
end
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
function NP:Construct_RaisedELement(nameplate)
|
||||
local RaisedElement = CreateFrame('Frame', nameplate:GetName() .. 'RaisedElement', nameplate)
|
||||
RaisedElement:SetFrameStrata(nameplate:GetFrameStrata())
|
||||
RaisedElement:SetFrameLevel(10)
|
||||
RaisedElement:SetAllPoints()
|
||||
RaisedElement:EnableMouse(false)
|
||||
|
||||
return RaisedElement
|
||||
end
|
||||
|
||||
function NP:StyleTargetPlate(nameplate)
|
||||
nameplate:ClearAllPoints()
|
||||
nameplate:Point('CENTER')
|
||||
nameplate:Size(NP.db.plateSize.personalWidth, NP.db.plateSize.personalHeight)
|
||||
nameplate:SetScale(E.global.general.UIScale)
|
||||
|
||||
nameplate.RaisedElement = NP:Construct_RaisedELement(nameplate)
|
||||
nameplate.ClassPower = NP:Construct_ClassPower(nameplate)
|
||||
|
||||
if E.myclass == 'DEATHKNIGHT' then
|
||||
nameplate.Runes = NP:Construct_Runes(nameplate)
|
||||
elseif E.myclass == 'MONK' then
|
||||
nameplate.Stagger = NP:Construct_Stagger(nameplate)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:UpdateTargetPlate(nameplate)
|
||||
NP:Update_ClassPower(nameplate)
|
||||
|
||||
if E.myclass == 'DEATHKNIGHT' then
|
||||
NP:Update_Runes(nameplate)
|
||||
elseif E.myclass == 'MONK' then
|
||||
NP:Update_Stagger(nameplate)
|
||||
end
|
||||
|
||||
nameplate:UpdateAllElements('OnShow')
|
||||
end
|
||||
|
||||
function NP:ScalePlate(nameplate, scale, targetPlate)
|
||||
local mult = (nameplate == _G.ElvNP_Player or nameplate == _G.ElvNP_Test) and 1 or E.global.general.UIScale
|
||||
if targetPlate and NP.targetPlate then
|
||||
NP.targetPlate:SetScale(mult)
|
||||
NP.targetPlate = nil
|
||||
end
|
||||
|
||||
if not nameplate then
|
||||
return
|
||||
end
|
||||
|
||||
local targetScale = format('%.2f', mult * scale)
|
||||
nameplate:SetScale(targetScale)
|
||||
|
||||
if targetPlate then
|
||||
NP.targetPlate = nameplate
|
||||
end
|
||||
end
|
||||
|
||||
function NP:StylePlate(nameplate)
|
||||
nameplate:ClearAllPoints()
|
||||
nameplate:Point('CENTER')
|
||||
nameplate:SetScale(E.global.general.UIScale)
|
||||
|
||||
nameplate.StyleFilterChanges = {}
|
||||
|
||||
nameplate.RaisedElement = NP:Construct_RaisedELement(nameplate)
|
||||
nameplate.Health = NP:Construct_Health(nameplate)
|
||||
nameplate.Health.Text = NP:Construct_TagText(nameplate.RaisedElement)
|
||||
nameplate.Health.Text.frequentUpdates = .1
|
||||
nameplate.HealthPrediction = NP:Construct_HealthPrediction(nameplate)
|
||||
nameplate.Power = NP:Construct_Power(nameplate)
|
||||
nameplate.Power.Text = NP:Construct_TagText(nameplate.RaisedElement)
|
||||
nameplate.Name = NP:Construct_TagText(nameplate.RaisedElement)
|
||||
nameplate.Level = NP:Construct_TagText(nameplate.RaisedElement)
|
||||
nameplate.Title = NP:Construct_TagText(nameplate.RaisedElement)
|
||||
nameplate.ClassificationIndicator = NP:Construct_ClassificationIndicator(nameplate.RaisedElement)
|
||||
nameplate.Castbar = NP:Construct_Castbar(nameplate)
|
||||
nameplate.Portrait = NP:Construct_Portrait(nameplate.RaisedElement)
|
||||
nameplate.QuestIcons = NP:Construct_QuestIcons(nameplate.RaisedElement)
|
||||
nameplate.RaidTargetIndicator = NP:Construct_RaidTargetIndicator(nameplate.RaisedElement)
|
||||
nameplate.TargetIndicator = NP:Construct_TargetIndicator(nameplate)
|
||||
nameplate.ThreatIndicator = NP:Construct_ThreatIndicator(nameplate.RaisedElement)
|
||||
nameplate.Highlight = NP:Construct_Highlight(nameplate)
|
||||
nameplate.ClassPower = NP:Construct_ClassPower(nameplate)
|
||||
nameplate.PvPIndicator = NP:Construct_PvPIndicator(nameplate.RaisedElement) -- Horde / Alliance / HonorInfo
|
||||
nameplate.PvPClassificationIndicator = NP:Construct_PvPClassificationIndicator(nameplate.RaisedElement) -- Cart / Flag / Orb / Assassin Bounty
|
||||
nameplate.PVPRole = NP:Construct_PVPRole(nameplate.RaisedElement)
|
||||
nameplate.Cutaway = NP:Construct_Cutaway(nameplate)
|
||||
nameplate.WidgetContainer = NP:Construct_WidgetContainer(nameplate)
|
||||
|
||||
NP:Construct_Auras(nameplate)
|
||||
|
||||
if E.myclass == 'DEATHKNIGHT' then
|
||||
nameplate.Runes = NP:Construct_Runes(nameplate)
|
||||
elseif E.myclass == 'MONK' then
|
||||
nameplate.Stagger = NP:Construct_Stagger(nameplate)
|
||||
end
|
||||
|
||||
NP.Plates[nameplate] = nameplate:GetName()
|
||||
end
|
||||
|
||||
function NP:UpdatePlate(nameplate, updateBase)
|
||||
NP:Update_RaidTargetIndicator(nameplate)
|
||||
NP:Update_PVPRole(nameplate)
|
||||
NP:Update_Portrait(nameplate)
|
||||
NP:Update_QuestIcons(nameplate)
|
||||
|
||||
local db = NP:PlateDB(nameplate)
|
||||
local sf = NP:StyleFilterChanges(nameplate)
|
||||
if not db.enable then
|
||||
NP:DisablePlate(nameplate)
|
||||
|
||||
if nameplate.RaisedElement:IsShown() then
|
||||
nameplate.RaisedElement:Hide()
|
||||
end
|
||||
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
nameplate.Castbar:SetAlpha(0)
|
||||
nameplate.ClassPower:SetAlpha(0)
|
||||
end
|
||||
elseif sf.Visibility or sf.NameOnly or db.nameOnly then
|
||||
NP:DisablePlate(nameplate, sf.NameOnly or (db.nameOnly and not sf.Visibility))
|
||||
|
||||
if nameplate == _G.ElvNP_Test then
|
||||
nameplate.Castbar:SetAlpha(0)
|
||||
nameplate.ClassPower:SetAlpha(0)
|
||||
end
|
||||
elseif updateBase then
|
||||
NP:Update_Tags(nameplate)
|
||||
NP:Update_Health(nameplate)
|
||||
NP:Update_HealthPrediction(nameplate)
|
||||
NP:Update_Highlight(nameplate)
|
||||
NP:Update_Power(nameplate)
|
||||
NP:Update_Castbar(nameplate)
|
||||
NP:Update_ClassPower(nameplate)
|
||||
NP:Update_Auras(nameplate)
|
||||
NP:Update_ClassificationIndicator(nameplate)
|
||||
NP:Update_PvPIndicator(nameplate) -- Horde / Alliance / HonorInfo
|
||||
NP:Update_PvPClassificationIndicator(nameplate) -- Cart / Flag / Orb / Assassin Bounty
|
||||
NP:Update_TargetIndicator(nameplate)
|
||||
NP:Update_ThreatIndicator(nameplate)
|
||||
NP:Update_Cutaway(nameplate)
|
||||
|
||||
if E.myclass == 'DEATHKNIGHT' then
|
||||
NP:Update_Runes(nameplate)
|
||||
elseif E.myclass == 'MONK' then
|
||||
NP:Update_Stagger(nameplate)
|
||||
end
|
||||
|
||||
if nameplate == _G.ElvNP_Player then
|
||||
NP:Update_Fader(nameplate)
|
||||
end
|
||||
else
|
||||
NP:Update_Health(nameplate, true) -- this will only reset the ouf vars so it won't hold stale threat ones
|
||||
end
|
||||
|
||||
if nameplate.isTarget and nameplate ~= _G.ElvNP_Test then
|
||||
NP:SetupTarget(nameplate, nil, true)
|
||||
end
|
||||
|
||||
NP:StyleFilterEvents(nameplate)
|
||||
end
|
||||
|
||||
NP.DisableInNotNameOnly = {
|
||||
'QuestIcons',
|
||||
'Highlight',
|
||||
'Portrait',
|
||||
'PVPRole'
|
||||
}
|
||||
|
||||
NP.DisableElements = {
|
||||
'Health',
|
||||
'HealthPrediction',
|
||||
'Power',
|
||||
'ClassificationIndicator',
|
||||
'Castbar',
|
||||
'ThreatIndicator',
|
||||
'TargetIndicator',
|
||||
'ClassPower',
|
||||
'PvPIndicator',
|
||||
'PvPClassificationIndicator',
|
||||
'Auras'
|
||||
}
|
||||
|
||||
if E.myclass == 'DEATHKNIGHT' then
|
||||
tinsert(NP.DisableElements, 'Runes')
|
||||
elseif E.myclass == 'MONK' then
|
||||
tinsert(NP.DisableElements, 'Stagger')
|
||||
end
|
||||
|
||||
function NP:DisablePlate(nameplate, nameOnly)
|
||||
for _, element in ipairs(NP.DisableElements) do
|
||||
if nameplate:IsElementEnabled(element) then
|
||||
nameplate:DisableElement(element)
|
||||
end
|
||||
end
|
||||
|
||||
if nameOnly then
|
||||
NP:Update_Tags(nameplate)
|
||||
NP:Update_Highlight(nameplate)
|
||||
|
||||
-- The position values here are forced on purpose.
|
||||
nameplate.Name:ClearAllPoints()
|
||||
nameplate.Name:Point('CENTER', nameplate, 'CENTER', 0, 0)
|
||||
|
||||
nameplate.RaidTargetIndicator:ClearAllPoints()
|
||||
nameplate.RaidTargetIndicator:Point('BOTTOM', nameplate, 'TOP', 0, 0)
|
||||
|
||||
nameplate.Portrait:ClearAllPoints()
|
||||
nameplate.Portrait:Point('RIGHT', nameplate.Name, 'LEFT', -6, 0)
|
||||
|
||||
nameplate.PVPRole:ClearAllPoints()
|
||||
nameplate.PVPRole:Point('RIGHT', (nameplate.Portrait:IsShown() and nameplate.Portrait) or nameplate.Name, 'LEFT', -6, 0)
|
||||
|
||||
nameplate.QuestIcons:ClearAllPoints()
|
||||
nameplate.QuestIcons:Point('LEFT', nameplate.Name, 'RIGHT', 6, 0)
|
||||
|
||||
nameplate.Title:ClearAllPoints()
|
||||
nameplate.Title:Point('TOP', nameplate.Name, 'BOTTOM', 0, -2)
|
||||
else
|
||||
for _, element in ipairs(NP.DisableInNotNameOnly) do
|
||||
if nameplate:IsElementEnabled(element) then
|
||||
nameplate:DisableElement(element)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:SetupTarget(nameplate, removed)
|
||||
if not NP.db.units then return end
|
||||
|
||||
local TCP = _G.ElvNP_TargetClassPower
|
||||
local cp = NP.db.units.TARGET.classpower
|
||||
|
||||
local db = NP:PlateDB(nameplate)
|
||||
local sf = NP:StyleFilterChanges(nameplate)
|
||||
|
||||
TCP.realPlate = (cp.enable and not (removed or sf.NameOnly or db.nameOnly) and nameplate) or nil
|
||||
|
||||
local moveToPlate = TCP.realPlate or TCP
|
||||
|
||||
if TCP.ClassPower then
|
||||
TCP.ClassPower:SetParent(moveToPlate)
|
||||
TCP.ClassPower:ClearAllPoints()
|
||||
TCP.ClassPower:Point('CENTER', moveToPlate, 'CENTER', cp.xOffset, cp.yOffset)
|
||||
end
|
||||
if TCP.Runes then
|
||||
TCP.Runes:SetParent(moveToPlate)
|
||||
TCP.Runes:ClearAllPoints()
|
||||
TCP.Runes:Point('CENTER', moveToPlate, 'CENTER', cp.xOffset, cp.yOffset)
|
||||
end
|
||||
if TCP.Stagger then
|
||||
TCP.Stagger:SetParent(moveToPlate)
|
||||
TCP.Stagger:ClearAllPoints()
|
||||
TCP.Stagger:Point('CENTER', moveToPlate, 'CENTER', cp.xOffset, cp.yOffset)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:SetNamePlateClickThrough()
|
||||
if InCombatLockdown() then return end
|
||||
|
||||
self:SetNamePlateSelfClickThrough()
|
||||
self:SetNamePlateFriendlyClickThrough()
|
||||
self:SetNamePlateEnemyClickThrough()
|
||||
end
|
||||
|
||||
function NP:SetNamePlateSelfClickThrough()
|
||||
C_NamePlate_SetNamePlateSelfClickThrough(NP.db.clickThrough.personal)
|
||||
_G.ElvNP_StaticSecure:EnableMouse(not NP.db.clickThrough.personal)
|
||||
end
|
||||
|
||||
function NP:SetNamePlateFriendlyClickThrough()
|
||||
C_NamePlate_SetNamePlateFriendlyClickThrough(NP.db.clickThrough.friendly)
|
||||
end
|
||||
|
||||
function NP:SetNamePlateEnemyClickThrough()
|
||||
C_NamePlate_SetNamePlateEnemyClickThrough(NP.db.clickThrough.enemy)
|
||||
end
|
||||
|
||||
function NP:Update_StatusBars()
|
||||
for bar in pairs(NP.StatusBars) do
|
||||
local sf = NP:StyleFilterChanges(bar:GetParent())
|
||||
if not sf.HealthTexture then
|
||||
bar:SetStatusBarTexture(LSM:Fetch('statusbar', NP.db.statusbar) or E.media.normTex)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:GROUP_ROSTER_UPDATE()
|
||||
local isInRaid = IsInRaid()
|
||||
NP.IsInGroup = isInRaid or IsInGroup()
|
||||
|
||||
wipe(NP.GroupRoles)
|
||||
|
||||
if NP.IsInGroup then
|
||||
local Unit = (isInRaid and 'raid') or 'party'
|
||||
for i = 1, ((isInRaid and GetNumGroupMembers()) or GetNumSubgroupMembers()) do
|
||||
if UnitExists(Unit .. i) then
|
||||
NP.GroupRoles[UnitName(Unit .. i)] = UnitGroupRolesAssigned(Unit .. i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function NP:GROUP_LEFT()
|
||||
NP.IsInGroup = IsInRaid() or IsInGroup()
|
||||
wipe(NP.GroupRoles)
|
||||
end
|
||||
|
||||
function NP:PLAYER_ENTERING_WORLD(_, initLogin, isReload)
|
||||
NP.InstanceType = select(2, GetInstanceInfo())
|
||||
|
||||
if initLogin or isReload then
|
||||
NP:ConfigureAll(true)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:ConfigureAll(skipUpdate)
|
||||
if E.private.nameplates.enable ~= true then return end
|
||||
NP:StyleFilterConfigure() -- keep this at the top
|
||||
NP:SetNamePlateClickThrough()
|
||||
NP:SetNamePlateSizes()
|
||||
NP:PLAYER_REGEN_ENABLED()
|
||||
NP:UpdateTargetPlate(_G.ElvNP_TargetClassPower)
|
||||
NP:Update_StatusBars()
|
||||
|
||||
local playerEnabled = NP.db.units.PLAYER.enable
|
||||
local isStatic = NP.db.units.PLAYER.useStaticPosition
|
||||
|
||||
if playerEnabled and isStatic then
|
||||
E:EnableMover('ElvNP_PlayerMover')
|
||||
_G.ElvNP_Player:Enable()
|
||||
_G.ElvNP_StaticSecure:Show()
|
||||
else
|
||||
NP:DisablePlate(_G.ElvNP_Player)
|
||||
E:DisableMover('ElvNP_PlayerMover')
|
||||
_G.ElvNP_Player:Disable()
|
||||
_G.ElvNP_StaticSecure:Hide()
|
||||
end
|
||||
|
||||
NP:SetCVar('nameplateShowSelf', (isStatic or not playerEnabled) and 0 or 1)
|
||||
|
||||
NP.SkipFading = true
|
||||
|
||||
if _G.ElvNP_Test:IsEnabled() then
|
||||
NP:NamePlateCallBack(_G.ElvNP_Test, 'NAME_PLATE_UNIT_ADDED')
|
||||
end
|
||||
|
||||
if skipUpdate then -- since this is a fake plate, we actually need to trigger this always
|
||||
NP:NamePlateCallBack(_G.ElvNP_Player, (isStatic and playerEnabled) and 'NAME_PLATE_UNIT_ADDED' or 'NAME_PLATE_UNIT_REMOVED', 'player')
|
||||
_G.ElvNP_Player:UpdateAllElements('ForceUpdate')
|
||||
else -- however, these only need to happen when changing options
|
||||
for nameplate in pairs(NP.Plates) do
|
||||
if nameplate.frameType == 'PLAYER' then
|
||||
nameplate:Size(NP.db.plateSize.personalWidth, NP.db.plateSize.personalHeight)
|
||||
elseif nameplate.frameType == 'FRIENDLY_PLAYER' or nameplate.frameType == 'FRIENDLY_NPC' then
|
||||
nameplate:Size(NP.db.plateSize.friendlyWidth, NP.db.plateSize.friendlyHeight)
|
||||
else
|
||||
nameplate:Size(NP.db.plateSize.enemyWidth, NP.db.plateSize.enemyHeight)
|
||||
end
|
||||
|
||||
if nameplate == _G.ElvNP_Player then
|
||||
NP:NamePlateCallBack(_G.ElvNP_Player, (isStatic and playerEnabled) and 'NAME_PLATE_UNIT_ADDED' or 'NAME_PLATE_UNIT_REMOVED', 'player')
|
||||
else
|
||||
nameplate.previousType = nil -- we still need a full update
|
||||
NP:NamePlateCallBack(nameplate, 'NAME_PLATE_UNIT_ADDED')
|
||||
end
|
||||
|
||||
nameplate:UpdateAllElements('ForceUpdate')
|
||||
end
|
||||
end
|
||||
|
||||
NP.SkipFading = nil
|
||||
end
|
||||
|
||||
function NP:PlateFade(nameplate, timeToFade, startAlpha, endAlpha)
|
||||
-- we need our own function because we want a smooth transition and dont want it to force update every pass.
|
||||
-- its controlled by fadeTimer which is reset when UIFrameFadeOut or UIFrameFadeIn code runs.
|
||||
|
||||
if not nameplate.FadeObject then
|
||||
nameplate.FadeObject = {}
|
||||
end
|
||||
|
||||
nameplate.FadeObject.timeToFade = (nameplate.isTarget and 0) or timeToFade
|
||||
nameplate.FadeObject.startAlpha = startAlpha
|
||||
nameplate.FadeObject.endAlpha = endAlpha
|
||||
nameplate.FadeObject.diffAlpha = endAlpha - startAlpha
|
||||
|
||||
if nameplate.FadeObject.fadeTimer then
|
||||
nameplate.FadeObject.fadeTimer = 0
|
||||
else
|
||||
E:UIFrameFade(nameplate, nameplate.FadeObject)
|
||||
end
|
||||
end
|
||||
|
||||
function NP:UpdatePlateGUID(nameplate, guid)
|
||||
NP.PlateGUID[nameplate.unitGUID] = (guid and nameplate) or nil
|
||||
end
|
||||
|
||||
function NP:NamePlateCallBack(nameplate, event, unit)
|
||||
if event == 'NAME_PLATE_UNIT_ADDED' or (event == 'UNIT_FACTION' and nameplate) then
|
||||
local updateBase = NP:StyleFilterClear(nameplate) -- keep this at the top
|
||||
|
||||
unit = unit or nameplate.unit
|
||||
|
||||
nameplate.blizzPlate = nameplate:GetParent().UnitFrame
|
||||
nameplate.className, nameplate.classFile, nameplate.classID = UnitClass(unit)
|
||||
nameplate.widgetsOnly = UnitNameplateShowsWidgetsOnly(unit)
|
||||
nameplate.widgetSet = UnitWidgetSet(unit)
|
||||
nameplate.classification = UnitClassification(unit)
|
||||
nameplate.creatureType = UnitCreatureType(unit)
|
||||
nameplate.isMe = UnitIsUnit(unit, 'player')
|
||||
nameplate.isPet = UnitIsUnit(unit, 'pet')
|
||||
nameplate.isFriend = UnitIsFriend('player', unit)
|
||||
nameplate.isEnemy = UnitIsEnemy('player', unit)
|
||||
nameplate.isPlayer = UnitIsPlayer(unit)
|
||||
nameplate.isPVPSanctuary = UnitIsPVPSanctuary(unit)
|
||||
nameplate.faction = UnitFactionGroup(unit)
|
||||
nameplate.reaction = UnitReaction('player', unit)
|
||||
nameplate.repReaction = UnitReaction(unit, 'player')
|
||||
nameplate.unitGUID = UnitGUID(unit)
|
||||
nameplate.unitName = UnitName(unit)
|
||||
nameplate.npcID = nameplate.unitGUID and select(6, strsplit('-', nameplate.unitGUID))
|
||||
|
||||
if nameplate.unitGUID then
|
||||
NP:UpdatePlateGUID(nameplate, nameplate.unitGUID)
|
||||
end
|
||||
|
||||
NP:StyleFilterSetVariables(nameplate) -- sets: isTarget, isTargetingMe, isFocused
|
||||
|
||||
if nameplate ~= _G.ElvNP_Test then
|
||||
if nameplate.isMe then
|
||||
nameplate.frameType = 'PLAYER'
|
||||
|
||||
if NP.db.units.PLAYER.enable then
|
||||
NP.PlayerNamePlateAnchor:ClearAllPoints()
|
||||
NP.PlayerNamePlateAnchor:SetParent(NP.db.units.PLAYER.useStaticPosition and _G.ElvNP_Player or nameplate)
|
||||
NP.PlayerNamePlateAnchor:SetAllPoints(NP.db.units.PLAYER.useStaticPosition and _G.ElvNP_Player or nameplate)
|
||||
NP.PlayerNamePlateAnchor:Show()
|
||||
end
|
||||
elseif nameplate.isPVPSanctuary then
|
||||
nameplate.frameType = 'FRIENDLY_PLAYER'
|
||||
elseif not nameplate.isEnemy and (not nameplate.reaction or nameplate.reaction > 4) then -- keep as: not isEnemy, dont switch to isFriend
|
||||
nameplate.frameType = (nameplate.isPlayer and 'FRIENDLY_PLAYER') or 'FRIENDLY_NPC'
|
||||
else
|
||||
nameplate.frameType = (nameplate.isPlayer and 'ENEMY_PLAYER') or 'ENEMY_NPC'
|
||||
end
|
||||
end
|
||||
|
||||
if nameplate.frameType == 'PLAYER' then
|
||||
nameplate.width, nameplate.height = NP.db.plateSize.personalWidth, NP.db.plateSize.personalHeight
|
||||
elseif nameplate.frameType == 'FRIENDLY_PLAYER' or nameplate.frameType == 'FRIENDLY_NPC' then
|
||||
nameplate.width, nameplate.height = NP.db.plateSize.friendlyWidth, NP.db.plateSize.friendlyHeight
|
||||
else
|
||||
nameplate.width, nameplate.height = NP.db.plateSize.enemyWidth, NP.db.plateSize.enemyHeight
|
||||
end
|
||||
|
||||
nameplate:Size(nameplate.width, nameplate.height)
|
||||
|
||||
if nameplate.widgetsOnly then
|
||||
NP:DisablePlate(nameplate)
|
||||
|
||||
if nameplate.RaisedElement:IsShown() then
|
||||
nameplate.RaisedElement:Hide()
|
||||
end
|
||||
else
|
||||
if not nameplate.RaisedElement:IsShown() then
|
||||
nameplate.RaisedElement:Show()
|
||||
end
|
||||
|
||||
if nameplate == _G.ElvNP_Player or nameplate == _G.ElvNP_Test then
|
||||
NP:UpdatePlate(nameplate, true)
|
||||
else
|
||||
NP:UpdatePlate(nameplate, updateBase or (nameplate.frameType ~= nameplate.previousType))
|
||||
nameplate.previousType = nameplate.frameType
|
||||
end
|
||||
end
|
||||
|
||||
if NP.db.fadeIn and (event == 'NAME_PLATE_UNIT_ADDED' and nameplate.frameType ~= 'PLAYER') and not NP.SkipFading then
|
||||
NP:PlateFade(nameplate, 1, 0, 1)
|
||||
end
|
||||
|
||||
nameplate.WidgetContainer:RegisterForWidgetSet(nameplate.widgetSet, NP.Widget_DefaultLayout, nil, unit)
|
||||
|
||||
NP:StyleFilterUpdate(nameplate, event) -- keep this at the end
|
||||
elseif event == 'NAME_PLATE_UNIT_REMOVED' then
|
||||
if nameplate ~= _G.ElvNP_Test then
|
||||
if nameplate.frameType == 'PLAYER' then
|
||||
NP.PlayerNamePlateAnchor:Hide()
|
||||
end
|
||||
|
||||
if nameplate.isTarget then
|
||||
NP:SetupTarget(nameplate, true)
|
||||
NP:ScalePlate(nameplate, 1, true)
|
||||
end
|
||||
end
|
||||
|
||||
if nameplate.unitGUID then
|
||||
NP:UpdatePlateGUID(nameplate)
|
||||
end
|
||||
|
||||
-- vars that we need to keep in a nonstale state
|
||||
nameplate.Health.cur = nil -- cutaway
|
||||
nameplate.Power.cur = nil -- cutaway
|
||||
nameplate.npcID = nil -- just cause
|
||||
|
||||
nameplate.WidgetContainer:UnregisterForWidgetSet()
|
||||
|
||||
NP:StyleFilterClearVariables(nameplate) -- keep this at the end
|
||||
elseif event == 'PLAYER_TARGET_CHANGED' then -- we need to check if nameplate exists in here
|
||||
NP:SetupTarget(nameplate) -- pass it, even as nil here
|
||||
end
|
||||
end
|
||||
|
||||
local optionsTable = {
|
||||
'EnemyMinus',
|
||||
'EnemyMinions',
|
||||
'FriendlyMinions',
|
||||
'PersonalResource',
|
||||
'PersonalResourceOnEnemy',
|
||||
'MotionDropDown',
|
||||
'ShowAll'
|
||||
}
|
||||
|
||||
function NP:HideInterfaceOptions()
|
||||
for _, x in pairs(optionsTable) do
|
||||
local o = _G['InterfaceOptionsNamesPanelUnitNameplates' .. x]
|
||||
o:SetSize(0.0001, 0.0001)
|
||||
o:SetAlpha(0)
|
||||
o:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function NP:SetNamePlateSizes()
|
||||
if InCombatLockdown() then return end
|
||||
|
||||
local scale = E.global.general.UIScale
|
||||
C_NamePlate_SetNamePlateSelfSize(NP.db.plateSize.personalWidth * scale, NP.db.plateSize.personalHeight * scale)
|
||||
C_NamePlate_SetNamePlateEnemySize(NP.db.plateSize.enemyWidth * scale, NP.db.plateSize.enemyHeight * scale)
|
||||
C_NamePlate_SetNamePlateFriendlySize(NP.db.plateSize.friendlyWidth * scale, NP.db.plateSize.friendlyHeight * scale)
|
||||
end
|
||||
|
||||
function NP:Initialize()
|
||||
NP.db = E.db.nameplates
|
||||
|
||||
if E.private.nameplates.enable ~= true then return end
|
||||
NP.Initialized = true
|
||||
|
||||
NP.thinBorders = NP.db.thinBorders
|
||||
NP.SPACING = (NP.thinBorders or E.twoPixelsPlease) and 0 or 1
|
||||
NP.BORDER = (NP.thinBorders and not E.twoPixelsPlease) and 1 or 2
|
||||
|
||||
ElvUF:RegisterStyle('ElvNP', function(frame, unit) NP:Style(frame, unit) end)
|
||||
ElvUF:SetActiveStyle('ElvNP')
|
||||
|
||||
NP.Plates = {}
|
||||
NP.PlateGUID = {}
|
||||
NP.StatusBars = {}
|
||||
NP.GroupRoles = {}
|
||||
NP.multiplier = 0.35
|
||||
|
||||
local BlizzPlateManaBar = _G.NamePlateDriverFrame.classNamePlatePowerBar
|
||||
if BlizzPlateManaBar then
|
||||
BlizzPlateManaBar:Hide()
|
||||
BlizzPlateManaBar:UnregisterAllEvents()
|
||||
end
|
||||
|
||||
hooksecurefunc(_G.NamePlateDriverFrame, 'UpdateNamePlateOptions', NP.SetNamePlateSizes)
|
||||
hooksecurefunc(_G.NamePlateDriverFrame, 'SetupClassNameplateBars', function(frame)
|
||||
if not frame or frame:IsForbidden() then
|
||||
return
|
||||
end
|
||||
if frame.classNamePlateMechanicFrame then
|
||||
frame.classNamePlateMechanicFrame:Hide()
|
||||
end
|
||||
if frame.classNamePlatePowerBar then
|
||||
frame.classNamePlatePowerBar:Hide()
|
||||
frame.classNamePlatePowerBar:UnregisterAllEvents()
|
||||
end
|
||||
end)
|
||||
|
||||
ElvUF:Spawn('player', 'ElvNP_Player', '')
|
||||
|
||||
_G.ElvNP_Player:ClearAllPoints()
|
||||
_G.ElvNP_Player:Point('TOP', _G.UIParent, 'CENTER', 0, -150)
|
||||
_G.ElvNP_Player:Size(NP.db.plateSize.personalWidth, NP.db.plateSize.personalHeight)
|
||||
_G.ElvNP_Player:SetScale(1)
|
||||
_G.ElvNP_Player.frameType = 'PLAYER'
|
||||
|
||||
E:CreateMover(_G.ElvNP_Player, 'ElvNP_PlayerMover', L["Player NamePlate"], nil, nil, nil, 'ALL,SOLO', nil, 'nameplate,playerGroup')
|
||||
|
||||
local StaticSecure = CreateFrame('Button', 'ElvNP_StaticSecure', _G.UIParent, 'SecureUnitButtonTemplate')
|
||||
StaticSecure:SetAttribute('unit', 'player')
|
||||
StaticSecure:SetAttribute('*type1', 'target')
|
||||
StaticSecure:SetAttribute('*type2', 'togglemenu')
|
||||
StaticSecure:SetAttribute('toggleForVehicle', true)
|
||||
StaticSecure:RegisterForClicks('LeftButtonDown', 'RightButtonDown')
|
||||
StaticSecure:SetScript('OnEnter', _G.UnitFrame_OnEnter)
|
||||
StaticSecure:SetScript('OnLeave', _G.UnitFrame_OnLeave)
|
||||
StaticSecure:ClearAllPoints()
|
||||
StaticSecure:Point('BOTTOMRIGHT', _G.ElvNP_PlayerMover)
|
||||
StaticSecure:Point('TOPLEFT', _G.ElvNP_PlayerMover)
|
||||
StaticSecure:Hide()
|
||||
StaticSecure.unit = 'player' -- Needed for OnEnter, OnLeave
|
||||
|
||||
ElvUF:Spawn('player', 'ElvNP_Test')
|
||||
|
||||
_G.ElvNP_Test:ClearAllPoints()
|
||||
_G.ElvNP_Test:Point('BOTTOM', _G.UIParent, 'BOTTOM', 0, 250)
|
||||
_G.ElvNP_Test:Size(NP.db.plateSize.personalWidth, NP.db.plateSize.personalHeight)
|
||||
_G.ElvNP_Test:SetScale(1)
|
||||
_G.ElvNP_Test:SetMovable(true)
|
||||
_G.ElvNP_Test:RegisterForDrag('LeftButton', 'RightButton')
|
||||
_G.ElvNP_Test:SetScript('OnDragStart', function() _G.ElvNP_Test:StartMoving() end)
|
||||
_G.ElvNP_Test:SetScript('OnDragStop', function() _G.ElvNP_Test:StopMovingOrSizing() end)
|
||||
_G.ElvNP_Test.frameType = 'PLAYER'
|
||||
_G.ElvNP_Test:Disable()
|
||||
NP:DisablePlate(_G.ElvNP_Test)
|
||||
|
||||
ElvUF:Spawn('player', 'ElvNP_TargetClassPower')
|
||||
|
||||
_G.ElvNP_TargetClassPower:SetScale(1)
|
||||
_G.ElvNP_TargetClassPower:Size(NP.db.plateSize.personalWidth, NP.db.plateSize.personalHeight)
|
||||
_G.ElvNP_TargetClassPower.frameType = 'TARGET'
|
||||
_G.ElvNP_TargetClassPower:SetAttribute('toggleForVehicle', true)
|
||||
_G.ElvNP_TargetClassPower:ClearAllPoints()
|
||||
_G.ElvNP_TargetClassPower:Point('TOP', E.UIParent, 'BOTTOM', 0, -500)
|
||||
|
||||
NP.PlayerNamePlateAnchor = CreateFrame('Frame', 'ElvUIPlayerNamePlateAnchor', E.UIParent)
|
||||
NP.PlayerNamePlateAnchor:EnableMouse(false)
|
||||
NP.PlayerNamePlateAnchor:Hide()
|
||||
|
||||
ElvUF:SpawnNamePlates('ElvNP_', function(nameplate, event, unit)
|
||||
NP:NamePlateCallBack(nameplate, event, unit)
|
||||
end)
|
||||
|
||||
NP:RegisterEvent('PLAYER_REGEN_ENABLED')
|
||||
NP:RegisterEvent('PLAYER_REGEN_DISABLED')
|
||||
NP:RegisterEvent('PLAYER_ENTERING_WORLD')
|
||||
NP:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED')
|
||||
NP:RegisterEvent('GROUP_ROSTER_UPDATE')
|
||||
NP:RegisterEvent('GROUP_LEFT')
|
||||
NP:RegisterEvent('PLAYER_LOGOUT')
|
||||
|
||||
NP:StyleFilterInitialize()
|
||||
NP:HideInterfaceOptions()
|
||||
NP:GROUP_ROSTER_UPDATE()
|
||||
NP:SetCVars()
|
||||
end
|
||||
|
||||
E:RegisterModule(NP:GetName())
|
||||
60
Modules/Nameplates/Plugins/ClassificationIndicator.lua
Normal file
60
Modules/Nameplates/Plugins/ClassificationIndicator.lua
Normal file
@@ -0,0 +1,60 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local oUF = E.oUF
|
||||
|
||||
local function Update(self)
|
||||
local element = self.ClassificationIndicator
|
||||
|
||||
if element.PreUpdate then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
local classification = self.classification
|
||||
if classification == 'elite' or classification == 'worldboss' then
|
||||
element:SetAtlas('nameplates-icon-elite-gold')
|
||||
element:Show()
|
||||
elseif classification == 'rareelite' or classification == 'rare' then
|
||||
element:SetAtlas('nameplates-icon-elite-silver')
|
||||
element:Show()
|
||||
else
|
||||
element:Hide()
|
||||
end
|
||||
|
||||
if element.PostUpdate then
|
||||
return element:PostUpdate(classification)
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
return (self.ClassificationIndicator.Override or Update) (self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
local element = self.ClassificationIndicator
|
||||
if element then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
|
||||
if element:IsObjectType('Texture') and not element:GetTexture() then
|
||||
element:SetTexture([[Interface\TARGETINGFRAME\Nameplates]])
|
||||
end
|
||||
|
||||
self:RegisterEvent('UNIT_CLASSIFICATION_CHANGED', Path)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
local element = self.ClassificationIndicator
|
||||
if element then
|
||||
element:Hide()
|
||||
|
||||
self:UnregisterEvent('UNIT_CLASSIFICATION_CHANGED', Path)
|
||||
end
|
||||
end
|
||||
|
||||
oUF:AddElement('ClassificationIndicator', Path, Enable, Disable)
|
||||
77
Modules/Nameplates/Plugins/Highlight.lua
Normal file
77
Modules/Nameplates/Plugins/Highlight.lua
Normal file
@@ -0,0 +1,77 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local oUF = E.oUF
|
||||
|
||||
local UnitExists = UnitExists
|
||||
local UnitIsUnit = UnitIsUnit
|
||||
|
||||
local function MouseOnUnit(frame)
|
||||
if frame and frame:IsVisible() and UnitExists('mouseover') then
|
||||
return frame.unit and UnitIsUnit('mouseover', frame.unit)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function OnUpdate(self, elapsed)
|
||||
if self.elapsed and self.elapsed > 0.1 then
|
||||
if not MouseOnUnit(self) then
|
||||
self:Hide()
|
||||
self:ForceUpdate()
|
||||
end
|
||||
|
||||
self.elapsed = 0
|
||||
else
|
||||
self.elapsed = (self.elapsed or 0) + elapsed
|
||||
end
|
||||
end
|
||||
|
||||
local function Update(self)
|
||||
local element = self.Highlight
|
||||
|
||||
if element.PreUpdate then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
if MouseOnUnit(self) then
|
||||
element:Show()
|
||||
else
|
||||
element:Hide()
|
||||
end
|
||||
|
||||
if element.PostUpdate then
|
||||
return element:PostUpdate(element:IsShown())
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
return (self.Highlight.Override or Update)(self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
local element = self.Highlight
|
||||
if element then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
element:SetScript('OnUpdate', OnUpdate)
|
||||
|
||||
self:RegisterEvent('UPDATE_MOUSEOVER_UNIT', Path, true)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
local element = self.Highlight
|
||||
if element then
|
||||
element:Hide()
|
||||
element:SetScript('OnUpdate', nil)
|
||||
|
||||
self:UnregisterEvent('UPDATE_MOUSEOVER_UNIT', Path)
|
||||
end
|
||||
end
|
||||
|
||||
oUF:AddElement('Highlight', Path, Enable, Disable)
|
||||
176
Modules/Nameplates/Plugins/PVPRole.lua
Normal file
176
Modules/Nameplates/Plugins/PVPRole.lua
Normal file
@@ -0,0 +1,176 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local oUF = E.oUF
|
||||
|
||||
local wipe = wipe
|
||||
local format = format
|
||||
local GetArenaOpponentSpec = GetArenaOpponentSpec
|
||||
local GetBattlefieldScore = GetBattlefieldScore
|
||||
local GetInstanceInfo = GetInstanceInfo
|
||||
local GetNumArenaOpponentSpecs = GetNumArenaOpponentSpecs
|
||||
local GetNumBattlefieldScores = GetNumBattlefieldScores
|
||||
local GetSpecializationInfoByID = GetSpecializationInfoByID
|
||||
local UnitName = UnitName
|
||||
local UNKNOWN = UNKNOWN
|
||||
|
||||
local healerSpecIDs = {
|
||||
65, --Paladin Holy
|
||||
105, --Druid Restoration
|
||||
256, --Priest Discipline
|
||||
257, --Priest Holy
|
||||
264, --Shaman Restoration
|
||||
270, --Monk Mistweaver
|
||||
}
|
||||
|
||||
local tankSpecIDs = {
|
||||
66, --Paladin Protection
|
||||
581, --Demon Hunter Vengeance
|
||||
104, --Druid Guardian
|
||||
268, --Monk Brewmaster
|
||||
73, --Warrior Protection
|
||||
250, --Death Knight Blood
|
||||
}
|
||||
|
||||
local Healers, HealerSpecs = {}, {}
|
||||
local Tanks, TankSpecs = {}, {}
|
||||
|
||||
for _, specID in pairs(healerSpecIDs) do
|
||||
local _, name = GetSpecializationInfoByID(specID)
|
||||
if name and not HealerSpecs[name] then
|
||||
HealerSpecs[name] = true
|
||||
end
|
||||
end
|
||||
|
||||
for _, specID in pairs(tankSpecIDs) do
|
||||
local _, name = GetSpecializationInfoByID(specID)
|
||||
if name and not TankSpecs[name] then
|
||||
TankSpecs[name] = true
|
||||
end
|
||||
end
|
||||
|
||||
local function WipeTable()
|
||||
wipe(Healers)
|
||||
wipe(Tanks)
|
||||
end
|
||||
|
||||
local function Event()
|
||||
local _, instanceType = GetInstanceInfo()
|
||||
if instanceType == 'pvp' or instanceType == 'arena' then
|
||||
local numOpps = GetNumArenaOpponentSpecs()
|
||||
if numOpps == 0 then
|
||||
for i = 1, GetNumBattlefieldScores() do
|
||||
local name, _, _, _, _, _, _, _, _, _, _, _, _, _, _, talentSpec = GetBattlefieldScore(i)
|
||||
name = name and name ~= UNKNOWN and E:StripMyRealm(name)
|
||||
if name then
|
||||
if HealerSpecs[talentSpec] then
|
||||
Healers[name] = talentSpec
|
||||
elseif Healers[name] then
|
||||
Healers[name] = nil;
|
||||
end
|
||||
if TankSpecs[talentSpec] then
|
||||
Tanks[name] = talentSpec
|
||||
elseif Tanks[name] then
|
||||
Tanks[name] = nil;
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif numOpps >= 1 then
|
||||
for i = 1, numOpps do
|
||||
local name, realm = UnitName(format('arena%d', i))
|
||||
if name and name ~= UNKNOWN then
|
||||
realm = (realm and realm ~= '') and E:ShortenRealm(realm)
|
||||
if realm then name = name..'-'..realm end
|
||||
|
||||
local s = GetArenaOpponentSpec(i)
|
||||
local _, talentSpec = nil, UNKNOWN
|
||||
|
||||
if s and s > 0 then
|
||||
_, talentSpec = GetSpecializationInfoByID(s)
|
||||
end
|
||||
|
||||
if talentSpec and talentSpec ~= UNKNOWN then
|
||||
if HealerSpecs[talentSpec] then
|
||||
Healers[name] = talentSpec
|
||||
end
|
||||
|
||||
if TankSpecs[talentSpec] then
|
||||
Tanks[name] = talentSpec
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Update(self)
|
||||
local element, isShown = self.PVPRole
|
||||
|
||||
if element.PreUpdate then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
local _, instanceType = GetInstanceInfo()
|
||||
if instanceType == 'pvp' or instanceType == 'arena' then
|
||||
local name, realm = UnitName(self.unit)
|
||||
realm = (realm and realm ~= '') and E:ShortenRealm(realm)
|
||||
if realm then name = name..'-'..realm end
|
||||
|
||||
if Healers[name] and element.ShowHealers then
|
||||
element:SetTexture(element.HealerTexture)
|
||||
isShown = true
|
||||
elseif Tanks[name] and element.ShowTanks then
|
||||
element:SetTexture(element.TankTexture)
|
||||
isShown = true
|
||||
end
|
||||
end
|
||||
|
||||
element:SetShown(isShown)
|
||||
|
||||
if element.PostUpdate then
|
||||
return element:PostUpdate(instanceType)
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
return (self.PVPRole.Override or Update) (self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
local element = self.PVPRole
|
||||
if element then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
|
||||
if not element.HealerTexture then element.HealerTexture = E.Media.Textures.Healer end
|
||||
if not element.TankTexture then element.TankTexture = E.Media.Textures.Tank end
|
||||
|
||||
self:RegisterEvent('UNIT_TARGET', Path)
|
||||
self:RegisterEvent('PLAYER_TARGET_CHANGED', Path, true)
|
||||
self:RegisterEvent('UNIT_NAME_UPDATE', Path)
|
||||
self:RegisterEvent('ARENA_OPPONENT_UPDATE', Event, true)
|
||||
self:RegisterEvent('UPDATE_BATTLEFIELD_SCORE', Event, true)
|
||||
self:RegisterEvent('PLAYER_ENTERING_WORLD', WipeTable, true)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
local element = self.PVPRole
|
||||
if element then
|
||||
element:Hide()
|
||||
|
||||
self:UnregisterEvent('UNIT_NAME_UPDATE', Path)
|
||||
self:UnregisterEvent('ARENA_OPPONENT_UPDATE', Event)
|
||||
self:UnregisterEvent('UPDATE_BATTLEFIELD_SCORE', Event)
|
||||
self:UnregisterEvent('UNIT_TARGET', Path)
|
||||
self:UnregisterEvent('PLAYER_TARGET_CHANGED', Path)
|
||||
self:UnregisterEvent('PLAYER_ENTERING_WORLD', WipeTable)
|
||||
end
|
||||
end
|
||||
|
||||
oUF:AddElement('PVPRole', Path, Enable, Disable)
|
||||
313
Modules/Nameplates/Plugins/QuestIcons.lua
Normal file
313
Modules/Nameplates/Plugins/QuestIcons.lua
Normal file
@@ -0,0 +1,313 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local oUF = E.oUF
|
||||
|
||||
local _G = _G
|
||||
local pairs, ipairs, ceil, floor, tonumber = pairs, ipairs, ceil, floor, tonumber
|
||||
local wipe, strmatch, strlower, strfind = wipe, strmatch, strlower, strfind
|
||||
|
||||
local GetLocale = GetLocale
|
||||
local IsInInstance = IsInInstance
|
||||
local UnitIsPlayer = UnitIsPlayer
|
||||
local GetQuestLogSpecialItemInfo = GetQuestLogSpecialItemInfo
|
||||
local C_QuestLog_GetTitleForLogIndex = C_QuestLog.GetTitleForLogIndex
|
||||
local C_QuestLog_GetNumQuestLogEntries = C_QuestLog.GetNumQuestLogEntries
|
||||
local C_QuestLog_GetQuestIDForLogIndex = C_QuestLog.GetQuestIDForLogIndex
|
||||
local ThreatTooltip = THREAT_TOOLTIP:gsub('%%d', '%%d-')
|
||||
|
||||
local questIcons = {
|
||||
iconTypes = { 'Default', 'Item', 'Skull', 'Chat' },
|
||||
indexByID = {}, --[questID] = questIndex
|
||||
activeQuests = {} --[questTitle] = questID
|
||||
}
|
||||
|
||||
NP.QuestIcons = questIcons
|
||||
|
||||
local typesLocalized = {
|
||||
enUS = {
|
||||
--- short matching applies here so,
|
||||
-- kill: killed, destory: destoryed, etc ...
|
||||
KILL = {'slain', 'destroy', 'eliminate', 'repel', 'kill', 'defeat'},
|
||||
CHAT = {'speak', 'talk'}
|
||||
},
|
||||
deDE = {
|
||||
KILL = {'besiegen', 'besiegt', 'getötet', 'töten', 'tötet', 'vernichtet', 'zerstört', 'genährt'},
|
||||
CHAT = {'befragt', 'sprecht'}
|
||||
},
|
||||
ruRU = {
|
||||
KILL = {'убит', 'уничтож', 'разбомблен', 'разбит', 'сразит'},
|
||||
CHAT = {'поговорит', 'спрашивать'}
|
||||
},
|
||||
esMX = {
|
||||
-- asesinad: asesinado, asesinados, asesinada, asesinadas
|
||||
-- derrota: derrotar, derrotado, derrotados, derrotada, derrotadas
|
||||
-- destrui: destruir, destruido, destruidos, destruida, destruidas
|
||||
-- elimin: eliminar, elimine, eliminadas, eliminada, eliminados, eliminado
|
||||
-- repel: repele, repelido, repelidos, repelida, repelidas
|
||||
KILL = {'asesinad', 'destrui', 'elimin', 'repel', 'derrota'},
|
||||
CHAT = {'habla', 'pídele'}
|
||||
},
|
||||
ptBR = {
|
||||
-- destrui: above but also destruição
|
||||
-- repel: repelir, repelido, repelidos, repelida, repelidas
|
||||
KILL = {'morto', 'morta', 'matar', 'destrui', 'elimin', 'repel', 'derrota'},
|
||||
CHAT = {'falar', 'pedir'}
|
||||
},
|
||||
frFR = {
|
||||
-- tué: tués, tuée, tuées
|
||||
-- abattu: abattus, abattue
|
||||
-- détrui: détruite, détruire, détruit, détruits, détruites
|
||||
-- repouss: repousser, repoussés, repoussée, repoussées
|
||||
-- élimin: éliminer, éliminé, éliminés, éliminée, éliminées
|
||||
KILL = {'tué', 'tuer', 'attaqué', 'attaque', 'abattre', 'abattu', 'détrui', 'élimin', 'repouss', 'vaincu', 'vaincre'},
|
||||
-- demande: demander, demandez
|
||||
-- parle: parler, parlez
|
||||
CHAT = {'parle', 'demande'}
|
||||
},
|
||||
koKR = {
|
||||
KILL = {'쓰러뜨리기', '물리치기', '공격', '파괴'},
|
||||
CHAT = {'대화'}
|
||||
},
|
||||
zhCN = {
|
||||
KILL = {'消灭', '摧毁', '击败', '毁灭', '击退'},
|
||||
CHAT = {'交谈', '谈一谈'}
|
||||
},
|
||||
zhTW = {
|
||||
KILL = {'毀滅', '擊退', '殺死'},
|
||||
CHAT = {'交談', '說話'}
|
||||
},
|
||||
}
|
||||
|
||||
local questTypes = typesLocalized[GetLocale()] or typesLocalized.enUS
|
||||
|
||||
local function CheckTextForQuest(text)
|
||||
local x, y = strmatch(text, '(%d+)/(%d+)')
|
||||
if x and y then
|
||||
return floor(y - x)
|
||||
elseif not strmatch(text, ThreatTooltip) then
|
||||
local progress = tonumber(strmatch(text, '([%d%.]+)%%'))
|
||||
if progress and progress <= 100 then
|
||||
return ceil(100 - progress), true
|
||||
end
|
||||
end
|
||||
end
|
||||
NP.QuestIcons.CheckTextForQuest = CheckTextForQuest
|
||||
|
||||
local function GetQuests(unitID)
|
||||
if IsInInstance() then return end
|
||||
|
||||
E.ScanTooltip:SetOwner(_G.UIParent, 'ANCHOR_NONE')
|
||||
E.ScanTooltip:SetUnit(unitID)
|
||||
E.ScanTooltip:Show()
|
||||
|
||||
local QuestList, notMyQuest, activeID
|
||||
for i = 3, E.ScanTooltip:NumLines() do
|
||||
local str = _G['ElvUI_ScanTooltipTextLeft' .. i]
|
||||
local text = str and str:GetText()
|
||||
if not text or text == '' then return end
|
||||
|
||||
if UnitIsPlayer(text) then
|
||||
notMyQuest = text ~= E.myname
|
||||
elseif text and not notMyQuest then
|
||||
local count, percent = CheckTextForQuest(text)
|
||||
|
||||
-- this line comes from one line up in the tooltip
|
||||
local activeQuest = questIcons.activeQuests[text]
|
||||
if activeQuest then activeID = activeQuest end
|
||||
|
||||
if count then
|
||||
local type, index, texture, _
|
||||
if activeID then
|
||||
index = questIcons.indexByID[activeID]
|
||||
_, texture = GetQuestLogSpecialItemInfo(index)
|
||||
end
|
||||
|
||||
if texture then
|
||||
type = 'QUEST_ITEM'
|
||||
else
|
||||
local lowerText = strlower(text)
|
||||
|
||||
-- check kill type first
|
||||
for _, listText in ipairs(questTypes.KILL) do
|
||||
if strfind(lowerText, listText, nil, true) then
|
||||
type = 'KILL'
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- check chat type if kill type doesn't exist
|
||||
if not type then
|
||||
for _, listText in ipairs(questTypes.CHAT) do
|
||||
if strfind(lowerText, listText, nil, true) then
|
||||
type = 'CHAT'
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not QuestList then QuestList = {} end
|
||||
QuestList[#QuestList + 1] = {
|
||||
isPercent = percent,
|
||||
itemTexture = texture,
|
||||
objectiveCount = count,
|
||||
questType = type or 'DEFAULT',
|
||||
-- below keys are currently unused
|
||||
questLogIndex = index,
|
||||
questID = activeID
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
E.ScanTooltip:Hide()
|
||||
return QuestList
|
||||
end
|
||||
|
||||
local function hideIcons(element)
|
||||
for _, object in pairs(questIcons.iconTypes) do
|
||||
local icon = element[object]
|
||||
icon:Hide()
|
||||
|
||||
if icon.Text then
|
||||
icon.Text:SetText('')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Update(self, event, arg1)
|
||||
local element = self.QuestIcons
|
||||
if not element then return end
|
||||
|
||||
local unit = (event == 'UNIT_NAME_UPDATE' and arg1) or self.unit
|
||||
if unit ~= self.unit then return end
|
||||
|
||||
if element.PreUpdate then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
hideIcons(element)
|
||||
|
||||
local QuestList = GetQuests(unit)
|
||||
if QuestList then
|
||||
element:Show()
|
||||
else
|
||||
element:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
local shownCount
|
||||
for i = 1, #QuestList do
|
||||
local quest = QuestList[i]
|
||||
local objectiveCount = quest.objectiveCount
|
||||
local questType = quest.questType
|
||||
local isPercent = quest.isPercent
|
||||
|
||||
if isPercent or objectiveCount > 0 then
|
||||
local icon
|
||||
if questType == 'DEFAULT' then
|
||||
icon = element.Default
|
||||
elseif questType == 'KILL' then
|
||||
icon = element.Skull
|
||||
elseif questType == 'CHAT' then
|
||||
icon = element.Chat
|
||||
elseif questType == 'QUEST_ITEM' then
|
||||
icon = element.Item
|
||||
end
|
||||
|
||||
if icon and not icon:IsShown() then
|
||||
shownCount = (shownCount and shownCount + 1) or 0
|
||||
|
||||
local size = icon.size or 25
|
||||
local setPosition = icon.position or 'TOPLEFT'
|
||||
local newPosition = E.InversePoints[setPosition]
|
||||
local offset = shownCount * (5 + size)
|
||||
|
||||
icon:Show()
|
||||
icon:ClearAllPoints()
|
||||
icon:Point(newPosition, element, newPosition, (strmatch(setPosition, 'LEFT') and -offset) or offset, 0)
|
||||
|
||||
if questType ~= 'CHAT' and icon.Text and (isPercent or objectiveCount > 1) then
|
||||
icon.Text:SetText((isPercent and objectiveCount..'%') or objectiveCount)
|
||||
end
|
||||
|
||||
if questType == 'QUEST_ITEM' then
|
||||
element.Item:SetTexture(quest.itemTexture)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if element.PostUpdate then
|
||||
return element:PostUpdate()
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
return (self.QuestIcons.Override or Update) (self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
local element = self.QuestIcons
|
||||
if element then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
|
||||
if element.Default:IsObjectType('Texture') and not element.Default:GetAtlas() then
|
||||
element.Default:SetAtlas('SmallQuestBang')
|
||||
end
|
||||
if element.Skull:IsObjectType('Texture') and not element.Skull:GetTexture() then
|
||||
element.Skull:SetTexture(E.Media.Textures.SkullIcon)
|
||||
end
|
||||
if element.Chat:IsObjectType('StatusBar') and not element.Chat:GetTexture() then
|
||||
element.Chat:SetTexture([[Interface\WorldMap\ChatBubble_64.PNG]])
|
||||
end
|
||||
|
||||
self:RegisterEvent('QUEST_LOG_UPDATE', Path, true)
|
||||
self:RegisterEvent('UNIT_NAME_UPDATE', Path, true)
|
||||
self:RegisterEvent('PLAYER_ENTERING_WORLD', Path, true)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
local element = self.QuestIcons
|
||||
if element then
|
||||
element:Hide()
|
||||
hideIcons(element)
|
||||
|
||||
self:UnregisterEvent('QUEST_LOG_UPDATE', Path)
|
||||
self:UnregisterEvent('UNIT_NAME_UPDATE', Path)
|
||||
self:UnregisterEvent('PLAYER_ENTERING_WORLD', Path)
|
||||
end
|
||||
end
|
||||
|
||||
local frame = CreateFrame('Frame')
|
||||
frame:RegisterEvent('QUEST_ACCEPTED')
|
||||
frame:RegisterEvent('QUEST_REMOVED')
|
||||
frame:RegisterEvent('PLAYER_ENTERING_WORLD')
|
||||
frame:SetScript('OnEvent', function(self, event)
|
||||
wipe(questIcons.indexByID)
|
||||
wipe(questIcons.activeQuests)
|
||||
|
||||
for i = 1, C_QuestLog_GetNumQuestLogEntries() do
|
||||
local id = C_QuestLog_GetQuestIDForLogIndex(i)
|
||||
if id and id > 0 then
|
||||
questIcons.indexByID[id] = i
|
||||
|
||||
local title = C_QuestLog_GetTitleForLogIndex(i)
|
||||
if title then questIcons.activeQuests[title] = id end
|
||||
end
|
||||
end
|
||||
|
||||
if event == 'PLAYER_ENTERING_WORLD' then
|
||||
self:UnregisterEvent(event)
|
||||
end
|
||||
end)
|
||||
|
||||
oUF:AddElement('QuestIcons', Path, Enable, Disable)
|
||||
167
Modules/Nameplates/Plugins/TargetIndicator.lua
Normal file
167
Modules/Nameplates/Plugins/TargetIndicator.lua
Normal file
@@ -0,0 +1,167 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule('NamePlates')
|
||||
|
||||
local UnitHealth = UnitHealth
|
||||
local UnitIsUnit = UnitIsUnit
|
||||
local UnitHealthMax = UnitHealthMax
|
||||
|
||||
--[[ Target Glow Style Option Variables
|
||||
style1:'Border',
|
||||
style2:'Background',
|
||||
style3:'Top Arrow Only',
|
||||
style4:'Side Arrows Only',
|
||||
style5:'Border + Top Arrow',
|
||||
style6:'Background + Top Arrow',
|
||||
style7:'Border + Side Arrows',
|
||||
style8:'Background + Side Arrows'
|
||||
]]
|
||||
|
||||
local _, ns = ...
|
||||
local oUF = ns.oUF
|
||||
|
||||
local function Update(self)
|
||||
local element = self.TargetIndicator
|
||||
|
||||
if element.PreUpdate then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
if element.TopIndicator then element.TopIndicator:Hide() end
|
||||
if element.LeftIndicator then element.LeftIndicator:Hide() end
|
||||
if element.RightIndicator then element.RightIndicator:Hide() end
|
||||
if element.Shadow then element.Shadow:Hide() end
|
||||
if element.Spark then element.Spark:Hide() end
|
||||
|
||||
if UnitIsUnit(self.unit, 'target') and (element.style ~= 'none') then
|
||||
if element.TopIndicator and (element.style == 'style3' or element.style == 'style5' or element.style == 'style6') then
|
||||
element.TopIndicator:Show()
|
||||
end
|
||||
|
||||
if element.LeftIndicator and element.RightIndicator and (element.style == 'style4' or element.style == 'style7' or element.style == 'style8') then
|
||||
element.RightIndicator:Show()
|
||||
element.LeftIndicator:Show()
|
||||
end
|
||||
|
||||
if element.Shadow and (element.style == 'style1' or element.style == 'style5' or element.style == 'style7') then
|
||||
element.Shadow:Show()
|
||||
end
|
||||
|
||||
if element.Spark and (element.style == 'style2' or element.style == 'style6' or element.style == 'style8') then
|
||||
element.Spark:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local r, g, b
|
||||
local showIndicator
|
||||
if UnitIsUnit(self.unit, 'target') then
|
||||
showIndicator = true
|
||||
r, g, b = NP.db.colors.glowColor.r, NP.db.colors.glowColor.g, NP.db.colors.glowColor.b
|
||||
elseif not UnitIsUnit(self.unit, 'target') and element.lowHealthThreshold > 0 then
|
||||
local health, maxHealth = UnitHealth(self.unit), UnitHealthMax(self.unit)
|
||||
local perc = (maxHealth > 0 and health/maxHealth) or 0
|
||||
|
||||
if perc <= element.lowHealthThreshold then
|
||||
showIndicator = true
|
||||
if perc <= element.lowHealthThreshold / 2 then
|
||||
r, g, b = 1, 0, 0
|
||||
else
|
||||
r, g, b = 1, 1, 0
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if showIndicator then
|
||||
if element.TopIndicator and (element.style == 'style3' or element.style == 'style5' or element.style == 'style6') then
|
||||
element.TopIndicator:SetVertexColor(r, g, b)
|
||||
element.TopIndicator:SetTexture(element.arrow)
|
||||
end
|
||||
|
||||
if element.LeftIndicator and element.RightIndicator and (element.style == 'style4' or element.style == 'style7' or element.style == 'style8') then
|
||||
element.LeftIndicator:SetVertexColor(r, g, b)
|
||||
element.RightIndicator:SetVertexColor(r, g, b)
|
||||
element.LeftIndicator:SetTexture(element.arrow)
|
||||
element.RightIndicator:SetTexture(element.arrow)
|
||||
end
|
||||
|
||||
if element.Shadow and (element.style == 'style1' or element.style == 'style5' or element.style == 'style7') then
|
||||
element.Shadow:Show()
|
||||
element.Shadow:SetBackdropBorderColor(r, g, b)
|
||||
end
|
||||
|
||||
if element.Spark and (element.style == 'style2' or element.style == 'style6' or element.style == 'style8') then
|
||||
element.Spark:Show()
|
||||
element.Spark:SetVertexColor(r, g, b)
|
||||
end
|
||||
end
|
||||
|
||||
if element.PostUpdate then
|
||||
return element:PostUpdate(self.unit)
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
return (self.TargetIndicator.Override or Update) (self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
local element = self.TargetIndicator
|
||||
if element then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
|
||||
if not element.style then
|
||||
element.style = 'style1'
|
||||
end
|
||||
|
||||
if not element.lowHealthThreshold then
|
||||
element.lowHealthThreshold = .4
|
||||
end
|
||||
|
||||
if element.Shadow and element.Shadow:IsObjectType('Frame') and not element.Shadow:GetBackdrop() then
|
||||
element.Shadow:SetBackdrop({edgeFile = E.Media.Textures.GlowTex, edgeSize = E:Scale(5)})
|
||||
end
|
||||
|
||||
if element.Spark and element.Spark:IsObjectType('Texture') and not element.Spark:GetTexture() then
|
||||
element.Spark:SetTexture(E.Media.Textures.Spark)
|
||||
end
|
||||
|
||||
if element.TopIndicator and element.TopIndicator:IsObjectType('Texture') and not element.TopIndicator:GetTexture() then
|
||||
element.TopIndicator:SetTexture(E.Media.Textures.ArrowUp)
|
||||
element.TopIndicator:SetRotation(3.14)
|
||||
end
|
||||
|
||||
if element.LeftIndicator and element.LeftIndicator:IsObjectType('Texture') and not element.LeftIndicator:GetTexture() then
|
||||
element.LeftIndicator:SetTexture(E.Media.Textures.ArrowUp)
|
||||
element.LeftIndicator:SetRotation(1.57)
|
||||
end
|
||||
|
||||
if element.RightIndicator and element.RightIndicator:IsObjectType('Texture') and not element.RightIndicator:GetTexture() then
|
||||
element.RightIndicator:SetTexture(E.Media.Textures.ArrowUp)
|
||||
element.RightIndicator:SetRotation(-1.57)
|
||||
end
|
||||
|
||||
self:RegisterEvent('PLAYER_TARGET_CHANGED', Path, true)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
local element = self.TargetIndicator
|
||||
if element then
|
||||
if element.TopIndicator then element.TopIndicator:Hide() end
|
||||
if element.LeftIndicator then element.LeftIndicator:Hide() end
|
||||
if element.RightIndicator then element.RightIndicator:Hide() end
|
||||
if element.Shadow then element.Shadow:Hide() end
|
||||
if element.Spark then element.Spark:Hide() end
|
||||
|
||||
self:UnregisterEvent('PLAYER_TARGET_CHANGED', Path)
|
||||
end
|
||||
end
|
||||
|
||||
oUF:AddElement('TargetIndicator', Path, Enable, Disable)
|
||||
1387
Modules/Nameplates/StyleFilter.lua
Normal file
1387
Modules/Nameplates/StyleFilter.lua
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user