-- Bigwigs/DBM nameplate aura support
--[[
Options ( defaults ) :
Plater.db . profile.bossmod_support_enabled = true
Plater.db . profile.bossmod_aura_height = 32
Plater.db . profile.bossmod_aura_width = 32
Plater.db . profile.bossmod_cooldown_text_size = 16
Plater.db . profile.bossmod_icons_anchor = { side = 8 , x = 0 , y = 40 }
Plater.db . profile.bossmod_support_bars_enabled = false
Plater.db . profile.bossmod_support_bars_text_max_len = 7
] ] --
local DF = _G [ " DetailsFramework " ]
local Plater = _G.Plater
local C_Timer = _G.C_Timer
local C_NamePlate = _G.C_NamePlate
local GetTime = _G.GetTime
local LCG = LibStub : GetLibrary ( " LibCustomGlow-1.0 " )
local UNIT_BOSS_MOD_AURAS_ACTIVE = { } --contains for each [GUID] a list of {texture, duration, desaturate}
local UNIT_BOSS_MOD_AURAS_TO_BE_REMOVED = { } --contains for each [GUID] a list of texture-ids to be removed
local UNIT_BOSS_MOD_BARS = { } --contains for each [GUID] the bar information
local UNIT_BOSS_MOD_NEEDS_UPDATE_IN = { } -- timestamp for next update!
local HOSTILE_ENABLED = false
local IS_REGISTERED = false
local DBM_TIMER_BARS_TEST_MODE = false --can be changed via callback. will disable after 30sec
-- core functions
local function ShowNameplateAura ( guid , texture , duration , desaturate , isPriority )
--print("ShowNameplateAura", guid, texture, duration, desaturate, isPriority, HOSTILE_ENABLED)
if not HOSTILE_ENABLED then return end
if not guid or not texture then return end
local values = {
texture = texture ,
duration = duration ,
desaturate = desaturate ,
isPriority = isPriority ,
starttime = GetTime ( ) ,
}
UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] = UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] or { }
for index , value in pairs ( UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] ) do
if value.texture == values.texture and value.starttime == values.starttime and value.duration == values.duration then
return
end
end
tinsert ( UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] , values )
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1
end
local function HideNameplateAura ( guid , texture )
--print("HideNameplateAura", guid, texture)
if not HOSTILE_ENABLED then return end
if not guid or not texture then return end
-- force direct removal when called for to ensure a new instance can directly be shown after
for activeIndex , activeData in pairs ( UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] or { } ) do
if texture == activeData.texture then
tremove ( UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] , activeIndex )
end
end
-- keep the old way for now
--UNIT_BOSS_MOD_AURAS_TO_BE_REMOVED [guid] = UNIT_BOSS_MOD_AURAS_TO_BE_REMOVED [guid] or {}
--tinsert(UNIT_BOSS_MOD_AURAS_TO_BE_REMOVED [guid], texture)
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1
end
local function DisableHostile ( )
--print("DisableHostile")
HOSTILE_ENABLED = false
UNIT_BOSS_MOD_AURAS_ACTIVE = { }
UNIT_BOSS_MOD_AURAS_TO_BE_REMOVED = { }
end
local function EnableHostile ( )
--print("EnableHostile")
if not Plater.db . profile.bossmod_support_enabled then
return
end
HOSTILE_ENABLED = true
end
local function StartGlow ( self , glowType )
if not glowType or glowType == 1 then
local options = {
glowType = " pixel " ,
color = self.bmData . color , -- all plater color types accepted, from lib: {r,g,b,a}, color of lines and opacity, from 0 to 1. Defaul value is {0.95, 0.95, 0.32, 1}
N = 8 , -- number of lines. Defaul value is 8;
frequency = 0.25 , -- frequency, set to negative to inverse direction of rotation. Default value is 0.25;
length = 3 , -- length of lines. Default value depends on region size and number of lines;
th = 3 , -- thickness of lines. Default value is 2;
xOffset = 0 ,
yOffset = 0 , -- offset of glow relative to region border;
border = false , -- set to true to create border under lines;
key = " BM_ImportantIconGlow " , -- key of glow, allows for multiple glows on one frame;
}
Plater.StartPixelGlow ( self , self.bmData . color or " orange " , options , " BM_ImportantIconGlow " )
elseif glowType == 2 then
local options = {
glowType = " proc " ,
color = self.bmData . color ,
--frameLevel = 8,
startAnim = true ,
xOffset = 0 ,
yOffset = 0 ,
duration = 1 ,
key = " BM_ImportantIconGlow " ,
}
Plater.StartProcGlow ( self , self.bmData . color or " orange " , options , " BM_ImportantIconGlow " )
elseif glowType == 3 then
local options = {
glowType = " ants " ,
color = self.bmData . color ,
N = 4 , -- number of particle groups. Default value is 4
frequency = 0.125 , -- frequency, set to negative to inverse direction of rotation. Default value is 0.125
scale = 1 , -- scale of particles.
xOffset = 0 ,
yOffset = 0 ,
duration = 1 ,
key = " BM_ImportantIconGlow " ,
}
Plater.StartAntsGlow ( self , self.bmData . color or " orange " , options , " BM_ImportantIconGlow " )
elseif glowType == 4 then
local options = {
glowType = " button " ,
color = self.bmData . color ,
frequency = 0.125 , --Default value is 0.125
key = " BM_ImportantIconGlow " ,
}
Plater.StartButtonGlow ( self , self.bmData . color or " orange " , options , " BM_ImportantIconGlow " )
end
end
local function StopGlow ( self , glowType )
--print("StopGlow", glowType)
if not glowType then
Plater.StopGlow ( self , " BM_ImportantIconGlow " )
elseif glowType == 1 then
Plater.StopPixelGlow ( self , " BM_ImportantIconGlow " )
elseif glowType == 2 then
Plater.StopProcGlow ( self , " BM_ImportantIconGlow " )
elseif glowType == 3 then
Plater.StopAntsGlow ( self , " BM_ImportantIconGlow " )
elseif glowType == 4 then
Plater.StopButtonGlow ( self , " BM_ImportantIconGlow " )
end
end
function Plater . CreateBossModAuraFrame ( unitFrame )
Plater.RegisterBossModAuras ( )
local options = {
icon_width = Plater.db . profile.bossmod_aura_width or 32 ,
icon_height = Plater.db . profile.bossmod_aura_height or 32 ,
texcoord = { .1 , .9 , .1 , .9 } ,
show_text = Plater.db . profile.bossmod_cooldown_text_enabled ,
text_size = Plater.db . profile.bossmod_cooldown_text_size or 16 ,
surpress_tulla_omni_cc = Plater.db . profile.disable_omnicc_on_auras ,
desc_text = true ,
desc_text_size = 10
}
unitFrame.BossModIconFrame = DF : CreateIconRow ( unitFrame.healthBar , " $parentBossModIconRow " , options )
unitFrame.BossModIconFrame : ClearIcons ( )
unitFrame.BossModIconFrame . RefreshID = 0
unitFrame.BossModIconFrame : SetOption ( " surpress_tulla_omni_cc " , Plater.db . profile.disable_omnicc_on_auras )
unitFrame.BossModIconFrame : SetOption ( " surpress_blizzard_cd_timer " , true )
unitFrame.BossModIconFrame : SetOption ( " anchor " , Plater.db . profile.bossmod_icons_anchor or { side = 8 , x = 0 , y = 30 } )
unitFrame.BossModIconFrame : SetOption ( " grow_direction " , unitFrame.ExtraIconFrame : GetIconGrowDirection ( ) )
Plater.SetAnchor ( unitFrame.BossModIconFrame , Plater.db . profile.bossmod_icons_anchor or { side = 8 , x = 0 , y = 30 } )
unitFrame.BossModIconFrame . OnIconTick = function ( self , deltaTime ) -- override to add glow effects
local now = GetTime ( )
if ( self.lastUpdateCooldown + 0.05 ) <= now then
self.timeRemaining = ( ( self.expirationTime or now ) - now ) / ( self.modRate or 1 )
if self.timeRemaining > 0 then
if self.parentIconRow . options.decimal_timer then
self.CountdownText : SetText ( self.parentIconRow . FormatCooldownTimeDecimal ( self.timeRemaining ) )
else
self.CountdownText : SetText ( self.parentIconRow . FormatCooldownTime ( self.timeRemaining ) )
end
else
self.CountdownText : SetText ( " " )
end
local profile = Plater.db . profile
local bmData = self.bmData or { }
local canGlow = false
if bmData.barType ~= " castnp " and ( profile.bossmod_aura_glow_cooldown and ( not bossmod_aura_glow_important_only or bmData.isPriority ) ) and self.timeRemaining < 4 and self.timeRemaining > 0 then
canGlow = true
elseif bmData.barType == " castnp " and profile.bossmod_aura_glow_casts and self.timeRemaining < 4 and self.timeRemaining > 0 then
canGlow = true
end
local glowType = bmData.barType == " castnp " and profile.bossmod_aura_glow_casts_glow_type or profile.bossmod_aura_glow_cooldown_glow_type
--print(canGlow, self.isGlowing)
if canGlow and not self.isGlowing then
StartGlow ( self , glowType )
self.isGlowing = glowType
elseif not canGlow and self.isGlowing ~= false or self.timeRemaining < 0 then
StopGlow ( self , self.isGlowing )
self.isGlowing = false
end
self.lastUpdateCooldown = now
end
end
end
function Plater . UpdateBossModAuraFrameSettings ( unitFrame , refreshID )
if ( unitFrame.BossModIconFrame . RefreshID < refreshID ) then
Plater.SetAnchor ( unitFrame.BossModIconFrame , Plater.db . profile.bossmod_icons_anchor )
unitFrame.BossModIconFrame : SetOption ( " surpress_tulla_omni_cc " , Plater.db . profile.disable_omnicc_on_auras )
unitFrame.BossModIconFrame : SetOption ( " text_size " , Plater.db . profile.bossmod_cooldown_text_size )
unitFrame.BossModIconFrame : SetOption ( " icon_width " , Plater.db . profile.bossmod_aura_width )
unitFrame.BossModIconFrame : SetOption ( " icon_height " , Plater.db . profile.bossmod_aura_height )
unitFrame.BossModIconFrame : SetOption ( " anchor " , Plater.db . profile.bossmod_icons_anchor or { side = 8 , x = 0 , y = 30 } )
unitFrame.BossModIconFrame : SetOption ( " grow_direction " , unitFrame.ExtraIconFrame : GetIconGrowDirection ( ) )
--> update refresh ID
unitFrame.BossModIconFrame . RefreshID = refreshID
end
end
function Plater . EnsureUpdateBossModAuras ( guid )
if not guid then return end
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1
end
function Plater . UpdateBossModAuras ( unitFrame )
Plater.StartLogPerformanceCore ( " Plater-Core " , " Update " , " UpdateBossModAuras " )
local guid = unitFrame.PlateFrame . namePlateUnitGUID
local curTime = GetTime ( )
if not UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] or UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] > curTime then
Plater.EndLogPerformanceCore ( " Plater-Core " , " Update " , " UpdateBossModAuras " )
return
end
-- maybe find a better way with iconFrame:RemoveIcon(...) ? (not yet implemented, but worth a thought)
if UNIT_BOSS_MOD_AURAS_TO_BE_REMOVED [ guid ] then
for removeIndex , removeTexture in pairs ( UNIT_BOSS_MOD_AURAS_TO_BE_REMOVED [ guid ] ) do
for activeIndex , activeData in pairs ( UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] or { } ) do
if removeTexture == activeData.texture then
tremove ( UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] , activeIndex )
end
end
end
UNIT_BOSS_MOD_AURAS_TO_BE_REMOVED [ guid ] = nil
end
local nextUpdateTime = nil
local iconFrame = unitFrame.BossModIconFrame
iconFrame : ClearIcons ( )
if HOSTILE_ENABLED and UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] then
for activeIndex , values in pairs ( UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] ) do
if values.duration and values.duration > 0 and curTime > values.starttime + values.duration then
tremove ( UNIT_BOSS_MOD_AURAS_ACTIVE [ guid ] , activeIndex )
else
local icon = iconFrame : SetIcon ( - 1 , nil , values.duration and values.duration > 0 and values.starttime , values.duration , values.texture )
-- spellId, borderColor, startTime, duration, forceTexture, descText, count, debuffType, caster, canStealOrPurge, spellName, isBuff
icon.Texture : SetDesaturated ( values.desaturate )
icon.bmData = values
icon.lastUpdateCooldown = icon.lastUpdateCooldown or 0
if icon.isGlowing ~= false then
StopGlow ( icon , icon.isGlowing )
icon.isGlowing = false
end
iconFrame.OnIconTick ( icon )
--icon.Cooldown:SetDesaturated(values.desaturate)
local endTime = values.duration and values.duration > 0 and ( values.starttime + values.duration ) or nil
if not nextUpdateTime or ( endTime and endTime < nextUpdateTime ) then
nextUpdateTime = endTime
end
--check if Masque is enabled on Plater and reskin the aura icon
if ( Plater.Masque and not icon.Masqued ) then
local t = {
FloatingBG = nil , --false,
Icon = icon.Texture ,
Cooldown = icon.Cooldown ,
Flash = nil , --false,
Pushed = nil , --false,
Normal = false ,
Disabled = nil , --false,
Checked = nil , --false,
Border = nil , --icon.Border,
AutoCastable = nil , --false,
Highlight = nil , --false,
HotKey = nil , --false,
Count = false ,
Name = nil , --false,
Duration = false ,
Shine = nil , --false,
}
icon.Border : Hide ( ) --let Masque handle the border...
Plater.Masque . BossModIconFrame : AddButton ( icon , t )
Plater.Masque . BossModIconFrame : ReSkin ( )
icon.Masqued = true
end
end
end
end
--timer bars
if Plater.db . profile.bossmod_support_bars_enabled and UNIT_BOSS_MOD_BARS [ guid ] then
local textEnabled = Plater.db . profile.bossmod_support_bars_text_enabled
local sortedAuras = { }
for id , data in pairs ( UNIT_BOSS_MOD_BARS [ guid ] ) do
tinsert ( sortedAuras , data )
end
table.sort ( sortedAuras , function ( a , b )
if a.paused and not b.paused then
return false
elseif b.paused and not a.paused then
return true
else
local at , bt = a.timer or 0 , b.timer or 0
local as , bs = a.start or 0 , b.start or 0
local ar = at - ( curTime - ( a.paused and ( curTime - ( a.pauseStartTime - a.start ) ) or as ) )
local br = bt - ( curTime - ( b.paused and ( curTime - ( b.pauseStartTime - b.start ) ) or bs ) )
return br > ar
end
end )
--for id, data in pairs(UNIT_BOSS_MOD_BARS [guid]) do
for _ , data in pairs ( sortedAuras ) do
local id = data.id
local overTime = curTime > data.start + data.timer
if not data.keep and data.timer and overTime then
UNIT_BOSS_MOD_BARS [ guid ] [ id ] = nil
else
local timer , start = data.timer , data.start
if data.paused then
start = curTime - ( data.pauseStartTime - start ) --offset for paused.
end
if overTime and data.keep then
timer = nil
end
--print(timer, start, data.name, data.msg, data.colorId)
local icon = iconFrame : SetIcon ( - 1 , data.color , timer and start , timer , data.icon , textEnabled and { text = data.display , text_color = data.color } or nil )
-- spellId, borderColor, startTime, duration, forceTexture, descText, count, debuffType, caster, canStealOrPurge, spellName, isBuff
--DF:TruncateText(icon.Desc, Plater.db.profile.bossmod_aura_width)
icon.bmData = data
icon.lastUpdateCooldown = icon.lastUpdateCooldown or 0
iconFrame.OnIconTick ( icon )
if data.paused then
icon : SetScript ( " OnUpdate " , nil )
icon.Cooldown : Pause ( )
icon.Texture : SetDesaturated ( true )
else
--[[
local curOnUpdate = iconFrame.OnIconTick --icon:GetScript("OnUpdate")
icon : SetScript ( " OnUpdate " , function ( self )
if self.timeRemaining <= 0 then
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1 -- fallback to remove icons that have run out
end
self.parentIconRow . OnIconTick ( self ) --curOnUpdate(self)
end )
] ]
icon.Texture : SetDesaturated ( false )
end
local endTime = timer and ( start + timer ) or nil
if not nextUpdateTime or ( endTime and endTime < nextUpdateTime ) then
nextUpdateTime = endTime
end
--check if Masque is enabled on Plater and reskin the aura icon
if ( Plater.Masque and not icon.Masqued ) then
local t = {
FloatingBG = nil , --false,
Icon = icon.Texture ,
Cooldown = icon.Cooldown ,
Flash = nil , --false,
Pushed = nil , --false,
Normal = false ,
Disabled = nil , --false,
Checked = nil , --false,
Border = nil , --icon.Border,
AutoCastable = nil , --false,
Highlight = nil , --false,
HotKey = nil , --false,
Count = false ,
Name = nil , --false,
Duration = false ,
Shine = nil , --false,
}
icon.Border : Hide ( ) --let Masque handle the border...
Plater.Masque . BossModIconFrame : AddButton ( icon , t )
Plater.Masque . BossModIconFrame : ReSkin ( )
icon.Masqued = true
end
end
end
end
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = nextUpdateTime
Plater.EndLogPerformanceCore ( " Plater-Core " , " Update " , " UpdateBossModAuras " )
end
--callbacks
local function Callback_DBM_ShowAura ( _ , is_guid , unit , texture , duration , desaturate , isPriority )
local guid = ( is_guid == true or is_guid == ' guid ' ) and unit or UnitGUID ( unit )
ShowNameplateAura ( guid , texture , duration , desaturate , isPriority )
end
local function Callback_DBM_HideNameplateAura ( _ , is_guid , unit , texture )
local guid = ( is_guid == true or is_guid == ' guid ' ) and unit or UnitGUID ( unit )
HideNameplateAura ( guid , texture )
end
local function Callback_DBM_DisableHostile ( )
DisableHostile ( )
end
local function Callback_DBM_EnableHostile ( )
EnableHostile ( )
end
local function Callback_BW_ShowAura ( guid , texture , duration , desaturate )
ShowNameplateAura ( guid , texture , duration , desaturate , isPriority )
end
local function Callback_BW_HideNameplateAura ( guid , texture )
HideNameplateAura ( guid , texture )
end
local function Callback_BW_DisableHostile ( )
DisableHostile ( )
end
local function Callback_BW_EnableHostile ( )
EnableHostile ( )
end
function Plater . RegisterBossModAuras ( )
if IS_REGISTERED then return end
if Plater.db . profile.bossmod_support_enabled then
if DBM and DBM.RegisterCallback then
DBM : RegisterCallback ( ' BossMod_ShowNameplateAura ' , Callback_DBM_ShowAura )
DBM : RegisterCallback ( ' BossMod_HideNameplateAura ' , Callback_DBM_HideNameplateAura )
DBM : RegisterCallback ( ' BossMod_EnableHostileNameplates ' , Callback_DBM_EnableHostile )
DBM : RegisterCallback ( ' BossMod_DisableHostileNameplates ' , Callback_DBM_DisableHostile )
IS_REGISTERED = true
end
if BigWigsLoader and BigWigsLoader.RegisterMessage then
--[[
BigWigsLoader.RegisterMessage ( Plater , ' BigWigs_ShowNameplateAura ' , function ( _ , _ , ... )
Callback_ShowAura ( select ( 5 , ... ) , ... )
end )
BigWigsLoader.RegisterMessage ( Plater , ' BigWigs_HideNameplateAura ' , function ( _ , _ , ... )
Callback_HideNameplateAura ( select ( 3 , ... ) , ... )
end )
] ] --
BigWigsLoader.RegisterMessage ( Plater , ' BigWigs_AddNameplateIcon ' , Callback_BW_ShowAura )
BigWigsLoader.RegisterMessage ( Plater , ' BigWigs_RemoveNameplateIcon ' , Callback_BW_HideNameplateAura )
BigWigsLoader.RegisterMessage ( Plater , ' BigWigs_EnableHostileNameplates ' , Callback_BW_EnableHostile )
BigWigsLoader.RegisterMessage ( Plater , ' BigWigs_DisableHostileNameplates ' , Callback_BW_DisableHostile )
IS_REGISTERED = true
end
end
end
function Plater . GetBossModsEventTimeLeft ( spell ) -- more or less deprecated, need to know how to get this information from bigwigs
if ( _G.DBM ) then
for bar , _ in _G.DBM . Bars : GetBarIterator ( ) do
if ( not bar.dead and bar.frame : IsShown ( ) ) then
if ( bar.id : find ( spell ) ) then
return bar.timer , bar.totalTime , bar.id , _G [ bar.frame : GetName ( ) .. " BarName " ] : GetText ( )
end
end
end
end
if ( BigWigsLoader ) then
end
end
---@class plater_altcastbarconfig : table
---@field iconTexture string
---@field iconTexcoord table
---@field iconAlpha number
---@field text string
---@field texture any
---@field color any
---@field isChanneling boolean
---@field canInterrupt boolean
---@field height number
---@field iconSize number
---@field textSize number
---@field spellNameAnchor df_anchor
---@field timerAnchor df_anchor
---@field iconAnchor df_anchor
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> spell prediction
function Plater . GetAltCastBarAltId ( plateFrame )
--check if the nameplate is valid
if ( not plateFrame or not plateFrame.unitFrame ) then
return
end
return plateFrame.unitFrame . castBar2.altCastId
end
function Plater . ClearAltCastBar ( plateFrame )
--check if the nameplate is valid
if ( not plateFrame or not plateFrame.unitFrame ) then
return
end
local castBar2 = plateFrame.unitFrame . castBar2
castBar2.altCastId = nil
castBar2 : Hide ( )
end
function Plater . SetAltCastBar ( plateFrame , configTable , timer , startedAt , altCastId )
---@cast configTable plater_altcastbarconfig
--check if the nameplate is valid
if ( not plateFrame or not plateFrame.unitFrame ) then
return
end
local castBar = plateFrame.unitFrame . castBar2
castBar.CastBarEvents = { }
--> just update the current value since it wasn't running its tick function during the hide state
--> everything else should be in the correct state
castBar.OnShow = function ( self )
self.flashTexture : Hide ( )
if ( self.unit ) then
if ( self.casting ) then
self.value = GetTime ( ) - self.spellStartTime
if self.value > self.maxValue then
self : Hide ( )
return
end
self : RunHooksForWidget ( " OnShow " , self , self.unit )
elseif ( self.channeling ) then
self.value = self.spellEndTime - GetTime ( )
if self.value < 0 then
self : Hide ( )
return
end
self : RunHooksForWidget ( " OnShow " , self , self.unit )
end
end
end
--reset the castbar
castBar.Icon : ClearAllPoints ( )
castBar.Icon : SetPoint ( " right " , castBar , " left " , - 1 , 0 )
castBar : ClearAllPoints ( )
castBar : SetPoint ( " topleft " , plateFrame.unitFrame . castBar , " bottomleft " , 0 , - 2 )
castBar : SetPoint ( " topright " , plateFrame.unitFrame . castBar , " bottomright " , 0 , - 2 )
castBar.percentText : ClearAllPoints ( )
castBar.percentText : SetPoint ( " right " , castBar , " right " , - 2 , 0 )
castBar.Text : ClearAllPoints ( )
castBar.Text : SetPoint ( " left " , castBar , " left " , 2 , 0 )
--set the unit
castBar : SetUnit ( plateFrame.unitFrame . unit )
castBar.altCastId = altCastId
--set spell name
castBar.Text : SetText ( configTable.text )
--set texture
castBar.Icon : SetTexture ( configTable.iconTexture or " " )
if ( configTable.iconTexcoord ) then
castBar.Icon : SetTexCoord ( unpack ( configTable.iconTexcoord ) )
else
castBar.Icon : SetTexCoord ( 0.1 , 0.9 , 0.1 , 0.9 )
end
castBar.Icon : SetAlpha ( configTable.iconAlpha or 1 )
castBar.Icon : Show ( )
castBar.percentText : Show ( )
castBar : SetHeight ( configTable.height or 12 )
if ( configTable.iconSize ) then
castBar.Icon : SetSize ( configTable.iconSize , configTable.iconSize )
else
castBar.Icon : SetSize ( castBar : GetHeight ( ) , castBar : GetHeight ( ) )
end
castBar.Spark : Show ( )
if ( configTable.spellNameAnchor ) then
Plater.SetAnchor ( castBar.Text , configTable.spellNameAnchor )
end
if ( configTable.timerAnchor ) then
Plater.SetAnchor ( castBar.percentText , configTable.timerAnchor )
end
if ( configTable.iconAnchor ) then
Plater.SetAnchor ( castBar.Icon , configTable.iconAnchor )
end
DF : SetFontSize ( castBar.Text , configTable.textSize or 10 )
DF : SetFontSize ( castBar.percentText , configTable.textSize or 10 )
local startTime
if ( startedAt ) then
startTime = startedAt
else
startTime = GetTime ( )
end
local endTime = startTime + timer
if ( configTable.isChanneling ) then
castBar.casting = nil
castBar.channeling = true
castBar.spellStartTime = startTime
castBar.spellEndTime = endTime
castBar.SpellStartTime = startTime
castBar.SpellEndTime = endTime
castBar.value = endTime - GetTime ( )
castBar.maxValue = endTime - startTime
castBar : SetMinMaxValues ( 0 , castBar.maxValue )
castBar : SetValue ( castBar.value )
else
castBar.casting = true
castBar.channeling = nil
castBar.spellStartTime = startTime
castBar.spellEndTime = endTime
castBar.SpellStartTime = startTime
castBar.SpellEndTime = endTime
castBar.value = GetTime ( ) - startTime
castBar.maxValue = endTime - startTime
castBar : SetMinMaxValues ( 0 , castBar.maxValue )
castBar : SetValue ( castBar.value )
end
castBar.finished = false
castBar.canInterrupt = configTable.canInterrupt
castBar : SetColor ( configTable.color or " yellow " )
castBar.spellName = configTable.text
castBar.spellID = 1
castBar.spellTexture = configTable.iconTexture or " "
castBar : SetStatusBarTexture ( configTable.texture or [[Interface\AddOns\Plater\images\bar_background]] )
castBar.flashTexture : Hide ( )
castBar : Animation_StopAllAnimations ( )
Plater.CastBarOnEvent_Hook ( castBar , " UNIT_SPELLCAST_START " , plateFrame.unitFrame . unit , plateFrame.unitFrame . unit )
if ( not castBar : IsShown ( ) ) then
castBar : Animation_FadeIn ( )
castBar : Show ( )
end
end
function Plater . StopAltCastBar ( plateFrame )
--check if the nameplate is valid
if ( not plateFrame or not plateFrame.unitFrame ) then
return
end
local castBar = plateFrame.unitFrame . castBar2
castBar.CastBarEvents = { }
castBar : SetUnit ( nil )
castBar.altCastId = nil
castBar.Text : SetText ( " " )
if ( castBar : IsShown ( ) ) then
castBar : Animation_FadeOut ( )
castBar : Hide ( )
end
end
function TESTPlater ( )
local plateFrame = C_NamePlate.GetNamePlateForUnit ( " target " )
local config = {
iconTexture = " Interface \\ CHARACTERFRAME \\ Button_BloodPresence_DeathKnight " ,
--iconTexcoord = {0, 1, 0, 1},
iconAlpha = 1 ,
text = " Test Cast Bar " ,
texture = " Interface \\ CHARACTERFRAME \\ UI-BarFill-Simple " ,
color = " pink " ,
isChanneling = false ,
canInterrupt = true ,
}
local timer = 5
Plater.SetAltCastBar ( plateFrame , config , timer )
end
--SETTINGS
local prediction_time_to_show = 3
local triggerCastBar = function ( timerObject )
--get the bar timer id
local timerId = timerObject.timerId
local barInfo = Plater.BossModsTimeBar [ timerId ]
--check if the bar still exists
if ( not barInfo ) then
--print("there no bar information for", timerId)
return
end
local bar = DBM.Bars : GetBar ( timerId )
if ( not bar ) then
--print("DBM returned nil for GetBar", timerId)
return
end
--the nameplate to attach the cast bar
local plateFrame
if ( timerObject.findUnitBySpellId ) then
--find the mob responsible for cast the ability
plateFrame = C_NamePlate.GetNamePlateForUnit ( " target " ) --debug
elseif ( timerObject.attachToCurrentTarget ) then
plateFrame = C_NamePlate.GetNamePlateForUnit ( " target " )
end
if ( not plateFrame ) then
return
end
--set the castbar config
local config = {
iconTexture = barInfo [ 5 ] ,
iconTexcoord = { 0.1 , 0.9 , 0.1 , 0.9 } ,
iconAlpha = 1 ,
text = barInfo [ 3 ] ,
texture = [[Interface\AddOns\Plater\images\bar_background]] ,
color = " silver " ,
isChanneling = false ,
canInterrupt = false ,
height = Plater.db . profile.spell_prediction . castbar_height ,
}
--show the cast bar
Plater.SetAltCastBar ( plateFrame , config , prediction_time_to_show )
DF : TruncateText ( plateFrame.unitFrame . castBar2.Text , plateFrame.unitFrame . castBar : GetWidth ( ) - 28 )
DF : SetFontSize ( plateFrame.unitFrame . castBar2.Text , 10 )
end
function Plater . GetBossTimer ( spellId )
for id , barInfo in pairs ( Plater.BossModsTimeBarDBM ) do
if ( ( barInfo.spellId == spellId ) or ( type ( id ) == " string " and id : find ( spellId ) ) ) then
return DF.table . copy ( { } , barInfo )
end
end
for id , barInfo in pairs ( Plater.BossModsTimeBarBW ) do
if ( ( barInfo.spellId == spellId ) or ( id == spellId ) ) then
return DF.table . copy ( { } , barInfo )
end
end
end
local function getDBTColor ( colorId )
if DBT and DBT.Options then
local barOptions = DBT.Options
local barStartRed , barStartGreen , barStartBlue
if colorId and colorId >= 1 then
if colorId == 1 then --Add
barStartRed , barStartGreen , barStartBlue = barOptions.StartColorAR , barOptions.StartColorAG , barOptions.StartColorAB
elseif colorId == 2 then --AOE
barStartRed , barStartGreen , barStartBlue = barOptions.StartColorAER , barOptions.StartColorAEG , barOptions.StartColorAEB
elseif colorId == 3 then --Debuff
barStartRed , barStartGreen , barStartBlue = barOptions.StartColorDR , barOptions.StartColorDG , barOptions.StartColorDB
elseif colorId == 4 then --Interrupt
barStartRed , barStartGreen , barStartBlue = barOptions.StartColorIR , barOptions.StartColorIG , barOptions.StartColorIB
elseif colorId == 5 then --Role
barStartRed , barStartGreen , barStartBlue = barOptions.StartColorRR , barOptions.StartColorRG , barOptions.StartColorRB
elseif colorId == 6 then --Phase
barStartRed , barStartGreen , barStartBlue = barOptions.StartColorPR , barOptions.StartColorPG , barOptions.StartColorPB
elseif colorId == 7 then --Important
barStartRed , barStartGreen , barStartBlue = barOptions.StartColorUIR , barOptions.StartColorUIG , barOptions.StartColorUIB
end
else
barStartRed , barStartGreen , barStartBlue = barOptions.StartColorR , barOptions.StartColorG , barOptions.StartColorB
end
return { barStartRed , barStartGreen , barStartBlue , 1 }
end
return { 1 , 1 , 1 , 1 }
end
local function getAllShownGUIDs ( )
local guids = { }
for _ , plateFrame in ipairs ( Plater.GetAllShownPlates ( ) ) do
if plateFrame.unitFrame . PlaterOnScreen then
tinsert ( guids , plateFrame.namePlateUnitGUID )
end
end
return guids
end
function Plater . PauseBarIcon ( name )
if not name then return end
local curTime = GetTime ( )
for id , entry in pairs ( Plater.BossModsTimeBarDBM ) do
if entry.msg == name then
--print("yes", entry.paused, id)
if not entry.paused then
entry.paused = true
entry.pauseStartTime = curTime
--UNIT_BOSS_MOD_BARS [entry.guid][id].paused = true
--UNIT_BOSS_MOD_BARS [entry.guid][id].pauseStartTime = curTime
else
entry.paused = false
entry.start = entry.start + ( curTime - entry.pauseStartTime )
entry.pauseStartTime = entry.start
--UNIT_BOSS_MOD_BARS [entry.guid][id].paused = false
--UNIT_BOSS_MOD_BARS [entry.guid][id].start = entry.start + (curTime - entry.pauseStartTime)
--UNIT_BOSS_MOD_BARS [entry.guid][id].pauseStartTime = entry.start
end
--print(name, entry.msg, entry.msg == name, entry.guid)
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ entry.guid ] = - 1
end
end
end
function Plater . UpdateBarIcon ( name , elapsed , totalTime )
if not name then return end
local curTime = GetTime ( )
for id , entry in pairs ( Plater.BossModsTimeBarDBM ) do
if entry.msg == name then
entry.timer = totalTime
entry.start = curTime - elapsed
if entry.paused then
entry.pauseStartTime = curTime
end
--print(name, entry.msg, entry.msg == name, entry.guid)
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ entry.guid ] = - 1
end
end
end
function Plater . KeepBarIcon ( name )
if not name then return end
for id , entry in pairs ( Plater.BossModsTimeBarDBM ) do
if entry.msg == name then
entry.keep = not entry.keep
--print(name, entry.msg, entry.msg == name, entry.guid)
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ entry.guid ] = - 1
end
end
end
function Plater . RegisterBossModsBars ( )
local DBM = _G.DBM
local BigWigsLoader = _G.BigWigsLoader
--check if Deadly Boss Mods is installed
if ( DBM ) then
--timer start
local timerStartCallback = function ( event , id , msg , timer , icon , barType , spellId , colorId , modId , keep , fade , name , guid , timerCount , isPriority )
if event ~= " DBM_NameplateStart " and not ( DBM_TIMER_BARS_TEST_MODE and event == " DBM_TimerStart " ) then return end
if ( id and guid ) then
local color = getDBTColor ( colorId )
local display = DF : CleanTruncateUTF8String ( strsub ( string.match ( name or msg or " " , " ^%s*(.-)%s*$ " ) , 1 , Plater.db . profile.bossmod_support_bars_text_max_len or 7 ) )
--local display = string.match(name or msg or "", "^%s*(.-)%s*$" )
local curTime = GetTime ( )
---@type dbmtimerbar
local barData = {
msg = msg ,
display = display or name or msg or " " ,
id = id ,
timer = timer ,
start = curTime ,
icon = icon ,
spellId = spellId ,
barType = barType or " cdnp " ,
color = color ,
colorId = colorId ,
modId = modId ,
keep = keep ,
fade = fade ,
name = name ,
guid = guid ,
timerCount = timerCount ,
isPriority = isPriority ,
paused = false ,
}
Plater.BossModsTimeBarDBM [ id ] = barData
UNIT_BOSS_MOD_BARS [ guid ] = UNIT_BOSS_MOD_BARS [ guid ] or { }
UNIT_BOSS_MOD_BARS [ guid ] [ id ] = barData
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1
elseif id and not guid and DBM_TIMER_BARS_TEST_MODE then
for _ , guid in pairs ( getAllShownGUIDs ( ) ) do
id = id .. guid
local color = getDBTColor ( colorId )
local display = DF : CleanTruncateUTF8String ( strsub ( string.match ( name or msg or " " , " ^%s*(.-)%s*$ " ) , 1 , Plater.db . profile.bossmod_support_bars_text_max_len or 7 ) )
--local display = string.match(name or msg or "", "^%s*(.-)%s*$" )
local curTime = GetTime ( )
---@type dbmtimerbar
local barData = {
msg = msg ,
display = display or name or msg or " " ,
id = id ,
timer = timer ,
start = curTime ,
icon = icon ,
spellId = spellId ,
barType = barType ,
color = color ,
colorId = colorId ,
modId = modId ,
keep = keep ,
fade = fade ,
name = name ,
guid = guid ,
timerCount = timerCount ,
isPriority = isPriority ,
paused = false ,
}
Plater.BossModsTimeBarDBM [ id ] = barData
UNIT_BOSS_MOD_BARS [ guid ] = UNIT_BOSS_MOD_BARS [ guid ] or { }
UNIT_BOSS_MOD_BARS [ guid ] [ id ] = barData
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1
end
end
end
DBM : RegisterCallback ( " DBM_NameplateStart " , timerStartCallback )
local timerUpdateCallback = function ( event , id , elapsed , totalTime )
if event ~= " DBM_NameplateUpdate " then return end
if not id or not elapsed or not totalTime then return end
local entry = id and Plater.BossModsTimeBarDBM [ id ] or nil
local guid = entry and entry.guid
local curTime = GetTime ( )
if entry and guid then
entry.timer = totalTime
entry.start = curTime - elapsed
if entry.paused then
entry.pauseStartTime = curTime
end
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1
end
end
DBM : RegisterCallback ( " DBM_NameplateUpdate " , timerUpdateCallback )
local timerPauseCallback = function ( event , id )
if event ~= " DBM_NameplatePause " then return end
if not id then return end
local entry = id and Plater.BossModsTimeBarDBM [ id ] or nil
local guid = entry and entry.guid
if entry and guid then
local curTime = GetTime ( )
--entry.start = entry.start - (curTime - entry.start)
entry.paused = true
entry.pauseStartTime = curTime
--UNIT_BOSS_MOD_BARS [guid][id].paused = true
--UNIT_BOSS_MOD_BARS [guid][id].pauseStartTime = curTime
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1
end
end
DBM : RegisterCallback ( " DBM_NameplatePause " , timerPauseCallback )
local timerResumeCallback = function ( event , id )
if event ~= " DBM_NameplateResume " then return end
if not id then return end
local entry = id and Plater.BossModsTimeBarDBM [ id ] or nil
local guid = entry and entry.guid
if entry and entry.paused and guid then
entry.paused = false
entry.start = entry.start + ( GetTime ( ) - entry.pauseStartTime )
entry.pauseStartTime = entry.start
--UNIT_BOSS_MOD_BARS [guid][id].paused = false
--UNIT_BOSS_MOD_BARS [guid][id].start = entry.start + (GetTime() - entry.pauseStartTime)
--UNIT_BOSS_MOD_BARS [guid][id].pauseStartTime = entry.start
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1
end
end
DBM : RegisterCallback ( " DBM_NameplateResume " , timerResumeCallback )
--timer stop
local timerEndCallback = function ( event , id )
if event ~= " DBM_NameplateStop " and not ( DBM_TIMER_BARS_TEST_MODE and event == " DBM_TimerStop " ) then return end
if not id then return end
local guid = Plater.BossModsTimeBarDBM [ id ] and Plater.BossModsTimeBarDBM [ id ] . guid
Plater.BossModsTimeBarDBM [ id ] = nil
if guid then
UNIT_BOSS_MOD_BARS [ guid ] = UNIT_BOSS_MOD_BARS [ guid ] or { }
UNIT_BOSS_MOD_BARS [ guid ] [ id ] = nil
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1
elseif not guid and DBM_TIMER_BARS_TEST_MODE then
for _ , guid in pairs ( getAllShownGUIDs ( ) ) do
UNIT_BOSS_MOD_BARS [ guid ] = UNIT_BOSS_MOD_BARS [ guid ] or { }
UNIT_BOSS_MOD_BARS [ guid ] [ id ] = nil
UNIT_BOSS_MOD_NEEDS_UPDATE_IN [ guid ] = - 1
end
end
end
DBM : RegisterCallback ( " DBM_NameplateStop " , timerEndCallback )
--test mode start
local testModeStartCallback = function ( event , timer )
if event ~= " DBM_TestModStarted " then return end
DBM_TIMER_BARS_TEST_MODE = true
DBM : RegisterCallback ( " DBM_TimerStart " , timerStartCallback )
DBM : RegisterCallback ( " DBM_TimerStop " , timerEndCallback )
C_Timer.After ( tonumber ( timer ) or 10 , function ( )
DBM_TIMER_BARS_TEST_MODE = false
DBM : UnregisterCallback ( " DBM_TimerStart " , timerStartCallback )
DBM : UnregisterCallback ( " DBM_TimerStop " , timerEndCallback )
end )
end
DBM : RegisterCallback ( " DBM_TestModStarted " , testModeStartCallback )
end
--check if BigWigs is installed
if ( BigWigsLoader ) then
function Plater : BigWigs_BarCreated ( ... )
local event , self , bar , module , key , text , time , icon , isApprox = ...
if ( event == " BigWigs_BarCreated " ) then
if ( key ) then
---@type bwtimerbar
local barData = {
msg = text ,
id = key ,
timer = time ,
start = GetTime ( ) ,
icon = icon ,
spellId = key ,
barType = " cdnp " , --bar,
--color = {1,1,1,1},
--colorId = colorId,
modId = ( module and ( module.moduleName or module.name ) ) or " N/A " ,
--keep = keep,
--fade = fade,
name = text ,
--guid = guid,
paused = false ,
}
Plater.BossModsTimeBarBW [ key ] = barData
end
end
end
if ( BigWigsLoader.RegisterMessage ) then
BigWigsLoader.RegisterMessage ( Plater , " BigWigs_BarCreated " )
end
end
end
Plater.RegisterBossModsBars ( )