Thread Tools Display Modes
07-31-13, 04:09 AM   #1
hooroo
A Defias Bandit
Join Date: Apr 2009
Posts: 3
Question Help with Raidframe Debuff Code

I'm just starting to learn LUA and am trying to modify this code so that it shows more than the limited amount of 3 debuffs to the left of the CompactRaidFrame. I managed to get the basics working but am stuck on a few issues.

1. When using Setpoint to "CompactRaidFrame"..i it cannot be found, I tried changing the createframe parentFrame from UIParent to CompactRaidFrameContainer but that didn't help, couldn't find anything useful with framestack.

2. Currently using UnitDebuff("player", i) for debugging but once i get the setpoint working i'm going to try and make it work for multiple units eg. "if in party for i=1,5 UnitDebuff(party"..i, i) else if in raid for i=1,10 UnitDebuff(raid"..i, i)" except i think that would only display party1, debuff1 - party2, debuff2 if i'm reading it correctly.

I guess i need to make another variable increment separately like UnitDebuff(party"..i, debuffN) etc What would be the proper way to do it?

Thanks

Code:
-- Create a table to hold all the debuff icons
local debuffIcons = {}
 
-- Create all the icons ahead of time.
for i = 1, 10 do
    local f = CreateFrame("Button", "RaidFrameDebuff"..i, CompactRaidFrameContainer)
    f:SetPoint("LEFT", _G["CompactRaidFrame"..i], 22 * (i - 1), 0)
    f:SetWidth(22)
    f:SetHeight(22)
    f:Hide() -- Hide the button for now.
 
    local t = f:CreateTexture(nil, "BACKGROUND")
    t:SetAllPoints(true)
    f.texture = t
 
    -- Put the icon into the table.
    debuffIcons[i] = f
end

local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("UNIT_AURA")
eventFrame:SetScript("OnEvent", function(self, event, unit)
    --[[if unit ~= "target" then
        -- Wrong unit. Quit.
        return
    end
 ]]
    for i = 1, 5 do
        -- Figure out which button to use for this slot.
        local button = debuffIcons[i]
        -- Get information about the debuff in this slot, if any.
        local name, _, icon, _, debuffType, duration, timeLeft = UnitDebuff("player", i)
        if name then
            -- There's a debuff in this slot.
            -- Set the correct texture, and show the button.
            button.texture:SetTexture(icon)
            button:Show()
        else
            -- There's no debuff in this slot.
            -- Clear the texture, and hide the button.
            button.texture:SetTexture("")
            button:Hide()
        end
    end
end)

Last edited by hooroo : 07-31-13 at 04:47 AM.
  Reply With Quote
07-31-13, 06:51 PM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by hooroo View Post
1. When using Setpoint to "CompactRaidFrame"..i it cannot be found, I tried changing the createframe parentFrame from UIParent to CompactRaidFrameContainer but that didn't help, couldn't find anything useful with framestack.
The problem is that the individual compact raid frames are not created yet when you log in. To solve this, you'll need to figure out which function gets called when a new compact unit frame gets created, and add the icons to that frame.

Originally Posted by hooroo View Post
2. Currently using UnitDebuff("player", i) for debugging but once i get the setpoint working i'm going to try and make it work for multiple units eg. "if in party for i=1,5 UnitDebuff(party"..i, i) else if in raid for i=1,10 UnitDebuff(raid"..i, i)" except i think that would only display party1, debuff1 - party2, debuff2 if i'm reading it correctly.
You don't need to loop over all the group units -- just update the icons for the unit that UNIT_AURA fired for, and keep track of the icons for each frame separately.

Here's a drycoded (completely untested) update of the code you posted, which I actually wrote in the first place, though I don't recall what the original request was. You'll need to adjust the position of the icons, and it could definitely be done more efficiently, but that's the general idea.

Code:
-- Store some variables for easier configuration:
local MAX_ICONS = 10
local ICON_SIZE = 17

-- Create a table to hold all the debuff icons:
local debuffIcons = {}

-- Create the icons for each frame when it's created:
hooksecurefunc("CompactUnitFrame_SetUnit", function(frame, unit)
	-- If this frame already has icons, quit:
	if debuffIcons[frame] then
		return
	end

	-- Otherwise, add the icons:
	debuffIcons[frame] = {}
	for i = 1, MAX_ICONS do
		local button = CreateFrame("Button", "$parentExtraDebuff"..i, frame)
		button:SetPoint("LEFT", _G["CompactRaidFrame"..i], ICON_SIZE * (i - 1), 0)
		button:SetSize(ICON_SIZE, ICON_SIZE)
		button:Hide()

		local tex = button:CreateTexture(nil, "BACKGROUND")
		tex:SetAllPoints(true)
		button.texture = tex

		debuffIcons[frame][i] = button
	end
end)

local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("UNIT_AURA")
eventFrame:SetScript("OnEvent", function(self, event, unit)
	-- Find the frame for this unit:
	for frame in pairs(debuffIcons) do
		if frame.displayedUnit == unit then
			for i = 1, MAX_ICONS do
				-- Figure out which button to use for this slot.
				local button = debuffIcons[frame][i]
				-- Get information about the debuff in this slot, if any.
				local name, _, icon, _, debuffType, duration, timeLeft = UnitDebuff("player", i)
				if name then
					-- There's a debuff in this slot.
					-- Set the correct texture, and show the button.
					button.texture:SetTexture(icon)
					button:Show()
				else
					-- There's no debuff in this slot.
					-- Clear the texture, and hide the button.
					button.texture:SetTexture("")
					button:Hide()
				end
			end
			-- Stop looking for the frame, since we found it:
			break
		end
	end
end)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
07-31-13, 10:00 PM   #3
hooroo
A Defias Bandit
Join Date: Apr 2009
Posts: 3
Originally Posted by Phanx View Post
The problem is that the individual compact raid frames are not created yet when you log in. To solve this, you'll need to figure out which function gets called when a new compact unit frame gets created, and add the icons to that frame.
Thanks for explaining your code, that makes sense and it's finally showing something.

Now i've run into some behavior which I can't understand which i think comes from this code:
Code:
button:SetPoint("LEFT", _G["CompactRaidFrame"..i], ICON_SIZE * (i - 1), 0)


1. The first Debuff shows up fine to the left within the raid frame (ignore the default raidframe generated debuff below it). The Second seems to get pushed out to the UIParent since it is way to the left, once the first Debuff runs out it jumps to the first debuffs position.

to try and find the problem I manually altered their positions doing:

Code:
for i = 1, MAX_ICONS do
	local button = CreateFrame("Button", "$parentExtraDebuff"..i, frame)
	if i == 1 then
                button:SetPoint("LEFT", _G["CompactRaidFrame1"], -17, 0)
        else
		button:SetPoint("LEFT", _G["CompactRaidFrame1"], -50, 0)
        end
....


That successfully moved them to their set positions which is to be expected I guess.

I'll keep on testing different things:
Code:
-- If this frame already has icons, quit:
if debuffIcons[frame] then
	return
end


Commenting out the code above makes the first debuff assume the correct position except on the wrong raid frame.

Maybe someone can see where it's going wrong.
  Reply With Quote
07-31-13, 11:17 PM   #4
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Change this:
Code:
button:SetPoint("LEFT", _G["CompactRaidFrame"..i], ICON_SIZE * (i - 1), 0)
to this:
Code:
button:SetPoint("LEFT", frame, ICON_SIZE * (i - 1), 0)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
07-31-13, 11:51 PM   #5
hooroo
A Defias Bandit
Join Date: Apr 2009
Posts: 3
Originally Posted by Phanx View Post
Change this:
Code:
button:SetPoint("LEFT", _G["CompactRaidFrame"..i], ICON_SIZE * (i - 1), 0)
to this:
Code:
button:SetPoint("LEFT", frame, ICON_SIZE * (i - 1), 0)
Thanks, that did it :) , i'll post the final addon once i've fixed the raid specific stuff if anyone is interested.

