I don't know why it would quit working, but I have tried this version of it (minor updates for modern code style and loading efficiency), and it worked on both production and experimental. It will also output whether it was able to find the two songs needed, like this in the API log: "Script loaded: Critical Sound Effects"
" * criticalHit: [Loaded]"
" * criticalFail: [Loaded]" Script: //Critical Sound Effects v1.2.3
on('ready',() => {
let excludeGM = false; // this to false if you wish to include GM rolls
let defaults = {
css: {
button: {
'border': '1px solid #cccccc',
'border-radius': '2px',
'background-color': '#006dcc',
'margin': '0 .1em',
'font-weight': 'bold',
'padding': '.1em 1em',
'color': 'white'
}
}
};
let templates = {};
let criticalHit = null;
let criticalFail = null;
let allsongs = findObjs({
_type: 'jukeboxtrack'
});
allsongs.forEach(function(song) {
if(song.get('title') === 'Critical Hit') {
criticalHit = song;
} else if (song.get('title') === 'Critical Fail') {
criticalFail = song;
}
});
buildTemplates();
function criticalHitOrFail(content) {
if (content.rolls) {
content.rolls.forEach(function(roll) {
if (roll.dice === 1 && roll.sides === 20) {
if (isCriticalHit(roll)) {
play(criticalHit);
} else if (roll.results[0].v === 1) {
play(criticalFail);
}
}
if (roll.dice === 2 && roll.sides === 20 && roll.mods && roll.mods.customCrit) {
if (keptResultIsCriticalHit(roll)) {
play(criticalHit);
}
else if (keptResultIsCriticalFailure(roll)) {
play(criticalFail);
}
}
function isCriticalHit(roll) {
return roll.results[0].v === 20 || roll.mods && roll.mods.customCrit && roll.results[0].v >= roll.mods.customCrit[0].point;
}
function keptResultIsCriticalHit(roll) {
let customCrit = roll.mods.customCrit[0].point;
return roll.mods && roll.mods.keep &&
roll.results.some(function(result) {
return result.d === undefined && result.v === 20 ||
result.d === undefined && result.v >= customCrit;
});
}
function keptResultIsCriticalFailure(roll) {
return roll.mods && roll.mods.keep &&
roll.results.some(function(result) {
return result.d === undefined && result.v === 1;
});
}
});
}
}
on("chat:message", function(msg) {
if (!playerIsGM(msg.playerid) || !excludeGM && msg.type !== "gmrollresult") {
//for Shaped 5e Character Sheet
if (msg.inlinerolls) {
msg.inlinerolls.forEach(function(inlineRoll) {
criticalHitOrFail(inlineRoll.results);
});
}
//for roll chat command
else if (msg && isJson(msg.content)) {
let content = JSON.parse(msg.content);
criticalHitOrFail(content);
}
}
});
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
function play (song) {
if (song) {
song.set({'playing': true, 'softstop': false});
}
}
function buildTemplates() {
templates.cssProperty =_.template(
'<%=name %>: <%=value %>;'
);
templates.style = _.template(
'style="<%='+
'_.map(css,function(v,k) {'+
'return templates.cssProperty({'+
'defaults: defaults,'+
'templates: templates,'+
'name:k,'+
'value:v'+
'});'+
'}).join("")'+
' %>"'
);
templates.button = _.template(
'<a <%= templates.style({'+
'defaults: defaults,'+
'templates: templates,'+
'css: _.defaults(css,defaults.css.button)'+
'}) %> href="<%= command %>"><%= label||"Button" %></a>'
);
}
log('Script loaded: Critical Sound Effects');
log(` * criticalHit: [${criticalHit?'Loaded':'Missing <Critical Hit>'}]`);
log(` * criticalFail: [${criticalFail?'Loaded':'Missing <Critical Fail>'}]`);
});