Reply
Thread Tools Display Modes
Unread 09-13-11, 08:01 AM   #1
Levisaxos
A Murloc Raider
Join Date: Sep 2011
Posts: 7
Need help creating a addon

Greetings,

I'm very new to creating addons in wow. However I do have some experience in programming (being a 4th year student in the programming business) but I can't get things to work yet.
Ofcourse this is because I lack the experience and knowlage about programming in LUA.

My idea is to create a very simple addon for myself which logs the mobs I kill by ID, Name and level.

Currently I have:

local frame = CreateFrame("FRAME", "KillCountFrame");
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
local function eventHandler(self, event, ...)
local timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags = select(1, ...)
if (type == "PARTY_KILL") then
print("Event: " .. type);
print("You just killed a "..UnitName("target").."("..UnitLevel("target")..")");
end
end
frame:SetScript("OnEvent", eventHandler);

The problem is however that the event is being triggered twice. Were I to put this in a WTF/Account etc file, it would register the kill as twice. How can I fix this?

I have tried by setting the timestamp in the first to a global one, and then checking wether the global timestamp matches the current. But this didn't work.


Also, I'm looking for a nice tutorial on how to write the information to a text file in the WTF/Account directory.
Hope you can help me since i've been working on it for 3 hours also and the above code is all I got.

Greetings, Levisaxos
Levisaxos is offline   Reply With Quote
Unread 09-13-11, 08:41 AM   #2
Taryble
A Molten Giant
 
Taryble's Avatar
Join Date: Jan 2009
Posts: 811
Addons can't write to text files on their own - however, WoW saves the variable that has the same name as the "SavedVariable" or "SavedVariablePerCharacter" line in the TOC file to a "SavedVariable" file.
__________________
-- Taryble
Taryble is offline   Reply With Quote
Unread 09-13-11, 09:46 AM   #3
Levisaxos
A Murloc Raider
Join Date: Sep 2011
Posts: 7
Originally Posted by Taryble View Post
Addons can't write to text files on their own - however, WoW saves the variable that has the same name as the "SavedVariable" or "SavedVariablePerCharacter" line in the TOC file to a "SavedVariable" file.
I'm sorry for the misunderstandment. I know WoW can't write to text files but it can write the savedvariables.
I think it's possible to control which data is being saved as a variable?

For instance, when I kill 2 mobs, it should read as 2 in that file?
Is this possible?
Levisaxos is offline   Reply With Quote
Unread 09-13-11, 02:30 PM   #4
Nibelheim
local roygbi-
 
Nibelheim's Avatar
Featured
Join Date: Jan 2010
Posts: 1,509
Originally Posted by Levisaxos View Post
I'm sorry for the misunderstandment. I know WoW can't write to text files but it can write the savedvariables.
I think it's possible to control which data is being saved as a variable?

For instance, when I kill 2 mobs, it should read as 2 in that file?
Is this possible?
Let's say you've got this line in your .toc
Code:
## SavedVariables: KillCountDB
Now, in your .lua file, you can do something like so:
Code:
local CharID
local KillCountDefaults = {
	totalkills = 0,
	characters = {},
}

local frame = CreateFrame("FRAME", "KillCountFrame");
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
frame:RegisterEvent("PLAYER_LOGIN");

local function eventHandler(self, event, ...)
	if event == "PLAYER_LOGIN" then
		CharID = UnitName("player") .. " - " .. GetRealmName()
		if not KillCountDB then
			KillCountDB = KillCountDefaults
		end
		if not KillCountDB.characters[CharID] then
			KillCountDB.characters[CharID] = 0,
		end
	else
		local timestamp, type, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags = select(1, ...)
		if (type == "PARTY_KILL") then
			print("Event: " .. type);
			print("You just killed a "..UnitName("target").."("..UnitLevel("target")..")");
			KillCountDB.characters[CharID] = KillCountDB.characters[CharID] + 1,
			KillCountDB.totalkills = KillCountDB.totalkills + 1
		end
	end
end

frame:SetScript("OnEvent", eventHandler);
Nibelheim is offline   Reply With Quote
Unread 09-13-11, 04:00 PM   #5
Levisaxos
A Murloc Raider
Join Date: Sep 2011
Posts: 7
Originally Posted by Nibelheim View Post
Let's say you've got this line in your .toc
Code:
See orginal post for code
Now, in your .lua file, you can do something like so:
Code:
See orginal post for code
Thanks, this got me a working version of what I exactly want but i'm still having the problem that both events, the PLAYER_LOADED and COMBAT_LOG_EVENT_UNFILTERED are being loaded twice whenever I log in, or kill a mob.
How can I fix this?