For future testing, do you know of a more practical way to test code like this than actually finding something to put debuffs on you (somehow generate dummy debuffs or something).
  Reply With Quote
08-01-13, 02:19 AM   #6
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Put this at the top of your file:

Code:
local UnitDebuff
do
	local fakeDebuffs = {
		{ "Allergies", false, "Ability_Creature_Disease_04", 0, false, 180, false, false, 31427, false, true, false },
		{ "Amplify Damage", false, "Spell_Shadow_Shadowfury", 99, false, 10, false, false, 39095, false, true, false },
		{ "Brood Affliction: Black", false, "INV_Misc_Head_Dragon_Black", 0, "Curse", 600, false, false, 23154, false, true, false },
		{ "Corruption", false, "Spell_Shadow_AbominationExplosion", 0, "Magic", 18, false, false, 172, false, false, true },
		{ "Enhance Magic", false, "Spell_Arcane_ArcanePotency", 0, "Magic", 8, true, false, 91624, false, false, false },
		{ "Enrage", false, "Ability_Druid_Enrage", 0, "", 10, false, false, 5229, false, false, true },
		{ "Furious Poison", false, "Spell_Yorsahj_Bloodboil_Green", 4, "Poison", 10, false, false, 115087, false, false, false },
		{ "Ghoul Rot", false, "Spell_Shadow_CreepingPlague", 0, "Disease", 20, false, false, 12541, false, false, false },
	}
	function UnitDebuff(unit, index, ...)
		if type(index) == "number" then
			local name, rank, icon, count, debuffType, duration, canStealOrPurge, shouldConsolidate, spellId, canApplyAura, isBossDebuff, isCastByPlayer = unpack(fakeDebuffs[random(#fakeDebuffs)])
			local expirationTime = GetTime() + duration - random(1, duration - 1)
			local unitCaster = "boss1"
			icon = "Interface\\Icons\\"..icon
			return name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, canStealOrPurge, shouldConsolidate, spellId, canApplyAura, isBossDebuff, isCastByPlayer
		else
			return _G.UnitDebuff(unit, index, ...)
		end
	end
end
Make sure you comment it out when not actively testing.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Simple Raidframe Debuff Code


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