From 909f61f102bb8779d9d17e0f3ddbd988d56e2ac6 Mon Sep 17 00:00:00 2001 From: NoM0Re <1629787+NoM0Re@users.noreply.github.com> Date: Sat, 29 Jun 2024 18:33:34 +0200 Subject: [PATCH] add nameplate trigger/anchor with awesome wotlk --- WeakAuras/AuraEnvironment.lua | 5 + WeakAuras/BuffTrigger2.lua | 62 +++++++++-- WeakAuras/Conditions.lua | 16 +++ WeakAuras/GenericTrigger.lua | 102 +++++++++++++++++- .../Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua | 41 +++++++ WeakAuras/Prototypes.lua | 40 ++++++- WeakAuras/RegionTypes/DynamicGroup.lua | 24 ++++- WeakAuras/RegionTypes/RegionPrototype.lua | 2 + WeakAuras/Types.lua | 12 ++- WeakAuras/WeakAuras.lua | 29 ++++- WeakAurasOptions/ActionOptions.lua | 10 +- WeakAurasOptions/BuffTrigger2.lua | 54 +++++++++- WeakAurasOptions/ConditionOptions.lua | 1 + .../RegionOptions/DynamicGroup.lua | 3 +- 14 files changed, 379 insertions(+), 22 deletions(-) diff --git a/WeakAuras/AuraEnvironment.lua b/WeakAuras/AuraEnvironment.lua index 292498e..1fb295b 100644 --- a/WeakAuras/AuraEnvironment.lua +++ b/WeakAuras/AuraEnvironment.lua @@ -115,6 +115,11 @@ WeakAuras.HideOverlayGlow = LCG.ButtonGlow_Stop local LGF = LibStub("LibGetFrame-1.0") WeakAuras.GetUnitFrame = LGF.GetUnitFrame +WeakAuras.GetUnitNameplate = function(unit) + if (Private.multiUnitUnits.nameplate[unit] and UnitName(unit) ~= WeakAuras.me) 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 8865b81..0c70e80 100644 --- a/WeakAuras/BuffTrigger2.lua +++ b/WeakAuras/BuffTrigger2.lua @@ -103,8 +103,25 @@ local matchDataByTrigger = {} local matchDataChanged = {} +local nameplateExists = {} +local unitVisible = {} + +-- Returns whether a unit id exists. If it exists, the GUID is returned +-- Otherwise false +-- Work around a issue where UnitExists returns true for nameplates even +-- if the nameplate doesn't exist anymore local function UnitExistsFixed(unit) - return UnitExists(unit) or UnitGUID(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 +end + +local function UnitIsVisibleFixed(unit) + if unitVisible[unit] == nil then + unitVisible[unit] = UnitIsVisible(unit) + end + return unitVisible[unit] end local function UnitInSubgroupOrPlayer(unit, includePets) @@ -140,7 +157,7 @@ end local function IsGroupTrigger(trigger) return trigger.unit == "group" or trigger.unit == "party" or trigger.unit == "raid" - or trigger.unit == "boss" or trigger.unit == "arena" or trigger.unit == "multi" + or trigger.unit == "boss" or trigger.unit == "nameplate" or trigger.unit == "arena" or trigger.unit == "multi" end local function IsSingleMissing(trigger) @@ -944,13 +961,15 @@ local function GetAllUnits(unit, allUnits, includePets) i = 0 end end - elseif unit == "boss" or unit == "arena" then + elseif unit == "boss" or unit == "arena" or unit == "nameplate" then local i = 1 local max if unit == "boss" then max = MAX_BOSS_FRAMES elseif unit == "arena" then max = 5 + elseif unit == "nameplate" then + max = 40 else return function() end end @@ -1009,7 +1028,7 @@ local function TriggerInfoApplies(triggerInfo, unit) return false end - if triggerInfo.ignoreInvisible and not UnitIsVisible(unit) then + if triggerInfo.ignoreInvisible and not UnitIsVisibleFixed(unit) then return false end @@ -1561,6 +1580,8 @@ local function ScanUnit(time, arg1) 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) else ScanGroupUnit(time, matchDataChanged, nil, arg1) end @@ -1700,6 +1721,17 @@ local function EventHandler(frame, event, arg1, arg2, ...) tinsert(unitsToRemove, pet) end end + elseif event == "NAME_PLATE_UNIT_ADDED" then + nameplateExists[arg1] = UnitGUID(arg1) + RecheckActiveForUnitType("nameplate", arg1, deactivatedTriggerInfos) + elseif event == "NAME_PLATE_UNIT_REMOVED" then + nameplateExists[arg1] = false + RecheckActiveForUnitType("nameplate", arg1, deactivatedTriggerInfos) + tinsert(unitsToRemove, arg1) + elseif event == "UNIT_FACTION" then + if arg1:sub(1, 9) == "nameplate" then + RecheckActiveForUnitType("nameplate", arg1, deactivatedTriggerInfos) + end elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then for unit in GetAllUnits("boss", true) do RecheckActiveForUnitType("boss", unit, deactivatedTriggerInfos) @@ -1754,6 +1786,7 @@ local function EventHandler(frame, event, arg1, arg2, ...) end frame:RegisterEvent("UNIT_AURA") +frame:RegisterEvent("UNIT_FACTION") frame:RegisterEvent("UNIT_NAME_UPDATE") frame:RegisterEvent("UNIT_FLAGS") frame:RegisterEvent("PLAYER_FLAGS_CHANGED") @@ -1767,6 +1800,8 @@ frame:RegisterEvent("PLAYER_TARGET_CHANGED") frame:RegisterEvent("PARTY_MEMBERS_CHANGED") frame:RegisterEvent("RAID_ROSTER_UPDATE") frame:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT") +frame:RegisterEvent("NAME_PLATE_UNIT_ADDED") +frame:RegisterEvent("NAME_PLATE_UNIT_REMOVED") frame:RegisterEvent("PLAYER_ENTERING_WORLD") frame:SetScript("OnEvent", EventHandler) @@ -2331,12 +2366,14 @@ function BuffTrigger.Add(data) end local groupTrigger = trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" - local effectiveIgnoreSelf = groupTrigger and trigger.ignoreSelf + local effectiveIgnoreSelf = (groupTrigger or trigger.unit == "nameplate") and trigger.ignoreSelf local effectiveClass = groupTrigger and trigger.useClass and trigger.class 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 effectiveNameCheck = groupTrigger and trigger.useUnitName and trigger.unitName + local effectiveNpcId = trigger.unit == "nameplate" and trigger.useNpcId and Private.ExecEnv.ParseStringCheck(trigger.npcId) if trigger.unit == "multi" then BuffTrigger.InitMultiAura() @@ -2394,12 +2431,14 @@ function BuffTrigger.Add(data) groupSubType = groupSubType, groupCountFunc = groupCountFunc, class = effectiveClass, + hostility = effectiveHostility, matchCountFunc = matchCountFunc, matchPerUnitCountFunc = matchPerUnitCountFunc, useAffected = unit == "group" and trigger.useAffected, isMulti = trigger.unit == "multi", nameChecker = effectiveNameCheck and WeakAuras.ParseNameCheck(trigger.unitName), - includePets = trigger.use_includePets and trigger.includePets + includePets = trigger.use_includePets and trigger.includePets, + npcId = effectiveNpcId } triggerInfos[id] = triggerInfos[id] or {} triggerInfos[id][triggernum] = triggerInformation @@ -3233,7 +3272,9 @@ function BuffTrigger.InitMultiAura() multiAuraFrame:RegisterEvent("UNIT_TARGET") multiAuraFrame:RegisterEvent("UNIT_AURA") multiAuraFrame:RegisterEvent("PLAYER_TARGET_CHANGED") - multiAuraFrame:RegisterEvent("PLAYER_FOCUS_CHANGED") + multiAuraFrame:RegisterEvent("PLAYER_FOCUS_CHANGED") + multiAuraFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED") + multiAuraFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED") multiAuraFrame:RegisterEvent("PLAYER_LEAVING_WORLD") multiAuraFrame:SetScript("OnEvent", BuffTrigger.HandleMultiEvent) WeakAuras.frames["Multi-target 2 Aura Trigger Handler"] = multiAuraFrame @@ -3250,6 +3291,13 @@ function BuffTrigger.HandleMultiEvent(frame, event, ...) TrackUid("target") elseif event == "PLAYER_FOCUS_CHANGED" then TrackUid("focus") + elseif event == "NAME_PLATE_UNIT_ADDED" then + TrackUid(...) + elseif event == "NAME_PLATE_UNIT_REMOVED" then + local unit = ... + ReleaseUID(unit) + unit = unit.."target" + ReleaseUID(unit) elseif event == "UNIT_AURA" then local unit = ... if not unit then return end diff --git a/WeakAuras/Conditions.lua b/WeakAuras/Conditions.lua index 1001ead..e456fb7 100644 --- a/WeakAuras/Conditions.lua +++ b/WeakAuras/Conditions.lua @@ -276,6 +276,22 @@ local function CreateTestForCondition(uid, input, allConditionsTemplate, usedSta end ]] fn = fn:format(input.op_range, input.range, op, value) + elseif input.type == "enemies" then + fn = [[ + return function() + local found = 0 + local op = %q + local range = %s + for i = 1, 40 do + local unit = "nameplate" .. i + if UnitExists(unit) and UnitCanAttack("player", unit) and WeakAuras.CheckRange(unit, range, op) then + found = found + 1 + end + end + return found %s %d + end + ]] + fn = fn:format(input.op_range, input.range, op, value) end if fn then local customCheck = WeakAuras.LoadFunction(fn, Private.UIDtoID(uid), "conditions range check") diff --git a/WeakAuras/GenericTrigger.lua b/WeakAuras/GenericTrigger.lua index 835649e..c0bf7b2 100644 --- a/WeakAuras/GenericTrigger.lua +++ b/WeakAuras/GenericTrigger.lua @@ -79,13 +79,21 @@ local timers = WeakAuras.timers; local LoadEvent, HandleEvent, HandleUnitEvent, TestForTriState, TestForToggle, TestForLongString, TestForMultiSelect local ConstructTest, ConstructFunction +local nameplateExists = {} + +---@param unit UnitToken +---@param smart? boolean +---@return boolean unitExists function WeakAuras.UnitExistsFixed(unit, smart) + if #unit > 9 and unit:sub(1, 9) == "nameplate" then + return nameplateExists[unit] + end if smart and IsInRaid() then - if unit:sub(1, 5) == "party" or unit == "player" then + if unit:sub(1, 5) == "party" or unit == "player" or unit == "pet" then return false end end - return UnitExists(unit) == 1 and true or false + return UnitExists(unit) or UnitGUID(unit) end function WeakAuras.split(input) @@ -860,6 +868,12 @@ end function HandleEvent(frame, event, arg1, arg2, ...) Private.StartProfileSystem("generictrigger " .. event); + if event == "NAME_PLATE_UNIT_ADDED" then + nameplateExists[arg1] = true + elseif event == "NAME_PLATE_UNIT_REMOVED" then + nameplateExists[arg1] = false + end + if not(WeakAuras.IsPaused()) then if(event == "COMBAT_LOG_EVENT_UNFILTERED") then WeakAuras.ScanEvents(event, arg1, arg2, ...); @@ -933,7 +947,11 @@ local frame = CreateFrame("FRAME"); frame.unitFrames = {}; WeakAuras.frames["WeakAuras Generic Trigger Frame"] = frame; frame:RegisterEvent("PLAYER_ENTERING_WORLD"); +frame:RegisterEvent("NAME_PLATE_UNIT_ADDED") +frame:RegisterEvent("NAME_PLATE_UNIT_REMOVED") genericTriggerRegisteredEvents["PLAYER_ENTERING_WORLD"] = true; +genericTriggerRegisteredEvents["NAME_PLATE_UNIT_ADDED"] = true; +genericTriggerRegisteredEvents["NAME_PLATE_UNIT_REMOVED"] = true; frame:SetScript("OnEvent", HandleEvent); function GenericTrigger.Delete(id) @@ -976,6 +994,10 @@ local function MultiUnitLoop(Func, unit, includePets, ...) for i = 1, 5 do Func(unit..i, ...) end + elseif unit == "nameplate" then + for i = 1, 40 do + Func(unit..i, ...) + end elseif unit == "group" then if includePets ~= "PetsOnly" then Func("player", ...) @@ -2426,7 +2448,9 @@ end local watchUnitChange -- Nameplates only distinguish between friends and everyone else -function WeakAuras.GetPlayerReaction(unit) +---@param unit UnitToken +---@return string? reaction + function WeakAuras.GetPlayerReaction(unit) local r = UnitReaction("player", unit) if r then return r < 5 and "hostile" or "friendly" @@ -2436,10 +2460,11 @@ end function WeakAuras.WatchUnitChange(unit) unit = string.lower(unit) if not watchUnitChange then - watchUnitChange = CreateFrame("FRAME"); + watchUnitChange = CreateFrame("Frame"); watchUnitChange.unitChangeGUIDS = {} watchUnitChange.unitRoles = {} watchUnitChange.inRaid = IsInRaid() + watchUnitChange.nameplateFaction = {} watchUnitChange.raidmark = {} WeakAuras.frames["Unit Change Frame"] = watchUnitChange; @@ -2449,6 +2474,9 @@ function WeakAuras.WatchUnitChange(unit) watchUnitChange:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT"); watchUnitChange:RegisterEvent("PARTY_MEMBERS_CHANGED"); watchUnitChange:RegisterEvent("RAID_ROSTER_UPDATE"); + watchUnitChange:RegisterEvent("NAME_PLATE_UNIT_ADDED") + watchUnitChange:RegisterEvent("NAME_PLATE_UNIT_REMOVED") + watchUnitChange:RegisterEvent("UNIT_FACTION") watchUnitChange:RegisterEvent("PLAYER_ENTERING_WORLD") watchUnitChange:RegisterEvent("UNIT_PET") watchUnitChange:RegisterEvent("RAID_TARGET_UPDATE") @@ -2468,6 +2496,21 @@ function WeakAuras.WatchUnitChange(unit) WeakAuras.ScanEvents("UNIT_CHANGED_" .. unit, unit) end end + elseif event == "NAME_PLATE_UNIT_ADDED" then + watchUnitChange.raidmark[unit] = GetRaidTargetIndex(unit) or 0 + watchUnitChange.nameplateFaction[unit] = WeakAuras.GetPlayerReaction(unit) + WeakAuras.ScanEvents(event, unit) + elseif event == "NAME_PLATE_UNIT_REMOVED" then + watchUnitChange.raidmark[unit] = nil + watchUnitChange.nameplateFaction[unit] = nil + WeakAuras.ScanEvents(event, unit) + elseif event == "UNIT_FACTION" then + local oldReaction = watchUnitChange.nameplateFaction[unit] + local newReaction = WeakAuras.GetPlayerReaction(unit) + if oldReaction ~= newReaction then + watchUnitChange.nameplateFaction[unit] = newReaction + WeakAuras.ScanEvents("UNIT_CHANGED_" .. unit, unit) + end else local inRaid = IsInRaid() local inRaidChanged = inRaid ~= watchUnitChange.inRaid @@ -2482,6 +2525,14 @@ function WeakAuras.WatchUnitChange(unit) WeakAuras.ScanEvents("UNIT_CHANGED_" .. unit, unit) watchUnitChange.unitChangeGUIDS[unit] = newGuid watchUnitChange.raidmark[unit] = newMarker + + local oldReaction = watchUnitChange.nameplateFaction[unit] + local newReaction = WeakAuras.GetPlayerReaction(unit) + if oldReaction ~= newReaction then + watchUnitChange.nameplateFaction[unit] = newReaction + WeakAuras.ScanEvents("UNIT_CHANGED_" .. unit, unit) + end + elseif Private.multiUnitUnits.group[unit] then -- If in raid changed we send a UNIT_CHANGED for the group units if inRaidChanged then @@ -3106,6 +3157,49 @@ do end end +-- Nameplate Target +do + local nameplateTargetFrame = nil + local nameplateTargets = {} + + local function nameplateTargetOnEvent(self, event, unit) + if event == "NAME_PLATE_UNIT_ADDED" then + nameplateTargets[unit] = UnitGUID(unit.."-target") or true + elseif event == "NAME_PLATE_UNIT_REMOVED" then + nameplateTargets[unit] = nil + end + end + + local tick_throttle = 0.2 + local throttle_update = tick_throttle + local function nameplateTargetOnUpdate(self, delta) + throttle_update = throttle_update - delta + if throttle_update < 0 then + for unit, targetGUID in pairs(nameplateTargets) do + local newTargetGUID = UnitGUID(unit.."-target") + if (newTargetGUID == nil and targetGUID ~= true) + or (newTargetGUID ~= nil and targetGUID ~= newTargetGUID) + then + nameplateTargets[unit] = newTargetGUID or true + WeakAuras.ScanEvents("WA_UNIT_TARGET_NAME_PLATE", unit) + end + end + throttle_update = tick_throttle + end + end + + WeakAuras.frames["Nameplate Target Handler"] = nameplateTargetFrame + function WeakAuras.WatchForNameplateTargetChange() + if not nameplateTargetFrame then + nameplateTargetFrame = CreateFrame("Frame") + nameplateTargetFrame:SetScript("OnUpdate", nameplateTargetOnUpdate) + nameplateTargetFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED") + nameplateTargetFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED") + nameplateTargetFrame:SetScript("OnEvent", nameplateTargetOnEvent) + end + end +end + -- Mounted Frame do local mountedFrame diff --git a/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua b/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua index 9c2afaf..f37e550 100644 --- a/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua +++ b/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua @@ -299,3 +299,44 @@ function lib.GetUnitFrame(target, opt) end end lib.GetFrame = lib.GetUnitFrame -- compatibility + +-- nameplates +function lib.GetUnitNameplate(unit) + if not unit then + return + end + local nameplate = C_NamePlate.GetNamePlateForUnit(unit) + if nameplate then + -- credit to Exality for https://wago.io/explosiveorbs + if nameplate.unitFrame and nameplate.unitFrame.Health then + -- elvui + return nameplate.unitFrame.Health + elseif nameplate.unitFramePlater and nameplate.unitFramePlater.healthBar then + -- plater + return nameplate.unitFramePlater.healthBar + elseif nameplate.kui and nameplate.kui.HealthBar then + -- kui + return nameplate.kui.HealthBar + elseif nameplate.extended and nameplate.extended.visual and nameplate.extended.visual.healthbar then + -- tidyplates + return nameplate.extended.visual.healthbar + elseif nameplate.TPFrame and nameplate.TPFrame.visual and nameplate.TPFrame.visual.healthbar then + -- tidyplates: threat plates + return nameplate.TPFrame.visual.healthbar + elseif nameplate.unitFrame and nameplate.unitFrame.Health then + -- bdui nameplates + return nameplate.unitFrame.Health + elseif nameplate.ouf and nameplate.ouf.Health then + -- bdNameplates + return nameplate.ouf.Health + elseif nameplate.slab and nameplate.slab.components and nameplate.slab.components.healthBar and nameplate.slab.components.healthBar.frame then + -- Slab + return nameplate.slab.components.healthBar.frame + elseif nameplate.UnitFrame and nameplate.UnitFrame.healthBar then + -- default + return nameplate.UnitFrame.healthBar + else + return nameplate + end + end +end diff --git a/WeakAuras/Prototypes.lua b/WeakAuras/Prototypes.lua index 784b1fc..0fb1549 100644 --- a/WeakAuras/Prototypes.lua +++ b/WeakAuras/Prototypes.lua @@ -1250,7 +1250,7 @@ Private.event_prototypes = { type = "toggle", width = WeakAuras.doubleWidth, enable = function(trigger) - return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" + return trigger.unit == "nameplate" or trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" end, init = "not UnitIsUnit(\"player\", unit)" }, @@ -1633,7 +1633,7 @@ Private.event_prototypes = { type = "toggle", width = WeakAuras.doubleWidth, enable = function(trigger) - return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" + return trigger.unit == "nameplate" or trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" end, init = "not UnitIsUnit(\"player\", unit)" }, @@ -1657,6 +1657,15 @@ Private.event_prototypes = { end, init = "UnitIsConnected(unit)" }, + { + name = "nameplateType", + display = L["Nameplate Type"], + type = "select", + init = "WeakAuras.GetPlayerReaction(unit)", + values = "hostility_types", + conditionType = "select", + store = true, + }, { name = "name", hidden = true, @@ -5171,6 +5180,9 @@ Private.event_prototypes = { internal_events = function(trigger) local unit = trigger.unit local result = {} + if unit == "nameplate" and trigger.use_onUpdateUnitTarget then + tinsert(result, "WA_UNIT_TARGET_NAME_PLATE") + end AddRemainingCastInternalEvents(unit, result) local includePets = trigger.use_includePets == true and trigger.includePets or nil AddUnitChangeInternalEvents(unit, result, includePets) @@ -5180,6 +5192,9 @@ Private.event_prototypes = { if trigger.use_showLatency and trigger.unit == "player" then WeakAuras.WatchForCastLatency() end + if trigger.unit == "nameplate" and trigger.use_onUpdateUnitTarget then + WeakAuras.WatchForNameplateTargetChange() + end end, force_events = unitHelperFunctions.UnitChangedForceEventsWithPets, canHaveDuration = "timed", @@ -5372,6 +5387,15 @@ Private.event_prototypes = { test = "true", init = "raidMarkIndex > 0 and '{rt'..raidMarkIndex..'}' or ''" }, + { + name = "nameplateType", + display = L["Nameplate Type"], + type = "select", + init = "WeakAuras.GetPlayerReaction(unit)", + values = "hostility_types", + store = true, + conditionType = "select", + }, { name = "includePets", display = WeakAuras.newFeatureString .. L["Include Pets"], @@ -5389,10 +5413,20 @@ Private.event_prototypes = { type = "toggle", width = WeakAuras.doubleWidth, enable = function(trigger) - return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" + return trigger.unit == "nameplate" or trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" end, init = "not UnitIsUnit(\"player\", unit)" }, + { + name = "onUpdateUnitTarget", + display = WeakAuras.newFeatureString .. L["Advanced Caster's Target Check"], + desc = L["Check nameplate's target every 0.2s"], + type = "toggle", + test = "true", + enable = function(trigger) + return trigger.unit == "nameplate" + end + }, { name = "sourceUnit", init = "unit", diff --git a/WeakAuras/RegionTypes/DynamicGroup.lua b/WeakAuras/RegionTypes/DynamicGroup.lua index e029bf1..452941e 100644 --- a/WeakAuras/RegionTypes/DynamicGroup.lua +++ b/WeakAuras/RegionTypes/DynamicGroup.lua @@ -360,6 +360,28 @@ local function staggerCoefficient(alignment, stagger) end local anchorers = { + ["NAMEPLATE"] = function(data) + return function(frames, activeRegions) + for _, regionData in ipairs(activeRegions) do + local unit = regionData.region.state and regionData.region.state.unit + local found + if unit then + local frame = WeakAuras.GetUnitNameplate(unit) + if frame then + frames[frame] = frames[frame] or {} + tinsert(frames[frame], regionData) + found = true + end + end + --if not found and WeakAuras.IsOptionsOpen() and regionData.region.state then + -- Private.ensurePRDFrame() + -- Private.personalRessourceDisplayFrame:anchorFrame(regionData.region.state.id, "NAMEPLATE") + -- frames[Private.personalRessourceDisplayFrame] = frames[Private.personalRessourceDisplayFrame] or {} + -- tinsert(frames[Private.personalRessourceDisplayFrame], regionData) + --end + end + end + end, ["UNITFRAME"] = function(data) return function(frames, activeRegions) for _, regionData in ipairs(activeRegions) do @@ -389,7 +411,7 @@ local anchorers = { } local function createAnchorPerUnitFunc(data) - local anchorer = anchorers[data.anchorPerUnit] or anchorers.UNITFRAME + local anchorer = anchorers[data.anchorPerUnit] or anchorers.NAMEPLATE or anchorers.UNITFRAME return anchorer(data) end diff --git a/WeakAuras/RegionTypes/RegionPrototype.lua b/WeakAuras/RegionTypes/RegionPrototype.lua index f5f2933..ed46aac 100644 --- a/WeakAuras/RegionTypes/RegionPrototype.lua +++ b/WeakAuras/RegionTypes/RegionPrototype.lua @@ -553,6 +553,7 @@ function WeakAuras.regionPrototype.modify(parent, region, data) not ( data.anchorFrameType == "CUSTOM" or data.anchorFrameType == "UNITFRAME" + or data.anchorFrameType == "NAMEPLATE" ) -- Group Auras that will never be expanded, so those need -- to be always anchored here @@ -892,6 +893,7 @@ function WeakAuras.regionPrototype.AddExpandFunction(data, region, cloneId, pare if data.anchorFrameType == "SELECTFRAME" or data.anchorFrameType == "CUSTOM" or data.anchorFrameType == "UNITFRAME" + or data.anchorFrameType == "NAMEPLATE" then Private.AnchorFrame(data, region, parent); end diff --git a/WeakAuras/Types.lua b/WeakAuras/Types.lua index a00dab1..a894bb5 100644 --- a/WeakAuras/Types.lua +++ b/WeakAuras/Types.lua @@ -25,6 +25,7 @@ Private.glow_action_types = { Private.glow_frame_types = { UNITFRAME = L["Unit Frame"], + NAMEPLATE = L["Nameplate"], FRAMESELECTOR = L["Frame Selector"] } @@ -772,6 +773,7 @@ Private.unit_types_bufftrigger_2 = { party = L["Party"], boss = L["Boss"], arena = L["Arena"], + nameplate = L["Nameplate"], pet = L["Pet"], member = L["Specific Unit"], multi = L["Multi-target"] @@ -794,6 +796,7 @@ Private.actual_unit_types_cast = { raid = L["Raid"], boss = L["Boss"], arena = L["Arena"], + nameplate = L["Nameplate"], pet = L["Pet"], member = L["Specific Unit"], } @@ -803,6 +806,7 @@ Private.actual_unit_types_cast_tooltip = L["• |cff00ff00Player|r, |cff00ff00Ta Private.threat_unit_types = { target = L["Target"], focus = L["Focus"], + nameplate = L["Nameplate"], boss = L["Boss"], member = L["Specific Unit"], none = L["At Least One Enemy"] @@ -918,6 +922,7 @@ Private.anchor_frame_types = { SCREEN = L["Screen/Parent Group"], MOUSE = L["Mouse Cursor"], SELECTFRAME = L["Select Frame"], + NAMEPLATE = L["Nameplates"], UNITFRAME = L["Unit Frames"], CUSTOM = L["Custom"] } @@ -1919,7 +1924,8 @@ Private.classification_types = { elite = L["Elite"], rare = L["Rare"], normal = L["Normal"], - trivial = L["Trivial (Low Level)"] + trivial = L["Trivial (Low Level)"], + minus = L["Minus (Small Nameplate)"] } Private.anim_start_preset_types = { @@ -2622,6 +2628,7 @@ Private.baseUnitId = { } Private.multiUnitId = { + ["nameplate"] = true, ["boss"] = true, ["arena"] = true, ["group"] = true, @@ -2634,6 +2641,7 @@ Private.multiUnitId = { } Private.multiUnitUnits = { + ["nameplate"] = {}, ["boss"] = {}, ["arena"] = {}, ["group"] = {}, @@ -2669,6 +2677,8 @@ end for i = 1, 40 do Private.baseUnitId["raid"..i] = true Private.baseUnitId["raidpet"..i] = true + Private.baseUnitId["nameplate"..i] = true + Private.multiUnitUnits.nameplate["nameplate"..i] = true Private.multiUnitUnits.group["raid"..i] = true Private.multiUnitUnits.raid["raid"..i] = true Private.multiUnitUnits.group["raidpet"..i] = true diff --git a/WeakAuras/WeakAuras.lua b/WeakAuras/WeakAuras.lua index b2f87d6..d0256ea 100644 --- a/WeakAuras/WeakAuras.lua +++ b/WeakAuras/WeakAuras.lua @@ -2839,7 +2839,10 @@ end function Private.HandleGlowAction(actions, region) if actions.glow_action and ( - (actions.glow_frame_type == "UNITFRAME" and region.state.unit) + ( + (actions.glow_frame_type == "UNITFRAME" or actions.glow_frame_type == "NAMEPLATE") + and region.state.unit + ) or (actions.glow_frame_type == "FRAMESELECTOR" and actions.glow_frame) ) then @@ -2856,6 +2859,8 @@ function Private.HandleGlowAction(actions, region) end elseif actions.glow_frame_type == "UNITFRAME" and region.state.unit then glow_frame = WeakAuras.GetUnitFrame(region.state.unit) + elseif actions.glow_frame_type == "NAMEPLATE" and region.state.unit then + glow_frame = WeakAuras.GetUnitNameplate(region.state.unit) end if glow_frame then @@ -3153,6 +3158,14 @@ end function Private.HideTooltip() currentTooltipRegion = nil; currentTooltipOwner = nil; + -- If a tooltip was shown for a "restricted" frame, that is e.g. for a aura + -- anchored to a nameplate, then that frame is no longer clamped to the screen, + -- because restricted frames can't be clamped. So dance to make the tooltip + -- unrestricted and then clamp it again. + GameTooltip:ClearAllPoints() + GameTooltip:SetPoint("RIGHT", UIParent, "LEFT"); + GameTooltip:SetClampedToScreen(true) + GameTooltip:Hide(); end @@ -4386,6 +4399,19 @@ local function GetAnchorFrame(data, region, parent) return mouseFrame; end + if (anchorFrameType == "NAMEPLATE") then + local unit = region.state and region.state.unit + if unit then + local frame = unit and WeakAuras.GetUnitNameplate(unit) + if frame then return frame end + end + --if WeakAuras.IsOptionsOpen() then + --Private.ensurePRDFrame() + --personalRessourceDisplayFrame:anchorFrame(id, anchorFrameType) + --return personalRessourceDisplayFrame + --end + end + if (anchorFrameType == "UNITFRAME") then local unit = region.state.unit if unit then @@ -4629,6 +4655,7 @@ do for i = 1, 40 do trackableUnits["raid" .. i] = true trackableUnits["raidpet" .. i] = true + trackableUnits["nameplate" .. i] = true end function WeakAuras.UntrackableUnit(unit) diff --git a/WeakAurasOptions/ActionOptions.lua b/WeakAurasOptions/ActionOptions.lua index 778a99e..afd0cdd 100644 --- a/WeakAurasOptions/ActionOptions.lua +++ b/WeakAurasOptions/ActionOptions.lua @@ -255,7 +255,10 @@ function OptionsPrivate.GetActionOptions(data) type = "select", width = WeakAuras.normalWidth, desc = function() - return data.actions.start.glow_frame_type == "UNITFRAME" + return ( + data.actions.start.glow_frame_type == "UNITFRAME" + or data.actions.start.glow_frame_type == "NAMEPLATE" + ) and L["Require unit from trigger"] or nil end, name = L["Glow Frame Type"], @@ -629,7 +632,10 @@ function OptionsPrivate.GetActionOptions(data) type = "select", width = WeakAuras.normalWidth, desc = function() - return data.actions.finish.glow_frame_type == "UNITFRAME" + return ( + data.actions.finish.glow_frame_type == "UNITFRAME" + or data.actions.finish.glow_frame_type == "NAMEPLATE" + ) and L["Require unit from trigger"] or nil end, name = L["Glow Frame Type"], diff --git a/WeakAurasOptions/BuffTrigger2.lua b/WeakAurasOptions/BuffTrigger2.lua index 9f28b61..17450d3 100644 --- a/WeakAurasOptions/BuffTrigger2.lua +++ b/WeakAurasOptions/BuffTrigger2.lua @@ -55,7 +55,7 @@ end local function IsGroupTrigger(trigger) return trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party" - or trigger.unit == "boss" or trigger.unit == "arena" or trigger.unit == "multi" + or trigger.unit == "boss" or trigger.unit == "nameplate" or trigger.unit == "arena" or trigger.unit == "multi" end local function IsSingleMissing(trigger) @@ -238,7 +238,7 @@ local function GetBuffTriggerOptions(data, triggernum) return OptionsPrivate.Private.unit_types_bufftrigger_2 end, hidden = function() return not trigger.type == "aura2" end, - desc = L["• |cff00ff00Player|r, |cff00ff00Target|r, |cff00ff00Focus|r, and |cff00ff00Pet|r correspond directly to those individual unitIDs.\n• |cff00ff00Specific Unit|r lets you provide a specific valid unitID to watch.\n|cffff0000Note|r: The game will not fire events for all valid unitIDs, making some untrackable by this trigger.\n• |cffffff00Party|r, |cffffff00Raid|r, |cffffff00Boss|r, |cffffff00Arena|r, and |cffffff00Nameplate|r can match multiple corresponding unitIDs.\n• |cffffff00Smart Group|r adjusts to your current group type, matching just the \"player\" when solo, \"party\" units (including \"player\") in a party or \"raid\" units in a raid.\n• |cffffff00Multi-target|r attempts to use the Combat Log events, rather than unitID, to track affected units.\n|cffff0000Note|r: Without a direct relationship to actual unitIDs, results may vary.\n\n|cffffff00*|r Yellow Unit settings can match multiple units and will default to being active even while no affected units are found without a Unit Count or Match Count setting."], + desc = L["� |cff00ff00Player|r, |cff00ff00Target|r, |cff00ff00Focus|r, and |cff00ff00Pet|r correspond directly to those individual unitIDs.\n� |cff00ff00Specific Unit|r lets you provide a specific valid unitID to watch.\n|cffff0000Note|r: The game will not fire events for all valid unitIDs, making some untrackable by this trigger.\n� |cffffff00Party|r, |cffffff00Raid|r, |cffffff00Boss|r, |cffffff00Arena|r, and |cffffff00Nameplate|r can match multiple corresponding unitIDs.\n� |cffffff00Smart Group|r adjusts to your current group type, matching just the \"player\" when solo, \"party\" units (including \"player\") in a party or \"raid\" units in a raid.\n� |cffffff00Multi-target|r attempts to use the Combat Log events, rather than unitID, to track affected units.\n|cffff0000Note|r: Without a direct relationship to actual unitIDs, results may vary.\n\n|cffffff00*|r Yellow Unit settings can match multiple units and will default to being active even while no affected units are found without a Unit Count or Match Count setting."], }, useSpecificUnit = { type = "toggle", @@ -757,6 +757,56 @@ local function GetBuffTriggerOptions(data, triggernum) end }, + useHostility = { + type = "toggle", + width = WeakAuras.normalWidth, + name = L["Filter by Nameplate Type"], + order = 69.1, + hidden = function() return + not (trigger.type == "aura2" and trigger.unit == "nameplate") + end + }, + hostility = { + type = "select", + width = WeakAuras.normalWidth, + name = L["Hostility"], + values = OptionsPrivate.Private.hostility_types, + hidden = function() return not (trigger.type == "aura2" and trigger.useHostility) end, + order = 69.2 + }, + hostilitySpace = { + type = "description", + name = "", + order = 69.3, + width = WeakAuras.normalWidth, + hidden = function() return not (trigger.type == "aura2" and trigger.unit == "nameplate" and not trigger.useHostility) end + }, + + useNpcId = { + type = "toggle", + width = WeakAuras.normalWidth, + name = L["Filter by Npc ID"], + order = 69.31, + hidden = function() return + not (trigger.type == "aura2" and trigger.unit == "nameplate") + end + }, + npcId = { + type = "input", + width = WeakAuras.normalWidth, + name = L["Npc ID"], + hidden = function() return not (trigger.type == "aura2" and trigger.unit == "nameplate" and trigger.useNpcId) end, + order = 69.32, + desc = L["Supports multiple entries, separated by commas"] + }, + npcIdSpace = { + type = "description", + name = "", + order = 69.33, + width = WeakAuras.normalWidth, + hidden = function() return not (trigger.type == "aura2" and trigger.unit == "nameplate" and not trigger.useNpcId) end + }, + ignoreSelf = { type = "toggle", name = L["Ignore Self"], diff --git a/WeakAurasOptions/ConditionOptions.lua b/WeakAurasOptions/ConditionOptions.lua index ce4dcb2..d9169a9 100644 --- a/WeakAurasOptions/ConditionOptions.lua +++ b/WeakAurasOptions/ConditionOptions.lua @@ -1802,6 +1802,7 @@ local function addControlsForIfLine(args, order, data, conditionVariable, totalA order = order, values = { group = L["Group player(s) found"], + enemies = L["Enemy nameplate(s) found"] }, get = function() return check.type diff --git a/WeakAurasOptions/RegionOptions/DynamicGroup.lua b/WeakAurasOptions/RegionOptions/DynamicGroup.lua index 9a37cee..ccb2ef2 100644 --- a/WeakAurasOptions/RegionOptions/DynamicGroup.lua +++ b/WeakAurasOptions/RegionOptions/DynamicGroup.lua @@ -134,7 +134,7 @@ local function createOptions(id, data) order = 1.5, width = WeakAuras.normalWidth, name = L["Group by Frame"], - desc = L["Group and anchor each auras by frame.\n\n- Unit Frames: attach to unit frame buttons per unit.\n- Custom Frames: choose which frame each region should be anchored to."], + desc = L["Group and anchor each auras by frame.\n\n- Nameplates: attach to nameplates per unit.\n- Unit Frames: attach to unit frame buttons per unit.\n- Custom Frames: choose which frame each region should be anchored to."], hidden = function() return data.grow == "CUSTOM" end, }, anchorPerUnit = { @@ -144,6 +144,7 @@ local function createOptions(id, data) order = 1.6, values = { ["UNITFRAME"] = L["Unit Frames"], + ["NAMEPLATE"] = L["Nameplates"], ["CUSTOM"] = L["Custom Frames"], }, hidden = function() return data.grow == "CUSTOM" end,