Thread Tools Display Modes
04-16-11, 08:12 AM   #1
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
Addon to split *emotes* out of messages

Basically, I'm looking for an addon that'll let me write *asterisk emotes* in a chat message and have those split into separate /emotes once the message is posted.

If I, for instance, write a message that goes:
Some message. *some emote.*
It'll be output in the chat as:
<Player> says: Some message.
<Player> some emote.
________________________
Vice versa, if I write the emote before the message, like this:
*some emote.* Some message.
It'll appear as:
<Player> some emote.
<Player> says: Some message.
________________________
Or if I do both several times within a message:
Some message. *some emote.* Some message. *some emote.*
That'll work too:
<Player> says: Some message.
<Player> some emote.
<Player> says: Some message.
<Player> some emote.
________________________
Support for the game's built-in emotes would also be nice:
Some message. *openfire* (or */openfire*)
Becomes:
<Player> says: Some message.
<Player> gives the order to open fire.
I had something that did this some time ago, but it was part of a bigger addon together with lots of other integrated features. It's been a while since I used that addon, it's been a while since last time there was much word from the developer, and it seems a bit crude to seek him out just to ask if he can extract that feature and make it an independent addon. So if there are anyone here with the time and energy to whip up an addon like this (can't imagine it being that hard), that'd be totally awesome (alternatively, if anyone knows of an addon that already does this, that'd be even more awesome).
  Reply With Quote
04-16-11, 10:16 AM   #2
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
I think I see what you mean, basically something like this I guess?


It should be possible by pre-hooking SendChatMessage I reckon.

Code:
local orig = SendChatMessage
function SendChatMessage(text, chan, ...)
  if chan ~= "EMOTE" then
    local emote = text:match("*(.+)*")
    if emote then
      text = text:gsub("*(.+)*", "")
      orig(text, chan, ...)
      return DoEmote(emote)
    end
  end
  return orig(text, chan, ...)
end
It's just an example, haven't tested it and there may be an easier way to do this. In short what I tried to do is match the "*string*" remove it from the message then send the message and finally the emote in the ** tags.
  Reply With Quote
04-16-11, 11:57 AM   #3
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
Yeah, that's pretty much exactly what I'm after, though I'm judging by the third line that it would kick in whenever the channel is not EMOTE (I've programmed in AS3, but never in Lua). The best way would be if it only does its work when it's posted to the SAY channel. Still, that is pretty much what I'm after.
  Reply With Quote
04-16-11, 03:39 PM   #4
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by Vladinator View Post
Code:
local orig = SendChatMessage
function SendChatMessage(text, chan, ...)
  if chan ~= "EMOTE" then
    local emote = text:match("*(.+)*")
    if emote then
      text = text:gsub("*(.+)*", "")
      orig(text, chan, ...)
      return DoEmote(emote)
    end
  end
  return orig(text, chan, ...)
end
There's a couple errors in the pattern. The asterisk is a magic character that needs to be escaped. Also, you need the capture to match as little as possible so it doesn't try to overflow outside the terminating asterisk if another one exists in the message or multiple emotes are in the message. You should use either "%*([^%*]-)%*" or "%*(.-)%*".
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
04-16-11, 03:46 PM   #5
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
The Lua patterns gods have spoken

Sorry, couldn't keep it down
  Reply With Quote
04-16-11, 04:48 PM   #6
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
I put together some code to do exactly what was described. It only operates on /say and it will attempt to use the emote slash command if it finds one that matches, otherwise, it'll send the emote out through the emote channel. Theoreticly, the slash command emotes support a target argument that lets you specify what UnitID to target. This option has been added in to this code as well.
lua Code:
  1. local Send=SendChatMessage;
  2. local pieces={};
  3. function SendChatMessage(msg,chan,...)
  4.     chan=chan:upper();--    Convert to make checks easier (channel is case-insensitive)
  5.     if chan=="SAY" then
  6. --      Clear our piece table
  7.         table.wipe(pieces);
  8.  
  9. --      Remove empty emotes and strip all spaces around "*" (try to replace empty emotes with a single space)
  10.         msg=strtrim(msg):gsub("%s*%*%s*%*%s*"," "):gsub("%s*%*%s*","%*");
  11.  
  12. --      Split string (strsplit() isn't working the way we need it to)
  13.         for i in msg:gmatch("[^%*]+") do pieces[#pieces+1]=i; end
  14.         if msg:sub(1,1)=="*" then table.insert(pieces,1,""); end
  15.  
  16. --      Iterate through pieces
  17.         for i,j in ipairs(pieces) do
  18.             if #j>0 then--  Don't do anything if string is empty
  19.                 if i%2>0 then-- Evaluates to 1 if say, 0 if emote
  20.                     Send(j,chan);
  21.                 else
  22. --                  Try to separate command and args
  23.                     local cmd,arg=j:match("(%S+) (.+)");
  24.                     if not cmd then cmd=j; end
  25.  
  26. --                  This is tricky, we need to check if the emote slash command exists
  27.                     local token;
  28.                     local tokencheck,tokenid=EMOTE1_TOKEN,1;
  29.                     while tokencheck do
  30.                         local cmdcheck,cmdid=_G["EMOTE"..tokenid.."_CMD1"],1;
  31.                         while cmdcheck do
  32.                             local slashcmd=cmdcheck:sub(2):lower();--   Skip the slash for the emote command
  33.                             if slashcmd==cmd:lower() then-- Command matches, token found
  34.                                 token=tokencheck;
  35.                                 break;
  36.                             end
  37.  
  38. --                          Increment command
  39.                             cmdcheck,cmdid=_G["EMOTE"..tokenid.."_CMD"..(cmdid+1)],cmdid+1;
  40.                         end
  41.  
  42. --                      Break if token found
  43.                         if token then break; end
  44.  
  45. --                      Increment token
  46.                         tokencheck,tokenid=_G["EMOTE"..(tokenid+1).."_TOKEN"],tokenid+1;
  47.                     end
  48.  
  49.                     if token then
  50.                         DoEmote(token,arg);--   Performs the same emote operation as supported by chat
  51.                     else
  52.                         Send(j,"EMOTE");
  53.                     end
  54.                 end
  55.             end
  56.         end
  57.     else
  58.         Send(msg,chan,...);
  59.     end
  60. end
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 04-19-11 at 12:35 PM.
  Reply With Quote
04-16-11, 07:09 PM   #7
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
Take a look on what I wrote and give me some feedback:

lua Code:
  1. local trim = function(str)
  2.   return str:trim(" \t\r\n")
  3. end
  4.  
  5. local match = function(str)
  6.   local ret = {}
  7.   for msg, emote in str:gmatch("(.-)%*(.-)%*") do
  8.     str = str:replace(msg, "")
  9.     str = str:replace("*"..emote.."*", "")
  10.     msg = trim(msg)
  11.     emote = trim(emote)
  12.     table.insert(ret, {
  13.       msg:len() > 0 and msg or nil,
  14.       emote:len() > 0 and emote or nil,
  15.     })
  16.   end
  17.   str = trim(str)
  18.   if str:len() > 0 then
  19.     table.insert(ret, {str, nil})
  20.   end
  21.   return #ret > 0 and ret or nil
  22. end

In short, match("message") will return either nil if nothing matched or a table containing {message, emote} that you can go trough each one, unpack each entry and send the message in the /say or /emote channels depending if it's a string or nil.

Far better than my first sketch, aye?

Last edited by Vlad : 04-16-11 at 07:34 PM.
  Reply With Quote
04-16-11, 08:29 PM   #8
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
string.trim() does not exist in the Lua core, however, the WoW API supplies strtrim() to do this and the default character string is " \t\r\n" if left undefined.

I still prefer my string splitting approach plus the added features the OP requested. Also to note, DoEmote() requires an emote token to run, you need to send it through the EMOTE channel with SendChatMessage() for custom emotes.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
04-17-11, 02:16 AM   #9
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
Originally Posted by SDPhantom View Post
I put together some code to do exactly what was described. It only operates on /say and it will attempt to use the emote slash command if it finds one that matches, otherwise, it'll send the emote out through the emote channel. Theoreticly, the slash command emotes support a target argument that lets you specify what UnitID to target. This option has been added in to this code as well.
lua Code:
  1. local Send=SendChatMessage;
  2. function SendChatMessage(msg,chan,...);
  3.     chan=chan:upper();--    Convert to make checks easier (channel is case-insensitive)
  4.     if chan=="SAY" then
  5. --      Strip all spaces around "*" and split into segments
  6.         local pieces={strsplit("*",msg:gsub("%s*%*%s*","%*"))};
  7.  
  8. --      Iterate through pieces
  9.         for i,j in ipairs(pieces) do
  10.             if #j>0 then--  Don't do anything if string is empty
  11.                 if i%2>0 then-- Evaluates to 1 if say, 0 if emote
  12.                     Send(j,chan);
  13.                 else
  14. --                  Try to separate command and args
  15.                     local cmd,arg=j:match("(%S+) (.+)");
  16.                     if not cmd then cmd=j; end
  17.  
  18. --                  This is tricky, we need to check if the emote slash command exists
  19.                     local token;
  20.                     local tokencheck,tokenid=EMOTE1_TOKEN,1;
  21.                     while tokencheck do
  22.                         local cmdcheck,cmdid=_G["EMOTE"..tokenid.."_CMD1"],1;
  23.                         while cmdcheck do
  24.                             local slashcmd=cmdcheck:sub(2):lower();--   Skip the slash for the emote command
  25.                             if slashcmd==cmd:lower() then-- Command matches, token found
  26.                                 token=tokencheck;
  27.                                 break;
  28.                             end
  29.  
  30. --                          Increment command
  31.                             cmdcheck,cmdid=_G["EMOTE"..tokenid.."_CMD"..(cmdid+1)],cmdid+1;
  32.                         end
  33.  
  34. --                      Break if token found
  35.                         if token then break; end
  36.  
  37. --                      Increment token
  38.                         tokencheck,tokenid=_G["EMOTE"..(tokenid+1)"_TOKEN",tokenid+1;
  39.                     end
  40.  
  41.                     if token then
  42.                         DoEmote(token,arg);--   Performs the same emote operation as supported by chat
  43.                     else
  44.                         Send(j,"EMOTE");
  45.                     end
  46.                 end
  47.             end
  48.         end
  49.     else
  50.         Send(msg,chan,...);
  51.     end
  52. end
So basically, I could take that code, put it in a .lua file, write a .toc file for it, put them in a folder and place it in the AddOns folder, and it'll work right out of the box? (Though it'd probably be better if someone who knows their way around the stuff does it, so that more people than just myself can benefit from it. )
  Reply With Quote
04-17-11, 04:07 AM   #10
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
Yes, you just gotta write it a .toc and put it in a folder so it becomes an addon.

Anyway gonna put this here http://pastey.net/149152 and now I can delete the local file from my PC, hehe.

Both will work, you pick what ever you like.
  Reply With Quote
04-17-11, 07:04 AM   #11
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
It would be cool if a full-fledged addon was made for this (as I doubt I'm the only one who finds this a handy thing to be able to do), but it looks like I've got what I was looking for. Thanks a lot for the help, both of you.

EDIT: It seems I've run into a couple of issues. I can't seem to get the version from you, SDPhantom, working, even though I'm certain I've got everything right; and the one from you, Vladinator, is working as it should but locks the game up if the *emote* comes before the Say message.
  Reply With Quote
04-18-11, 12:20 AM   #12
Jigain
A Molten Giant
 
Jigain's Avatar
Join Date: Jul 2009
Posts: 732
There's an addon called TotalRP 2 that does just what you're asking for, and more.

It hasn't updated in quite a while though. While it still works, I don't know if it's a discontinued project.
__________________


  Reply With Quote
04-18-11, 02:34 AM   #13
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
Originally Posted by Jigain View Post
There's an addon called TotalRP 2 that does just what you're asking for, and more.

It hasn't updated in quite a while though. While it still works, I don't know if it's a discontinued project.
Yeah, I know of that one. It's what I referred to in the opening post. But I don't need all the other things it offers in addition to this; I just want that one feature.
  Reply With Quote
04-18-11, 04:29 AM   #14
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
Are you sure you're doing it the right way? Otherwise this thread might help:

http://www.mmo-champion.com/threads/...lve-easy-steps
  Reply With Quote
04-18-11, 04:50 AM   #15
Aurorablade
A Deviate Faerie Dragon
 
Aurorablade's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2005
Posts: 16
Well i maintain the addon tongues and may add this to the addon come next update, but given that would you still want just this in an addon cuase i will see what i can do.

Edit:And there was an error i found and fixed
line 38 should be
tokencheck,tokenid=_G["EMOTE"..(tokenid+1).."_TOKEN"],tokenid+1;

and its not stripping the trailing * at the moment.
  Reply With Quote
04-18-11, 05:07 AM   #16
Aurorablade
A Deviate Faerie Dragon
 
Aurorablade's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2005
Posts: 16
this should works maybe unless i made a glareing error

Code:
local Send=SendChatMessage;
function SendChatMessage(msg,chan,...);
    chan=chan:upper();--    Convert to make checks easier (channel is case-insensitive)
    if chan=="SAY" then
 local pieces={strsplit("*",msg:gsub("%s*%*%s*","%*"))};
 
--      Iterate through pieces
        for i,j in ipairs(pieces) do
            if #j>0 then--  Don't do anything if string is empty
                if i%2>0 then-- Evaluates to 1 if say, 0 if emote
                   Send(j,chan);
				   
                else
--                  Try to separate command and args
                    j=strsplit("*", j)
                    local cmd,arg=j:match("(%S+) (.+)");
                    if not cmd then cmd=j; end
                       
--                  This is tricky, we need to check if the emote slash command exists
                    local token;
                    local tokencheck,tokenid=EMOTE1_TOKEN,1;
                    while tokencheck do
                        local cmdcheck,cmdid=_G["EMOTE"..tokenid.."_CMD1"],1;
                        while cmdcheck do
                            local slashcmd=cmdcheck:sub(2):lower();--   Skip the slash for the emote command
                            if slashcmd==cmd:lower() then-- Command matches, token found
                                token=tokencheck;
                                break;
                            end
 
--                          Increment command
                            cmdcheck,cmdid=_G["EMOTE"..tokenid.."_CMD"..(cmdid+1)],cmdid+1;
                        end
 
--                      Break if token found
                        if token then break; end
 
--                      Increment token
                        tokencheck,tokenid=_G["EMOTE"..(tokenid+1).."_TOKEN"],tokenid+1;
                    end
 
                    if token then
                        DoEmote(token,arg);--   Performs the same emote operation as supported by chat
                    else
					    
                       Send(j,"EMOTE");
                    end
                end
            end
        end
		
	  else
        Send(msg,chan,...);
    end
end
  Reply With Quote
04-18-11, 09:07 AM   #17
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
Hehe, fixed it in case you wish to look to learn or anything. http://pastey.net/149174 -not the only way to do this, I'm glad Aurorablade posts his variant too!
  Reply With Quote
04-18-11, 02:02 PM   #18
Aurorablade
A Deviate Faerie Dragon
 
Aurorablade's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2005
Posts: 16
Wells its SDs variant i just fixed a few things.. I think.
  Reply With Quote
04-18-11, 02:16 PM   #19
Folji
A Flamescale Wyrmkin
 
Folji's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 136
Heh, wow. I come back at the end of the day to check for replies, and all the troubles I had earlier have been taken care of. Thanks a lot everyone (again).
  Reply With Quote
04-19-11, 03:51 AM   #20
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by Aurorablade View Post
there was an error i found and fixed
line 38 should be
tokencheck,tokenid=_G["EMOTE"..(tokenid+1).."_TOKEN"],tokenid+1;
Corrected missing second concatenation operator in my post above.
Thanks for pointing it out.

Originally Posted by Aurorablade View Post
and its not stripping the trailing * at the moment.
Line 10 should handle a leading and/or trailing asterisk with a check for a zero-length string. A leading asterisk should cause the first element to be zero-length and a trailing asterisk would have it as the last element. In either case, the entire string is skipped and the code moves on to the next piece. Unless there's a glitch in the API, strsplit() shouldn't return string pieces containing the delimiter.





Edit: Maybe I should run my code through the game next time before posting, lol.
The following has been fixed in my above code:
-Removed the ";" at the end of the parameter list.
-Fixed more of line 38, missing end bracket for index.
-Replaced strsplit() with alternate code. (Function returns didn't match documentation.)
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 04-19-11 at 04:43 AM.
  Reply With Quote

WoWInterface » AddOns, Compilations, Macros » AddOn Search/Requests » Addon to split *emotes* out of messages

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