Thread Tools Display Modes
04-16-18, 06:41 AM   #1
doofus
A Chromatic Dragonspawn
Join Date: Feb 2018
Posts: 158
UnitAura API

Maybe I should be doing more testing while trying this but thought of asking here, in case you get there before me.

I am using the UnitAura API to read buffs and debuffs on friendly players, party and raid members, and on hostile targets.

For friendly players I need to know their buffs and debuffs, eg does this player got a Rejuvenation ticking, and does he have a debuff I could (the "player") potentially dispel ?

I can read buffs OK using

Code:
    bf_name, bf_rank, bf_icon, bf_count, bf_debuffType, bf_duration, bf_expirationTime, bf_unitCaster, bf_canStealOrPurge, bf_nameplateShowPersonal, bf_spellId, bf_canApplyAura, bf_isBossDebuff, bf_isCastByPlayer, bf_nameplateShowAll, bf_timeMod = UnitAura(unit_codename, i,"HELPFUL");
    if ( bf_name == nil ) then break; end;
    bf_duration = bf_expirationTime - GetTime();
    if ( bf_duration < 0 ) then bf_duration = 3600; end;
    if ( bf_isCastByPlayer or bf_unitCaster == "player" or bf_unitCaster == "pet" ) then
        do something with this buff
    end
I am using castbyPlayer and uni9tCaster=="player" to know these are my buffs, and therefore this Rejuvenation is mine.

But now we move on to debuffs and would like to know if the friendly player has any debuffs I could remove.

I use something very similar to the above:

Code:
    bf_name, bf_rank, bf_icon, bf_count, bf_debuffType, bf_duration, bf_expirationTime, bf_unitCaster, bf_canStealOrPurge, bf_nameplateShowPersonal, bf_spellId, bf_canApplyAura, bf_isBossDebuff, bf_isCastByPlayer, bf_nameplateShowAll, bf_timeMod = UnitAura(unit_codename, i,"HARMFUL");
    if ( bf_name == nil ) then break; end;
    bf_duration = bf_expirationTime - GetTime();
    if ( bf_duration < 0 ) then bf_duration = 3600; end;
    if ( bf_canStealOrPurge ) then
    then
                do something with this debuff
    end
The only way I have found to test this code (some help here please) is in Mythic dungeons where sometimes there are dispellable debuffs on players - it is a cumbersome and timewasting process and so far the above code does not work very well, or at all, it does not work at all. If I allow for all debuffs to be returned then I receive debuffs which I cannot dispell so it seems this flag is to blame ()but am still debugging).

Any help greatly appreciated.
  Reply With Quote
04-16-18, 08:01 AM   #2
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
There is no flag for dispellable debuffs on friendly players. All you can check for is Magic/Poison/Disease/Curse, and even then, not all are dispellable.

That flag is for enemy debuffs that you can Spellsteal or dispel (those that would show up with glowing white border on unit frames.)
  Reply With Quote
04-16-18, 08:05 AM   #3
d87
A Chromatic Dragonspawn
 
d87's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2006
Posts: 163
canStealOrPurge is only about offensive dispel, so you'll have to manually check whether your class can dispel the spell's debuff type
  Reply With Quote
04-16-18, 01:38 PM   #4
doofus
A Chromatic Dragonspawn
Join Date: Feb 2018
Posts: 158
OK, but the standard raid frames have a setting "show only dispellable debuffs". How do they do it?

In my case this setting has been unselected; nevertheless the party frames have displayed the debuffs on their top right corner and they all have been dispellable by my priest and druid - coincidence ?

Edit:

In addition, gamepedia seems to differ from wowpedia considerably

https://wow.gamepedia.com/API_UnitAura

http://wowwiki.wikia.com/wiki/API_UnitAura

Last edited by doofus : 04-16-18 at 01:44 PM.
  Reply With Quote
04-16-18, 03:47 PM   #5
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,871
UnitAura

Gamepedia has the 5th return as debuffType whereas WowProgramming has it as dispelType which is probably more accurate or at least more informative.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 04-16-18 at 03:52 PM.
  Reply With Quote
