Thread Tools Display Modes
02/06/17, 10:57 PM   #1
ArtOfShred
 
ArtOfShred's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 103
2.7 - Can see other player debuffs now (Tips for Buff/Debuff Frame addon makers)

So with the API changes in 2.7 we can now see debuffs applied onto enemies by other friendly players. This has also led to more NPC self buffs displaying which is great! However, due to the massive increase in number of buffs displayed on the target this can lead to a lot of unnecessary information being broadcast.

I've found a solution that is relatively foolproof for adjusting what is displayed by using EVENT_COMBAT_EVENT to filter incoming buffs/debuffs. EVENT_COMBAT_EVENT will return a nil source or target if the source or target is not the player. This allows us to filter in anything incoming if its not from the player in a rather simple way. Thankfully this event returns information before EVENT_EFFECT_CHANGED.

First off you'll want to create 2 local variables in the relevant lua file for your addon which you intend to control buff/display:

Code:
local buffSource = nil
local buffTarget = nil
Now, we can use EVENT_COMBAT_EVENT to determine when any effect is fired. Under your function for EVENT_COMBAT_EVENT:

Code:
buffSource = zo_strformat("<<t:1>>",sourceName)
buffTarget = zo_strformat("<<t:1>>",targetName)
Next, LUI uses EVENT_EFFECT_CHANGED to create buff displays by reading the information and running a function to create and remove buff containers based off of it. In the beginning of your function for displaying buffs:

Code:
if buffSource == "" and buffTarget == "" and effectType == 2 then return end
Note that effectType 2 is EFFECT_TYPE_DEBUFF. You could also add something in for buffs to prevent those from displaying as well, however that is less of an issue. This statement will filter out any non-player sourced/targeted debuff changes.

Of course instead of returning the function, you could add specific conditions in here to change the way a buff is displayed when its source is not the player (greying it out for example).

Now the only issue with this is it will hide some self-applied debuffs NPC's place on themselves that may provide useful information to the player. The counter to this is to create a table of AbilityID's to be listed as an exception to this.

I have a table in LUI to create exceptions.

Code:
E.DebuffDisplayOverride = {

	[2727] = true, -- Off-Balance

}
The example above is the Off-Balance effect applied when the player interrupts an NPC cast. The npc staggers backwards and then after the stagger effect fades applies 2727 Off-Balance as a debuff onto themselves. This is relevant information that should show regardless of whether another player interrupted the NPC or not.
Then you can modify the statement above to something like:

Code:
if buffSource == "" and buffTarget == "" and effectType == 2 and not E.DebuffDisplayOverride[abilityId] then return end
Hopefully this might be of use to anyone working on an addon with Buff/Debuff trackers!

EDIT: Also note: it is important that we check for both SOURCE and TARGET when determining whether an effect is from a non-player source/target. The reason for this is that EFFECT_COMBAT_EVENT displays buffs and debuffs that are fading with a NIL source and the target as a player. Without checking for both source/target, its possible that an effect that has an unlimited duration (a toggle ability, mundus buff, etc) would never be removed from the buff/debuff display. There's probably other potential problems with it, depending on the method you're using to create buff/debuff displays. With this method, the container is just never created at all which should cause 0 issues.

Last thing, consider adding:
Code:
if isError then return end
Into the beginning of both functions, as its likely to return an error on reloading the UI in combat.

Last edited by ArtOfShred : 02/06/17 at 11:19 PM.
  Reply With Quote
02/07/17, 02:27 AM   #2
sirinsidiator
 
sirinsidiator's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 1,567
Nice writeup, just a little bit behind the times. Instead of filtering all combat events in Lua, you should always try to filter them with the built in event filters first, as they offer way better better performance for this task. Afterwards you can filter the remaining events in Lua without much impact
  Reply With Quote
02/07/17, 04:08 AM   #3
ArtOfShred
 
ArtOfShred's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 103
Originally Posted by sirinsidiator View Post
Nice writeup, just a little bit behind the times. Instead of filtering all combat events in Lua, you should always try to filter them with the built in event filters first, as they offer way better better performance for this task. Afterwards you can filter the remaining events in Lua without much impact
Oh thanks for the info, didn't even know about the filters. My knowledge is pretty limited, I just wanted to post this out here to get the idea going. I imagine I could probably do the same thing just using REGISTER_FILTER_UNIT_TAG and checking to make sure its not nil then. REGISTER_FILTER_ABILITY_ID could be linked to a table of abilityID's to ignore for this too then eh?

I'll have to look into it a bit more, I definitely need to optimize some of the custom functions I've put into LUI's event display.

Thanks!

Last edited by ArtOfShred : 02/07/17 at 04:18 AM.
  Reply With Quote
02/07/17, 06:58 AM   #4
Solinur
AddOn Author - Click to view addons
Join Date: Aug 2014
Posts: 78
Originally Posted by sirinsidiator View Post
Nice writeup, just a little bit behind the times. Instead of filtering all combat events in Lua, you should always try to filter them with the built in event filters first, as they offer way better better performance for this task. Afterwards you can filter the remaining events in Lua without much impact
It's not aplicable in this case. With EFFECT_COMBAT_EVENT you don't have info in that event to filter it. You want to have all events where the player is involved, but you only get the "target" unit. (A debuff is cast by the player but then active on another unit, so filtering by player would filter out all debuffs)

You also can not give a list of abilities. Instead you would need to register each ability on its own. (see the custom ability part in CombatMetrics.lua)
  Reply With Quote
04/13/17, 01:30 PM   #5
Letho
AddOn Author - Click to view addons
Join Date: Apr 2016
Posts: 238
This brings up a new question: Until now I assumed that event data was only sent once to a client per event occurance.

1. Lets assume we have two addons: A and B.
2. B adds a filter for a specific event.
3. A uses this event too. The event is still accessible for A.

=> events are triggered at a "per addon" basis. Ain't that very unefficient or am I missing sth.?
  Reply With Quote
04/14/17, 01:23 AM   #6
Sounomi
Join Date: Oct 2014
Posts: 40
The event is triggered internally by the client and add-ons merely request that a callback function is called when that event is triggered. So when it goes off, the client goes through all of the registered callbacks and fires them off. The filter is only applied to that add-on's registered callback and merely just has it checked by the client itself instead of the add-on's code doing the checking.
  Reply With Quote
04/14/17, 02:00 AM   #7
Letho
AddOn Author - Click to view addons
Join Date: Apr 2016
Posts: 238
I see, thx for the info!
  Reply With Quote

ESOUI » Developer Discussions » Tutorials & Other Helpful Info » 2.7 - Can see other player debuffs now (Tips for Buff/Debuff Frame addon makers)

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