Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[Script] Critical Sound Effects v1.0

1476905517

Edited 1476905650
I created a script using the API that will play a specific sound in the jukebox any time one of my players rolls a natural 20 or natural 1. I figured some people might be interested in using it, so I put it up on GitHub for you guys: github.com/catlinbuckley/roll20criticalhitorfail Setup: Install the script on Roll20, then select 2 sounds in the Jukebox. Name one sound 'Critical Hit' and the other 'Critical Fail'. The script will automatically play these sounds when a player rolls a natural 20 or natural 1 on a d20. By default, the GM is excluded from these rolls (I do a lot of rolling, so it would get annoying). However, if you want to include the GM, just set excludeGM to false at the top of the script. This is one of my first scripts so any feedback is appreciated.
1476906988
The Aaron
Pro
API Scripter
This is a great first script!  Very clean.  I do have a few suggestions for you, since you asked for feedback.  • I noticed you have a list of player ids that you're checking against.  You can probably replace all that with the  playerIsGM() function to determine if the chat message is from a GM.  Note that this respects if the GM rejoins as a player and reports them as not a GM in that case. • You might consider adding checking for crits in ranges, say for things like [[1d20cs>18]].  That information is provided in the roll data, though it's a bit complicated to parse.  I write a short example for someone a few weeks ago which you might find useful to look at: on('ready',function(){     'use strict'; var getCritComparitor = function(roll){ let comp=[]; if(_.has(roll,'mods') && _.has(roll.mods,'customCrit')){ _.each(roll.mods.customCrit,function(cc){ switch(cc.comp){ case '<=':comp.push((o)=>o<=cc.point);break; case '==':comp.push((o)=>o==cc.point);break; case '>=':comp.push((o)=>o>=cc.point);break; } }); } else { comp.push((o)=>o==roll.sides); }  return function(v){             let crit=false; _.find(comp,(f)=>crit=crit||f(v));             return crit; }; }; var isCrit = function(roll){ let comp=getCritComparitor(roll); _.each(roll.results,(r)=>{ if(comp(r.v)){ sendChat('isCrit',`The ${r.v} is a critical!`); } }); }; on('chat:message',function(msg){ if(msg.inlinerolls){ _.each(msg.inlinerolls,(ir)=>_.each(ir.results.rolls,(irrr)=>isCrit(irrr))); } }); }); That is only the criticals, not the failures, but you get the idea. • I think the implementation of JSON.parse() in the API returns undefined on failure, rather than throwing an exception.  I'll have to check that, but I think your isJson() function will always return true. • You might enjoy rewriting your song lookup using the  filterObjs() function, which allows you to supply a function for matching.  You could even forgo the return with something akin to:     var criticalHit = {},         criticalFail = {};     filterObjs((o)=>{         if( 'jukeboxtrack' === o.get('type')) {             if('Critical Hit' === o.get('title')){                 criticalHit = o;             } else if('Critical Fail' === o.get('title')){                 criticalFail = o;             }         }     }), Not much different, but an option (and only a single traversal). • It's always nice to include a version number in the code, just so if you end up helping someone with it and you've made modifications you can know what one they've got. I hope you go on to write more scripts!  Happy Rolling!
Thanks for the feedback. I'll make those changes you suggested.
Cool!
1477164320

Edited 1477164492
I was hoping to find a script which will give me text commands for the jukebox. Is there a way I could tear apart this script to get it to play jukebox tracks by name? !jukebox -TrackNameGoesHere I think thats a....callback? I want it for use in macros. I love this idea. I think it would be great if you used the damage type to denote the critical strike track. Critical failures can just have that Wah-wah-wah-waaaaa~aaaaah noise but I'd like some distinct noises for my players crit with his greatsword (slashing damage) or an arrow strike (piercing/ranged).
1477187153
Pat
Pro
API Scripter
Simple, elegant and very cool.  Excellent job Catlin!
Avatar of Woah, I like that idea about using !jukebox to queue up tracks. If you take a look at the latest code (not release), I started implementing something along those lines last night. It's rough right now, but the functionality is there. Just type !jukebox and it'll give you some options.
1479211416
Mike W.
Pro
Sheet Author
Is it hard coded to work only for a 20 or a 1 ? If it is, could it be changed to allow the GM to input the numbers via a command line to set them? For example: I play GURPS and automatic Critical Successes are on a 3 or 4 (3d6) and an automatic Critical Failure is on an 18 (3d6). Mind you GURPS has other levels of Critical Failures and Critical Successes, but that depends on the margin of failure or success when the die roll is made against a Target number. Might be nice to program that in there as well but for now to able to change to a 3,4 or 18 woudl be the first step for me.
Does this script still work as intended, ive set my gm value to false and ive tried just randomly rolling 1d20s over and over to hear the sound and it never plays.  I have the name set to 'Critical Hit' and 'Critical Fail' and they never play when I or a player rolls a natural 20. Ive tried it without the quotes as well. 
Ryan, there was a bug in the version you are using. When I added extra commands for extended jukebox controls, I introduced a bug where the critical sound effects wouldn't play. I just posted a fix in the latest release
Can I recomend another script based on this one? So, now that we have BattleBards sounds and they have a bunch of sound effects for sword hitting, shooting arrows, and doing magic. Could we have an scrip for adding a specific sound to a macro. For ex: All my players have the "&{default}" macros from SRD5 for attacks e some spells. When the Rogue for example, hits the Dagger-Attack macro,  the jukebox plays one effect from Battlebards.  I Livestream my tables and it would be awesome for role play.  Thanks! And sorry for my bad english...
1482857207
Z
Pro
Sheet Author
to make it so it will play sound for rolls the GM makes but not for /gr rolls, change line 129 to:  if (!playerIsGM(msg.playerid) || !excludeGM && msg.type !== "gmrollresult") {
Thanks, Z. I've committed the update you suggested so /gr rolls should be ignored if excludeGM is set.
1488018344

Edited 1488026955
Mal
Plus
I just tried it out and I love it. However there's an issue..! With the new 5e shaped update you can query rolls. So, if I roll "normal" with query sometimes it still plays the sounds, and I think thats due to some hidden extra d20 somewhere. Is there any way around this? EDIT: Actually its even without query. 
Hey Mal, I noticed this as well when I updated to the new shaped one. I'll take a look at it once I have time and let you know when it's been fixed.
Awesome! Much appreciated :))
1488170054

