Compare commits

...

2 Commits

Author SHA1 Message Date
6a985bc67a Add Evoker, empowered casting support 2022-11-11 11:29:15 -06:00
3a5e58bf34 Add Spell ID support for aura tracking (#31) 2022-11-06 08:34:01 -06:00
10 changed files with 253 additions and 28 deletions

View File

@ -3,7 +3,7 @@ IceCastBar = IceCore_CreateClass(IceBarElement)
local IceHUD = _G.IceHUD local IceHUD = _G.IceHUD
IceCastBar.Actions = { None = 0, Cast = 1, Channel = 2, Instant = 3, Success = 4, Failure = 5 } IceCastBar.Actions = { None = 0, Cast = 1, Channel = 2, Instant = 3, Success = 4, Failure = 5, ReverseChannel = 6 }
IceCastBar.prototype.action = nil IceCastBar.prototype.action = nil
IceCastBar.prototype.actionStartTime = nil IceCastBar.prototype.actionStartTime = nil
@ -49,6 +49,13 @@ function IceCastBar.prototype:init(name)
self:SetDefaultColor("CastChanneling", 242, 242, 10) self:SetDefaultColor("CastChanneling", 242, 242, 10)
self:SetDefaultColor("CastSuccess", 242, 242, 70) self:SetDefaultColor("CastSuccess", 242, 242, 70)
self:SetDefaultColor("CastFail", 1, 0, 0) self:SetDefaultColor("CastFail", 1, 0, 0)
if GetUnitEmpowerMinHoldTime then
self:SetDefaultColor("EmpowerStage0", 165, 165, 165)
self:SetDefaultColor("EmpowerStage1", 242, 42, 10)
self:SetDefaultColor("EmpowerStage2", 242, 142, 10)
self:SetDefaultColor("EmpowerStage3", 242, 242, 10)
self:SetDefaultColor("EmpowerStage4", 242, 242, 242)
end
self.unit = "player" self.unit = "player"
self.delay = 0 self.delay = 0
@ -109,6 +116,12 @@ function IceCastBar.prototype:Enable(core)
self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", "SpellCastChannelUpdate") -- unit, spell, rank self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", "SpellCastChannelUpdate") -- unit, spell, rank
self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", "SpellCastChannelStop") -- unit, spell, rank self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", "SpellCastChannelStop") -- unit, spell, rank
if GetUnitEmpowerHoldAtMaxTime then
self:RegisterEvent("UNIT_SPELLCAST_EMPOWER_START", "SpellCastChannelStart")
self:RegisterEvent("UNIT_SPELLCAST_EMPOWER_UPDATE", "SpellCastChannelUpdate")
self:RegisterEvent("UNIT_SPELLCAST_EMPOWER_STOP", "SpellCastChannelStop")
end
end end
self:Show(false) self:Show(false)
end end
@ -311,7 +324,13 @@ function IceCastBar.prototype:PositionIcons()
self.barFrame.icon:SetHeight(AuraIconHeight * self.moduleSettings.auraIconScale) self.barFrame.icon:SetHeight(AuraIconHeight * self.moduleSettings.auraIconScale)
end end
function IceCastBar.prototype:GetRemainingCastTime()
return self.actionStartTime + self.actionDuration - GetTime()
end
function IceCastBar.prototype:GetCurrentCastDurationMs()
return (GetTime() - (self.actionStartTime or GetTime())) * 1000
end
-- OnUpdate handler -- OnUpdate handler
function IceCastBar.prototype:MyOnUpdate() function IceCastBar.prototype:MyOnUpdate()
@ -322,17 +341,15 @@ function IceCastBar.prototype:MyOnUpdate()
return return
end end
local time = GetTime()
self:Update() self:Update()
self:SetTextAlpha() self:SetTextAlpha()
-- handle casting and channeling -- handle casting and channeling
if (self.action == IceCastBar.Actions.Cast or self.action == IceCastBar.Actions.Channel) then if (self.action == IceCastBar.Actions.Cast or self.action == IceCastBar.Actions.Channel or self.action == IceCastBar.Actions.ReverseChannel) then
local remainingTime = self.actionStartTime + self.actionDuration - time local remainingTime = self:GetRemainingCastTime()
local scale = 1 - (self.actionDuration ~= 0 and remainingTime / self.actionDuration or 0) local scale = 1 - (self.actionDuration ~= 0 and remainingTime / self.actionDuration or 0)
if (self.moduleSettings.reverseChannel and self.action == IceCastBar.Actions.Channel) then if self.action == IceCastBar.Actions.ReverseChannel then
scale = self.actionDuration ~= 0 and remainingTime / self.actionDuration or 0 scale = self.actionDuration ~= 0 and remainingTime / self.actionDuration or 0
end end
@ -343,14 +360,22 @@ function IceCastBar.prototype:MyOnUpdate()
end end
local timeString = self.moduleSettings.showCastTime and string.format("%.1fs ", remainingTime) or "" local timeString = self.moduleSettings.showCastTime and string.format("%.1fs ", remainingTime) or ""
self:SetBottomText1(timeString .. self.actionMessage) local empowerString = self.NumStages ~= nil and (L["Stage %d"]):format(self:GetCurrentStage()) or ""
local line1 = timeString .. self.actionMessage
if self.moduleSettings.empowerStageTextDisplay == "TOPLINE" then
line1 = line1 .. " " .. empowerString
end
if self.moduleSettings.empowerStageTextDisplay == "BOTTOMLINE" then
self:SetBottomText2(empowerString)
end
self:SetBottomText1(line1)
return return
end end
-- stop bar if casting or channeling is done (in theory this should not be needed) -- stop bar if casting or channeling is done (in theory this should not be needed)
if (self.action == IceCastBar.Actions.Cast or self.action == IceCastBar.Actions.Channel) then if (self.action == IceCastBar.Actions.Cast or self.action == IceCastBar.Actions.Channel or self.action == IceCastBar.Actions.ReverseChannel) then
self:StopBar() self:StopBar()
return return
end end
@ -361,7 +386,7 @@ function IceCastBar.prototype:MyOnUpdate()
self.action == IceCastBar.Actions.Success or self.action == IceCastBar.Actions.Success or
self.action == IceCastBar.Actions.Failure) self.action == IceCastBar.Actions.Failure)
then then
local scale = time - self.actionStartTime local scale = GetTime() - self.actionStartTime
if (scale > 1) then if (scale > 1) then
self:StopBar() self:StopBar()
@ -381,12 +406,60 @@ function IceCastBar.prototype:MyOnUpdate()
self:StopBar() self:StopBar()
end end
function IceCastBar.prototype:GetCurrentCastingColor() function IceCastBar.prototype:GetStageDuration(stage)
local updateColor = "CastCasting" if not GetUnitEmpowerMinHoldTime then
if self.action == IceCastBar.Actions.Channel then return 0
updateColor = "CastChanneling"
end end
return updateColor
if stage == 0 then
return GetUnitEmpowerMinHoldTime(self.unit)
end
return GetUnitEmpowerStageDuration(self.unit, stage);
end
function IceCastBar.prototype:GetDurationUpToStage(stage)
if stage == nil or stage < 0 then
return 0
end
local total = 0
for i=0,stage-1 do
total = total + self:GetStageDuration(i)
end
return total
end
function IceCastBar.prototype:GetCurrentStage()
if not GetUnitEmpowerMinHoldTime then
return 0
end
local castDuration = self:GetCurrentCastDurationMs()
for i=1,self.NumStages do
if castDuration < self:GetDurationUpToStage(i) then
return i - 1
end
end
return self.NumStages
end
function IceCastBar.prototype:IsCastingEmpowerSpell()
return self.NumStages ~= nil
end
function IceCastBar.prototype:GetCurrentCastingColor()
if self:IsCastingEmpowerSpell() then
return ("EmpowerStage%d"):format(self:GetCurrentStage())
end
if self.action == IceCastBar.Actions.Channel or self.action == IceCastBar.Actions.ReverseChannel then
return "CastChanneling"
end
return "CastCasting"
end end
function IceCastBar.prototype:FlashBar(color, alpha, text, textColor) function IceCastBar.prototype:FlashBar(color, alpha, text, textColor)
@ -406,7 +479,7 @@ end
function IceCastBar.prototype:StartBar(action, message) function IceCastBar.prototype:StartBar(action, message)
local spell, rank, displayName, icon, startTime, endTime, isTradeSkill local spell, rank, displayName, icon, startTime, endTime, isTradeSkill, numStages
if IceHUD.SpellFunctionsReturnRank then if IceHUD.SpellFunctionsReturnRank then
spell, rank, displayName, icon, startTime, endTime, isTradeSkill = UnitCastingInfo(self.unit) spell, rank, displayName, icon, startTime, endTime, isTradeSkill = UnitCastingInfo(self.unit)
else else
@ -416,7 +489,24 @@ function IceCastBar.prototype:StartBar(action, message)
if IceHUD.SpellFunctionsReturnRank then if IceHUD.SpellFunctionsReturnRank then
spell, rank, displayName, icon, startTime, endTime = UnitChannelInfo(self.unit) spell, rank, displayName, icon, startTime, endTime = UnitChannelInfo(self.unit)
else else
spell, displayName, icon, startTime, endTime = UnitChannelInfo(self.unit) spell, displayName, icon, startTime, endTime, isTradeSkill, _, _, _, numStages = UnitChannelInfo(self.unit)
end
end
local isChargeSpell = numStages and numStages > 0
if isChargeSpell then
self.NumStages = numStages
endTime = endTime + GetUnitEmpowerHoldAtMaxTime(self.unit)
action = IceCastBar.Actions.ReverseChannel
else
self.NumStages = nil
end
if self.moduleSettings.reverseChannel then
if action == IceCastBar.Actions.Channel then
action = IceCastBar.Actions.ReverseChannel
elseif action == IceCastBar.Actions.ReverseChannel then
action = IceCastBar.Actions.Channel
end end
end end
@ -465,6 +555,7 @@ function IceCastBar.prototype:StopBar()
self.actionDuration = nil self.actionDuration = nil
self:SetBottomText1() self:SetBottomText1()
self:SetBottomText2()
self:SetScale(0) self:SetScale(0)
self:Show(false) self:Show(false)
end end
@ -514,7 +605,8 @@ function IceCastBar.prototype:SpellCastStop(event, unit, castGuid, spellId)
if (self.action ~= IceCastBar.Actions.Success and if (self.action ~= IceCastBar.Actions.Success and
self.action ~= IceCastBar.Actions.Failure and self.action ~= IceCastBar.Actions.Failure and
self.action ~= IceCastBar.Actions.Channel) self.action ~= IceCastBar.Actions.Channel and
self.action ~= IceCastBar.Actions.ReverseChannel)
then then
self:StopBar() self:StopBar()
self.current = nil self.current = nil
@ -532,7 +624,7 @@ function IceCastBar.prototype:SpellCastFailed(event, unit, castGuid, spellId)
end end
-- channeled spells will call ChannelStop, not cast failed -- channeled spells will call ChannelStop, not cast failed
if self.action == IceCastBar.Actions.Channel then if self.action == IceCastBar.Actions.Channel or self.action == IceCastBar.Actions.ReverseChannel then
return return
end end
@ -582,7 +674,7 @@ function IceCastBar.prototype:SpellCastSucceeded(event, unit, castGuid, spellId)
--IceHUD:Debug("SpellCastSucceeded", unit, castGuid, spellId) --IceHUD:Debug("SpellCastSucceeded", unit, castGuid, spellId)
-- never show on channeled (why on earth does this event even fire when channeling starts?) -- never show on channeled (why on earth does this event even fire when channeling starts?)
if (self.action == IceCastBar.Actions.Channel) then if (self.action == IceCastBar.Actions.Channel or self.action == IceCastBar.Actions.ReverseChannel) then
return return
end end

