Hello, I am trying to create an addon with two OnEvent functions. While alone, they work without issue. When I have both of them enabled, they don’t work. I think something in conflicting between the two events but I can’t seem to narrow it down. Any help would be greatly appreciated.
What I have tried…
local hyperSpawn_Toggle = false
local hyperSpawn_Alert = false
local hyperSpawn_StartTimer = CreateFrame(“FRAME”,“Timer”);
local hyperSpawn_StatueFocus = CreateFrame(“FRAME”,“Alert”);
local function eventHandlerTimer(self, event)
if (hyperSpawn_Toggle == true) then
Stopwatch_StartCountdown(0, 2, 0); Stopwatch_Play();
else
end
end
SLASH_HSTOGGLE1 = “/hstoggle”
SlashCmdList[“HSTOGGLE”] = function()
if (hyperSpawn_Toggle == true) then
hyperSpawn_Toggle = false
StopwatchFrame:Hide();
print(“Loot Timer has been disabled.”);
else
hyperSpawn_Toggle = true
print(“Loot Timer has been enabled.”);
end
end
SLASH_HSALERT1 = “/hsalert”
SlashCmdList[“HSALERT”] = function()
if (hyperSpawn_Alert == true) then
hyperSpawn_Alert = false
print(“Alert has been disabled.”);
else
hyperSpawn_Alert = true
print(“Alert has been enabled.”);
end
end
I also tried this…
function hyperSpawn_OnLoad()
hyperSpawn_StartTimer:RegisterEvent(“LOOT_CLOSED”);
hyperSpawn_StatueFocus:RegisterEvent(“PLAYER_FOCUS_CHANGED”);
end
function hyperSpawn_OnEvent(event)
if event == “PLAYER_FOCUS_CHANGED” then
print(“Your statue has died!”);
elseif event == “LOOT_CLOSED” then
Stopwatch_StartCountdown(0, 2, 0); Stopwatch_Play();
end
end
Your first one has no events, it seems to want to be slash command driven, something like
/hs followed by s to start or k to kill
SLASH_HSTOGGLE1 = "/hs"
SlashCmdList["HSTOGGLE"] = function(msg)
local action = string.upper(msg)
if action == "S" then
if StopwatchFrame:IsShown() then
print("Stopwatch is running!")
return
end
Stopwatch_StartCountdown(0, 2, 0)
Stopwatch_Play()
elseif action == "K" then
if StopwatchFrame:IsShown() then
Stopwatch_Toggle()
end
end
end
Otherwise, a bit more explanation of what you want the outcome to be might help a feeble mind like mine.
Thank you for the quick reply. Everything works when its by itself. It is only when I have one or the other not commented out that it doesn’t work. One of the events is to track when your loot windows loaded and starts a countdown timer for 2 minutes. The second event alerts you when your focus target changes, or is killed.
Frames created in lua don’t need an OnLoad function because they are “loaded” as soon as they have been created (it’s more an html frames thing).
Your event handler also had the event parameter where the function would have been receiving “self” (the reference to the frame) and not the event…
local function hyperSpawn_OnEvent(self, event, ...) -- Event function
if event == "PLAYER_FOCUS_CHANGED" then
print("Your statue has died!");
elseif event == "LOOT_CLOSED" then
Stopwatch_StartCountdown(0, 2, 0);
Stopwatch_Play();
end
end
local hyperSpawn_StartTimer = CreateFrame("Frame","hyperSpawn_Timer"); -- Create the frame
hyperSpawn_StartTimer:RegisterEvent("LOOT_CLOSED"); -- register the events
hyperSpawn_StartTimer:RegisterEvent("PLAYER_FOCUS_CHANGED");
hyperSpawn_StartTimer:SetScript("OnEvent", hyperSpawn_OnEvent) -- set the event handler
A frame can only have a single event handler (not counting the use of HookScript) but a frames event handler will be passed every event registered to that frame as it occurs.
I created an announcement that is disabled if the user is in a particular zone. However, it doesn’t seem to be taking that command into effect and ignores it. I tried moving the if than statements around but it didn’t make a difference.
Here is the code:
elseif (event == “MERCHANT_SHOW”) then
local hyperSpawn_Zone = GetZoneText();
if (hyperSpawn_Zone ~= “Stormwind City” and “City of Ironforge” and “The Exodar” and “Darnassus” and “Orgrimmar” and “Thunder Bluff” and “Dalaran” and “Shattrath City” and “Shrine of Seven Stars” and “Shrine of Two Moons” and “Stormshield” and “Warspear” and “Lunarfall” and “Frostwall” and “Undercity” and “Silvermoon City” and “Boralus Harbor” and “Zuldazar”) then
if (hyperSpawn_Vendor == true) then
if UnitInParty(“player”) then
SendChatMessage(“There may be a VENDOR MOUNT nearby (generated by the Hyperspawn addon).”, “PARTY”)
else
end
end
end
end
end
I think I found the problem with the if and and and and and part. It is only applying to the first part which is Stormwind City. The others don’t take effect.
-- code
if not Cities[GetZoneText()] and hyperSpawn_Vendor and UnitInParty(“player”) then
SendChatMessage(“There may be a VENDOR MOUNT nearby (generated by the Hyperspawn addon).”, “PARTY”)
end
Dude! You’re amazing! I have been trying to figure out the dynamic variables thing and wasn’t making much progress lol. I will give this a shot and let you know!
EDIT: That worked, thank you! I have another problem…
elseif (event == “UNIT_SPELLCAST_SUCCEEDED”) then
local unitID, spell, rank, lineID, spellID = select(1, …)
if spellId == 122708 then
print(“Finished casting”);
end
I found out you could use this event to know when mounts/toys are summoned. If I move the local, spellID line, it will print when I cast a spell. I saw another addon use this and I assume that it is supposed to take info from the spell cast and store them in a variable so I can check to see which spell was casted. However… it isn’t doing anything. Any tips? I will continue researching!
EDIT again: So I removed the part to check the SpellID and just had it print the variables, being Spell and Spell ID. And I get back random numbers in hexadecimal… so I guess it works, but I am not sure how to read that information as a spell ID…
Cast-3-3881-0-17-122708-001BA65448
This is what is received for the SPELL variable.
122708 is the spell ID for the grand expedition yak, so I guess I need to figure out how to parse the string or check to see if it contains that value… still researching!
Anything doing select(1… is wasting cycles as assignment automatically begins at 1.
Ranks have been removed from well, everything including event payloads so it’s best to check for the latest information: https://wow.gamepedia.com/UNIT_SPELLCAST_SUCCEEDED
elseif (event == “UNIT_SPELLCAST_SUCCEEDED”) then
local unitTarget, castGUID, spellID = ...
if spellID == 122708 then
print(“Finished casting”)
end
I had a feeling that was as bit dated… I went to that page and saw the three payloads or whatever. I am super noob at LUA, and programming in general, I guess I have enough knowledge to be dangerous lol. I will give this a shot and report back!!! I am putting you in my credits
elseif (event == “UNIT_SPELLCAST_SUCCEEDED”) then
local unitTarget, castGUID, spellID = …
if spellId == 122708 then
print(spellID);
end
end
Hmm, I tried this with the Yak and it didn’t print anything… did I do something wrong?
There were two issues there, one being the capitalization and the other being that I copied directly from the quote block and there was a weird space that was causing the addon to not load. I got it working after typing it all out manually.
Two more questions if you don’t mind…
I want to link the spell name when it is casted instead of just typing it out regularly. I tried used the links from WoWhead but they weren’t going out right.
I am trying to add more elseif events under the first spell to handle if the other spells were cast. The Yak is the first if SpellID and it works, when I add the ID for the traveler’s mammoth it doesn’t work but the code is the same. This is all in the same event function you helped me make earlier. Can you use elseif inside of multiple blocks that are already using elseif?
Like so…
elseif (event == “LOOT_CLOSED”) then
if (hyperSpawn_Timer == true) then
Stopwatch_StartCountdown(0, 2, 0);
Stopwatch_Play();
end
– Announcements
elseif (event == “UNIT_SPELLCAST_SUCCEEDED”) then
local unitTarget, castGUID, spellID = …
if not hyperSpawn_Cities[GetZoneText()] then
if not hyperSpawn_Towns[GetMinimapZoneText()] then
if UnitInParty(“player”) then
– Grand Expedition Yak
if (spellID == 122708) then
SendChatMessage(“I have summoned a [Yak]!”, “SAY”)
– Traveler’s Tundra Mammoth
elseif (spellID == 61447) then
SendChatMessage(“I have summoned a [Mammoth]!”, “SAY”)
end
end
end
end
end
end
Scratch that #2, Wowhead has the wrong spellID listed for the Traveler’s Mammoth.
if event == "UNIT_SPELLCAST_SUCCEEDED" then
local unitTarget, castGUID, spellID = ...
if spellID == 122708 then
local link = GetSpellLink(spellID)
print("You just finished casting:", link);
end
end
WoW lua is a restricted subset of the 5.1 version of lua and the WoW API is a bit of a moving feast. Other addons, the WoW stock UI code and questions are probably the best methods of learning.
Apart from the earlier books there’s not really any general guides.
… denotes a variable number of parameters (arguments). As with events, each one can have zero, one or more parameters in its payload .
If multiple events are processed by a single event handler, the event determines how many, and what they are
if event == "UNIT_HEALTH" then -- only one parameter here
local unit = ...
-- This units health has changed
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
local unitTarget, castGUID, spellID = ...
-- etc.
lua doesn’t have the same requirement for things like parentheses in if statements or semi-colons at the end of lines etc. but many people coming from other languages will use them for reasons…
EDIT: This is to track when my Black Ox Statue died. I also tried UNIT_DESTROYED. I also tried just killing random mobs.
I am trying to cleanup the focus alert by parsing the combat log, from what I can see this should work… but when a unit dies, nothing is posted. Any idea?
elseif (event == “COMBAT_LOG_EVENT_UNFILTERED”) then
local timestamp, type, hideCaster, sourceGUID, sourceName, sourceFlags, sourceFlags2, destGUID, destName, destFlags, destFlags2 = …
if (type == “UNIT_DIED”) then
local destGUID, destName = …
print(destGUID);
print(destName);
end
end