WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Get raid target icon from destGUID (https://www.wowinterface.com/forums/showthread.php?t=39366)

daylesan 03-21-11 04:35 AM

Get raid target icon from destGUID
 
I want to check if a unit (identified through the destGUID parameter) from a COMBAT_LOG_EVENT_UNFILTERED event has been marked with a raid marker.

Is there a better/simpler way of doing it than this?
1) upon receiving the combat log event, go through all unitID's and check if they are raid marked
2) if a raid marked unitID has been found, get its unitGUID
3) compare the destGUID from the combat log event with the unitGUID from step 2. If they match, destGUID is raid marked.

Nobgul 03-21-11 05:18 AM

As there is no api call for IsRaidMarked, I don't think there is a easier way =(

oomp 03-21-11 06:46 AM

Don't use destGUID, use destFlags...

Lua Code:
  1. local function GetIconIndex(flags)
  2.     local number, mask, mark
  3.     if bit.band(flags, COMBATLOG_OBJECT_SPECIAL_MASK) ~= 0 then
  4.         for i=1,8 do
  5.             mask = COMBATLOG_OBJECT_RAIDTARGET1 * (2 ^ (i - 1))
  6.             mark = bit.band(flags, mask) == mask
  7.             if mark then number = i break end
  8.         end
  9.     end
  10.     return number
  11. end

This will return a number from 1 to 8 corresponding to each mark, or nil if the target doesn't have a mark, see here for more information. However, if you are intent on using destGUID, I suppose you could do the following, assuming the unit you are checking is a player with a valid unitId:

Lua Code:
  1. local function GetRaidTargetIndexFromGUID(guid)
  2.     local name = select(6, GetPlayerInfoByGUID(guid)) -- Get the unit's name; works globally
  3.     local icon = GetRaidTargetIndex(name) -- Returns a number from 1 to 8, or nil
  4.     return icon
  5. end

daylesan 03-21-11 09:12 AM

Quote:

Originally Posted by oomp (Post 232488)
Don't use destGUID, use destFlags...

Lua Code:
  1. local function GetIconIndex(flags)
  2.     local number, mask, mark
  3.     if bit.band(flag, COMBATLOG_OBJECT_SPECIAL_MASK) ~= 0 then
  4.         for i=1,8 do
  5.             mask = COMBATLOG_OBJECT_RAIDTARGET1 * (2 ^ (i - 1))
  6.             mark = bit.band(flags, mask) == mask
  7.             if mark then number = i break end
  8.         end
  9.     end
  10.     return number
  11. end

This will return a number from 1 to 8 corresponding to each mark, or nil if the target doesn't have a mark, see here for more information. However, if you are intent on using destGUID, I suppose you could do the following, assuming the unit you are checking is a player with a valid unitId:

Thank you, that looks a lot cleaner than what I had in mind.

daylesan 03-21-11 11:32 AM

There's a small error: bit.band(flag, COMBATLOG_OBJECT_SPECIAL_MASK) should be bit.band(flags, COMBATLOG_OBJECT_SPECIAL_MASK)

Even after fixing that, the function always returns nil though. Here's the code for review

Lua Code:
  1. function ezInterrupt:COMBAT_LOG_EVENT_UNFILTERED(_,_,event,sourceGUID,_,_,_,destName,destFlags,spellID,_,_,extraID, ...)
  2.     if event == "SPELL_INTERRUPT" and (sourceGUID == UnitGUID("player") or sourceGUID == UnitGUID("pet")) then
  3.         local raidIconIndex = self:GetRaidIconIndex(destFlags)
  4.         print(tostring(raidIconIndex))
  5. -- cut off the rest of the code

and

Lua Code:
  1. function ezInterrupt:GetRaidIconIndex(flags)
  2.     local number, mask, mark
  3.     if bit.band(flags, COMBATLOG_OBJECT_SPECIAL_MASK) ~= 0 then
  4.         for i=1,8 do
  5.             mask = COMBATLOG_OBJECT_RAIDTARGET1 * (2 ^ (i - 1))
  6.             mark = bit.band(flags, mask) == mask
  7.             if mark then number = i break end
  8.         end
  9.     end
  10.     return number
  11. end

Vrul 03-21-11 03:04 PM

Combat log processing has the potential to be executed very frequently so I would suggest changing what you've posted to:
Code:

local bit_and = bit.band

local RaidIconMaskToIndex = {
        [COMBATLOG_OBJECT_RAIDTARGET1] = 1,
        [COMBATLOG_OBJECT_RAIDTARGET2] = 2,
        [COMBATLOG_OBJECT_RAIDTARGET3] = 3,
        [COMBATLOG_OBJECT_RAIDTARGET4] = 4,
        [COMBATLOG_OBJECT_RAIDTARGET5] = 5,
        [COMBATLOG_OBJECT_RAIDTARGET6] = 6,
        [COMBATLOG_OBJECT_RAIDTARGET7] = 7,
        [COMBATLOG_OBJECT_RAIDTARGET8] = 8
}

function ezInterrupt:COMBAT_LOG_EVENT_UNFILTERED(_, _, event, sourceGUID, _, sourceFlags, _, destName, destFlags, spellID, _, _, extraID, ...)
        if event == "SPELL_INTERRUPT" and bit_and(sourceFlags, COMBATLOG_OBJECT_AFFILIATION_MINE) then
                local raidIconIndex = RaidIconMaskToIndex[bit_and(destFlags, COMBATLOG_OBJECT_RAIDTARGET_MASK)]
                print(tostring(raidIconIndex))


daylesan 03-21-11 04:19 PM

Thanks for the tip Vrul.

I still can't get this to work though. print(tostring(raidIconIndex)) is nil no matter what code I try.

