I've been working on my addon, Trade Chat Champion, recently, and as it's grown in popularity, the need as arisen to have the addons communicate between each other. The addon needs to roll in a preset channel unique to those addons, and not display the rolls in any visible area of chat. While it is rolling, the addon will use a GetTime() function just prior to rolling and add 2 to it.
After waiting two seconds for all the rolls, the if / then command with the time + 2 variable will meet its conditions, and continue with the rest of the commands that is required IF, and only if, that specific instance of the addon had the highest roll.
Problem is, I'm not 100% sure how to do this because I have just recently started teaching myself LUA, so if you're reading this, feel free to drop a suggestion, even if your idea / help is even a tiny part of the whole function I'm looking to create!
Obviously, with time, I'll be able to google my way through the problem, but I figure why not try two different sources.
Again, any help at all will be greatly appreciated, and I thank those that will respond in advance!
After looking into the situation a bit more, I'm interested in the SendAddonMessage API. Is it possible to send information over a private channel using this?
In other news, I've worked out a rough logic for my addon, and while I have reservations for displaying my lack of skill, it is the following:
1. /join channel on login (optional: when player joins trade / BG (separate channels for each?))
Currently, the the addon uses JoinChannelByName, and joins my test channel "tcctest".
2. When triggered, the addon should use GetTime() + 2 to retrieve the time and add a sufficient enough delay.
3. Read chat
4. Compare math.random(1, 1000) of all the addons
5. Highest number continues to main function, rest end (if then with 0 or 1?)
6. (optional: /leave channel when you leave the respective trade / bg channel) -- LeaveChannelByName("channel") - Leaves the channel with the specified name.
Is there a way to hide such a communication? I've been looking rather extensively to find something of that nature.
EDIT: What I'm asking for is a way to have the instances of my addons communicate with each other. They need to be able to communicate cross-city, and continent. They need to be free of guild or group communication restrictions. And it all needs to be hidden from the user.
I may be mistaken, but don't you access that with SendAddonMessage? That only works for party, raid, battleground, guild, or whisper. I need something that can communicate between guilds or parties, over trade chat.
Before Blizzard added SendAddonMessage, addons used to handle communication over chat channels. It had some issue though, like being drunk (it modifies some strings so you have to escape them to make the message drunk-safe) and something far more annoying: people not having the addon will see all "hidden" communications. So using the regular trade channel is a very, very bad idea.
I'm not saying that it has to communicate over trade, just something that can operate along side trade. A custom channel seems like the best way to do this because only the addon users will have joined it, and then (I hope) all the chat can be hidden from the user.
Keep in mind this has its own set of issues, such as channel number reordering (if your addon loads before the chat servers sync), unhiding of channel, or the channel showing up on chat config screens.
You'll need code to deal with the chat channel being password protected (go to a alternative channel perhaps), deal with drunk player chat, chop messages into smaller parts, etc.
It sounds like the goal of your addon is to send predefined messages to Trade chat in response to messages that match certain criteria, but avoid having all users of the addon spam Trade chat in response to the same message. If so, rather than trying to make your addon communicate with everyone else using it, you could just do:
â Addon detects a matching message to respond to.
â Addon waits a random amount of time.
â At the end of the random amount of time,
ââ ...if the addon has seen one if its predefined messages during the wait, do nothing;
ââ ...otherwise, send a predefined message.
Of course, if you provide a way for users to supply their own messages, this wouldn't work, but if you have a hardcoded list of possible messages, it would, and would be a lot less work than trying to implement addon communication over a player chat channel.
I considered something like that in the very beginning, but I was unable to find any wait commands that didn't cause WoW to lock up. Are there any working ones that exist in LUA? I was under the impression that a sleep/pause function didn't exist.
Also, thinking about it, using your way, I could just random 1-20, say, and then the lowest response time would go off, correct? I liked this idea when I first started, but then I ran into the problem of "Well, how am I going to make it wait when LUA doesn't have a sleep command?"
I tried a simple loop along the lines of:
while TimePlusWait > GetTime() do
But that froze my WoW up. I assumed WoW doesn't like an addon taking up CPU cycles. Or perhaps my addon is somehow sleeping the entire WoW program, but that seems unlikely.
I also looked into the use of libraries with sleep functions, and while I really would prefer to not include a library in this addon, if that is the only way, I guess a must is a must.
Wow lua execution is mono-threaded. So if you run a infinite loop, it locks up. However, it is event-driven (think "signals"), so there are ways to react to specific events (like when chat communication is received). And there are libraries helping in handling timed tasks, like AceTimer-3.0.
After looking into a lot of different ways to do this, I'm still hitting a wall on the following problem.
I have created a few extra functions to help deal with the addon responding or not responding based on if another addon has "spoken" , so to speak. That is to say, if another addon has randomed a lower number than the instance we are speaking about, and replied sooner, the instance of the addon that we're speaking about will not reply. However, I am missing one crucial element. I cannot seem to figure out how to have the addon wait and still understand that at the end of the wait period, if no other addon has responded THEN reply. I am at a loss as to how to do this without a loop. Also, I fear including and calling an addon library isn't something I'm 100% sure how to do. Is that the only way? Should I be researching how to embed a function from a library (I assume thats how it works)?
The following is the main function in my LUA program. I fear my programming skills are just insufficient, and to be honest, I feel a little out of control now. I know the following code really doesn't do what it's supposed to, so I'm looking for a little help.
Things to know:
fTimeIni is a function that will retrieve the current time and the time the addon is allowed to respond once. At the end of its sequence, it changes a variable from 0 to 1, disallowing another call.
Matchtrigger is a function that checks for a trigger (for debugging, I've added [TCC] to the beginning of all responses) and if it finds it, it will change AllowTalk to 1, disallowing the CheckMsgMatch function to execute.
fTime is the same as TimeIni, but will execute as many times as necessary.
CheckMsgMatch will check if the player is a friend, or a guildmate. If not, it will roll 1-100 (chance to respond). If it rolls below the percentage number, it will respond. If not, it will print something to the user letting them know what happened.
local f = CreateFrame("Frame")
f:SetScript("OnEvent", function (self, event, msg, arg2, _, _, _, _, _, channel, channame)
-- Mod test channel.
if (event == "CHAT_MSG_CHANNEL") and (channame == "tcctest") then
if GetTime() >= waittime then
matchTrigger(msg, "CHANNEL", channel)
if AllowTalk == 0 then
sent() -- **Debug**
CheckMsgMatch(msg, "CHANNEL", channel)
WoW's game loop is single threaded. This means if your Lua code enters a loop that waits for 1 seconds, your wow will essentially hang for 1 second.
Instead, have your frame be assigned an OnUpdate script
f.time = 0
function myfunc(self, elapsed)
f.time = f.time + elapsed
if f.time > 1.5 then
f.time = 0 -- reset time
-- do stuff after 1.5 seconds
The frame will essentially receive the "OnUpdate" event every frame, and the 2 arguments passed to it is the frame and the elapsed time.
Because the OnUpdate function runs every frame, make sure its as optimized as possible. the frame "f" must also be shown for it to receive the OnUpdate event (IsShown() == true), if it is hidden, it will not run. This obviously makes it a good way to enable and disable the script (or otherwise setting the OnUpdate script to nil).