WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   General Authoring Discussion (https://www.wowinterface.com/forums/forumdisplay.php?f=20)
-   -   Attempting to track emotes performed on targets. (https://www.wowinterface.com/forums/showthread.php?t=56050)

briskman3000 02-16-18 07:23 PM

Attempting to track emotes performed on targets.
 
Greetings,

I had a guildy ask for (probably joking) for an addon to track how many times he performed a certain standard emote (ex /bonk or /silly) on different people. So I was bored and tried to see if I could figure this out and I hit a wall.

When you perform a standard emote, it fires the event CHAT_MSG_TEXT_EMOTE. The problem with that event, is that it lacks the actual information that I would want to capture for tracking. The event output args don't actually tell you which emote fired (it does capture the emote string that is output to chat) or who you emoted at.

My thoughts on capturing this data after discovering that the event is almost useless, would be the following:
  1. Watch for the event to fire
  2. Store the current target name in a variable
  3. Perform pattern matching on the text output to determine the emote
  4. And if the emote is one we are tracking, add the occurrence to the table counting that emote for the target.

This sounds like it could work, but I would have to build a table of the emotes that I want to track and their output text first which could get pretty big if I wanted to make the addon customizable.

Anyone have any thoughts on how to accomplish this an easier , or at the very least less convoluted way?

Kanegasi 02-16-18 08:33 PM

Check out the blizzard function that actually handles emote commands, ChatEdit_ParseText. When you use an emote, it checks the table hash_EmoteTokenList, which has every emote in the game, organized by command (key) and what emote it calls (value). If the command used matches this table, it passes the value of that table to DoEmote().

What you can do is hooksecurefunc DoEmote() and cache the first argument, then when CHAT_MSG_TEXT_EMOTE fires, you now have confirmation a valid emote was fired, what emote was used, and the target without needing to parse the actual text from the event. If there's no target unit, then the emote wasn't used on anyone.

briskman3000 03-29-18 07:56 PM

OK .... so after much trial and error, I've hit a wall. I successfully set up all of my conditionals to check to see if my target is the unit type I want, grab the target's name, and check to see if the emote used is the one that I want to track.

I store the target's name into a variable, and I am attempting to use the name variable as a key in a table, and then the value for that key is numerical. I'm pretty sure that I'm going about this wrong, as when I attempt to add the value to the table, and then immediately print() it, I get no output. The error is most likely something simple in my for loop syntax, but I can't seem to figure out what I am doing wrong.

Lua Code:
  1. --Create the table
  2. bonktrack = {}
  3.  
  4. local emotetype, btname
  5.  
  6. local function btracker(token)
  7.     emotetype = token
  8.     --print(emotetype)
  9.     btname = GetUnitName("target", true)
  10.     tartype = UnitIsPlayer("target")
  11.     --print(tartype)
  12.     --print(btname)
  13.     if tartype == true then
  14.         if btname ~= nil then
  15.             if emotetype == "BONK" then
  16.                 --print("Success")
  17.                 for k, v in pairs(bonktrack) do
  18.                     if bonktrack[btname] then
  19.                         bonktrack[btname] = bonktrack[btname] + 1
  20.                         print(bonktrack[btname] .. " Added")
  21.                     else
  22.                         table.insert(btname, 1)
  23.                         print(bonktrack[btname] .. " Init")
  24.                     end
  25.                 end
  26.             else
  27.                 print("BONK fail")
  28.             end
  29.         else
  30.             print("btname fail")
  31.         end
  32.     else
  33.         print("Not a player or no target")
  34.     end
  35. end
  36. hooksecurefunc("DoEmote", btracker)

Ammako 03-29-18 08:47 PM

k, v are the values being iterated through in your for loop (k = key, v = value)

You use those variables in the loop and it "increments" through to the next key/value every time it loops through.

Example usage:

lua Code:
  1. local function contains(table, element)
  2.     for _, value in pairs(table) do
  3.         if value == element then
  4.             return true
  5.         end
  6.     end
  7.     return false
  8. end

Kanegasi 03-29-18 08:48 PM

When you first use this code, the loop doesn't do anything because the table is empty. There's nothing to loop through, so that if statement never happens.

Instead of a loop, use a ternary statement:

Lua Code:
  1. if emotetype == "BONK" then
  2.     --print("Success")
  3.     bonktrack[btname] = bonktrack[btname] and bonktrack[btname]+1 or 1
  4.     print("BONKed " .. btname .. " " .. bonktrack[btname] .. " times")
  5. else
  6.     print("BONK fail")
  7. end

The line after the commented print is called a ternary statement or operator. I have also seen "logic shorthand". When Lua parses this, which is variable = logic statement, it skips the rest of it when it reaches something true and returns the value of the last part of the true statement, whether it's true itself (the boolean value) or a non-false/non-nil value (result of math, another variable, the return from a function, etc). In this case, if there's a value at bonktrack[btname], it returns that value+1 into that key. If that key is nil, it skips the +1 and just sets it at 1.

briskman3000 03-30-18 07:35 PM

Quote:

Originally Posted by Kanegasi (Post 327396)
Snip

Thanks this helped alot.


All times are GMT -6. The time now is 11:01 AM.

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