Thread Tools Display Modes
10-26-10, 12:37 PM   #1
Obivous
A Murloc Raider
Join Date: Oct 2010
Posts: 9
Handling combat log

Hi folks.

I'm a rookie in Addon development and am currently working on an addon to detect any enemy player according to the combat log. The main use would be in arenas, battlegrounds (for stealthed players, most probably) and also during raids on other main cities.

I've been reading the WowWiki for hours and I think I understood most of the stuff they give out but have one major question :
Is the rogue ability Stealth considered as an aura, or a spell ? If it is handeld as a spell, I guess the target is the source, or nil. Is it A SPELL_DAMAGE ?

Secondly, I have started some LUA code and I was wondering if it would work as expected. I'm a bit messed up with handling events though, so here is the source.

Code:
local frame = createFrame("Frame", "CombatLogHandler_Obi");

frame:SetFrameStrata("BACKGROUND");
frame:SetWidth(0);
frame:SetHeight(0);

-- Registering event. It fires every combat log modification
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");

function EventHandler(self, event, ...)
	-- First, check if player is in sanctuary (IE Dalaran)
	if (PlayerIsInSanctuary()) then
		-- Do nothing [Yes I know it's crap]
	else
		if (event == "COMBAT_LOG_EVENT_UNFILTERED") then
			-- Ok so we have a new entry in the combat log
			local timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags = select(1, ...);
			-- What interests us is the sourceFlag, sourceName, destName, and destFlag.
			-- For instance, if the origin is an adversary player, like a rogue, and the target a friend or not
			local isMatch = CombatLog_Object_IsA(sourceFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS);
			if (isMatch == 1) then
				-- This is a hostile !
				-- Now we have to handle the whole bunch of different log events
				if (type == "SPELL_DAMAGE") then
					-- This is a spell. Let's get its DB ID.
					local spellId, spellName, spellSchool, damageDealt = select(9, ...);
					DEFAULT_CHAT_FRAME:AddMessage(sourceName.." lance «"..spellName.."» sur "..destName.." ["..damageDealt.." dégâts de "..spellSchool.."]");
				end
			else
				-- Non hostile. May be player, NPC, or whatever
				DEFAULT_CHAT_FRAME:AddMessage("Évènement non hostile. (Débuggeur)");
			end
		end
	end
end

function PlayerIsInSanctuary()
    local pvpType, nil, nil = GetZonePVPInfo();
    if (pvpType == "sanctuary") then
        return(true);
    else
        return(false);
    end
end

function InInstance()
	local inInstance, instanceType = IsInInstance()
	if inInstance == nil then 
		return(false); 
	else 
		return(true); 
	end  
end
I did not attach the EventHandler() function to the frame yet.

As you can see I'm french (Hope my English is not too bad by the way). Coming from this I have another question : Do I correctly check whether the source is and hostile ? I know I can use the sourceFlag but I did not understand anything on the unitFlag WowWiki page.

Any help, remarks, explanations will be greatly appreciated. Thanks in advance and have a nice day.

Last edited by Obivous : 10-26-10 at 03:05 PM.
  Reply With Quote
10-26-10, 03:41 PM   #2
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
Some tips:

lua Code:
  1. function InSanctuary()
  2.     return GetZonePVPInfo() == "sanctuary" -- a bit more efficient, use it like "if InSanctuary() then" or "if not InSanctuary() then" for the opposite
  3. end
  4.  
  5. function InInstance()
  6.     return IsInInstance() -- in other words you can just use "if IsInInstance() then" or "if not IsInInstance() then" for the opposite -instead of making an alias function ;)
  7. end
  8.  
  9. function EventHandler(self, event, ...)
  10.     if not GetZonePVPInfo() == "sanctuary" and event == "COMBAT_LOG_EVENT_UNFILTERED" then
  11.         local timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, damageDealt = ...
  12.         local isMatch = CombatLog_Object_IsA(sourceFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS)
  13.         if isMatch then
  14.             if bit.band(sourceFlags, COMBATLOG_OBJECT_REACTION_HOSTILE) > 0 then -- if the target is hostile
  15.                 DEFAULT_CHAT_FRAME:AddMessage(sourceName.." lance «"..spellName.."» sur "..destName.." ["..damageDealt.." dégâts de "..spellSchool.."]")
  16.             end
  17.         else
  18.             DEFAULT_CHAT_FRAME:AddMessage("Évènement non hostile. (Débuggeur)")
  19.         end
  20.     end
  21. end
  Reply With Quote
