Thread Tools Display Modes
12-04-20, 06:40 PM   #1
LudiusMaximus
A Rage Talon Dragon Guard
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 320
AlertFrame identified by numbers?

I want to set the UIFrame alpha to 0 but still see the alert frames (e.g. from achievements or world quests). So I guess what I have to do is run SetIgnoreParentAlpha(true) on the respective frames. But what frames are these? When I use /fstack I get some strange names consisting of numbers. How could I handle this?

__________________
~ Be the change you want to see in the world... of warcraft interface! ~
  Reply With Quote
12-05-20, 11:14 AM   #2
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Frames that don't have a name or weren't created with the ParentKey XML attribute will have a random number in /fstack. This is basically their internal memory pointer similar to if you tostring() a table or function. There isn't a practical way to reference a frame with this number. It's mainly to show something's there and differentiate it from any other unnamed frame.

These are very likely created using frame pools and you'll need to look at the source code to find a way to get to them.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
12-05-20, 12:53 PM   #3
LudiusMaximus
A Rage Talon Dragon Guard
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 320
All right, thanks! I was afraid so... :-)

I already looked in the Blizzard code and found AlertFrameSystems.lua to be most promising.
It includes this function:
Code:
function WorldQuestCompleteAlertFrame_SetUp(frame, questData)
  PlaySound(SOUNDKIT.UI_WORLDQUEST_COMPLETE);

  frame.questID = questData.questID;
  frame.QuestName:SetText(questData.taskName);

  frame.QuestTexture:SetTexture(questData.icon);

  frame.ToastText:SetText(questData.displayAsObjective and TOAST_OBJECTIVE_COMPLETE or WORLD_QUEST_COMPLETE);

  ResetRewardFrames(frame);

  if questData.money > 0 then
    local rewardFrame = GetRewardFrame(frame, "WorldQuestFrameRewardTemplate");
    DungeonCompletionAlertFrameReward_SetRewardMoney(rewardFrame, questData.money);
  end

  if questData.xp > 0 and not IsPlayerAtEffectiveMaxLevel() then
    local rewardFrame = GetRewardFrame(frame, "WorldQuestFrameRewardTemplate");
    DungeonCompletionAlertFrameReward_SetRewardXP(rewardFrame, questData.xp);
  end

  if questData.currencyRewards then
    for currencyIndex, currencyTexture in ipairs(questData.currencyRewards) do
      local rewardFrame = GetRewardFrame(frame, "WorldQuestFrameRewardTemplate");
      SetPortraitToTexture(rewardFrame.texture, currencyTexture);
      rewardFrame.currencyIndex = currencyIndex;
    end
  end

  StandardRewardAlertFrame_AdjustRewardAnchors(frame);
end

So I tried to hook it:
Code:
hooksecurefunc("WorldQuestCompleteAlertFrame_SetUp", function(...)
  print("WorldQuestCompleteAlertFrame_SetUp", ...)
end)

But I never see the print of my hook...

Am I missing something?
__________________
~ Be the change you want to see in the world... of warcraft interface! ~
  Reply With Quote
12-05-20, 04:04 PM   #4
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Originally Posted by LudiusMaximus View Post
But I never see the print of my hook...

Am I missing something?
That function runs before your code ever has a chance to hook it.

You need something like:
Lua Code:
  1. local function SetIgnoreParentAlpha(_, frame)
  2.     frame:SetIgnoreParentAlpha(true)
  3. end
  4.  
  5. for _, subSystem in pairs(AlertFrame.alertFrameSubSystems) do
  6.     local pool = type(subSystem) == 'table' and subSystem.alertFramePool
  7.     if type(pool) == 'table' and type(pool.resetterFunc) == 'function' then
  8.         hooksecurefunc(pool, "resetterFunc", SetIgnoreParentAlpha)
  9.     end
  10. end
Here is an easy way to test it:
Code:
/run UIParent:SetAlpha(0.5); NewMountAlertSystem:ShowAlert("123")
  Reply With Quote
12-05-20, 05:57 PM   #5
LudiusMaximus
A Rage Talon Dragon Guard
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 320
Wow, this is amazing!! How do you get to know stuff like this?? :-D

Could you also think of a way to SetIgnoreParentAlpha() of alert frames that are already shown; i.e. after the resetterFunc has already been fired?

Anyway, thank you so much!


UPDATE: I think I found a way.

Lua Code:
  1. local collectedAlertFrames = {}
  2. local alertFramesIgnoreParentAlpha = false
  3.  
  4. -- Function I call whenever I toggle UIParent's alpha.
  5. local function SetAlertFramesIgnoreParentAlpha(enable)
  6.   alertFramesIgnoreParentAlpha = enable
  7.   for _, v in pairs(collectedAlertFrames) do
  8.     v:SetIgnoreParentAlpha(enable)
  9.   end
  10. end
  11.  
  12. local function CollectAlertFrame(_, frame)
  13.   if not frame.IEF_collected then
  14.     tinsert(collectedAlertFrames, frame)
  15.     frame.IEF_collected = true
  16.     frame:SetIgnoreParentAlpha(alertFramesIgnoreParentAlpha)
  17.   end
  18. end
  19.  
  20. for _, subSystem in pairs(AlertFrame.alertFrameSubSystems) do
  21.   local pool = type(subSystem) == 'table' and subSystem.alertFramePool
  22.   if type(pool) == 'table' and type(pool.resetterFunc) == 'function' then
  23.     hooksecurefunc(pool, "resetterFunc", CollectAlertFrame)
  24.   end
  25. end
__________________
~ Be the change you want to see in the world... of warcraft interface! ~

Last edited by LudiusMaximus : 12-05-20 at 06:44 PM.
  Reply With Quote
12-05-20, 06:45 PM   #6
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Originally Posted by LudiusMaximus View Post
Could you also think of a way to SetIgnoreParentAlpha() of alert frames that are already shown; i.e. after the resetterFunc has already been fired?
That shouldn't be necessary since resetterFunc is called once when a new object is created or acquired from the pool and once when it is placed back in the pool (activeObjects and inactiveObjects respectively).
  Reply With Quote
12-05-20, 06:48 PM   #7
LudiusMaximus
A Rage Talon Dragon Guard
 
LudiusMaximus's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2018
Posts: 320
Yes, I don't want to interfere with other addons. So I only want the alerts to ignore parent UI when *my* addon fades out UIParent. But I got it to work. See my "UPDATE" in the previous post.
__________________
~ Be the change you want to see in the world... of warcraft interface! ~

Last edited by LudiusMaximus : 12-05-20 at 06:52 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » AlertFrame identified by numbers?

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off