You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
356 lines
11 KiB
356 lines
11 KiB
|
5 years ago
|
--NOBODY, except Keseva touches this file.
|
||
|
|
|
||
|
|
-- globals
|
||
|
|
DBM.Nameplate = {}
|
||
|
|
-- locals
|
||
|
|
local nameplateFrame = DBM.Nameplate
|
||
|
|
local units = {}
|
||
|
|
local num_units = 0
|
||
|
|
local playerName, playerGUID = UnitName("player"), UnitGUID("player")--Cache these, they never change
|
||
|
|
local GetNamePlateForUnit, GetNamePlates = C_NamePlate.GetNamePlateForUnit, C_NamePlate.GetNamePlates
|
||
|
|
local twipe, floor = table.wipe, math.floor
|
||
|
|
|
||
|
|
--------------------
|
||
|
|
-- Create Frame --
|
||
|
|
--------------------
|
||
|
|
local DBMNameplateFrame = CreateFrame("Frame", "DBMNameplate", UIParent)
|
||
|
|
DBMNameplateFrame:SetFrameStrata('BACKGROUND')
|
||
|
|
DBMNameplateFrame:Hide()
|
||
|
|
|
||
|
|
--------------------------
|
||
|
|
-- Aura frame functions --
|
||
|
|
--------------------------
|
||
|
|
local CreateAuraFrame
|
||
|
|
do
|
||
|
|
local function AuraFrame_CreateIcon(frame)
|
||
|
|
local icon = DBMNameplateFrame:CreateTexture(nil,'BACKGROUND',nil,0)
|
||
|
|
icon:SetSize(DBM.Options.NPAuraSize, DBM.Options.NPAuraSize)
|
||
|
|
icon:Hide()
|
||
|
|
|
||
|
|
tinsert(frame.icons,icon)
|
||
|
|
|
||
|
|
return icon
|
||
|
|
end
|
||
|
|
local function AuraFrame_GetIcon(frame,texture)
|
||
|
|
-- find unused icon or create new icon
|
||
|
|
if not frame.icons or #frame.icons == 0 then
|
||
|
|
return frame:CreateIcon()
|
||
|
|
else
|
||
|
|
if frame.texture_index[texture] then
|
||
|
|
-- return icon already used for this texture
|
||
|
|
return frame.texture_index[texture]
|
||
|
|
else
|
||
|
|
-- find unused icon:
|
||
|
|
for _,icon in ipairs(frame.icons) do
|
||
|
|
if not icon:IsShown() then
|
||
|
|
return icon
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- create new icon
|
||
|
|
return frame:CreateIcon()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
local function AuraFrame_ArrangeIcons(frame)
|
||
|
|
if not frame.icons or #frame.icons == 0 then return end
|
||
|
|
|
||
|
|
local prev,total_width,first_icon
|
||
|
|
for _,icon in ipairs(frame.icons) do
|
||
|
|
if icon:IsShown() then
|
||
|
|
icon:ClearAllPoints()
|
||
|
|
|
||
|
|
if not prev then
|
||
|
|
total_width = 0
|
||
|
|
first_icon = icon
|
||
|
|
icon:SetPoint('BOTTOM',frame.parent,'TOP')
|
||
|
|
else
|
||
|
|
total_width = total_width + icon:GetWidth()
|
||
|
|
icon:SetPoint('LEFT',prev,'RIGHT')
|
||
|
|
end
|
||
|
|
|
||
|
|
prev = icon
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if first_icon and total_width and total_width > 0 then
|
||
|
|
-- shift first icon back to centre visible row
|
||
|
|
first_icon:SetPoint('BOTTOM',frame.parent,'TOP',
|
||
|
|
-floor(total_width/2),0)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
local function AuraFrame_AddAura(frame,aura_tbl)
|
||
|
|
if not frame.icons then
|
||
|
|
frame.icons = {}
|
||
|
|
end
|
||
|
|
if not frame.texture_index then
|
||
|
|
frame.texture_index = {}
|
||
|
|
end
|
||
|
|
|
||
|
|
local icon = frame:GetIcon(aura_tbl.texture)
|
||
|
|
icon:SetTexture(aura_tbl.texture)
|
||
|
|
icon:Show()
|
||
|
|
|
||
|
|
frame.texture_index[aura_tbl.texture] = icon
|
||
|
|
frame:ArrangeIcons()
|
||
|
|
end
|
||
|
|
local function AuraFrame_RemoveAura(frame,texture,batch)
|
||
|
|
if not texture then return end
|
||
|
|
if not frame.texture_index then return end
|
||
|
|
|
||
|
|
local icon = frame.texture_index[texture]
|
||
|
|
if not icon then return end
|
||
|
|
|
||
|
|
icon:Hide()
|
||
|
|
frame.texture_index[texture] = nil
|
||
|
|
|
||
|
|
if not batch then
|
||
|
|
frame:ArrangeIcons()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
local function AuraFrame_RemoveAll(frame)
|
||
|
|
if not frame.icons or not frame.texture_index then return end
|
||
|
|
|
||
|
|
for texture,_ in pairs(frame.texture_index) do
|
||
|
|
frame:RemoveAura(texture,true)
|
||
|
|
end
|
||
|
|
twipe(frame.texture_index)
|
||
|
|
end
|
||
|
|
|
||
|
|
local auraframe_proto = {
|
||
|
|
CreateIcon = AuraFrame_CreateIcon,
|
||
|
|
GetIcon = AuraFrame_GetIcon,
|
||
|
|
ArrangeIcons = AuraFrame_ArrangeIcons,
|
||
|
|
AddAura = AuraFrame_AddAura,
|
||
|
|
RemoveAura = AuraFrame_RemoveAura,
|
||
|
|
RemoveAll = AuraFrame_RemoveAll,
|
||
|
|
}
|
||
|
|
auraframe_proto.__index = auraframe_proto
|
||
|
|
|
||
|
|
function CreateAuraFrame(frame)
|
||
|
|
if not frame then return end
|
||
|
|
|
||
|
|
local new_frame = {}
|
||
|
|
setmetatable(new_frame, auraframe_proto)
|
||
|
|
new_frame.parent = frame
|
||
|
|
|
||
|
|
return new_frame
|
||
|
|
end
|
||
|
|
end
|
||
|
|
-------------------------
|
||
|
|
-- Nameplate functions --
|
||
|
|
-------------------------
|
||
|
|
local function Nameplate_OnHide(frame)
|
||
|
|
if not frame then return end
|
||
|
|
frame.DBMAuraFrame:RemoveAll()
|
||
|
|
end
|
||
|
|
local function HookNameplate(frame)
|
||
|
|
if not frame then return end
|
||
|
|
frame.DBMAuraFrame = CreateAuraFrame(frame)
|
||
|
|
frame:HookScript('OnHide',Nameplate_OnHide)
|
||
|
|
end
|
||
|
|
|
||
|
|
local function Nameplate_AutoHide(self, isGUID, unit, spellId, texture)
|
||
|
|
self:Hide(isGUID, unit, spellId, texture)
|
||
|
|
end
|
||
|
|
|
||
|
|
local function Nameplate_UnitAdded(frame,unit)
|
||
|
|
if not frame or not unit then return end
|
||
|
|
|
||
|
|
if not frame.DBMAuraFrame then
|
||
|
|
-- hook as required;
|
||
|
|
HookNameplate(frame)
|
||
|
|
end
|
||
|
|
|
||
|
|
local unitName = DBM:GetUnitFullName(unit)
|
||
|
|
local guid = UnitGUID(unit)
|
||
|
|
local unit_tbl
|
||
|
|
|
||
|
|
if guid and units[guid] then
|
||
|
|
unit_tbl = units[guid]
|
||
|
|
elseif unitName and units[unitName] then
|
||
|
|
unit_tbl = units[unitName]
|
||
|
|
end
|
||
|
|
|
||
|
|
if unit_tbl and #unit_tbl > 0 then
|
||
|
|
for _,aura_tbl in ipairs(unit_tbl) do
|
||
|
|
frame.DBMAuraFrame:AddAura(aura_tbl)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
----------------
|
||
|
|
-- On Event --
|
||
|
|
----------------
|
||
|
|
DBMNameplateFrame:SetScript("OnEvent", function(_, event, ...)
|
||
|
|
if event == 'NAME_PLATE_UNIT_ADDED' then
|
||
|
|
local unit = ...
|
||
|
|
if not unit then return end
|
||
|
|
local f = GetNamePlateForUnit(unit)
|
||
|
|
if not f then return end
|
||
|
|
|
||
|
|
Nameplate_UnitAdded(f,unit)
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
-----------------
|
||
|
|
-- Functions --
|
||
|
|
-----------------
|
||
|
|
--/run DBM:FireEvent("BossMod_EnableHostileNameplates")
|
||
|
|
--/run DBM.Nameplate:Show(false, GetUnitName("target", true), 227723)--Mana tracking, easy to find in Dalaran
|
||
|
|
--/run DBM.Nameplate:Hide(true, nil, nil, nil, true)
|
||
|
|
--/run DBM.Nameplate:Hide(true, UnitGUID("target"), 227723)
|
||
|
|
--/run DBM.Nameplate:Hide(false, GetUnitName("target", true), 227723)
|
||
|
|
|
||
|
|
--Add more nameplate mods as they gain support
|
||
|
|
function nameplateFrame:SupportedNPMod()
|
||
|
|
if not DBM.Options.UseNameplateHandoff then return false end
|
||
|
|
if _G["KuiNameplates"] or _G["TidyPlatesThreatDBM"] or _G["Plater"] then return true end
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
|
||
|
|
--isGUID: guid or name (bool)
|
||
|
|
--ie, anchored to UIParent Center (ie player is in center) and to bottom of nameplate aura.
|
||
|
|
function nameplateFrame:Show(isGUID, unit, spellId, texture, duration, desaturate)
|
||
|
|
-- nameplate icons are disabled;
|
||
|
|
if DBM.Options.DontShowNameplateIcons then return end
|
||
|
|
|
||
|
|
-- ignore player nameplate;
|
||
|
|
if playerGUID == unit or playerName == unit then return end
|
||
|
|
|
||
|
|
--Texture Id passed as string so as not to get confused with spellID for GetSpellTexture
|
||
|
|
local currentTexture = tonumber(texture) or texture or GetSpellTexture(spellId)
|
||
|
|
|
||
|
|
-- Supported by nameplate mod, passing to their handler;
|
||
|
|
if self:SupportedNPMod() then
|
||
|
|
DBM:FireEvent("BossMod_ShowNameplateAura", isGUID, unit, currentTexture, duration, desaturate)
|
||
|
|
DBM:Debug("DBM.Nameplate Found supported NP mod, only sending Show callbacks", 3)
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
--Not running supported NP Mod, internal handling
|
||
|
|
if not self:IsShown() then
|
||
|
|
DBMNameplateFrame:Show()
|
||
|
|
DBMNameplateFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
|
||
|
|
DBM:Debug("DBM.Nameplate Enabling", 2)
|
||
|
|
end
|
||
|
|
|
||
|
|
if not units[unit] then
|
||
|
|
units[unit] = {}
|
||
|
|
num_units = num_units + 1
|
||
|
|
end
|
||
|
|
|
||
|
|
tinsert(units[unit], {
|
||
|
|
texture = currentTexture
|
||
|
|
})
|
||
|
|
|
||
|
|
-- find frame for this unit;
|
||
|
|
if not isGUID then
|
||
|
|
local frame = GetNamePlateForUnit(unit)
|
||
|
|
if frame then
|
||
|
|
Nameplate_UnitAdded(frame, unit)
|
||
|
|
if duration then
|
||
|
|
DBM:Schedule(duration, Nameplate_AutoHide, self, isGUID, unit, spellId, texture)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
--GUID, less efficient because it must scan all plates to find
|
||
|
|
--but supports npcs/enemies
|
||
|
|
for _, frame in pairs(GetNamePlates()) do
|
||
|
|
local foundUnit = frame.namePlateUnitToken or (frame.UnitFrame and frame.UnitFrame.unit)
|
||
|
|
if foundUnit and UnitGUID(foundUnit) == unit then
|
||
|
|
Nameplate_UnitAdded(frame, foundUnit)
|
||
|
|
if duration then
|
||
|
|
DBM:Schedule(duration, Nameplate_AutoHide, self, isGUID, unit, spellId, texture)
|
||
|
|
end
|
||
|
|
break
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--Friendly is still being kept around for world bosses, for now anyways, but args being swapped.
|
||
|
|
function nameplateFrame:Hide(isGUID, unit, spellId, texture, force, isHostile, isFriendly)
|
||
|
|
--Texture Id passed as string so as not to get confused with spellID for GetSpellTexture
|
||
|
|
local currentTexture = tonumber(texture) or texture or GetSpellTexture(spellId)
|
||
|
|
|
||
|
|
if self:SupportedNPMod() then
|
||
|
|
DBM:Debug("DBM.Nameplate Found supported NP mod, only sending Hide callbacks", 3)
|
||
|
|
|
||
|
|
if force then
|
||
|
|
if isFriendly then
|
||
|
|
DBM:FireEvent("BossMod_DisableFriendlyNameplates")
|
||
|
|
end
|
||
|
|
if isHostile then
|
||
|
|
DBM:FireEvent("BossMod_DisableHostileNameplates")
|
||
|
|
end
|
||
|
|
elseif unit then
|
||
|
|
DBM:FireEvent("BossMod_HideNameplateAura", isGUID, unit, currentTexture)
|
||
|
|
end
|
||
|
|
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
--Not running supported NP Mod, internal handling
|
||
|
|
if unit and units[unit] then
|
||
|
|
if currentTexture then
|
||
|
|
for i,aura_tbl in ipairs(units[unit]) do
|
||
|
|
if aura_tbl.texture == currentTexture then
|
||
|
|
tremove(units[unit],i)
|
||
|
|
break
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if not currentTexture or #units[unit] == 0 then
|
||
|
|
units[unit] = nil
|
||
|
|
num_units = num_units - 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- find frame for this unit
|
||
|
|
-- (or hide all visible textures if force ~= nil)
|
||
|
|
if not isGUID and not force then--Only need to find one unit
|
||
|
|
local frame = GetNamePlateForUnit(unit)
|
||
|
|
if frame and frame.DBMAuraFrame then
|
||
|
|
if not currentTexture then
|
||
|
|
frame.DBMAuraFrame:RemoveAll()
|
||
|
|
else
|
||
|
|
frame.DBMAuraFrame:RemoveAura(currentTexture)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
--We either passed force, or GUID,
|
||
|
|
--either way requires scanning all nameplates
|
||
|
|
for _, frame in pairs(GetNamePlates()) do
|
||
|
|
if frame.DBMAuraFrame then
|
||
|
|
if force then
|
||
|
|
frame.DBMAuraFrame:RemoveAll()
|
||
|
|
elseif isGUID then
|
||
|
|
local foundUnit = frame.namePlateUnitToken or (frame.UnitFrame and frame.UnitFrame.unit)
|
||
|
|
if foundUnit and UnitGUID(foundUnit) == unit then
|
||
|
|
if not currentTexture then
|
||
|
|
frame.DBMAuraFrame:RemoveAll()
|
||
|
|
else
|
||
|
|
frame.DBMAuraFrame:RemoveAura(currentTexture)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- disable nameplate hooking;
|
||
|
|
if force or num_units <= 0 then
|
||
|
|
twipe(units)
|
||
|
|
num_units = 0
|
||
|
|
|
||
|
|
DBMNameplateFrame:UnregisterEvent("NAME_PLATE_UNIT_ADDED")
|
||
|
|
DBMNameplateFrame:Hide()
|
||
|
|
DBM:Debug("DBM.Nameplate Disabling", 2)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function nameplateFrame:IsShown()
|
||
|
|
return DBMNameplateFrame and DBMNameplateFrame:IsShown()
|
||
|
|
end
|