10-26-10, 04:19 PM   #3
Obivous
A Murloc Raider
Join Date: Oct 2010
Posts: 9
Originally Posted by Vladinator View Post
Some tips:

lua Code:
  1. function InSanctuary()
  2.     return GetZonePVPInfo() == "sanctuary" -- a bit more efficient, use it like "if InSanctuary() then" or "if not InSanctuary() then" for the opposite
  3. end
  4.  
  5. function InInstance()
  6.     return IsInInstance() -- in other words you can just use "if IsInInstance() then" or "if not IsInInstance() then" for the opposite -instead of making an alias function ;)
  7. end
  8.  
  9. function EventHandler(self, event, ...)
  10.     if not GetZonePVPInfo() == "sanctuary" and event == "COMBAT_LOG_EVENT_UNFILTERED" then
  11.         local timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, damageDealt = ...
  12.         local isMatch = CombatLog_Object_IsA(sourceFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS)
  13.         if isMatch then
  14.             if bit.band(sourceFlags, COMBATLOG_OBJECT_REACTION_HOSTILE) > 0 then -- if the target is hostile
  15.                 DEFAULT_CHAT_FRAME:AddMessage(sourceName.." lance «"..spellName.."» sur "..destName.." ["..damageDealt.." dégâts de "..spellSchool.."]")
  16.             end
  17.         else
  18.             DEFAULT_CHAT_FRAME:AddMessage("Évènement non hostile. (Débuggeur)")
  19.         end
  20.     end
  21. end
Thanks, I think I've pretty much understood what you gave me. Now I simply need to find how to handle spells
Btw I'll dig about bit.band.
  Reply With Quote
10-26-10, 05:07 PM   #4
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
The flags are hex numbers, what bit.band does is that it checks a specific digit and if the specific bit position in the number is marked or not. It's hard to explain, look at:
1. http://www.wowpedia.org/UnitFlag
2. http://www.wowpedia.org/Lua_functions#Bit_Functions

For the user end we can use constant variables that substitute numbers -lucky ey? :P
  Reply With Quote
10-26-10, 05:27 PM   #5
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,327
It might also be a good idea to check destination info too, in case a friendly debuff is applied or fades from a hostile player or a hostile player is attacked by a friendly one.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
10-26-10, 05:59 PM   #6
Obivous
A Murloc Raider
Join Date: Oct 2010
Posts: 9
Originally Posted by SDPhantom View Post
It might also be a good idea to check destination info too, in case a friendly debuff is applied or fades from a hostile player or a hostile player is attacked by a friendly one.
That's exactly what I planned

Originally Posted by Vladinator View Post
The flags are hex numbers, what bit.band does is that it checks a specific digit and if the specific bit position in the number is marked or not. It's hard to explain, look at:
1. http://www.wowpedia.org/UnitFlag
2. http://www.wowpedia.org/Lua_functions#Bit_Functions

For the user end we can use constant variables that substitute numbers -lucky ey? :P
Thanks for the wowpedia links, those were the pages where I didn't understand anything I think I'll read over again and make some trys.

Last edited by Obivous : 10-26-10 at 06:35 PM.
  Reply With Quote
10-26-10, 08:29 PM   #7
Obivous
A Murloc Raider
Join Date: Oct 2010
Posts: 9
Okay, so I have come with some sourcecode I expected to work, but obviously it doesn,t since I tested it.