View File

@ -36,6 +36,7 @@ else
end end
-- compatibility/feature flags -- compatibility/feature flags
IceHUD.GetPlayerAuraBySpellID = _G["C_UnitAuras"] and C_UnitAuras.GetPlayerAuraBySpellID
IceHUD.SpellFunctionsReturnRank = IceHUD.WowMain and IceHUD.WowVer < 80000 IceHUD.SpellFunctionsReturnRank = IceHUD.WowMain and IceHUD.WowVer < 80000
IceHUD.EventExistsPlayerPetChanged = IceHUD.WowMain and IceHUD.WowVer < 80000 IceHUD.EventExistsPlayerPetChanged = IceHUD.WowMain and IceHUD.WowVer < 80000
IceHUD.EventExistsPetBarChanged = IceHUD.WowMain and IceHUD.WowVer < 80000 IceHUD.EventExistsPetBarChanged = IceHUD.WowMain and IceHUD.WowVer < 80000
@ -494,6 +495,16 @@ function IceHUD:GetAuraCount(auraType, unit, ability, onlyMine, matchByName)
return 0 return 0
end end
-- Support for Spell IDs
if (IceHUD.GetPlayerAuraBySpellID and tonumber(ability) ~= nil) then
local aura = C_UnitAuras.GetPlayerAuraBySpellID(ability)
if aura ~= nil then
return aura.applications
else
return 0
end
end
local i = 1 local i = 1
local name, _, texture, applications local name, _, texture, applications
if IceHUD.SpellFunctionsReturnRank then if IceHUD.SpellFunctionsReturnRank then

