local addonName, XSM = ... local BarWidth = 200 local BarHeight = 15 local FontSize = 10 XSM = XSM or {} XSM.ShieldSpells = { 17, -- Power Word: Shield -- Regular Ability 123258, -- Power Word: Shield -- Modified by Angelic Bulwhark (108946), Divine Insight (123266) 47753, -- Divine Aegis (1) -- Modified by Angelic Bulwhark (108946) 114908, -- Spirit Shell 77613, -- Grace 59889, -- Borrowed Time } XSM.PlayerSpells = { 17, -- Power Word: Shield -- Regular Ability 123258, -- Power Word: Shield -- Modified by Angelic Bulwhark (108946), Divine Insight (123266) 47753, -- Divine Aegis (1) -- Modified by Angelic Bulwhark (108946) 114908, -- Spirit Shell -- 47517, -- Grace -- Modifies Flash Heal, Greater Heal, Penance 77613, -- Grace 59889, -- Borrowed Time 109175, -- Divine Insight (75) -- Applies Aura Divine Insight (124430/123266/123267) 123266, -- Divine Insight -- Modifies Power Word Shield (17) 123267, -- Divine Insight 124430, -- Divine Insight 108946, -- Angelic Bulwhark -- Modifies Power Word: Shield (17), Spirit Shell (109964) 114214, -- Angelic Bulwhark (1) -- Regular Ability ? } XSM.PlayerCooldowns = { 109964, -- Spirit Shell (28) -- Modifies Heals to absorb - Modified By Angelic Bulwhark (108946) 47750, -- Penance 47540, -- Penance (Discipline) 52798, -- Borrowed Time ( Discipline ) -- Applies Aura 59889 } XSM.SetMovable = function(self,frame) if not frame then return end frame:EnableMouse(true) frame:SetMovable(true) frame:RegisterForDrag("LeftButton") frame:SetScript("OnDragStart",function(self) self:StartMoving() end) frame:SetScript("OnDragStop",function(self) self:StopMovingOrSizing() self:SetUserPlaced(true) self:SetClampedToScreen(true) end) frame:SetScript("OnHide",function(self) self:StopMovingOrSizing() self:SetUserPlaced(true) self:SetClampedToScreen(true) end) end XSM.CreateShieldFrame = function(self,unit) local f = CreateFrame("Frame","XSM_"..unit.."ShieldMonitor",UIParent,"SecureHandlerStateTemplate") f.unit = unit f:SetWidth(BarWidth) f:SetHeight(BarHeight * 3) self:SetMovable(f) if ( not f:IsUserPlaced() ) then f:SetPoint("CENTER") end f:SetBackdrop(self.Backdrop["Tooltip4"]) f:SetBackdropColor(self.BackdropColor["Tooltip4"]) f.Name = f:CreateFontString(nil,"OVERLAY") f.Name:SetFont("Fonts\\FRIZQT__.TTF",FontSize,"THICKOUTLINE") f.Name:SetPoint("TOP",f,"TOP",0,-5) f.Name:SetJustifyV("CENTER") f.Name:SetJustifyH("MIDDLE") f.Name:SetText(unit) f.Name:SetHeight(BarHeight) f.Shield = CreateFrame("StatusBar","$parentShield",f) f.Shield:SetWidth(BarWidth - 10) f.Shield:SetHeight(BarHeight) f.Shield:SetOrientation("HORIZONTAL") f.Shield:SetMinMaxValues(0,100) f.Shield:SetStatusBarColor(0,1,0,1) f.Shield:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar") f.Shield:SetValue(0) f.Shield:SetPoint("BOTTOMLEFT",f,"BOTTOMLEFT",5,5) f.Shield.Background = f.Shield:CreateTexture(nil,"BACKGROUND") f.Shield.Background:SetAllPoints() f.Shield.Background:Show() f.Shield.Text = f.Shield:CreateFontString(nil,"OVERLAY") f.Shield.Text:SetFont("Fonts\\FRIZQT__.TTF",FontSize,"THICKOUTLINE") f.Shield.Text:SetHeight(BarHeight - 5) f.Shield.Text:SetWidth(BarWidth - 5) f.Shield.Text:SetJustifyV("CENTER") f.Shield.Text:SetJustifyH("MIDDLE") f.Shield.Text:SetAllPoints() f.Shield.Text:SetText("Test") f.Shield.Text:Show() f.Shield:Show() f.Icons = {} local firstIcon,lastIcon = nil,nil for i,v in pairs(f.unit == "player" and XSM.PlayerSpells or XSM.ShieldSpells) do f.Icons[v] = CreateFrame("Frame","$parent_Icon_"..v,f) f.Icons[v]:SetWidth(32) f.Icons[v]:SetHeight(32) if i == 1 then f.Icons[v]:SetPoint("TOPLEFT",f,"BOTTOMLEFT",5,-5) lastLineIcon = v elseif math.fmod(i,6) == 1 then f.Icons[v]:SetPoint("TOPLEFT",f.Icons[lastLineIcon],"BOTTOMLEFT",0,0) lastLineIcon = v else f.Icons[v]:SetPoint("TOPLEFT",f.Icons[lastIcon],"TOPRIGHT",0,0) end f.Icons[v]:SetScript("OnEnter",function(self) GameTooltip:SetOwner(self,"ANCHOR_CURSOR") GameTooltip:SetSpellByID(v) GameTooltip:AddLine(string.format("Spell ID: %d",v),1.0,1.0,1.0,1.0) GameTooltip:Show() end) f.Icons[v]:SetScript("OnLeave",function(self) GameTooltip:Hide() end) f.Icons[v].Texture = f.Icons[v]:CreateTexture(nil,"ARTWORK") f.Icons[v].Texture:SetTexture(GetSpellTexture(v)) f.Icons[v].Texture:SetAllPoints() f.Icons[v].Texture:Show() f.Icons[v].Caption = f.Icons[v]:CreateFontString(nil,"OVERLAY","GameFontNormal") f.Icons[v].Caption:SetFont("Fonts\\FRIZQT__.TTF",FontSize,"OUTLINE") f.Icons[v].Caption:SetJustifyV("CENTER") f.Icons[v].Caption:SetJustifyH("MIDDLE") f.Icons[v].Caption:SetAllPoints() f.Icons[v].Caption:Show() f.Icons[v].Cooldown = CreateFrame("Cooldown","$parent_Cooldown",f.Icons[v],"CooldownFrameTemplate") f.Icons[v].Duration = CreateFrame("Cooldown","$parent_Duration",f.Icons[v],"CooldownFrameTemplate") f.Icons[v].Duration:SetScript("OnUpdate",function(self,elapsed) local spellName = GetSpellInfo(v) if not f.Icons[v].AuraActivated then return end f.Icons[v].AuraCounter = f.Icons[v].AuraCounter + elapsed f.Icons[v].AuraLeft = f.Icons[v].AuraDuration - f.Icons[v].AuraCounter if f.Icons[v].LastAuraLeft and f.Icons[v].AuraLeft > f.Icons[v].LastAuraLeft then CooldownFrame_SetTimer(self,f.Icons[v].AuraStart,f.Icons[v].AuraDuration,true) f.Icons[v].DurationStarted = true end f.Icons[v].Caption:SetText(string.format("%0.2d",f.Icons[v].AuraLeft)) local percLeft = (( f.Icons[v].AuraLeft / f.Icons[v].AuraDuration ) * 100 ) local auraName = UnitAura(f.unit or unit,spellName,"PLAYER HELPFUL") if ( not auraName and spellId == v or f.Icons[v].AuraLeft < 0 ) then f.Icons[v].AuraActivated = false f.Icons[v].Caption:SetText("") f.Icons[v].DurationStarted = false f.Icons[v]:SetAlpha(0.25) end f.Icons[v].LastAuraLeft = f.Icons[v].AuraLeft end) f.Icons[v]:SetAlpha(0.25) f.Icons[v]:Show() lastIcon = v end f.RefreshAbsorb = function(self) if f.Shield then f.MaxAbsorb = f.MaxAbsorb or UnitGetTotalAbsorbs(f.unit) or 0 f.CurrAbsorb = UnitGetTotalAbsorbs(f.unit) or 0 if ( f.CurrAbsorb > f.MaxAbsorb ) then f.MaxAbsorb = f.CurrAbsorb end f.PercAbsorb = f.MaxAbsorb > 0 and ((f.CurrAbsorb / f.MaxAbsorb) * 100) or 0 if f.PercAbsorb < 0 then f.MaxAbsorb = 0 f.CurrAbsorb = 0 f.PercAbsorb = 0 end f.Shield:SetValue( f.PercAbsorb ) HealthBar_OnValueChanged(f.Shield,f.PercAbsorb,true) f.Shield.Text:SetText(AbbreviateLargeNumbers(f.CurrAbsorb) .. " / " .. AbbreviateLargeNumbers(f.MaxAbsorb) .. " (" .. string.format("%0.2d",f.PercAbsorb) .. "% )") f.Shield.TextString = f.Shield.Text:GetText() f.LastAbsorb = f.CurrAbsorb end end f.RefreshName = function(self) local name = GetUnitName(f.unit) or "" local unitText = "(" .. f.unit ..")" f.Name:SetText(name .. unitText) end f.RefreshAuras = function(self) for i = 1,40 do local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, canStealOrPurge, shouldConsolidate, spellId, canApplyAura, isBossDebuff, isCastByPlayer, auraData1,auraData2,auraData3 = UnitAura(f.unit,i,"PLAYER HELPFUL") if name and name == "Divine Insight" then print(name,spellId) end if tContains(XSM.ShieldSpells,spellId) and name then f.Icons[tonumber(spellId)].AuraStart = GetTime() f.Icons[tonumber(spellId)].AuraDuration = expirationTime - f.Icons[tonumber(spellId)].AuraStart f.Icons[tonumber(spellId)].AuraCounter = 0 f.Icons[tonumber(spellId)].AuraEnabled = true f.Icons[tonumber(spellId)].AuraActivated = true if ( not f.Icons[tonumber(spellId)].DurationStarted ) then CooldownFrame_SetTimer(f.Icons[tonumber(spellId)].Duration,f.Icons[tonumber(spellId)].AuraStart,f.Icons[tonumber(spellId)].AuraDuration,true) f.Icons[tonumber(spellId)].DurationStarted = true end f.Icons[tonumber(spellId)]:SetAlpha(1) end end end f.RefreshUnit = function(self) f.RefreshName() f.RefreshAbsorb() f.RefreshAuras() end RegisterStateDriver(f,"visibility","[@"..unit..",exists] show;hide") f:SetShown(UnitExists(unit)) f:RegisterUnitEvent("UNIT_AURA",unit) f:RegisterUnitEvent("UNIT_ABSORB_AMOUNT_CHANGED",unit) f:RegisterUnitEvent("UNIT_TARGET",unit) f:RegisterEvent("PLAYER_ENTERING_WORLD") f:SetScript("OnEvent",function(self,event,...) if event == "UNIT_TARGET" and f.unit == "player" then if UnitExists("target") then f.TargetFrame:RefreshUnit() end elseif event == "UNIT_TARGET" and f.unit == "target" then if UnitExists("targettarget") then f.TargetFrame:RefreshUnit() end elseif event == "UNIT_TARGET" and f.unit == "focus" then if UnitExists("focustarget") then f.TargetFrame:RefreshUnit() end elseif event == "UNIT_FOCUS" and f.unit == "player" then if UnitExists("focus") then f.FocusFrame:RefreshUnit() end elseif event == "UNIT_ABSORB_AMOUNT_CHANGED" and f.unit == ... then f:RefreshAbsorb() elseif event == "UNIT_AURA" and ... == f.unit then f:RefreshAuras() elseif event == "PLAYER_ENTERING_WORLD" then f.MaxAbsorb = 0 f.CurrAbsorb = 0 f.PercAbsorb = 0 f.LastAbsorb = 0 f:RefreshUnit() if f.TargetFrame and UnitExists(f.TargetFrame.unit) then f.TargetFrame:RefreshUnit() f.TargetFrame.TargetFrame:RefreshUnit() end if f.FocusFrame and UnitExists(f.FocusFrame.unit) then f.FocusFrame:RefreshUnit() f.FocusFrame.TargetFrame:RefreshUnit() end end end) return f end XSM.Events = CreateFrame("Frame") -- check any events and deal with accordingly XSM.Events:SetScript("OnEvent",function(self,event,...) local args = { ... } if ( event == "ADDON_LOADED" and args[1] == addonName ) then --XSM:CreateFrames() XSM.PlayerFrame = XSM:CreateShieldFrame("player") XSM.TargetFrame = XSM:CreateShieldFrame("target") XSM.PlayerFrame.TargetFrame = XSM.TargetFrame XSM.FocusFrame = XSM:CreateShieldFrame("focus") XSM.PlayerFrame.FocusFrame = XSM.FocusFrame end end) XSM.Events:RegisterEvent("ADDON_LOADED")