lua Code:
  1. local frame = createFrame("Frame", "CombatLogHandler_Obi");
  2.  
  3. frame:SetFrameStrata("BACKGROUND");
  4. frame:SetWidth(0);
  5. frame:SetHeight(0);
  6.  
  7. -- Registering event. It fires every combat log modification
  8. frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
  9.  
  10. -- Assigning the function ...
  11. frame:SetScript("OnEvent", EventHandler);
  12.  
  13. -- Thanks Vladinator for the improvement
  14. function InSanctuary()
  15.     return GetZonePVPInfo() == "sanctuary";
  16. end
  17.      
  18. function InInstance()
  19.     return IsInInstance()
  20. end
  21.  
  22. -- The fun part ...
  23. function EventHandler(self, event, ...)
  24.     if not InSanctuary() and event == "COMBAT_LOG_EVENT_UNFILTERED" then
  25.         local timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, spellSchool, damageDealt = ...;
  26.         local isMatch = CombatLog_Object_IsA(sourceFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS);
  27.         if isMatch then
  28.             -- Is origin hostile ?
  29.             if bit.band(sourceFlags, COMBATLOG_OBJECT_REACTION_HOSTILE) > 0 then
  30.                 -- DEFAULT_CHAT_FRAME:AddMessage(sourceName.." lance «"..spellName.."» sur "..destName.." ["..damageDealt.." dégâts de "..spellSchool.."]");
  31.                
  32.                 local channel = "CHANNEL";
  33.                 -- To which channel do we send that ?
  34.                 if UnitInParty("player") then
  35.                     channel = "PARTY";
  36.                 end
  37.                
  38.                 if UnitInRaid("player") then
  39.                     channel = "RAID";
  40.                     if IsRaidLeader() then
  41.                         channel = "RAID_WARNING";
  42.                     end
  43.                 end
  44.                
  45.                 -- Is destination hostile ?
  46.                 if bit.band(destFlags, COMBATLOG_OBJECT_REACTION_HOSTILE) > 0 then
  47.                     -- Hostile on hostile
  48.                     if not channel == "CHANNEL" then
  49.                         SendChatMessage(sourceName.." lance "..spellName.." sur "..destName, channel, nil, "1");
  50.                     end
  51.                     DEFAULT_CHAT_FRAME:AddMessage("|cffff0000"..sourceName.."|r lance |cff0077ff"..spellName.."|r sur |cffff0000"..destName.."|r");
  52.                 else
  53.                     -- Hostile on friendly
  54.                     if not channel == "CHANNEL" then
  55.                         SendChatMessage(sourceName.." lance "..spellName.." sur "..destName, channel, nil, "1");
  56.                     end
  57.                     DEFAULT_CHAT_FRAME:AddMessage("|cffff0000"..sourceName.."|r lance |cff0077ff"..spellName.."|r sur |cff33aa00"..destName.."|r" );
  58.                 end
  59.             end
  60.         else
  61.             -- DEFAULT_CHAT_FRAME:AddMessage("Évènement non hostile. (Débuggeur)");
  62.         end
  63.     end
  64. end

Lines 42 and 46 are juste not to spam the /1 Channel. This was just for test, I will limit the detection to certain spells ... But it doesn't work. Is it because the event doesn't « fire » in my frame ? I must say I'm lost.

Thanks in advance.

Last edited by Obivous : 10-26-10 at 11:17 PM.
  Reply With Quote
10-27-10, 12:42 AM   #8
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,327
Put the function definition above the code that sets the OnEvent handler. The way the code is now, it's setting the handler to nil, which completely disables the handler since the function doesn't exist yet.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
10-27-10, 02:55 AM   #9
Xubera
A Cobalt Mageweaver
 
Xubera's Avatar
AddOn Author - Click to view addons
Join Date: May 2009
Posts: 207
for Stealth, it would probably be
SPELL_AURA_APPLIED

or just SPELL_CAST_SUCCESS ill see

/run local frame = CreateFrame("Frame") frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") frame:SetScript("OnEvent", function(self,...) print(...) end)

outputs when i go stealth

COMBAT_LOG_EVENT_UNFILTERED timestamp SPELL_AURA_APPLIED sourceGUID sourceName sourceFlags destGUID destName destFlags 1784 Stealth 1 BUFF
COMBAT_LOG_EVENT_UNFILTERED timestamp SPELL_CAST_SUCCESS sourceGUID sourceName sourceFlags destGUID destName destFlags 1784 Stealth 1 BUFF
__________________
Chat Consolidate is the solution to any out of control trade chat. Ignore lines, throttle chat, consolidate posts!Follow the link to find out how!

▲ ▲ WoWInterface wont let me triforce >.>

