Hey there! I'm having trouble with an API script that was posted by Mohkan about 4 years ago. I was wondering if any of you might be able to provide some insight. It's the script from this post that sums damage from attack rolls: <a href="https://app.roll20.net/forum/post/7831600/slug%7D" rel="nofollow">https://app.roll20.net/forum/post/7831600/slug%7D</a> The problem I'm having is that it doesn't work for crit rolls. Any ideas what I'm doing wrong? I'm using the D&D 5e 2014 Sheet with Google Chrome. Jumpgate. extractRoll = function(msg){
return _.chain(msg.inlinerolls)
.reduce(function(m,v,k){
m['$[['+k+']]']=v.results.total || 0;
return m;
},{})
.reduce(function(m,v,k){
return m.replace(k,v);
},msg.content)
.value();
}
findRollResult = function(msg, rollname, isString = 0){
let pattern = new RegExp('{{' + rollname + '=(.+?)}}');
let result = 0;
if (isString > 0) {
msg.content.replace(pattern,(match,rollResult)=>{
result = rollResult;
});
} else {
msg.content.replace(pattern,(match,rollResult)=>{
result = parseInt(rollResult);
});
}
return result;
}
// builds a comparison function for all the crit rules
var getCritComparitor = function(roll){
let comp=[];
// handle explicit custom rules
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 {
// default "max value" rule
comp.push((o)=>o==roll.sides);
}
// return a comparison function that checks each rule on a value
return function(v){
let crit=false;
_.find(comp,(f)=>crit=crit||f(v));
return crit;
};
};
var isCrit = function(roll){
var crits = 0;
// builds a comparison function for crits in this roll type
if (roll.sides == 20) {
let comp=getCritComparitor(roll);
_.each(roll.results,(r)=>{
// check each value with the comparison function
if(comp(r.v)){
// If it was a crit, report it to chat
// (replace with what you want or return true here and false outside the if for an inspection function)
// sendChat('isCrit',`The ${r.v} is a critical!`);
crits += 1;
}
});
}
return crits;
};
on("chat:message", function(orig_msg) {
if (orig_msg.rolltemplate && orig_msg.inlinerolls) {
if(/{{dmg\d=/.test(orig_msg.content)){
let msg = _.clone(orig_msg),
damageType, damageBase, damageCrit, atk1, atk2, critTarget, charName;
damageBase = damageCrit = atk1 = atk2 = crits = 0;
damageType = charName = advantage = normal = disadvantage = always = critBtn = critDmg ='';
msg.content = extractRoll(msg);
msg.content.replace(/charname=(.+?)$/,(match,charname)=>{
charName = charname;
});
damageType = findRollResult(msg, 'dmg1type', 1);
damageBase = findRollResult(msg, 'dmg1') + findRollResult(msg, 'dmg2') + findRollResult(msg, 'hldmg') + findRollResult(msg, 'globaldamage');
damageCrit = damageBase + findRollResult(msg, 'crit1') + findRollResult(msg, 'crit2') + findRollResult(msg, 'hldmgcrit') + findRollResult(msg, 'globaldamagecrit');
advantage = findRollResult(msg, 'advantage');
normal = findRollResult(msg, 'normal');
disadvantage = findRollResult(msg, 'disadvantage');
always = findRollResult(msg, 'always');
_.each(msg.inlinerolls,(ir)=>_.each(ir.results.rolls,(irrr)=>{
if (irrr.sides == 20) crits +=isCrit(irrr);
}));
if (damageType == 'Healing') {
//whispers the button to the GM
sendChat('Healing','/w gm [Healing](!token-mod --ids &#64;{target|1|token_id} --set bar1_value|&#91;&#91;{&#64;{target|1|bar1}+'+damageBase+'+ 0d0,&#64;{target|1|bar1|max}+0d0}kl1&#93;&#93;)');
//Also adds it up for the players
sendChat('','Total: '+damageBase);
}
else {
// if it's normal or advantage, and 1 crit roll is detected, it's a crit
// if it's disadvantage 2 crits are needed for it to be a crit.
// if they always roll advantage and 2 crits are detected, only show crit button
if ( ((normal || advantage) && (crits >= 1)) || ((disadvantage || always) && (crits >= 2)) ) {
//whispers the button to the GM
sendChat('Damage','/w gm [Critical](!token-mod --ids &#64;{target|token_id} --set bar1_value|-&#91;&#91;floor('+damageCrit+'/&#63;{Resistance|No,1|Yes,2}&#41;&#93;&#93;)');
//Also adds it up for the players
sendChat('',' Total Crit: ' + damageCrit);
}
else {
//if they use the Always Roll Advantage and 1 crit is detected, add the crit button as option
if (always && (crits >= 1)) {
critBtn = '[Critical](!token-mod --ids &#64;{target|token_id} --set bar1_value|-&#91;&#91;floor('+damageCrit+'/&#63;{Resistance|No,1|Yes,2}&#41;&#93;&#93;)';
critDmg = ' Total Crit: ' + damageCrit;
}
//whispers the button to the GM
sendChat('Damage','/w gm [Normal](!token-mod --ids &#64;{target|token_id} --set bar1_value|-&#91;&#91;floor('+damageBase+'/&#63;{Resistance|No,1|Yes,2}&#41;&#93;&#93;)' + critBtn);
//Also adds it up for the players
sendChat('','Total: ' + damageBase + critDmg);
}
}
}
}
}); Thanks so much. I love this script and would love to use it to speed up my games.