1741 lines
58 KiB
Lua
1741 lines
58 KiB
Lua
if not WeakAuras.IsLibsOK() then return end
|
||
local AddonName, Private = ...
|
||
|
||
local timer = WeakAuras.timer;
|
||
local L = WeakAuras.L
|
||
|
||
Private.ExecEnv.BossMods = {}
|
||
|
||
-- DBM
|
||
Private.ExecEnv.BossMods.DBM = {
|
||
registeredEvents = {},
|
||
bars = {},
|
||
nextExpire = nil,
|
||
recheckTimer = nil,
|
||
|
||
CopyBarToState = function(self, bar, states, timerId, extendTimer)
|
||
extendTimer = extendTimer or 0
|
||
states[timerId] = states[timerId] or {}
|
||
local state = states[timerId]
|
||
state.show = true
|
||
state.changed = true
|
||
state.icon = bar.icon
|
||
state.message = bar.message
|
||
state.text = bar.message
|
||
state.name = bar.message
|
||
state.expirationTime = bar.expirationTime + extendTimer
|
||
state.progressType = 'timed'
|
||
state.duration = bar.duration + extendTimer
|
||
state.timerType = bar.timerType
|
||
state.spellId = bar.spellId
|
||
state.count = bar.count
|
||
state.dbmType = bar.dbmType
|
||
state.dbmColor = bar.dbmColor
|
||
state.extend = extendTimer
|
||
if extendTimer ~= 0 then
|
||
state.autoHide = true
|
||
end
|
||
state.paused = bar.paused
|
||
state.remaining = bar.remaining
|
||
end,
|
||
|
||
TimerMatches = function(self, timerId, message, operator, spellId, counter, triggerId, dbmType, noCastBar)
|
||
if not self.bars[timerId] then
|
||
return false
|
||
end
|
||
|
||
local v = self.bars[timerId]
|
||
if triggerId and triggerId ~= "" and triggerId ~= timerId then
|
||
return false
|
||
end
|
||
if spellId and spellId ~= "" and spellId ~= v.spellId then
|
||
return false
|
||
end
|
||
if message and message ~= "" and operator then
|
||
if operator == "==" then
|
||
if v.message ~= message then
|
||
return false
|
||
end
|
||
elseif operator == "find('%s')" then
|
||
if v.message == nil or not v.message:find(message, 1, true) then
|
||
return false
|
||
end
|
||
elseif operator == "match('%s')" then
|
||
if v.message == nil or not v.message:match(message) then
|
||
return false
|
||
end
|
||
end
|
||
end
|
||
if counter then
|
||
counter:SetCount(tonumber(v.count) or 0)
|
||
if not counter:Match() then
|
||
return false
|
||
end
|
||
end
|
||
|
||
if noCastBar and v.timerType:find("^cast") then
|
||
return false
|
||
end
|
||
|
||
if dbmType and dbmType ~= v.dbmType then
|
||
return false
|
||
end
|
||
return true
|
||
end,
|
||
|
||
TimerMatchesGeneric = function(self, timerId, message, operator, spellId, counter)
|
||
return self:TimerMatches(timerId, message, operator, spellId, counter, nil, nil, true)
|
||
end,
|
||
|
||
GetStage = function()
|
||
if DBM then
|
||
return DBM:GetStage()
|
||
end
|
||
return 0, 0
|
||
end,
|
||
|
||
GetAllTimers = function(self)
|
||
return self.bars
|
||
end,
|
||
|
||
GetTimerById = function(self, timerId)
|
||
return self.bars[timerId]
|
||
end,
|
||
|
||
GetTimer = function(self, message, operator, spellId, extendTimer, count, triggerId, dbmType, noCastBar)
|
||
local bestMatch
|
||
for timerId, bar in pairs(self.bars) do
|
||
if self:TimerMatches(timerId, message, operator, spellId, count, triggerId, dbmType, noCastBar)
|
||
and (bestMatch == nil or bar.expirationTime < bestMatch.expirationTime)
|
||
and bar.expirationTime + extendTimer > GetTime()
|
||
then
|
||
bestMatch = bar
|
||
end
|
||
end
|
||
return bestMatch
|
||
end,
|
||
|
||
GetTimerGeneric = function(self, message, operator, spellId, extendTimer, count)
|
||
return self:GetTimer(message, operator, spellId, extendTimer, count, nil, nil, true)
|
||
end,
|
||
|
||
RecheckTimers = function(self)
|
||
local now = GetTime()
|
||
self.nextExpire = nil
|
||
for timerId, bar in pairs(self.bars) do
|
||
if not bar.paused then
|
||
if bar.expirationTime < now then
|
||
if bar.scheduledScanExpireAt == nil or bar.scheduledScanExpireAt <= GetTime() then
|
||
self.bars[timerId] = nil
|
||
else
|
||
if self.nextExpire == nil then
|
||
self.nextExpire = bar.scheduledScanExpireAt
|
||
elseif bar.scheduledScanExpireAt < self.nextExpire then
|
||
self.nextExpire = bar.scheduledScanExpireAt
|
||
end
|
||
end
|
||
if not bar.expired then
|
||
bar.expired = true
|
||
Private.ScanEvents("DBM_TimerStop", timerId)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerStop", timerId)
|
||
end
|
||
end
|
||
elseif self.nextExpire == nil then
|
||
self.nextExpire = bar.expirationTime
|
||
elseif bar.expirationTime < self.nextExpire then
|
||
self.nextExpire = bar.expirationTime
|
||
end
|
||
end
|
||
end
|
||
if self.nextExpire then
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, self.nextExpire - now, self)
|
||
end
|
||
end,
|
||
|
||
EventCallback = function(self, event, ...)
|
||
if event == "DBM_Announce" then
|
||
local message, icon, _, spellId, _, count = ...
|
||
Private.ScanEvents("DBM_Announce", spellId, message, icon)
|
||
if self.isGeneric then
|
||
count = count and tostring(count) or "0"
|
||
Private.ScanEvents("BossMod_Announce", spellId, message, icon, count)
|
||
end
|
||
elseif event == "DBM_TimerStart" then
|
||
local timerId, msg, duration, icon, timerType, spellId, dbmType, _, _, _, _, _, timerCount = ...
|
||
local now = GetTime()
|
||
local expirationTime = now + duration
|
||
self.bars[timerId] = self.bars[timerId] or {}
|
||
local bar = self.bars[timerId]
|
||
bar.message = msg
|
||
bar.expirationTime = expirationTime
|
||
bar.duration = duration
|
||
bar.icon = icon
|
||
bar.timerType = timerType
|
||
bar.spellId = tostring(spellId)
|
||
bar.count = timerCount and tostring(timerCount) or "0"
|
||
bar.dbmType = dbmType
|
||
bar.expired = nil
|
||
|
||
local r, g, b = 0, 0, 0
|
||
if DBT.GetColorForType then
|
||
r, g, b = DBT:GetColorForType(dbmType)
|
||
r, g, b = r or 0, g or 0, b or 0
|
||
else
|
||
-- Compability code for DBM versions from around Aberrus
|
||
-- Can be removed once we can assume newer versions
|
||
local barOptions = DBT.Options
|
||
|
||
if dbmType == 1 then
|
||
r, g, b = barOptions.StartColorAR, barOptions.StartColorAG, barOptions.StartColorAB
|
||
elseif dbmType == 2 then
|
||
r, g, b = barOptions.StartColorAER, barOptions.StartColorAEG, barOptions.StartColorAEB
|
||
elseif dbmType == 3 then
|
||
r, g, b = barOptions.StartColorDR, barOptions.StartColorDG, barOptions.StartColorDB
|
||
elseif dbmType == 4 then
|
||
r, g, b = barOptions.StartColorIR, barOptions.StartColorIG, barOptions.StartColorIB
|
||
elseif dbmType == 5 then
|
||
r, g, b = barOptions.StartColorRR, barOptions.StartColorRG, barOptions.StartColorRB
|
||
elseif dbmType == 6 then
|
||
r, g, b = barOptions.StartColorPR, barOptions.StartColorPG, barOptions.StartColorPB
|
||
elseif dbmType == 7 then
|
||
r, g, b = barOptions.StartColorUIR, barOptions.StartColorUIG, barOptions.StartColorUIB
|
||
elseif dbmType == 8 then
|
||
r, g, b = barOptions.StartColorI2R, barOptions.StartColorI2G, barOptions.StartColorI2B
|
||
else
|
||
r, g, b = barOptions.StartColorR, barOptions.StartColorG, barOptions.StartColorB
|
||
end
|
||
end
|
||
bar.dbmColor = {r, g, b}
|
||
|
||
Private.ScanEvents("DBM_TimerStart", timerId)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerStart", timerId)
|
||
end
|
||
if self.nextExpire == nil then
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, expirationTime - now, self)
|
||
self.nextExpire = expirationTime
|
||
elseif expirationTime < self.nextExpire then
|
||
timer:CancelTimer(self.recheckTimer)
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, expirationTime - now, self)
|
||
self.nextExpire = expirationTime
|
||
end
|
||
elseif event == "DBM_TimerStop" then
|
||
local timerId = ...
|
||
local bar = self.bars[timerId]
|
||
if bar then
|
||
if bar.scheduledScanExpireAt == nil or bar.scheduledScanExpireAt <= GetTime() then
|
||
self.bars[timerId] = nil
|
||
end
|
||
bar.expired = true
|
||
Private.ScanEvents("DBM_TimerStop", timerId)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerStop", timerId)
|
||
end
|
||
end
|
||
elseif event == "DBM_TimerPause" then
|
||
local timerId = ...
|
||
local bar = self.bars[timerId]
|
||
if bar then
|
||
bar.paused = true
|
||
bar.remaining = bar.expirationTime - GetTime()
|
||
Private.ScanEvents("DBM_TimerPause", timerId)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerPause", timerId)
|
||
end
|
||
if self.recheckTimer then
|
||
timer:CancelTimer(self.recheckTimer)
|
||
end
|
||
self:RecheckTimers()
|
||
end
|
||
elseif event == "DBM_TimerResume" then
|
||
local timerId = ...
|
||
local bar = self.bars[timerId]
|
||
if bar then
|
||
bar.paused = nil
|
||
bar.expirationTime = GetTime() + (bar.remaining or 0)
|
||
bar.remaining = nil
|
||
Private.ScanEvents("DBM_TimerResume", timerId)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerResume", timerId)
|
||
end
|
||
if self.nextExpire == nil then
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, bar.expirationTime - GetTime(), self)
|
||
self.nextExpire = bar.expirationTime
|
||
elseif bar.expirationTime < self.nextExpire then
|
||
timer:CancelTimer(self.recheckTimer)
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, bar.expirationTime - GetTime(), self)
|
||
self.nextExpire = bar.expirationTime
|
||
end
|
||
end
|
||
elseif event == "DBM_TimerUpdate" then
|
||
local timerId, elapsed, duration = ...
|
||
local now = GetTime()
|
||
local expirationTime = now + duration - elapsed
|
||
local bar = self.bars[timerId]
|
||
if bar then
|
||
bar.duration = duration
|
||
bar.expirationTime = expirationTime
|
||
if self.nextExpire == nil then
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, bar.expirationTime - now, self)
|
||
self.nextExpire = expirationTime
|
||
elseif self.nextExpire == nil or expirationTime < self.nextExpire then
|
||
timer:CancelTimer(self.recheckTimer)
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, bar.expirationTime - now, self)
|
||
self.nextExpire = expirationTime
|
||
end
|
||
end
|
||
Private.ScanEvents("DBM_TimerUpdate", timerId)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerUpdate", timerId)
|
||
end
|
||
elseif event == "DBM_TimerUpdateIcon" then
|
||
local timerId, icon = ...
|
||
local bar = self.bars[timerId]
|
||
if bar then
|
||
bar.icon = icon
|
||
end
|
||
Private.ScanEvents("DBM_TimerUpdateIcon", timerId)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerUpdateIcon", timerId)
|
||
end
|
||
elseif event == "DBM_SetStage" or event == "DBM_Pull" or event == "DBM_Wipe" or event == "DBM_Kill" then
|
||
Private.ScanEvents("DBM_SetStage")
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_SetStage")
|
||
end
|
||
end
|
||
end,
|
||
|
||
RegisterCallback = function(self, event)
|
||
if self.registeredEvents[event] then
|
||
return
|
||
end
|
||
if DBM then
|
||
DBM:RegisterCallback(event, function(...) self:EventCallback(...) end)
|
||
self.registeredEvents[event] = true
|
||
end
|
||
end,
|
||
|
||
RegisterTimer = function(self)
|
||
self:RegisterCallback("DBM_TimerStart")
|
||
self:RegisterCallback("DBM_TimerStop")
|
||
self:RegisterCallback("DBM_TimerPause")
|
||
self:RegisterCallback("DBM_TimerResume")
|
||
self:RegisterCallback("DBM_TimerUpdate")
|
||
self:RegisterCallback("DBM_TimerUpdateIcon")
|
||
end,
|
||
|
||
RegisterMessage = function(self)
|
||
self:RegisterCallback("DBM_Announce")
|
||
end,
|
||
|
||
RegisterStage = function(self)
|
||
self:RegisterCallback("DBM_SetStage")
|
||
self:RegisterCallback("DBM_Pull")
|
||
self:RegisterCallback("DBM_Kill")
|
||
end,
|
||
|
||
scheduled_scans = {},
|
||
|
||
DoScan = function(self, fireTime)
|
||
self.scheduled_scans[fireTime] = nil
|
||
Private.ScanEvents("DBM_TimerUpdate")
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerUpdate")
|
||
end
|
||
end,
|
||
|
||
ScheduleCheck = function(self, fireTime)
|
||
if not self.scheduled_scans[fireTime] then
|
||
self.scheduled_scans[fireTime] = timer:ScheduleTimer(self.DoScan, fireTime - GetTime(), self, fireTime)
|
||
end
|
||
end
|
||
}
|
||
|
||
Private.event_prototypes["DBM Stage"] = {
|
||
type = "addons",
|
||
events = {},
|
||
internal_events = {
|
||
"DBM_SetStage"
|
||
},
|
||
force_events = "DBM_SetStage",
|
||
name = L["DBM Stage"],
|
||
init = function(trigger)
|
||
Private.ExecEnv.BossMods.DBM:RegisterStage()
|
||
return ""
|
||
end,
|
||
args = {
|
||
{
|
||
name = "stage",
|
||
init = "Private.ExecEnv.BossMods.DBM:GetStage()",
|
||
display = L["Stage"],
|
||
desc = L["Matches stage number of encounter journal.\nIntermissions are .5\nE.g. 1;2;1;2;2.5;3"],
|
||
type = "number",
|
||
conditionType = "number",
|
||
store = true,
|
||
},
|
||
{
|
||
name = "stageTotal",
|
||
init = "select(2, Private.ExecEnv.BossMods.DBM:GetStage())",
|
||
display = L["Stage Counter"],
|
||
desc = L["Increases by one per stage or intermission."],
|
||
type = "number",
|
||
conditionType = "number",
|
||
store = true,
|
||
},
|
||
},
|
||
automaticrequired = true,
|
||
statesParameter = "one",
|
||
progressType = "none"
|
||
}
|
||
Private.category_event_prototype.addons["DBM Stage"] = L["DBM Stage"]
|
||
|
||
Private.event_prototypes["DBM Announce"] = {
|
||
type = "addons",
|
||
events = {},
|
||
internal_events = {
|
||
"DBM_Announce"
|
||
},
|
||
name = L["DBM Announce"],
|
||
init = function(trigger)
|
||
Private.ExecEnv.BossMods.DBM:RegisterMessage();
|
||
local ret = "local use_cloneId = %s;"
|
||
return ret:format(trigger.use_cloneId and "true" or "false");
|
||
end,
|
||
statesParameter = "all",
|
||
args = {
|
||
{
|
||
name = "spellId",
|
||
init = "arg",
|
||
display = L["Spell Id"],
|
||
type = "spell",
|
||
noValidation = true,
|
||
showExactOption = false,
|
||
},
|
||
{
|
||
name = "message",
|
||
init = "arg",
|
||
display = L["Message"],
|
||
type = "longstring",
|
||
store = true,
|
||
conditionType = "string"
|
||
},
|
||
{
|
||
name = "name",
|
||
init = "message",
|
||
hidden = true,
|
||
test = "true",
|
||
store = true,
|
||
},
|
||
{
|
||
name = "icon",
|
||
init = "arg",
|
||
store = true,
|
||
hidden = true,
|
||
test = "true"
|
||
},
|
||
{
|
||
name = "cloneId",
|
||
display = L["Clone per Event"],
|
||
type = "toggle",
|
||
test = "true",
|
||
init = "use_cloneId and WeakAuras.GetUniqueCloneId() or ''"
|
||
},
|
||
},
|
||
timedrequired = true,
|
||
progressType = "timed"
|
||
}
|
||
Private.category_event_prototype.addons["DBM Announce"] = L["DBM Announce"]
|
||
|
||
Private.event_prototypes["DBM Timer"] = {
|
||
type = "addons",
|
||
events = {},
|
||
internal_events = {
|
||
"DBM_TimerStart", "DBM_TimerStop", "DBM_TimerUpdate", "DBM_TimerForce", "DBM_TimerResume", "DBM_TimerPause",
|
||
"DBM_TimerUpdateIcon"
|
||
},
|
||
force_events = "DBM_TimerForce",
|
||
name = L["DBM Timer"],
|
||
progressType = "timed",
|
||
triggerFunction = function(trigger)
|
||
Private.ExecEnv.BossMods.DBM:RegisterTimer()
|
||
local ret = [=[
|
||
local triggerCounter = %q
|
||
local counter
|
||
if triggerCounter and triggerCounter ~= "" then
|
||
counter = Private.ExecEnv.CreateTriggerCounter(triggerCounter)
|
||
else
|
||
counter = Private.ExecEnv.CreateTriggerCounter()
|
||
end
|
||
return function (states, event, timerId)
|
||
local triggerId = %q
|
||
local triggerSpellId = %q
|
||
local triggerText = %q
|
||
local triggerTextOperator = %q
|
||
local useClone = %s
|
||
local extendTimer = %s
|
||
local triggerUseRemaining = %s
|
||
local triggerRemaining = %s
|
||
local triggerDbmType = %s
|
||
local cloneId = useClone and timerId or ""
|
||
local state = states[cloneId]
|
||
local counter = counter
|
||
|
||
function copyOrSchedule(bar, cloneId)
|
||
local remainingTime
|
||
local changed
|
||
if bar.paused then
|
||
remainingTime = bar.remaining + extendTimer
|
||
else
|
||
remainingTime = bar.expirationTime - GetTime() + extendTimer
|
||
end
|
||
if triggerUseRemaining then
|
||
if remainingTime > 0 and remainingTime %s triggerRemaining then
|
||
Private.ExecEnv.BossMods.DBM:CopyBarToState(bar, states, cloneId, extendTimer)
|
||
changed = true
|
||
else
|
||
local state = states[cloneId]
|
||
if state and state.show then
|
||
state.show = false
|
||
state.changed = true
|
||
changed = true
|
||
end
|
||
end
|
||
if not bar.paused then
|
||
if extendTimer > 0 then
|
||
bar.scheduledScanExpireAt = math.max(bar.scheduledScanExpireAt or 0, bar.expirationTime + extendTimer)
|
||
end
|
||
if remainingTime >= triggerRemaining then
|
||
Private.ExecEnv.BossMods.DBM:ScheduleCheck(bar.expirationTime - triggerRemaining + extendTimer)
|
||
end
|
||
end
|
||
else
|
||
if not bar.paused and extendTimer > 0 then
|
||
bar.scheduledScanExpireAt = math.max(bar.scheduledScanExpireAt or 0, bar.expirationTime + extendTimer)
|
||
end
|
||
if remainingTime > 0 then
|
||
Private.ExecEnv.BossMods.DBM:CopyBarToState(bar, states, cloneId, extendTimer)
|
||
changed = true
|
||
end
|
||
end
|
||
return changed
|
||
end
|
||
|
||
if useClone then
|
||
if event == "DBM_TimerStart"
|
||
or event == "DBM_TimerPause"
|
||
or event == "DBM_TimerResume"
|
||
then
|
||
if Private.ExecEnv.BossMods.DBM:TimerMatches(timerId, triggerText, triggerTextOperator, triggerSpellId, counter, triggerId, triggerDbmType) then
|
||
local bar = Private.ExecEnv.BossMods.DBM:GetTimerById(timerId)
|
||
if bar then
|
||
return copyOrSchedule(bar, cloneId)
|
||
end
|
||
end
|
||
elseif event == "DBM_TimerStop" and state then
|
||
local bar_remainingTime = state.expirationTime - GetTime() + (state.extend or 0)
|
||
if state.extend == 0 or bar_remainingTime <= 0 then
|
||
state.show = false
|
||
state.changed = true
|
||
return true
|
||
end
|
||
elseif event == "DBM_TimerUpdate" or event == "DBM_TimerUpdateIcon" then
|
||
local changed
|
||
for timerId, bar in pairs(Private.ExecEnv.BossMods.DBM:GetAllTimers()) do
|
||
if Private.ExecEnv.BossMods.DBM:TimerMatches(timerId, triggerText, triggerTextOperator, triggerSpellId, counter, triggerId, triggerDbmType) then
|
||
changed = copyOrSchedule(bar, timerId) or changed
|
||
else
|
||
local state = states[timerId]
|
||
if state then
|
||
local bar_remainingTime = state.expirationTime - GetTime() + (state.extend or 0)
|
||
if state.extend == 0 or bar_remainingTime <= 0 then
|
||
state.show = false
|
||
state.changed = true
|
||
changed = true
|
||
end
|
||
end
|
||
end
|
||
end
|
||
return changed
|
||
elseif event == "DBM_TimerForce" then
|
||
local changed
|
||
for _, state in pairs(states) do
|
||
state.show = false
|
||
state.changed = true
|
||
changed = true
|
||
end
|
||
for timerId, bar in pairs(Private.ExecEnv.BossMods.DBM:GetAllTimers()) do
|
||
if Private.ExecEnv.BossMods.DBM:TimerMatches(timerId, triggerText, triggerTextOperator, triggerSpellId, counter, triggerId, triggerDbmType) then
|
||
changed = copyOrSchedule(bar, timerId) or changed
|
||
end
|
||
end
|
||
return changed
|
||
end
|
||
else
|
||
if event == "DBM_TimerStart" or event == "DBM_TimerUpdate" then
|
||
if extendTimer ~= 0 then
|
||
if Private.ExecEnv.BossMods.DBM:TimerMatches(timerId, triggerText, triggerTextOperator, triggerSpellId, counter, triggerId, triggerDbmType) then
|
||
local bar = Private.ExecEnv.BossMods.DBM:GetTimerById(timerId)
|
||
Private.ExecEnv.BossMods.DBM:ScheduleCheck(bar.expirationTime + extendTimer)
|
||
end
|
||
end
|
||
end
|
||
local bar = Private.ExecEnv.BossMods.DBM:GetTimer(triggerText, triggerTextOperator, triggerSpellId, extendTimer, counter, triggerId, triggerDbmType)
|
||
if bar then
|
||
if extendTimer == 0
|
||
or not (state and state.show)
|
||
or (state and state.show and state.expirationTime > (bar.expirationTime + extendTimer))
|
||
then
|
||
return copyOrSchedule(bar, cloneId)
|
||
end
|
||
else
|
||
if state and state.show then
|
||
local bar_remainingTime = state.expirationTime - GetTime() + (state.extend or 0)
|
||
if state.extend == 0 or bar_remainingTime <= 0 then
|
||
state.show = false
|
||
state.changed = true
|
||
return true
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
]=]
|
||
|
||
return ret:format(
|
||
trigger.use_count and trigger.count or "",
|
||
trigger.use_id and trigger.id or "",
|
||
trigger.use_spellId and tostring(trigger.spellId) or "",
|
||
trigger.use_message and trigger.message or "",
|
||
trigger.use_message and trigger.message_operator or "",
|
||
trigger.use_cloneId and "true" or "false",
|
||
trigger.use_extend and tonumber(trigger.extend or 0) or 0,
|
||
trigger.use_remaining and "true" or "false",
|
||
trigger.remaining and tonumber(trigger.remaining or 0) or 0,
|
||
trigger.use_dbmType and trigger.dbmType or "nil",
|
||
trigger.remaining_operator or "<"
|
||
)
|
||
end,
|
||
statesParameter = "full",
|
||
args = {
|
||
{
|
||
name = "id",
|
||
display = L["Timer Id"],
|
||
type = "string",
|
||
},
|
||
{
|
||
name = "spellId",
|
||
display = L["Spell Id"],
|
||
store = true,
|
||
type = "spell",
|
||
conditionType = "string",
|
||
noValidation = true,
|
||
showExactOption = false,
|
||
},
|
||
{
|
||
name = "message",
|
||
display = L["Message"],
|
||
type = "longstring",
|
||
store = true,
|
||
conditionType = "string"
|
||
},
|
||
{
|
||
name = "remaining",
|
||
display = L["Remaining Time"],
|
||
type = "number",
|
||
},
|
||
{
|
||
name = "extend",
|
||
display = L["Offset Timer"],
|
||
type = "string",
|
||
},
|
||
{
|
||
name = "count",
|
||
display = L["Count"],
|
||
desc = L["Occurrence of the event, reset when aura is unloaded\nCan be a range of values\nCan have multiple values separated by a comma or a space\n\nExamples:\n2nd 5th and 6th events: 2, 5, 6\n2nd to 6th: 2-6\nevery 2 events: /2\nevery 3 events starting from 2nd: 2/3\nevery 3 events starting from 2nd and ending at 11th: 2-11/3\n\nOnly if DBM shows it on it's bar"],
|
||
type = "string",
|
||
conditionType = "string",
|
||
},
|
||
{
|
||
name = "dbmType",
|
||
display = L["Type"],
|
||
type = "select",
|
||
values = "dbm_types",
|
||
conditionType = "select",
|
||
test = "true"
|
||
},
|
||
{
|
||
name = "cloneId",
|
||
display = L["Clone per Event"],
|
||
type = "toggle"
|
||
}
|
||
},
|
||
automaticrequired = true,
|
||
}
|
||
Private.category_event_prototype.addons["DBM Timer"] = L["DBM Timer"]
|
||
|
||
-- BigWigs
|
||
Private.ExecEnv.BossMods.BigWigs = {
|
||
registeredEvents = {},
|
||
bars = {},
|
||
nextExpire = nil,
|
||
recheckTimer = nil,
|
||
currentStage = 0,
|
||
|
||
CopyBarToState = function(self, bar, states, timerId, extendTimer)
|
||
extendTimer = extendTimer or 0
|
||
states[timerId] = states[timerId] or {}
|
||
local state = states[timerId]
|
||
state.show = true
|
||
state.changed = true
|
||
state.addon = bar.addon
|
||
state.spellId = bar.spellId
|
||
state.text = bar.text
|
||
state.message = bar.text
|
||
state.name = bar.text
|
||
state.duration = bar.duration + extendTimer
|
||
state.expirationTime = bar.expirationTime + extendTimer
|
||
state.bwBarColor = bar.bwBarColor
|
||
state.bwTextColor = bar.bwTextColor
|
||
state.bwBackgroundColor = bar.bwBackgroundColor
|
||
state.count = bar.count
|
||
state.cast = bar.cast
|
||
state.progressType = "timed"
|
||
state.icon = bar.icon
|
||
state.extend = extendTimer
|
||
if extendTimer ~= 0 then
|
||
state.autoHide = true
|
||
end
|
||
state.paused = bar.paused
|
||
state.remaining = bar.remaining
|
||
state.isCooldown = bar.isCooldown
|
||
end,
|
||
|
||
TimerMatches = function(self, timerId, message, operator, spellId, counter, cast, cooldown)
|
||
if not self.bars[timerId] then
|
||
return false
|
||
end
|
||
|
||
local v = self.bars[timerId]
|
||
if spellId and spellId ~= "" and spellId ~= v.spellId then
|
||
return false
|
||
end
|
||
if message and message ~= "" and operator then
|
||
if operator == "==" then
|
||
if v.text ~= message then
|
||
return false
|
||
end
|
||
elseif operator == "find('%s')" then
|
||
if v.text == nil or not v.text:find(message, 1, true) then
|
||
return false
|
||
end
|
||
elseif operator == "match('%s')" then
|
||
if v.text == nil or not v.text:match(message) then
|
||
return false
|
||
end
|
||
end
|
||
end
|
||
if counter then
|
||
counter:SetCount(tonumber(v.count) or 0)
|
||
if not counter:Match() then
|
||
return false
|
||
end
|
||
end
|
||
if cast ~= nil and v.cast ~= cast then
|
||
return false
|
||
end
|
||
if cooldown ~= nil and v.isCooldown ~= cooldown then
|
||
return false
|
||
end
|
||
return true
|
||
end,
|
||
|
||
TimerMatchesGeneric = function(self, timerId, message, operator, spellId, counter)
|
||
return self:TimerMatches(timerId, message, operator, spellId, counter, false, nil)
|
||
end,
|
||
|
||
GetStage = function(self)
|
||
return self.currentStage
|
||
end,
|
||
|
||
GetAllTimers = function(self)
|
||
return self.bars
|
||
end,
|
||
|
||
GetTimerById = function(self, timerId)
|
||
return self.bars[timerId]
|
||
end,
|
||
|
||
GetTimer = function(self, text, operator, spellId, extendTimer, counter, cast, cooldown)
|
||
local bestMatch
|
||
for timerId, bar in pairs(self.bars) do
|
||
if self:TimerMatches(timerId, text, operator, spellId, counter, cast, cooldown)
|
||
and (bestMatch == nil or bar.expirationTime < bestMatch.expirationTime)
|
||
and bar.expirationTime + extendTimer > GetTime()
|
||
then
|
||
bestMatch = bar
|
||
end
|
||
end
|
||
return bestMatch
|
||
end,
|
||
|
||
GetTimerGeneric = function(self, text, operator, spellId, extendTimer, counter)
|
||
return self:GetTimer(text, operator, spellId, extendTimer, counter, false, nil)
|
||
end,
|
||
|
||
RecheckTimers = function(self)
|
||
local now = GetTime()
|
||
self.nextExpire = nil
|
||
for timerId, bar in pairs(self.bars) do
|
||
if not bar.paused then
|
||
if bar.expirationTime < now then
|
||
if bar.scheduledScanExpireAt == nil or bar.scheduledScanExpireAt <= GetTime() then
|
||
self.bars[timerId] = nil
|
||
else
|
||
if self.nextExpire == nil then
|
||
self.nextExpire = bar.scheduledScanExpireAt
|
||
elseif bar.scheduledScanExpireAt < self.nextExpire then
|
||
self.nextExpire = bar.scheduledScanExpireAt
|
||
end
|
||
end
|
||
if not bar.expired then
|
||
bar.expired = true
|
||
Private.ScanEvents("BigWigs_StopBar", timerId)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerStop", timerId)
|
||
end
|
||
end
|
||
elseif self.nextExpire == nil then
|
||
self.nextExpire = bar.expirationTime
|
||
elseif bar.expirationTime < self.nextExpire then
|
||
self.nextExpire = bar.expirationTime
|
||
end
|
||
end
|
||
end
|
||
|
||
if self.nextExpire then
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, self.nextExpire - now, self)
|
||
end
|
||
end,
|
||
|
||
EventCallback = function(self, event, ...)
|
||
if event == "BigWigs_Message" then
|
||
Private.ScanEvents("BigWigs_Message", ...)
|
||
if self.isGeneric then
|
||
local _, spellId, text, _, icon = ...
|
||
local count = text and text:match("%((%d+)%)") or text:match("((%d+))") or "0"
|
||
Private.ScanEvents("BossMod_Announce", spellId, text, icon, count)
|
||
end
|
||
elseif event == "BigWigs_StartBar" then
|
||
local addon, spellId, text, duration, icon, isCD = ...
|
||
local now = GetTime()
|
||
local expirationTime = now + duration
|
||
|
||
self.bars[text] = self.bars[text] or {}
|
||
local bar = self.bars[text]
|
||
bar.addon = addon
|
||
bar.spellId = tostring(spellId)
|
||
bar.name = text
|
||
bar.text = text
|
||
bar.duration = duration
|
||
bar.expirationTime = expirationTime
|
||
bar.icon = icon
|
||
bar.isCooldown = isCD or false
|
||
bar.expired = nil
|
||
local BWColorModule = BigWigs:GetPlugin("Colors")
|
||
bar.bwBarColor = BWColorModule:GetColorTable("barColor", addon, spellId)
|
||
bar.bwTextColor = BWColorModule:GetColorTable("barText", addon, spellId)
|
||
bar.bwBackgroundColor = BWColorModule:GetColorTable("barBackground", addon, spellId)
|
||
bar.count = text:match("%((%d+)%)") or text:match("((%d+))") or "0"
|
||
bar.cast = not(text:match("^[^<]") and true)
|
||
|
||
Private.ScanEvents("BigWigs_StartBar", text)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerStart", text)
|
||
end
|
||
if self.nextExpire == nil then
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, expirationTime - now, self)
|
||
self.nextExpire = expirationTime
|
||
elseif expirationTime < self.nextExpire then
|
||
timer:CancelTimer(self.recheckTimer)
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, expirationTime - now, self)
|
||
self.nextExpire = expirationTime
|
||
end
|
||
elseif event == "BigWigs_StopBar" then
|
||
local addon, text = ...
|
||
local bar = self.bars[text]
|
||
if bar then
|
||
if bar.scheduledScanExpireAt == nil or bar.scheduledScanExpireAt <= GetTime() then
|
||
self.bars[text] = nil
|
||
end
|
||
Private.ScanEvents("BigWigs_StopBar", text)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerStop", text)
|
||
end
|
||
end
|
||
elseif event == "BigWigs_PauseBar" then
|
||
local addon, text = ...
|
||
local bar = self.bars[text]
|
||
if bar and not bar.paused then
|
||
bar.paused = true
|
||
bar.remaining = bar.expirationTime - GetTime()
|
||
Private.ScanEvents("BigWigs_PauseBar", text)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerPause", text)
|
||
end
|
||
if self.recheckTimer then
|
||
timer:CancelTimer(self.recheckTimer)
|
||
end
|
||
self:RecheckTimers()
|
||
end
|
||
elseif event == "BigWigs_ResumeBar" then
|
||
local addon, text = ...
|
||
local bar = self.bars[text]
|
||
if bar and bar.paused then
|
||
bar.paused = nil
|
||
bar.expirationTime = GetTime() + (bar.remaining or 0)
|
||
bar.remaining = nil
|
||
Private.ScanEvents("BigWigs_ResumeBar", text)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerResume", text)
|
||
end
|
||
if self.nextExpire == nil then
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, bar.expirationTime - GetTime(), self)
|
||
elseif bar.expirationTime < self.nextExpire then
|
||
timer:CancelTimer(self.recheckTimer)
|
||
self.recheckTimer = timer:ScheduleTimer(self.RecheckTimers, bar.expirationTime - GetTime(), self)
|
||
self.nextExpire = bar.expirationTime
|
||
end
|
||
end
|
||
elseif event == "BigWigs_StopBars"
|
||
or event == "BigWigs_OnBossDisable"
|
||
or event == "BigWigs_OnPluginDisable"
|
||
then
|
||
local addon = ...
|
||
for timerId, bar in pairs(self.bars) do
|
||
if bar.addon == addon then
|
||
self.bars[timerId] = nil
|
||
Private.ScanEvents("BigWigs_StopBar", timerId)
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerStop", timerId)
|
||
end
|
||
end
|
||
end
|
||
elseif event == "BigWigs_SetStage" then
|
||
local addon, stage = ...
|
||
self.currentStage = stage
|
||
Private.ScanEvents("BigWigs_SetStage")
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_SetStage")
|
||
end
|
||
elseif event == "BigWigs_OnBossWipe" or event == "BigWigs_OnBossWin" then
|
||
self.currentStage = 0
|
||
Private.ScanEvents("BigWigs_SetStage")
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_SetStage")
|
||
end
|
||
end
|
||
end,
|
||
|
||
RegisterCallback = function(self, event)
|
||
if self.registeredEvents[event] then
|
||
return
|
||
end
|
||
if BigWigsLoader then
|
||
BigWigsLoader.RegisterMessage(WeakAuras, event, function(...) self:EventCallback(...) end)
|
||
self.registeredEvents[event] = true
|
||
if event == "BigWigs_SetStage" then
|
||
-- on init of BigWigs_SetStage callback, we want to fetch currentStage in case we are already in an encounter when this is run
|
||
if BigWigs and BigWigs.IterateBossModules then
|
||
local stage = 0
|
||
for _, module in BigWigs:IterateBossModules() do
|
||
if module:IsEngaged() then
|
||
stage = math.max(stage, module:GetStage() or 1)
|
||
end
|
||
end
|
||
self.currentStage = stage
|
||
end
|
||
end
|
||
end
|
||
end,
|
||
|
||
RegisterTimer = function(self)
|
||
self:RegisterCallback("BigWigs_StartBar")
|
||
self:RegisterCallback("BigWigs_StopBar")
|
||
self:RegisterCallback("BigWigs_StopBars")
|
||
self:RegisterCallback("BigWigs_OnBossDisable")
|
||
self:RegisterCallback("BigWigs_PauseBar")
|
||
self:RegisterCallback("BigWigs_ResumeBar")
|
||
end,
|
||
|
||
RegisterMessage = function(self)
|
||
self:RegisterCallback("BigWigs_Message")
|
||
end,
|
||
|
||
RegisterStage = function(self)
|
||
self:RegisterCallback("BigWigs_SetStage")
|
||
self:RegisterCallback("BigWigs_OnBossWipe")
|
||
self:RegisterCallback("BigWigs_OnBossWin")
|
||
end,
|
||
|
||
scheduled_scans = {},
|
||
|
||
DoScan = function(self, fireTime)
|
||
self.scheduled_scans[fireTime] = nil
|
||
Private.ScanEvents("BigWigs_Timer_Update")
|
||
if self.isGeneric then
|
||
Private.ScanEvents("BossMod_TimerUpdate")
|
||
end
|
||
end,
|
||
|
||
ScheduleCheck = function(self, fireTime)
|
||
if not self.scheduled_scans[fireTime] then
|
||
self.scheduled_scans[fireTime] = timer:ScheduleTimer(self.DoScan, fireTime - GetTime(), self, fireTime)
|
||
end
|
||
end
|
||
}
|
||
|
||
Private.event_prototypes["BigWigs Stage"] = {
|
||
type = "addons",
|
||
events = {},
|
||
internal_events = {
|
||
"BigWigs_SetStage"
|
||
},
|
||
name = L["BigWigs Stage"],
|
||
init = function(trigger)
|
||
Private.ExecEnv.BossMods.BigWigs:RegisterStage()
|
||
return ""
|
||
end,
|
||
args = {
|
||
{
|
||
name = "stage",
|
||
init = "Private.ExecEnv.BossMods.BigWigs:GetStage()",
|
||
display = L["Stage"],
|
||
type = "number",
|
||
conditionType = "number",
|
||
store = true,
|
||
}
|
||
},
|
||
automaticrequired = true,
|
||
statesParameter = "one",
|
||
progressType = "none"
|
||
}
|
||
Private.category_event_prototype.addons["BigWigs Stage"] = L["BigWigs Stage"]
|
||
|
||
Private.event_prototypes["BigWigs Message"] = {
|
||
type = "addons",
|
||
events = {},
|
||
internal_events = {
|
||
"BigWigs_Message"
|
||
},
|
||
name = L["BigWigs Message"],
|
||
init = function(trigger)
|
||
Private.ExecEnv.BossMods.BigWigs:RegisterMessage();
|
||
local ret = "local use_cloneId = %s;"
|
||
return ret:format(trigger.use_cloneId and "true" or "false");
|
||
end,
|
||
statesParameter = "all",
|
||
args = {
|
||
{
|
||
name = "addon",
|
||
init = "arg",
|
||
display = L["BigWigs Addon"],
|
||
type = "string"
|
||
},
|
||
{
|
||
name = "spellId",
|
||
init = "arg",
|
||
display = L["ID"],
|
||
desc = L["The 'ID' value can be found in the BigWigs options of a specific spell"],
|
||
type = "spell",
|
||
conditionType = "string",
|
||
noValidation = true,
|
||
showExactOption = false,
|
||
},
|
||
{
|
||
name = "text",
|
||
init = "arg",
|
||
display = L["Message"],
|
||
type = "longstring",
|
||
store = true,
|
||
conditionType = "string"
|
||
},
|
||
{
|
||
name = "name",
|
||
init = "text",
|
||
hidden = true,
|
||
test = "true",
|
||
store = true
|
||
},
|
||
{}, -- Importance, might be useful
|
||
{
|
||
name = "icon",
|
||
init = "arg",
|
||
hidden = true,
|
||
test = "true",
|
||
store = true
|
||
},
|
||
{
|
||
name = "cloneId",
|
||
display = L["Clone per Event"],
|
||
type = "toggle",
|
||
test = "true",
|
||
init = "use_cloneId and WeakAuras.GetUniqueCloneId() or ''"
|
||
},
|
||
},
|
||
timedrequired = true,
|
||
progressType = "timed"
|
||
}
|
||
Private.category_event_prototype.addons["BigWigs Message"] = L["BigWigs Message"]
|
||
|
||
Private.event_prototypes["BigWigs Timer"] = {
|
||
type = "addons",
|
||
events = {},
|
||
internal_events = {
|
||
"BigWigs_StartBar", "BigWigs_StopBar", "BigWigs_Timer_Update", "BigWigs_PauseBar", "BigWigs_ResumeBar"
|
||
},
|
||
force_events = "BigWigs_Timer_Force",
|
||
name = L["BigWigs Timer"],
|
||
progressType = "timed",
|
||
triggerFunction = function(trigger)
|
||
Private.ExecEnv.BossMods.BigWigs:RegisterTimer()
|
||
local ret = [=[
|
||
local triggerCounter = %q
|
||
local counter
|
||
if triggerCounter and triggerCounter ~= "" then
|
||
counter = Private.ExecEnv.CreateTriggerCounter(triggerCounter)
|
||
else
|
||
counter = Private.ExecEnv.CreateTriggerCounter()
|
||
end
|
||
return function(states, event, timerId)
|
||
local triggerSpellId = %q
|
||
local triggerText = %q
|
||
local triggerTextOperator = %q
|
||
local useClone = %s
|
||
local extendTimer = %s
|
||
local triggerUseRemaining = %s
|
||
local triggerRemaining = %s
|
||
local triggerCast = %s
|
||
local triggerIsCooldown = %s
|
||
local cloneId = useClone and timerId or ""
|
||
local state = states[cloneId]
|
||
local counter = counter
|
||
|
||
function copyOrSchedule(bar, cloneId)
|
||
local remainingTime
|
||
local changed
|
||
if bar.paused then
|
||
remainingTime = bar.remaining + extendTimer
|
||
else
|
||
remainingTime = bar.expirationTime - GetTime() + extendTimer
|
||
end
|
||
if triggerUseRemaining then
|
||
if remainingTime > 0 and remainingTime %s triggerRemaining then
|
||
Private.ExecEnv.BossMods.BigWigs:CopyBarToState(bar, states, cloneId, extendTimer)
|
||
changed = true
|
||
else
|
||
local state = states[cloneId]
|
||
if state and state.show then
|
||
state.show = false
|
||
state.changed = true
|
||
changed = true
|
||
end
|
||
end
|
||
if not bar.paused then
|
||
if extendTimer > 0 then
|
||
bar.scheduledScanExpireAt = math.max(bar.scheduledScanExpireAt or 0, bar.expirationTime + extendTimer)
|
||
end
|
||
if remainingTime >= triggerRemaining then
|
||
Private.ExecEnv.BossMods.BigWigs:ScheduleCheck(bar.expirationTime - triggerRemaining + extendTimer)
|
||
end
|
||
end
|
||
else
|
||
if not bar.paused and extendTimer > 0 then
|
||
bar.scheduledScanExpireAt = math.max(bar.scheduledScanExpireAt or 0, bar.expirationTime + extendTimer)
|
||
end
|
||
if remainingTime > 0 then
|
||
Private.ExecEnv.BossMods.BigWigs:CopyBarToState(bar, states, cloneId, extendTimer)
|
||
changed = true
|
||
end
|
||
end
|
||
return changed
|
||
end
|
||
|
||
if useClone then
|
||
if event == "BigWigs_StartBar"
|
||
or event == "BigWigs_PauseBar"
|
||
or event == "BigWigs_ResumeBar"
|
||
then
|
||
if Private.ExecEnv.BossMods.BigWigs:TimerMatches(timerId, triggerText, triggerTextOperator, triggerSpellId, counter, triggerCast, triggerIsCooldown) then
|
||
local bar = Private.ExecEnv.BossMods.BigWigs:GetTimerById(timerId)
|
||
if bar then
|
||
return copyOrSchedule(bar, cloneId)
|
||
end
|
||
end
|
||
elseif event == "BigWigs_StopBar" and state then
|
||
local bar_remainingTime = state.expirationTime - GetTime() + (state.extend or 0)
|
||
if state.extend == 0 or bar_remainingTime <= 0 then
|
||
state.show = false
|
||
state.changed = true
|
||
return true
|
||
end
|
||
elseif event == "BigWigs_Timer_Update" then
|
||
local changed
|
||
for timerId, bar in pairs(Private.ExecEnv.BossMods.BigWigs:GetAllTimers()) do
|
||
if Private.ExecEnv.BossMods.BigWigs:TimerMatches(timerId, triggerText, triggerTextOperator, triggerSpellId, counter, triggerCast, triggerIsCooldown) then
|
||
changed = copyOrSchedule(bar, timerId) or changed
|
||
end
|
||
end
|
||
return changed
|
||
elseif event == "BigWigs_Timer_Force" then
|
||
local changed
|
||
for _, state in pairs(states) do
|
||
state.show = false
|
||
state.changed = true
|
||
changed = true
|
||
end
|
||
for timerId, bar in pairs(Private.ExecEnv.BossMods.BigWigs:GetAllTimers()) do
|
||
if Private.ExecEnv.BossMods.BigWigs:TimerMatches(timerId, triggerText, triggerTextOperator, triggerSpellId, counter, triggerCast, triggerIsCooldown) then
|
||
changed = copyOrSchedule(bar, timerId) or changed
|
||
end
|
||
end
|
||
return changed
|
||
end
|
||
else
|
||
if event == "BigWigs_StartBar" then
|
||
if extendTimer ~= 0 then
|
||
if Private.ExecEnv.BossMods.BigWigs:TimerMatches(timerId, triggerText, triggerTextOperator, triggerSpellId, counter, triggerCast, triggerIsCooldown) then
|
||
local bar = Private.ExecEnv.BossMods.BigWigs:GetTimerById(timerId)
|
||
Private.ExecEnv.BossMods.BigWigs:ScheduleCheck(bar.expirationTime + extendTimer)
|
||
end
|
||
end
|
||
end
|
||
local bar = Private.ExecEnv.BossMods.BigWigs:GetTimer(triggerText, triggerTextOperator, triggerSpellId, extendTimer, counter, triggerCast, triggerIsCooldown)
|
||
if bar then
|
||
if extendTimer == 0
|
||
or not (state and state.show)
|
||
or (state and state.show and state.expirationTime > (bar.expirationTime + extendTimer))
|
||
then
|
||
return copyOrSchedule(bar, cloneId)
|
||
end
|
||
else
|
||
if state and state.show then
|
||
local bar_remainingTime = state.expirationTime - GetTime() + (state.extend or 0)
|
||
if state.extend == 0 or bar_remainingTime <= 0 then
|
||
state.show = false
|
||
state.changed = true
|
||
return true
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
]=]
|
||
return ret:format(
|
||
trigger.use_count and trigger.count or "",
|
||
trigger.use_spellId and tostring(trigger.spellId) or "",
|
||
trigger.use_text and trigger.text or "",
|
||
trigger.use_text and trigger.text_operator or "",
|
||
trigger.use_cloneId and "true" or "false",
|
||
trigger.use_extend and tonumber(trigger.extend or 0) or 0,
|
||
trigger.use_remaining and "true" or "false",
|
||
trigger.remaining and tonumber(trigger.remaining or 0) or 0,
|
||
trigger.use_cast == nil and "nil" or trigger.use_cast and "true" or "false",
|
||
trigger.use_isCooldown == nil and "nil" or trigger.use_isCooldown and "true" or "false",
|
||
trigger.remaining_operator or "<"
|
||
)
|
||
end,
|
||
statesParameter = "full",
|
||
args = {
|
||
{
|
||
name = "spellId",
|
||
display = L["ID"],
|
||
desc = L["The 'ID' value can be found in the BigWigs options of a specific spell"],
|
||
type = "spell",
|
||
conditionType = "string",
|
||
noValidation = true,
|
||
showExactOption = false,
|
||
},
|
||
{
|
||
name = "text",
|
||
display = L["Message"],
|
||
type = "longstring",
|
||
store = true,
|
||
conditionType = "string"
|
||
},
|
||
{
|
||
name = "remaining",
|
||
display = L["Remaining Time"],
|
||
type = "number",
|
||
},
|
||
{
|
||
name = "extend",
|
||
display = L["Offset Timer"],
|
||
type = "string",
|
||
},
|
||
{
|
||
name = "count",
|
||
display = L["Count"],
|
||
desc = L["Occurrence of the event, reset when aura is unloaded\nCan be a range of values\nCan have multiple values separated by a comma or a space\n\nExamples:\n2nd 5th and 6th events: 2, 5, 6\n2nd to 6th: 2-6\nevery 2 events: /2\nevery 3 events starting from 2nd: 2/3\nevery 3 events starting from 2nd and ending at 11th: 2-11/3\n\nOnly if BigWigs shows it on it's bar"],
|
||
type = "string",
|
||
store = true,
|
||
conditionType = "string",
|
||
},
|
||
{
|
||
name = "cast",
|
||
display = L["Cast Bar"],
|
||
desc = L["Filter messages with format <message>"],
|
||
type = "tristate",
|
||
test = "true",
|
||
init = "false",
|
||
conditionType = "bool"
|
||
},
|
||
{
|
||
name = "isCooldown",
|
||
display = L["Cooldown"],
|
||
desc = L["Cooldown bars show time before an ability is ready to be use, BigWigs prefix them with '~'"],
|
||
type = "tristate",
|
||
test = "true",
|
||
init = "false",
|
||
conditionType = "bool"
|
||
},
|
||
{
|
||
name = "cloneId",
|
||
display = L["Clone per Event"],
|
||
type = "toggle",
|
||
test = "true",
|
||
init = "false"
|
||
},
|
||
},
|
||
automaticrequired = true,
|
||
}
|
||
Private.category_event_prototype.addons["BigWigs Timer"] = L["BigWigs Timer"]
|
||
|
||
-- Unified
|
||
if DBM then
|
||
Private.ExecEnv.BossMods.Generic = Private.ExecEnv.BossMods.DBM
|
||
Private.ExecEnv.BossMods.DBM.isGeneric = true
|
||
Private.ExecEnv.BossMods.DBM.isInstalled = true
|
||
end
|
||
--[[if BigWigsLoader or not DBM then
|
||
Private.ExecEnv.BossMods.Generic = Private.ExecEnv.BossMods.BigWigs
|
||
Private.ExecEnv.BossMods.BigWigs.isGeneric = true
|
||
Private.ExecEnv.BossMods.BigWigs.isInstalled = BigWigsLoader ~= nil
|
||
elseif DBM then
|
||
Private.ExecEnv.BossMods.Generic = Private.ExecEnv.BossMods.DBM
|
||
Private.ExecEnv.BossMods.DBM.isGeneric = true
|
||
Private.ExecEnv.BossMods.DBM.isInstalled = true
|
||
end]]
|
||
|
||
local ActiveBossModText
|
||
if Private.ExecEnv.BossMods.BigWigs.isInstalled then
|
||
ActiveBossModText = L["Active boss mod addon: |cFFffcc00BigWigs|r\n\nNote: This trigger will use BigWigs or DBM, in that order if both are installed."]
|
||
elseif Private.ExecEnv.BossMods.DBM.isInstalled then
|
||
ActiveBossModText = L["Active boss mod addon: |cFFffcc00DBM|r\n\nNote: This trigger will use BigWigs or DBM, in that order if both are installed."]
|
||
else
|
||
ActiveBossModText = L["No active boss mod addon detected.\n\nNote: This trigger will use BigWigs or DBM, in that order if both are installed."]
|
||
end
|
||
|
||
Private.event_prototypes["Boss Mod Stage"] = {
|
||
type = "addons",
|
||
events = {},
|
||
internal_events = {
|
||
"BossMod_SetStage"
|
||
},
|
||
force_events = "BossMod_SetStage",
|
||
name = L["Boss Mod Stage"],
|
||
init = function(trigger)
|
||
Private.ExecEnv.BossMods.Generic:RegisterStage()
|
||
return ""
|
||
end,
|
||
args = {
|
||
{
|
||
name = "stage",
|
||
init = "Private.ExecEnv.BossMods.Generic:GetStage()",
|
||
display = L["Stage"],
|
||
type = "number",
|
||
conditionType = "number",
|
||
store = true,
|
||
},
|
||
{
|
||
name = "note",
|
||
type = "description",
|
||
display = "",
|
||
text = ActiveBossModText
|
||
},
|
||
},
|
||
automaticrequired = true,
|
||
statesParameter = "one",
|
||
progressType = "none"
|
||
}
|
||
Private.category_event_prototype.addons["Boss Mod Stage"] = L["Boss Mod Stage"]
|
||
|
||
Private.event_prototypes["Boss Mod Stage (Event)"] = {
|
||
type = "event",
|
||
events = {
|
||
["events"] = {
|
||
"BossMod_SetStage",
|
||
}
|
||
},
|
||
name = L["Boss Mod Stage (Event)"],
|
||
init = function(trigger)
|
||
Private.ExecEnv.BossMods.Generic:RegisterStage()
|
||
return ""
|
||
end,
|
||
args = {
|
||
{
|
||
name = "stage",
|
||
init = "Private.ExecEnv.BossMods.Generic:GetStage()",
|
||
display = L["Stage"],
|
||
type = "number",
|
||
conditionType = "number",
|
||
store = true,
|
||
},
|
||
{
|
||
name = "note",
|
||
type = "description",
|
||
display = "",
|
||
text = ActiveBossModText
|
||
},
|
||
},
|
||
statesParameter = "one",
|
||
progressType = "timed",
|
||
delayEvents = true,
|
||
timedrequired = true
|
||
}
|
||
Private.category_event_prototype.addons["Boss Mod Stage (Event)"] = L["Boss Mod Stage (Event)"]
|
||
|
||
Private.event_prototypes["Boss Mod Announce"] = {
|
||
type = "addons",
|
||
events = {},
|
||
internal_events = {
|
||
"BossMod_Announce"
|
||
},
|
||
name = L["Boss Mod Announce"],
|
||
init = function(trigger)
|
||
Private.ExecEnv.BossMods.Generic:RegisterMessage();
|
||
local ret = "local use_cloneId = %s;"
|
||
return ret:format(trigger.use_cloneId and "true" or "false");
|
||
end,
|
||
statesParameter = "all",
|
||
args = {
|
||
{
|
||
name = "spellId",
|
||
init = "arg",
|
||
display = L["ID"],
|
||
store = true,
|
||
type = "spell",
|
||
conditionType = "string",
|
||
noValidation = true,
|
||
showExactOption = false,
|
||
negativeIsEJ = true
|
||
},
|
||
{
|
||
name = "message",
|
||
init = "arg",
|
||
display = L["Message"],
|
||
type = "longstring",
|
||
store = true,
|
||
conditionType = "string"
|
||
},
|
||
{
|
||
name = "name",
|
||
init = "message",
|
||
hidden = true,
|
||
test = "true",
|
||
store = true,
|
||
},
|
||
{
|
||
name = "icon",
|
||
init = "arg",
|
||
store = true,
|
||
hidden = true,
|
||
test = "true"
|
||
},
|
||
{
|
||
name = "count",
|
||
init = "arg",
|
||
display = L["Count"],
|
||
desc = L["Occurrence of the event\nCan be a range of values\nCan have multiple values separated by a comma or a space\n\nExamples:\n2nd 5th and 6th events: 2, 5, 6\n2nd to 6th: 2-6\nevery 2 events: /2\nevery 3 events starting from 2nd: 2/3\nevery 3 events starting from 2nd and ending at 11th: 2-11/3\n\nWorks only if Boss Mod addon show counter"],
|
||
type = "string",
|
||
preamble = "local counter = Private.ExecEnv.CreateTriggerCounter(%q)",
|
||
test = "counter:SetCount(tonumber(count) or 0) == nil and counter:Match()",
|
||
conditionTest = function(state, needle, op, preamble)
|
||
return preamble:Check(state.count)
|
||
end,
|
||
store = true,
|
||
conditionType = "string",
|
||
},
|
||
{
|
||
name = "cloneId",
|
||
display = L["Clone per Event"],
|
||
type = "toggle",
|
||
test = "true",
|
||
init = "use_cloneId and WeakAuras.GetUniqueCloneId() or ''"
|
||
},
|
||
{
|
||
name = "note",
|
||
type = "description",
|
||
display = "",
|
||
text = ActiveBossModText
|
||
},
|
||
},
|
||
timedrequired = true,
|
||
progressType = "timed"
|
||
}
|
||
Private.category_event_prototype.addons["Boss Mod Announce"] = L["Boss Mod Announce"]
|
||
|
||
Private.event_prototypes["Boss Mod Timer"] = {
|
||
type = "addons",
|
||
events = {},
|
||
internal_events = {
|
||
"BossMod_TimerStart", "BossMod_TimerStop", "BossMod_TimerUpdate", "BossMod_TimerForce", "BossMod_TimerResume",
|
||
"BossMod_TimerPause", "BossMod_TimerUpdateIcon"
|
||
},
|
||
force_events = "BossMod_TimerForce",
|
||
name = L["Boss Mod Timer"],
|
||
progressType = "timed",
|
||
triggerFunction = function(trigger)
|
||
Private.ExecEnv.BossMods.Generic:RegisterTimer()
|
||
local ret = [=[
|
||
local triggerCounter = %q
|
||
local counter
|
||
if triggerCounter and triggerCounter ~= "" then
|
||
counter = Private.ExecEnv.CreateTriggerCounter(triggerCounter)
|
||
else
|
||
counter = Private.ExecEnv.CreateTriggerCounter()
|
||
end
|
||
local isBW = Private.ExecEnv.BossMods.Generic == Private.ExecEnv.BossMods.BigWigs
|
||
local isDBM = Private.ExecEnv.BossMods.Generic == Private.ExecEnv.BossMods.DBM
|
||
|
||
return function (states, event, timerId)
|
||
local triggerSpellId = %q
|
||
local triggerText = %q
|
||
local triggerTextOperator = %q
|
||
local useClone = %s
|
||
local extendTimer = %s
|
||
local triggerUseRemaining = %s
|
||
local triggerRemaining = %s
|
||
local cloneId = useClone and timerId or ""
|
||
local state = states[cloneId]
|
||
local counter = counter
|
||
|
||
function copyOrSchedule(bar, cloneId)
|
||
local remainingTime
|
||
local changed
|
||
if bar.paused then
|
||
remainingTime = bar.remaining + extendTimer
|
||
else
|
||
remainingTime = bar.expirationTime - GetTime() + extendTimer
|
||
end
|
||
if triggerUseRemaining then
|
||
if remainingTime > 0 and remainingTime %s triggerRemaining then
|
||
Private.ExecEnv.BossMods.Generic:CopyBarToState(bar, states, cloneId, extendTimer)
|
||
changed = true
|
||
else
|
||
local state = states[cloneId]
|
||
if state and state.show then
|
||
state.show = false
|
||
state.changed = true
|
||
changed = true
|
||
end
|
||
end
|
||
if not bar.paused then
|
||
if extendTimer > 0 then
|
||
bar.scheduledScanExpireAt = math.max(bar.scheduledScanExpireAt or 0, bar.expirationTime + extendTimer)
|
||
end
|
||
if remainingTime >= triggerRemaining then
|
||
Private.ExecEnv.BossMods.Generic:ScheduleCheck(bar.expirationTime - triggerRemaining + extendTimer)
|
||
end
|
||
end
|
||
else
|
||
if not bar.paused and extendTimer > 0 then
|
||
bar.scheduledScanExpireAt = math.max(bar.scheduledScanExpireAt or 0, bar.expirationTime + extendTimer)
|
||
end
|
||
if remainingTime > 0 then
|
||
Private.ExecEnv.BossMods.Generic:CopyBarToState(bar, states, cloneId, extendTimer)
|
||
changed = true
|
||
end
|
||
end
|
||
return changed
|
||
end
|
||
|
||
if useClone then
|
||
if event == "BossMod_TimerStart"
|
||
or event == "BossMod_TimerPause"
|
||
or event == "BossMod_TimerResume"
|
||
then
|
||
if Private.ExecEnv.BossMods.Generic:TimerMatchesGeneric(timerId, triggerText, triggerTextOperator, triggerSpellId, counter) then
|
||
local bar = Private.ExecEnv.BossMods.Generic:GetTimerById(timerId)
|
||
if bar then
|
||
return copyOrSchedule(bar, cloneId)
|
||
end
|
||
end
|
||
elseif event == "BossMod_TimerStop" and state then
|
||
local bar_remainingTime = state.expirationTime - GetTime() + (state.extend or 0)
|
||
if state.extend == 0 or bar_remainingTime <= 0 then
|
||
state.show = false
|
||
state.changed = true
|
||
return true
|
||
end
|
||
elseif event == "BossMod_TimerUpdate" or event == "BossMod_TimerUpdateIcon" then
|
||
local changed
|
||
for timerId, bar in pairs(Private.ExecEnv.BossMods.Generic:GetAllTimers()) do
|
||
if Private.ExecEnv.BossMods.Generic:TimerMatchesGeneric(timerId, triggerText, triggerTextOperator, triggerSpellId, counter) then
|
||
changed = copyOrSchedule(bar, timerId) or changed
|
||
else
|
||
local state = states[timerId]
|
||
if state then
|
||
local bar_remainingTime = state.expirationTime - GetTime() + (state.extend or 0)
|
||
if state.extend == 0 or bar_remainingTime <= 0 then
|
||
state.show = false
|
||
state.changed = true
|
||
changed = true
|
||
end
|
||
end
|
||
end
|
||
end
|
||
return changed
|
||
elseif event == "BossMod_TimerForce" then
|
||
local changed
|
||
for _, state in pairs(states) do
|
||
state.show = false
|
||
state.changed = true
|
||
changed = true
|
||
end
|
||
for timerId, bar in pairs(Private.ExecEnv.BossMods.Generic:GetAllTimers()) do
|
||
if Private.ExecEnv.BossMods.Generic:TimerMatchesGeneric(timerId, triggerText, triggerTextOperator, triggerSpellId, counter) then
|
||
changed = copyOrSchedule(bar, timerId) or changed
|
||
end
|
||
end
|
||
return changed
|
||
end
|
||
else
|
||
if event == "BossMod_TimerStart" or event == "BossMod_TimerUpdate" then
|
||
if extendTimer ~= 0 then
|
||
if Private.ExecEnv.BossMods.Generic:TimerMatchesGeneric(timerId, triggerText, triggerTextOperator, triggerSpellId, counter) then
|
||
local bar = Private.ExecEnv.BossMods.Generic:GetTimerById(timerId)
|
||
Private.ExecEnv.BossMods.Generic:ScheduleCheck(bar.expirationTime + extendTimer)
|
||
end
|
||
end
|
||
end
|
||
local bar = Private.ExecEnv.BossMods.Generic:GetTimerGeneric(triggerText, triggerTextOperator, triggerSpellId, extendTimer, counter)
|
||
if bar then
|
||
if extendTimer == 0
|
||
or not (state and state.show)
|
||
or (state and state.show and state.expirationTime > (bar.expirationTime + extendTimer))
|
||
then
|
||
return copyOrSchedule(bar, cloneId)
|
||
end
|
||
else
|
||
if state and state.show then
|
||
local bar_remainingTime = state.expirationTime - GetTime() + (state.extend or 0)
|
||
if state.extend == 0 or bar_remainingTime <= 0 then
|
||
state.show = false
|
||
state.changed = true
|
||
return true
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
]=]
|
||
|
||
return ret:format(
|
||
trigger.use_count and trigger.count or "",
|
||
trigger.use_spellId and tostring(trigger.spellId) or "",
|
||
trigger.use_message and trigger.message or "",
|
||
trigger.use_message and trigger.message_operator or "",
|
||
trigger.use_cloneId and "true" or "false",
|
||
trigger.use_extend and tonumber(trigger.extend or 0) or 0,
|
||
trigger.use_remaining and "true" or "false",
|
||
trigger.remaining and tonumber(trigger.remaining or 0) or 0,
|
||
trigger.remaining_operator or "<"
|
||
)
|
||
end,
|
||
statesParameter = "full",
|
||
args = {
|
||
{
|
||
name = "spellId",
|
||
display = L["ID"],
|
||
store = true,
|
||
type = "spell",
|
||
conditionType = "string",
|
||
noValidation = true,
|
||
showExactOption = false,
|
||
negativeIsEJ = true
|
||
},
|
||
{
|
||
name = "message",
|
||
display = L["Message"],
|
||
type = "longstring",
|
||
store = true,
|
||
conditionType = "string"
|
||
},
|
||
{
|
||
name = "remaining",
|
||
display = L["Remaining Time"],
|
||
type = "number",
|
||
},
|
||
{
|
||
name = "extend",
|
||
display = L["Offset Timer"],
|
||
type = "string",
|
||
},
|
||
{
|
||
name = "count",
|
||
display = L["Count"],
|
||
desc = L["Occurrence of the event, reset when aura is unloaded\nCan be a range of values\nCan have multiple values separated by a comma or a space\n\nExamples:\n2nd 5th and 6th events: 2, 5, 6\n2nd to 6th: 2-6\nevery 2 events: /2\nevery 3 events starting from 2nd: 2/3\nevery 3 events starting from 2nd and ending at 11th: 2-11/3\n\nOnly if DBM shows it on it's bar"],
|
||
type = "string",
|
||
conditionType = "string",
|
||
},
|
||
{
|
||
name = "cloneId",
|
||
display = L["Clone per Event"],
|
||
type = "toggle"
|
||
},
|
||
{
|
||
name = "note",
|
||
type = "description",
|
||
display = "",
|
||
text = ActiveBossModText
|
||
},
|
||
},
|
||
automaticrequired = true,
|
||
}
|
||
Private.category_event_prototype.addons["Boss Mod Timer"] = L["Boss Mod Timer"]
|
||
|
||
-- Disable DBM for users with an outdated DBM version and always disable BigWigs triggers
|
||
-- Only disable DBM triggers if the DBM version is older than 2025-Feb-09
|
||
-- References:
|
||
-- Commit: https://github.com/Zidras/DBM-Warmane/commit/5791dac460a07225c5d617d0252a88ce1e210618
|
||
-- Download: https://github.com/Zidras/DBM-Warmane/archive/refs/heads/main.zip
|
||
if not (DBM and type(DBM.Revision) == "number" and DBM.Revision >= 20250209000000) then
|
||
local dbm_trigger = {
|
||
"DBM Stage",
|
||
"DBM Announce",
|
||
"DBM Timer",
|
||
"Boss Mod Stage",
|
||
"Boss Mod Stage (Event)",
|
||
"Boss Mod Announce",
|
||
"Boss Mod Timer"
|
||
}
|
||
|
||
-- Remove all relevant DBM event prototypes
|
||
for _, event in ipairs(dbm_trigger) do
|
||
Private.event_prototypes[event] = nil
|
||
end
|
||
end
|
||
|
||
-- Always disable BigWigs triggers
|
||
local bigwigs_trigger = {
|
||
"BigWigs Stage",
|
||
"BigWigs Message",
|
||
"BigWigs Timer"
|
||
}
|
||
|
||
for _, event in ipairs(bigwigs_trigger) do
|
||
Private.event_prototypes[event] = nil
|
||
end
|