04-16-18, 09:25 PM   #6
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2012
Posts: 341
Originally Posted by doofus View Post
OK, but the standard raid frames have a setting "show only dispellable debuffs". How do they do it?

In my case this setting has been unselected; nevertheless the party frames have displayed the debuffs on their top right corner and they all have been dispellable by my priest and druid - coincidence ?

Edit:

In addition, gamepedia seems to differ from wowpedia considerably

https://wow.gamepedia.com/API_UnitAura

http://wowwiki.wikia.com/wiki/API_UnitAura
To get only dispellable debuffs, you need to pass different 3rd argument to UnitAura. It's even mentioned on wowpedia.

RAID - auras that can be applied (if HELPFUL) or dispelled (if HARMFUL) by the player.
So, your third arg should be "HARMFUL|RAID" instead of just "HARMFUL". And if you know that the default UI does it, you should look for it in Blizz UI code then, it's fairly easy to find.
__________________
  Reply With Quote
04-17-18, 04:11 AM   #7
doofus
A Chromatic Dragonspawn
Join Date: Feb 2018
Posts: 158
I have tried the RAID argument and it did not work.

A very good solution would be to look at the Blizzard code, to be honest I am not sure how to get it.

However I seem to have an interim solution, I compare debuffType with preset strings for each class, for example for Resto Shaman it is "Magic" and "Curse" - if it matches then I consider it a "dispellable" debuf.
  Reply With Quote
04-17-18, 04:14 AM   #8
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
I would be careful with that solution, because you would have to consider that not all debuffs of those types are necessarily dispellable.
  Reply With Quote
04-17-18, 05:27 AM   #9
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
Originally Posted by doofus View Post
A very good solution would be to look at the Blizzard code, to be honest I am not sure how to get it.
https://www.townlong-yak.com/framexml/live
Blizzard_CompactRaidFrames
__________________
The cataclysm broke the world ... and the pandas could not fix it!
  Reply With Quote
04-17-18, 06:40 AM   #10
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2012
Posts: 341
Originally Posted by doofus View Post
I have tried the RAID argument and it did not work.
It's "HARMFUL|RAID" and not just "RAID", unless you're using UnitDebuff, then it's just "RAID".

I've just tested it and it works fine, that's also how Blizz raid frames debuffs work, UnitDebuff + "RAID".
__________________
  Reply With Quote
04-17-18, 06:47 AM   #11
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2012
Posts: 341
Originally Posted by Rilgamon View Post
All relevant info is mainly in /FrameXML/CompactUnitFrame.xml, /FrameXML/CompactUnitFrame.lua.
__________________

Last edited by lightspark : 04-17-18 at 06:53 AM.
  Reply With Quote
04-17-18, 11:22 AM   #12
doofus
A Chromatic Dragonspawn
Join Date: Feb 2018
Posts: 158
Here is the code

Code:
local dispellableDebuffTypes = { Magic = true, Curse = true, Disease = true, Poison = true};
function CompactUnitFrame_UpdateDispellableDebuffs(frame)
	if ( not frame.dispelDebuffFrames or not frame.optionTable.displayDispelDebuffs ) then
		CompactUnitFrame_HideAllDispelDebuffs(frame);
		return;
	end
	
	--Clear what we currently have.
	for debuffType, display in pairs(dispellableDebuffTypes) do
		if ( display ) then
			frame["hasDispel"..debuffType] = false;
		end
	end
	
	local index = 1;
	local frameNum = 1;
	local filter = "RAID";	--Only dispellable debuffs.
	while ( frameNum <= frame.maxDispelDebuffs ) do
		local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, canStealOrPurge, _, spellId = UnitDebuff(frame.displayedUnit, index, filter);
		if ( dispellableDebuffTypes[debuffType] and not frame["hasDispel"..debuffType] ) then
			frame["hasDispel"..debuffType] = true;
			local dispellDebuffFrame = frame.dispelDebuffFrames[frameNum];
			CompactUnitFrame_UtilSetDispelDebuff(dispellDebuffFrame, debuffType, index)
			frameNum = frameNum + 1;
		elseif ( not name ) then
			break;
		end
		index = index + 1;
	end
	for i=frameNum, frame.maxDispelDebuffs do
		local dispellDebuffFrame = frame.dispelDebuffFrames[i];
		dispellDebuffFrame:Hide();
	end
