diff --git a/WeakAuras/AuraEnvironment.lua b/WeakAuras/AuraEnvironment.lua index e966cc2..a89a015 100644 --- a/WeakAuras/AuraEnvironment.lua +++ b/WeakAuras/AuraEnvironment.lua @@ -117,7 +117,11 @@ WeakAuras.HideOverlayGlow = LCG.ButtonGlow_Stop local LGF = LibStub("LibGetFrame-1.0") WeakAuras.GetUnitFrame = LGF.GetUnitFrame -WeakAuras.GetNamePlateForUnit = LGF.GetUnitNameplate +WeakAuras.GetNamePlateForUnit = function(unit) + if Private.multiUnitUnits.nameplate[unit] then + return LGF.GetUnitNameplate(unit) + end +end local blockedFunctions = { -- Lua functions that may allow breaking out of the environment diff --git a/WeakAuras/BuffTrigger2.lua b/WeakAuras/BuffTrigger2.lua index 821a8b9..abc2d44 100644 --- a/WeakAuras/BuffTrigger2.lua +++ b/WeakAuras/BuffTrigger2.lua @@ -46,6 +46,18 @@ Returns the potential conditions for a trigger if not WeakAuras.IsLibsOK() then return end local AddonName, Private = ... +local function FixDebuffClass(debuffClass) + if debuffClass == nil then + debuffClass = "none" + elseif debuffClass == "" then + debuffClass = "enrage" + else + debuffClass = string.lower(debuffClass) + end + return debuffClass +end + + -- Lua APIs local tinsert, wipe = table.insert, wipe local pairs, next, type = pairs, next, type @@ -112,7 +124,7 @@ local function UnitExistsFixed(unit) if #unit > 9 and unit:sub(1, 9) == "nameplate" then return nameplateExists[unit] or false end - return UnitExists(unit) or UnitGUID(unit) or false + return (UnitExists(unit) and UnitGUID(unit)) or false end local function UnitIsVisibleFixed(unit) @@ -240,6 +252,24 @@ local function MatchesTriggerInfoMulti(triggerInfo, sourceGUID) end end +local function CheckScanFuncs(scanFuncs, unit, filter, key) + if scanFuncs then + for triggerInfo in pairs(scanFuncs) do + if triggerInfo.fetchTooltip then + local md = matchData[unit][filter][key] + md:UpdateTooltip(GetTime()) + end + if not triggerInfo.scanFunc or triggerInfo.scanFunc(time, matchData[unit][filter][key]) then + local id = triggerInfo.id + local triggernum = triggerInfo.triggernum + ReferenceMatchData(id, triggernum, unit, filter, key) + matchDataChanged[id] = matchDataChanged[id] or {} + matchDataChanged[id][triggernum] = true + end + end + end +end + local function UpdateToolTipDataInMatchData(matchData, time) if matchData.tooltipUpdated == time then return @@ -257,15 +287,15 @@ local function UpdateToolTipDataInMatchData(matchData, time) return changed end -local function UpdateMatchData(time, matchDataChanged, unit, index, filter, name, icon, stacks, debuffClass, duration, expirationTime, unitCaster, isStealable, _, spellId) +local function UpdateMatchData(time, matchDataChanged, unit, key, filter, name, icon, stacks, debuffClass, duration, expirationTime, unitCaster, isStealable, _, spellId) if not matchData[unit] then matchData[unit] = {} end if not matchData[unit][filter] then matchData[unit][filter] = {} end - if not matchData[unit][filter][index] then - matchData[unit][filter][index] = { + if not matchData[unit][filter][key] then + matchData[unit][filter][key] = { name = name, icon = icon, stacks = stacks, @@ -281,7 +311,7 @@ local function UpdateMatchData(time, matchDataChanged, unit, index, filter, name time = time, lastChanged = time, filter = filter, - index = index, + index = key, UpdateTooltip = UpdateToolTipDataInMatchData, auras = {} } @@ -289,7 +319,7 @@ local function UpdateMatchData(time, matchDataChanged, unit, index, filter, name return true end - local data = matchData[unit][filter][index] + local data = matchData[unit][filter][key] local changed = false if data.name ~= name then @@ -362,11 +392,11 @@ local function UpdateMatchData(time, matchDataChanged, unit, index, filter, name for id, triggerData in pairs(data.auras) do for triggernum in pairs(triggerData) do if matchDataByTrigger[id] - and matchDataByTrigger[id][triggernum] - and matchDataByTrigger[id][triggernum][unit] - and matchDataByTrigger[id][triggernum][unit][index] + and matchDataByTrigger[id][triggernum] + and matchDataByTrigger[id][triggernum][unit] + and matchDataByTrigger[id][triggernum][unit][key] then - matchDataByTrigger[id][triggernum][unit][index] = nil + matchDataByTrigger[id][triggernum][unit][key] = nil matchDataChanged[id] = matchDataChanged[id] or {} matchDataChanged[id][triggernum] = true end @@ -375,7 +405,7 @@ local function UpdateMatchData(time, matchDataChanged, unit, index, filter, name wipe(data.auras) end - data.index = index + data.index = key data.time = time data.unit = unit @@ -471,18 +501,18 @@ local function FindBestMatchDataForUnit(time, id, triggernum, triggerInfo, unit) end local GetTexCoordsForRole = function(role) - local textureHeight, textureWidth = 256, 256; - local roleHeight, roleWidth = 67, 67; + local textureHeight, textureWidth = 256, 256 + local roleHeight, roleWidth = 67, 67 - if ( role == "GUIDE" ) then - return GetTexCoordsByGrid(1, 1, textureWidth, textureHeight, roleWidth, roleHeight); - elseif ( role == "TANK" ) then - return GetTexCoordsByGrid(1, 2, textureWidth, textureHeight, roleWidth, roleHeight); - elseif ( role == "HEALER" ) then - return GetTexCoordsByGrid(2, 1, textureWidth, textureHeight, roleWidth, roleHeight); - elseif ( role == "DAMAGER" ) then - return GetTexCoordsByGrid(2, 2, textureWidth, textureHeight, roleWidth, roleHeight); - end + if ( role == "GUIDE" ) then + return GetTexCoordsByGrid(1, 1, textureWidth, textureHeight, roleWidth, roleHeight) + elseif ( role == "TANK" ) then + return GetTexCoordsByGrid(1, 2, textureWidth, textureHeight, roleWidth, roleHeight) + elseif ( role == "HEALER" ) then + return GetTexCoordsByGrid(2, 1, textureWidth, textureHeight, roleWidth, roleHeight) + elseif ( role == "DAMAGER" ) then + return GetTexCoordsByGrid(2, 2, textureWidth, textureHeight, roleWidth, roleHeight) + end end local roleIcons = { @@ -1266,7 +1296,7 @@ local function UpdateTriggerState(time, id, triggernum) local cloneId = "" local useMatch = true - if triggerInfo.unitExists ~= nil and not existingUnits[triggerInfo.unit] then + if triggerInfo.unitExists ~= nil and not UnitExistsFixed(triggerInfo.unit) then useMatch = triggerInfo.unitExists else useMatch = SatisfiesGroupMatchCount(triggerInfo, unitCount, maxUnitCount, matchCount) @@ -1322,7 +1352,7 @@ local function UpdateTriggerState(time, id, triggernum) end local useMatches = true - if triggerInfo.unitExists ~= nil and not existingUnits[triggerInfo.unit] then + if triggerInfo.unitExists ~= nil and not UnitExistsFixed(triggerInfo.unit) then useMatches = triggerInfo.unitExists else useMatches = SatisfiesGroupMatchCount(triggerInfo, unitCount, maxUnitCount, matchCount) @@ -1488,14 +1518,7 @@ local function PrepareMatchData(unit, filter) break end - if debuffClass == nil then - debuffClass = "none" - elseif debuffClass == "" then - debuffClass = "enrage" - else - debuffClass = string.lower(debuffClass) - end - + debuffClass = FixDebuffClass(debuffClass) local updatedMatchData = UpdateMatchData(time, matchDataChanged, unit, index, filter, name, icon, stacks, debuffClass, duration, expirationTime, unitCaster, isStealable, _, spellId) index = index + 1 end @@ -1510,7 +1533,7 @@ local function CleanUpOutdatedMatchData(removeIndex, unit, filter) if matchData[unit] and matchData[unit][filter] then for index = removeIndex, #matchData[unit][filter] do local data = matchData[unit][filter][index] - if data.index >= removeIndex or not UnitExistsFixed(unit) then + if (data and data.index >= removeIndex) or not UnitExistsFixed(unit) then matchData[unit][filter][index] = nil for id, triggerData in pairs(data.auras) do for triggernum in pairs(triggerData) do @@ -1563,23 +1586,6 @@ local function DeactivateScanFuncs(toDeactivate) end end -local function CheckScanFuncs(scanFuncs, unit, filter, index) - if scanFuncs then - for triggerInfo in pairs(scanFuncs) do - if triggerInfo.fetchTooltip then - matchData[unit][filter][index]:UpdateTooltip(GetTime()) - end - if not triggerInfo.scanFunc or triggerInfo.scanFunc(time, matchData[unit][filter][index]) then - local id = triggerInfo.id - local triggernum = triggerInfo.triggernum - ReferenceMatchData(id, triggernum, unit, filter, index) - matchDataChanged[id] = matchDataChanged[id] or {} - matchDataChanged[id][triggernum] = true - end - end - end -end - local function ScanUnitWithFilter(matchDataChanged, time, unit, filter, scanFuncNameGroup, scanFuncSpellIdGroup, scanFuncGeneralGroup, scanFuncName, scanFuncSpellId, scanFuncGeneral) @@ -1591,22 +1597,14 @@ local function ScanUnitWithFilter(matchDataChanged, time, unit, filter, return end - local index = 1 - if UnitExistsFixed(unit) then + local index = 1 while true do local name, rank, icon, stacks, debuffClass, duration, expirationTime, unitCaster, isStealable, _, spellId = UnitAura(unit, index, filter) if not name then break end - - if debuffClass == nil then - debuffClass = "none" - elseif debuffClass == "" then - debuffClass = "enrage" - else - debuffClass = string.lower(debuffClass) - end + debuffClass = FixDebuffClass(debuffClass) local updatedMatchData = UpdateMatchData(time, matchDataChanged, unit, index, filter, name, icon, stacks, debuffClass, duration, expirationTime, unitCaster, isStealable, _, spellId) @@ -1620,9 +1618,9 @@ local function ScanUnitWithFilter(matchDataChanged, time, unit, filter, end index = index + 1 end - end - CleanUpOutdatedMatchData(index, unit, filter) + CleanUpOutdatedMatchData(index, unit, filter) + end matchDataUpToDate[unit] = matchDataUpToDate[unit] or {} matchDataUpToDate[unit][filter] = true @@ -1711,23 +1709,26 @@ local function ScanGroupUnit(time, matchDataChanged, unitType, unit) end end -local function ScanUnit(time, arg1) - if not arg1 then return end - if (Private.multiUnitUnits.raid[arg1] and IsInRaid()) then - ScanGroupUnit(time, matchDataChanged, "group", arg1) - elseif (Private.multiUnitUnits.party[arg1] and not IsInRaid()) then - ScanGroupUnit(time, matchDataChanged, "group", arg1) - elseif Private.multiUnitUnits.boss[arg1] then - ScanGroupUnit(time, matchDataChanged, "boss", arg1) - elseif Private.multiUnitUnits.arena[arg1] then - ScanGroupUnit(time, matchDataChanged, "arena", arg1) - elseif arg1:sub(1, 9) == "nameplate" then - ScanGroupUnit(time, matchDataChanged, "nameplate", arg1) +local function UnitToUnitType(unit) + if (Private.multiUnitUnits.raid[unit] and IsInRaid()) then + return "group" + elseif (Private.multiUnitUnits.party[unit] and not IsInRaid()) then + return "group" + elseif Private.multiUnitUnits.boss[unit] then + return "boss", unit + elseif Private.multiUnitUnits.arena[unit] then + return "arena" + elseif unit:sub(1, 9) == "nameplate" then + return "nameplate" else - ScanGroupUnit(time, matchDataChanged, nil, arg1) + return nil end end +local function ScanUnit(time, unit, unitAuraUpdateInfo) + ScanGroupUnit(time, matchDataChanged, UnitToUnitType(unit), unit) +end + local function AddScanFuncs(triggerInfo, filter, unit, scanFuncName, scanFuncSpellId, scanFuncGeneral) if triggerInfo.auranames then for _, name in ipairs(triggerInfo.auranames) do @@ -1843,15 +1844,11 @@ local function EventHandler(frame, event, arg1, arg2, ...) local unitsToRemove = {} local time = GetTime() - if event == "PLAYER_TARGET_CHANGED" then - ScanGroupUnit(time, matchDataChanged, nil, "target") - if not UnitExistsFixed("target") then - tinsert(unitsToRemove, "target") - end - elseif event == "PLAYER_FOCUS_CHANGED" then - ScanGroupUnit(time, matchDataChanged, nil, "focus") - if not UnitExistsFixed("focus") then - tinsert(unitsToRemove, "focus") + local targetUnit = Private.player_target_events[event] + if targetUnit then + ScanGroupUnit(time, matchDataChanged, nil, targetUnit) + if not UnitExistsFixed(targetUnit) then + tinsert(unitsToRemove, targetUnit) end elseif event == "UNIT_PET" then local pet = WeakAuras.unitToPetUnit[arg1] @@ -1893,8 +1890,8 @@ local function EventHandler(frame, event, arg1, arg2, ...) local exists = UnitExistsFixed(unit) if not exists then tinsert(unitsToRemove, unit) - elseif exists ~= existingUnits[unit] then - ScanGroupUnit(time, matchDataChanged, "group", unit) + else + ScanGroupUnit(time, matchDataChanged, "group", unit, nil) end end ScanGroupRoleScanFunc(matchDataChanged) @@ -2477,7 +2474,7 @@ function BuffTrigger.Add(data) triggerInfos[id] = nil for triggernum, triggerData in ipairs(data.triggers) do - local trigger, untrigger = triggerData.trigger, triggerData.untrigger + local trigger = triggerData.trigger if trigger.type == "aura2" then trigger.unit = trigger.unit or "player" @@ -2567,10 +2564,10 @@ function BuffTrigger.Add(data) local effectiveRaidRole = groupTrigger and trigger.useRaidRole and trigger.raid_role or nil local effectiveClass = groupTrigger and trigger.useClass and trigger.class local effectiveSpecId = groupTrigger and trigger.useActualSpec and trigger.actualSpec or nil + local effectiveHostility = (groupTrigger or trigger.unit == "nameplate") and trigger.useHostility and trigger.hostility local effectiveIgnoreDead = groupTrigger and trigger.ignoreDead local effectiveIgnoreDisconnected = groupTrigger and trigger.ignoreDisconnected local effectiveIgnoreInvisible = groupTrigger and trigger.ignoreInvisible - 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" or trigger.unit == "boss") and trigger.useNpcId and Private.ExecEnv.ParseStringCheck(trigger.npcId) @@ -3453,13 +3450,8 @@ local function AugmentMatchDataMulti(matchData, unit, filter, sourceGUID, nameKe return false end - if debuffClass == nil then - debuffClass = "none" - elseif debuffClass == "" then - debuffClass = "enrage" - else - debuffClass = string.lower(debuffClass) - end + debuffClass = FixDebuffClass(debuffClass) + local auraSourceGuid = unitCaster and UnitGUID(unitCaster) if (name == nameKey or spellId == spellKey) and sourceGUID == auraSourceGuid then local changed = AugmentMatchDataMultiWith(matchData, unit, name, icon, stacks, debuffClass, duration, expirationTime, unitCaster, isStealable, _, spellId) @@ -3543,13 +3535,8 @@ local function CheckAurasMulti(base, unit, filter) return false end - if debuffClass == nil then - debuffClass = "none" - elseif debuffClass == "" then - debuffClass = "enrage" - else - debuffClass = string.lower(debuffClass) - end + debuffClass = FixDebuffClass(debuffClass) + local auraCasterGUID = unitCaster and UnitGUID(unitCaster) if base[name] and base[name][auraCasterGUID] then local changed = AugmentMatchDataMultiWith(base[name][auraCasterGUID], unit, name, icon, stacks, debuffClass, duration, expirationTime, unitCaster, isStealable, _, spellId) @@ -3611,10 +3598,8 @@ function BuffTrigger.HandleMultiEvent(frame, event, ...) CombatLog(...) elseif event == "UNIT_TARGET" then TrackUid(...) - elseif event == "PLAYER_TARGET_CHANGED" then - TrackUid("target") - elseif event == "PLAYER_FOCUS_CHANGED" then - TrackUid("focus") + elseif Private.player_target_events[event] then + TrackUid(Private.player_target_events[event]) elseif event == "NAME_PLATE_UNIT_ADDED" then TrackUid(...) elseif event == "NAME_PLATE_UNIT_REMOVED" then diff --git a/WeakAuras/GenericTrigger.lua b/WeakAuras/GenericTrigger.lua index 082c284..973a8b9 100644 --- a/WeakAuras/GenericTrigger.lua +++ b/WeakAuras/GenericTrigger.lua @@ -3690,66 +3690,14 @@ function WeakAuras.RegisterItemCountWatch() end end --- Queued Action -do - local GetActionInfo, GetMacroSpell, GetSpellLink = GetActionInfo, GetMacroSpell, GetSpellLink - - local queuedActionFrame = nil - local buttonIDList = {} - local spellIDList = {} - - local function GetActionSpellID(slot) - local actionType, id, _, spellId = GetActionInfo(slot) - if actionType == "spell" then - return spellId - elseif actionType == "macro" then - local name, rank = GetMacroSpell(id) - if name then - local spellLink = GetSpellLink(name, rank or "") - if spellLink then - return tonumber(spellLink:match("spell:(%d+)")) - end - end - end - end - - function WeakAuras.WatchQueuedAction() - if not(queuedActionFrame) then - queuedActionFrame = CreateFrame("Frame"); - Private.frames["Queued Action Frame"] = queuedActionFrame - for slotID = 1, 120 do - local spellID = GetActionSpellID(slotID) - if spellID then - buttonIDList[slotID] = spellID - spellIDList[spellID] = slotID - end - end - end - queuedActionFrame:RegisterEvent("ACTIONBAR_SLOT_CHANGED") - queuedActionFrame:SetScript("OnEvent", function(_, _, slotID) - Private.StartProfileSystem("generictrigger queued action"); - local spellID = GetActionSpellID(slotID) - if spellID then - buttonIDList[slotID] = spellID - spellIDList[spellID] = slotID - elseif buttonIDList[slotID] then - spellIDList[buttonIDList[slotID]] = nil - buttonIDList[slotID] = nil - end - Private.StopProfileSystem("generictrigger queued action"); - end) - end - - function WeakAuras.FindSpellActionButtons(spellID) - return spellIDList[spellID] - end -end - -- LibSpecWrapper -- We always register, because it's probably not that often called, and ScanEvents checks -- early if anyone wants the event Private.LibGroupTalentsWrapper.Register(function(unit) WeakAuras.ScanEvents("UNIT_SPEC_CHANGED_" .. unit, unit) + if unit == "player" then + Private.ScanForLoads(nil, "UNIT_SPEC_CHANGED_" .. unit) + end end) do diff --git a/WeakAuras/Prototypes.lua b/WeakAuras/Prototypes.lua index c545f10..0e3ab84 100644 --- a/WeakAuras/Prototypes.lua +++ b/WeakAuras/Prototypes.lua @@ -5,21 +5,21 @@ local AddonName, Private = ... local tinsert, tsort = table.insert, table.sort local tostring = tostring local select, pairs, type = select, pairs, type -local ceil, min = ceil, min +local ceil = ceil -- WoW APIs local GetTalentInfo = GetTalentInfo local UnitClass = UnitClass local GetSpellInfo, GetItemInfo, GetItemCount, GetItemIcon = GetSpellInfo, GetItemInfo, GetItemCount, GetItemIcon local GetShapeshiftFormInfo, GetShapeshiftForm = GetShapeshiftFormInfo, GetShapeshiftForm +local GetRuneCooldown, UnitCastingInfo, UnitChannelInfo = GetRuneCooldown, UnitCastingInfo, UnitChannelInfo local UnitDetailedThreatSituation = UnitDetailedThreatSituation +local MAX_NUM_TALENTS = MAX_NUM_TALENTS or 40 local MONEY = MONEY local WeakAuras = WeakAuras local L = WeakAuras.L -local LibGroupTalents = LibStub("LibGroupTalents-1.0") - local SpellRange = LibStub("SpellRange-1.0") function WeakAuras.IsSpellInRange(spellId, unit) return SpellRange.IsSpellInRange(spellId, unit) @@ -87,6 +87,7 @@ end local constants = { nameRealmFilterDesc = L[" Filter formats: 'Name', 'Name-Realm', '-Realm'. \n\nSupports multiple entries, separated by commas\nCan use \\ to escape -."], + instanceFilterDeprecated = L["This filter has been moved to the Location trigger. Change your aura to use the new Location trigger or join the WeakAuras Discord server for help."], } WeakAuras.UnitRaidRole = function(unit) @@ -799,15 +800,7 @@ function Private.ExecEnv.CheckCombatLogFlagsObjectType(flags, flagToCheck) return bit.band(flags, bitToCheck) ~= 0; end -function WeakAuras.GetSpellCritChance() - local spellCrit = GetSpellCritChance(2) - for i = 3, MAX_SPELL_SCHOOLS do - spellCrit = min(spellCrit, GetSpellCritChance(i)) - end - return spellCrit -end - -function WeakAuras.GetSpecString(unit) +function WeakAuras.SpecForUnit(unit) local spec = WeakAuras.LGT:GetUnitTalentSpec(unit) local class = select(2, UnitClass(unit)) return spec and class and (class .. spec) @@ -979,17 +972,6 @@ 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"], @@ -1038,7 +1020,7 @@ Private.load_prototype = { type = "multiselect", values = "spec_types_all", test = "WeakAuras.CheckClassSpec(class, %s)", - events = {"UNIT_SPEC_CHANGED_player"}, + events = {"UNIT_SPEC_CHANGED_player", "WA_DELAYED_PLAYER_ENTERING_WORLD"}, }, { name = "talent", @@ -1050,7 +1032,7 @@ Private.load_prototype = { return WeakAuras.CheckTalentByIndex(talent, arg) ~= nil end, multiConvertKey = nil, - events = {"PLAYER_TALENT_UPDATE", "SPELL_UPDATE_USABLE"}, + events = {"PLAYER_TALENT_UPDATE", "SPELL_UPDATE_USABLE", "WA_DELAYED_PLAYER_ENTERING_WORLD"}, inverse = nil, extraOption = nil, control = "WeakAurasMiniTalent", @@ -1076,7 +1058,7 @@ Private.load_prototype = { return WeakAuras.CheckTalentByIndex(talent, arg) ~= nil end, multiConvertKey = nil, - events = {"PLAYER_TALENT_UPDATE", "SPELL_UPDATE_USABLE"}, + events = {"PLAYER_TALENT_UPDATE", "SPELL_UPDATE_USABLE", "WA_DELAYED_PLAYER_ENTERING_WORLD"}, inverse = nil, extraOption = nil, control = "WeakAurasMiniTalent", @@ -1106,7 +1088,7 @@ Private.load_prototype = { return WeakAuras.CheckTalentByIndex(talent, arg) ~= nil end, multiConvertKey = nil, - events = {"PLAYER_TALENT_UPDATE", "SPELL_UPDATE_USABLE"}, + events = {"PLAYER_TALENT_UPDATE", "SPELL_UPDATE_USABLE", "WA_DELAYED_PLAYER_ENTERING_WORLD"}, inverse = nil, extraOption = nil, control = "WeakAurasMiniTalent", @@ -1603,7 +1585,7 @@ Private.event_prototypes = { name = "unitisunit", display = L["Unit is Unit"], type = "unit", - init = "UnitIsUnit(unit, extraUnit) == 1 and true or false", + init = "UnitIsUnit(unit, extraUnit)", values = function(trigger) if Private.multiUnitUnits[trigger.unit] then return Private.actual_unit_types @@ -1684,7 +1666,7 @@ Private.event_prototypes = { store = true, conditionType = "select", enable = function(trigger) - return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" + return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" or trigger.unit == "player" end }, { @@ -1808,7 +1790,7 @@ Private.event_prototypes = { name = "attackable", display = L["Attackable"], type = "tristate", - init = "UnitCanAttack('player', unit) == 1 and true or false", + init = "UnitCanAttack('player', unit)", store = true, conditionType = "bool" }, @@ -1816,7 +1798,7 @@ Private.event_prototypes = { name = "inCombat", display = L["In Combat"], type = "tristate", - init = "UnitAffectingCombat(unit) == 1 and true or false", + init = "UnitAffectingCombat(unit)", store = true, conditionType = "bool" }, @@ -1824,7 +1806,7 @@ Private.event_prototypes = { name = "afk", display = L["Afk"], type = "tristate", - init = "UnitIsAFK(unit) == 1 and true or false", + init = "UnitIsAFK(unit)", store = true, conditionType = "bool" }, @@ -1832,7 +1814,7 @@ Private.event_prototypes = { name = "dnd", display = L["Do Not Disturb"], type = "tristate", - init = "UnitIsDND(unit) == 1 and true or false", + init = "UnitIsDND(unit)", store = true, conditionType = "bool" }, @@ -2170,7 +2152,7 @@ Private.event_prototypes = { end, operator_types = "none", desc = L["Supports multiple entries, separated by commas. Prefix with '-' for negation."] - }, + }, { name = "class", display = L["Class"], @@ -2184,7 +2166,7 @@ Private.event_prototypes = { name = "specId", display = L["Specialization"], type = "multiselect", - init = "WeakAuras.GetSpecString(unit)", + init = "WeakAuras.SpecForUnit(unit)", values = "spec_types_all", store = true, conditionType = "select", @@ -2202,7 +2184,7 @@ Private.event_prototypes = { store = true, conditionType = "select", enable = function(trigger) - return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" + return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" or trigger.unit == "player" end }, { @@ -2605,7 +2587,7 @@ Private.event_prototypes = { name = "specId", display = L["Specialization"], type = "multiselect", - init = "WeakAuras.GetSpecString(unit)", + init = "WeakAuras.SpecForUnit(unit)", values = "spec_types_all", store = true, conditionType = "select", @@ -2623,7 +2605,7 @@ Private.event_prototypes = { store = true, conditionType = "select", enable = function(trigger) - return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" + return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" or trigger.unit == "player" end }, { @@ -2707,7 +2689,6 @@ Private.event_prototypes = { { name = "inRange", display = L["In Range"], - desc = L["Uses UnitInRange() to check if in range. Matches default raid frames out of range behavior, which is between 25 to 40 yards depending on your class and spec."], type = "toggle", width = WeakAuras.doubleWidth, enable = function(trigger) @@ -4462,6 +4443,7 @@ Private.event_prototypes = { text = function() return L["Note: Due to how complicated the swing timer behavior is and the lack of APIs from Blizzard, results are inaccurate in edge cases."] end, + }, { name = "hand", @@ -4738,6 +4720,7 @@ Private.event_prototypes = { events = { ["events"] = {"PLAYER_TALENT_UPDATE", "SPELL_UPDATE_USABLE"} }, + internal_events = {"WA_DELAYED_PLAYER_ENTERING_WORLD"}, force_events = "PLAYER_TALENT_UPDATE", name = L["Talent Known"], init = function(trigger) @@ -4841,7 +4824,8 @@ Private.event_prototypes = { ["Class/Spec"] = { type = "unit", events = {}, - internal_events = { "UNIT_SPEC_CHANGED_player" }, + internal_events = {"WA_DELAYED_PLAYER_ENTERING_WORLD"}, + force_events = "UNIT_SPEC_CHANGED_player", name = L["Class and Specialization"], init = function(trigger) local class = select(2, UnitClass("player")) or "UNKNOWN" @@ -6638,7 +6622,7 @@ Private.event_prototypes = { conditionType = "select", enable = function(trigger) return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" - and not trigger.use_inverse + or trigger.unit == "player" and not trigger.use_inverse end }, { @@ -7528,6 +7512,7 @@ Private.event_prototypes = { { name = "instance_size", display = L["Instance Type"].." "..L["|cffff0000deprecated|r"], + desc = constants.instanceFilterDeprecated, type = "multiselect", values = "instance_types", sorted = true, @@ -7537,6 +7522,7 @@ Private.event_prototypes = { { name = "instance_difficulty", display = L["Instance Difficulty"].." "..L["|cffff0000deprecated|r"], + desc = constants.instanceFilterDeprecated, type = "multiselect", values = "difficulty_types", init = "WeakAuras.InstanceDifficulty()" @@ -7718,15 +7704,18 @@ Private.event_prototypes = { "ACTIONBAR_PAGE_CHANGED" }, name = L["Queued Action"], - loadFunc = function() - WeakAuras.WatchQueuedAction() - end, init = function(trigger) trigger.spellName = trigger.spellName or 0 + local spellName + if trigger.use_exact_spellName then + spellName = trigger.spellName + else + spellName = type(trigger.spellName) == "number" and GetSpellInfo(trigger.spellName) or trigger.spellName + end local ret = [=[ - local button = WeakAuras.FindSpellActionButtons(%d) + local spellname = %q ]=] - return ret:format(trigger.spellName) + return ret:format(spellName) end, args = { { @@ -7735,11 +7724,11 @@ Private.event_prototypes = { display = L["Spell"], type = "spell", test = "true", - forceExactOption = true, + showExactOption = true, }, { hidden = true, - test = "button and IsCurrentAction(button)"; + test = "spellname and IsCurrentSpell(spellname)"; }, }, iconFunc = function(trigger) diff --git a/WeakAuras/RegionTypes/DynamicGroup.lua b/WeakAuras/RegionTypes/DynamicGroup.lua index 93380f3..aa184a5 100644 --- a/WeakAuras/RegionTypes/DynamicGroup.lua +++ b/WeakAuras/RegionTypes/DynamicGroup.lua @@ -97,7 +97,7 @@ end local function releaseControlPoint(self, controlPoint) controlPoint:Hide() - controlPoint:ClearAnchorPoint() + controlPoint:SetAnchorPoint(self.parent.selfPoint) local regionData = controlPoint.regionData if regionData then if self.parent.anchorPerUnit == "UNITFRAME" then @@ -1391,9 +1391,11 @@ local function modify(parent, region, data) end if parent and parent.IsObjectType and parent:IsObjectType("Frame") then controlPoint:SetParent(parent) + controlPoint:SetScale(data.scale and data.scale > 0 and data.scale <= 10 and data.scale or 1) end else controlPoint:SetParent(self) + controlPoint:SetScale(1) end local childData = controlPoint.regionData.data @@ -1536,7 +1538,7 @@ local function modify(parent, region, data) -- if self.dynamicAnchor then self:UpdateBorder(); return end Private.StartProfileSystem("dynamicgroup") Private.StartProfileAura(data.id) - local numVisible, minX, maxX, maxY, minY = 0 + local numVisible, minX, maxX, maxY, minY = 0, nil, nil, nil, nil for active, regionData in ipairs(self.sortedChildren) do if regionData.shown then numVisible = numVisible + 1 diff --git a/WeakAuras/RegionTypes/Group.lua b/WeakAuras/RegionTypes/Group.lua index ae79799..dd5550a 100644 --- a/WeakAuras/RegionTypes/Group.lua +++ b/WeakAuras/RegionTypes/Group.lua @@ -99,22 +99,28 @@ local function modify(parent, region, data) -- Scale region:SetScale(data.scale and data.scale > 0 and data.scale <= 10 and data.scale or 1) - -- Get overall bounding box - local leftest, rightest, lowest, highest = 0, 0, 0, 0; - for child in Private.TraverseLeafs(data) do - local childRegion = WeakAuras.GetRegion(child.id) - if(child) then - local blx, bly, trx, try = getRect(child, childRegion); - leftest = math.min(leftest, blx); - rightest = math.max(rightest, trx); - lowest = math.min(lowest, bly); - highest = math.max(highest, try); + region.GetBoundingRect = function(self) + if not self.boundingRect then + local leftest, rightest, lowest, highest = 0, 0, 0, 0; + for child in Private.TraverseLeafs(data) do + local childRegion = WeakAuras.GetRegion(child.id) + if(child) then + local blx, bly, trx, try = getRect(child, childRegion); + leftest = math.min(leftest, blx); + rightest = math.max(rightest, trx); + lowest = math.min(lowest, bly); + highest = math.max(highest, try); + end + end + self.blx = leftest + self.bly = lowest + self.trx = rightest + self.try = highest + self.boundingRect = true end + return self.blx, self.bly, self.trx, self.try end - region.blx = leftest; - region.bly = lowest; - region.trx = rightest; - region.try = highest; + region.boundingRect = false -- Adjust frame-level sorting Private.FixGroupChildrenOrderForGroup(data); @@ -150,6 +156,8 @@ local function modify(parent, region, data) -- Show border if child is visible if childVisible then + local blx, bly, trx, try = self:GetBoundingRect() + border:SetBackdrop({ edgeFile = data.borderEdge ~= "None" and SharedMedia:Fetch("border", data.borderEdge) or "", edgeSize = data.borderSize, @@ -165,8 +173,8 @@ local function modify(parent, region, data) border:SetBackdropColor(data.backdropColor[1], data.backdropColor[2], data.backdropColor[3], data.backdropColor[4]); border:ClearAllPoints(); - border:SetPoint("bottomleft", region, "bottomleft", leftest-data.borderOffset, lowest-data.borderOffset); - border:SetPoint("topright", region, "topright", rightest+data.borderOffset, highest+data.borderOffset); + border:SetPoint("bottomleft", region, "bottomleft", blx - data.borderOffset, bly - data.borderOffset); + border:SetPoint("topright", region, "topright", trx + data.borderOffset, try + data.borderOffset); border:Show(); else border:Hide(); diff --git a/WeakAuras/RegionTypes/Model.lua b/WeakAuras/RegionTypes/Model.lua index 3bd9c55..8fd5c49 100644 --- a/WeakAuras/RegionTypes/Model.lua +++ b/WeakAuras/RegionTypes/Model.lua @@ -33,6 +33,8 @@ local default = { borderBackdrop = "Blizzard Tooltip" }; +Private.regionPrototype.AddAlphaToDefault(default) + local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20; local properties = { @@ -63,7 +65,13 @@ local function GetProperties(data) end local regionFunctions = { - Update = function() end + Update = function() end, + SetAlpha = function(self, alpha) + self.alpha = alpha + if self.model then + self.model:SetAlpha(alpha) + end + end } -- Called when first creating a new region/display @@ -161,6 +169,7 @@ local function AcquireModel(region, data) end local function ReleaseModel(model) + model:SetAlpha(1) --model:SetKeepModelOnHide(false) model:Hide() model:UnregisterEvent("UNIT_MODEL_CHANGED"); @@ -272,6 +281,9 @@ local function modify(parent, region, data) else ConfigureModel(region, region.model, data) end + if type(data.alpha) == "number" then + region:SetAlpha(data.alpha) + end end function region:PreHide() diff --git a/WeakAuras/RegionTypes/RegionPrototype.lua b/WeakAuras/RegionTypes/RegionPrototype.lua index f0240d0..65c215b 100644 --- a/WeakAuras/RegionTypes/RegionPrototype.lua +++ b/WeakAuras/RegionTypes/RegionPrototype.lua @@ -703,7 +703,7 @@ function Private.regionPrototype.create(region) region.RunCode = RunCode; region.GlowExternal = GlowExternal; - --region.ReAnchor = UpdatePosition; https://github.com/WeakAuras/WeakAuras2/commit/7859d5e + region.ReAnchor = UpdatePosition; region.SetAnchor = SetAnchor; region.SetOffset = SetOffset; region.SetXOffset = SetXOffset; diff --git a/WeakAuras/Types.lua b/WeakAuras/Types.lua index c1b0dfe..cde4357 100644 --- a/WeakAuras/Types.lua +++ b/WeakAuras/Types.lua @@ -972,6 +972,11 @@ Private.debuff_class_types = { none = L["None"] } +Private.player_target_events = { + PLAYER_TARGET_CHANGED = "target", + PLAYER_FOCUS_CHANGED = "focus", +} + Private.unit_types = { player = L["Player"], target = L["Target"], diff --git a/WeakAuras/WeakAuras.lua b/WeakAuras/WeakAuras.lua index 979a13e..ed8bdb6 100644 --- a/WeakAuras/WeakAuras.lua +++ b/WeakAuras/WeakAuras.lua @@ -1,6 +1,6 @@ local AddonName, Private = ... -local internalVersion = 82 +local internalVersion = 83 -- Lua APIs local insert = table.insert @@ -2935,8 +2935,9 @@ function Private.SetRegion(data, cloneId) local parent = WeakAurasFrame; if(data.parent) then - if WeakAuras.GetData(data.parent) then - parent = Private.EnsureRegion(data.parent) + local parentRegion = WeakAuras.GetRegion(data.parent) + if parentRegion then + parent = parentRegion else data.parent = nil; end @@ -2998,6 +2999,10 @@ local function EnsureRegion(id) local data = WeakAuras.GetData(id) tinsert(aurasToCreate, data.id) id = data.parent + + if WeakAuras.GetRegion(id) then + break + end end for _, toCreateId in ipairs_reverse(aurasToCreate) do @@ -3282,7 +3287,6 @@ function Private.HandleGlowAction(actions, region) glow_frame = WeakAuras.GetUnitFrame(region.state.unit) should_glow_frame = true elseif actions.glow_frame_type == "NAMEPLATE" and region.state.unit then - if not(WeakAuras.isAwesomeEnabled()) then return end glow_frame = WeakAuras.GetNamePlateForUnit(region.state.unit) should_glow_frame = true elseif actions.glow_frame_type == "PARENTFRAME" then diff --git a/WeakAurasOptions/LoadOptions.lua b/WeakAurasOptions/LoadOptions.lua index 08f4046..b147170 100644 --- a/WeakAurasOptions/LoadOptions.lua +++ b/WeakAurasOptions/LoadOptions.lua @@ -648,7 +648,15 @@ function OptionsPrivate.ConstructOptions(prototype, data, startorder, triggernum local icon = spellCache.GetIcon(value); return icon and tostring(icon) or "", 18, 18; elseif(arg.type == "spell") then - local _, _, icon = GetSpellInfo(value); + local spellName, _, icon = GetSpellInfo(value); + if arg.noValidation then + -- GetSpellInfo and other wow apis are case insensitive, but the later matching we do + -- isn't. For validted inputs, we automatically correct the casing via GetSpellName + -- Since we don't do that for noValidation, we are extra picky on the input + if type(value) == "string" and spellName ~= value then + return "", 18, 18 + end + end return icon and tostring(icon) or "", 18, 18; elseif(arg.type == "item") then local _, _, _, _, _, _, _, _, _, icon = GetItemInfo(value); diff --git a/WeakAurasOptions/OptionsFrames/MoverSizer.lua b/WeakAurasOptions/OptionsFrames/MoverSizer.lua index 26efe73..06d4c5c 100644 --- a/WeakAurasOptions/OptionsFrames/MoverSizer.lua +++ b/WeakAurasOptions/OptionsFrames/MoverSizer.lua @@ -516,8 +516,9 @@ local function ConstructMoverSizer(parent) mover:ClearAllPoints() frame:ClearAllPoints() if data.regionType == "group" then - mover:SetWidth((region.trx - region.blx) * scale) - mover:SetHeight((region.try - region.bly) * scale) + local blx, bly, trx, try = region:GetBoundingRect() + mover:SetWidth((trx - blx) * scale) + mover:SetHeight((try - bly) * scale) mover:SetPoint("BOTTOMLEFT", mover.anchor or UIParent, mover.anchorPoint or "CENTER", (xOff + region.blx) * scale, (yOff + region.bly) * scale) else mover:SetWidth(region:GetWidth() * scale) diff --git a/WeakAurasOptions/RegionOptions/Model.lua b/WeakAurasOptions/RegionOptions/Model.lua index 49c2574..4ad95ff 100644 --- a/WeakAurasOptions/RegionOptions/Model.lua +++ b/WeakAurasOptions/RegionOptions/Model.lua @@ -103,6 +103,17 @@ local function createOptions(id, data) bigStep = 3, order = 45, }, + alpha = { + type = "range", + control = "WeakAurasSpinBox", + width = WeakAuras.normalWidth, + name = L["Alpha"], + order = 50, + min = 0, + max = 1, + bigStep = 0.01, + isPercent = true + }, endHeader = { type = "header", order = 100,