#trying to fetch information about group members

31 messages · Page 1 of 1 (latest)

solar gale
#

I am trying to make a WA for some PI tracking and therefore am intresstes in the amount of Priests in my Group.

´´´
function(allstates, event, ...)

local timeStamp = GetTime()

if event == "COMBAT_LOG_EVENT_UNFILTERED" then
    
    local _, subevent, _, sourceGUID = ...
    local destGUID, destName = select(8, ...)
    local spellID = select(12, ...) or 0
    
    if subevent == "SPELL_AURA_APPLIED" and spellID == 10060 then
        
        local numPriests = 0
        
        for i = 1, GetNumGroupMembers() do
            
            local class = UnitClass("raid" .. i) or UnitClass("party" .. i) or UnitClass("player")
            local unit = "raid" .. i
            if UnitisUnit(unit, "player") then
                unit = "PLAYER"
            end
            
            print(i .. ": " .. class)
            print(i .. ": " .. unit)
            
            if class == "Priest" and UnitIsConnected(unit) and not UnitIsDeadOrGhost(unit) then
                numPriests = numPriests + 1
            end  
            
        end
        print("Number of Priest in Group: " .. numPriests)
        print("Number of Members in Group: " .. GetNumGroupMembers())
    end
end

end
´´´

this works with every member of the group except the player, I am trying to convert the raid(i) into "PLAYER" but i can´t find a solution

twin verge
#

that's horrible code though

#

on every combat log event, you iterate over all group members

#

that's not smart

solar gale
#

ît only iterates on subevent SpellAuraApplied Power Infusion

muted scroll
solar gale
#

Continuing on that, getting the number of priest is no issue anymore.
I know that fetching spec/talents of other players is difficult with Weakauras but i still want to give it a shot.

#
function(allstates, event, ...)
    
    local timeStamp = GetTime()
    
    if event == "GROUP_ROSTER_UPDATE" or event == "ACTIVE_TALENT_GROUP_CHANGED" or event == "READY_CHECK" or event == "CHARACTER_POINTS_CHANGED" then
        
        local numPriests = 0
        
        for unit in WA_IterateGroupMembers() do
            local class = select(2, UnitClass(unit))
            
            print(unit .. ": " .. class)
            
            if class == "PRIEST" and UnitIsConnected(unit) and not UnitIsDeadOrGhost(unit) then
                numPriests = numPriests + 1
                
                
            end
        end
        print("Number of Priests in Group: " .. numPriests)
    end
    
    
    
    if event == "COMBAT_LOG_EVENT_UNFILTERED" then
        
        local _, subevent, _, sourceGUID = ...
        local destGUID, destName = select(8, ...)
        local spellID = select(12, ...) or 0
        
        if subevent == "SPELL_AURA_APPLIED" and (spellID == 10060 or spellID == 48066) then
            
            local numPriests = 0
            
            for unit in WA_IterateGroupMembers() do
                local class = select(2, UnitClass(unit))
                
                print(unit .. ": " .. class)
                
                if class == "PRIEST" and UnitIsConnected(unit) and not UnitIsDeadOrGhost(unit) then
                    if CanInspect(unit) and CheckInteractDistance(unit, 1) then
                        NotifyInspect(unit)
                    end
                    
                    
                    numPriests = numPriests + 1
                    --local specID = GetInspectSpecialization(unit) 
                    --print(unit .. ": " .. specID)
                    
                    
                end
            end
            
            print("Number of Priests in Group: " .. numPriests)
        end
    end
end 
#

This is my code of my first trigger. The first events are the ones i want to use in the end but are hard to trigger for testing, that is why I use the CLEU to trigger it easier.

After I filtered the Priests i want to check their talents with :

if CanInspect(unit) and CheckInteractDistance(unit, 1) then
    NotifyInspect(unit)
end

That should trigger the INSPECT_READY event, which I try to catch with a 2nd trigger:

function(event, guid, ...)
    
    local unit = select(1, ...)
    local specID = GetInspectSpecialization(unit)
    
    if specID == 3 then
        print(unit .. " is Discipline")
    end
    
    ClearInspectPlayer(unit)
end

Unfortunately the 2nd trigger never gets reached.

last pagoda
#

WeakAuras can do a lot of this tracking already.

To get the number of priests in your group, I would suggest creating a trigger for Unit Characteristics, Unit = Smart Group, Class = Priest, Ignore Disconnected.

