from retail
This commit is contained in:
@@ -598,19 +598,24 @@ local function firstLine(string)
|
||||
end
|
||||
|
||||
local function CreateFunctionCache(exec_env)
|
||||
local cache = {}
|
||||
cache.Load = function(self, string)
|
||||
if self[string] then
|
||||
return self[string]
|
||||
local cache = {
|
||||
funcs = setmetatable({}, {__mode = "v"})
|
||||
}
|
||||
cache.Load = function(self, string, silent)
|
||||
if self.funcs[string] then
|
||||
return self.funcs[string]
|
||||
else
|
||||
local loadedFunction, errorString = loadstring(string, firstLine(string))
|
||||
if errorString then
|
||||
print(errorString)
|
||||
else
|
||||
if not silent then
|
||||
print(errorString)
|
||||
end
|
||||
return nil, errorString
|
||||
elseif loadedFunction then
|
||||
setfenv(loadedFunction, exec_env)
|
||||
local success, func = pcall(assert(loadedFunction))
|
||||
if success then
|
||||
self[string] = func
|
||||
self.funcs[string] = func
|
||||
return func
|
||||
end
|
||||
end
|
||||
@@ -626,8 +631,8 @@ function WeakAuras.LoadFunction(string)
|
||||
return function_cache_custom:Load(string)
|
||||
end
|
||||
|
||||
function Private.LoadFunction(string)
|
||||
return function_cache_builtin:Load(string)
|
||||
function Private.LoadFunction(string, silent)
|
||||
return function_cache_builtin:Load(string, silent)
|
||||
end
|
||||
|
||||
function Private.GetSanitizedGlobal(key)
|
||||
|
||||
@@ -2443,7 +2443,7 @@ function BuffTrigger.Add(data)
|
||||
local effectiveIgnoreDead = groupTrigger and trigger.ignoreDead
|
||||
local effectiveIgnoreDisconnected = groupTrigger and trigger.ignoreDisconnected
|
||||
local effectiveIgnoreInvisible = groupTrigger and trigger.ignoreInvisible
|
||||
local effectiveHostility = trigger.unit == "nameplate" and trigger.useHostility and trigger.hostility
|
||||
local effectiveHostility = (groupTrigger or trigger.unit == "nameplate") and trigger.useHostility and trigger.hostility
|
||||
local effectiveNameCheck = groupTrigger and trigger.useUnitName and trigger.unitName
|
||||
local effectiveNpcId = trigger.unit == "nameplate" and trigger.useNpcId and Private.ExecEnv.ParseStringCheck(trigger.npcId)
|
||||
|
||||
@@ -3465,7 +3465,8 @@ function BuffTrigger.InitMultiAura()
|
||||
end
|
||||
|
||||
function BuffTrigger.HandleMultiEvent(frame, event, ...)
|
||||
Private.StartProfileSystem("bufftrigger2 - multi")
|
||||
local system = "bufftrigger2 - multi - " .. event
|
||||
Private.StartProfileSystem(system)
|
||||
if event == "COMBAT_LOG_EVENT_UNFILTERED" then
|
||||
CombatLog(...)
|
||||
elseif event == "UNIT_TARGET" then
|
||||
@@ -3498,7 +3499,7 @@ function BuffTrigger.HandleMultiEvent(frame, event, ...)
|
||||
end
|
||||
wipe(matchDataMulti)
|
||||
end
|
||||
Private.StopProfileSystem("bufftrigger2 - multi")
|
||||
Private.StopProfileSystem(system)
|
||||
end
|
||||
|
||||
function BuffTrigger.GetTriggerDescription(data, triggernum, namestable)
|
||||
|
||||
@@ -52,6 +52,9 @@ local function formatValueForAssignment(vType, value, pathToCustomFunction, path
|
||||
elseif vType == "progressSource" then
|
||||
if type(value) == "table" then
|
||||
local progressSource = Private.AddProgressSourceMetaData(data, value)
|
||||
if not progressSource then
|
||||
return "{}"
|
||||
end
|
||||
local trigger = progressSource[1] or -1
|
||||
local progressType = progressSource[2] or "auto"
|
||||
local property = progressSource[3]
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
if not WeakAuras.IsLibsOK() then return end
|
||||
|
||||
local AddonName, Private = ...
|
||||
|
||||
Private.DiscordList = {
|
||||
[=[007bb]=],
|
||||
[=[AcidWeb]=],
|
||||
[=[aelen]=],
|
||||
[=[Aishuu]=],
|
||||
[=[Ariani Continuity]=],
|
||||
[=[Azortharion]=],
|
||||
[=[BadBrain]=],
|
||||
[=[Bart]=],
|
||||
[=[Boneshock]=],
|
||||
[=[Boxthor]=],
|
||||
[=[Burlis]=],
|
||||
[=[Causese]=],
|
||||
[=[Chab]=],
|
||||
[=[cheswick]=],
|
||||
[=[Darian]=],
|
||||
[=[Desik]=],
|
||||
[=[DjinnFish]=],
|
||||
[=[exality]=],
|
||||
[=[Fatpala]=],
|
||||
[=[Fels]=],
|
||||
[=[Fenchurch]=],
|
||||
[=[Guffin]=],
|
||||
[=[Ifor]=],
|
||||
[=[Ironi]=],
|
||||
[=[Jiberish]=],
|
||||
[=[Jods]=],
|
||||
[=[kanegasi]=],
|
||||
[=[Koxy]=],
|
||||
[=[Listefano]=],
|
||||
[=[Luckyone]=],
|
||||
[=[Luxthos]=],
|
||||
[=[m33shoq]=],
|
||||
[=[maddin]=],
|
||||
[=[Max rdv 2026 pour TBC cla]=],
|
||||
[=[MetalMusicMan]=],
|
||||
[=[Murph]=],
|
||||
[=[Mynze]=],
|
||||
[=[Nona]=],
|
||||
[=[NostraDumAzz]=],
|
||||
[=[Ocelots]=],
|
||||
[=[Oi]=],
|
||||
[=[Ora]=],
|
||||
[=[phoenix7700]=],
|
||||
[=[Pseiko]=],
|
||||
[=[Reloe]=],
|
||||
[=[Shwinsta]=],
|
||||
[=[Slurp]=],
|
||||
[=[Spaten]=],
|
||||
[=[Tollo]=],
|
||||
[=[update]=],
|
||||
[=[vozochris]=],
|
||||
[=[Wizeowel]=],
|
||||
[=[Xepheris]=],
|
||||
[=[Мектран]=],
|
||||
}
|
||||
Private.DiscordListCJ = {
|
||||
}
|
||||
Private.DiscordListK = {
|
||||
}
|
||||
@@ -703,6 +703,9 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2
|
||||
elseif (data.statesParameter == "unit") then
|
||||
if arg1 then
|
||||
if Private.multiUnitUnits[data.trigger.unit] then
|
||||
if data.trigger.unit == "group" and IsInRaid() and Private.multiUnitUnits.party[arg1] then
|
||||
return
|
||||
end
|
||||
unitForUnitTrigger = arg1
|
||||
cloneIdForUnitTrigger = arg1
|
||||
else
|
||||
@@ -1149,8 +1152,8 @@ function HandleEvent(frame, event, arg1, arg2, ...)
|
||||
if (event == "PLAYER_ENTERING_WORLD") then
|
||||
timer:ScheduleTimer(function()
|
||||
HandleEvent(frame, "WA_DELAYED_PLAYER_ENTERING_WORLD");
|
||||
Private.StartProfileSystem("generictrigger WA_DELAYED_PLAYER_ENTERING_WORLD");
|
||||
Private.ScanForLoads(nil, "WA_DELAYED_PLAYER_ENTERING_WORLD")
|
||||
Private.StartProfileSystem("generictrigger WA_DELAYED_PLAYER_ENTERING_WORLD");
|
||||
Private.CheckCooldownReady();
|
||||
Private.StopProfileSystem("generictrigger WA_DELAYED_PLAYER_ENTERING_WORLD");
|
||||
Private.PreShowModels()
|
||||
@@ -1843,7 +1846,7 @@ function GenericTrigger.Add(data, region)
|
||||
end
|
||||
|
||||
if warnAboutCLEUEvents then
|
||||
Private.AuraWarnings.UpdateWarning(data.uid, "spammy_event_warning", "warning",
|
||||
Private.AuraWarnings.UpdateWarning(data.uid, "spammy_event_warning", "error",
|
||||
L["COMBAT_LOG_EVENT_UNFILTERED with no filter can trigger frame drops in raid environment. Find more information:\nhttps://github.com/WeakAuras/WeakAuras2/wiki/Deprecated-CLEU"])
|
||||
else
|
||||
Private.AuraWarnings.UpdateWarning(data.uid, "spammy_event_warning")
|
||||
@@ -2199,19 +2202,21 @@ do
|
||||
end,
|
||||
Schedule = function(self, expirationTime, id)
|
||||
if (not self.expirationTime[id] or expirationTime < self.expirationTime[id]) and expirationTime > 0 then
|
||||
if self.handles[id] then
|
||||
timer:CancelTimer(self.handles[id])
|
||||
self.handles[id] = nil
|
||||
self.expirationTime[id] = nil
|
||||
end
|
||||
|
||||
self:Cancel(id)
|
||||
local duration = expirationTime - GetTime()
|
||||
if duration > 0 then
|
||||
self.handles[id] = timer:ScheduleTimer(self.Recheck, duration, self, id)
|
||||
self.expirationTime[id] = expirationTime
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
Cancel = function(self, id)
|
||||
if self.handles[id] then
|
||||
timer:CancelTimer(self.handles[id])
|
||||
self.handles[id] = nil
|
||||
self.expirationTime[id] = nil
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
local function FetchSpellCooldown(self, id)
|
||||
@@ -2226,6 +2231,7 @@ do
|
||||
local nowReady = false
|
||||
local time = GetTime()
|
||||
if self.expirationTime[id] and self.expirationTime[id] <= time and self.expirationTime[id] ~= 0 then
|
||||
self.readyTime[id] = self.expirationTime[id]
|
||||
self.duration[id] = 0
|
||||
self.expirationTime[id] = 0
|
||||
changed = true
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A.
|
||||
with Reserved Font Name < Fira >,
|
||||
Digitized data copyright 2012-2018: The Mozilla Foundation, Telefonica S.A., Carrois Corporate GbR and bBox Type GmbH.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
@@ -19,7 +18,7 @@ with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,95 @@
|
||||
Copyright (c) 2018, Paratype Inc (https://paratype.com),
|
||||
Copyright (c) 2018, Paratype Ltd,
|
||||
with Reserved Font Name "PT Sans".
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
@@ -1533,6 +1533,176 @@ function Private.Modernize(data, oldSnapshot)
|
||||
end
|
||||
end
|
||||
|
||||
if data.internalVersion < 76 then
|
||||
local function removeHoles(t)
|
||||
local keys = {}
|
||||
for key in pairs(t) do
|
||||
table.insert(keys, key)
|
||||
end
|
||||
if #keys ~= #t then
|
||||
table.sort(keys)
|
||||
local newTable = {}
|
||||
for i, key in ipairs(keys) do
|
||||
newTable[i] = t[key]
|
||||
end
|
||||
return newTable
|
||||
else
|
||||
return t
|
||||
end
|
||||
end
|
||||
local trigger_migration = {
|
||||
["Spell Cast Succeeded"] = {
|
||||
"spellId",
|
||||
},
|
||||
["Unit Characteristics"] = {
|
||||
"level",
|
||||
},
|
||||
["Power"] = {
|
||||
"power",
|
||||
"percentpower",
|
||||
"deficit",
|
||||
"maxpower",
|
||||
},
|
||||
["Combat Log"] = {
|
||||
"spellId",
|
||||
"spellName",
|
||||
},
|
||||
["Health"] = {
|
||||
"health",
|
||||
"percenthealth",
|
||||
"deficit",
|
||||
"maxhealth",
|
||||
},
|
||||
["Location"] = {
|
||||
"zone",
|
||||
"subzone",
|
||||
},
|
||||
["Threat Situation"] = {
|
||||
"threatpct",
|
||||
"rawthreatpct",
|
||||
"threatvalue",
|
||||
},
|
||||
["Character Stats"] = {
|
||||
"strength",
|
||||
"agility",
|
||||
"stamina",
|
||||
"intellect",
|
||||
"spirit",
|
||||
"attackpower",
|
||||
"spellpower",
|
||||
"rangedattackpower",
|
||||
"criticalrating",
|
||||
"criticalpercent",
|
||||
"hitrating",
|
||||
"hitpercent",
|
||||
"hasterating",
|
||||
"hastepercent",
|
||||
"expertiserating",
|
||||
"expertisebonus",
|
||||
"armorpenrating",
|
||||
"armorpenpercent",
|
||||
"spellpenpercent",
|
||||
"resiliencerating",
|
||||
"resiliencepercent",
|
||||
"expertisebonus",
|
||||
"expertiserating",
|
||||
"resistancefire",
|
||||
"resistancenature",
|
||||
"resistancefrost",
|
||||
"resistanceshadow",
|
||||
"resistancearcane",
|
||||
"movespeedpercent",
|
||||
"dodgerating",
|
||||
"dodgepercent",
|
||||
"parryrating",
|
||||
"parrypercent",
|
||||
"blockpercent",
|
||||
"blockvalue",
|
||||
"armorrating",
|
||||
"armorpercent",
|
||||
},
|
||||
["Cast"] = {
|
||||
"spellNames",
|
||||
"spellIds",
|
||||
},
|
||||
}
|
||||
for _, triggerData in ipairs(data.triggers) do
|
||||
local trigger = triggerData.trigger
|
||||
local fieldsToMigrate = trigger_migration[trigger.event]
|
||||
if fieldsToMigrate then
|
||||
for _, field in ipairs(fieldsToMigrate) do
|
||||
if type(trigger[field]) == "table" then
|
||||
trigger[field] = removeHoles(trigger[field])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[if data.internalVersion < 77 then
|
||||
-- fix data broken by wago export
|
||||
local triggerFix = {
|
||||
talent = {
|
||||
multi = true
|
||||
},
|
||||
herotalent = {
|
||||
multi = true
|
||||
},
|
||||
form = {
|
||||
multi = true
|
||||
},
|
||||
specId = {
|
||||
multi = true
|
||||
},
|
||||
actualSpec = true,
|
||||
arena_spec = true
|
||||
}
|
||||
local loadFix = {
|
||||
talent = {
|
||||
multi = true
|
||||
},
|
||||
talent2 = {
|
||||
multi = true
|
||||
},
|
||||
talent3 = {
|
||||
multi = true
|
||||
},
|
||||
herotalent = {
|
||||
multi = true
|
||||
},
|
||||
class_and_spec = {
|
||||
multi = true
|
||||
}
|
||||
}
|
||||
local function fixData(data, fields)
|
||||
for k, v in pairs(fields) do
|
||||
if v == true and type(data[k]) == "table" then
|
||||
-- fix field k
|
||||
local tofix = {}
|
||||
for key in pairs(data[k]) do
|
||||
if type(key) == "string" then
|
||||
table.insert(tofix, key)
|
||||
end
|
||||
end
|
||||
for _, oldkey in ipairs(tofix) do
|
||||
local newkey = tonumber(oldkey)
|
||||
if newkey then
|
||||
data[k][newkey] = data[k][oldkey]
|
||||
end
|
||||
data[k][oldkey] = nil
|
||||
end
|
||||
elseif type(v) == "table" and type(data[k]) == "table" then
|
||||
-- recurse
|
||||
fixData(data[k], fields[k])
|
||||
end
|
||||
end
|
||||
end
|
||||
for _, triggerData in ipairs(data.triggers) do
|
||||
fixData(triggerData.trigger, triggerFix)
|
||||
end
|
||||
fixData(data.load, loadFix)
|
||||
end]]
|
||||
|
||||
data.internalVersion = max(data.internalVersion or 0, WeakAuras.InternalVersion())
|
||||
end
|
||||
|
||||
|
||||
@@ -711,8 +711,8 @@ end
|
||||
|
||||
function WeakAuras.ValidateNumericOrPercent(info, val)
|
||||
if val ~= nil and val ~= "" then
|
||||
local percent = string.match(val, "(%d+)%%")
|
||||
local number = percent and tonumber(percent) or tonumber(val)
|
||||
local index = val:find("%% *$")
|
||||
local number = index and tonumber(val:sub(1, index-1)) or tonumber(val)
|
||||
if(not number or number >= 2^31) then
|
||||
return false;
|
||||
end
|
||||
@@ -965,6 +965,15 @@ Private.load_prototype = {
|
||||
optional = true,
|
||||
events = {"VEHICLE_UPDATE", "UNIT_ENTERED_VEHICLE", "UNIT_EXITED_VEHICLE"}
|
||||
},
|
||||
{ -- broken, fix later COMPANION_UPDATE fires too early for an check, needs some custom stuff
|
||||
name = "mounted",
|
||||
display = L["Mounted"],
|
||||
type = "tristate",
|
||||
init = "arg",
|
||||
width = WeakAuras.normalWidth,
|
||||
optional = true,
|
||||
--events = {"PLAYER_MOUNT_DISPLAY_CHANGED"}
|
||||
},
|
||||
{
|
||||
name ="playerTitle",
|
||||
display = L["Player"],
|
||||
@@ -3810,7 +3819,13 @@ Private.event_prototypes = {
|
||||
test = "true",
|
||||
conditionType = "bool",
|
||||
conditionTest = function(state, needle)
|
||||
return state and state.show and (UnitExists('target') and IsItemInRange(state.itemname, 'target')) == (needle == 1)
|
||||
if not state or not state.show or not UnitExists('target') then
|
||||
return false
|
||||
end
|
||||
if InCombatLockdown() and not UnitCanAttack('player', 'target') then
|
||||
return false
|
||||
end
|
||||
return IsItemInRange(state.itemname, 'target') == (needle == 1)
|
||||
end,
|
||||
conditionEvents = {
|
||||
"PLAYER_TARGET_CHANGED",
|
||||
@@ -4419,7 +4434,7 @@ Private.event_prototypes = {
|
||||
return { "SPELL_COOLDOWN_CHANGED:" .. spellName }
|
||||
end,
|
||||
force_events = "SPELL_UPDATE_USABLE",
|
||||
name = L["Action Usable"],
|
||||
name = L["Spell Usable"],
|
||||
statesParameter = "one",
|
||||
loadFunc = function(trigger)
|
||||
trigger.spellName = trigger.spellName or 0;
|
||||
|
||||
@@ -449,7 +449,7 @@ local centeredIndexerStart = {
|
||||
if maxIndex >= 3 then
|
||||
return maxIndex - maxIndex % 2
|
||||
else
|
||||
return maxIndex
|
||||
return maxIndex > 0 and maxIndex or nil
|
||||
end
|
||||
end,
|
||||
-- Center -> Right -> Left, e.g: 3 1 2 4
|
||||
@@ -457,7 +457,7 @@ local centeredIndexerStart = {
|
||||
if maxIndex % 2 == 1 then
|
||||
return maxIndex
|
||||
else
|
||||
return maxIndex - 1
|
||||
return maxIndex > 0 and maxIndex - 1 or nil
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
@@ -344,8 +344,9 @@ local function SetProgressSource(self, progressSource)
|
||||
self:UpdateProgress()
|
||||
end
|
||||
local function SetAdjustedMin(self, adjustedMin)
|
||||
local percent = string.match(adjustedMin, "(%d+)%%")
|
||||
if percent then
|
||||
local index = adjustedMin:find("%% *$")
|
||||
if index then
|
||||
local percent = adjustedMin:sub(1, index-1)
|
||||
self.adjustedMinRelPercent = tonumber(percent) / 100
|
||||
self.adjustedMin = nil
|
||||
else
|
||||
@@ -355,8 +356,9 @@ local function SetAdjustedMin(self, adjustedMin)
|
||||
self:UpdateProgress()
|
||||
end
|
||||
local function SetAdjustedMax(self, adjustedMax)
|
||||
local percent = string.match(adjustedMax, "(%d+)%%")
|
||||
if percent then
|
||||
local index = adjustedMax:find("%% *$")
|
||||
if index then
|
||||
local percent = adjustedMax:sub(1, index-1)
|
||||
self.adjustedMaxRelPercent = tonumber(percent) / 100
|
||||
else
|
||||
self.adjustedMax = tonumber(adjustedMax)
|
||||
|
||||
+4
-3
@@ -2377,8 +2377,8 @@ end
|
||||
-- register options font
|
||||
LSM:Register("font", "Fira Mono Medium", "Interface\\Addons\\WeakAuras\\Media\\Fonts\\FiraMono-Medium.ttf", LSM.LOCALE_BIT_western + LSM.LOCALE_BIT_ruRU)
|
||||
-- Other Fira fonts
|
||||
LSM:Register("font", "Fira Sans Black", "Interface\\Addons\\WeakAuras\\Media\\Fonts\\FiraSans-Black.ttf", LSM.LOCALE_BIT_western + LSM.LOCALE_BIT_ruRU)
|
||||
LSM:Register("font", "Fira Sans Condensed Black", "Interface\\Addons\\WeakAuras\\Media\\Fonts\\FiraSansCondensed-Black.ttf", LSM.LOCALE_BIT_western + LSM.LOCALE_BIT_ruRU)
|
||||
LSM:Register("font", "Fira Sans Black", "Interface\\Addons\\WeakAuras\\Media\\Fonts\\FiraSans-Heavy.ttf", LSM.LOCALE_BIT_western + LSM.LOCALE_BIT_ruRU)
|
||||
LSM:Register("font", "Fira Sans Condensed Black", "Interface\\Addons\\WeakAuras\\Media\\Fonts\\FiraSansCondensed-Heavy.ttf", LSM.LOCALE_BIT_western + LSM.LOCALE_BIT_ruRU)
|
||||
LSM:Register("font", "Fira Sans Condensed Medium", "Interface\\Addons\\WeakAuras\\Media\\Fonts\\FiraSansCondensed-Medium.ttf", LSM.LOCALE_BIT_western + LSM.LOCALE_BIT_ruRU)
|
||||
LSM:Register("font", "Fira Sans Medium", "Interface\\Addons\\WeakAuras\\Media\\Fonts\\FiraSans-Medium.ttf", LSM.LOCALE_BIT_western + LSM.LOCALE_BIT_ruRU)
|
||||
LSM:Register("font", "PT Sans Narrow Regular", "Interface\\Addons\\WeakAuras\\Media\\Fonts\\PTSansNarrow-Regular.ttf", LSM.LOCALE_BIT_western + LSM.LOCALE_BIT_ruRU)
|
||||
@@ -2606,7 +2606,8 @@ Private.update_categories = {
|
||||
"url",
|
||||
"desc",
|
||||
"version",
|
||||
"semver"
|
||||
"semver",
|
||||
"wagoID", -- i don't *love* that we're so closely tied to wago, but eh
|
||||
},
|
||||
default = true,
|
||||
label = L["Meta Data"],
|
||||
|
||||
+143
-97
@@ -1,6 +1,6 @@
|
||||
local AddonName, Private = ...
|
||||
|
||||
local internalVersion = 75
|
||||
local internalVersion = 78
|
||||
|
||||
-- Lua APIs
|
||||
local insert = table.insert
|
||||
@@ -183,6 +183,8 @@ function SlashCmdList.WEAKAURAS(input)
|
||||
WeakAuras.PrintProfile();
|
||||
elseif msg == "pcancel" then
|
||||
WeakAuras.CancelScheduledProfile()
|
||||
elseif msg == "pshow" or msg == "profiling" then
|
||||
WeakAuras.RealTimeProfilingWindow:Toggle()
|
||||
elseif msg == "minimap" then
|
||||
Private.ToggleMinimap();
|
||||
elseif msg == "help" then
|
||||
@@ -1075,21 +1077,20 @@ function Private.LoginMessage()
|
||||
return loginMessage
|
||||
end
|
||||
|
||||
function Private.Login(initialTime, takeNewSnapshots)
|
||||
function Private.Login(takeNewSnapshots)
|
||||
local loginThread = coroutine.create(function()
|
||||
Private.Pause();
|
||||
|
||||
coroutine.yield(100)
|
||||
if db.history then
|
||||
local histRepo = WeakAuras.LoadFromArchive("Repository", "history")
|
||||
local migrationRepo = WeakAuras.LoadFromArchive("Repository", "migration")
|
||||
for uid, hist in pairs(db.history) do
|
||||
local histStore = histRepo:Set(uid, hist.data)
|
||||
local migrationStore = migrationRepo:Set(uid, hist.migration)
|
||||
coroutine.yield()
|
||||
coroutine.yield(1000, "login move old history")
|
||||
end
|
||||
-- history is now in archive so we can shrink WeakAurasSaved
|
||||
db.history = nil
|
||||
coroutine.yield();
|
||||
end
|
||||
|
||||
local toAdd = {};
|
||||
@@ -1103,14 +1104,15 @@ function Private.Login(initialTime, takeNewSnapshots)
|
||||
|
||||
tinsert(toAdd, data);
|
||||
end
|
||||
coroutine.yield();
|
||||
coroutine.yield(8000);
|
||||
|
||||
Private.AddMany(toAdd, takeNewSnapshots);
|
||||
coroutine.yield();
|
||||
coroutine.yield(1000);
|
||||
|
||||
Private.RegisterLoadEvents();
|
||||
coroutine.yield(10000);
|
||||
Private.Resume();
|
||||
coroutine.yield();
|
||||
coroutine.yield(100);
|
||||
|
||||
local nextCallback = loginQueue[1];
|
||||
while nextCallback do
|
||||
@@ -1120,7 +1122,7 @@ function Private.Login(initialTime, takeNewSnapshots)
|
||||
else
|
||||
nextCallback()
|
||||
end
|
||||
coroutine.yield();
|
||||
coroutine.yield(1000, "login post login callbacks");
|
||||
nextCallback = loginQueue[1];
|
||||
end
|
||||
|
||||
@@ -1129,31 +1131,12 @@ function Private.Login(initialTime, takeNewSnapshots)
|
||||
for _, region in pairs(Private.regions) do
|
||||
if (region.region and region.region.RunDelayedActions) then
|
||||
region.region:RunDelayedActions();
|
||||
coroutine.yield()
|
||||
coroutine.yield(500, "login delayed region actions");
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if initialTime then
|
||||
local startTime = debugprofilestop()
|
||||
local finishTime = debugprofilestop()
|
||||
local ok, msg
|
||||
-- hard limit seems to be 19 seconds. We'll do 15 for now.
|
||||
while coroutine.status(loginThread) ~= 'dead' and finishTime - startTime < 15000 do
|
||||
ok, msg = coroutine.resume(loginThread)
|
||||
finishTime = debugprofilestop()
|
||||
end
|
||||
if coroutine.status(loginThread) ~= 'dead' then
|
||||
Private.dynFrame:AddAction('login', loginThread)
|
||||
end
|
||||
if not ok then
|
||||
loginMessage = L["WeakAuras has encountered an error during the login process. Please report this issue at https://github.com/WeakAuras/Weakauras2/issues/new."]
|
||||
.. "\nMessage:" .. msg
|
||||
geterrorhandler()(msg .. '\n' .. debugstack(loginThread))
|
||||
end
|
||||
else
|
||||
Private.dynFrame:AddAction('login', loginThread)
|
||||
end
|
||||
Private.Threads:Immediate('login', loginThread, 15000, 1000)
|
||||
end
|
||||
|
||||
local WeakAurasFrame = CreateFrame("Frame", "WeakAurasFrame", UIParent);
|
||||
@@ -1194,7 +1177,8 @@ loadedFrame:SetScript("OnEvent", function(self, event, addon)
|
||||
|
||||
if db.lastArchiveClear == nil then
|
||||
db.lastArchiveClear = time();
|
||||
elseif db.lastArchiveClear < time() - 86400 then
|
||||
elseif db.lastArchiveClear < time() - 2505600 --[[29 days]] then
|
||||
db.lastArchiveClear = time();
|
||||
Private.CleanArchive(db.historyCutoff, db.migrationCutoff);
|
||||
end
|
||||
db.minimap = db.minimap or { hide = false };
|
||||
@@ -1216,8 +1200,7 @@ loadedFrame:SetScript("OnEvent", function(self, event, addon)
|
||||
dbIsValid = true
|
||||
end
|
||||
if dbIsValid then
|
||||
-- run login thread for up to 15 seconds, then defer to dynFrame
|
||||
Private.Login(15000, takeNewSnapshots)
|
||||
Private.Login(takeNewSnapshots)
|
||||
else
|
||||
-- db isn't valid. Request permission to run repair tool before logging in
|
||||
StaticPopup_Show("WEAKAURAS_CONFIRM_REPAIR", nil, nil, {reason = "downgrade"})
|
||||
@@ -1412,12 +1395,15 @@ local function scanForLoadsImpl(toCheck, event, arg1, ...)
|
||||
local vehicleUi = UnitHasVehicleUI("player") or false
|
||||
|
||||
local raidMemberType = 0
|
||||
|
||||
if UnitIsPartyLeader("player") then
|
||||
raidMemberType = raidMemberType + 1
|
||||
|
||||
elseif UnitIsRaidOfficer("player") then
|
||||
raidMemberType = raidMemberType + 2
|
||||
end
|
||||
|
||||
local mounted = IsMounted()
|
||||
local size, difficulty, instanceType = GetInstanceTypeAndSize()
|
||||
local group = Private.ExecEnv.GroupType()
|
||||
local groupSize = GetNumGroupMembers()
|
||||
@@ -1433,8 +1419,8 @@ local function scanForLoadsImpl(toCheck, event, arg1, ...)
|
||||
if (data and not data.controlledChildren) then
|
||||
local loadFunc = loadFuncs[id];
|
||||
local loadOpt = loadFuncsForOptions[id];
|
||||
shouldBeLoaded = loadFunc and loadFunc("ScanForLoads_Auras", inCombat, alive, pvp, vehicle, vehicleUi, player, realm, class, race, faction, playerLevel, raidRole, group, groupSize, raidMemberType, zone, zoneId, subzone, size, difficulty);
|
||||
couldBeLoaded = loadOpt and loadOpt("ScanForLoads_Auras", inCombat, alive, pvp, vehicle, vehicleUi, player, realm, class, race, faction, playerLevel, raidRole, group, groupSize, raidMemberType, zone, zoneId, subzone, size, difficulty);
|
||||
shouldBeLoaded = loadFunc and loadFunc("ScanForLoads_Auras", inCombat, alive, pvp, vehicle, vehicleUi, mounted, player, realm, class, race, faction, playerLevel, raidRole, group, groupSize, raidMemberType, zone, zoneId, subzone, size, difficulty);
|
||||
couldBeLoaded = loadOpt and loadOpt("ScanForLoads_Auras", inCombat, alive, pvp, vehicle, vehicleUi, mounted, player, realm, class, race, faction, playerLevel, raidRole, group, groupSize, raidMemberType, zone, zoneId, subzone, size, difficulty);
|
||||
|
||||
if(shouldBeLoaded and not loaded[id]) then
|
||||
changed = changed + 1;
|
||||
@@ -1983,20 +1969,20 @@ function Private.NeedToRepairDatabase()
|
||||
return db.dbVersion and db.dbVersion > WeakAuras.InternalVersion()
|
||||
end
|
||||
|
||||
local function RepairDatabase(loginAfter)
|
||||
local function RepairDatabase()
|
||||
local coro = coroutine.create(function()
|
||||
Private.SetImporting(true)
|
||||
-- set db version to current code version
|
||||
db.dbVersion = WeakAuras.InternalVersion()
|
||||
-- reinstall snapshots from history
|
||||
local newDB = WeakAuras.Mixin({}, db.displays)
|
||||
coroutine.yield()
|
||||
coroutine.yield(1000)
|
||||
for id, data in pairs(db.displays) do
|
||||
local snapshot = Private.GetMigrationSnapshot(data.uid)
|
||||
if snapshot then
|
||||
newDB[id] = nil
|
||||
newDB[snapshot.id] = snapshot
|
||||
coroutine.yield()
|
||||
coroutine.yield(1000, "repair get snapshot")
|
||||
end
|
||||
end
|
||||
db.displays = newDB
|
||||
@@ -2004,7 +1990,7 @@ local function RepairDatabase(loginAfter)
|
||||
-- finally, login
|
||||
Private.Login()
|
||||
end)
|
||||
Private.dynFrame:AddAction("repair", coro)
|
||||
Private.Threads:Add("repair", coro, 'urgent')
|
||||
end
|
||||
|
||||
StaticPopupDialogs["WEAKAURAS_CONFIRM_REPAIR"] = {
|
||||
@@ -2165,9 +2151,9 @@ local function loadOrder(tbl, idtable)
|
||||
if not(loaded[data.parent]) then
|
||||
local dependsOut = CopyTable(depends)
|
||||
dependsOut[data.parent] = true
|
||||
coroutine.yield()
|
||||
coroutine.yield(100, "sort deps")
|
||||
load(data.parent, dependsOut)
|
||||
coroutine.yield()
|
||||
coroutine.yield(100, "sort deps")
|
||||
end
|
||||
end
|
||||
else
|
||||
@@ -2175,15 +2161,15 @@ local function loadOrder(tbl, idtable)
|
||||
end
|
||||
end
|
||||
if not(loaded[id]) then
|
||||
coroutine.yield();
|
||||
coroutine.yield(100, "sort deps");
|
||||
loaded[id] = true;
|
||||
tinsert(order, idtable[id])
|
||||
end
|
||||
end
|
||||
|
||||
for id, data in pairs(idtable) do
|
||||
for id in pairs(idtable) do
|
||||
load(id, {});
|
||||
coroutine.yield()
|
||||
coroutine.yield(100, "sort deps")
|
||||
end
|
||||
return order
|
||||
end
|
||||
@@ -2207,17 +2193,26 @@ function Private.AddMany(tbl, takeSnapshots)
|
||||
end
|
||||
|
||||
local order = loadOrder(tbl, idtable)
|
||||
coroutine.yield()
|
||||
coroutine.yield(5000)
|
||||
|
||||
local oldSnapshots = {}
|
||||
local copies = {}
|
||||
if takeSnapshots then
|
||||
for _, data in ipairs(order) do
|
||||
if Private.ModernizeNeedsOldSnapshot(data) then
|
||||
oldSnapshots[data.uid] = Private.GetMigrationSnapshot(data.uid)
|
||||
end
|
||||
Private.SetMigrationSnapshot(data.uid, data)
|
||||
coroutine.yield()
|
||||
copies[data.uid] = CopyTable(data)
|
||||
coroutine.yield(200, "addmany prepare snapshot")
|
||||
end
|
||||
Private.Threads:Add("snapshot", coroutine.create(function()
|
||||
prettyPrint(L["WeakAuras is creating a rollback snapshot of your auras. This snapshot will allow you to revert to the current state of your auras if something goes wrong. This process may cause your framerate to drop until it is complete."])
|
||||
for uid, data in pairs(copies) do
|
||||
Private.SetMigrationSnapshot(uid, data)
|
||||
coroutine.yield(200, "snapshot")
|
||||
end
|
||||
prettyPrint(L["Rollback snapshot is complete. Thank you for your patience!"])
|
||||
end), 'normal')
|
||||
end
|
||||
|
||||
local groups = {}
|
||||
@@ -2238,7 +2233,7 @@ function Private.AddMany(tbl, takeSnapshots)
|
||||
elseif data.regionType == "dynamicgroup" or data.regionType == "group" then
|
||||
groups[data] = true
|
||||
end
|
||||
coroutine.yield()
|
||||
coroutine.yield(1000, "addmany modernize")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2254,13 +2249,14 @@ function Private.AddMany(tbl, takeSnapshots)
|
||||
end
|
||||
end
|
||||
end
|
||||
coroutine.yield()
|
||||
coroutine.yield(2000, "addmany add")
|
||||
end
|
||||
|
||||
for id in pairs(anchorTargets) do
|
||||
local data = idtable[id]
|
||||
if data and not bads[data.id] and (data.parent == nil or idtable[data.parent].regionType ~= "dynamicgroup") then
|
||||
Private.EnsureRegion(id)
|
||||
coroutine.yield(100, "addmany ensure anchor")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2274,7 +2270,7 @@ function Private.AddMany(tbl, takeSnapshots)
|
||||
WeakAuras.Add(data)
|
||||
end
|
||||
end
|
||||
coroutine.yield();
|
||||
coroutine.yield(1000, "addmany reload dynamic group");
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3839,78 +3835,128 @@ function WeakAuras.EnsureString(input)
|
||||
end
|
||||
|
||||
-- Handle coroutines
|
||||
local dynFrame = {};
|
||||
local threads = {
|
||||
frame = CreateFrame("Frame"),
|
||||
size = 0,
|
||||
---@type table<string, threadPriority>
|
||||
prios = {},
|
||||
pools = {
|
||||
urgent = {},
|
||||
normal = {},
|
||||
background = {},
|
||||
instant = {},
|
||||
},
|
||||
};
|
||||
do
|
||||
-- Internal data
|
||||
dynFrame.frame = CreateFrame("Frame");
|
||||
dynFrame.update = {};
|
||||
dynFrame.size = 0;
|
||||
local validPriorities = {
|
||||
urgent = true,
|
||||
normal = true,
|
||||
background = true,
|
||||
instant = true,
|
||||
}
|
||||
|
||||
-- Add an action to be resumed via OnUpdate
|
||||
function dynFrame.AddAction(self, name, func)
|
||||
if not name then
|
||||
name = string.format("NIL", dynFrame.size+1);
|
||||
function threads:Add(name, thread, prio)
|
||||
if not prio or not validPriorities[prio] then
|
||||
prio = "normal"
|
||||
end
|
||||
if type(thread) == "function" then
|
||||
thread = coroutine.create(thread)
|
||||
end
|
||||
if not self.prios[name] then
|
||||
self.prios[name] = prio
|
||||
self.pools[prio][name] = {
|
||||
thread = thread,
|
||||
sequence = {}
|
||||
}
|
||||
self.size = self.size + 1
|
||||
self.frame:Show()
|
||||
end
|
||||
end
|
||||
|
||||
if not dynFrame.update[name] then
|
||||
dynFrame.update[name] = func;
|
||||
dynFrame.size = dynFrame.size + 1
|
||||
dynFrame.frame:Show();
|
||||
function threads:SetPriority(name, prio)
|
||||
local oldPrio = self.prios[name]
|
||||
if oldPrio and oldPrio ~= prio then
|
||||
self.pools[prio][name] = self.pools[oldPrio][name]
|
||||
self.pools[oldPrio][name] = nil
|
||||
self.prios[name] = prio
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove an action from OnUpdate
|
||||
function dynFrame.RemoveAction(self, name)
|
||||
if dynFrame.update[name] then
|
||||
dynFrame.update[name] = nil;
|
||||
dynFrame.size = dynFrame.size - 1
|
||||
if dynFrame.size == 0 then
|
||||
dynFrame.frame:Hide();
|
||||
function threads:Remove(name)
|
||||
local prio = self.prios[name]
|
||||
if prio then
|
||||
local pool = self.pools[prio]
|
||||
pool[name] = nil
|
||||
self.prios[name] = nil
|
||||
self.size = self.size - 1
|
||||
if self.size == 0 then
|
||||
self.frame:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Setup frame
|
||||
dynFrame.frame:Hide();
|
||||
dynFrame.frame:SetScript("OnUpdate", function(self, elapsed)
|
||||
-- Start timing
|
||||
local start = debugprofilestop();
|
||||
local hasData = true;
|
||||
|
||||
-- Resume as often as possible (Limit to 16ms per frame -> 60 FPS)
|
||||
while (debugprofilestop() - start < 16 and hasData) do
|
||||
-- Stop loop without data
|
||||
hasData = false;
|
||||
|
||||
-- Resume all coroutines
|
||||
for name, func in pairs(dynFrame.update) do
|
||||
-- Loop has data
|
||||
hasData = true;
|
||||
|
||||
-- Resume or remove
|
||||
if coroutine.status(func) ~= "dead" then
|
||||
local ok, msg = coroutine.resume(func)
|
||||
if not ok then
|
||||
geterrorhandler()(msg .. '\n' .. debugstack(func))
|
||||
end
|
||||
local function runThreadPool(pool, finish, defaultEstimate)
|
||||
local start = debugprofilestop()
|
||||
if finish <= start then return end
|
||||
local estimates = {}
|
||||
local ok, val1, val2
|
||||
local continue = false
|
||||
repeat
|
||||
continue = false
|
||||
for name, threadData in pairs(pool) do
|
||||
local estimate = estimates[name] or defaultEstimate
|
||||
if debugprofilestop() + estimate > finish then
|
||||
break
|
||||
else
|
||||
dynFrame:RemoveAction(name);
|
||||
continue = true
|
||||
ok, val1, val2 = coroutine.resume(threadData.thread)
|
||||
if not ok then
|
||||
geterrorhandler()(val1 .. '\n' .. debugstack(threadData.thread))
|
||||
end
|
||||
if coroutine.status(threadData.thread) ~= "dead" then
|
||||
estimates[name] = type(val1) == "number" and val1 or defaultEstimate
|
||||
local sequence = val2 or ""
|
||||
threadData.sequence[sequence] = (threadData.sequence[sequence] or 0) + 1
|
||||
else
|
||||
threads:Remove(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
until not continue
|
||||
end
|
||||
|
||||
function threads:Immediate(name, func, limit, defaultEstimate)
|
||||
self:Add(name, func, "instant")
|
||||
runThreadPool(self.pools.instant, debugprofilestop() + limit, defaultEstimate or 1000)
|
||||
if coroutine.status(func) ~= "dead" then
|
||||
self:SetPriority(name, "urgent")
|
||||
else
|
||||
self:Remove(name)
|
||||
end
|
||||
end
|
||||
|
||||
-- Setup frame
|
||||
threads.frame:Hide();
|
||||
threads.frame:SetScript("OnUpdate", function()
|
||||
local start = debugprofilestop();
|
||||
runThreadPool(threads.pools.urgent, start + 15000, 1000)
|
||||
runThreadPool(threads.pools.normal, start + 20, 1)
|
||||
runThreadPool(threads.pools.background, start + 2, 0.5)
|
||||
end);
|
||||
dynFrame.frame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
dynFrame.frame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
dynFrame.frame:SetScript("OnEvent", function(self, event)
|
||||
threads.frame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
threads.frame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
threads.frame:SetScript("OnEvent", function(self, event)
|
||||
if event == "PLAYER_REGEN_ENABLED" and self:IsShown() then
|
||||
self:Hide()
|
||||
elseif event == "PLAYER_REGEN_DISABLED" and not self:IsShown() and dynFrame.size > 0 then
|
||||
elseif event == "PLAYER_REGEN_DISABLED" and not self:IsShown() and threads.size > 0 then
|
||||
self:Show()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
Private.dynFrame = dynFrame;
|
||||
Private.Threads = threads;
|
||||
|
||||
function WeakAuras.RegisterTriggerSystem(types, triggerSystem)
|
||||
for _, v in ipairs(types) do
|
||||
|
||||
@@ -72,3 +72,6 @@ SubRegionTypes\Border.lua
|
||||
SubRegionTypes\Glow.lua
|
||||
SubRegionTypes\Tick.lua
|
||||
SubRegionTypes\Model.lua
|
||||
|
||||
#Misc
|
||||
DiscordList.lua
|
||||
Reference in New Issue
Block a user