From cbac9297d011d5c783721556dc175537b88a7c55 Mon Sep 17 00:00:00 2001 From: Vollmer Date: Tue, 17 Dec 2024 19:35:15 +0100 Subject: [PATCH] [Feature] Add 'Interrupted' Cast Bar (#194) * add defaults * add menu options * add consts * implement functionality * label %i => %t * locale and tooltips --- Data/Constants.lua | 2 ++ Data/Defaults.lua | 3 +++ Locales/enUS.lua | 5 +++++ Menu/Builder.lua | 14 +++++++++++++- WidgetAnnotations.lua | 3 +++ Widgets/Bars/CastBar.lua | 36 +++++++++++++++++++++++++++++++++++- 6 files changed, 61 insertions(+), 2 deletions(-) diff --git a/Data/Constants.lua b/Data/Constants.lua index e7a09b2..4b9771d 100644 --- a/Data/Constants.lua +++ b/Data/Constants.lua @@ -178,6 +178,8 @@ const.OPTION_KIND = { GLOW = "glow", SHOW_TARGET = "showTarget", TARGET_SEPARATOR = "targetSeparator", + TIME_TO_HOLD = "timeToHold", + INTERRUPTED_LABEL = "interruptedLabel", } ---@enum AURA_OPTION_KIND diff --git a/Data/Defaults.lua b/Data/Defaults.lua index d324ca6..54e4f71 100644 --- a/Data/Defaults.lua +++ b/Data/Defaults.lua @@ -668,6 +668,9 @@ Defaults.Widgets = { frameLevel = 10, onlyShowInterrupt = false, anchorToParent = true, + timeToHold = 0, + interruptedLabel = "%t", + showInterruptedSpell = false, position = { point = "TOPLEFT", offsetY = -30, diff --git a/Locales/enUS.lua b/Locales/enUS.lua index f7cc704..2d42544 100644 --- a/Locales/enUS.lua +++ b/Locales/enUS.lua @@ -242,6 +242,11 @@ L.playerCastBar = "Player Cast Bar" L.HideAtMaxLevel = "Hide at Max Level" L.ShowTarget = "Show Target" L.Separator = "Separator" +L.TimeToHold = "Time to Hold" +L.TimeToHoldTooltip = "Time in seconds to hold the Cast Bar after the spell has failed or been interrupted" +L.Label = "Label" +L.InterruptedLabelTooltip = [[%s - Type (%s or %s) +%s - Spell Name]] -- Custom Formats L.ValidTags = "Valid Tags" diff --git a/Menu/Builder.lua b/Menu/Builder.lua index 7b911cb..393dd1c 100644 --- a/Menu/Builder.lua +++ b/Menu/Builder.lua @@ -64,6 +64,9 @@ Builder.MenuOptions = { Glow = 37 } +local FAILED = FAILED or "Failed" +local INTERRUPTED = INTERRUPTED or "Interrupted" + ------------------------------------------------- -- MARK: Build Menu ------------------------------------------------- @@ -1555,7 +1558,7 @@ function Builder:CreateCastBarGeneralOptions(parent, widgetName) ---@class CastBarOptions: OptionsFrame local f = CUF:CreateFrame(nil, parent, 1, 1, true, true) f.id = "CastBarOptions" - f.optionHeight = 135 + f.optionHeight = 195 -- Title f.title = self:CreateOptionTitle(f, "General") @@ -1575,6 +1578,15 @@ function Builder:CreateCastBarGeneralOptions(parent, widgetName) const.OPTION_KIND.ONLY_SHOW_INTERRUPT) self:AnchorBelowCB(f.onlyShowInterruptableCB, f.reverseCB) + f.timeToHoldSlider = self:CreateSlider(f, widgetName, L.TimeToHold, nil, 0, 10, const.OPTION_KIND.TIME_TO_HOLD) + self:AnchorBelow(f.timeToHoldSlider, f.onlyShowInterruptableCB) + CUF:SetTooltips(f.timeToHoldSlider, "ANCHOR_TOPLEFT", 0, 3, L.TimeToHold, L.TimeToHoldTooltip) + + f.interruptedLabelEditBox = self:CreateEditBox(f, widgetName, L.Label, nil, const.OPTION_KIND.INTERRUPTED_LABEL) + self:AnchorRight(f.interruptedLabelEditBox, f.timeToHoldSlider) + CUF:SetTooltips(f.interruptedLabelEditBox, "ANCHOR_TOPLEFT", 0, 3, L.Label, + string.format(L.InterruptedLabelTooltip, "%t", INTERRUPTED, FAILED, "%s")) + local function LoadPageDB() f.onlyShowInterruptableCB:SetEnabled(CUF.vars.selectedUnit ~= const.UNIT.PLAYER) end diff --git a/WidgetAnnotations.lua b/WidgetAnnotations.lua index c0996bf..26768f9 100644 --- a/WidgetAnnotations.lua +++ b/WidgetAnnotations.lua @@ -276,6 +276,9 @@ ---@field icon CastBarIconOpt ---@field useClassColor boolean ---@field onlyShowInterrupt boolean +---@field timeToHold number +---@field interruptedLabel string +---@field showInterruptedSpell boolean ---@class CastBarSparkOpt ---@field enabled boolean diff --git a/Widgets/Bars/CastBar.lua b/Widgets/Bars/CastBar.lua index 08fef37..16a0240 100644 --- a/Widgets/Bars/CastBar.lua +++ b/Widgets/Bars/CastBar.lua @@ -15,6 +15,9 @@ local Builder = CUF.Builder local Handler = CUF.Handler local P = CUF.PixelPerfect +local FAILED = FAILED or "Failed" +local INTERRUPTED = INTERRUPTED or "Interrupted" + ------------------------------------------------- -- MARK: AddWidget ------------------------------------------------- @@ -62,6 +65,12 @@ function W.UpdateCastBarWidget(button, unit, setting, subSetting, ...) if not setting or setting == const.OPTION_KIND.TARGET_SEPARATOR then castBar.spellText.targetSeparator = styleTable.targetSeparator end + if not setting or setting == const.OPTION_KIND.TIME_TO_HOLD then + castBar.timeToHold = styleTable.timeToHold + end + if not setting or setting == const.OPTION_KIND.INTERRUPTED_LABEL then + castBar.interruptedLabel = styleTable.interruptedLabel + end if not setting or setting == const.OPTION_KIND.SPARK then castBar.spark.enabled = styleTable.spark.enabled @@ -244,6 +253,8 @@ function CastStart(button, event, unit, castGUID) castBar.max = endTime - startTime castBar.startTime = startTime + castBar.holdTime = 0 + castBar.notInterruptible = notInterruptible castBar.castID = castID castBar.spellID = spellID @@ -363,6 +374,21 @@ function CastFail(button, event, unit, castID, spellID) return end + if castBar.timeToHold > 0 then + castBar.holdTime = castBar.timeToHold + + local type = event == 'UNIT_SPELLCAST_FAILED' and FAILED or INTERRUPTED + castBar.spellText:SetText(castBar.interruptedLabel:gsub("%%t", type):gsub("%%s", + castBar.displayName ~= "" and castBar.displayName or castBar.spellName or "")) + + if castBar.spark:IsShown() then + castBar.spark:Hide() + end + + castBar:SetValue(castBar.max) + castBar:SetCastBarColor() + end + castBar:ResetAttributes() end @@ -457,6 +483,8 @@ local function onUpdate(self, elapsed) self:OnUpdateStage() end end + elseif self.holdTime > 0 then + self.holdTime = self.holdTime - elapsed else self:ResetAttributes() self:Hide() @@ -726,7 +754,9 @@ end ---@param self CastBarWidget local function SetCastBarColor(self) - if self.useClassColor then + if self.holdTime > 0 then + self.statusBar:SetStatusBarColor(1, 0, 0, 1) + elseif self.useClassColor then local r, g, b = CUF.Util:GetUnitClassColor(self._owner.states.unit) self.statusBar:SetStatusBarColor(r, g, b, 1) elseif self.notInterruptible then @@ -901,6 +931,10 @@ function W:CreateCastBar(button) castBar.useClassColor = false castBar.onlyShowInterrupt = false + castBar.timeToHold = 0 + castBar.holdTime = 0 + castBar.interruptedLabel = "" + -- Number of stages in current empower castBar.NumStages = 0 -- Current stage defaults to CASTBAR_STAGE_INVALID (-1)