Quantcast
Bizzare Bug - Addon seems to randomly not work, then work again later - WoWInterface
Thread Tools Display Modes
06-13-10, 09:52 AM   #1
Ingensu
A Fallenroot Satyr
 
Ingensu's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 22
Bizarre Bug in Nibelung Count Addon

*** RESOLVED. ***

Okay, here's the deal. I'm working on an addon for the purposes of tracking the Val'kyr spawns off of the Nibelung staff. It works perfectly so far...sometimes. It'll work consistently for a while, then (seemingly at random) break for a while. It's a little odd, to say the least, and I've been scratching my head trying to figure out the problem with it. I was hoping that someone here could take a look and see if they can see where I went wrong, but honestly, I have no idea.

The way it (is supposed to) works is it maintains a counter as to how many Val'kyr are currently up at any given point in time. Now, the Val'kyr in question are named "Val'kyr Guardian" and are summoned by a spell called "Summon Val'kyr Guardian", which is reported as a summon in a combat log event. They last 30 seconds, but are able to be killed, so the addon needs to make note of this as well. When they despawn, they fire no combat log event (as far as I can tell), so I track each Val'kyr with a non-indexed table. In this case, the keys are the GUIDs of each Val'kyr (which are gathered from the summoning event), and the values are the system time, in seconds, when it was summoned. At this point, all I need to do is remove these from the table when a Val'kyr either A) dies or B) has been up for at least 30 seconds, in which case it has despawned. To check to see if a Val'kyr has been up for 30 seconds, on every combat log event it goes through the table and compares the current system time for the one logged for each individual Val'kyr. If any of them have a 30 second difference with the current time, that Val'kyr is dropped from the table. The user's GUID is recorded to double-check that Val'kyr that are summoned actually belong to the user, rather than someone else's procs.

So far, this method has been precise enough that it registers a Val'kyr's despawn within a second or less, and a Val'kyr's death instantaneously. This is good enough for my purposes.

The issue is that the mod loads properly (with the "counter loaded" message displaying), but will occasionally not report, or count, any Val'kyr spawns, despawns, or deaths. If I check the values of the count variables or the table manually when they -should- be changing, they come up nil.

Code:
valktable={};
playerguid=nil;
valkcount=0;
function ValkyrLoad()
	DEFAULT_CHAT_FRAME:AddMessage("Val'kyr Counter Loaded.");
	ValkyrCountFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
	playerguid = UnitGUID("player");
end


function ValkyrOnEvent(self, event, ...)
	for i,v in pairs(valktable) do
	local comptime = GetTime();
		if(v+30<comptime) then
		valktable[i]=nil;
		valkcount=valkcount-1;
		DEFAULT_CHAT_FRAME:AddMessage("Val'kyr timed out. Count: " .. valkcount);

		end
	end


	if(event=="COMBAT_LOG_EVENT_UNFILTERED") then
	local timestamp, combatevent, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags = ...;

		if(combatevent=="UNIT_DIED") then
			for i,v in pairs(valktable) do
				if(destGUID==i) then
					valktable[i]=nil;
					valkcount=valkcount-1;
					DEFAULT_CHAT_FRAME:AddMessage("Val'kyr died. Count: " .. valkcount);
				end
			end
		end

		if (combatevent=="SPELL_SUMMON" and destName=="Val'kyr Guardian" and sourceGUID == playerguid) then
			local comptime = GetTime();
			valktable[destGUID]=comptime;
			valkcount=valkcount+1;
			DEFAULT_CHAT_FRAME:AddMessage("Val'kyr spawned. Count: " .. valkcount);

		end

	end



end
I suspect that it may be an issue with pulling the user's GUID. But I'm not sure why there would be a problem with the way I'm doing it.

Any help would be appreciated! I hope this was complete enough for you to understand what I'm trying to accomplish!
__________________
Devī - Level 85 Beast Mastery hunter.
Devikins - Level 85 Feral (Bear) druid.
Aetheriel - Level 85 Restoration shaman.
US - Stormrage
Goal: Level and gear one of every class. (2.5/10)

Last edited by Ingensu : 06-13-10 at 12:38 PM. Reason: Resolved.
  Reply With Quote
06-13-10, 10:15 AM   #2
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Unless you're posting your complete code, any advice you receive here will generally be useless - since the gist I garnered is that this is the case, I didn't bother really looking at the logic of your code. I did glance over it, though, and have some general suggestions:

You're using global variables and functions which is not only inefficient but could clash with other AddOns which are similarly coded or even with parts of the default UI.

You are repeatedly asking for the value of the player's GUID, which never changes. Ever. Get this value at the beginning of the file's code block.

You are using GetTime() repeatedly within loops, which are executing so quickly that each call will produce roughly identical values - asking for that data once per function call (when the event occurs) is sufficient.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
06-13-10, 10:19 AM   #3
v6o
An Onyxian Warder
AddOn Author - Click to view addons
Join Date: Mar 2009
Posts: 399
Also, your suspicion is correct, you should be delaying the playerguid = UnitGUID("player") part until you're ingame.

To make it more clear

