Thread Tools Display Modes
03-05-18, 08:59 PM   #1
Eungavi
A Theradrim Guardian
Join Date: Nov 2017
Posts: 64
Detecting a spell sound or registering a callback on it

Hiya!

As the title says...
Would it be possible to detect a spell sound or register a callback on it?

I'm asking this because of Bag of Tricks (192657) and afaik, it doesn't show any GUI indications on both player and enemies, but only a sound effect or AoE texture on floor when it pops

Any ideas, please?

Thank you!

Last edited by Eungavi : 03-05-18 at 09:03 PM.
  Reply With Quote
03-06-18, 12:14 AM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
You can't detect when a specific sound is played (unless it was played by the UI code or an addon) but you can detect when a spell is cast.

Try this:
Code:
local f = CreateFrame("Frame")
f:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", "player")
f:SetScript("OnEvent", function(self, event, unit, spellName, _, lineID, spellID)
	if spellID == 192657 then
		DEFAULT_CHAT_FRAME:AddMessage(string.format("%s was cast!", GetSpellLink(spellID)))
	end
end)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
03-06-18, 01:13 AM   #3
Eungavi
A Theradrim Guardian
Join Date: Nov 2017
Posts: 64
Originally Posted by Phanx View Post
You can't detect when a specific sound is played (unless it was played by the UI code or an addon) but you can detect when a spell is cast.

Try this:
Code:
-- Phanx' code
Hi Phanx,

Just tried your approach and seems like this particular spell cannot be tracked that way :/
I also attempted printing all those succeeded spells' name and id, but no luck...

Lua Code:
  1. local f = CreateFrame("Frame")
  2. f:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", "player")
  3. f:SetScript("OnEvent", function(self, event, unit, spellName, _, lineID, spellID)
  4.     print(spellName, spellID); -- Still not printing for Bag of Tricks (192657) nor for Poison Bomb (192660)
  5.  
  6.     --if spellID == 192657 then
  7.     --  DEFAULT_CHAT_FRAME:AddMessage(string.format("%s was cast!", GetSpellLink(spellID)))
  8.     --end
  9. end)
  Reply With Quote
03-06-18, 01:57 AM   #4
Eungavi
A Theradrim Guardian
Join Date: Nov 2017
Posts: 64
The major goal is to track the start time and expiration of Poison Bomb (192660) and since the duration is fixed to 3 seconds, the expiration could be easily calculated, but obtaining a start time is bit complicating.

I had a go with COMBAT_LOG_EVENT_UNFILTERED and thankfully(?), it does track the damage done via Poison Bomb, but there is still a case where the Poison Bomb is newly applied before the previous one is expired
  Reply With Quote
03-06-18, 05:24 PM   #5
Banknorris
A Chromatic Dragonspawn
 
Banknorris's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 153
Usually when you apply a dot, hot, aura on a target that does not have it from you, you get a SPELL_AURA_APPLIED as your combat log sub event and when reapplying a non-expired dot, hot, aura you get a SPELL_AURA_REFRESH sub-event instead. Maybe that is the case.
__________________
"In this world nothing can be said to be certain, except that fractional reserve banking is a Ponzi scheme and that you won't believe it." - Mandrill
  Reply With Quote
03-07-18, 12:19 AM   #6
Eungavi
A Theradrim Guardian
Join Date: Nov 2017
Posts: 64
Originally Posted by Banknorris View Post
Usually when you apply a dot, hot, aura on a target that does not have it from you, you get a SPELL_AURA_APPLIED as your combat log sub event and when reapplying a non-expired dot, hot, aura you get a SPELL_AURA_REFRESH sub-event instead. Maybe that is the case.
Hi Banknorris,

The first thing that I've done with COMBAT_LOG_EVENT_UNFILTERED was to see which sub events are fired with those spells (192657 and 192660).

Lua Code:
  1. local f = CreateFrame("Frame")
  2. f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
  3. f:SetScript("OnEvent", function(self, event, ...)
  4.     local _, subEvent, _, sourceGUID, _, _, _, _, _, _, _, spellID = ...
  5.  
  6.     if sourceGUID == UnitGUID("player") and (spellID and (spellID == 192660 or spellID == 192657)) then
  7.         local spellName = GetSpellInfo(spellID)
  8.         print(subEvent, spellID, spellName)
  9.     end
  10. end)