Assuming you want to also track whenever a priest casts PI and who the target was, create a trigger for Combat Log, Message Prefix = Spell, Message Suffix = Cast Success, Spell Id = 10060.

You can then make use of these triggers in your custom trigger by listening for the WeakAuras internal event TRIGGER:1:2 (assuming the previous triggers were numbered 1 and 2). The arguments to your custom function for TRIGGER events will be event, triggerNum, triggerStates. Use DevTool:AddData(triggerStates, event) to see what the data you're working with looks like.

You'll probably want to maintain a table in aura_env of each priest, the time they cast PI, and who they cast it on. Use the first trigger I mentioned to perform any necessary changes when a priest joins or leaves the group. I would also do some cleanup whenever an encounter starts. Generate/maintain the allStates table for your TSU using this as the point of truth.

Good luck!

muted scroll
#

the problem with inspecting is that blizzard heavily throttled it after the gearscore addon became popular in original wotlk, so INSPECT_READY isn't fired immediately after NotifyInspect and the event gets blocked from firing if NotifyInspect is used too often. that makes it difficult to get inspect-related info from multiple units

solar gale
# last pagoda WeakAuras can do a lot of this tracking already. To get the number of priests i...

I know that there are options to make a weakaura that tracks the pi buff.
I am interested in am more advanced version, like the addon MRT but in Weakaura form and only for the buffs that interesst a caster for example. (I also know you can customise MRT, but implementing that into a class- UI weakaura makes it way smoother to use).

That is why I try to use the TSU to update the allstates tabel with the information about PI/multiple PI's.
CLEU:UNIT_DIED to remove the available PI or BOSS_KILL reset the PI cooldown etc.

solar gale
# muted scroll the problem with inspecting is that blizzard heavily throttled it after the gear...

I see the issue, but i thought NotifyInspect() happens asyncron.

If there is no proper interrupt handler in the INSPECT_READY that will handle the calls then i got an issue. For my example there is no time relevancy, I can store the priests units in a global variable and inspect them one by one slowly. since the call should only happens once per session.

Any idea how to circumvent the problem you mentioned?

muted scroll
#

unfortunately i'm not sure how to do that

muted scroll
#

i'm guessing i'd try to add WeakAuras.ScanEvents at the end of trigger 2 to start another NotifyInspect from trigger 1 (details on ScanEvents found in the same github link above)
and then a C_Timer.After function as a backup if NotifyInspect was blocked from running
alternatively C_Timer.NewTicker can be used to call NotifyInspect every few seconds and then cancelled once it has gone through

solar gale
#

I did not manage to get anything usable with inspecting players if someone does I would be happy to check it out.

What i did now:

#

Events:

CLEU:SPELL_AURA_APPLIED,CLEU:UNIT_DIED,CLEU:SPELL_RESURRECT,BOSS_KILL,UNIT_COMBAT,GROUP_ROSTER_UPDATE
#

Trigger:

function(allstates, event, ...)
    local timeStamp = GetTime()  
    if event == "COMBAT_LOG_EVENT_UNFILTERED" then
        local _, subevent = ... 
        local sourceGUID, sourceName = select(4, ...)
        local destGUID, destName = select(8, ...)
        local spellID, spellName = select(12, ...)
        if subevent == "SPELL_AURA_APPLIED" and spellID == 10060 and IsInInstance() then 
            allstates[sourceGUID] = allstates[sourceGUID] or {}
            local state = allstates[sourceGUID]
            state.name = sourceName
            state.progressType = 'timed'
            state.duration = aura_env.PI_CD_duration
            state.expirationTime = timeStamp + aura_env.PI_CD_duration
            state.spellid = spellID
            state.autoHide = false
            state.changed = true
            state.show = true
            allstates[destGUID].customField = {
                dead = false,
            }
        end
        if subevent == "UNIT_DIED" then 
            if destGUID and UnitIsPlayer(destName) and allstates[destGUID] then
                allstates[destGUID].customField = {
                    dead = true,
                }
                allstates[destGUID].changed = true
            end
        end
        if subevent == "SPELL_RESURRECT" then 
            if destGUID and UnitIsPlayer(destName) and allstates[destGUID] then
                allstates[destGUID].customField = {
                    dead = false,
                }
                allstates[destGUID].changed = true
            end
        end
    end
