
Selfish request: I'm wondering if anyone can provide a serious critique of the code I've presented in terms of layout and overall method used. IOW would this be an acceptable script or just a mess? Please be brutal if you think it warrants it.
As those who are seeing me post yet again realize, I'm fairly new at javascript, period, and javascript in the roll20 sandbox, of course. I've had wonderful help to enable me to finally complete a script for the text chat window that:
1) Rolls a specified number of 6 sided dice, up to 8 maximum;
2) Allows the user to optionally specify what individual result on a die is required for a success - "hit" is the term used in the code - with 5 or 6 being the default;
3) Offers guidance to the user if they get the format or parameters messed up.
It works, and I should probably accept this as is, but if I get experienced with this and try to help others, I don't want to give bad advice.
Thanks in advance. My background in development has dealt with many types of variables other than variants, which is why I have various prefixes on my variable names.
on("chat:message", function(msg) {
//Dice roller for Crossfire (WWII infantry wargame) attacks.
//This allows players to enter !cf <number> to roll a number of d6 dice
//with a default target of 5 or 6. A space and a second number will change
//the target to 6, 4-6 or whatever.
//FORMAT: !cf 4 (rolls 4 dice, 5,6 to hit.) !cf 4 6 (4 dice, 6 to hit).
//log("-->start cf process<--");
if(msg.type == "api" && msg.content.toLowerCase().indexOf("!cf") !== -1) {
//Declare variables at this point so as not to drain any memory/processing needlessly.
var numDice; //Number of dice to roll
var str1 = msg.content.toLowerCase(); //Write msg content to str1 in lowercase
var posSpace; //Position of a space, if any, between numbers
var numDice2 = 5; //Second number, defaults to 5
var booReady = -1; //If we get through the checks, booReady will be 0 for one or two arguments
//If Has str1 been processed so that it is ready to be used? -1 no 0 yes.
//log("1 ====== BEGIN CF FUNCTION ======");
//log("2 str1: '" + str1 + "'");
str1 = str1.replace("!cf", "");
//log("3 str1 !cf removed: '" + str1 + "'");
numDice = str1.trim();
//log("4 numDice is str1 Trimmed: '" + numDice + "'");
//log("5 Number function result " + Number(numDice));
if (isNaN(numDice)) {
//log("--> isNaN is true Begin isNan Handling);
//So before we write this off, let's see if the NaN is because of
//a space - which could indicate a second number entered for
//the to hit value.
//Ascertain the position of the space, if there is one.
posSpace = (numDice.indexOf(" "));
if (posSpace !== -1) {
//log("isNan: posSpace is " + posSpace);
//This means there is a space at position posSpace!
//Check the SECOND number, first.
numDice2 = numDice.substring(posSpace + 1);
numDice2 = numDice2.trim();
//log("isNan: numDice2 is " + numDice2);
//If the second number fails the isNumber test, we can ignore
//it as gobbedlygook if the FIRST number is valid.
//So change numDice2 to the default of 5 if it is silly.
if (isNaN(numDice2)) {numDice2 = 5;}
//Now evaluate the first number.
numDice = numDice.substr(0, posSpace)
numDice = numDice.trim();
//log("isNan: numDice is " + numDice);
//If the first number is not a number, shag it all.
if (isNaN(numDice)) {booReady = -1;} else {booReady = 0;}
//log("isNan: booReady is " + booReady);
} else {
booReady = -1;
//A booReady of -1 shows not all is well with the world.
}
} else {
//log("isNaN is not true, ready to proceed with booReady = 0);
booReady = 0;
}
//log ("booReady is: " + booReady);
//We reach the next stage to first give an ERROR result. If
//booReady is -1, give an advisory if arguments are OUTSIDE PARAMETRTS,
//or all is well and PROCEED.
if (booReady == -1) {
//ERROR route.
//log('ERROR message');
sendChat('player|' + msg.playerid, '===============<br>**Crossfire Roll Error**<br>You entered: ' + msg.content +'.<br>The correct ' +
'format is:<br><br>!cf [no of dice] [OPTIONAL to hit] <br><br>**Examples**:<br>' +
'!cf 3 will roll 3 dice, with 5,6 to hit.<br>!cf 2 6 will roll 2 dice, just a 6 hits (note just a space, no comma).');
} else if (Number(numDice) > 8 || Number(numDice) < 1 || Number(numDice2) <= 1 || Number(numDice2) > 6) {
//OUTSIDE PARAMETERS Route
//booReady is 0, but there are too many dice specified or 1-6 specified as a hit.
//repurpose str1 to develop a error message
//log("OUTSIDE PARAMETERS: too many/few dice or incorrect range");
str1 = '';
//numDice > 8 or numDice < 1
if (Number(numDice) > 8) {
str1 = "Specified too many dice - the maximum dice " + "in a Crossfire roll is 8.";
} else if (Number(numDice) < 1) {
str1 = "Specified less than one dice which makes no sense.";
}
//log(OUTSIDE PARAMETERS: " + str1);
//numDice2 <= 1 or numDice2 >6
if (Number(numDice2) <=1) {
if (str1 !== '') {str1 = str1 + " Also, you have s";} else {str1 = "S";}
str1 = str1 + 'pecified ' + numDice2 + ' to 6 as a hit. The "to hit" ' +
'argument needs to be 2 or more. If it is less, hits are automatic.';
} else if (Number(numDice2) > 6) {
if (str1 !== '') {str1 = str1 + " Also, you have s";} else {str1 = "S";}
str1 = str1 + 'pecified ' + numDice2 + ' to hit. If not left blank, this argument may only be 2 to 6.';
}
sendChat('player|' + msg.playerid, '===============<br>**Crossfire Roll Input Error**<br>You entered: ' +
msg.content +'.<br>Format is correct, but you have:<br><br>' + str1);
} else {
//PROCEED
//log("PROCEED - All is good! booReady is " + booReady);
//log("PROCEED - numDice:" + numDice +"; numDice2:" + numDice2);
//log("PROCEED - /roll " + numDice + "d6>" + numDice2);
//Repurpose str1
switch(Number(numDice2)) {
case 6:
str1 = "only 6 is a hit.";
break;
case 5:
str1 = "5 or 6 is a hit (normal).";
break;
default:
str1 = numDice2 + " to 6 is a hit";
}
//Resuse str1 to build a message about the numbe rof dice rolled.
sendChat('player|' + msg.playerid, "===============<br>**Crossfire Roll** (" + msg.content + ")<br>Roll " + numDice +
" dice; " + str1 + "\n/roll " +
numDice + "d6>" + numDice2, null, {use3d: true});
}
}
});