Sadly, the only sub event fired was SPELL_DAMAGE



If I'm guessing correctly, SPELL_AURA_APPLIED and SPELL_AURA_REFRESH are not fired since this spell doesn't even apply any debuff on enemies.

So... yeah :/

Last edited by Eungavi : 03-07-18 at 04:42 AM.
  Reply With Quote
03-07-18, 04:13 PM   #7
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
I would be very surprised if UNIT_SPELLCAST_SUCCEEDED didn't fire for this spell.

Try using RegisterEvent instead of RegisterUnitEvent, and then filter by source after you determine if it fires.

RegisterUnitEvent sometimes doesn't behave the way you would expect it to.

Also don't assume you have the spell IDs correct, watch for the spell name if you need to filter it or just don't filter it at all if it isn't too spammy, then once you know you have the right spell ID you can watch for that.

Occasionally scripted spells aren't considered "cast" by the player and can't be tracked directly, but they're relatively uncommon.

Last edited by semlar : 03-07-18 at 04:40 PM.
  Reply With Quote
03-07-18, 05:49 PM   #8
Eungavi
A Theradrim Guardian
Join Date: Nov 2017
Posts: 64
Originally Posted by semlar View Post
I would be very surprised if UNIT_SPELLCAST_SUCCEEDED didn't fire for this spell.

Try using RegisterEvent instead of RegisterUnitEvent, and then filter by source after you determine if it fires.

RegisterUnitEvent sometimes doesn't behave the way you would expect it to.

Also don't assume you have the spell IDs correct, watch for the spell name if you need to filter it or just don't filter it at all if it isn't too spammy, then once you know you have the right spell ID you can watch for that.

Occasionally scripted spells aren't considered "cast" by the player and can't be tracked directly, but they're relatively uncommon.
Hi semlar,

Just had a shot with RegisterEvent (instead of RegisterUnitEvent) as you've advised, but yeah...... It's still not getting it...

Lua Code:
  1. local f = CreateFrame("Frame")
  2. f:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
  3. f:SetScript("OnEvent", function(self, event, ...)
  4.     local _, spellName, _, _, spellID = ...
  5.     print(spellName, spellID)
  6. end)



In addition to this, I've tried to print all available results from COMBAT_LOG_EVENT_UNFILTERED, but same for this one.

Lua Code:
  1. local f = CreateFrame("Frame")
  2. f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
  3. f:SetScript("OnEvent", function(self, event, ...)
  4.     local _, subEvent, _, _, _, _, _, _, _, _, _, spellID = ...
  5.     local spellName = GetSpellInfo(spellID)
  6.  
  7.     if spellName then
  8.         print(subEvent, spellID, spellName)
  9.     end
  10. end)



The only sub event fired for a poison bomb related spell is SPELL_DAMAGE.

Hm..................... This is so tricky

Last edited by Eungavi : 03-07-18 at 06:00 PM.
  Reply With Quote
03-07-18, 06:53 PM   #9
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
If the only thing you can watch that even identifies whether the spell has procced is SPELL_DAMAGE, and it only has a chance of happening after casting Envenom or Rupture, then you can possibly measure the time difference between the SPELL_DAMAGE event and when the last Envenom or Rupture was cast (on the same target) to gauge whether it was spawned by a new cast or not.

This relies on relatively stable timings, so it might not be a particularly good solution, but it doesn't look like there are a lot of alternatives here.

You can also judge by how frequently the damage ticks are happening on a particular target (eg. if the pool ticks every 0.5ish seconds, but the mob took 2 hits before the next tick should have happened, there must be more than one out).

I pulled up a random assassination rogue on warcraftlogs to check timings, it might help you with this if you want to go that route.

Last edited by semlar : 03-07-18 at 07:22 PM.
  Reply With Quote
03-07-18, 07:47 PM   #10
Eungavi
A Theradrim Guardian
Join Date: Nov 2017
Posts: 64
I have not deeply considered the first solution yet, but since the second solution also came across my mind, I have thought of some possible cases.

You are right. The duration of this spell is 3 seconds and according to COMBAT_LOG_EVENT_UNFILTERED, this ticks every 0.5ish second and in total does 6 ticks.

BUT, I ain't sure if this is affected by haste...

1. Poison Bomb A (pbA) and Poison Bomb B (pbB)

