forked from wow/OmicronFrames
Add multiple spell ids support to AuraTrigger
Before AuraTrigger only supported a single spell id but now multiple spells can activate the same trigger. Related changes: - Change the glue between AuraList and AuraTrigger to match this new functionality. - Update the default frame config
This commit is contained in:
1 parent
8be0732930
commit
eaebe470b9
3 files changed
+127
-56
No files matched your search
+24
-8
@@ -16,6 +16,8 @@
|
||||
-- Omicron Frames. If not, see <https://www.gnu.org/licenses/>.
|
||||
local omi = select(2, ...)
|
||||
local types = omi.GetModule("types")
|
||||
local AuraTrigger = types.AuraTrigger
|
||||
local StatusTrigger = types.StatusTrigger
|
||||
|
||||
--- AuraList keeps track of all the auras attached to a unitframe
|
||||
---@class AuraList: Object
|
||||
@@ -180,21 +182,35 @@ function AuraList:Init(unitframe)
|
||||
self.triggersByStatus = {}
|
||||
end
|
||||
|
||||
---@param trigger AuraTrigger | StatusTrigger
|
||||
function AuraList:AddTrigger(trigger)
|
||||
---@param trigger StatusTrigger
|
||||
function AuraList:AddStatusTrigger(trigger)
|
||||
table.insert(self.triggers, trigger)
|
||||
local spellId = trigger.spellId
|
||||
local status = trigger.status
|
||||
if spellId then
|
||||
if self.triggersByStatus[status] == nil then
|
||||
self.triggersByStatus[status] = {}
|
||||
end
|
||||
table.insert(self.triggersByStatus[status], trigger)
|
||||
end
|
||||
|
||||
---@param trigger AuraTrigger
|
||||
function AuraList:AddAuraTrigger(trigger)
|
||||
table.insert(self.triggers, trigger)
|
||||
for spellId in pairs(trigger.spellIds) do
|
||||
if self.triggersBySpell[spellId] == nil then
|
||||
self.triggersBySpell[spellId] = {}
|
||||
end
|
||||
table.insert(self.triggersBySpell[spellId], trigger)
|
||||
end
|
||||
end
|
||||
|
||||
---@param trigger AuraTrigger | StatusTrigger
|
||||
function AuraList:AddTrigger(trigger)
|
||||
if trigger:IsInstanceOf(AuraTrigger) then
|
||||
self:AddAuraTrigger(trigger)
|
||||
elseif trigger:IsInstanceOf(StatusTrigger) then
|
||||
self:AddStatusTrigger(trigger)
|
||||
else
|
||||
if self.triggersByStatus[status] == nil then
|
||||
self.triggersByStatus[status] = {}
|
||||
end
|
||||
table.insert(self.triggersByStatus[status], trigger)
|
||||
error("AddTrigger: trigger is neither an AuraTrigger nor a StatusTrigger")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ local Trigger = types.Trigger
|
||||
|
||||
---AuraTrigger is a Trigger that can be attached to AuraList as datasource
|
||||
---@class AuraTrigger: Trigger
|
||||
---@field spellId number
|
||||
---@field spellIds table<number, true>
|
||||
---@field count number
|
||||
---@field requiredCount number
|
||||
local AuraTrigger = types.CreateClass("AuraTrigger", Trigger)
|
||||
@@ -33,7 +33,8 @@ types.AuraTrigger = AuraTrigger
|
||||
---@param config table
|
||||
---@return AuraTrigger
|
||||
function AuraTrigger.CreateFromConfig(unit, config)
|
||||
local trigger = AuraTrigger:new(config.spellId, config.own, config.requiredCount, config.invert, config.defaultData)
|
||||
local trigger =
|
||||
AuraTrigger:new(config.spellIds, config.own, config.requiredCount, config.invert, config.defaultData)
|
||||
unit.auras:AddTrigger(trigger)
|
||||
return trigger
|
||||
end
|
||||
@@ -47,29 +48,33 @@ function AuraTrigger.new(cls, ...)
|
||||
end
|
||||
|
||||
--- Initialize a new AuraTrigger object
|
||||
---@param spellId number
|
||||
---@param spellIds table<number, true>
|
||||
---@param own boolean
|
||||
---@param requiredCount number | nil
|
||||
---@param invert boolean | nil
|
||||
---@param defaultData table | nil
|
||||
function AuraTrigger:Init(spellId, own, requiredCount, invert, defaultData)
|
||||
function AuraTrigger:Init(spellIds, own, requiredCount, invert, defaultData)
|
||||
Trigger.Init(self, invert, defaultData)
|
||||
self.spellId = spellId
|
||||
self.spellIds = spellIds
|
||||
self.instanceData = {}
|
||||
self.requiredCount = requiredCount or 1
|
||||
self.own = own
|
||||
self.count = 0
|
||||
self.bestAuraID = nil
|
||||
end
|
||||
|
||||
--- Reset the AuraTrigger to the default state
|
||||
function AuraTrigger:Reset()
|
||||
self.count = 0
|
||||
self:SetState(self.count >= self.requiredCount, false)
|
||||
self.bestAuraID = nil
|
||||
table.wipe(self.instanceData)
|
||||
self:SetStateAndData(self.count >= self.requiredCount, {})
|
||||
end
|
||||
|
||||
---Check if a given aura matches this AuraTrigger
|
||||
---@param aura UnitAuraInfo
|
||||
function AuraTrigger:IsMatching(aura)
|
||||
if aura.spellId ~= aura.spellId then
|
||||
if not self.spellIds[aura.spellId] then
|
||||
return false
|
||||
end
|
||||
if self.own and aura.sourceUnit ~= "player" then
|
||||
@@ -78,35 +83,68 @@ function AuraTrigger:IsMatching(aura)
|
||||
return true
|
||||
end
|
||||
|
||||
-- Get the ID of the current best matching aura in AuraTrigger.instanceData
|
||||
function AuraTrigger:BestAuraID()
|
||||
local found = nil
|
||||
for k, v in pairs(self.instanceData) do
|
||||
if not found then
|
||||
found = k
|
||||
elseif v.expirationTime > self.instanceData[found].expirationTime then
|
||||
found = k
|
||||
end
|
||||
end
|
||||
return found
|
||||
end
|
||||
|
||||
---Grab the best aura data and update the current recorded best aura
|
||||
---It returns data if the current best aura is different from the previous
|
||||
---@param updatedInstanceId number|nil the aura id that was recently updated
|
||||
function AuraTrigger:BestAuraData(updatedInstanceId)
|
||||
local bid = self:BestAuraID()
|
||||
if bid == nil then
|
||||
self.bestAuraID = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
local data = nil
|
||||
if bid ~= self.bestAuraID or (updatedInstanceId and bid == updatedInstanceId) then
|
||||
local aura = self.instanceData[bid]
|
||||
data = {
|
||||
stacks = aura.applications,
|
||||
duration = aura.duration,
|
||||
expirationTime = aura.expirationTime,
|
||||
icon = aura.icon,
|
||||
}
|
||||
self.bestAuraID = bid
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
---Inform the trigger about an added aura
|
||||
---@param aura UnitAuraInfo
|
||||
function AuraTrigger:AddAura(aura)
|
||||
if not self:IsMatching(aura) then
|
||||
return
|
||||
end
|
||||
local aid = aura.auraInstanceID
|
||||
self.instanceData[aid] = aura
|
||||
self.count = self.count + 1
|
||||
self:SetData({
|
||||
stacks = aura.applications,
|
||||
duration = aura.duration,
|
||||
expirationTime = aura.expirationTime,
|
||||
icon = aura.icon,
|
||||
})
|
||||
self:SetState(self.count >= self.requiredCount, false)
|
||||
local newData = self:BestAuraData(nil)
|
||||
self:SetStateAndData(self.count >= self.requiredCount, newData)
|
||||
end
|
||||
|
||||
---Inform the trigger about an updated aura
|
||||
---@param before UnitAuraInfo
|
||||
---@param after UnitAuraInfo
|
||||
function AuraTrigger:UpdateAura(before, after)
|
||||
self:SetData({
|
||||
stacks = after.applications,
|
||||
duration = after.duration,
|
||||
expirationTime = after.expirationTime,
|
||||
icon = after.icon,
|
||||
})
|
||||
if self.active then
|
||||
self.indicator:Update(self.data)
|
||||
if not self:IsMatching(after) then
|
||||
return
|
||||
end
|
||||
local aid = after.auraInstanceID
|
||||
self.instanceData[aid] = after
|
||||
|
||||
local newData = self:BestAuraData(aid)
|
||||
self:SetStateAndData(self.count >= self.requiredCount, newData)
|
||||
end
|
||||
|
||||
---Inform the trigger about an aura that got removed
|
||||
@@ -115,7 +153,11 @@ function AuraTrigger:RemoveAura(aura)
|
||||
if not self:IsMatching(aura) then
|
||||
return
|
||||
end
|
||||
|
||||
local aid = aura.auraInstanceID
|
||||
self.instanceData[aid] = nil
|
||||
self.count = self.count - 1
|
||||
self:SetData({})
|
||||
self:SetState(self.count >= self.requiredCount, false)
|
||||
|
||||
local newData = self:BestAuraData(nil)
|
||||
self:SetStateAndData(self.count >= self.requiredCount, newData)
|
||||
end
|
||||
Reference in new issue
Block a user