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

How to process autocalc values in a sheet worker (no sendChat)

Sorry, I feel like I have missed something obvious but I can't seem to figure this out. Working on updates to my Runequest6/Mythras sheet and I want to give users the ability to change the values used for Attribute table lookups.  A number of example gifts from the rulebook change the attributes that may be used.  For example you normally add STR and SIZ and lookup the result a table to find your Damage Modifier.  Through a cult gift however this could change to STR+SIZ+POW.   My plan was to simply provide a field which defaults to @{str}+@{siz} and allow the user to edit it as needed.  This is fine for most attributes because I can simply include that formula in a larger one to get the table result but the damage mod table has no formula driving the results.  Problem is I use getAttrs and the value I get is a string = "@{str}+@{siz}" and not the resulting value.  This is expected but I can't find a way to evaluate it into an integer. In the API you would use sendChat but it seems this is not available in the sheet workers.  

Edited 1463139411
Sheet Author
API Scripter
var autocalc = '@{str}+@{siz}-floor(@{example|max}/2)', regexp = /@\{(.+?(?:\|max)?)\}/g, matches = [], tmp; while ((tmp = regexp.exec(autocalc)) !== null) { matches.push(tmp[1].replace(/\|max$/, '_max')); } // matches == ['str', 'siz', 'example_max'] This would let you produce the array you need for the first parameter to getAttrs, to ensure you have all of the attributes being referenced. var autocalc = '@{str}+@{siz}-floor(@{example|max}/2', regexp = /@\{(.+?(?:\|max)?)\}/g, reformatted = autocalc.replace(regexp, ($0, $1) => `${values[$1.replace(/\|max$/, '_max')]}`), evalStr = reformatted.replace(/(abs|ceil|floor|round)\((.+?)\)/g, 'Math.$1($2)'), calculatedValue = eval(evalStr); // reformatted == '5+2-floor(7/2)', assuming values.str == 5, values.siz == 2, and values.example_max == 7 // evalStr == '5+2-Math.floor(7/2)' // calculatedValue == 4 I'm assuming here that eval is available to sheet workers, and that may be an incorrect assumption. If eval isn't available, you'd have to include a complicated parser in your sheet worker. So, putting it together: on(..., function(e) { getAttrs(['my_autocalc_value'], function(v) { var regexp = /@\{(.+?(?:\|max)?)\}/g, matches = [], tmp; while ((tmp = regexp.exec(v.my_autocalc_value)) !== null) { matches.push(tmp[1].replace(/\|max$/, '_max')); } getAttrs(matches, function(values) { var reformatted = v.my_autocalc_value.replace(regexp, ($0, $1) => `${values[$1.replace(/\|max$/, '_max')]}`), evalStr = reformatted.replace(/(abs|ceil|floor|round)\((.+?)\)/g, 'Math.$1($2)'), calculatedValue = eval(evalStr); setAttrs({ my_autocalc_calculation: calculatedValue }); }); }); }); If the attributes being used themselves contain references to other attributes, you would have to apply this process recursively, which could get tricky since getAttrs is asynchronous.
Thanks for the help.  I was afraid I would need to essentially parse the string manually.  To simplify matters I'll probably just convert most stuff to sheet worker calcs to avoid recursion and include a checkbox for the gift and have the sheet worker include @{pow} in the total table lookup value if it is checked.  Making it entirely customized was probably overkill anyway.