Let's say pbA did spawn and already did some damage ticks. But, what if pbB newly spawns and does its first tick damage on the same time as pbA's next tick?

I know the chance is SUPER low, but theoretically it is possible, isn't it?

2. Poison Bomb A (pbA) + Enemy A (eA) and Enemy B (eB)

There's only one poison bomb, pbA, spawned underneath eA which already did couple of damage ticks, then eB suddenly jumps onto pbA. If poison bomb ticks same for both creature no matter whether they jumped on late or not, that should be fine. However, what if that single poison bomb ticks differently for each creatures?

This could be confirmed by testing, but I currently can't enter the game :/




EDIT #1 Thank you for warcraftlogs link!

I'll have a look into it

EDIT #2 I guess your first solution would be more suitable in this case.

It's more reasonable, straight-forward and just makes more sense. But, would still need more consideration to identify whether it's new cast or not.

According to the log, poison bombs are mostly spawned within 0.6 second after Rupture or Envenom, but there is still a case where it's spawned only 0.062 second after Rupture OR where the current poison bomb's next tick is still done within 0.6 second after Rupture or Envenom.

Last edited by Eungavi : 03-07-18 at 08:14 PM.
  Reply With Quote
03-07-18, 08:18 PM   #11
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Originally Posted by Eungavi View Post
1. Poison Bomb A (pbA) and Poison Bomb B (pbB)

Let's say pbA did spawn and already did some damage ticks. But, what if pbB newly spawns and does its first tick damage on the same time as pbA's next tick?

I know the chance is SUPER low, but theoretically it is possible, isn't it?
It is possible, but if you have 2 ticks of damage on the same target at the same time you know it's coming from two different pools.
Originally Posted by Eungavi View Post
2. Poison Bomb A (pbA) + Enemy A (eA) and Enemy B (eB)

