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.

948 lines
29 KiB

local _, Cell = ...
local L = Cell.L
local F = Cell.funcs
local I = Cell.iFuncs
local P = Cell.pixelPerfectFuncs
local LCG = LibStub("LibCustomGlow-1.0")
local LGI = LibStub:GetLibrary("LibGroupInfo")
local A = Cell.animations
local UnitIsConnected = UnitIsConnected
local UnitIsVisible = UnitIsVisible
local UnitIsDeadOrGhost = UnitIsDeadOrGhost
local UnitIsUnit = UnitIsUnit
local UnitIsPlayer = UnitIsPlayer
local UnitGUID = UnitGUID
local UnitClassBase = UnitClassBase
local UnitLevel = UnitLevel
local IsInGroup = IsInGroup
local IsInRaid = IsInRaid
local sort, tinsert, tconcat = table.sort, table.insert, table.concat
---------------------------------------------------------------------
-- data
---------------------------------------------------------------------
local buffs = {}
local requiredBuffs = {}
local requiredByEveryone = {}
local available = {}
local unaffected = {}
if Cell.isRetail then
buffs = {
stamina = {
tag = ITEM_MOD_STAMINA_SHORT, -- Stamina
icon = 135987,
order = 1,
provider = {
PRIEST = {id = 21562, level = 6}, -- Power Word: Fortitude - 真言术:韧
}
},
versatility = {
tag = STAT_VERSATILITY, -- Versatility
icon = 136078,
order = 2,
provider = {
DRUID = {id = 1126, level = 9}, -- Mark of the Wild - 野性印记
}
},
mastery = {
tag = STAT_MASTERY, -- Mastery
icon = 4630367,
order = 3,
provider = {
SHAMAN = {id = 462854, level = 16}, -- Skyfury - 天怒
}
},
intellect = {
tag = ITEM_MOD_INTELLECT_SHORT, -- Intellect
icon = 135932,
order = 4,
provider = {
MAGE = {id = 1459, level = 8}, -- Arcane Brilliance - 奥术智慧
}
},
attackPower = {
tag = RAID_BUFF_3, -- Attack Power
icon = 132333,
order = 5,
provider = {
WARRIOR = {id = 6673, level = 10}, -- Battle Shout - 战斗怒吼
}
},
movement = {
tag = TUTORIAL_TITLE2, -- Movement
icon = 4622448,
order = 6,
provider = {
EVOKER = {id = 364342, level = 30}, -- Blessing of the Bronze - 青铜龙的祝福
}
}
}
requiredBuffs = {
[250] = "attackPower", -- Blood
[251] = "attackPower", -- Frost
[252] = "attackPower", -- Unholy
[577] = "attackPower", -- Havoc
[581] = "attackPower", -- Vengeance
[102] = "intellect", -- Balance
[103] = "attackPower", -- Feral
[104] = "attackPower", -- Guardian
[105] = "intellect", -- Restoration
[1467] = "intellect", -- Devastation
[1468] = "intellect", -- Preservation
[253] = "attackPower", -- Beast Mastery
[254] = "attackPower", -- Marksmanship
[255] = "attackPower", -- Survival
[62] = "intellect", -- Arcane
[63] = "intellect", -- Fire
[64] = "intellect", -- Frost
[268] = "attackPower", -- Brewmaster
[269] = "attackPower", -- Windwalker
[270] = "intellect", -- Mistweaver
[65] = "intellect", -- Holy
[66] = "attackPower", -- Protection
[70] = "attackPower", -- Retribution
[256] = "intellect", -- Discipline
[257] = "intellect", -- Holy
[258] = "intellect", -- Shadow
[259] = "attackPower", -- Assassination
[260] = "attackPower", -- Outlaw
[261] = "attackPower", -- Subtlety
[262] = "intellect", -- Elemental
[263] = "attackPower", -- Enhancement
[264] = "intellect", -- Restoration
[265] = "intellect", -- Affliction
[266] = "intellect", -- Demonology
[267] = "intellect", -- Destruction
[71] = "attackPower", -- Arms
[72] = "attackPower", -- Fury
[73] = "attackPower", -- Protection
}
requiredByEveryone = {
stamina = true,
versatility = true,
mastery = true,
movement = true,
}
available = {
stamina = false,
versatility = false,
mastery = false,
intellect = false,
attackPower = false,
movement = false,
}
unaffected = {
stamina = {},
versatility = {},
mastery = {},
intellect = {},
attackPower = {},
movement = {},
}
elseif Cell.isMists then
buffs = {
stamina = {
tag = RAID_BUFF_2, -- Stamina
icon = 135987,
order = 1,
provider = {
PRIEST = {id = 21562, level = 22}, -- Power Word: Fortitude
WARLOCK = {id = 109773, level = 82}, -- Dark Intent
WARRIOR = {id = 469, level = 68}, -- Commanding Shout
},
},
stats = {
tag = RAID_BUFF_1, -- Stats
icon = 136078,
order = 2,
provider = {
DRUID = {id = 1126, level = 62}, -- Mark of the Wild
MONK = {id = 115921, level = 22}, -- Legacy of the Emperor
PALADIN = {id = 20217, level = 30}, -- Blessing of Kings
}
},
spellPower = {
tag = RAID_BUFF_5, -- Spell Power
icon = 135932,
order = 3,
provider = {
MAGE = {id = {1459, 61316}, level = 58}, -- Arcane Brilliance / Dalaran Brilliance
SHAMAN = {id = 77747, level = 40}, -- Burning Wrath
WARLOCK = {id = 109773, level = 82}, -- Dark Intent
}
},
attackPower = {
tag = RAID_BUFF_3, -- Attack Power
icon = 132333,
order = 4,
provider = {
DEATHKNIGHT = {id = 57330, level = 65}, -- Horn of Winter
HUNTER = {id = 19506, level = 39}, -- Trueshot Aura
WARRIOR = {id = 6673, level = 42}, -- Battle Shout
}
},
mastery = {
tag = RAID_BUFF_7, -- Mastery
icon = 135908,
order = 5,
provider = {
PALADIN = {id = 19740, level = 81}, -- Blessing of Might
SHAMAN = {id = 116956, level = 80}, -- Grace of Air
}
}
}
requiredBuffs = {
[250] = "attackPower", -- Blood
[251] = "attackPower", -- Frost
[252] = "attackPower", -- Unholy
[102] = "spellPower", -- Balance
[103] = "attackPower", -- Feral
[104] = "attackPower", -- Guardian
[105] = "spellPower", -- Restoration
[253] = "attackPower", -- Beast Mastery
[254] = "attackPower", -- Marksmanship
[255] = "attackPower", -- Survival
[62] = "spellPower", -- Arcane
[63] = "spellPower", -- Fire
[64] = "spellPower", -- Frost
[268] = "attackPower", -- Brewmaster
[269] = "attackPower", -- Windwalker
[270] = "spellPower", -- Mistweaver
[65] = "spellPower", -- Holy
[66] = "attackPower", -- Protection
[70] = "attackPower", -- Retribution
[256] = "spellPower", -- Discipline
[257] = "spellPower", -- Holy
[258] = "spellPower", -- Shadow
[259] = "attackPower", -- Assassination
[260] = "attackPower", -- Outlaw
[261] = "attackPower", -- Subtlety
[262] = "spellPower", -- Elemental
[263] = "attackPower", -- Enhancement
[264] = "spellPower", -- Restoration
[265] = "spellPower", -- Affliction
[266] = "spellPower", -- Demonology
[267] = "spellPower", -- Destruction
[71] = "attackPower", -- Arms
[72] = "attackPower", -- Fury
[73] = "attackPower", -- Protection
}
requiredByEveryone = {
stamina = true,
stats = true,
mastery = true,
}
available = {
stamina = false,
stats = false,
spellPower = false,
attackPower = false,
mastery = false,
}
unaffected = {
stamina = {},
stats = {},
spellPower = {},
attackPower = {},
mastery = {},
}
end
---------------------------------------------------------------------
-- prepare
---------------------------------------------------------------------
local classBuffs = {
-- class = {
-- buff = level,
-- }
}
local buffOrder = {}
local buffsProvidedByMe = {}
local myClass = UnitClassBase("player")
do
local myLevel = UnitLevel("player")
local function Insert(class, buffKey, name, icon)
tinsert(buffs[buffKey]["names"], name)
if myClass == class and myLevel >= classBuffs[class][buffKey] then
buffsProvidedByMe[buffKey] = {name, icon}
end
end
for buffKey, buffData in pairs(buffs) do
tinsert(buffOrder, buffKey)
buffData.names = {}
for class, info in pairs(buffData.provider) do
classBuffs[class] = classBuffs[class] or {}
classBuffs[class][buffKey] = info.level
if type(info.id) == "table" then
for _, spellId in ipairs(info.id) do
local name, icon = F.GetSpellInfo(spellId)
if name then
Insert(class, buffKey, name, icon)
end
end
else
local name, icon = F.GetSpellInfo(info.id)
if name then
Insert(class, buffKey, name, icon)
end
end
end
end
sort(buffOrder, function(a, b)
return buffs[a]["order"] < buffs[b]["order"]
end)
end
-------------------------------------------------
-- vars
-------------------------------------------------
local enabled
local myUnit = ""
local hasBuffProvider
local fl function Reset(which)
if not which or which == "available" then
for k, v in pairs(available) do
available[k] = false
end
hasBuffProvider = false
end
if not which or which == "unaffected" then
for k, v in pairs(unaffected) do
wipe(unaffected[k])
end
end
end
local function GetUnaffectedString(buff)
local list = unaffected[buff]
local name = buffs[buff]["tag"]
local players = {}
for unit in pairs(list) do
local name = UnitName(unit)
tinsert(players, name)
end
if #players == 0 then
return
elseif #players <= 10 then
return L["Missing Buff"] .. " (" .. name .. "): " .. tconcat(players, ", ")
else
return L["Missing Buff"] .. " (" .. name .. "): " .. L["many"]
end
end
-------------------------------------------------
-- frame
-------------------------------------------------
local buffTrackerFrame = CreateFrame("Frame", "CellBuffTrackerFrame", Cell.frames.mainFrame, "BackdropTemplate")
Cell.frames.buffTrackerFrame = buffTrackerFrame
P.Size(buffTrackerFrame, 102, 50)
PixelUtil.SetPoint(buffTrackerFrame, "BOTTOMLEFT", CellParent, "CENTER", 1, 1)
buffTrackerFrame:SetClampedToScreen(true)
-- buffTrackerFrame:SetClampRectInsets(0, 0, -20, 0)
buffTrackerFrame:SetMovable(true)
buffTrackerFrame:RegisterForDrag("LeftButton")
buffTrackerFrame:SetScript("OnDragStart", function()
buffTrackerFrame:StartMoving()
buffTrackerFrame:SetUserPlaced(false)
end)
buffTrackerFrame:SetScript("OnDragStop", function()
buffTrackerFrame:StopMovingOrSizing()
P.SavePosition(buffTrackerFrame, CellDB["tools"]["buffTracker"][4])
end)
-------------------------------------------------
-- mover
-------------------------------------------------
buffTrackerFrame.moverText = buffTrackerFrame:CreateFontString(nil, "OVERLAY", "CELL_FONT_WIDGET")
buffTrackerFrame.moverText:SetPoint("TOP", 0, -3)
buffTrackerFrame.moverText:SetText(L["Mover"])
buffTrackerFrame.moverText:Hide()
local fakeIconsFrame = CreateFrame("Frame", nil, buffTrackerFrame)
P.Point(fakeIconsFrame, "BOTTOMRIGHT", buffTrackerFrame)
P.Point(fakeIconsFrame, "TOPLEFT", buffTrackerFrame, "TOPLEFT", 0, -18)
fakeIconsFrame:EnableMouse(true)
fakeIconsFrame:SetFrameLevel(buffTrackerFrame:GetFrameLevel() + 10)
fakeIconsFrame:Hide()
local fakeIcons = {}
local function CreateFakeIcon(spellIcon)
local bg = fakeIconsFrame:CreateTexture(nil, "BORDER")
bg:SetColorTexture(0, 0, 0, 1)
P.Size(bg, 32, 32)
local icon = fakeIconsFrame:CreateTexture(nil, "ARTWORK")
icon:SetTexture(spellIcon)
icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
P.Point(icon, "TOPLEFT", bg, "TOPLEFT", 1, -1)
P.Point(icon, "BOTTOMRIGHT", bg, "BOTTOMRIGHT", -1, 1)
function bg:UpdatePixelPerfect()
P.Resize(bg)
P.Repoint(bg)
P.Repoint(icon)
end
return bg
end
do
for _, k in ipairs(buffOrder) do
tinsert(fakeIcons, CreateFakeIcon(buffs[k]["icon"]))
end
end
local function ShowMover(show)
if show then
if not CellDB["tools"]["buffTracker"][1] then return end
buffTrackerFrame:EnableMouse(true)
buffTrackerFrame.moverText:Show()
Cell.StylizeFrame(buffTrackerFrame, {0, 1, 0, 0.4}, {0, 0, 0, 0})
fakeIconsFrame:Show()
buffTrackerFrame:SetAlpha(1)
else
buffTrackerFrame:EnableMouse(false)
buffTrackerFrame.moverText:Hide()
Cell.StylizeFrame(buffTrackerFrame, {0, 0, 0, 0}, {0, 0, 0, 0})
fakeIconsFrame:Hide()
buffTrackerFrame:SetAlpha(CellDB["tools"]["fadeOut"] and 0 or 1)
end
end
Cell.RegisterCallback("ShowMover", "BuffTracker_ShowMover", ShowMover)
-------------------------------------------------
-- buttons
-------------------------------------------------
local sendChannel
local function UpdateSendChannel()
if IsInGroup(LE_PARTY_CATEGORY_INSTANCE) then
sendChannel = "INSTANCE_CHAT"
elseif IsInRaid() then
sendChannel = "RAID"
else
sendChannel = "PARTY"
end
end
local function CreateBuffButton(parent, buff)
local b = CreateFrame("Button", nil, parent, "SecureActionButtonTemplate,BackdropTemplate")
if parent then b:SetFrameLevel(parent:GetFrameLevel() + 1) end
P.Size(b, 32, 32)
b:SetBackdrop({edgeFile = Cell.vars.whiteTexture, edgeSize = P.Scale(1)})
b:SetBackdropBorderColor(0, 0, 0, 1)
b:RegisterForClicks("LeftButtonUp", "RightButtonUp", "LeftButtonDown", "RightButtonDown") -- NOTE: ActionButtonUseKeyDown will affect this
-- cast
if buffsProvidedByMe[buff] then
b:SetAttribute("type1", "macro")
b:SetAttribute("macrotext1", "/cast [@player] " .. buffsProvidedByMe[buff][1])
end
-- chat
b:HookScript("OnClick", function(self, button, down)
if button == "RightButton" and (down == GetCVarBool("ActionButtonUseKeyDown")) then
local msg = GetUnaffectedString(buff)
if msg then
UpdateSendChannel()
SendChatMessage(msg, sendChannel)
end
end
end)
b.texture = b:CreateTexture(nil, "OVERLAY")
P.Point(b.texture, "TOPLEFT", b, "TOPLEFT", 1, -1)
P.Point(b.texture, "BOTTOMRIGHT", b, "BOTTOMRIGHT", -1, 1)
b.texture:SetTexture(buffs[buff]["icon"])
b.texture:SetTexCoord(0.08, 0.92, 0.08, 0.92)
b.count = b:CreateFontString(nil, "OVERLAY")
P.Point(b.count, "TOPLEFT", b.texture, "TOPLEFT", 2, -2)
b.count:SetFont(GameFontNormal:GetFont(), 14, "OUTLINE")
b.count:SetShadowColor(0, 0, 0)
b.count:SetShadowOffset(0, 0)
b.count:SetTextColor(1, 0, 0)
b:SetScript("OnLeave", function()
CellTooltip:Hide()
end)
function b:SetTooltips(list)
b:SetScript("OnEnter", function()
if F.Getn(list) ~= 0 then
CellTooltip:SetOwner(b, "ANCHOR_TOPLEFT", 0, 3)
CellTooltip:AddLine(L["Unaffected"] .. " |cffb7b7b7" .. buffs[buff]["tag"])
for unit in pairs(list) do
local class = UnitClassBase(unit)
local name = UnitName(unit)
if class and name then
CellTooltip:AddLine(F.GetClassColorStr(class) .. name .. "|r")
end
end
CellTooltip:Show()
end
end)
end
function b:SetDesaturated(flag)
b.texture:SetDesaturated(flag)
end
function b:StartGlow(glowType, ...)
LCG.PixelGlow_Start(b, ...)
end
function b:StopGlow()
LCG.PixelGlow_Stop(b)
end
function b:Reset()
b.texture:SetDesaturated(false)
b.count:SetText("")
b:SetAlpha(1)
b:StopGlow()
end
function b:UpdatePixelPerfect()
P.Resize(b)
P.Repoint(b)
b:SetBackdrop({edgeFile = Cell.vars.whiteTexture, edgeSize = P.Scale(1)})
b:SetBackdropBorderColor(0, 0, 0, 1)
P.Repoint(b.texture)
P.Repoint(b.count)
end
return b
end
local buttons = {}
do
for _, buff in ipairs(buffOrder) do
buttons[buff] = CreateBuffButton(buffTrackerFrame, buff)
buttons[buff]:Hide()
buttons[buff]:SetTooltips(unaffected[buff])
end
end
local function UpdateButtons()
for _, buff in pairs(buffOrder) do
if available[buff] then
local n = F.Getn(unaffected[buff])
if n == 0 then
buttons[buff].count:SetText("")
buttons[buff]:SetAlpha(0.5)
buttons[buff]:StopGlow()
else
buttons[buff].count:SetText(n)
buttons[buff]:SetAlpha(1)
if unaffected[buff][myUnit] then
-- color, N, frequency, length, thickness
buttons[buff]:StartGlow("Pixel", {1, 0.19, 0.19, 1}, 8, 0.25, P.Scale(8), P.Scale(2))
else
buttons[buff]:StopGlow()
end
end
end
end
end
local function RepointButtons()
if InCombatLockdown() then
buffTrackerFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
else
local point, relativePoint, offsetX, offsetY, firstX, firstY
if CellDB["tools"]["buffTracker"][2] == "left-to-right" then
point, relativePoint = "BOTTOMLEFT", "BOTTOMRIGHT"
offsetX, offsetY = 3, 0
firstX, firstY = 0, 0
elseif CellDB["tools"]["buffTracker"][2] == "right-to-left" then
point, relativePoint = "BOTTOMRIGHT", "BOTTOMLEFT"
offsetX, offsetY = -3, 0
firstX, firstY = 0, 0
elseif CellDB["tools"]["buffTracker"][2] == "top-to-bottom" then
point, relativePoint = "TOPLEFT", "BOTTOMLEFT"
offsetX, offsetY = 0, -3
firstX, firstY = 0, -18
elseif CellDB["tools"]["buffTracker"][2] == "bottom-to-top" then
point, relativePoint = "BOTTOMLEFT", "TOPLEFT"
offsetX, offsetY = 0, 3
firstX, firstY = 0, 0
end
local last
for _, k in pairs(buffOrder) do
P.ClearPoints(buttons[k])
if available[k] then
buttons[k]:Show()
if last then
P.Point(buttons[k], point, last, relativePoint, offsetX, offsetY)
else
P.Point(buttons[k], point, firstX, firstY)
end
last = buttons[k]
else
buttons[k]:Hide()
buttons[k]:Reset()
end
end
last = nil
for _, icon in pairs(fakeIcons) do
P.ClearPoints(icon)
if last then
P.Point(icon, point, last, relativePoint, offsetX, offsetY)
else
P.Point(icon, point, buffTrackerFrame, point, firstX, firstY)
end
last = icon
end
end
end
local function ResizeButtons()
if InCombatLockdown() then
buffTrackerFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
else
local size = CellDB["tools"]["buffTracker"][3]
for _, i in pairs(fakeIcons) do
P.Size(i, size, size)
end
for _, b in pairs(buttons) do
P.Size(b, size, size)
end
local n = F.Getn(buttons)
if strfind(CellDB["tools"]["buffTracker"][2], "left") then
buffTrackerFrame:SetSize(n * P.Scale(size) + (n - 1) * P.Scale(3), P.Scale(size + 18))
else
buffTrackerFrame:SetSize(P.Scale(size), n * P.Scale(size) + (n - 1) * P.Scale(3) + P.Scale(18))
end
end
end
-------------------------------------------------
-- fade out
-------------------------------------------------
local fadeOuts = {}
for _, b in pairs(buttons) do
tinsert(fadeOuts, b)
end
A.ApplyFadeInOutToParent(buffTrackerFrame, function()
return CellDB["tools"]["fadeOut"] and not buffTrackerFrame.moverText:IsShown()
end, unpack(fadeOuts))
---------------------------------------------------------------------
-- find aura
---------------------------------------------------------------------
local GetAuraDataBySpellName = C_UnitAuras.GetAuraDataBySpellName
local function UnitBuffExists(unit, buff)
local names = buffs[buff]["names"]
local aura
for _, name in next, names do
aura = GetAuraDataBySpellName(unit, name, "HELPFUL")
if aura then
return true, aura.sourceUnit == "player"
end
end
end
---------------------------------------------------------------------
-- missing buffs
---------------------------------------------------------------------
local missingBuffsFromMe = {}
local hasBuffFromMe = {}
local function UpdateMissingBuffs(unit, buff)
missingBuffsFromMe[unit] = missingBuffsFromMe[unit] or {}
tinsert(missingBuffsFromMe[unit], buff)
end
local function ShowMissingBuffs(unit)
I.HideMissingBuffs(unit)
if not missingBuffsFromMe[unit] then return end
local num = #missingBuffsFromMe[unit]
if num == 0 then return end
if myClass == "PALADIN" or myClass == "WARRIOR" then
if hasBuffFromMe[unit] then return end
end
if num == 1 or myClass == "PRIEST" then
for _, buff in next, missingBuffsFromMe[unit] do
I.ShowMissingBuff(unit, buffsProvidedByMe[buff][2])
end
else
I.ShowMissingBuff(unit, 254882)
end
end
-------------------------------------------------
-- check
-------------------------------------------------
local function CheckUnit(unit, updateBtn)
-- print("CheckUnit", unit)
if not hasBuffProvider then return end
if missingBuffsFromMe[unit] then wipe(missingBuffsFromMe[unit]) end
hasBuffFromMe[unit] = nil
if UnitIsConnected(unit) and UnitIsVisible(unit) and not UnitIsDeadOrGhost(unit) then
local info = LGI:GetCachedInfo(UnitGUID(unit))
local spec = info and info.specId
local required = spec and requiredBuffs[spec]
for buff, hasProvider in next, available do
if hasProvider then
if required == buff or requiredByEveryone[buff] then
local exists, providedByMe = UnitBuffExists(unit, buff)
if exists then
unaffected[buff][unit] = nil
if providedByMe then
hasBuffFromMe[unit] = true
end
else
unaffected[buff][unit] = true
if buffsProvidedByMe[buff] then
UpdateMissingBuffs(unit, buff)
end
end
end
else
unaffected[buff][unit] = nil
end
end
else
for k, t in next, unaffected do
t[unit] = nil
end
end
ShowMissingBuffs(unit)
if updateBtn then UpdateButtons() end
end
local function IterateAllUnits()
Reset("available")
myUnit = ""
local class, level
for unit in F.IterateGroupMembers() do
if UnitIsConnected(unit) and UnitIsVisible(unit) then
class = UnitClassBase(unit)
level = UnitLevel(unit)
if classBuffs[class] then
for buff, lvl in pairs(classBuffs[class]) do
if not available[buff] and level >= lvl then
available[buff] = true
hasBuffProvider = true
end
end
end
if UnitIsUnit("player", unit) then
myUnit = unit
end
end
end
RepointButtons()
Reset("unaffected")
for unit in F.IterateGroupMembers() do
CheckUnit(unit)
end
UpdateButtons()
end
-------------------------------------------------
-- events
-------------------------------------------------
function buffTrackerFrame:UnitUpdated(event, guid, unit, info)
-- print(event, guid, unit, info.specId)
if unit == "player" then
if UnitIsUnit("player", myUnit) then CheckUnit(myUnit, true) end
elseif UnitIsPlayer(unit) then -- ignore pets
CheckUnit(unit, true)
end
end
function buffTrackerFrame:PLAYER_ENTERING_WORLD()
buffTrackerFrame:UnregisterEvent("PLAYER_ENTERING_WORLD")
buffTrackerFrame:GROUP_ROSTER_UPDATE()
end
local timer
function buffTrackerFrame:GROUP_ROSTER_UPDATE(immediate)
if timer then timer:Cancel() end
if IsInGroup() then
buffTrackerFrame:RegisterEvent("READY_CHECK")
buffTrackerFrame:RegisterEvent("UNIT_FLAGS")
buffTrackerFrame:RegisterEvent("PLAYER_UNGHOST")
buffTrackerFrame:RegisterEvent("UNIT_AURA")
else
buffTrackerFrame:UnregisterEvent("READY_CHECK")
buffTrackerFrame:UnregisterEvent("UNIT_FLAGS")
buffTrackerFrame:UnregisterEvent("PLAYER_UNGHOST")
buffTrackerFrame:UnregisterEvent("UNIT_AURA")
Reset()
RepointButtons()
return
end
if immediate then
IterateAllUnits()
else
timer = C_Timer.NewTimer(3, IterateAllUnits)
end
end
function buffTrackerFrame:READY_CHECK()
buffTrackerFrame:GROUP_ROSTER_UPDATE(true)
end
function buffTrackerFrame:UNIT_FLAGS()
buffTrackerFrame:GROUP_ROSTER_UPDATE()
end
function buffTrackerFrame:PLAYER_UNGHOST()
buffTrackerFrame:GROUP_ROSTER_UPDATE()
end
function buffTrackerFrame:UNIT_AURA(unit)
if IsInRaid() then
if unit:find("^raid%d+$") then
CheckUnit(unit, true)
end
else
if unit:find("^party%d$") or unit == "player" then
CheckUnit(unit, true)
end
end
end
function buffTrackerFrame:PLAYER_REGEN_ENABLED()
buffTrackerFrame:UnregisterEvent("PLAYER_REGEN_ENABLED")
RepointButtons()
ResizeButtons()
end
buffTrackerFrame:SetScript("OnEvent", function(self, event, ...)
self[event](self, ...)
end)
-------------------------------------------------
-- functions
-------------------------------------------------
local function UpdateTools(which)
if not which or which == "buffTracker" then
if CellDB["tools"]["buffTracker"][1] then
buffTrackerFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
buffTrackerFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
LGI.RegisterCallback(buffTrackerFrame, "GroupInfo_Update", "UnitUpdated")
if not enabled and which == "buffTracker" then -- already in world, manually enabled
buffTrackerFrame:GROUP_ROSTER_UPDATE(true)
end
enabled = true
if Cell.vars.showMover then
ShowMover(true)
end
else
buffTrackerFrame:UnregisterAllEvents()
LGI.UnregisterCallback(buffTrackerFrame, "GroupInfo_Update")
Reset()
myUnit = ""
enabled = false
ShowMover(false)
-- missingBuffs indicator
for unit in F.IterateGroupMembers() do
I.HideMissingBuffs(unit, true)
end
end
RepointButtons()
ResizeButtons()
end
if not which or which == "fadeOut" then
if CellDB["tools"]["fadeOut"] and not buffTrackerFrame.moverText:IsShown() then
buffTrackerFrame:SetAlpha(0)
else
buffTrackerFrame:SetAlpha(1)
end
end
if not which then -- position
P.LoadPosition(buffTrackerFrame, CellDB["tools"]["buffTracker"][4])
end
end
Cell.RegisterCallback("UpdateTools", "BuffTracker_UpdateTools", UpdateTools)
local function UpdatePixelPerfect()
-- P.Resize(buffTrackerFrame)
for _, i in pairs(fakeIcons) do
i:UpdatePixelPerfect()
end
for _, b in pairs(buttons) do
b:UpdatePixelPerfect()
end
end
Cell.RegisterCallback("UpdatePixelPerfect", "BuffTracker_UpdatePixelPerfect", UpdatePixelPerfect)