from retail

This commit is contained in:
NoM0Re
2025-01-13 14:56:26 +01:00
parent 613c9ecefe
commit 0291e5b5e7
2 changed files with 228 additions and 25 deletions
+218 -24
View File
@@ -73,6 +73,7 @@ local events = {}
local loaded_events = {}
local loaded_unit_events = {};
local watched_trigger_events = Private.watched_trigger_events
local delayTimerEvents = {}
local loaded_auras = {}; -- id to bool map
-- Local functions
@@ -672,7 +673,12 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2
if(data.triggerFunc) then
local untriggerCheck = false;
if (data.statesParameter == "full") then
local ok, returnValue = pcall(data.triggerFunc, allStates, event, arg1, arg2, ...);
local ok, returnValue
if data.counter then
ok, returnValue = pcall(data.triggerFunc, allStates, data.counter, event, arg1, arg2, ...);
else
ok, returnValue = pcall(data.triggerFunc, allStates, event, arg1, arg2, ...);
end
if not ok then
errorHandler(returnValue)
elseif ok and returnValue then
@@ -686,7 +692,12 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2
end
end
elseif (data.statesParameter == "all") then
local ok, returnValue = pcall(data.triggerFunc, allStates, event, arg1, arg2, ...);
local ok, returnValue
if data.counter then
ok, returnValue = pcall(data.triggerFunc, allStates, data.counter, event, arg1, arg2, ...);
else
ok, returnValue = pcall(data.triggerFunc, allStates, event, arg1, arg2, ...);
end
if not ok then
errorHandler(returnValue)
elseif (ok and returnValue) or optionsEvent then
@@ -722,7 +733,12 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2
end
allStates[cloneIdForUnitTrigger] = allStates[cloneIdForUnitTrigger] or {};
local state = allStates[cloneIdForUnitTrigger];
local ok, returnValue = pcall(data.triggerFunc, state, event, unitForUnitTrigger, arg1, arg2, ...);
local ok, returnValue
if data.counter then
ok, returnValue = pcall(data.triggerFunc, state, data.counter, event, unitForUnitTrigger, arg1, arg2, ...);
else
ok, returnValue = pcall(data.triggerFunc, state, event, unitForUnitTrigger, arg1, arg2, ...);
end
if not ok then
errorHandler(returnValue)
elseif (ok and returnValue) or optionsEvent then
@@ -736,7 +752,12 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2
elseif (data.statesParameter == "one") then
allStates[""] = allStates[""] or {};
local state = allStates[""];
local ok, returnValue = pcall(data.triggerFunc, state, event, arg1, arg2, ...);
local ok, returnValue
if data.counter then
ok, returnValue = pcall(data.triggerFunc, state, data.counter, event, arg1, arg2, ...);
else
ok, returnValue = pcall(data.triggerFunc, state, event, arg1, arg2, ...);
end
if not ok then
errorHandler(returnValue)
elseif (ok and returnValue) or optionsEvent then
@@ -747,7 +768,12 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2
untriggerCheck = true;
end
else
local ok, returnValue = pcall(data.triggerFunc, event, arg1, arg2, ...);
local ok, returnValue
if data.counter then
ok, returnValue = pcall(data.triggerFunc, data.counter, event, arg1, arg2, ...);
else
ok, returnValue = pcall(data.triggerFunc, event, arg1, arg2, ...);
end
if not ok then
errorHandler(returnValue)
elseif (ok and returnValue) or optionsEvent then
@@ -896,8 +922,13 @@ function WeakAuras.ScanEventsInternal(event_list, event, arg1, arg2, ... )
local updateTriggerState = false;
for triggernum, data in pairs(triggers) do
local allStates = WeakAuras.GetTriggerStateForTrigger(id, triggernum);
if (RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2, ...)) then
updateTriggerState = true;
local delay = GenericTrigger.GetDelay(data)
if delay == 0 then
if (RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2, ...)) then
updateTriggerState = true
end
else
Private.RunTriggerFuncWithDelay(delay, id, triggernum, data, event, arg1, arg2, ...)
end
end
if (updateTriggerState) then
@@ -908,6 +939,50 @@ function WeakAuras.ScanEventsInternal(event_list, event, arg1, arg2, ... )
end
end
do
local function RunTriggerFuncForDelay(id, triggernum, data, event, ...)
Private.StartProfileAura(id)
Private.ActivateAuraEnvironment(id)
local allStates = WeakAuras.GetTriggerStateForTrigger(id, triggernum)
if (RunTriggerFunc(allStates, data, id, triggernum, event, ...)) then
Private.UpdatedTriggerState(id)
end
Private.StopProfileAura(id)
Private.ActivateAuraEnvironment(nil)
-- clear expired timers
for i, t in ipairs_reverse(delayTimerEvents[id][triggernum]) do
if t.ends <= GetTime() then
table.remove(delayTimerEvents[id][triggernum], i)
end
end
end
function Private.RunTriggerFuncWithDelay(delay, id, triggernum, data, event, ...)
delayTimerEvents[id] = delayTimerEvents[id] or {}
delayTimerEvents[id][triggernum] = delayTimerEvents[id][triggernum] or {}
local timerId = timer:ScheduleTimer(RunTriggerFuncForDelay, delay, id, triggernum, data, event, ...)
tinsert(delayTimerEvents[id][triggernum], timerId)
end
end
function Private.CancelDelayedTrigger(id)
if delayTimerEvents[id] then
for triggernum, timers in pairs(delayTimerEvents[id]) do
for _, timerId in ipairs(timers) do
timer:CancelTimer(timerId)
end
end
delayTimerEvents[id] = nil
end
end
function Private.CancelAllDelayedTriggers()
for id in pairs(delayTimerEvents) do
Private.CancelDelayedTrigger(id)
end
end
function Private.ScanEventsWatchedTrigger(id, watchedTriggernums)
Private.StartProfileAura(id);
Private.ActivateAuraEnvironment(id);
@@ -1066,6 +1141,7 @@ function GenericTrigger.UnloadAll()
wipe(loaded_auras);
wipe(loaded_events);
wipe(loaded_unit_events);
Private.CancelAllDelayedTriggers();
Private.UnregisterAllEveryFrameUpdate();
end
@@ -1086,6 +1162,8 @@ function GenericTrigger.UnloadDisplays(toUnload)
auras[id] = nil;
end
end
Private.CancelDelayedTrigger(id);
Private.UnregisterEveryFrameUpdate(id);
end
end
@@ -1294,6 +1372,10 @@ function GenericTrigger.LoadDisplays(toLoad, loadEvent, ...)
end
end
if data.counter then
data.counter:Reset()
end
LoadEvent(id, triggernum, data);
end
end
@@ -1343,6 +1425,80 @@ end
function GenericTrigger.FinishLoadUnload()
end
do
local function ParseCron(pattern)
local tests = {}
for test in pattern:gmatch("[^ ,]+") do
local startString, endString, intervalString = test:match("(%d*)-?(%d*)/?(%d*)")
local intervalNumber = tonumber(intervalString)
local startNumber = startString == "" and 0 or tonumber(startString) or 0
local endNumber = tonumber(endString)
if not endNumber then
endNumber = intervalNumber and math.huge or startNumber
end
intervalNumber = intervalNumber or 1
tinsert(tests, {
startNumber = startNumber,
endNumber = endNumber,
intervalNumber = intervalNumber,
Match = function(self, count)
return (count >= self.startNumber and count <= self.endNumber and (count - self.startNumber) % self.intervalNumber == 0)
end
})
end
return tests
end
function Private.CreateTriggerCounter(pattern)
local counter = {
count = 0,
tests = {
},
fastMatches = {
},
Reset = function(self)
self.count = 0
end,
GetNext = function(self)
self.count = self.count + 1
return self.count
end,
}
if pattern then
counter.tests = ParseCron(pattern)
counter.RunTests = function(self, count)
for _, test in ipairs(self.tests) do
if test:Match(count) then
return true
end
end
return false
end
for i = 1, 20 do
counter.fastMatches[i] = counter.RunTests(counter, i)
end
counter.Match = function(self)
if self.count <= 20 then
return counter.fastMatches[self.count]
end
return self:RunTests(self.count)
end
else
counter.Match = function(self)
return true
end
end
return counter
end
end
--- Adds a display, creating all internal data structures for all triggers.
-- @param data
-- @param region
@@ -1371,6 +1527,7 @@ function GenericTrigger.Add(data, region)
local prototype = nil
local automaticAutoHide
local duration
local counter
if(Private.category_event_prototype[triggerType]) then
if not(trigger.event) then
error("Improper arguments to WeakAuras.Add - trigger type is \"event\" but event is not defined");
@@ -1432,6 +1589,14 @@ function GenericTrigger.Add(data, region)
WeakAuras.prettyPrint("Invalid Prototype found: " .. prototype.name)
end
if prototype.countEvents then
if trigger.use_count and type(trigger.count) == "string" and trigger.count ~= "" then
counter = Private.CreateTriggerCounter(trigger.count)
else
counter = Private.CreateTriggerCounter()
end
end
if(prototype) then
local trigger_all_events = prototype.events;
internal_events = prototype.internal_events;
@@ -1616,7 +1781,8 @@ function GenericTrigger.Add(data, region)
automaticAutoHide = automaticAutoHide,
tsuConditionVariables = tsuConditionVariables,
prototype = prototype,
ignoreOptionsEventErrors = data.information.ignoreOptionsEventErrors
ignoreOptionsEventErrors = data.information.ignoreOptionsEventErrors,
counter = counter,
};
end
end
@@ -3746,23 +3912,26 @@ function GenericTrigger.CanHaveDuration(data, triggernum)
local trigger = data.triggers[triggernum].trigger
if (Private.category_event_prototype[trigger.type]) then
if trigger.event and Private.event_prototypes[trigger.event] then
if Private.event_prototypes[trigger.event].durationFunc then
if(type(Private.event_prototypes[trigger.event].init) == "function") then
Private.event_prototypes[trigger.event].init(trigger);
if trigger.event then
local prototype = Private.event_prototypes[trigger.event]
if prototype then
if prototype.durationFunc then
if(type(prototype.init) == "function") then
prototype.init(trigger);
end
local current, maximum, custom = prototype.durationFunc(trigger);
current = type(current) ~= "number" and current or 0
maximum = type(maximum) ~= "number" and maximum or 0
if(custom) then
return {current = current, maximum = maximum};
else
return "timed";
end
elseif prototype.canHaveDuration then
return prototype.canHaveDuration, prototype.useModRate
elseif prototype.timedrequired then
return "timed"
end
local current, maximum, custom = Private.event_prototypes[trigger.event].durationFunc(trigger);
current = type(current) ~= "number" and current or 0
maximum = type(maximum) ~= "number" and maximum or 0
if(custom) then
return {current = current, maximum = maximum};
else
return "timed";
end
elseif Private.event_prototypes[trigger.event].canHaveDuration then
return Private.event_prototypes[trigger.event].canHaveDuration
elseif Private.event_prototypes[trigger.event].timedrequired then
return "timed"
end
end
elseif (trigger.type == "custom") then
@@ -3777,6 +3946,19 @@ function GenericTrigger.CanHaveDuration(data, triggernum)
return false
end
function GenericTrigger.GetDelay(data)
if data.event then
local prototype = Private.event_prototypes[data.event]
if prototype and prototype.delayEvents then
local trigger = data.trigger
if trigger.use_delay and type(trigger.delay) == "number" and trigger.delay > 0 then
return trigger.delay
end
end
end
return 0
end
function GenericTrigger.GetTsuConditionVariables(id, triggernum)
local ok, variables = xpcall(events[id][triggernum].tsuConditionVariables, Private.GetErrorHandlerId(id, L["Custom Variables"]));
if ok then
@@ -3959,6 +4141,11 @@ function GenericTrigger.GetAdditionalProperties(data, triggernum)
end
end
if Private.event_prototypes[trigger.event].countEvents then
found = true;
additional = additional .. "|cFFFF0000%".. triggernum .. ".count|r - " .. L["Count"] .. "\n";
end
if (found) then
ret = ret .. additional;
end
@@ -4106,6 +4293,13 @@ function GenericTrigger.GetTriggerConditions(data, triggernum)
end
end
if Private.event_prototypes[trigger.event].countEvents then
result.count = {
display = L["Count"],
type = "number"
}
end
return result;
end
elseif(trigger.type == "custom") then
+10 -1
View File
@@ -3015,7 +3015,9 @@ Private.event_prototypes = {
test = "true"
},
},
timedrequired = true
countEvents = true,
delayEvents = true,
timedrequired = true,
},
["Cooldown Progress (Spell)"] = {
type = "spell",
@@ -5400,6 +5402,8 @@ Private.event_prototypes = {
reloadOptions = true
},
},
countEvents = true,
delayEvents = true,
timedrequired = true
},
["Ready Check"] = {
@@ -5409,6 +5413,8 @@ Private.event_prototypes = {
},
name = L["Ready Check"],
args = {},
statesParameter = "one",
delayEvents = true,
timedrequired = true
},
["Combat Events"] = {
@@ -5430,6 +5436,9 @@ Private.event_prototypes = {
test = "event == %q"
}
},
statesParameter = "one",
countEvents = true,
delayEvents = true,
timedrequired = true
},
["Death Knight Rune"] = {