Startup/No event = nil
ADDON_LOADED = nil
VARIABLES_LOADED = nil
PLAYER_LOGIN = 0x060000000331C874
PLAYER_ENTERING_WORLD = 0x060000000331C874
__________________
I stopped playing back World of Warcraft in 2010 and I have no plans on returning.
This is a dead account and if you want to continue any of my addons or make a fork then feel free to do so.
This is your permission slip.

If you need to contact me, do so on Twitter @v6ooo

Best regards, v6.

Last edited by v6o : 06-13-10 at 10:30 AM.
  Reply With Quote
06-13-10, 10:30 AM   #4
Waverian
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Dec 2006
Posts: 188
Is your combat log working? There is an occasional UI bug that prevents the client from receiving combat log data. It usually happens after changing zone to a new area (loading screen).

http://www.wowinterface.com/download...batLogFix.html
  Reply With Quote
06-13-10, 12:22 PM   #5
Ingensu
A Fallenroot Satyr
 
Ingensu's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 22
Originally Posted by Torhal View Post
Unless you're posting your complete code, any advice you receive here will generally be useless - since the gist I garnered is that this is the case, I didn't bother really looking at the logic of your code. I did glance over it, though, and have some general suggestions:

You're using global variables and functions which is not only inefficient but could clash with other AddOns which are similarly coded or even with parts of the default UI.

You are repeatedly asking for the value of the player's GUID, which never changes. Ever. Get this value at the beginning of the file's code block.

You are using GetTime() repeatedly within loops, which are executing so quickly that each call will produce roughly identical values - asking for that data once per function call (when the event occurs) is sufficient.

Thanks for your input. ^^ I've been out of the modding scene for about a year and a half, so I'm a little rusty.


Originally Posted by v6o View Post
Also, your suspicion is correct, you should be delaying the playerguid = UnitGUID("player") part until you're ingame.

To make it more clear

Startup/No event = nil
ADDON_LOADED = nil
VARIABLES_LOADED = nil
PLAYER_LOGIN = 0x060000000331C874
PLAYER_ENTERING_WORLD = 0x060000000331C874
Alright, I thought so. ^^

Thanks so much, guys! I should be able to polish this puppy up and maybe upload it if anyone has any interest in it. :3 As I said, I haven't modded in a long time, so I'm really thankful for your help.
__________________
Devī - Level 85 Beast Mastery hunter.
Devikins - Level 85 Feral (Bear) druid.
Aetheriel - Level 85 Restoration shaman.
US - Stormrage
Goal: Level and gear one of every class. (2.5/10)
  Reply With Quote
06-13-10, 01:22 PM   #6
Vrul
An Onyxian Warder
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 389
Taking what you posted and cleaning it up:
Code:
local frame, numValks, timer, valks, playerGUID = CreateFrame('Frame'), 0, 0, { }
frame:Hide()

frame:SetScript('OnUpdate', function(self, elapsed)
	timer = timer + elapsed
	if timer < 0.5 then return end
	timer = 0
	local count, now = numValks, time()
	for guid, timeOut in pairs(valks) do
		if timeOut <= now then
			valks[guid] = nil
			numValks = numValks - 1
		end
	end
	if numValks ~= count then
		print("Val'kyr timed out. Count: " .. numValks)
		if numValks == 0 then
			self:Hide()
		end
	end
end)

local function OnEvent(self, event, timeStamp, combatEvent, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags)
	if combatEvent == 'SPELL_SUMMON' then
		if destName == "Val'kyr Guardian" and sourceGUID == playerGUID then
			valks[destGUID] = time() + 30
			numValks = numValks + 1
			if numValks == 1 then
				self:Show()
			end
			print("Val'kyr spawned. Count: " .. numValks)
		end
	elseif combatEvent == 'UNIT_DIED' and valks[destGUID] then
		valks[destGUID] = nil
		numValks = numValks - 1
		if numValks == 0 then
			timer = 0
			self:Hide()
		end
		print("Val'kyr died. Count: " .. numValks)
	end
end

frame:SetScript('OnEvent', function(self)
	self:UnregisterEvent('PLAYER_ENTERING_WORLD')
	playerGUID = UnitGUID('player')
	self:SetScript('OnEvent', OnEvent)
	self:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED')
	print("Val'kyr Counter Loaded.")
end)
frame:RegisterEvent('PLAYER_ENTERING_WORLD')
That will do basically the same as what you posted and is completely stand alone. I'm not sure why anyone would want this though. Maybe if instead of spamming text you had an icon with a counter that is only shown when you have Val'kyr active.
  Reply With Quote
06-13-10, 02:41 PM   #7
Ingensu
A Fallenroot Satyr
 
Ingensu's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 22
This is just a rough start for such an addon. ^^ My friend wanted an addon that keeps a count of how many Val'kyr he had up. The message spam is only a debugging measure--I wanted the core functionality working before I developed any kind of interface for it--that's just how I prefer to develop. Here's the start of the interface if you're curious:



Notice that it's the "start" of the interface. ;p It's not very pretty.
__________________
Devī - Level 85 Beast Mastery hunter.
Devikins - Level 85 Feral (Bear) druid.
Aetheriel - Level 85 Restoration shaman.
US - Stormrage
Goal: Level and gear one of every class. (2.5/10)

Last edited by Ingensu : 06-13-10 at 02:44 PM. Reason: Elaborating.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Bizzare Bug - Addon seems to randomly not work, then work again later

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