ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   Tutorials & Other Helpful Info (https://www.esoui.com/forums/forumdisplay.php?f=172)
-   -   2.7 - Can see other player debuffs now (Tips for Buff/Debuff Frame addon makers) (https://www.esoui.com/forums/showthread.php?t=6793)

ArtOfShred 02/06/17 10:57 PM

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.

sirinsidiator 02/07/17 02:27 AM

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 ;)

ArtOfShred 02/07/17 04:08 AM

Quote:

Originally Posted by sirinsidiator (Post 29672)
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!

Solinur 02/07/17 06:58 AM

Quote:

Originally Posted by sirinsidiator (Post 29672)
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)

Letho 04/13/17 01:30 PM

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.?

Sounomi 04/14/17 01:23 AM

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.

Letho 04/14/17 02:00 AM

I see, thx for the info!


All times are GMT -6. The time now is 03:16 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI