Thread Tools Display Modes
11-25-12, 06:06 PM   #1
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Best way to determine who killed me

Hi all,
I'd like to improve my ganklist addon to offer the possibility to show a frame with the name of the char that killed you to easily add to the db.

So I begin to study a little bit the combat log.

The best way I found to determine who killed me is something like this pseudo sample code:


Lua Code:
  1. --- other code above
  2. local playerName = UnitName("player");
  3. local type = ""
  4. local typeMask = 0x00F
  5.  
  6. local function eventHandler_cleu(self, event, ...)
  7.     local timeStamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, prefixParam1, prefixParam2, dummyparam, suffixParam1, suffixParam2 = ...
  8.        
  9.         -- bit.band(tonumber(sourceGUID:sub(1,5)),typeMask) = 0 Player, 3-4 NPC
  10.  
  11.         if destName == playerName and bit.band(tonumber(sourceGUID:sub(1,5)),typeMask) == 0 and (event == "SPELL_DAMAGE" or event == "SPELL_PERIODIC_DAMAGE" or event == "RANGE_DAMAGE") and suffixParam2 > 0  then
  12.             print(type .. " ["..sourceName.."] killed ["..destName.."] with "..suffixParam1.." damage of ".. GetSpellLink(prefixParam1) .. " overkill " .. suffixParam2)   
  13.         elseif destName == playerName and bit.band(tonumber(sourceGUID:sub(1,5)),typeMask) == 0 and event == "SWING_DAMAGE" and prefixParam2 > 0 then
  14.             print(type .." ["..sourceName.."] killed ["..destName.."] with "..prefixParam1.." Melee, overkill " .. suffixParam2 )
  15.         end        
  16.        
  17.         -- a sample line when an enemy player killed me
  18.         -- [name] killed [me] with 65762 damage of [Combustione dell'Ombra] overkill 48472
  19.     end
  20.  
  21.  
  22. local frame_cleu = CreateFrame("FRAME", "remgankframe_cleu")
  23. frame_cleu:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
  24. frame_cleu:SetScript("OnEvent", eventHandler_cleu)
  25.  
  26. --- other code not show...


Some questions now:

1) As noted in another thread the UNIT_DIED subevent not contain all the information about the src of the damage so I think I can't use it. So is this the best way ( check the overkill ) ?

2) May I use the CLE not CLEU ? I have not understand so much the differences but if in the first there are only events related to me probably is more efficent than the second and for what I need is the same.

3) I am a little bit scared about the so many conditions to parsing of the die event ... if it is my name related (destName), if I am not in a bg/arena, if the srcName is a Player, if this player is an Enemy (this could be omitted I think), if the there is an overkill so I am died by spell or it was a melee ... etc :-) . But I think I can't summarize them all :-)

Thanks all for attention.
  Reply With Quote
11-25-12, 10:16 PM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
You could use COMBAT_LOG_EVENT instead of COMBAT_LOG_EVENT_UNFILTERED, but only if your combat log is currently set to display the events you need. This means that if you switch to a combat log filter that only shows your actions, for example, your addon would stop working. You also can't guarantee that other people will have their filters set correctly. For these reasons (mainly the second) you should always use CLEU over CLE for addons you plan to release to the public.

Also, there's no need to use string.sub and tonumber on the GUID; just use bit.band on the whole GUID and compare it to the COMBATLOG_OBJECT_CONTROL_PLAYER global (0x00000100). This will save you 2 function calls and one string creation.

Here's a drycoded example with a few other minor changes:

Code:
-- For general use, I wouldn't recommend obsessively upvaluing every
-- global but it is worth doing for situations like CLEU or OnUpdate
-- where you are accessing them extremely often.
local bit_band = bit.band
local COMBATLOG_OBJECT_CONTROL_PLAYER = COMBATLOG_OBJECT_CONTROL_PLAYER

-- GUIDs are not available when the main chunk executes, so you have to
-- wait and fill this in once the combat log starts running.
local playerGUID

