Glad it was helpful, though I must admit I'm pretty much just a hack. You should browse the forums and see some of the wizardry that GiGs and Oosh pull out of their hats! Re: 3D dice - I'm pretty sure that 3D dice can't be triggered from the API. One of the gurus could probably confirm or refute. Thought it would be a fun exercise, so in case it's useful here's another version, with the fumble numbers adjusted by one to make the logic work out for the edge cases (I think). New input now includes the CS and the type of action, and returns the d100 roll and color coded Result specific to the action, rather than just the generic success level. Could make the ActionType optional if it is ever useful to just get success levels like the previous version. ActionType is currently required. !CS <#> <ActionType> e.g. !CS -3 Force !CS +5 RollWithTheBlow Here's a query macro to handle all cases and prevent typos in the ActionType input. Note no spaces, as I was too lazy to change my parsing :) !CS ?{select CS|9|8|7|6|5|4|3|2|1|0|-1|-2|-3|-4|-5|-6|-7|-8|-9} ?{select Action|BluntAttack|EdgedAttack|Shooting|ThrowingEdged|ThrowingBlunt|Energy|Force|Grappling|Grabbing|Escaping|Charging|Dodging|Evading|Blocking|Catching|Stun|Slam|KO|Bleed|Kill|RollWithTheBlow|BounceBack} Sample output Code const CS = (() => {
const version = '0.1.0';
const successText = ["Fumble", "Miss", "Partial Success", "Success", "Enhanced Success", "Critical Success"]; //not used
let CS9 = [2, 6, 31, 56, 81];
let CS8 = [2, 9, 36, 61, 86];
let CS7 = [4, 11, 41, 66, 86];
let CS6 = [4, 16, 46, 71, 89];
let CS5 = [4, 21, 51, 71, 89];
let CS4 = [4, 26, 56, 76, 92];
let CS3 = [6, 31, 61, 81, 92];
let CS2 = [6, 36, 66, 86, 94];
let CS1 = [6, 41, 71, 86, 94];
let CS0 = [6, 46, 76, 89, 96];
let CS_1 = [9, 51, 76, 89, 96];
let CS_2 = [9, 56, 81, 92, 96];
let CS_3 = [11, 61, 81, 92, 96];
let CS_4 = [11, 66, 86, 94, 98];
let CS_5 = [16, 71, 89, 94, 98];
let CS_6 = [16, 76, 92, 96, 98];
let CS_7 = [21, 81, 92, 96, 98];
let CS_8 = [21, 86, 94, 98, 100];
let CS_9 = [26, 89, 96, 98, 100];
let bluntAttack = ["Fumble", "Miss", "Hit", "Slam", "Stun", "K.O."];
let edgedAttack = ["Fumble", "Miss", "Hit", "Slam", "Bleed", "Kill"];
let shooting = ["Fumble", "Miss", "Hit", "Bullseye", "Bleed", "Kill"];
let throwingEdged = ["Fumble", "Miss", "Hit", "Bullseye", "Bleed", "Kill"];
let throwingBlunt = ["Fumble", "Miss", "Hit", "Bullseye", "Stun", "K.O."];
let energy = ["Fumble", "Miss", "Hit", "Bullseye", "Stun", "Kill"];
let force = ["Fumble", "Miss", "Hit", "Bullseye", "Stun", "Slam"];
let grappling = ["Fumble", "Miss", "Hit", "Partial", "Hold", "Stun"];
let grabbing = ["Fumble", "Miss", "Take", "Grab", "Grab", "Break"];
let escaping = ["Fumble", "Miss", "Miss", "Escape", "Reverse", "Counter"];
let charging = ["Fumble", "Miss", "Hit", "Slam", "Stun", "K.O."];
let dodging = ["Autohit", "None", "-1CS", "-2CS", "-4CS", "-8CS"];
let evading = ["+Stun", "Autohit", "Evasion", "+1CS", "+2CS", "+3CS"];
let blocking = ["+Stun", "-6CS", "-4CS", "-2CS", "-1CS", "+1CS"];
let catching = ["+Stun", "Autohit", "Miss", "Damage", "Catch", "Riposte"];
let stun = ["+K.O.", "1-10", "1", "No", "No", "No"];
let slam = ["+Stun", "Gr. Slam", "1 Area", "Stagger", "No", "Deflect"];
let ko = ["+Kill", "Knockout", "+Stun", "No", "No", "No"];
let bleed = ["+Kill", "Bleed", "-1", "No", "No", "No"];
let kill = ["KIA", "En. Loss", "E/S", "No", "No", "No"];
let rollWithTheBlow = ["+1CS", "No", "-1CS", "-2CS", "-3CS", "-4CS"];
let bounceBack = ["+Stun", "No", "-1CS", "End", "+1CS", "+2CS"];
const checkInstall = () => {
log('-=> CS v'+version);
};
//sendChat output formatting styles
const _h = {
fumble: (...o) => `<span style="font-weight: bold;padding: .2em .2em; background-color:rgba(1,176,241,1);">${o.join('')}</span>`,
miss: (...o) => `<span style="font-weight: bold;padding: .2em .2em; background-color:rgba(255,255,255,1);">${o.join('')}</span>`,
partial: (...o) => `<span style="font-weight: bold;padding: .2em .2em; background-color:rgba(1,144,2,1);">${o.join('')}</span>`,
success: (...o) => `<span style="font-weight: bold;padding: .2em .2em; background-color:rgba(254,246,142,1);">${o.join('')}</span>`,
enhanced: (...o) => `<span style="font-weight: bold;padding: .2em .2em; background-color:rgba(191,116,1,1);">${o.join('')}</span>`,
crit: (...o) => `<span style="font-weight: bold;padding: .2em .2em; background-color:rgba(192,0,0,1);">${o.join('')}</span>`
};
const formattedResult = function (successLevel, text) {
switch(successLevel){
case 0:
return _h.fumble(text);
break;
case 1:
return _h.miss(text);
break;
case 2:
return _h.partial(text);
break;
case 3:
return _h.success(text);
break;
case 4:
return _h.enhanced(text);
break;
case 5:
return _h.crit(text);
break;
}
}
const getSuccessLevel = function (tableArr, roll) {
if (roll>=tableArr[4]) {return 5} //"Critical Success"
if (roll>=tableArr[3] && roll<tableArr[4]) {return 4} //"Enhanced Success"
if (roll>=tableArr[2] && roll<tableArr[3]) {return 3} //"Success"
if (roll>=tableArr[1] && roll<tableArr[2]) {return 2} //"Partial Success"
if (roll>=tableArr[0] && roll<tableArr[1]) {return 1} //"Miss"
if (roll<tableArr[0]) {return 0} //"Fumble"
};
const handleInput = (msg) => {
const scriptName = 'CS';
let roll = 0;
let tableName;
let tableArr;
let actionArr;
let action = "";
let successLevel;
let result;
if(msg.type=="api" && msg.content.indexOf("!CS") === 0 ) {
try {
who = getObj('player',msg.playerid).get('_displayname');
let args = msg.content.split(/\s+/);
if (args[1]>=0) {
tableName = 'CS' + parseInt(args[1]);
} else {
tableName = 'CS_' + -1*parseInt(args[1]);
}
//Get Success Level Array
switch(tableName){
case "CS9":
tableArr = CS9;
break;
case "CS8":
tableArr = CS8;
break;
case "CS7":
tableArr = CS7;
break;
case "CS6":
tableArr = CS6;
break;
case "CS5":
tableArr = CS5;
break;
case "CS4":
tableArr = CS4;
break;
case "C3":
tableArr = CS3;
break;
case "CS2":
tableArr = CS2;
break;
case "CS1":
tableArr = CS1;
break;
case "CS0":
tableArr = CS0;
break;
case "CS_1":
tableArr = CS_1;
break;
case "CS_2":
tableArr = CS_2;
break;
case "CS_3":
tableArr = CS_3;
break;
case "CS_4":
tableArr = CS_4;
break;
case "CS_5":
tableArr = CS_5;
break;
case "CS_6":
tableArr = CS_6;
break;
case "CS_7":
tableArr = CS_7;
break;
case "CS_8":
tableArr = CS_8;
break;
case "CS_9":
tableArr = CS_9;
break;
}
//Get Action Array
action = args[2];
switch(args[2]){
case "BluntAttack":
actionArr = bluntAttack;
break;
case "EdgedAttack":
actionArr = edgedAttack;
break;
case "Shooting":
actionArr = shooting;
break;
case "ThrowingEdged":
actionArr = throwingEdged;
break;
case "ThrowingBlunt":
actionArr = throwingBlunt;
break;
case "Energy":
actionArr = energy;
break;
case "Force":
actionArr = force;
break;
case "Grappling":
actionArr = grappling;
break;
case "Grabbing":
actionArr = grabbing;
break;
case "Escaping":
actionArr = escaping;
break;
case "Charging":
actionArr = charging;
break;
case "Dodging":
actionArr = dodging;
break;
case "Evading":
actionArr = evading;
break;
case "Blocking":
actionArr = blocking;
break;
case "Catching":
actionArr = catching;
break;
case "Stun":
actionArr = stun;
break;
case "Slam":
actionArr = slam;
break;
case "KO":
actionArr = ko;
break;
case "Bleed":
actionArr = bleed;
break;
case "Kill":
actionArr = kill;
break;
case "RollWithTheBlow":
actionArr = rollWithTheBlow;
break;
case "BounceBack":
actionArr = bounceBack;
break;
default:
sendChat(scriptName,`/w "${who}" `+ 'Error: Action \"' + action + '\" not found.');
break
}
tableName = tableName.replace("_", "-");
roll = randomInteger(100);
successLevel = getSuccessLevel(tableArr, roll);
result = actionArr[successLevel];
//let output = '&{template:default} {{name=' + tableName + '}} {{Roll=[[' + roll + ']]}} {{SuccessLevel=' + _h.inlineResult(result) + '}}';
let output = '&{template:default} {{name=' + action + ' ' + tableName + '}} {{Roll=[[' + roll + ']]}} {{Result=' + formattedResult(successLevel, result) + '}}';
sendChat(scriptName, output);
}
catch(err) {
sendChat(scriptName,`/w "${who}" `+ 'Error: ' + err.message);
}
};
};
const registerEventHandlers = () => {
on('chat:message', handleInput);
};
on('ready', () => {
checkInstall();
registerEventHandlers();
});
})();
Had a fun time with this. Let me know if there is a problem somewhere.