Last edited by Xubera : 10-27-10 at 03:02 AM.
  Reply With Quote
10-27-10, 06:35 AM   #10
Sideshow
A Flamescale Wyrmkin
 
Sideshow's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 103
Download dtevents to track down events.
You can find it on wowprogramming under utils
  Reply With Quote
10-27-10, 02:49 PM   #11
Obivous
A Murloc Raider
Join Date: Oct 2010
Posts: 9
Angry

Okay now I'm starting to get pissed off ...

lua Code:
  1. /run local frame = CreateFrame("Frame") frame:SetScript("OnEvent", function(self, event, ...) local PVPType, isFFA, faction = GetZonePVPInfo() if not (PVPType == "sanctuary") then print("Enemy spotted") end end);

Doesn't work, though Xubera's does.

SDPhantom, I did define the function prior to assign it the OnEvent. It still doesn't work.

Sideshow, I didn't find it, maybe I didn't search correctly.

Currently I'm too pissed, I'll take a break. I've been working on that for at least two hours.
  Reply With Quote
10-27-10, 03:48 PM   #12
Xubera
A Cobalt Mageweaver
 
Xubera's Avatar
AddOn Author - Click to view addons
Join Date: May 2009
Posts: 207
you need to register the event

Code:
/run local frame = CreateFrame("Frame") frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")  frame:SetScript("OnEvent", function(self, event, ...) local PVPType, isFFA, faction = GetZonePVPInfo() if not (PVPType == "sanctuary") then print("Enemy spotted") end end)
__________________
Chat Consolidate is the solution to any out of control trade chat. Ignore lines, throttle chat, consolidate posts!Follow the link to find out how!

▲ ▲ WoWInterface wont let me triforce >.>
  Reply With Quote
10-27-10, 04:06 PM   #13
Obivous
A Murloc Raider
Join Date: Oct 2010
Posts: 9
I'm an idiot. I will edit for any other problem.

[EDIT]
OKay ...
I've dropped the sourcecode from the beginning and am starting over again :
lua Code:
  1. frame = CreateFrame("LogParserObi");
  2.  
  3. frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
  4.  
  5. function EventHandle(self, event, ...)
  6.     local PVPType, isFFA, faction = GetZonePVPInfo();
  7.     if not (PVPType == "sanctuary") then
  8.         if event == "COMBAT_LOG_EVENT_UNFILTERED" then
  9.             local timestamp, type, sGUID, sName, sFlags, dGUID, dName, dFlags, spellID, spellName, spellSchool, damageDealt = ...;
  10.             print(sName);
  11.         end
  12.     end
  13. end
  14.  
  15. frame:SetScript("OnEvent", EventHandle);

This doesn't work. However, the Ingame version works (dropping the sanctuary test because of the characters limitation) :
/run f=CreateFrame("Frame") f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") f:SetScript("OnEvent", function(self, event, ...) if event=="COMBAT_LOG_EVENT_UNFILTERED" then local t,u,v,w=... print(w) end end);

This does work also :
/run f=CreateFrame("Frame") f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") f:SetScript("OnEvent", function(self, event, ...) a,b,c=GetZonePVPInfo() if not a=="sanctuary" then local t,u,v,w=... print(w) end end);

[EDIT2] Re-coded this crap, which works :
lua Code:
  1. frame = CreateFrame("Frame");
  2. frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
  3.  
  4. function Event(self,event,...)
  5.     if event=="COMBAT_LOG_EVENT_UNFILTERED" and not (GetZonePVPInfo()=="sanctuary") then
  6.         local timestamp, type, sGUID, sName, sFlags, dGUID, dName, dFlags, spellID, spellName, sSchool, dDealt = ...;
  7.         -- Fuuu it works
  8.        
  9.     end
  10. end
  11.  
  12. frame:SetScript("OnEvent", Event);

Last edited by Obivous : 10-27-10 at 11:49 PM.
  Reply With Quote
10-27-10, 11:45 PM   #14
Xubera
A Cobalt Mageweaver
 