local frame_cleu = CreateFrame("FRAME", "remgankframe_cleu")
frame_cleu:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")

-- There's no need to define your event handler function separately and
-- then set it as the OnEvent script. You can just define the function
-- right in the SetScript call.
frame_cleu:SetScript("OnEvent", function(self, event, timeStamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, prefixParam1, prefixParam2, dummyparam, suffixParam1, suffixParam2)
	-- Fill in the playerGUID variable here if needed.
	if not playerGUID then
		playerGUID = UnitGUID("player")
	end

	-- Since these first two conditions apply no matter which event is
	-- firing, check them first.
	if destGUID == playerGUID and bit_band(sourceGUID, COMBATLOG_OBJECT_CONTROL_PLAYER) == COMBATLOG_OBJECT_CONTROL_PLAYER then
		if event == "SWING_DAMAGE" then
			-- Nest checks inside each other instead of using and, so
			-- that if any check matches (eg. it is this event, but not
			-- the right prefix) the code doesn't keep checking other
			-- things that obviously can never match.
			if prefixParam2 > 0 then
				print(string_format("[%s] killed [%s] with %s Melee overkill %s", sourceName, destName, prefixParam1, suffixParam2))
			end
		elseif event == "SPELL_DAMAGE" or event == "SPELL_PERIODIC_DAMAGE" or event == "RANGE_DAMAGE" then
			if suffixParam2 > 0 then
				print(string_format("[%s] killed [%s] with %s damage of %s overkill %s", sourceName, destName, suffixParam1, GetSpellLink(prefixParam1), suffixParam2))
			end
		end
	end

	-- a sample line when an enemy player killed me
	-- [name] killed [me] with 65762 damage of [Combustione dell'Ombra] overkill 48472
end)
I also don't know what you were using the type variable for (since it was always set to an empty string) and it's generally a bad idea to use local variables with the same names as global functions or variables (the type function tells you whether a value is a string, number, table, etc.) so I just deleted it.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
11-26-12, 01:28 AM   #3
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Originally Posted by Phanx View Post

Also, there's no need to use string.sub and tonumber on the GUID; just use bit.band on the whole GUID and compare it to the COMBATLOG_OBJECT_CONTROL_PLAYER global (0x00000100). This will save you 2 function calls and one string creation.
Yes, every day I'll learn something new :-)
Probably I also seen these globals during googling/wowiki/wowpedia and the book but I was unable how to use them with proficency.

I also don't know what you were using the type variable for (since it was always set to an empty string) and it's generally a bad idea to use local variables with the same names as global functions or variables (the type function tells you whether a value is a string, number, table, etc.) so I just deleted it.
this was a "read and rewrite" from a book :-) and it was used to define type = NPC, Player etc etc ... I didn't think to the global impact of the thing and used the same variable name I found. Now I'll take more care in the future for the variable name.

A thing which I didn't understand so well in your code is the defining as local of:


Lua Code:
  1. -- For general use, I wouldn't recommend obsessively upvaluing every
  2. -- global but it is worth doing for situations like CLEU or OnUpdate
  3. -- where you are accessing them extremely often.
  4. local bit_band = bit.band
  5. local COMBATLOG_OBJECT_CONTROL_PLAYER = COMBATLOG_OBJECT_CONTROL_PLAYER

1) Defining a lua function (bit.band) as local is better than use it as is ?
2) Defining local to this addon the global constant for the controller type. Is it better and faster than using as is ?


Last question:

Lua Code:
  1. frame_cleu:SetScript("OnEvent", function(self, event,
  2.  
  3. --- etc etc

could be evaluated depending of a condition or a variable name ?

Something like (I am writing on the fly so be kind about my errors in the replies :-) :

Lua Code:
  1. if not UnitInBattleground("player") or not IsActiveBattlefieldArena() then
  2.        
  3.          frame_cleu:SetScript("OnEvent", function(self, event,
  4.  
  5.          --- etc etc
  6.  
  7. end

Thanks again for everything.
  Reply With Quote
11-26-12, 08:51 AM   #4
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by gmarco View Post
1) Defining a lua function (bit.band) as local is better than use it as is ?
local bit_band = bit.band
... simply creates a local shortcut named "bit_band" that points to the global "bit.band" function. It doesn't replace or change the function in any way. It just makes it faster to access it.

Imagine the global namespace as a book, and yourself as a reader with absolutely no short-term memory. Every time you ask for "bit.band" you have to go through the whole book to find it. Creating a local shortcut -- this is called an "upvalue" -- is like putting a sticky note on the page, so instead of having to look through the thousands of pages in the book (at the moment there are 49,080 objects in my global namespace) you only have to look at the few sticky notes sticking out of the side. Much faster.

Plus, "bit.band" is actually two lookups -- one global lookup to find "bit", and then a table lookup inside "bit" to find "band". So creating the "bit_band" upvalue is even faster in this case.

Originally Posted by gmarco View Post
2) Defining local to this addon the global constant for the controller type. Is it better and faster than using as is ?
As far as the game is concerned, looking up a function in the global namespace is exactly the same as looking up a string, table, or other kind of value. It doesn't know what kind of value it is until it's found it. Going back to the book analogy, you know you're looking for a page entitled "COMBATLOG_OBJECT_CONTROL_PLAYER" but until you find the page, you have no idea what information is on that page, or even what kind of information is on that page.

Now, despite all of this, I wouldn't suggest creating local upvalues for every global thing you access in your addon. Only do it for things you access very frequently, like in an OnUpdate script, or in response to events like CLEU that fire very often. For infrequently accessed globals, the speed doesn't matter, so creating upvalues just adds clutter to your code. Also, upvalues will always point to the original value, so if someone comes along and overwrites the global "bit.band" with a new function, your upvalue will still point to the original function, not the new one. Obviously nobody is (or should be) overwriting "bit.band" but this is another argument against upvaluing everything all the time. Also, there is a limit on the number of locals that can be in scope at once; I don't remember what it is, and you probably won't ever hit it in normal use, but you might if you go wild with upvalues.

Originally Posted by gmarco View Post
Code:
if not UnitInBattleground("player") or not IsActiveBattlefieldArena() then 
        frame_cleu:SetScript("OnEvent", function(self, event, 
         --- etc etc 
end
That is valid Lua code, but it won't work the way you're imagining. That code will cause your frame to only respond to events if you are outside of a battleground or arena when the addon first loads, and it won't detect when you enter or leave one and change the script.

If you want to ignore events that occur inside a battleground or arena, you should register for the event that fires when you change zones, and register/unregister CLEU as needed depending on what kind of zone you're in:

Code:
-- Don't register CLEU here!
frame_cleu:RegisterEvent("ZONE_CHANGED_NEW_AREA")

frame_cleu:SetScript("OnEvent", function(self, event, ...)
     if event == "ZONE_CHANGED_NEW_AREA" then
          local _, instanceType = IsInInstance()
          if instanceType == "arena" or instanceType == "pvp" or (instanceType == "none" and GetZonePVPInfo() == "combat") then
               -- arena is, obviously, an arena.
               -- pvp is a battleground.
               -- none with GetZonePVPInfo() == "combat" is an outdoor PvP zone like Wintergrasp.
               self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
          else
               -- If not in a pvp zone, register CLEU:
               self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
          end
          return
     end

     local timeStamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, prefixParam1, prefixParam2, dummyparam, suffixParam1, suffixParam2 = ...

     -- proceed with CLEU handling
end)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 11-26-12 at 09:00 AM.
  Reply With Quote
11-26-12, 11:27 AM   #5
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Originally Posted by Phanx View Post
local bit_band = bit.band
... simply creates a local shortcut named "bit_band" that points to the global "bit.band" function. It doesn't replace or change the function in any way. It just makes it faster to access it.

Imagine the global namespace as a book, and yourself as a reader with absolutely no short-term memory. Every time you ask for "bit.band" you have to go through the whole book to find it. Creating a local shortcut -- this is called an "upvalue" -- is like putting a sticky note on the page, so instead of having to look through the thousands of pages in the book (at the moment there are 49,080 objects in my global namespace) you only have to look at the few sticky notes sticking out of the side. Much faster.

Plus, "bit.band" is actually two lookups -- one global lookup to find "bit", and then a table lookup inside "bit" to find "band". So creating the "bit_band" upvalue is even faster in this case.



As far as the game is concerned, looking up a function in the global namespace is exactly the same as looking up a string, table, or other kind of value. It doesn't know what kind of value it is until it's found it. Going back to the book analogy, you know you're looking for a page entitled "COMBATLOG_OBJECT_CONTROL_PLAYER" but until you find the page, you have no idea what information is on that page, or even what kind of information is on that page.

Now, despite all of this, I wouldn't suggest creating local upvalues for every global thing you access in your addon. Only do it for things you access very frequently, like in an OnUpdate script, or in response to events like CLEU that fire very often. For infrequently accessed globals, the speed doesn't matter, so creating upvalues just adds clutter to your code. Also, upvalues will always point to the original value, so if someone comes along and overwrites the global "bit.band" with a new function, your upvalue will still point to the original function, not the new one. Obviously nobody is (or should be) overwriting "bit.band" but this is another argument against upvaluing everything all the time. Also, there is a limit on the number of locals that can be in scope at once; I don't remember what it is, and you probably won't ever hit it in normal use, but you might if you go wild with upvalues.



That is valid Lua code, but it won't work the way you're imagining. That code will cause your frame to only respond to events if you are outside of a battleground or arena when the addon first loads, and it won't detect when you enter or leave one and change the script.

If you want to ignore events that occur inside a battleground or arena, you should register for the event that fires when you change zones, and register/unregister CLEU as needed depending on what kind of zone you're in:

Code:
-- Don't register CLEU here!
frame_cleu:RegisterEvent("ZONE_CHANGED_NEW_AREA")

frame_cleu:SetScript("OnEvent", function(self, event, ...)
     if event == "ZONE_CHANGED_NEW_AREA" then
          local _, instanceType = IsInInstance()
          if instanceType == "arena" or instanceType == "pvp" or (instanceType == "none" and GetZonePVPInfo() == "combat") then
               -- arena is, obviously, an arena.
               -- pvp is a battleground.
               -- none with GetZonePVPInfo() == "combat" is an outdoor PvP zone like Wintergrasp.
               self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
          else
               -- If not in a pvp zone, register CLEU:
               self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
          end
          return
     end

     local timeStamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, prefixParam1, prefixParam2, dummyparam, suffixParam1, suffixParam2 = ...

     -- proceed with CLEU handling
end)

Hi Phanx,
thanks so much for your kind reply.

I always don't like to quote everything in a reply but I think your reply is a masterpice and should be sticky somewhere in the LUA forum.

Finally I begin to understand how things move inside addons and the game itself.

Thanks again.
  Reply With Quote
11-26-12, 05:56 PM   #6
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
There is some more discussion on the topic here:

http://www.wowinterface.com/forums/s...ad.php?t=43658

(More book analogies for you. )
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
11-27-12, 01:22 AM   #7
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Thanks for the very interesting thread Phanx.

Lua and Lua in WoW is for me a so different approach that I usually spend hours trying to do so simple things that I usually do in other languages in a few minutes. But I like it and so every input is more than welcome !!! :-)

Returning on your code above, I check it better and I though a thing. If you log in a zone and NOT change it the CLEU never be triggered because it was not registered. So perhaps is it better if we register it by default and then UNregister it if we enter in a pvp area ?

And if you log in a pvp area (like wintergrasp) you are unlucky :-) (probably I should check also ZONE_CHANGED also ???)

Thanks again for your time.
  Reply With Quote
11-27-12, 01:36 AM   #8
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
What about this ?

It is not so beautifull but when you login you move and walk a little bit it should trigger :-)


Lua Code:
  1. local frame_cleu = CreateFrame("FRAME", "remgankframe_cleu");
  2.  
  3. -- Don't register CLEU here!
  4. frame_cleu:RegisterEvent("ZONE_CHANGED_NEW_AREA")
  5. frame_cleu:RegisterEvent("ZONE_CHANGED")
  6.  
  7. frame_cleu:SetScript("OnEvent", function(self, event, ...)
  8.    
  9.     print ( prgname .. " : " .. event)
  10.    
  11.     if event == "ZONE_CHANGED_NEW_AREA" or event == "ZONE_CHANGED" then
  12.    
  13.         local _, instanceType = IsInInstance()
  14.        
  15.         if instanceType == "arena" or instanceType == "pvp" or (instanceType == "none" and GetZonePVPInfo() == "combat") then
  16.  
  17.  
  18. --- code continues as above


If you login and don't move it doesn't trigger but in this case you want stress the poor programmer :-)


P.s
I have also add the line:
local string_format = string.format
to "upvalued" also the declared string_format (local of string.format) function I presume.

Last edited by gmarco : 11-27-12 at 02:10 AM.
  Reply With Quote
11-27-12, 03:43 AM   #9
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Instead of ZONE_CHANGED, use PLAYER_ENTERING_WORLD. This will fire both when you first enter the world (no matter what kind of zone you're in) and whenever you pass through a loading screen.

Also (I might have mentioned this in one of your other threads) semicolons at the end of lines are not needed in Lua. They can technically avoid issues with ambiguous syntax, but I've been writing WoW addons in Lua for about 7 years now and have never even seen any code where a semicolon was needed to clarify the syntax, so unless you're dead-set on using them as a carry-over from some other programming language you're used to working with, I'd suggest leaving them out to reduce clutter in your code.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 11-27-12 at 03:46 AM.
  Reply With Quote
11-28-12, 01:18 AM   #10
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Hi Phanx,

Thanks so much for your helps again. I used the PLAYER_ENTERING_WORLD event and everything is fine now. I can be killed everytime and everywhere now :-)

I removed also every ";" :-) that I put in my code or because I have habits to use them or because when I am doing copy and paste sometime I get them too :-)

Now I have add also an input frame, very simple that should be fired when you are killed or you use the hidden cmd switch "debugaddframe" . It will show the "killer" and let you choose to input a custom note for adding in the DB.

I have learn that adding frames in lua is a long work... So I'd like to ask what is the better way to add frame ? Simple things, like a scroll lists and some input editbox. Continue to write them in lua or try to use xml ? ACE ?

... and to code them ? I am usually "vi" addicted but this time I think I'd use happily something that automagically generate code of the frame :-)

But I think I have to continue to use vi because all the things I have tried are outdated or simply crash on my win7-64 or my mac :-)
Attached Files
File Type: zip remgank-0.3.zip (3.3 KB, 522 views)

Last edited by gmarco : 11-28-12 at 01:21 AM.
  Reply With Quote
11-28-12, 05:40 AM   #11
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Years ago, there were several programs available for "automatically" generating XML code from a visual GUI, but none of them ever worked very well -- think "HTML code generated by MS Word in 2002 -- and none of them have been updated in a very long time, so they are not up to date with the current WoW API. Long story short, you shouldn't use them.

Anyway, I wrote up a (fairly) simple addon with a scrolling list frame for someone on the WowAce forums a while ago. If you ignore all the code related to looting and item icons and such, the rest should be relatively easy to understand and adapt:

http://forums.wowace.com/showthread.php?p=320619

You'd also want to modify the click handler to add an editing function, in addition to the current deleting function.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
11-28-12, 06:16 PM   #12
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Downloaded the sandbox2 addon... I am checking it ...

And I continue with my infinite number of questions

Lua Code:
  1. local bit_band = bit.band
  2. local COMBATLOG_OBJECT_CONTROL_PLAYER = COMBATLOG_OBJECT_CONTROL_PLAYER
  3.  
  4. -- code
  5.  
  6. if destGUID == playerGUID and bit_band(sourceGUID, COMBATLOG_OBJECT_CONTROL_PLAYER) == COMBATLOG_OBJECT_CONTROL_PLAYER then
  7.  
  8. -- code


if possible that this "if" is true also for raid bosses (the second condition) ? My guild raid mates continued to be prompted by RemGank that want to add bosses name as a possible gankers after a wipe :-)

Thanks :-)
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
11-28-12, 08:35 PM   #13
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Try changing this:

Code:
bit_band(sourceGUID, COMBATLOG_OBJECT_CONTROL_PLAYER) == COMBATLOG_OBJECT_CONTROL_PLAYER
to this:

Code:
bit_band(sourceGUID, COMBATLOG_OBJECT_CONTROL_PLAYER) ~= 0
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
11-29-12, 02:36 PM   #14
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
It doesn't work either.

