-- Copyright 2023 -- -- This file is part of Omicron Frames -- -- Omicron Frames is free software: you can redistribute it and/or modify it -- under the terms of the GNU General Public License as published by the Free -- Software Foundation, either version 3 of the License, or (at your option) -- any later version. -- -- Omicron Frames is distributed in the hope that it will be useful, but -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -- more details. -- -- You should have received a copy of the GNU General Public License along with -- Omicron Frames. If not, see . local omi = select(2, ...) local types = omi.GetModule("types") types.Trigger = types.CreateClass("Trigger") local Trigger = types.Trigger -- Constructor for Trigger. -- fn: -- The callback function that gets called every time this trigger changes -- states between active and inactive. Function takes one boolean argument. function Trigger:Init(fn) self.fn = fn end -- Returns whether the trigger is active function Trigger:IsActive() return false end -- Reset the trigger to the default state. Does run the untrigger callback if -- the trigger is active when Reset is called. function Trigger:Reset() end types.AuraTrigger = types.CreateClass("AuraTrigger", Trigger) local AuraTrigger = types.AuraTrigger -- Constructor for AuraTrigger -- fn: -- The callback function that gets called every time this trigger changes -- states between active and inactive. Function takes one boolean argument. -- -- requiredCount = 1: -- The minimum number of conditions that must be met before the trigger -- activates. What exactly this means depends on the trigger, examples are -- # of matching auras, # of stacks. -- -- invert = false: -- If the trigger is inverted it will activate when count < requiredCount. -- If the trigger is not inverted it will activate when count >= requiredCount. function AuraTrigger:Init(fn, spellId, own, requiredCount, invert) Trigger.Init(self, fn) self.spellId = spellId self.requiredCount = requiredCount or 1 self.own = own self.count = 0 self.invert = invert or false end -- Reset the trigger to the default state. Does run the untrigger callback if -- the trigger is active when it is called function AuraTrigger:Reset() local before = self:IsActive() self.count = 0 local after = self:IsActive() if before ~= after then self.fn(after) end end -- Return true if the aura matches the trigger -- aura: -- Must be a valid UnitAuraInfo structure. function AuraTrigger:IsMatching(aura) if aura.spellId ~= aura.spellId then return false end if self.own and aura.sourceUnit ~= "player" then return false end return true end -- Inform the trigger about an added aura -- aura: -- Must be a valid UnitAuraInfo function AuraTrigger:AddAura(aura) if not self:IsMatching(aura) then return end self.count = self.count + 1 -- Be mindful, this works only if count always changes by 1. if self.count == self.requiredCount then self.fn(not self.invert) end end -- Inform the trigger about an updated aura -- before: -- Must be a valid UnitAuraInfo for the aura before the update -- after: -- Must be a valid UnitAuraInfo for the aura after the update function AuraTrigger:UpdateAura(before, after) -- end -- Inform the trigger about an aura that got removed -- Must be a valid UnitAuraInfo for the aura before it got removed function AuraTrigger:RemoveAura(aura) if not self:IsMatching(aura) then return end self.count = self.count - 1 -- Be mindful, this works only if count always changes by 1. if self.count == self.requiredCount - 1 then self.fn(self.invert) end end -- Returns true if the trigger is active, false otherwise function AuraTrigger:IsActive() if self.invert then return self.count < self.requiredCount else return self.count >= self.requiredCount end end