#
if event == "BOSS_KILL" and IsInRaid() then
        for _, state in pairs(allstates) do
            state.duration = 0
            state.expirationTime = 0
            state.changed = true
        end
    end
    if event == "UNIT_COMBAT" then
        for guid, state in pairs(allstates) do
            local unit = state.name
            if unit and UnitIsPlayer(unit) and not UnitIsDeadOrGhost(unit) then
                allstates[guid].customField = {
                    dead = false,
                }
                allstates[guid].changed = true
            end
        end
    end
    if event == "GROUP_ROSTER_UPDATE" then
        for guid, state in pairs(allstates) do
            if not UnitInRaid(state.name) and not UnitInParty(state.name) then
                allstates[guid] = nil
            end    
        end
    end
    return true 
end
#

Variables:

{
    expirationTime = true,
    duration = true,
    
    isDead = {
        display = "is Dead",
        type = "bool",
        test = function(state, needle)
            return state.customField and state.customField.dead == (needle == 1)
        end,
        events = {
            "COMBAT_LOG_EVENT_UNFILTERED"
        },
    }
}
#

Issues that I am still encountering and don't know how to fix:

  1. Cooldown's resetting after a wipe "BOSS_KILL" makes it easy on killing a raid boss but I have not found a solution to reset the CD's on a wipe.

  2. Registering a player as alive when he runs into an Instance in Ghost form. My work-around is "UNIT_COMBAT" it is an acceptable solution but triggers a bit to often and obviously is not as accurate.
    I also tried "CLEU:SPELL_AURA_REMOVED" / "UNIT_AURA" with the Ghost debuff you have as a player in Ghost form, but that never triggered.

muted scroll
#
  1. ENCOUNTER_END should be good for that, fires when a boss encounter either dies or resets.
  2. would be best to grab a friend & test this in real-time with /etrace inside a dungeon to see what events fire (Gundrak would be good for long-range testing as the two entrances are far apart). my assumption would be either UNIT_FLAGS (fires when afk/pvp/dnd etc changes, being dead might count as a flag) or UNIT_PHASE (fires when a unit gets phased)
solar gale
#

Fixed it like this with ENCOUNTER_END:

if event == "ENCOUNTER_END" and IsInRaid() then
        
        local encounterID = ...
        
        if not aura_env.no_Reset_Boss[encounterID] then
            
            for _, state in pairs(allstates) do
                
                state.duration = 0
                state.expirationTime = 0
                state.changed = true
                
            end
            
        end  
        
    end
#

UNIT_FLAGS works for beeing resureccted by walking into the instance:

    if event == "UNIT_FLAGS" then
        
        local unit = ...
        local guid = UnitGUID(unit) or "Unknown"
        
        if unit and UnitIsPlayer(unit) and not UnitIsDeadOrGhost(unit) and allstates[guid] then
            
            allstates[guid].customField = {
                dead = false,
            }
            allstates[guid].changed = true
            
        end
        
    end
patent olive
#

Can you use the role assignment instead? That API is very easy to use and I suspect you only care about DPS vs healer and not disc vs holy

solar gale
#

Also added detection for changed specs:

if event == "UNIT_SPELLCAST_SUCCEEDED" then
        
        local unit, _, spellID = ...
        local guid = UnitGUID(unit) or "Unknown"
        
        if unit and UnitIsPlayer(unit) and (spellID == 63644 or spellID == 63645) and allstates[guid] then
            
            allstates[guid] = nil 
            
        end
        
    end

I checked with ACTIVE_TALENT_GROUP_CHANGED, to also implement if someone changed away from the disc spec but since this doesn't return the unit that changed, i would need to check both events and it was not worth the work (If someone want to do that DM me).

#

Last thing I added was Log-on Log-off detection:

    if event == "UNIT_CONNECTION" then  
        
        local unit, isConnected = ...
        
        if unit and UnitIsPlayer(unit) and not isConnected and allstates and type(allstates) == "table" then
            
            for guid, state in pairs(allstates) do
                
                if not UnitIsConnected(state.name) then
                    
                    allstates[guid].customField = {
                        dead = true,
                    }
                    allstates[guid].changed = true
                    
                end
                
            end
            
        end
        
        if unit and UnitIsPlayer(unit) and not isConnected and allstates and type(allstates) == "table" then
            
            for guid, state in pairs(allstates) do
                
                if UnitIsConnected(state.name) then
                    
                    allstates[guid].customField = {
                        dead = true,
                    }
                    allstates[guid].changed = true
                    
                end
                
            end
            
        end
        
    end

This got rather complicated since apparently if someone logged off UnitGUID(unit) only returns the same GUID no matter who logs off (probably the Players)

solar gale
patent olive