pfUI:RegisterModule("lossofcontrol", function () -- 5.x's loss of control alert. ClassicAPI's C_LossOfControl builds the -- effects from the player's debuffs and from the school lockout of an -- interrupt. local strings = L["lossofcontrol"] -- how much each effect takes away; the alert shows the strongest one local PRIORITY = { STUN = 3, FEAR = 3, CONFUSE = 3, CHARM = 3, POSSESS = 3, PACIFYSILENCE = 3, SILENCE = 2, SCHOOL_INTERRUPT = 2, PACIFY = 2, DISARM = 1, ROOT = 1, } -- the lockout packet does not name the interrupting spell local INTERRUPT_ICON = "Interface\\Icons\\Ability_Kick" local function IsStronger(data, best) local priority, bestPriority = PRIORITY[data.locType], PRIORITY[best.locType] if priority ~= bestPriority then return priority > bestPriority end return (data.timeRemaining or math.huge) > (best.timeRemaining or math.huge) end local frame = CreateFrame("Frame", "pfLossOfControl", UIParent) frame:SetSize(220, 48) frame:SetPoint("CENTER", 0, 120) frame:SetFrameStrata("HIGH") frame:Hide() frame.icon = CreateFrame("Frame", nil, frame) frame.icon:SetSize(48, 48) frame.icon:SetPoint("LEFT", 0, 0) CreateBackdrop(frame.icon, nil, true) frame.icon.tex = frame.icon:CreateTexture(nil, "ARTWORK") HandleIcon(frame.icon, frame.icon.tex) frame.cd = CreateFrame("Cooldown", nil, frame.icon, "CooldownFrameTemplate") frame.cd:SetAllPoints(frame.icon.tex) frame.cd.pfCooldownStyleAnimation = 1 -- the alert prints the time itself frame.cd.noCooldownCount = true frame.label = frame:CreateFontString(nil, "OVERLAY") frame.label:SetFont(pfUI.font_default, 20, "OUTLINE") frame.label:SetTextColor(NORMAL_FONT_COLOR:GetRGB()) frame.label:SetPoint("TOPLEFT", frame.icon, "TOPRIGHT", 8, -4) frame.time = frame:CreateFontString(nil, "OVERLAY") frame.time:SetFont(pfUI.font_default, 14, "OUTLINE") frame.time:SetPoint("BOTTOMLEFT", frame.icon, "BOTTOMRIGHT", 8, 4) frame.Refresh = function(self) local best for i = 1, C_LossOfControl.GetActiveLossOfControlDataCount() do local data = C_LossOfControl.GetActiveLossOfControlData(i) if not best or IsStronger(data, best) then best = data end end if not best then if pfUI.unlock and pfUI.unlock:IsShown() then return end self:Hide() return end if best.locType == "SCHOOL_INTERRUPT" then self.label:SetText(format(strings.LOSS_OF_CONTROL_DISPLAY_INTERRUPT_SCHOOL, C_Spell.GetSchoolString(best.lockoutSchool))) self.icon.tex:SetTexture(INTERRUPT_ICON) else self.label:SetText(strings["LOSS_OF_CONTROL_DISPLAY_" .. best.locType]) self.icon.tex:SetTexture(best.iconTexture) end -- a refreshed effect or a second kick on the same school changes the -- timer without an event, so this runs again while the alert shows if self.start ~= best.startTime or self.duration ~= best.duration then self.start, self.duration = best.startTime, best.duration CooldownFrame_SetTimer(self.cd, best.startTime or 0, best.duration or 0, best.startTime and 1 or 0) end self.time:SetText(best.timeRemaining and format("%.1f %s", best.timeRemaining, strings.LOSS_OF_CONTROL_SECONDS) or "") self:Show() end frame:SetScript("OnUpdate", function() if ( this.tick or 0) > GetTime() then return else this.tick = GetTime() + .1 end this:Refresh() end) pfUI.events:RegisterFrameEventAndCallback("LOSS_OF_CONTROL_ADDED", function() frame:Refresh() end) pfUI.events:RegisterFrameEventAndCallback("LOSS_OF_CONTROL_UPDATE", function() frame:Refresh() end) UpdateMovable(frame) pfUI.lossofcontrol = frame end)