View File

@ -99,6 +99,7 @@ modules\Stagger.lua
modules\PlayerAltMana.lua modules\PlayerAltMana.lua
modules\ArcaneCharges.lua modules\ArcaneCharges.lua
modules\RollTheBones.lua modules\RollTheBones.lua
modules\EssencePower.lua
#@do-not-package@ #@do-not-package@
IceHUD_Options\Json.lua IceHUD_Options\Json.lua

View File

@ -52,7 +52,13 @@ function IceStackCounter_GetOptions(frame, opts)
opts["auraName"] = { opts["auraName"] = {
type = 'input', type = 'input',
name = L["Aura to track"], name = L["Aura to track"],
desc = L["Which buff/debuff this counter will be tracking. \n\nRemember to press ENTER after filling out this box with the name you want or it will not save."], desc = function()
if IceHUD.GetPlayerAuraBySpellID then
return L["Which buff/debuff this counter will be tracking. Can use the name or spell id. \n\nRemember to press ENTER after filling out this box with the name you want or it will not save."]
else
return L["Which buff/debuff this counter will be tracking. \n\nRemember to press ENTER after filling out this box with the name you want or it will not save."]
end
end,
get = function() get = function()
return frame.moduleSettings.auraName return frame.moduleSettings.auraName
end, end,

View File

@ -1,5 +1,11 @@
# Changelog # Changelog
v1.14.3:
- Add Spell ID support for aura tracking.
- Add Evoker support.
- Add Empowered Casting (hold-to-cast levels) support.
v1.14.2: v1.14.2:
- Fix CC and Invuln modules not showing immediately when they should. - Fix CC and Invuln modules not showing immediately when they should.

View File

@ -39,6 +39,9 @@ function CastBar.prototype:GetDefaultSettings()
settings["rangeColor"] = true settings["rangeColor"] = true
settings["bAllowExpand"] = false settings["bAllowExpand"] = false
settings["respectLagTolerance"] = true settings["respectLagTolerance"] = true
settings["lockUpperTextAlpha"] = true
settings["lockLowerTextAlpha"] = true
settings["empowerStageTextDisplay"] = "TOPLINE"
return settings return settings
end end
@ -236,6 +239,7 @@ function CastBar.prototype:GetOptions()
end, end,
set = function(info, v) set = function(info, v)
self.moduleSettings.lockUpperTextAlpha = v self.moduleSettings.lockUpperTextAlpha = v
self.moduleSettings.lockLowerTextAlpha = v
self:Redraw() self:Redraw()
end, end,
order = 13 order = 13
@ -308,7 +312,26 @@ function CastBar.prototype:GetOptions()
disabled = function() disabled = function()
return not self.moduleSettings.enabled return not self.moduleSettings.enabled
end, end,
} },
empowerStageText = {
type = 'select',
name = L["Empower stage label display"],
desc = L["How to display the stage of an empowered spell"],
get = function()
return self.moduleSettings.empowerStageTextDisplay
end,
set = function(info, value)
self.moduleSettings.empowerStageTextDisplay = value
end,
values = { NONE = L["Don't show"], TOPLINE = L["After spell name"], BOTTOMLINE = L["Below spell name"] },
disabled = function()
return not self.moduleSettings.enabled
end,
hidden = function()
return not GetUnitEmpowerMinHoldTime
end,
},
} }
} }

