diff --git a/WeakAuras/AnchorToWeakAuras.lua b/WeakAuras/AnchorToWeakAuras.lua new file mode 100644 index 0000000..ae24901 --- /dev/null +++ b/WeakAuras/AnchorToWeakAuras.lua @@ -0,0 +1,72 @@ +--- @type string, Private +local AddonName, Private = ... + +--- @type table +local attachedToTarget = {} +--- @type table> +local targetToAttached = {} + +-- Handles + + +--- @type fun(_: any, uid: uid, id: auraId) +local function OnDelete(_, uid, id) + local target = attachedToTarget[id] + if target then + if targetToAttached[target] then + targetToAttached[target][id] = nil + end + attachedToTarget[id] = nil + end +end + +--- @type fun(_: any, uid: uid, oldId: auraId, newId: auraId) +local function OnRename(_, uid, oldId, newId) + + local target = attachedToTarget[oldId] + if target then + -- renamed aura is an attached aura + attachedToTarget[newId] = attachedToTarget[oldId] + attachedToTarget[oldId] = nil + + targetToAttached[target][oldId] = nil + targetToAttached[target][newId] = true + end + + -- renamed aura is a targeted aura + if targetToAttached[oldId] then + for attached in pairs(targetToAttached[oldId]) do + local data = WeakAuras.GetData(attached) + if data then + data.anchorFrameFrame = "WeakAuras:" .. newId + WeakAuras.Add(data, nil, true) + end + + attachedToTarget[attached] = newId + end + targetToAttached[newId] = targetToAttached[oldId] + targetToAttached[oldId] = nil + end + +end + +--- @type fun(_: any, uid: uid, id: auraId, data: auraData, simpleChange: boolean) +local function OnAdd(_, uid, id, data, simpleChange) + if simpleChange then + return + end + OnDelete(nil, uid, id) + if data.anchorFrameType == "SELECTFRAME" + and data.anchorFrameFrame + and data.anchorFrameFrame:sub(1, 10) == "WeakAuras:" + then + local target = data.anchorFrameFrame:sub(11) + attachedToTarget[data.id] = target + targetToAttached[target] = targetToAttached[target] or {} + targetToAttached[target][data.id] = true + end +end + +Private.callbacks:RegisterCallback("Delete", OnDelete) +Private.callbacks:RegisterCallback("Rename", OnRename) +Private.callbacks:RegisterCallback("Add", OnAdd) diff --git a/WeakAuras/AuraEnvironment.lua b/WeakAuras/AuraEnvironment.lua index dd3d8d7..fa5f8cb 100644 --- a/WeakAuras/AuraEnvironment.lua +++ b/WeakAuras/AuraEnvironment.lua @@ -436,9 +436,12 @@ local FakeWeakAurasMixin = { -- Note these shouldn't exist in the WeakAuras namespace, but moving them takes a bit of effort, -- so for now just block them and clean them up later genericTriggerTypes = true, - newFeatureString = true, spellCache = true, StopMotion = true, + -- We block the loaded table, even though it doesn't exist anymore, + -- because some versions of ZT Tracker overwrote region:Collpase() and + -- checked for WeakAuras.loaded in there + loaded = true }, override = { me = UnitName("player"), diff --git a/WeakAuras/GenericTrigger.lua b/WeakAuras/GenericTrigger.lua index 32867ba..c94d868 100644 --- a/WeakAuras/GenericTrigger.lua +++ b/WeakAuras/GenericTrigger.lua @@ -2126,14 +2126,18 @@ do cdReadyFrame:SetScript("OnUpdate", nil) Private.StartProfileSystem("generictrigger cd tracking"); - if(event == "SPELL_UPDATE_COOLDOWN" + if type(event) == "number" then-- Called from OnUpdate! + Private.CheckSpellKnown() + Private.CheckCooldownReady() + Private.CheckItemSlotCooldowns() + elseif(event == "SPELL_UPDATE_COOLDOWN" or event == "RUNE_POWER_UPDATE" or event == "RUNE_TYPE_UPDATE" or event == "ACTIONBAR_UPDATE_COOLDOWN" or event == "PLAYER_TALENT_UPDATE" or event == "CHARACTER_POINTS_CHANGED") then Private.CheckCooldownReady(); elseif(event == "SPELLS_CHANGED") then - Private.CheckSpellKnown(); - Private.CheckCooldownReady(); + Private.CheckSpellKnown() + Private.CheckCooldownReady() elseif(event == "UNIT_SPELLCAST_SENT") then local unit, name, _ = ...; if(unit == "player") then @@ -3403,31 +3407,35 @@ do castLatencyFrame:RegisterEvent("CURRENT_SPELL_CAST_CHANGED") castLatencyFrame:RegisterEvent("UNIT_SPELLCAST_START") castLatencyFrame:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START") - castLatencyFrame:RegisterEvent("UNIT_SPELLCAST_STOP") castLatencyFrame:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP") castLatencyFrame:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED") + castLatencyFrame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") - castLatencyFrame:SetScript("OnEvent", function(self, event, unit) + castLatencyFrame:SetScript("OnEvent", function(self, event, unit, ...) if unit and unit ~= "player" then return end - if event == "UNIT_SPELLCAST_START" then - Private.LAST_CURRENT_SPELL_CAST_START = select(4, UnitCastingInfo("player")) / 1000 - elseif event == "UNIT_SPELLCAST_CHANNEL_START" then - Private.LAST_CURRENT_SPELL_CAST_START = select(4, UnitChannelInfo("player")) / 1000 - elseif event == "CURRENT_SPELL_CAST_CHANGED" then - -- We want to store the CURRENT_SPELL_CAST_CHANGED time - -- that was the last before the actual START event - -- This prevents updating the CURRENT_SPELL_CAST_CHANGED time after - -- we got the start time - if not Private.LAST_CURRENT_SPELL_CAST_START then - Private.LAST_CURRENT_SPELL_CAST_CHANGED = GetTime() - end - else -- STOP EVENTS - Private.LAST_CURRENT_SPELL_CAST_START = nil + + if event == "CURRENT_SPELL_CAST_CHANGED" then + castLatencyFrame.sendTime = GetTime() + return + end + if event == "UNIT_SPELLCAST_SUCCEEDED" or event == "UNIT_SPELLCAST_STOP" or event == "UNIT_SPELLCAST_CHANNEL_STOP" or event == "UNIT_SPELLCAST_INTERRUPTED" then + castLatencyFrame.sendTime = nil + return + end + if castLatencyFrame.sendTime then + castLatencyFrame.timeDiff = (GetTime() - castLatencyFrame.sendTime) + else + castLatencyFrame.timeDiff = nil end end) end end + + function WeakAuras.GetCastLatency() + return castLatencyFrame and castLatencyFrame.timeDiff or 0 + end + end -- Nameplate Target @@ -3764,9 +3772,14 @@ function GenericTrigger.CanHaveDuration(data, triggernum) return false end +function GenericTrigger.GetTsuConditionVariables(id, triggernum) + local ok, variables = xpcall(events[id][triggernum].tsuConditionVariables, Private.GetErrorHandlerId(id, L["Custom Variables"])); + if ok then + return variables + end +end + --- Returns a table containing the names of all overlays --- @param data --- @param triggernum function GenericTrigger.GetOverlayInfo(data, triggernum) local result; @@ -3786,7 +3799,7 @@ function GenericTrigger.GetOverlayInfo(data, triggernum) if (trigger.type == "custom") then if (trigger.custom_type == "stateupdate") then local count = 0; - local variables = events[data.id][triggernum].tsuConditionVariables(); + local variables = GenericTrigger.GetTsuConditionVariables(data.id, triggernum) if (type(variables) == "table") then if (type(variables.additionalProgress) == "table") then count = #variables.additionalProgress; @@ -3941,7 +3954,7 @@ function GenericTrigger.GetAdditionalProperties(data, triggernum) end else if (trigger.custom_type == "stateupdate") then - local variables = events[data.id][triggernum].tsuConditionVariables(); + local variables = GenericTrigger.GetTsuConditionVariables(data.id, triggernum) if (type(variables) == "table") then for var, varData in pairs(variables) do if (type(varData) == "table") then @@ -4115,7 +4128,7 @@ function GenericTrigger.GetTriggerConditions(data, triggernum) elseif (trigger.custom_type == "stateupdate") then if (events[data.id][triggernum] and events[data.id][triggernum].tsuConditionVariables) then Private.ActivateAuraEnvironment(data.id, nil, nil, nil, true) - local result = events[data.id][triggernum].tsuConditionVariables() + local result = GenericTrigger.GetTsuConditionVariables(data.id, triggernum) Private.ActivateAuraEnvironment(nil) if (type(result)) ~= "table" then return nil; diff --git a/WeakAuras/Prototypes.lua b/WeakAuras/Prototypes.lua index 19be76c..f83d3d0 100644 --- a/WeakAuras/Prototypes.lua +++ b/WeakAuras/Prototypes.lua @@ -6267,8 +6267,9 @@ Private.event_prototypes = { { name = L["Latency"], func = function(trigger, state) - if not Private.LAST_CURRENT_SPELL_CAST_START or not Private.LAST_CURRENT_SPELL_CAST_CHANGED then return 0, 0 end - return 0, Private.LAST_CURRENT_SPELL_CAST_START - Private.LAST_CURRENT_SPELL_CAST_CHANGED + local latency = WeakAuras.GetCastLatency() + if not latency then return 0, 0 end + return 0, latency end, enable = function(trigger) return trigger.use_showLatency and trigger.unit == "player" diff --git a/WeakAuras/Transmission.lua b/WeakAuras/Transmission.lua index 179bdc7..692edea 100644 --- a/WeakAuras/Transmission.lua +++ b/WeakAuras/Transmission.lua @@ -504,6 +504,9 @@ function WeakAuras.Import(inData, target, callbackFunc) else target = targetData end + if data.uid and data.uid ~= target.uid then + return false, "Invalid update target, uids don't match." + end end WeakAuras.PreAdd(data) if children then diff --git a/WeakAuras/WeakAuras.lua b/WeakAuras/WeakAuras.lua index e54b9d8..7a6ff00 100644 --- a/WeakAuras/WeakAuras.lua +++ b/WeakAuras/WeakAuras.lua @@ -2672,6 +2672,7 @@ local function pAdd(data, simpleChange) end end Private.UpdatedTriggerState(id) + Private.callbacks:Fire("Add", data.uid, data.id, data, simpleChange) else Private.DebugLog.SetEnabled(data.uid, data.information.debugLog) @@ -2778,6 +2779,7 @@ local function pAdd(data, simpleChange) end Private.UpdateSoundIcon(data) + Private.callbacks:Fire("Add", data.uid, data.id, data, simpleChange) end end @@ -4311,7 +4313,7 @@ local function nextState(char, state) return state end -local function ContainsPlaceHolders(textStr, symbolFunc) +local function ContainsPlaceHolders(textStr, symbolFunc, checkDoublePercent) if not textStr then return false end @@ -4320,13 +4322,17 @@ local function ContainsPlaceHolders(textStr, symbolFunc) local state = 0 local currentPos = 1 local start = 1 + local containsDoublePercent = false while currentPos <= endPos do local char = string.byte(textStr, currentPos); local nextState = nextState(char, state) if state == 1 then -- Last char was a % - if char == 123 then + if char == 123 then -- { start = currentPos + 1 + elseif char == 37 then -- % + containsDoublePercent = true + start = currentPos else start = currentPos end @@ -4350,6 +4356,9 @@ local function ContainsPlaceHolders(textStr, symbolFunc) end end + if checkDoublePercent then + return containsDoublePercent + end return false end @@ -4378,7 +4387,7 @@ function Private.ContainsPlaceHolders(textStr, toCheck) end function Private.ContainsAnyPlaceHolders(textStr) - return ContainsPlaceHolders(textStr, function(symbol) return true end) + return ContainsPlaceHolders(textStr, function(symbol) return true end, true) end local function ValueForSymbol(symbol, region, customFunc, regionState, regionStates, useHiddenStates, formatters) @@ -4432,6 +4441,9 @@ function Private.ReplacePlaceHolders(textStr, region, customFunc, useHiddenState if (endPos == 2) then if string.byte(textStr, 1) == 37 then local symbol = string.sub(textStr, 2) + if symbol == "%" then + return "%" -- Double % input + end local value = ValueForSymbol(symbol, region, customFunc, regionState, regionStates, useHiddenStates, formatters); if (value) then textStr = tostring(value); @@ -4455,7 +4467,7 @@ function Private.ReplacePlaceHolders(textStr, region, customFunc, useHiddenState end end elseif state == 1 then -- Percent Start State - if char == 123 then + if char == 123 then -- { sign start = currentPos + 1 else start = currentPos diff --git a/WeakAuras/WeakAuras.toc b/WeakAuras/WeakAuras.toc index 729e5d7..9d299e5 100644 --- a/WeakAuras/WeakAuras.toc +++ b/WeakAuras/WeakAuras.toc @@ -39,6 +39,7 @@ Transmission.lua Modernize.lua Animations.lua Conditions.lua +AnchorToWeakAuras.lua # Trigger systems BuffTrigger2.lua diff --git a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasExpand.lua b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasExpand.lua index 7fa0556..1732ec0 100644 --- a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasExpand.lua +++ b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasExpand.lua @@ -3,7 +3,7 @@ Button Widget for our Expand button -------------------------------------------------------------------------------]] if not WeakAuras.IsLibsOK() then return end -local Type, Version = "WeakAurasExpand", 4 +local Type, Version = "WeakAurasExpand", 5 local AceGUI = LibStub and LibStub("AceGUI-3.0", true) if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end @@ -38,6 +38,7 @@ local methods = { self:SetHeight(110) self:SetWidth(110) self:SetLabel() + self:SetFontObject(GameFontHighlightLarge) self:SetImage(nil) self:SetImageSize(64, 64) self:SetDisabled(false) diff --git a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasPendingUpdateButton.lua b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasPendingUpdateButton.lua index 6d58dd8..e475d98 100644 --- a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasPendingUpdateButton.lua +++ b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasPendingUpdateButton.lua @@ -99,7 +99,10 @@ local methods = { func = function() local auraData = WeakAuras.GetData(auraId) if auraData then - WeakAuras.Import(self.companionData.encoded, auraData) + local success, error = WeakAuras.Import(self.companionData.encoded, auraData) + if not success then + WeakAuras.prettyPrint(error) + end end end }, diff --git a/WeakAurasOptions/OptionsFrames/Update.lua b/WeakAurasOptions/OptionsFrames/Update.lua index bba4db8..26ac567 100644 --- a/WeakAurasOptions/OptionsFrames/Update.lua +++ b/WeakAurasOptions/OptionsFrames/Update.lua @@ -341,6 +341,17 @@ local function BuildUidMap(data, children, type) if data.parent then uidMap.map[data.uid].parent = idToUid[data.parent] end + + -- Handle anchorFrameFrame + if data.anchorFrameType == "SELECTFRAME" + and data.anchorFrameFrame + and data.anchorFrameFrame:sub(1, 10) == "WeakAuras:" + then + local target = data.anchorFrameFrame:sub(11) + if idToUid[target] then + uidMap.map[data.uid].anchorFrameFrame = idToUid[target] + end + end end local function handleSortHybridTable(data) @@ -504,6 +515,13 @@ local function BuildUidMap(data, children, type) data.controlledChildren = nil end + if self.map[uid].anchorFrameFrame then + local target = self:GetIdFor(self.map[uid].anchorFrameFrame) + if target then + data.anchorFrameFrame = "WeakAuras:" .. target + end + end + if data.regionType == "dynamicgroup" then data.sortHybridTable = {} for i, childUid in ipairs(self.map[uid].controlledChildren) do