Thread Tools Display Modes
06-02-23, 06:41 PM   #1
lualoser
A Defias Bandit
Join Date: Jun 2023
Posts: 2
Move Player Debuffs (Default UI)

Hi,

Since I wanted to adjust the Blizzard default UI (in Classic Wow) to my liking, I created an addon in order to move the position of the player debuffs. To be more specific I wanted to achieve the following two things:
  1. The player debuffs should appear at the center of the screen while the player buffs stay at their default position in the top right corner.
  2. The alignment of the player debuffs should be centered. So instead of having a fixed anchor from which the debuffs grow to the left or to the right, I want to have a dynamic anchor that adjusts depending on the amount of debuffs. My goal is that all the debuffs combined are always perfectly centered.

Here is what I did:
Basically I copy+pasted some of the code of BlizzardInterfaceCode\Interface\FrameXML\BuffFrame into my addon and adjusted some numbers and anchors. It worked out partially. The debuffs are at the center of the screen, as I wanted it. The alignment-part however did not work. As it is now the anchor is fixed in the center from where the debuffs grow to the right. I think there might be a problem with "DEBUFF_ACTUAL_DISPLAY" in line 19 of my lua code but I'm unable to fix it.

It goes without saying that I have no idea of what I'm doing. If there is a more elegant way to achieve what I want, I'd be eager to hear. I really appreciate any help. Thanks in advance!


Lua Code:
  1. function DebuffButton_UpdateAnchors(buttonName, index)
  2.     local numBuffs = BUFF_ACTUAL_DISPLAY + BuffFrame.numEnchants;
  3.  
  4.     local rows = ceil(numBuffs/BUFFS_PER_ROW);
  5.     local buff = _G[buttonName..index];
  6.  
  7.  
  8.  
  9.     -- Position debuffs
  10.     if ( (index > 1) and (mod(index, BUFFS_PER_ROW) == 1) ) then
  11.         -- New row
  12.         buff:SetPoint("TOP", _G[buttonName..(index-BUFFS_PER_ROW)], "BOTTOM", 0, -BUFF_ROW_SPACING);
  13.     elseif ( index == 1 ) then
  14.         if ( rows < 2 ) then
  15.             DebuffButton1.offsetY = 1*((2*BUFF_ROW_SPACING)+BUFF_BUTTON_HEIGHT);
  16.         else
  17.             DebuffButton1.offsetY = rows*(BUFF_ROW_SPACING+BUFF_BUTTON_HEIGHT);
  18.         end
  19.         buff:SetPoint("CENTER", Screen, "CENTER", -(DEBUFF_ACTUAL_DISPLAY)*(BUFF_BUTTON_HEIGHT), -200);
  20.     else
  21.         buff:SetPoint("LEFT", _G[buttonName..(index-1)], "RIGHT", 5, 0);
  22.     end
  23. end

Last edited by lualoser : 06-04-23 at 04:29 PM.
  Reply With Quote
06-06-23, 04:31 AM   #2
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,323
This appears to be from the Vanilla Classic client. Wrath Classic adds buff consolidation and Dragon Flight's code was rewritten into mixins. The target client matters as oftentimes the code we're seeking to modify and sometimes even API calls will be different.

That being said, I have a few additional notes. DEBUFF_ACTUAL_DISPLAY is being incremented as DebuffButton_UpdateAnchors() is repeatedly called. For example, it would show zero in the first call, 1 for the second, 2 for the third, and so on. For this reason, you don't have a usable count of how many debuffs you have until after the last call of your function.

Screen doesn't refer to a UI Object. It isn't a magic keyword, Lua just sees it as a variable name. The contents of an undefined variable is nil, which when given as the reference object for :SetPoint() does anchor to the screen. The problem here is if anyone else were to haphazardly store a value into this variable, the result will break your code. It's common practice to anchor to UIParent as that's the root frame of the entire UI and what UI scaling is applied directly to.

UIParent_ManageFramePositions() is called shortly after your function runs, which is susceptible to addon taint. You'll want to avoid directly replacing Blizzard functions unless you're sure protected code doesn't run after your function does. Blizzard provides a way to post-hook functions without spreading taint through hooksecurefunc().



Here's how I would implement your requested change.
Lua Code:
  1. local Step=BUFF_BUTTON_HEIGHT+5;--  Precalculated horizontal step
  2. hooksecurefunc("BuffFrame_Update",function()
  3.     local offset=(DEBUFF_ACTUAL_DISPLAY-1)*Step/2;--    Half the total width added after the first debuff
  4.     for i=1,DEBUFF_ACTUAL_DISPLAY do
  5.         local debuff=_G["DebuffButton"..i];
  6.         if debuff and debuff:IsShown() then--   Sanity check
  7. --          Arrange left-to-right (stock is right-to-left)
  8.             debuff:ClearAllPoints();--  Clear existing anchors (resizing happens when more than one point is defined)
  9.             debuff:SetPoint("CENTER",UIParent,"CENTER",(i-1)*Step-offset,-200);
  10.         end
  11.     end
  12. end);
__________________
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
06-07-23, 04:48 PM   #3
lualoser
A Defias Bandit
Join Date: Jun 2023
Posts: 2
Thank you for your reply!

By Classic Wow, I actually meant Classic Vanilla or Classic Era, which is why I indeed took the code from the Vanilla Classic client. I should have been more precise in that regard.

So I tested your code on the classic era servers and it works just perfectly. Again, thank you very much! Not only for providing me the code but also for your thorough explanations. I really appreciate it.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Move Player Debuffs (Default UI)

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