Last edited by Levisaxos : 09-13-11 at 04:04 PM.
Levisaxos is offline   Reply With Quote
Unread 09-13-11, 04:35 PM   #6
Nibelheim
local roygbi-
 
Nibelheim's Avatar
Featured
Join Date: Jan 2010
Posts: 1,509
Originally Posted by Levisaxos View Post
Thanks, this got me a working version of what I exactly want but i'm still having the problem that both events, the PLAYER_LOADED and COMBAT_LOG_EVENT_UNFILTERED are being loaded twice whenever I log in, or kill a mob.
How can I fix this?
Looks like your CLEU args were off.

Code:
local Char, PlayerID, Realm
local KillCountDefaults = {
	totalkills = 0,
	characters = {},
}

local frame = CreateFrame("FRAME", "KillCountFrame");
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
frame:RegisterEvent("PLAYER_LOGIN");

local function eventHandler(self, event, ...)
	if event == "PLAYER_LOGIN" then
		Char = UnitName("player")
		Realm = GetRealmName()
		PlayerID = UnitGUID("player")
		local CharID = Char .. " - " .. Realm
		
		if not KillCountDB then
			KillCountDB = KillCountDefaults
		end
		if not KillCountDB.characters[CharID] then
			KillCountDB.characters[CharID] = 0,
		end
	else
		local _, type, _, sourceGUID = ...
		if ( (sourceGUID == PlayerID) and (type == "PARTY_KILL") ) then
			print("Event: " .. type);
			print("You just killed a "..UnitName("target").."("..UnitLevel("target")..")");
			KillCountDB.characters[CharID] = KillCountDB.characters[CharID] + 1,
			KillCountDB.totalkills = KillCountDB.totalkills + 1
		end
	end
end

frame:SetScript("OnEvent", eventHandler);
Nibelheim is offline   Reply With Quote
Unread 09-14-11, 03:57 AM   #7
Levisaxos
A Murloc Raider
Join Date: Sep 2011
Posts: 7
Originally Posted by Nibelheim View Post
Looks like your CLEU args were off.

Code:
See orginal post for code
Still registers the events twice sadly.
also, it doesn't register party kills anymore.

[edit]
I've manage to get the UnitName from the destName parameter. However I can't seem to get the Unit level.
Is there any way, like via GUID or flags, that I can use to help me get the unit level without him being a target?

Last edited by Levisaxos : 09-14-11 at 06:38 AM.
Levisaxos is offline   Reply With Quote
Unread 09-14-11, 12:39 PM   #8
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 9,581
Are you using an XML file and/or loading your Lua file twice?
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

Seerah is offline   Reply With Quote
Unread 09-15-11, 12:13 AM   #9
Levisaxos
A Murloc Raider
Join Date: Sep 2011
Posts: 7
Originally Posted by Seerah View Post
Are you using an XML file and/or loading your Lua file twice?
I'm using one xml and one lua file

The XML file consist of:
Code:
<Ui xmlns="http://www.blizzard.com/wow/ui/" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://www.blizzard.com/wow/ui/ 
 ..\..\FrameXML\UI.xsd">
  <Script File="KillCount.lua"/>
  <Frame name="KillCountFrame">
   <Scripts>
    <OnLoad>     
    </OnLoad>
   </Scripts>
  </Frame>
</Ui>
I assume this doesn't load the lua file twice ?
Levisaxos is offline   Reply With Quote
Unread 09-15-11, 12:43 AM   #10
Nibelheim
local roygbi-
 
Nibelheim's Avatar
Featured
Join Date: Jan 2010
Posts: 1,509
Originally Posted by Levisaxos View Post
I'm using one xml and one lua file

The XML file consist of:
Code:
<Ui xmlns="http://www.blizzard.com/wow/ui/" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://www.blizzard.com/wow/ui/ 
 ..\..\FrameXML\UI.xsd">
  <Script File="KillCount.lua"/>
  <Frame name="KillCountFrame">
   <Scripts>
    <OnLoad>     
    </OnLoad>
   </Scripts>
  </Frame>
</Ui>
I assume this doesn't load the lua file twice ?
If that's all your XML file is, then delete it Make sure KillCount.lua is mentioned in your .toc file
Nibelheim is offline   Reply With Quote
Unread 09-15-11, 08:59 PM   #11
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 9,581
If you have your Lua file listed in your TOC *and* in your XML file, then yes it would be loaded twice. But, as Nib mentioned, just delete your XML file. All you're using it for is to load the Lua file (which you can do in the TOC) and to create a frame (which you aren't using, because you create another one in the Lua file).
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

