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.
384 lines
11 KiB
384 lines
11 KiB
|
3 years ago
|
-- Neuron is a World of Warcraft® user interface addon.
|
||
|
|
-- Copyright (c) 2017-2021 Britt W. Yazel
|
||
|
|
-- Copyright (c) 2006-2014 Connor H. Chenoweth
|
||
|
|
-- This code is licensed under the MIT license (see LICENSE for details)
|
||
|
|
|
||
|
|
local _, addonTable = ...
|
||
|
|
local Neuron = addonTable.Neuron
|
||
|
|
|
||
|
|
---@class CastButton : StatusButton @define class CastButton inherits from class StatusButton
|
||
|
|
local CastButton = setmetatable({}, { __index = Neuron.StatusButton })
|
||
|
|
Neuron.CastButton = CastButton
|
||
|
|
|
||
|
|
local L = LibStub("AceLocale-3.0"):GetLocale("Neuron")
|
||
|
|
|
||
|
|
local castWatch = {}
|
||
|
|
|
||
|
|
CastButton.sbStrings = {
|
||
|
|
[1] = { L["None"], function(self) return "" end },
|
||
|
|
[2] = { L["Spell"], function(self) if castWatch[self:GetUnit()] then return castWatch[self:GetUnit()].spell end end },
|
||
|
|
[3] = { L["Timer"], function(self) if castWatch[self:GetUnit()] then return castWatch[self:GetUnit()].timer end end },
|
||
|
|
}
|
||
|
|
|
||
|
|
--these used to be a part of the core UI before being removed in 10.0
|
||
|
|
local CASTING_BAR_ALPHA_STEP = 0.05
|
||
|
|
local CASTING_BAR_FLASH_STEP = 0.2
|
||
|
|
local CASTING_BAR_HOLD_TIME = 1
|
||
|
|
|
||
|
|
---Constructor: Create a new Neuron Button object (this is the base object for all Neuron button types)
|
||
|
|
---@param bar Bar @Bar Object this button will be a child of
|
||
|
|
---@param buttonID number @Button ID that this button will be assigned
|
||
|
|
---@param defaults table @Default options table to be loaded onto the given button
|
||
|
|
---@return CastButton @ A newly created StatusButton object
|
||
|
|
function CastButton.new(bar, buttonID, defaults)
|
||
|
|
--call the parent object constructor with the provided information specific to this button type
|
||
|
|
local newButton = Neuron.StatusButton.new(bar, buttonID, defaults, CastButton, "CastBar", "Cast Button")
|
||
|
|
|
||
|
|
return newButton
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
function CastButton:InitializeButton()
|
||
|
|
self:RegisterEvent("UNIT_SPELLCAST_START", "OnEvent")
|
||
|
|
self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", "OnEvent")
|
||
|
|
self:RegisterEvent("UNIT_SPELLCAST_FAILED", "OnEvent")
|
||
|
|
self:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED", "OnEvent")
|
||
|
|
self:RegisterEvent("UNIT_SPELLCAST_DELAYED", "OnEvent")
|
||
|
|
self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START", "OnEvent")
|
||
|
|
self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", "OnEvent")
|
||
|
|
self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", "OnEvent")
|
||
|
|
|
||
|
|
if Neuron.isWoWRetail then
|
||
|
|
self:RegisterEvent("UNIT_SPELLCAST_INTERRUPTIBLE", "OnEvent")
|
||
|
|
self:RegisterEvent("UNIT_SPELLCAST_NOT_INTERRUPTIBLE", "OnEvent")
|
||
|
|
end
|
||
|
|
|
||
|
|
self.holdTime = 0
|
||
|
|
|
||
|
|
self:SetScript("OnUpdate", function(self, elapsed) self:OnUpdate(elapsed) end)
|
||
|
|
|
||
|
|
self.StatusBar:Hide()
|
||
|
|
self.typeString = L["Cast Bar"]
|
||
|
|
|
||
|
|
self:InitializeButtonSettings()
|
||
|
|
end
|
||
|
|
|
||
|
|
function CastButton:OnEvent(event,...)
|
||
|
|
local unit = select(1, ...)
|
||
|
|
local eventCastID = select(2,...) --return payload is "unitTarget", "castGUID", spellID
|
||
|
|
|
||
|
|
if unit ~= self:GetUnit() then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if not castWatch[unit] then
|
||
|
|
castWatch[unit] = {}
|
||
|
|
end
|
||
|
|
|
||
|
|
if event == "UNIT_SPELLCAST_START" then
|
||
|
|
local name, text, texture, startTime, endTime, isTradeSkill, castID, notInterruptible
|
||
|
|
if Neuron.isWoWRetail then
|
||
|
|
name, text, texture, startTime, endTime, isTradeSkill, castID, notInterruptible = UnitCastingInfo(unit)
|
||
|
|
else
|
||
|
|
name, text, texture, startTime, endTime, isTradeSkill, castID, notInterruptible = CastingInfo() --classic doesn't have UnitCastingInfo()
|
||
|
|
end
|
||
|
|
|
||
|
|
if not name then
|
||
|
|
self:Reset()
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
self.StatusBar:SetStatusBarColor(self.config.castColor[1], self.config.castColor[2], self.config.castColor[3])
|
||
|
|
|
||
|
|
self.StatusBar.Spark:SetTexture("Interface\\AddOns\\Neuron\\Images\\CastingBar_Spark_"..self.orientation)
|
||
|
|
self.StatusBar.Spark:Show()
|
||
|
|
|
||
|
|
|
||
|
|
self.value = (GetTime()-(startTime/1000))
|
||
|
|
self.maxValue = (endTime-startTime)/1000
|
||
|
|
self.StatusBar:SetMinMaxValues(0, self.maxValue)
|
||
|
|
self.StatusBar:SetValue(self.value)
|
||
|
|
|
||
|
|
self.StatusBar.totalTime = self.maxValue - self.StatusBar:GetValue()
|
||
|
|
|
||
|
|
castWatch[unit].spell = text
|
||
|
|
|
||
|
|
if self:GetShowIcon() then
|
||
|
|
self.StatusBar.Icon:SetTexture(texture)
|
||
|
|
self.StatusBar.Icon:Show()
|
||
|
|
|
||
|
|
if notInterruptible then
|
||
|
|
self.StatusBar.Shield:Show()
|
||
|
|
else
|
||
|
|
self.StatusBar.Shield:Hide()
|
||
|
|
end
|
||
|
|
else
|
||
|
|
self.StatusBar.Icon:Hide()
|
||
|
|
self.StatusBar.Shield:Hide()
|
||
|
|
end
|
||
|
|
|
||
|
|
self.StatusBar:SetAlpha(1.0)
|
||
|
|
self.holdTime = 0
|
||
|
|
self.casting = true
|
||
|
|
self.castID = castID
|
||
|
|
self.channeling = nil
|
||
|
|
self.fadeout = nil
|
||
|
|
|
||
|
|
self.StatusBar:Show()
|
||
|
|
|
||
|
|
elseif event == "UNIT_SPELLCAST_CHANNEL_START" then
|
||
|
|
local name, text, texture, startTime, endTime, isTradeSkill, notInterruptible = UnitChannelInfo(unit)
|
||
|
|
|
||
|
|
if not name then
|
||
|
|
self:Reset()
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
self.StatusBar:SetStatusBarColor(self.config.channelColor[1], self.config.channelColor[2], self.config.channelColor[3])
|
||
|
|
|
||
|
|
self.value = ((endTime/1000)-GetTime())
|
||
|
|
self.maxValue = (endTime - startTime) / 1000;
|
||
|
|
self.StatusBar:SetMinMaxValues(0, self.maxValue);
|
||
|
|
self.StatusBar:SetValue(self.value)
|
||
|
|
|
||
|
|
castWatch[unit].spell = text
|
||
|
|
|
||
|
|
if self:GetShowIcon() then
|
||
|
|
|
||
|
|
self.StatusBar.Icon:SetTexture(texture)
|
||
|
|
self.StatusBar.Icon:Show()
|
||
|
|
|
||
|
|
if notInterruptible then
|
||
|
|
self.StatusBar.Shield:Show()
|
||
|
|
else
|
||
|
|
self.StatusBar.Shield:Hide()
|
||
|
|
end
|
||
|
|
else
|
||
|
|
self.StatusBar.Icon:Hide()
|
||
|
|
self.StatusBar.Shield:Hide()
|
||
|
|
end
|
||
|
|
|
||
|
|
self.StatusBar.Spark:Hide()
|
||
|
|
|
||
|
|
self.StatusBar:SetAlpha(1.0)
|
||
|
|
self.holdTime = 0
|
||
|
|
self.casting = nil
|
||
|
|
self.channeling = true
|
||
|
|
self.fadeout = nil
|
||
|
|
|
||
|
|
self.StatusBar:Show()
|
||
|
|
|
||
|
|
elseif event == "UNIT_SPELLCAST_SUCCEEDED" and not self.channeling then --don't do anything with this event when channeling as it fires at each pulse of a spell channel
|
||
|
|
self.StatusBar:SetStatusBarColor(self.config.successColor[1], self.config.successColor[2], self.config.successColor[3])
|
||
|
|
|
||
|
|
elseif event == "UNIT_SPELLCAST_SUCCEEDED" and self.channeling then
|
||
|
|
-- do nothing (when Tranquility is channeling if reports UNIT_SPELLCAST_SUCCEEDED many times during the duration)
|
||
|
|
|
||
|
|
elseif (event == "UNIT_SPELLCAST_FAILED" or event == "UNIT_SPELLCAST_INTERRUPTED") and self.castID == eventCastID or event == "UNIT_SPELLCAST_CHANNEL_STOP" then
|
||
|
|
if self.StatusBar:IsShown() and (self.casting or self.channeling) and not self.fadeout then
|
||
|
|
self.StatusBar:SetValue(self.maxValue)
|
||
|
|
self.StatusBar:SetStatusBarColor(self.config.failColor[1], self.config.failColor[2], self.config.failColor[3])
|
||
|
|
self.StatusBar.Spark:Hide()
|
||
|
|
|
||
|
|
if event == "UNIT_SPELLCAST_FAILED" then
|
||
|
|
castWatch[unit].spell = FAILED
|
||
|
|
elseif event == "UNIT_SPELLCAST_CHANNEL_STOP" then
|
||
|
|
-- empty --
|
||
|
|
else
|
||
|
|
castWatch[unit].spell = INTERRUPTED
|
||
|
|
end
|
||
|
|
|
||
|
|
self.casting = nil
|
||
|
|
self.channeling = nil
|
||
|
|
self.fadeout = true
|
||
|
|
self.holdTime = GetTime() + CASTING_BAR_HOLD_TIME
|
||
|
|
end
|
||
|
|
|
||
|
|
elseif event == "UNIT_SPELLCAST_DELAYED" then
|
||
|
|
if self.StatusBar:IsShown() then
|
||
|
|
local name, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(unit)
|
||
|
|
if not name then
|
||
|
|
self:Reset()
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
self.value = (GetTime()-(startTime/1000))
|
||
|
|
self.maxValue = (endTime-startTime)/1000
|
||
|
|
self.StatusBar:SetMinMaxValues(0, self.maxValue)
|
||
|
|
|
||
|
|
if not self.casting then
|
||
|
|
self.StatusBar:SetStatusBarColor(self.config.castColor[1], self.config.castColor[2], self.config.castColor[3])
|
||
|
|
self.StatusBar.Spark:Show()
|
||
|
|
self.StatusBar.BarFlash:SetAlpha(0.0)
|
||
|
|
self.StatusBar.BarFlash:Hide()
|
||
|
|
|
||
|
|
self.casting = true
|
||
|
|
self.channeling = nil
|
||
|
|
self.flash = nil
|
||
|
|
self.fadeout = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
elseif event == "UNIT_SPELLCAST_CHANNEL_UPDATE" then
|
||
|
|
if self.StatusBar:IsShown() then
|
||
|
|
local name, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(unit)
|
||
|
|
if not name then
|
||
|
|
self:Reset()
|
||
|
|
return
|
||
|
|
end
|
||
|
|
self.value = ((endTime/1000)-GetTime())
|
||
|
|
self.maxValue = (endTime-startTime)/1000
|
||
|
|
self.StatusBar:SetMinMaxValues(0, self.maxValue)
|
||
|
|
self.StatusBar:SetValue(self.value)
|
||
|
|
end
|
||
|
|
|
||
|
|
elseif self.StatusBar.showShield and event == "UNIT_SPELLCAST_INTERRUPTIBLE" then
|
||
|
|
self.StatusBar.Shield:Hide()
|
||
|
|
|
||
|
|
elseif self.StatusBar.showShield and event == "UNIT_SPELLCAST_NOT_INTERRUPTIBLE" then
|
||
|
|
self.StatusBar.Shield:Show()
|
||
|
|
end
|
||
|
|
|
||
|
|
if not Neuron.barEditMode and not Neuron.buttonEditMode then
|
||
|
|
self.StatusBar.CenterText:SetText(self:cFunc())
|
||
|
|
self.StatusBar.LeftText:SetText(self:lFunc())
|
||
|
|
self.StatusBar.RightText:SetText(self:rFunc())
|
||
|
|
self.StatusBar.MouseoverText:SetText(self:mFunc())
|
||
|
|
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function CastButton:OnUpdate(elapsed)
|
||
|
|
if Neuron.pendingReload then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
--bail out if these values don't exist. Otherwise we will error later on
|
||
|
|
if not self.value and not self.maxValue then
|
||
|
|
self:Reset()
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if not castWatch[self:GetUnit()] then
|
||
|
|
castWatch[self:GetUnit()] = {}
|
||
|
|
end
|
||
|
|
if self.maxValue then
|
||
|
|
castWatch[self:GetUnit()].timer = string.format("%0.1f", self.value).."/"..format("%0.1f", self.maxValue)
|
||
|
|
else
|
||
|
|
castWatch[self:GetUnit()].timer = string.format("%0.1f", self.value)
|
||
|
|
end
|
||
|
|
|
||
|
|
if self.casting then
|
||
|
|
self.value = self.value + elapsed
|
||
|
|
if self.value >= self.maxValue then
|
||
|
|
self.StatusBar:SetValue(self.maxValue)
|
||
|
|
self:FinishCast()
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
self.StatusBar:SetValue(self.value)
|
||
|
|
self.StatusBar.BarFlash:Hide()
|
||
|
|
|
||
|
|
if self.orientation == 1 then
|
||
|
|
local sparkPosition = (self.value/self.maxValue)*self.StatusBar:GetWidth()
|
||
|
|
if sparkPosition < 0 then
|
||
|
|
sparkPosition = 0
|
||
|
|
end
|
||
|
|
self.StatusBar.Spark:SetPoint("CENTER", self.StatusBar, "LEFT", sparkPosition, 0)
|
||
|
|
else
|
||
|
|
local sparkPosition = (self.value/self.maxValue) * self.StatusBar:GetHeight()
|
||
|
|
if sparkPosition < 0 then
|
||
|
|
sparkPosition = 0
|
||
|
|
end
|
||
|
|
self.StatusBar.Spark:SetPoint("CENTER", self.StatusBar, "BOTTOM", 0, sparkPosition)
|
||
|
|
end
|
||
|
|
|
||
|
|
elseif self.channeling then
|
||
|
|
self.value = self.value - elapsed
|
||
|
|
if self.value <= 0 then
|
||
|
|
self:FinishCast()
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
self.StatusBar:SetValue(self.value)
|
||
|
|
self.StatusBar.BarFlash:Hide()
|
||
|
|
|
||
|
|
elseif GetTime() < self.holdTime then
|
||
|
|
return
|
||
|
|
|
||
|
|
elseif self.flash then
|
||
|
|
local alpha = self.StatusBar.BarFlash:GetAlpha() + CASTING_BAR_FLASH_STEP or 0
|
||
|
|
if alpha < 1 then
|
||
|
|
self.StatusBar.BarFlash:SetAlpha(alpha)
|
||
|
|
else
|
||
|
|
self.StatusBar.BarFlash:SetAlpha(1.0)
|
||
|
|
self.flash = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
elseif self.fadeout and (not Neuron.barEditMode and not Neuron.buttonEditMode) then
|
||
|
|
local alpha = self.StatusBar:GetAlpha() - CASTING_BAR_ALPHA_STEP
|
||
|
|
if alpha > 0 then
|
||
|
|
self.StatusBar:SetAlpha(alpha)
|
||
|
|
else
|
||
|
|
self:Reset()
|
||
|
|
end
|
||
|
|
else
|
||
|
|
self:Reset()
|
||
|
|
end
|
||
|
|
|
||
|
|
if not Neuron.barEditMode and not Neuron.buttonEditMode then
|
||
|
|
self.StatusBar.CenterText:SetText(self:cFunc())
|
||
|
|
self.StatusBar.LeftText:SetText(self:lFunc())
|
||
|
|
self.StatusBar.RightText:SetText(self:rFunc())
|
||
|
|
self.StatusBar.MouseoverText:SetText(self:mFunc())
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function CastButton:FinishCast()
|
||
|
|
self.StatusBar.Spark:Hide()
|
||
|
|
self.StatusBar.BarFlash:SetAlpha(1.0)
|
||
|
|
self.StatusBar.BarFlash:Show()
|
||
|
|
self.flash = true
|
||
|
|
self.fadeout = true
|
||
|
|
self.casting = nil
|
||
|
|
self.channeling = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
function CastButton:Reset()
|
||
|
|
self.fadeout = true
|
||
|
|
self.casting = nil
|
||
|
|
self.channeling = nil
|
||
|
|
self.StatusBar:SetStatusBarColor(self.config.castColor[1], self.config.castColor[2], self.config.castColor[3])
|
||
|
|
|
||
|
|
if not Neuron.barEditMode and not Neuron.buttonEditMode then
|
||
|
|
self.StatusBar:Hide()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-----------------------------------------------------
|
||
|
|
-------------------Sets and Gets---------------------
|
||
|
|
-----------------------------------------------------
|
||
|
|
|
||
|
|
---@alias BarUnit "player"|"pet"|"target"|"targettarget"|"focus"|"mouseover"|"party1"|"party2"|"party3"|"party4"
|
||
|
|
|
||
|
|
---@param unit BarUnid
|
||
|
|
function CastButton:SetUnit(unit)
|
||
|
|
if unit then
|
||
|
|
self.config.unit = unit
|
||
|
|
else
|
||
|
|
unit = "player"
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function CastButton:GetUnit()
|
||
|
|
return self.config.unit
|
||
|
|
end
|
||
|
|
|
||
|
|
function CastButton:SetShowIcon(show)
|
||
|
|
self.config.showIcon = show
|
||
|
|
end
|
||
|
|
|
||
|
|
function CastButton:GetShowIcon()
|
||
|
|
return self.config.showIcon
|
||
|
|
end
|