WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Bizzare Bug - Addon seems to randomly not work, then work again later (https://www.wowinterface.com/forums/showthread.php?t=33139)

Ingensu 06-13-10 09:52 AM

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!

Torhal 06-13-10 10:15 AM

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.

v6o 06-13-10 10:19 AM

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

Waverian 06-13-10 10:30 AM

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

Ingensu 06-13-10 12:22 PM

Quote:

Originally Posted by Torhal (Post 191942)
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.


Quote:

Originally Posted by v6o (Post 191944)
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.

Vrul 06-13-10 01:22 PM

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.

Ingensu 06-13-10 02:41 PM

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.


All times are GMT -6. The time now is 01:33 PM.

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