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.

920 lines
25 KiB

local E = select(2, ...):unpack()
local P, CM = E.Party, E.Comm
local pairs, ipairs, type, tonumber, tinsert, tremove, wipe, floor = pairs, ipairs, type, tonumber, table.insert, table.remove, table.wipe, math.floor
local UnitHealth, UnitIsConnected, UnitIsDeadOrGhost = UnitHealth, UnitIsConnected, UnitIsDeadOrGhost
local GetSpellLevelLearned = C_Spell and C_Spell.GetSpellLevelLearned or GetSpellLevelLearned
if E.spell_requiredLevel then
GetSpellLevelLearned = function(id) return not P.isInTestMode and E.spell_requiredLevel[id] or 0 end
elseif E.preMoP then
GetSpellLevelLearned = function() return 0 end
end
local SpellTooltip = CreateFrame("GameTooltip", "OmniCDSpellTooltip", UIParent, "GameTooltipTemplate")
local TOOLTIP_UPDATE_TIME = 0.2
SpellTooltip.updateTooltipTimer = TOOLTIP_UPDATE_TIME
local FEIGN_DEATH = 5384
local TOUCH_OF_KARMA = 125174
local unitBars = {}
local unusedBars = {}
local numBars = 0
local unusedIcons = {}
local numIcons = 0
local unusedContainers = {}
local UNIT_TO_PET = {
["raid1"]="raidpet1", ["raid2"]="raidpet2", ["raid3"]="raidpet3", ["raid4"]="raidpet4", ["raid5"]="raidpet5",
["raid6"]="raidpet6", ["raid7"]="raidpet7", ["raid8"]="raidpet8", ["raid9"]="raidpet9", ["raid10"]="raidpet10",
["raid11"]="raidpet11", ["raid12"]="raidpet12", ["raid13"]="raidpet13", ["raid14"]="raidpet14", ["raid15"]="raidpet15",
["raid16"]="raidpet16", ["raid17"]="raidpet17", ["raid18"]="raidpet18", ["raid19"]="raidpet19", ["raid20"]="raidpet20",
["raid21"]="raidpet21", ["raid22"]="raidpet22", ["raid23"]="raidpet23", ["raid24"]="raidpet24", ["raid25"]="raidpet25",
["raid26"]="raidpet26", ["raid27"]="raidpet27", ["raid28"]="raidpet28", ["raid29"]="raidpet29", ["raid30"]="raidpet30",
["raid31"]="raidpet31", ["raid32"]="raidpet32", ["raid33"]="raidpet33", ["raid34"]="raidpet34", ["raid35"]="raidpet35",
["raid36"]="raidpet36", ["raid37"]="raidpet37", ["raid38"]="raidpet38", ["raid39"]="raidpet39", ["raid40"]="raidpet40",
["party1"]="partypet1", ["party2"]="partypet2", ["party3"]="partypet3", ["party4"]="partypet4", ["player"]="pet"
}
E.UNIT_TO_PET = UNIT_TO_PET
function P:SetEnabledColorScheme(info)
if info.isDisabledColor then
info.isDisabledColor = nil
local desaturate = E.db.icons.desaturateActive
local condition = E.db.highlight.glowBorderCondition
for _, icon in pairs(info.spellIcons) do
local statusBar = icon.statusBar
if statusBar then
if icon.active then
local castingBar = statusBar.CastingBar
local startColor, startBGColor, startTextColor = self.CastingBarFrame_GetEffectiveStartColor(castingBar, true)
castingBar:SetStatusBarColor(startColor:GetRGBA())
castingBar.BG:SetVertexColor(startBGColor:GetRGBA())
castingBar.Text:SetTextColor(startTextColor:GetRGB())
end
self:SetExStatusBarColor(icon, statusBar.key)
end
icon.icon:SetVertexColor(1, 1, 1)
icon.icon:SetDesaturated(desaturate and icon.active == 0 and not icon.isHighlighted)
if icon.glowBorder then
icon.Glow:SetShown(condition==3 or (condition==1 and icon.active~=0) or (condition==2 and icon.active==0))
end
end
for key, frame in pairs(P.extraBars) do
if frame.shouldRearrangeInterrupts then
P:SetExIconLayout(key, true)
end
end
end
end
local function CooldownBarFrame_OnEvent(self, event, ...)
local guid = self.guid
local info = P.groupInfo[guid]
if not info then
return
end
if event == 'UNIT_SPELLCAST_SUCCEEDED' then
local unit, _, spellID = ...
if unit ~= info.unit and unit ~= UNIT_TO_PET[info.unit] then
return
end
if P.spell_enabled[spellID] or E.spell_modifiers[spellID] then
E.ProcessSpell(spellID, guid)
elseif spellID == 384255
or ((E.isWOTLKC or E.isCata) and (spellID == 63644 or spellID == 63645)) then
if guid ~= E.userGUID and not CM.syncedGroupMembers[guid] then
CM:EnqueueInspect(nil, guid)
end
end
elseif event == 'UNIT_HEALTH' then
local unit = ...
if unit ~= info.unit then
return
end
if not UnitIsDeadOrGhost(unit) then
if E.preMoP then
local icon = info.spellIcons[20608]
if icon then
local mult = info.talentData[16184] and 0.3 or (info.talentData[16209] and 0.4) or 0.2
if UnitHealth(unit) == floor(UnitHealthMax(unit) * mult) then
P:StartCooldown(icon, icon.duration)
end
end
else
--[[
local percHealth = UnitHealth(unit) / UnitHealthMax(unit)
if percHealth > 0.5 and percHealth < 0.7 or percHealth > 0.9 then
E.Libs.CBH:Fire("OnBattleRezed")
end
]]
E.Libs.CBH:Fire("OnBattleRezed")
end
info.isDead = nil
info.isDeadOrOffline = not UnitIsConnected(unit)
P:SetEnabledColorScheme(info)
self:UnregisterEvent(event)
end
elseif event == 'UNIT_AURA' then
local unit = ...
if unit ~= info.unit then
return
end
--[[ Patch 9.0 HSA no longer fires CLEU -> Patch 9.1 removed
if E.isBFA and P.isInArena then
if P:IsDebuffActive(unit, DEBUFF_HEARTSTOP_AURA) then
if not info.auras.isHeartStopped then
P.UpdateCDRR(info, 1/0.7)
info.auras.isHeartStopped = true
end
else
if info.auras.isHeartStopped then
P.UpdateCDRR(info, 0.7)
info.auras.isHeartStopped = nil
end
end
end
]]
if info.glowIcons[TOUCH_OF_KARMA] then
if not P:GetBuffDuration(unit, TOUCH_OF_KARMA) then
local icon = info.glowIcons[TOUCH_OF_KARMA]
if icon then
P:RemoveHighlight(icon)
end
if E.isBFA and not P.isInArena then
self:UnregisterEvent(event)
end
self:UnregisterEvent(event)
end
elseif info.preactiveIcons[FEIGN_DEATH] then
if not P:GetBuffDuration(unit, FEIGN_DEATH) then
local icon = info.preactiveIcons[FEIGN_DEATH]
if icon then
P:RemoveHighlight(icon)
info.preactiveIcons[FEIGN_DEATH] = nil
icon.icon:SetVertexColor(1, 1, 1)
P:StartCooldown(icon, icon.duration)
end
if E.isBFA and not P.isInArena then
self:UnregisterEvent(event)
end
self:UnregisterEvent(event)
end
elseif not E.isBFA or not P.isInArena then
self:UnregisterEvent(event)
end
elseif event == 'PLAYER_SPECIALIZATION_CHANGED' then
local unit = ...
if unit ~= info.unit then
return
end
if UnitIsConnected(unit) then
CM:EnqueueInspect(nil, guid)
end
elseif event == 'UNIT_CONNECTION' then
local unit, isConnected = ...
if unit == info.unit then
info.isDeadOrOffline = UnitIsDeadOrGhost(unit) or not isConnected
if info.isDeadOrOffline then
P:SetDisabledColorScheme(info)
else
P:SetEnabledColorScheme(info)
end
end
end
end
function P:HideBar(bar)
local guid = bar.guid
if self.groupInfo[guid] then
return
end
if guid == E.userGUID then
self.userInfo.bar = nil
end
for i = #unitBars, 1, -1 do
local frame = unitBars[i]
if frame == bar then
tremove(unitBars, i)
break
end
end
tinsert(unusedBars, bar)
self:RemoveUnusedIcons(bar, 1)
bar.numIcons = 0
self:RemoveUnusedContainers(bar)
for key, frame in pairs(self.extraBars) do
local icons = frame.icons
local n = 0
local shouldUpdateLayout
for j = frame.numIcons, 1, -1 do
local icon = icons[j]
local iconGUID = icon.guid
if guid == iconGUID then
self:RemoveIcon(icon)
tremove(icons, j)
n = n + 1
shouldUpdateLayout = true
end
end
frame.numIcons = frame.numIcons - n
if shouldUpdateLayout then
self:SetExIconLayout(key)
end
end
bar:UnregisterAllEvents()
end
local function OmniCDCooldown_OnHide(self)
if self:GetCooldownTimes() > 0 then
return
end
local icon = self:GetParent()
local spellID = icon.spellID
local info = P.groupInfo[icon.guid]
if not info then
return
end
local active = info.active[spellID]
if not active then
return
end
local maxcharges = icon.maxcharges
local charges = active.charges
if maxcharges and charges then
if charges + 1 < maxcharges then
P:StartCooldown(icon, icon.duration, true)
return
end
icon.count:SetText(maxcharges)
end
info.active[spellID] = nil
icon.active = nil
if icon.glowBorder then
icon.Glow:SetShown(not info.isDeadOrOffline and E.db.highlight.glowBorderCondition ~= 2)
end
if not info.isDeadOrOffline then
icon.icon:SetDesaturated(false)
end
local frame = icon:GetParent():GetParent()
local key = frame.key
if type(key) == "number" then
icon:SetAlpha(E.db.icons.inactiveAlpha)
if not P.displayInactive then
P:SetIconLayout(frame)
end
else
local statusBar = icon.statusBar
if statusBar then
icon:SetAlpha(E.db.extraBars[key].useIconAlpha and E.db.icons.inactiveAlpha or 1.0)
P.OmniCDCastingBarFrame_OnEvent(statusBar.CastingBar, 'UNIT_SPELLCAST_STOP')
else
icon:SetAlpha(E.db.icons.inactiveAlpha)
end
if frame.shouldRearrangeInterrupts then
P:SetExIconLayout(key, true)
end
end
end
local function SpellTooltip_OnUpdate(self, elapsed)
self.updateTooltipTimer = self.updateTooltipTimer - elapsed
if self.updateTooltipTimer > 0 then
return
end
self.updateTooltipTimer = TOOLTIP_UPDATE_TIME
local owner = self:GetOwner()
if owner then
self:SetSpellByID(owner.tooltipID or owner.spellID)
end
end
SpellTooltip:SetScript("OnUpdate", SpellTooltip_OnUpdate)
local function OmniCDIcon_OnEnter(self)
local id = self.tooltipID or self.spellID
if id then
SpellTooltip:SetOwner(self, "ANCHOR_RIGHT")
SpellTooltip:SetSpellByID(id)
end
end
local function OmniCDIcon_OnLeave()
SpellTooltip:Hide()
end
local function GetUnitBarFrame()
local frame = tremove(unusedBars)
if not frame then
numBars = numBars + 1
frame = CreateFrame("Frame", "OmniCDBar" .. numBars, UIParent, "OmniCDTemplate")
frame.icons = {}
frame.numIcons = 0
frame.exContainers = {}
frame.anchor:Hide()
frame.anchor.text:SetFontObject(E.AnchorFont)
frame.anchor:SetScript("OnMouseUp", E.OmniCDAnchor_OnMouseUp)
frame.anchor:SetScript("OnMouseDown", E.OmniCDAnchor_OnMouseDown)
frame:SetScript("OnHide", OmniCDBar_OnHide)
frame:SetScript("OnEvent", CooldownBarFrame_OnEvent)
end
unitBars[#unitBars + 1] = frame
return frame
end
function P:HideBars()
for i = #unitBars, 1, -1 do
local frame = unitBars[i]
self:HideBar(frame)
end
end
function P:RemoveUnusedContainers(frame, raidBarIndex)
if ( raidBarIndex ) then
if ( frame.exContainers[raidBarIndex] ) then
tinsert(unusedContainers, frame.exContainers[raidBarIndex])
wipe(frame.exContainers[raidBarIndex].icons)
frame.exContainers[raidBarIndex] = nil
end
else
for i, container in pairs(frame.exContainers) do
tinsert(unusedContainers, container)
wipe(container.icons)
frame.exContainers[i] = nil
end
end
end
local function GetContainer(frame, raidBarIndex)
local container = tremove(unusedContainers)
if ( not container ) then
container = CreateFrame("Frame")
container:SetSize(1, 1)
container.icons = {}
end
frame.exContainers[raidBarIndex] = container
return container
end
local textureUVs = {
"borderTop",
"borderBottom",
"borderRight",
"borderLeft",
}
local pendingPassThroughButtons = {}
function P:UpdatePassThroughButtons()
local showTooltip = E.db.icons.showTooltip
for i = #pendingPassThroughButtons, 1, -1 do
local icon = pendingPassThroughButtons[i]
icon:SetPassThroughButtons("LeftButton", "RightButton")
icon.isPassThrough = true
if showTooltip then
icon:EnableMouse(true)
end
pendingPassThroughButtons[i] = nil
end
end
local function GetIcon(barFrame, iconIndex, container)
local icon = tremove(unusedIcons)
if not icon then
numIcons = numIcons + 1
icon = CreateFrame("Button", "OmniCDIcon" .. numIcons, UIParent, "OmniCDButtonTemplate")
icon:SetSize(E.baseIconHeight, E.baseIconHeight)
icon.counter = icon.cooldown:GetRegions()
for _, pieceName in ipairs(textureUVs) do
local region = icon[pieceName]
if region then
region:SetTexelSnappingBias(0.0)
region:SetSnapToPixelGrid(false)
end
end
icon.icon:SetTexelSnappingBias(0.0)
icon.icon:SetSnapToPixelGrid(false)
icon.name:SetFontObject(E.IconFont)
if E.ElvUI1 then
E.ElvUI1:RegisterCooldown(icon.cooldown, "OmniCD")
end
icon.cooldown:SetScript("OnHide", OmniCDCooldown_OnHide)
icon:SetScript("OnEnter", OmniCDIcon_OnEnter)
icon:SetScript("OnLeave", OmniCDIcon_OnLeave)
if icon.SetPassThroughButtons then
if P.inLockdown then
tinsert(pendingPassThroughButtons, icon)
else
icon:SetPassThroughButtons("LeftButton", "RightButton")
icon.isPassThrough = true
end
end
end
icon:SetParent(container or barFrame.container)
barFrame.icons[iconIndex] = icon
return icon
end
function P:RemoveIcon(icon)
local statusBar = icon.statusBar
if statusBar then
self:RemoveStatusBar(statusBar)
icon.statusBar = nil
end
self:HideOverlayGlow(icon)
icon:Hide()
tinsert(unusedIcons, icon)
end
function P:RemoveUnusedIcons(barFrame, n)
for i = #barFrame.icons, n, -1 do
local icon = barFrame.icons[i]
self:RemoveIcon(icon)
barFrame.icons[i] = nil
end
end
function P:SetBarBackdrop(barFrame)
local icons = barFrame.icons
local db = E.db.icons
for i = 1, barFrame.numIcons do
local icon = icons[i]
self:SetBorder(icon, db)
end
end
function P:UpdateUnitBar(guid, isUpdateBarsOrGRU)
local info = self.groupInfo[guid]
local class = info.class
local raceID = info.raceID
local index = info.index
local unit = info.unit
local name = info.name
local notUser = guid ~= E.userGUID
wipe(info.spellIcons)
if not info.bar then
info.bar = GetUnitBarFrame()
end
local frame = info.bar
frame.key = index
frame.guid = guid
frame.class = class
frame.raceID = raceID
frame.unit = unit
frame.anchor.text:SetText(index)
frame:UnregisterAllEvents()
if info.isAdminObsForMDI then
frame.numIcons = 0
self:RemoveUnusedIcons(frame, 1)
return
end
if not E.preMoP and notUser then
frame:RegisterUnitEvent('PLAYER_SPECIALIZATION_CHANGED', unit)
end
if E.isBFA then
if self.isInArena then
frame:RegisterUnitEvent('UNIT_AURA', unit)
end
else
if info.glowIcons[TOUCH_OF_KARMA] or info.preactiveIcons[FEIGN_DEATH] then
frame:RegisterUnitEvent('UNIT_AURA', unit)
end
end
if info.isDead then
frame:RegisterUnitEvent('UNIT_HEALTH', unit)
end
if not E.isClassic then
frame:RegisterUnitEvent('UNIT_SPELLCAST_SUCCEEDED', unit, UNIT_TO_PET[unit])
end
frame:RegisterUnitEvent('UNIT_CONNECTION', unit)
for _, f in pairs(P.extraBars) do
if ( f.db.enabled and f.db.unitBar ) then
local raidBarIndex = f.index
local container = frame.exContainers[raidBarIndex]
if ( container ) then
if ( container.icons[1] ) then
wipe(container.icons)
end
else
frame.exContainers[raidBarIndex] = GetContainer(frame, raidBarIndex)
end
end
end
local isInspectedUnit = info.spec
local lvl = info.level
local iconIndex = 0
local loginsessionData = self.loginsessionData[guid]
if not CM.syncedGroupMembers[guid] and not info.shadowlandsData.covenantID and isInspectedUnit and loginsessionData then
for k, v in pairs(loginsessionData) do
if k == "covenantID" then
info.shadowlandsData.covenantID = v
else
info.talentData[k] = v
end
end
end
if E.isDF then
local found
AuraUtil.ForEachAura(unit, "HELPFUL", nil, function(_,_,_,_,_,_, source, _,_, id)
if id == 423510 then
info.auras[2050] = true
info.auras[34861] = true
elseif id == 410318 then
found = true
info.itemData[205146] = true
end
end)
if info.itemData[205146] and not found then
info.itemData[205146] = nil
end
end
for spellID, spell in pairs(E.hash_spelldb) do
local cat, spellType, spec, race, item, item2, talent, disabledSpec = spell.class, spell.type, spell.spec, spell.race, spell.item, spell.item2, spell.talent, spell.disabledSpec
local isValidSpell
local enabledSpell = self.spell_enabled[spellID]
local extraBarKey, extraBarFrame
if enabledSpell and enabledSpell > 0 then
extraBarKey = "raidBar" .. enabledSpell
extraBarFrame = E.db.extraBars[extraBarKey].enabled and self.extraBars[extraBarKey]
end
if enabledSpell and (notUser or not self.isUserHidden or (extraBarFrame and not extraBarFrame.db.unitBar)) then
if cat == "RACIAL" then
if type(race) == "table" then
for k = 1, #race do
local id = race[k]
if id == raceID then
isValidSpell = true
end
end
elseif race == raceID then
isValidSpell = true
end
elseif isInspectedUnit then
if cat == class then
isValidSpell = (not E.postBFA or not E.covenant_abilities[spellID] or self.isInShadowlands)
and self:IsSpecOrTalentForPvpStatus(spec==true and spellID or spec, info, lvl >= GetSpellLevelLearned(spellID), disabledSpec and disabledSpec[info.spec])
and (not talent or not self:IsSpecOrTalentForPvpStatus(talent, info, true))
elseif cat == "COVENANT" then
isValidSpell = self.isInShadowlands and self:IsSpecOrTalentForPvpStatus(spec==true and spellID or spec, info, true)
elseif cat == "ESSENCE" then
isValidSpell = info.talentData[spec]
elseif not E.BOOKTYPE_CATEGORY[cat] then
isValidSpell = self:IsEquipped(info, item, item2) or info.sessionItemData[item]
end
else
if cat == class then
isValidSpell = lvl >= GetSpellLevelLearned(spellID) and (not spec or (loginsessionData and loginsessionData[spec])) and not talent
elseif cat == "COVENANT" then
isValidSpell = self.isInShadowlands and loginsessionData and loginsessionData[spec]
elseif cat == "TRINKET" then
isValidSpell = not item or info.sessionItemData[item]
end
end
end
if isValidSpell then
local cd = self:GetValueByType(spell.duration, guid, item2)
if not E.preMoP or not self.isInArena or cd < 900 then
local buffID, iconTexture = spell.buff, spell.icon
local ch = self:GetValueByType(spell.charges, guid) or 1
local baseCooldown = cd
if isInspectedUnit then
if cat == class then
local modData = E.spell_cdmod_talents[spellID]
if modData then
for k = 1, #modData, 2 do
local tal = modData[k]
local rank = self:IsSpecAndTalentForPvpStatus(tal, info)
if rank then
local rt = modData[k+1]
rt = type(rt) == "table" and (rt[rank] or rt[1]) or rt
if (tal == 422748 or tal == 422894) and self.isPvP then
rt = rt / 2
end
cd = cd - rt
end
end
end
modData = E.spell_cxmod_azerite[spellID]
if modData and info.talentData[modData.azerite] then
if modData.duration then
cd = cd - modData.duration
elseif modData.charges then
ch = ch + modData.charges
end
end
modData = E.spell_cdmod_conduits[spellID]
if modData and self.isInShadowlands then
local rankValue = info.talentData[modData]
if rankValue then
--[[ Dec 23, 2020 Hotfixed
if spellID == 212653 then
rankValue = rankValue / 2
end
]]
if self.isPvP and modData == 336636 then
rankValue = rankValue / 2
end
cd = cd - rankValue
end
end
modData = E.spell_cdmod_by_haste[spellID]
if modData == true or modData == info.spec then
if E.preMoP then
cd = cd + (info.rangedWeaponSpeed or 0)
else
local spellHasteMult = info.spellHasteMult or 1/(1 + UnitSpellHaste("player")/100)
cd = cd * spellHasteMult
end
end
modData = E.spell_cdmod_talents_mult[spellID]
if modData then
for k = 1, #modData, 2 do
local tal = modData[k]
local rank = self:IsTalentForPvpStatus(tal, info)
if rank then
local mult = modData[k+1]
mult = type(mult) == "table" and (mult[rank] or mult[1]) or mult
cd = cd * mult
end
end
end
modData = E.spell_cdmod_conduits_mult[spellID]
if modData and self.isInShadowlands then
local rankValue = info.talentData[modData]
if rankValue then
cd = cd * rankValue
end
end
modData = info.talentData["essStriveMult"]
if modData then
local stiveSpec = E.spell_cdmod_ess_strive_mult[spellID]
if stiveSpec == true or stiveSpec == info.spec then
local pvpCD = self.isPvP and self.loginsessionData[guid] and self.loginsessionData[guid]["strivedPvpCD"]
cd = pvpCD or cd * modData
info.talentData["essStrivedPvpID"] = spellID
elseif spellID == 107574 and info.spec == 71 then
cd = cd - 5
end
end
if info.talentData[412713] and spellID ~= 404381 then
cd = cd * 0.9
end
modData = E.spell_chmod_talents[spellID]
if modData then
for k = 1, #modData, 2 do
local tal = modData[k]
local rank = self:IsSpecAndTalentForPvpStatus(tal, info)
if rank then
local charges = modData[k + 1]
charges = type(charges) == "table" and (charges[rank] or charges[1]) or charges
ch = ch + charges
end
end
end
modData = E.majorMovementAbilitiesByIDs[spellID]
if modData and not info.auras["isBlessingOfTheBronze"] and self:GetBuffDuration(unit, modData) then
info.auras["isBlessingOfTheBronze"] = true
end
elseif cat == "COVENANT" then
local covData = E.covenant_cdmod_conduits[spellID]
if covData and info.talentData[ covData[1] ] then
cd = cd - covData[2]
end
covData = E.covenant_cdmod_items_mult[spellID]
if covData and info.itemData[ covData[1] ] then
cd = cd * covData[2]
end
covData = E.covenant_chmod_conduits[spellID]
if covData and info.talentData[ covData[1] ] then
ch = ch + covData[2]
end
elseif cat == "ESSENCE" then
local essData = E.spell_cdmod_essrank23 [spellID]
if essData then
if E:IsEssenceRankUpgraded(info.talentData["essMajorID"]) then
cd = cd - essData
end
end
essData = E.spell_chargemod_essrank3 [spellID]
if essData then
if essData[1] == info.talentData["essMajorID"] then
ch = ch + essData[2]
end
end
elseif cat == "RACIAL" then
local modData = E.spell_cdmod_talents[spellID]
if modData then
for k = 1, #modData, 2 do
local tal = modData[k]
local rank = self:IsSpecAndTalentForPvpStatus(tal, info)
if rank then
local rt = modData[k+1]
rt = type(rt) == "table" and (rt[rank] or rt[1]) or rt
cd = cd - rt
end
end
end
if info.talentData[412713] then
cd = cd * 0.9
end
end
end
ch = ch > 1 and ch
local icon
if extraBarFrame then
extraBarFrame.numIcons = extraBarFrame.numIcons + 1
if ( extraBarFrame.db.unitBar ) then
local container = frame.exContainers[enabledSpell]
icon = GetIcon(extraBarFrame, extraBarFrame.numIcons, container)
container.icons[#container.icons + 1] = icon
else
icon = GetIcon(extraBarFrame, extraBarFrame.numIcons)
end
else
iconIndex = iconIndex + 1
icon = frame.icons[iconIndex] or GetIcon(frame, iconIndex)
end
icon.name:Hide()
icon.guid = guid
icon.spellID = spellID
icon.class = class
icon.unit = unit
icon.unitName = name
icon.type = spellType
icon.priority = E.db.spellPriority[spellID] or E.db.priority[spellType]
icon.category = cat
icon.buff = buffID
icon.duration = cd and cd < 1 and 1 or cd
icon.baseCooldown = baseCooldown
icon.maxcharges = ch
icon.count:SetText(ch or (spellID == 323436 and info.auras.purifySoulStacks) or (spellID == 6262 and info.auras.healthStoneStacks) or "")
icon.icon:SetTexture(iconTexture)
icon.iconTexture = iconTexture
icon.active = nil
icon.tooltipID = nil
icon.glowBorder = not extraBarFrame and E.db.highlight.glowBorder and E.db.spellGlow[spellID]
icon.Glow:Hide()
self:HideOverlayGlow(icon)
local active = info.active[spellID]
if active and active.startTime then
if icon.maxcharges then
active.charges = active.charges or (icon.maxcharges - 1)
icon.count:SetText(active.charges)
else
active.charges = nil
end
self:HighlightIcon(icon, true)
icon.cooldown:SetCooldown(active.startTime, active.duration, active.iconModRate)
icon.active = active.charges or 0
else
icon.cooldown:Clear()
end
if info.preactiveIcons[spellID] then
info.preactiveIcons[spellID] = icon
self:HighlightIcon(icon, true)
end
if extraBarFrame then
local statusBar = icon.statusBar
if statusBar then
if not extraBarFrame.shouldShowProgressBar then
self:RemoveStatusBar(statusBar)
icon.statusBar = nil
end
else
if extraBarFrame.shouldShowProgressBar then
self:GetStatusBar(icon, extraBarKey)
end
end
end
info.spellIcons[spellID] = icon
end
end
end
frame.numIcons = iconIndex
self:RemoveUnusedIcons(frame, iconIndex + 1)
if not self.effectivePixelMult and E.db.general.showRange and not E.db.position.detached then
local relFrame = self:FindRelativeFrame(guid)
if relFrame then
self.effectivePixelMult = E.uiUnitFactor / relFrame:GetEffectiveScale()
self:UpdatePositionValues()
end
end
if notUser or not self.isUserHidden then
self:ApplySettings(frame)
self:SetIconLayout(frame, true)
else
self:SetAnchor(frame)
end
if not isUpdateBarsOrGRU then
self:UpdateExBars()
end
end
function P:UpdateBars()
for guid in pairs(self.groupInfo) do
self:UpdateUnitBar(guid, true)
end
end
function P:UpdateAllBars()
self:HideExBars(true)
self:UpdateBars()
self:UpdateExBars()
end
P.unusedBars = unusedBars
P.unusedIcons = unusedIcons