Vrul 03-21-11 06:51 PM

I just tested this and it appears you must be in a group or raid before the proper bits are set in sourceFlags and destFlags to indicate a raid icon is present. So get someone to group up with you when you need to test.

Also, in the code I posted above, change:
Code:

bit_and(sourceFlags, COMBATLOG_OBJECT_AFFILIATION_MINE)
to:
Code:

bit_and(sourceFlags, COMBATLOG_OBJECT_AFFILIATION_MINE) ~= 0

daylesan 03-22-11 03:18 AM

Quote:

I just tested this and it appears you must be in a group or raid before the proper bits are set in sourceFlags and destFlags to indicate a raid icon is present.
Mystery unraveled.

daylesan 03-22-11 05:47 AM

The raid icon is correctly recognized if present, but another problem appeared.

Once recognized, the raid icon is added to the destName string which is then processed into a message to be shown in a variety of ways depending on the user settings. The problem is that I can't find a way to insert the raid icon in a manner that works for both SendChatMessage() and ChatFrame:AddMessage().

Thus the question is: can raid icons be added in a format that works for both types of messages?

The following way works for ChatFrame:AddMessage() but results in a LUA error stating
Quote:

SendChatMessage(): Invalid escape code in chat message
LUA Code:
  1. RaidIconMaskToIcon = {
  2. [COMBATLOG_OBJECT_RAIDTARGET1] = format(TEXT_MODE_A_STRING_DEST_ICON, COMBATLOG_OBJECT_RAIDTARGET1, "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_1.blp:0|t"),
  3. -- etc
  4. }

While the following way works with SendChatMessage(), it doesn't work with ChatFrame:AddMessage() (the {rt1} will not be replaced by the actual icon texture).

LUA Code:
  1. RaidIconMaskToIcon = {
  2. [COMBATLOG_OBJECT_RAIDTARGET1] = "{rt1}",
  3. -- etc
  4. }



Relevant code for review:

LUA Code:
  1. local bit_and = bit.band
  2. local RaidIconMaskToIcon = {
  3.     [COMBATLOG_OBJECT_RAIDTARGET1] = format(TEXT_MODE_A_STRING_DEST_ICON, COMBATLOG_OBJECT_RAIDTARGET1, "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_1.blp:0|t"),
  4.     [COMBATLOG_OBJECT_RAIDTARGET2] = format(TEXT_MODE_A_STRING_DEST_ICON, COMBATLOG_OBJECT_RAIDTARGET2, "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_2.blp:0|t"),
  5.     [COMBATLOG_OBJECT_RAIDTARGET3] = format(TEXT_MODE_A_STRING_DEST_ICON, COMBATLOG_OBJECT_RAIDTARGET3, "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_3.blp:0|t"),
  6.     [COMBATLOG_OBJECT_RAIDTARGET4] = format(TEXT_MODE_A_STRING_DEST_ICON, COMBATLOG_OBJECT_RAIDTARGET4, "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_4.blp:0|t"),
  7.     [COMBATLOG_OBJECT_RAIDTARGET5] = format(TEXT_MODE_A_STRING_DEST_ICON, COMBATLOG_OBJECT_RAIDTARGET5, "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_5.blp:0|t"),
  8.     [COMBATLOG_OBJECT_RAIDTARGET6] = format(TEXT_MODE_A_STRING_DEST_ICON, COMBATLOG_OBJECT_RAIDTARGET6, "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_6.blp:0|t"),
  9.     [COMBATLOG_OBJECT_RAIDTARGET7] = format(TEXT_MODE_A_STRING_DEST_ICON, COMBATLOG_OBJECT_RAIDTARGET7, "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_7.blp:0|t"),
  10.     [COMBATLOG_OBJECT_RAIDTARGET8] = format(TEXT_MODE_A_STRING_DEST_ICON, COMBATLOG_OBJECT_RAIDTARGET8, "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_8.blp:0|t")
  11. }
  12. local msgTags = {}
  13.  
  14. function ezInterrupt:COMBAT_LOG_EVENT_UNFILTERED(_,_,event,sourceGUID,_,sourceFlags,_,destName,destFlags,spellID,_,_,extraID, ...)
  15.     if event == "SPELL_INTERRUPT" and bit_and(sourceFlags, COMBATLOG_OBJECT_AFFILIATION_MINE) ~= 0 then
  16.         local raidIcon = RaidIconMaskToIcon[bit_and(destFlags, COMBATLOG_OBJECT_RAIDTARGET_MASK)]
  17.         if raidIcon then destName = string.format("%s%s", raidIcon, destName) end
  18.         msgTags["[spell]"] = GetSpellLink(extraID)
  19.         msgTags["[target]"] = destName
  20.         msgTags["[interrupt]"] = GetSpellLink(spellID) 
  21.         local msg = string.gsub(self.db.profile.customMessage, "%[%a+%]", msgTags)
  22.         if self.db.profile.enableWhispering and self.db.profile.whisperTarget ~= nil then SendChatMessage(msg, "WHISPER", nil, self.db.profile.whisperTarget ) end
  23.         if self.db.profile.enableCustomChannel and self.db.profile.customChannel ~= nil then SendChatMessage(msg, "CHANNEL", nil, self.db.profile.customChannel ) end  
  24.         if self.db.profile.enableSystemMessage then LAST_ACTIVE_CHAT_EDIT_BOX:GetParent():AddMessage(msg) end
  25.         if outputChannel then SendChatMessage(msg, outputChannel) end
  26.     end
  27. end

For clarity
self.db.profile.customMessage = "Interrupted [target]'s [spell] with [interrupt]"
outputChannel is either "SAY" "PARTY" "RAID" or false


All times are GMT -6. The time now is 05:55 PM.

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