View File

@ -462,10 +462,14 @@ function IceClassPowerCounter.prototype:CheckValidSpec()
end end
end end
function IceClassPowerCounter.prototype:GetPowerEvent()
return IceHUD.UnitPowerEvent
end
function IceClassPowerCounter.prototype:DisplayCounter() function IceClassPowerCounter.prototype:DisplayCounter()
self:UnregisterEvent("PLAYER_LEVEL_UP") self:UnregisterEvent("PLAYER_LEVEL_UP")
self:RegisterEvent(IceHUD.UnitPowerEvent, "UpdateRunePower") self:RegisterEvent(self:GetPowerEvent(), "UpdateRunePower")
self:RegisterEvent("UNIT_DISPLAYPOWER", "UpdateRunePower") self:RegisterEvent("UNIT_DISPLAYPOWER", "UpdateRunePower")
self:RegisterEvent("PLAYER_ENTERING_WORLD", "EnteringWorld") self:RegisterEvent("PLAYER_ENTERING_WORLD", "EnteringWorld")
if IceHUD.EventExistsUnitMaxPower then if IceHUD.EventExistsUnitMaxPower then
@ -493,7 +497,7 @@ function IceClassPowerCounter.prototype:EnteringWorld()
end end
function IceClassPowerCounter.prototype:UpdateRunePower(event, arg1, arg2) function IceClassPowerCounter.prototype:UpdateRunePower(event, arg1, arg2)
if event and (event == IceHUD.UnitPowerEvent or event == "UNIT_POWER_FREQUENT") and arg1 ~= "player" and arg1 ~= "vehicle" then if event and (event == self:GetPowerEvent() or event == "UNIT_POWER_FREQUENT") and arg1 ~= "player" and arg1 ~= "vehicle" then
return return
end end