Edited 1488203273
Hey Mal, I think I have fixed the issue. I also expanded the script to allow for the shaped custom crits. That way it won't only hit on a 20 if the weapon has a lower crit range (like 19-20... etc). You can get it at&nbsp; <a href="https://github.com/catlinbuckley/roll20criticalhitorfail/releases/tag/1.2.1" rel="nofollow">https://github.com/catlinbuckley/roll20criticalhitorfail/releases/tag/1.2.1</a> Looking at the script, it was getting a bit bloated with the extra jukebox controls so I split it off into a separate project. If you'd like to keep that functionality, check out&nbsp; <a href="https://github.com/catlinbuckley/roll20jukeboxcontrol/releases/tag/1.0.0" rel="nofollow">https://github.com/catlinbuckley/roll20jukeboxcontrol/releases/tag/1.0.0</a> Let me know if you have any more issues and I'll try and get them resolved. Thanks for using my script!
Forgive my ignorance, but your current script has both V1.2 and&nbsp;v1.1.1 in it. I've tried both with and removing the V1.1.1 bit but I just keep getting a syntax error. "SyntaxError: Unexpected end of input" Can you advise? Thanks!
Tom, Sorry, I botched a merge and that's why it's like that. Here's the fix:&nbsp; <a href="https://github.com/catlinbuckley/roll20criticalhitorfail/releases/tag/1.2.1" rel="nofollow">https://github.com/catlinbuckley/roll20criticalhitorfail/releases/tag/1.2.1</a>
Great, I'm gonna try it out and see if it works out during today's game :)
Thanks Catlin!
I love this idea! Alas, it doesn't deal with more than one d20, it will crash the sandbox. /roll 2d20 TypeError: Cannot read property '0' of undefined TypeError: Cannot read property '0' of undefined at keptResultIsCriticalHit (apiscript.js:23352:58) at apiscript.js:23339:25 at Array.forEach (native) at criticalHitOrFail (apiscript.js:23313:27) at apiscript.js:23308:17 at eval (eval at (/home/node/d20-api-server/api.js:146:34), :65:16) at Object.publish (eval at (/home/node/d20-api-server/api.js:146:34), :70:8) at /home/node/d20-api-server/api.js:1510:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147)
1489454178

Edited 1489543673
Hi Thorsten, Thanks for posting the bug. I looked into the issue and pushed a fix. The latest release should resolve your issue. <a href="https://github.com/catlinbuckley/roll20criticalhitorfail/releases/tag/v1.2.2" rel="nofollow">https://github.com/catlinbuckley/roll20criticalhitorfail/releases/tag/v1.2.2</a>
That did the trick, thank you!
I found another bug. This script can be crashed by typing a number into chat, such as: 600 The sandbox then stops with: TypeError: Cannot read property 'forEach' of undefined TypeError: Cannot read property 'forEach' of undefined at criticalHitOrFail (apiscript.js:23591:26) at apiscript.js:23586:17 at eval (eval at (/home/node/d20-api-server/api.js:146:1), :65:16) at Object.publish (eval at (/home/node/d20-api-server/api.js:146:1), :70:8) at /home/node/d20-api-server/api.js:1510:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546) at Id.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:489) at Zd.Ld.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:94:425)
Getting the same problem as Thorsten
Sorry for the slow reply. I was on vacation and didn't have access to a computer. I've posted a fix that should resolve your issue. Thanks for all the feedback! <a href="https://raw.githubusercontent.com/catlinbuckley/roll20CriticalSoundEffects/master/roll20CriticalHitOrFail.js" rel="nofollow">https://raw.githubusercontent.com/catlinbuckley/roll20CriticalSoundEffects/master/roll20CriticalHitOrFail.js</a>
That fixed it, thanks!
Does this interrupt other SFX?
No, it shouldn't. I've played with music in the background and the sound effects just play over whatever is currently playing.
I'm using PowerCards to spit out simple 1d20 rolls. &nbsp;I'm getting sounds played on things that are not 1 or 20.
1494292895

Edited 1494418468
Is there any way of doing this for when someone hits 0 life?&nbsp;&nbsp; Is it possible to have it pick from a randomised list?&nbsp; Critical Hit 1, Critical Hit 2, Critical Hit 3?&nbsp; Does it play over itself if someone somehow manages two criticals in a row? Biggest question does it differentiate between skills and attacks?&nbsp; Would it be able to somehow? This could be really epic if it had these things. It'd be an amazing way to automate a lot of the highs and lows of a flowing combat.&nbsp;
Ron, I will take a look tonight and see if I can get a fix for you. Volomon, it may be possible to play a sound when someone hits 0 life, but that would be pretty different from how I'm handling rolls so it may take a while.. I'll add that to the list of feature requests and look into it. The script does not distinguish between skill checks and attacks. I am not aware of a way to distinguish between them based on the roll output to the API. Thanks for the feedback!