end
Thank you all for suggestions. Last I checked, RAID did not work at all.

As I mentioned earlier, it is too hard to check for debuffs, I had asked another Druid to cast Roots on me - how else can I check it ? Of course I could also do it with two accounts and two copies of WoW client - but my second account is unpaid currently...

It seems it uses the return from UnitAura / debuffType to check whether it should display the debuff or not on the raid frames. If the debuf is one of Curse, Poison, Magic or Disease then it gets shown.

This would further imply that the RAID flag of UnitAura filters out debuffs that the player cannot dispell for example a Resto Shaman cannot dispell Disease. The code however would happily accept disease as a valid debuff ? The only logical explanation is that the RAID filter has already filtered those kind of debuffs out. Fair enough. But then why bother even checking? Weird. Could someone please explain?

My Lua knowledge is not great and I am wondering:

local dispellableDebuffTypes = { Magic = true, Curse = true, Disease = true, Poison = true};

I cannot understand what Magic / Curse / Disease / Poison types are. They seem to be booleans but on the other hand are not declared anywhere (did a quick search). In addition the code then indexes dispellableDebuffTypes with the return from UnitAura() debuffType which is a string. Very weird and confusing and it works, obviously, so I am going to try it, but it would make more sense if it were like this

local dispellableDebuffTypes = { "Magic" = true, "Curse" = true, "Disease" = true, "Poison" = true};

If it were like this then we have a table indexed by strings and the UnitAura/debuffType is also a string.

Could someone please explain this to me too ?

Last edited by doofus : 04-17-18 at 11:24 AM.
  Reply With Quote
04-17-18, 12:37 PM   #13
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
lua Code:
  1. local t = {
  2.   Magic = "M",
  3.   ["Poison"] = "P",
  4. }
  5.  
  6. local dispel = "Magic"
  7.  
  8. print(t.Magic)
  9. print(t["Magic"])
  10. print(t[dispel])
  11.  
  12. dispel = "Poison"
  13.  
  14. print(t.Poison)
  15. print(t["Poison"])
  16. print(t[dispel])

The output is:
Code:
M
M
M
P
P
P
t.Magic is just syntactic sugar for t["Magic"]. Beware t[dispel] - it is not the same as t["dispel"] - without the quotation marks it is the variable dispel, that contains the string value "Magic", with the quotation marks it is a string literal and thus a key named "dispel" will be looked up (which does not exist in the example)

lua Code:
  1. local t = { "Curse" = "C" } -- INVALID SYNTAX
  Reply With Quote
04-17-18, 01:12 PM   #14
doofus
A Chromatic Dragonspawn
Join Date: Feb 2018
Posts: 158
Ah OK I now understand it should be:

local tbl = { ["stringA"] = "A", ["stringB"] = "B" };

On the other subject of filtering debuffs, the Blizzard code above accepts any of "Magic", "Disease", "Poison" and "Curse" - which puzzles me, for example if I am playing the Priest I cannot dispel Poison - will I see a "Posion" debuff on my raid frames?
  Reply With Quote
04-17-18, 03:21 PM   #15
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
UnitAura(unit, index, 'HARMFUL|RAID') will return values only for debuffs on friendly units your current character can dispel. It will return nil for poisons when you are on your priest. It will also return nil for poisons when your druid has not learned "Remove Corruption" yet. However it does not work with honor talents. It will return nil for magic debuffs on your hunter, even when "Survival Tactics" is known and active.
  Reply With Quote
04-19-18, 08:14 AM   #16
doofus
A Chromatic Dragonspawn
Join Date: Feb 2018
Posts: 158
Great, thank you.

Will run tests and report back what I have found.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » UnitAura API

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