View File

@ -329,16 +329,18 @@ function IceCustomBar.prototype:GetOptions()
opts["buffToTrack"] = { opts["buffToTrack"] = {
type = 'input', type = 'input',
name = L["Aura to track"], name = L["Aura to track"],
desc = L["Which buff/debuff this bar will be tracking.\n\nRemember to press ENTER after filling out this box with the name you want or it will not save."], desc = function()
if IceHUD.GetPlayerAuraBySpellID then
return L["Which buff/debuff this bar will be tracking. Can use the name or spell id. \n\nRemember to press ENTER after filling out this box with the name you want or it will not save."]
else
return L["Which buff/debuff this bar will be tracking.\n\nRemember to press ENTER after filling out this box with the name you want or it will not save."]
end
end,
get = function() get = function()
return self.moduleSettings.buffToTrack return self.moduleSettings.buffToTrack
end, end,
set = function(info, v) set = function(info, v)
local orig = v local orig = v
--Parnic: we now allow spell IDs to be used directly
--if tonumber(v) ~= nil then
-- v = GetSpellInfo(tonumber(v))
--end
if v == nil then if v == nil then
v = orig v = orig
end end

74
modules/EssencePower.lua Normal file
View File

@ -0,0 +1,74 @@
local L = LibStub("AceLocale-3.0"):GetLocale("IceHUD", false)
local EssencePower = IceCore_CreateClass(IceClassPowerCounter)
local SPELL_POWER_ESSENCE = SPELL_POWER_ESSENCE
if Enum and Enum.PowerType then
SPELL_POWER_ESSENCE = Enum.PowerType.Essence
end
function EssencePower.prototype:init()
EssencePower.super.prototype.init(self, "EssencePower")
self:SetDefaultColor("EssencePowerNumeric", 150, 150, 255)
self.unit = "player"
self.numericColor = "EssencePowerNumeric"
self.unitPower = SPELL_POWER_ESSENCE
self.minLevel = 0
self.bTreatEmptyAsFull = false
self.runeWidth = self.runeHeight
end
function EssencePower.prototype:Enable(core)
self.numRunes = UnitPowerMax(self.unit, SPELL_POWER_ESSENCE)
self.runeCoords = { }
for i = 1, self.numRunes do
self:SetupNewRune(i)
end
EssencePower.super.prototype.Enable(self, core)
end
function EssencePower.prototype:SetupNewRune(rune)
self.runeCoords[rune] = {0, 1, 0, 1}
end
function EssencePower.prototype:GetPowerEvent()
return "UNIT_POWER_FREQUENT"
end
function EssencePower.prototype:GetDefaultSettings()
local defaults = EssencePower.super.prototype.GetDefaultSettings(self)
defaults["pulseWhenFull"] = false
return defaults
end
function EssencePower.prototype:GetOptions()
local opts = EssencePower.super.prototype.GetOptions(self)
opts.hideBlizz.hidden = function() return true end
return opts
end
function EssencePower.prototype:GetRuneAtlas(rune)
return "UF-Essence-Icon"
end
function EssencePower.prototype:GetShineAtlas(rune)
return "Mage-ArcaneCharge-SmallSpark"
end
function EssencePower.prototype:ShowBlizz()
end
function EssencePower.prototype:HideBlizz()
end
-- Load us up
local _, unitClass = UnitClass("player")
if unitClass == "EVOKER" then
IceHUD.EssencePower = EssencePower:new()
end

View File

@ -1,5 +1,11 @@
# Changelog # Changelog
v1.14.3:
- Add Spell ID support for aura tracking.
- Add Evoker support.
- Add Empowered Casting (hold-to-cast levels) support.
v1.14.2: v1.14.2:
- Fix CC and Invuln modules not showing immediately when they should. - Fix CC and Invuln modules not showing immediately when they should.