There's only one poison bomb, pbA, spawned underneath eA which already did couple of damage ticks, then eB suddenly jumps onto pbA. If poison bomb ticks same for both creature no matter whether they jumped on late or not, that should be fine. However, what if that single poison bomb ticks differently for each creatures?
From the logs, the damage hits all targets affected by the pool at the same time, but if you're specifically tracking the unit that the spell was cast on then it won't matter (Envenom's target). The only thing I'd worry about is if the pool can potentially be cast, but not hit its initial target, like if Envenom kills its target and then spawns a pool at its location (if that's even possible).

I didn't notice overlapping casts of Poison Bomb in the couple of logs I looked at, so I'm not sure how common this is, or how important it is to track separate instances of it for whatever it is that you're creating.

Originally Posted by Eungavi View Post
According to the log, poison bombs are mostly spawned within 0.6 second after Rupture or Envenom, but there is still a case where it's spawned only 0.062 second after Rupture OR where the current poison bomb's next tick is still done within 0.6 second after Rupture or Envenom.
It looked like the log I linked was showing Rupture ticks but not the initial cast of it, so a different cast may have spawned the pool. You can see the casts here, I'm not sure if there's a way to merge this with the other list (which is only showing damage).

Alright, I think this graph should show both the casts and the damage events in the same list.

Last edited by semlar : 03-07-18 at 08:26 PM.
  Reply With Quote
03-07-18, 08:51 PM   #12
Eungavi
A Theradrim Guardian
Join Date: Nov 2017
Posts: 64
Originally Posted by semlar View Post
The only thing I'd worry about is if the pool can potentially be cast, but not hit its initial target, like if Envenom kills its target and then spawns a pool at its location (if that's even possible).
I guess this is strongly possible!

Originally Posted by semlar View Post
Alright, I think this graph should show both the casts and the damage events in the same list.
Damn... warcraftlogs seems super handy... The only thing that I could've done with it is just checking my scores D:


+ Guess I should do some research (or experiment) on how Poison Bomb works.
  Reply With Quote
03-14-18, 10:11 AM   #13
Eungavi
A Theradrim Guardian
Join Date: Nov 2017
Posts: 64
So, here's what I've got so far.
(It took a time... I know... I was just lazy and didn't do any research or test for a week )

According to the log that semlar had provided, the first tick of poison bomb normally occurs about 0.5 seconds after either by envenom or rupture cast.

Here's the calculation that I've done with that log.

Code:
00:00:06.778	Rupture
00:00:07.332	Poison Bomb	+00:00:00.554
00:00:07.817	Poison Bomb	+00:00:00.485
00:00:08.319	Poison Bomb	+00:00:00.502
00:00:08.838	Poison Bomb	+00:00:00.519
00:00:09.317	Poison Bomb	+00:00:00.479
00:00:09.827	Poison Bomb	+00:00:00.510

00:00:26.173	Envenom
00:00:26.741	Poison Bomb	+00:00:00.568
00:00:27.221	Poison Bomb	+00:00:00.480
00:00:27.704	Poison Bomb	+00:00:00.483
00:00:28.240	Poison Bomb	+00:00:00.536
00:00:28.721	Poison Bomb	+00:00:00.381
00:00:29.223	Poison Bomb	+00:00:00.502

00:01:11.232	Envenom
00:01:11.779	Poison Bomb	+00:00:00.547
00:01:12.265	Poison Bomb	+00:00:00.486
00:01:12.792	Poison Bomb	+00:00:00.527
00:01:13.326	Poison Bomb	+00:00:00.534
00:01:13.770	Poison Bomb	+00:00:00.444
00:01:14.289	Poison Bomb	+00:00:00.519

00:01:18.972	Envenom
00:01:19.507	Poison Bomb	+00:00:00.535
00:01:20.013	Poison Bomb	+00:00:00.506
00:01:20.491	Poison Bomb	+00:00:00.478
00:01:21.004	Poison Bomb	+00:00:00.513
00:01:21.503	Poison Bomb	+00:00:00.499
00:01:21.991	Poison Bomb	+00:00:00.488

00:01:41.702	Rupture
00:01:42.270	Poison Bomb	+00:00:00.568
00:01:42.739	Poison Bomb	+00:00:00.469
00:01:43.242	Poison Bomb	+00:00:00.503
00:01:43.765	Poison Bomb	+00:00:00.523
00:01:44.261	Poison Bomb	+00:00:00.496
00:01:44.761	Poison Bomb	+00:00:00.500

00:02:35.440	Rupture
00:02:35.972	Poison Bomb	+00:00:00.532
00:02:36.499	Poison Bomb	+00:00:00.527
00:02:36.975	Poison Bomb	+00:00:00.476
00:02:37.474	Poison Bomb	+00:00:00.499
00:02:37.967	Poison Bomb	+00:00:00.493
00:02:38.480	Poison Bomb	+00:00:00.513

And here's the most cheaty way that I could think of...

Lua Code:
  1. local finisherTimeStamp;
  2.  
  3. local f = CreateFrame("Frame")
  4. f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
  5. f:SetScript("OnEvent", function(self, event, ...)
  6.     if event == "COMBAT_LOG_EVENT_UNFILTERED" then
  7.         local timeStamp, subEvent, _, sourceGUID, _, _, _, destGUID, _, _, _, spellID = ...
  8.  
  9.         if sourceGUID ~= UnitGUID("player") then
  10.             return
  11.         end
  12.  
  13.         if subEvent == "SPELL_CAST_SUCCESS" and (spellID == 32645 or spellID == 1943) then
  14.             finisherTimeStamp = timeStamp
  15.         elseif subEvent == "SPELL_DAMAGE" and spellID == 192660 then
  16.             local timeStampGap = timeStamp - finisherTimeStamp
  17.  
  18.             if timeStampGap >= 0.4 and timeStampGap <= 0.6 then
  19.                 print("POISON BOMB!")
  20.             end
  21.         end
  22.     end
  23. end)

This is working fine against single training dummy. And since semlar had confirmed that the single poison bomb pool works equally against multiple targets even if they jump in late, that's not a problem. However, in case if I'm in raid or mythic+ where I could fire those finishers fast enough which didn't even spawn new poison bomb pool, but has a time stamp gap between 0.4 and 0.6 with existing pool's damage tick...

Like semlar questioned, spawning two overlapping pools are pretty rare cases, but still possible and sometimes it's quite easy to observe especially when encountering bosses or large number of trashes. However, since the poison bomb is not visible by other group members (especially by TANKS) lots and lots of pools are wasted and ultimately you'll lose tons of DPS which depresses me playing Assassination rogue

I wish WoW Dev team to revise such spells and make it more flexible (or visible) so that it could be easily tracked with Lua.

Last edited by Eungavi : 03-14-18 at 10:29 AM.
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Detecting a spell sound or registering a callback on it

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