I have read here and there and I found something:

All entities in World of Warcraft are identified by a unique 64-bit number; generally presented as a string containing a hexadecimal representation of the number (e.g. "0xF530007EAC083004"). (Note that Lua in WoW does not support 64-bit integers, so this value cannot be converted with tonumber.)

The type of unit represented by a GUID can be determined by using bit.band() to mask the first three digits with 0x00F: - 0x000 - A player - 0x003 - An NPC - 0x004 - A player's pet (i.e. hunter/warlock pets and similar; non-combat pets count as NPCs) - 0x005 - A vehicle
In this way it seems to work. But as Phanx said it is quite expensive. Is there a better way to do this ?

local bit_band = bit.band
-- code
if destGUID == playerGUID and bit_band(tonumber(sourceGUID:sub(1,5)),0x00F) == 0 then
instead the code:
bit_band(sourceGUID, COMBATLOG_OBJECT_CONTROL_PLAYER)
always return me 256 with players or npcs.

Thanks very much for attention and patience.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.

Last edited by gmarco : 11-29-12 at 06:24 PM.
  Reply With Quote
12-02-12, 09:22 PM   #15
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
This will return whether a guid is a player.. tonumber(sourceGUID:sub(5,5), 16) % 8 == 0

You could probably get away with just this: sourceGUID:sub(5,5) == '8'

You can use this to test it in-game..
Lua Code:
  1. /run print((UnitGUID('target')):sub(5,5) == '8')

Last edited by semlar : 12-02-12 at 09:29 PM.
  Reply With Quote
12-02-12, 10:14 PM   #16
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Actually, looking at this again, I realize I'm an idiot, and you should be using sourceFlags instead of sourceGUID in the bit.band with COMBATLOG_OBJECT_CONTROL_PLAYER. >_<
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
12-02-12, 10:29 PM   #17
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Yeah I was kind of wondering about that..

But you can get the unit type from the guid anyway, so that should work.
  Reply With Quote
12-03-12, 03:36 PM   #18
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
You can't get the reaction, though.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
12-03-12, 05:23 PM   #19
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Yeah, but if they killed you then you can infer that they were hostile (nevermind).

If you want to check if they're mind controlled you'd have to do something else.

I guess it could be friendly fire, so you should probably check the flags anyway.

I think a mind controlled player would be flagged as a hostile pet.

Last edited by semlar : 12-03-12 at 05:44 PM.
  Reply With Quote
12-03-12, 06:06 PM   #20
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Don't forget friendly fire. If you've already got the sourceFlags, though, it's just easier to check those than to try to account for a bunch of special exceptions, since that's exactly what they're there for. Try this:

Code:
local HOSTILE_PLAYER = bit_bor(COMBATLOG_OBJECT_REACTION_HOSTILE, COMBATLOG_OBJECT_CONTROL_PLAYER)

if bit_band(sourceFlags, HOSTILE_PLAYER) ~= 0 then
    -- source is a hostile player
end
You can find a complete list of combat log bitmasks here:
http://wow.go-hero.net/framexml/16309/Constants.lua#374
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 12-04-12 at 11:27 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Best way to determine who killed me

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