Seerah is offline   Reply With Quote
Unread 09-16-11, 01:25 AM   #12
Levisaxos
A Murloc Raider
Join Date: Sep 2011
Posts: 7
Thank you all for your help guys!

Now all I have to find out is how to filter the kills to only kills made by people in my group (Could use party_kills for that, but that doesn't get raid kills!) and people in my raid!

So i'm guessing I will have to check the sourceName or sourceGUID to my raidmembers.

If anyone wishes to help me with that they are welcome to do so

[edit]
I noticed that PARTY_KILL event is being triggered before UNIT_DIED.. so when I kill one myself I can just check the sourceGUID with my GUID on a PARTY_KILL event.
PARTY_KILL is also triggered when someone from my group kills a mob so that one isn't hard either..

However, how can I register if a mob is killed by a raid member?
UNIT_DIED does not give a valid sourceGUID of the person that killed him?

Last edited by Levisaxos : 09-16-11 at 03:30 AM.
Levisaxos is offline   Reply With Quote
Unread 09-16-11, 02:06 PM   #13
Ketho
A Molten Giant
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 565
Originally Posted by Levisaxos View Post
Thank you all for your help guys!

Now all I have to find out is how to filter the kills to only kills made by people in my group (Could use party_kills for that, but that doesn't get raid kills!) and people in my raid!

So i'm guessing I will have to check the sourceName or sourceGUID to my raidmembers.

If anyone wishes to help me with that they are welcome to do so

[...]

However, how can I register if a mob is killed by a raid member?
UNIT_DIED does not give a valid sourceGUID of the person that killed him?
You would maybe have to check for the overkill parameter

Here is a quick example (borrowing the code from Nibelheim )
Code:
local Char, PlayerID, Realm
local KillCountDefaults = {
	totalkills = 0,
	characters = {},
}

local playerName = UnitName("player")
local damageEvent = {
	["SWING_DAMAGE"] = true,
	["RANGE_DAMAGE"] = true,
	["SPELL_DAMAGE"] = true,
	["SPELL_PERIODIC_DAMAGE"] = true,
}

local frame = CreateFrame("FRAME", "KillCountFrame");
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
frame:RegisterEvent("PLAYER_LOGIN");

local function eventHandler(self, event, ...)
	if event == "PLAYER_LOGIN" then
		Char = UnitName("player")
		Realm = GetRealmName()
		PlayerID = UnitGUID("player")
		local CharID = Char .. " - " .. Realm
		
		if not KillCountDB then
			KillCountDB = KillCountDefaults
		end
		if not KillCountDB.characters[CharID] then
			KillCountDB.characters[CharID] = 0,
		end
	else
		local timestamp, subevent, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags = ...
		local amount, overkill
		if damageEvent[subevent] then
			if subevent == "SWING_DAMAGE" then
				amount, overkill = select(12, ...)
			else
				amount, overkill = select(15, ...)
			end
			if overkill > 1 and (UnitInRaid(sourceName) or UnitInParty(sourceName) or sourceName == playerName) then
				--print(sourceName.." killed "..destName.." for "..amount.." damage!")
				KillCountDB.characters[sourceName] = (KillCountDB.characters[sourceName] or 0) + 1,
			end
		end
	end
end

frame:SetScript("OnEvent", eventHandler);
There might be a problem with multiple timed overkill events for the same unit, so you maybe have to add in a throttle for each individual player, or it would all get counted as a kill
__________________

Last edited by Ketho : 11-09-11 at 09:38 AM.
Ketho is offline   Reply With Quote
Unread 09-16-11, 02:40 PM   #14
Levisaxos
A Murloc Raider
Join Date: Sep 2011
Posts: 7
Originally Posted by Ketho View Post
You would maybe have to check for the overkill parameter

Here is a quick example (borrowing the code from Nibelheim )
Code:
See original post for code
There might be a problem with multiple timed overkill events for the same unit, so you maybe have to add in a throttle for each individual player, or it would all get counted as a kill
Thank you for your suggestion.
Currently I have it fixed by checking in which zone I am.
If i'm in a raid zone, it only reacts to the UNIT_DEAD event type.

It still has some bumbs and bruises, like party members dying are being read as a kill aswell, but slowly i'm getting there !
Levisaxos is offline   Reply With Quote
Reply

Go BackWoWInterface » Developer Discussions » General Authoring Discussion » Need help creating a addon

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