Files
OmicronFrames/src/types/trigger.lua
2023-03-15 17:13:01 +01:00

137 lines
4.1 KiB
Lua

-- Copyright 2023 <omicron.me@protonmail.com>
--
-- 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 <https://www.gnu.org/licenses/>.
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