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

[Error] Help fixing Script

1560530591

Edited 1560541604
Michael I.
Pro
Sheet Author
I have isolated the script giving the Error by disabling all other scripts. Your scripts are currently disabled due to an error that was detected. Please make appropriate changes to your scripts and click the "Save Script" button and we'll attempt to start running them again.  More info... For reference, the error message generated was:  SyntaxError: missing ) after argument list I don't know if its because I have looked at the script for so long, or what but i am not seeing the error hoping some one can help spot it. script below on('chat:message', function(e) { if (e.type === 'rollresult') { var content = JSON.parse(e.content); var rolls = content.rolls; var tn = false; var edge = false; var automatic = false; var eye = false; var tengwars = 0; var featResult; var piercing = ""; var eyeOnAttack = ""; //log(content); // determine who triggered the roll, player or character var characters = findObjs({_type: 'character'}); var speaking; characters.forEach(function(chr) { if(chr.get('name') == e.who) speaking = chr; });    rolls.forEach(function(roll) { // detect Target Number if (roll.type === 'C') { var text = roll.text.replace(/\s/g, ''); // remove whitespace //split the string into an array separated by space var params = roll.text.splitArgs(); //log(params); //the target number is found at position 1 of the array (see the macro) tn = params[1]; //the edge value is found at position 4 of the array (see the macro) //a params array for attack-rolls should look like this [">", "(tn)", "Edge:", "(edge)"] //if this is not an attack-roll then the variable edge will be undefined edge = params[3]; } // loop through dice results if (roll.type === 'R') { if (roll.sides === 12) { featResult = roll.results[0].v; automatic = (roll.table === 'lm-feat' && roll.results[0].tableidx === 10 ? true : automatic); // eye as adversary automatic = (roll.table === 'feat' && roll.results[0].tableidx === 11 ? true : automatic); // gandalf as player eye = (roll.table === 'feat' && roll.results[0].tableidx === 10 ? true : eye); // eye as player } if (roll.sides === 6) { // check for tengwars roll.results.forEach(function(result) { tengwars = (result.v === 6 ? tengwars + 1 : tengwars); }, this); } } }, this); //set chat msgs //if this is an attack, then edge is set (see macro) if (edge) { if (featResult >= edge || automatic) { piercing = " And might inflict a wound!"; } //setting a chat-msg if player has rolled an eye during an attack if (eye) { eyeOnAttack = " And provokes the opponent to try a Called Shot next round!"; } } // gandalf rune for feat table, or eye for lm-feat table if (automatic) { if (tengwars === 0) { if(speaking) sendChat('character|'+speaking.id, '/desc rolls an automatic success!'+piercing); else sendChat('player|'+e.playerid, '/desc rolls an automatic success!'+piercing); } else  if (tengwars === 1) { if(speaking) sendChat('character|'+speaking.id, '/desc rolls an automatic great success!'+piercing); else sendChat('player|'+e.playerid, '/desc rolls an automatic great success!'+piercing); } else if (tengwars > 1) { if(speaking) sendChat('character|'+speaking.id, '/desc rolls an automatic extraordinary success!'+piercing); else sendChat('player|'+e.playerid, '/desc rolls an automatic extraordinary success!'+piercing); } // a hit } else if (tn !== false && content.total >= tn) { if (tengwars === 0) { if(speaking) sendChat('character|'+speaking.id, '/desc rolls a success!'+piercing); else sendChat('player|'+e.playerid, '/desc rolls a success!'+piercing); } else  if (tengwars === 1) { if(speaking) sendChat('character|'+speaking.id, '/desc rolls a great success!'+piercing); else sendChat('player|'+e.playerid, '/desc rolls a great success!'+piercing); } else if (tengwars > 1) { if(speaking) sendChat('character|'+speaking.id, '/desc rolls an extraordinary success!'+piercing); else sendChat('player|'+e.playerid, '/desc rolls an extraordinary success!'+piercing); } // a miss } else if (tn !== false && content.total < tn) { if(speaking) sendChat('character|'+speaking.id, '/desc misses.'+eyeOnAttack); else sendChat('player|'+e.playerid, '/desc misses.'eyeOnAttack); } else { if (tengwars === 1) { if(speaking) sendChat('character|'+speaking.id, '/desc rolls a tengwar.'); else sendChat('player|'+e.playerid, '/desc rolls a tengwar.'); } else if (tengwars === 2) { if(speaking) sendChat('character|'+speaking.id, '/desc rolls two tengwars.'); else sendChat('player|'+e.playerid, '/desc rolls two tengwars.'); } else if (tengwars > 2) { if(speaking) sendChat('character|'+speaking.id, '/desc rolls whole lotta tengwars.'); else sendChat('player|'+e.playerid, '/desc rolls whole lotta tengwars.'); } } } }); /**  * Splits a string into arguments using some separator. If no separator is  * given, whitespace will be used. Most importantly, quotes in the original  * string will allow you to group delimited tokens. Single and double quotes  * can be nested one level.  *   * As a convenience, this function has been added to the String prototype,  * letting you treat it like a function of the string object.    *   * Example: on('chat:message', function(msg) {     var command, params;          params = msg.content.splitArgs();     command = params.shift().substring(1);          // msg.content: !command with parameters, "including 'with quotes'"     // command: command     // params: ["with", "parameters,", "including 'with quotes'"] });       */ var bshields = bshields || {}; bshields.splitArgs = (function() { 'use strict';      var version = 1.0;      function splitArgs(input, separator) { var singleQuoteOpen = false, doubleQuoteOpen = false, tokenBuffer = [], ret = [], arr = input.split(''), element, i, matches; separator = separator || /\s/g;          for (i = 0; i < arr.length; i++) { element = arr[i]; matches = element.match(separator); if (element === '\'') { if (!doubleQuoteOpen) { singleQuoteOpen = !singleQuoteOpen; continue; } } else if (element === '"') { if (!singleQuoteOpen) { doubleQuoteOpen = !doubleQuoteOpen; continue; } }              if (!singleQuoteOpen && !doubleQuoteOpen) { if (matches) { if (tokenBuffer && tokenBuffer.length > 0) { ret.push(tokenBuffer.join('')); tokenBuffer = []; } } else { tokenBuffer.push(element); } } else if (singleQuoteOpen || doubleQuoteOpen) { tokenBuffer.push(element); } } if (tokenBuffer && tokenBuffer.length > 0) { ret.push(tokenBuffer.join('')); }          return ret; }      return splitArgs; }()); String.prototype.splitArgs = String.prototype.splitArgs || function(separator) { return bshields.splitArgs(this, separator); }; 
1560534095

Edited 1560534444
Ada L.
Marketplace Creator
Sheet Author
API Scripter
On the line else sendChat('player|'+e.playerid, '/desc misses.'eyeOnAttack); you forgot your + operator between '/desc misses.' and eyeOnAttack. For debugging syntactical issues like this, I would highly recommend checking your code with a JS syntax checker such as Google Closure Compiler . It will parse your code and tell you where any syntax errors like these are. Also, when sharing code samples on the forums, I would recommend putting them in a code block like this. This makes the code easier for others to read and it automatically preserves its indentation and other whitespace.
1560543183
Michael I.
Pro
Sheet Author
Thank you Stephen, I cant tell you how many time I went by that and I will try and use a JS syntax checker more. I was in a bit of rush this morning and thought I had placed the code in a code block. but again thank you. for finding that it was driving me insane..
1560621209
Ada L.
Marketplace Creator
Sheet Author
API Scripter
If you have your IDE set up for it, you can also take advantage of a Javascript linter that will mark syntax errors for you as you code. It's really handy! JSHint is a good Javascript linter.
1560635476

Edited 1560638225
The Aaron
Roll20 Production Team
API Scripter
ESLint is more in vogue lately. (Ranked #1 for Javascript linters, JSHint has fallen down to #5 ). Here's the .eslintrc.js config file I use for ESLint: module.exports = { "env": { }, "globals": { "Set": true, "setInterval": true, "clearInterval": true, "clearTimeout": true, "setTimeout": true, "playerIsGM": true, "getObj": true, "findObjs": true, "filterObjs": true, "createObj": true, "sendChat": true, "log": true, "toFront": true, "toBack": true, "randomInteger": true, "setDefaultTokenForCharacter": true, "spawnFx": true, "spawnFxBetweenPoints": true, "spawnFxWithDefinition": true, "playJukeboxPlaylist": true, "stopJukeboxPlaylist": true, "sendPing": true, "state": true, "globalconfig": true, "_": true, "Campaign": true, "getAllObjs": true, "getAttrByName": true, "onSheetWorkerCompleted": true, "on": true, "Promise":true, "Uint32Array":true, "takeCardFromPlayer":true, "giveCardToPlayer":true, "recallCards":true, "shuffleDeck":true, "drawCard":true, "cardInfo":true, "playCardToTable":true }, "extends": "eslint:recommended", "parserOptions": { "ecmaVersion": 2017, "ecmaFeatures": { "impliedStrict": true, "experimentalObjectRestSpread": true }, "sourceType": "module" }, "plugins": [ ], "rules": { "no-console": "warn", "linebreak-style": [ "error", "unix" ], "semi": [ "error", "always" ], "comma-dangle": [ "error", "never" ] } }; (If you're on windows, you'll probably want to remove the bold part I have above.)
1560637541
GiGs
Pro
Sheet Author
API Scripter
That is very handy, thanks Aaron. Is this rule spelled correctly?  "implitedStrict" PS you have playerIsGM twice in the globals.
1560638209
The Aaron
Roll20 Production Team
API Scripter
Probably not. =D  Should be "impliedStrict"  Looks like it's true by default for sourceType module. Good catch on the playerIsGM being there twice.  =D  Removed. I'll correct the above for posterity. 
1560638304

Edited 1560638759
The Aaron
Roll20 Production Team
API Scripter
Incidentally, that comma-dangle is actually pretty important, as a dangling comma will prevent the API from starting up and the error message is particularly obscure. For reference, the error message generated was:  SyntaxError: Unexpected token } Bad: const options = { foo: true, bar: false, }; Good: const options = { foo: true, bar: false };
1560639698
GiGs
Pro
Sheet Author
API Scripter
I've definitely made that error a few times! :)
1560905552
Michael I.
Pro
Sheet Author
I want to Thank you all for your help in this. I have added both Javascript linter to my toolbox