Xubera's Avatar
AddOn Author - Click to view addons
Join Date: May 2009
Posts: 207
lua Code:
  1. --frame = CreateFrame("LogParserObi");
  2. frame = CreateFrame("Frame", "LogParserObi") --the first parameter to CreateFrame is the type of widget... also its good practice to make UIParent the parent to your master frame if you plan on it showing stuff
  3.  
  4. frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
  5.  
  6.  
  7. --function EventHandle(self, event, ...)
  8. local function EventHandle(self, event, ...) --make it local, faster and doesnt use global name space... thats a common name so you could get interference.
  9.     --local PVPType, isFFA, faction = GetZonePVPInfo();
  10.     local PVPType = GetZonePVPInfo() --if you dont need other variables, why make em?
  11.     if not (PVPType == "sanctuary") then
  12.         if event == "COMBAT_LOG_EVENT_UNFILTERED" then
  13.             local timestamp, type, sGUID, sName, sFlags, dGUID, dName, dFlags, spellID, spellName, spellSchool, damageDealt = ...;
  14.             print(sName);
  15.         end
  16.     end
  17. end
  18.  
  19. frame:SetScript("OnEvent", EventHandle);
__________________
Chat Consolidate is the solution to any out of control trade chat. Ignore lines, throttle chat, consolidate posts!Follow the link to find out how!

▲ ▲ WoWInterface wont let me triforce >.>
  Reply With Quote
10-28-10, 03:50 PM   #15
Obivous
A Murloc Raider
Join Date: Oct 2010
Posts: 9
I'm working on another idea right now : detect mirror images. I've noticed they are flagged as « Mirror Image » in the chat log. I was wondering if I could retrieve their HP. I would then check with the HP of my current target (I sometimes hit by mistake TAB so I switch target ..) and also check mana, energy and so on.If these were equal I would output an personnalized raid message (I know how to do that) telling me to switch target. However I was wondering if it was possible to automatically switch to the real player, though I doubt it is possible to do so. Do you have any opinion ?

[EDIT] Examples GUIDs for the mirror image of a player and the players :
Player : 0x000000000001FBF4 (quite logical)
Mirror image : 0xF1300079F08ECB61

I guess I can exploit that

Last edited by Obivous : 10-28-10 at 04:22 PM.
  Reply With Quote
10-28-10, 05:47 PM   #16
Xubera
A Cobalt Mageweaver
 
Xubera's Avatar
AddOn Author - Click to view addons
Join Date: May 2009
Posts: 207
it used to be ( i dont knwo if they changed in 4.0) that UnitName("target") when targeting a mirror would return "Mirror Image" and since no one can have a space in their name, pretty good indicator that its not your intended target...

and your right, cant auto target
__________________
Chat Consolidate is the solution to any out of control trade chat. Ignore lines, throttle chat, consolidate posts!Follow the link to find out how!

▲ ▲ WoWInterface wont let me triforce >.>
  Reply With Quote
10-28-10, 08:31 PM   #17
Obivous
A Murloc Raider
Join Date: Oct 2010
Posts: 9
Okay, so I got the scheme, but let's say I use this function :

Code:
local function MirrorImageDetector()
	if UnitName("target") == "Image miroir" then
		RaidNotice_AddMessage(RaidWarningFrame, "You are targeting a Mirror Image !", ChatTypeInfo["RAID_WARNING"])
	end
end
If I execute it, as long as I target the mirror image, I will get flooded by this message. So I was wondering if there was a way to detect if the target changed. As far as I've searched there is no built-in function for that purpose, neither events. I thought of storing the old target name in a var and then compare but I cannot find how to retrieve the target's name ... =/
  Reply With Quote
10-29-10, 02:20 AM   #18
Xubera
A Cobalt Mageweaver
 
Xubera's Avatar
AddOn Author - Click to view addons
Join Date: May 2009
Posts: 207
PLAYER_TARGET_CHANGED

http://www.wowwiki.com/Events/Unit_Info

2nd event down
__________________
Chat Consolidate is the solution to any out of control trade chat. Ignore lines, throttle chat, consolidate posts!Follow the link to find out how!

▲ ▲ WoWInterface wont let me triforce >.>
  Reply With Quote
10-29-10, 01:05 PM   #19
Obivous
A Murloc Raider
Join Date: Oct 2010
Posts: 9
Now I gotta learn to read x) Thanks
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Handling combat log


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