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 .
×
Advertisement Create a free account

[Script] libInline - provides an easy interface for inlinerolls (including roll-tips!)

1612388278

Edited 1632184148
timmaugh
Pro
API Scripter
libInline File Location: libInline (this is submitted to the one-click install; until it shows up there, the above link will point to my personal repo) Abstract: libInline is a library that simplifies interaction with the inlinerolls object of a message. Using this library, a scripter can easily obtain various datapoints from any inline roll, such as the resulting total, the resulting value (different for a table versus a die roll), various combinations of the resulting dice (all the dice, only the included dice, only the dropped dice, only the critical successes, only the critical failures, etc.), and, most importantly, the resulting rolltip (the tip that pops up when you hover over an inline roll in the chat window). Using this library should free you from having to manually reduce the inline rolls from a message, and should provide the well-formatted roll-tip that was lacking in the common form that reduction would take. Thread Map: Post 1: (this post) will provide the documentation for the library, including the Change Log, File Location, and any Open Issues Post 2: will contain code examples for using this in your scripts. Credits: Though I am the one posting this, this library is equal parts The Aaron. He had started but never finished this project some time ago, and when I needed something similar for another script I was working on (APILogic, which I am about to post, as well), he lent me what he had so I could take it over the finish line. He also lent his expertise when I had a problem getting it over the finish line. Library Name Use libInline as the scoped name for the exposed functions, below (so, libInline.getRollData() ). Exposed Functions (Base) getRollData Syntax: getRollData( arg ) Returns: array Arg Requirements: arg can be:  the message object: getRollData(msg)  the inlineroll array of the message object: getRollData(msg.inlinerolls)  a filtered array of rolls from the message object: getRollData(msg.inlinerolls.filter(r=>...))  a single roll from the message object: getRollData(msg.inlinerolls[0]) Description: getRollData gets the entire parsed data structure of the rolls from the passed inlineroll array. The output is an array of objects, just as the inlineroll array is -- so if there are 2 rolls in the inlineroll array, there will be 2 rolls in the returned array from getRollData(). The indices of the rolls in the array will also match (roll 0 will be roll 0, roll 1 will be roll 1, etc.). See the Parsed Roll Examples  section below for examples of returned arrays. getValue Syntax: getValue( roll ) Returns: number or string Arg Requirements: roll can be: an array of rolls as from the getRollData examples, above: getValue(msg.inlinerolls) a single roll: getValue(msg.inlinerolls[0]) Description: getValue gets the chat window result of a roll. This is different than getting the total of the roll from the inlinerolls array directly in that getValue detects whether the roll was made against a rollable table. If the result that reached the chat window would have been the returned value from a table, getValue will return that value. This is also different than the roll-tip (the hover tip that accompanies an inline roll result in the chat window). For that, use getRollTip (below). If an array of rolls is passed to the function, getValue will evaluate and return the value from only the first roll. No other parsed data structure is retained. getTables Syntax: getTables( roll, reduce = true ) Returns: array Arg Requirements: roll can be: an array of rolls as from the getRollData examples, above: getTables(msg.inlinerolls) a single roll: getTables(msg.inlinerolls[0]) Description: getTables gets the table results generated by the roll organized into an array of values. If you need the results to be more differentiated, you can pass false for the reduce argument. In that case, you will retrieve an array of objects in the form of: {     name: 'Table Name',     returns: [ return 0 , return 1 , ... return N ] } The objects occur in the array in the order they were encountered in the roll. So if your roll included [[ 1t[Table1] + 1t[Table2] + 2t[Table1] ]], the array from reduce = false will have a length of 3 (even though the same table was referenced in the first and third items), and the last entry will have 2 entries in the returns property. If an array of rolls is passed to the function, getTables will evaluate and return the value from only the first roll. No other parsed data structure is retained. getParsed Syntax: getParsed( roll ) Returns: string Arg Requirements: roll can be: an array of rolls as from the getRollData examples, above: getParsed(msg.inlinerolls) a single roll: getParsed(msg.inlinerolls[0]) Description: getParsed gets the equation generated by reducing all of the dice or table returns to their values. This is equivalent to the equation of the roll-tip without the formatting of the roll-tip. For instance, a roll of [[ {2d10 + 3} + 1d4 ]] might produce the parsed value of ({7 + 3} + 2). Be aware that the equation may contain dice which are dropped; in the roll-tip, this is indicated by formatting, but that formatting is not present outside of the roll-tip (e.g., as returned by this function). If an array of rolls is passed to the function, getParsed will evaluate and return the value from only the first roll. No other parsed data structure is retained. getRollTip Syntax: getRollTip( roll ) Returns: string Arg Requirements: roll can be: an array of rolls as from the getRollData examples, above: getRollTip(msg.inlinerolls) a single roll: getRollTip(msg.inlinerolls[0]) Description: getRollTip gets the chat output required for the roll, including the chat value and associated roll-tip for the roll. Use this to drop html-formatted content in place of roll markers to render an inline roll the same as the Roll20 chat parser would. See the section **Formatting Differences vs Native Roll20** for information on minor formatting differences (and why we think ours is slightly better). If an array of rolls is passed to the function, getParsed will evaluate and return the value from only the first roll. No other parsed data structure is retained. getDice Syntax: getDice(roll, type) Returns: *array* Arg Requirements: roll can be: an array of rolls as from the getRollData examples, above: getDice(msg.inlinerolls, type) a single roll: getDice(msg.inlinerolls[0], type) type can be any of the following list: all   returns all dice included   returns included dice (i.e., not dropped) success   returns critical success dice crit   alias of success fail   returns critical failure dice fumble   alias of fail allcrit   returns all critical success and critical failure dice dropped   returns dropped dice Description: getDice returns an array of dice values from a roll that match the type supplied. the chat output required for the roll, including the chat value and associated roll-tip for the roll. Use this to drop html-formatted content in place of roll markers to render an inline roll the same as the Roll20 chat parser would. See the section **Formatting Differences vs Native Roll20** for information on minor formatting differences (and why we think ours is slightly better). If an array of rolls is passed to the function, getParsed will evaluate and return the value from only the first roll. No other parsed data structure is retained. Late Eval Functions (each Roll) If you use getRollData to return the fully parsed inline roll objects, you have a certain number of properties available to you (see Parsed Roll Structure & Examples , below), but you also have a certain number of function properties attached to each parsed roll object for returning late-evaluation of the data. These functions include: getDice( type ) getTables() getRollTip() These operate the same as their base counterparts, except that you do not have to provide the roll to evaluate (they will evaluate the roll to which they are attached). let pir = libInline.getRollData(msg); log(pir[0].getDice('included')); // outputs the array of included dice from the first inline roll As well, getTables differs in that it does not take a reduce argument. This is because the non-reduced array of table data is available to you as a property of the parsed roll object (tableReturns), so the only remaining necessary purpose of this function is to reduce the original data down to a simple array for you. Parsed Roll Structure & Examples When you use libInline.getRollData(), the returned array contains an object representing each roll. These objects have the following properties: expression (string) parsed (string) resultType (string) total (number) value (number or string) labels (array) tableReturns  (array) display (string) dice (array) As mentioned, each roll also has these function properties: getDice( type ) returns array getTableValues() returns array getRollTip() returns string A Word on Labels Labels, as tracked by Roll20, are only stored as the label itself. libInline attempts to guess what was intended to be referenced, looking just to the left of the label. In this, it may not be exact. If you see 1d10 + 3 [Quality Bonus] in an inline roll, does the label only refer to the +3 or to the entire 1d10 + 3? libInline defaults to the latter, returning more information that could fit the definition of the label. Labels are stored as an array of objects in the form of: {     label: 'Quality Bonus',     value: '1d10 + 3' } Obviously, if you need only the labels, this is easily obtained by use of _.pluck() or a custom .map() operation. Roll Examples Rolling [[2d20 + 3]]     [          {             expression: 2d20 + 3 [Quality Bonus],             parsed: (6+8)+3,             resultType: sum,             total: 17,             value: 17,             labels: [                {                   label: Quality Bonus,                   value: 2d20 + 3                 }             ],             tableReturns: [],             display: (<span class="basicdiceroll">6</span>+<span class="basicdiceroll">8</span>)+3,             dice: [                {                   v: 6,                   display: <span class="basicdiceroll">6</span>                },                {                   v: 8,                   display: <span class="basicdiceroll">8</span>                }             ]          }       ] Rolling [[10d10!r<3d3cs>8cf=4]]     [          {             expression: 10d10!r<3d3cs>8cf=4,             parsed: (4+8+6+6+5+7+5+6+9+2+9),             resultType: sum,             total: 51,             value: 51,             labels: [],             tableReturns: [],             display: (<span class="basicdiceroll dropped">4</span>+<span class="basicdiceroll critsuccess ">8</span>+<span class="basicdiceroll">6</span>+<span class="basicdiceroll">6</span>+<span class="basicdiceroll dropped">5</span>+<span class="basicdiceroll">7</span>+<span class="basicdiceroll dropped">5</span>+<span class="basicdiceroll">6</span>+<span class="basicdiceroll critsuccess ">9</span>+<span class="basicdiceroll dropped">2</span>+<span class="basicdiceroll critsuccess ">9</span>),             dice: [                {                   v: 4,                   type: drop,                   display: <span class="basicdiceroll dropped">4</span>                },                {                   v: 8,                   type: success,                   display: <span class="basicdiceroll critsuccess ">8</span>                },                {                   v: 6,                   display: <span class="basicdiceroll">6</span>                },                {                   v: 6,                   display: <span class="basicdiceroll">6</span>                },                {                   v: 5,                   type: drop,                   display: <span class="basicdiceroll dropped">5</span>                },                {                   v: 7,                   display: <span class="basicdiceroll">7</span>                },                {                   v: 5,                   type: drop,                   display: <span class="basicdiceroll dropped">5</span>                },                {                   v: 6,                   display: <span class="basicdiceroll">6</span>                },                {                   v: 9,                   type: success,                   display: <span class="basicdiceroll critsuccess ">9</span>                },                {                   v: 2,                   type: drop,                   display: <span class="basicdiceroll dropped">2</span>                },                {                   v: 9,                   type: success,                   display: <span class="basicdiceroll critsuccess ">9</span>                }             ]          }       ] Rolling [[6d6mt]]     [          {             expression: 6d6mt,             parsed: (3+4+2+3+3+1),             resultType: match,             total: 1,             value: 1,             labels: [],             tableReturns: [],             display: (<span class="basicdiceroll" style="color: #ee0086">3</span>+<span class="basicdiceroll">4</span>+<span class="basicdiceroll">2</span>+<span class="basicdiceroll" style="color: #ee0086">3</span>+<span class="basicdiceroll" style="color: #ee0086">3</span>+<span class="basicdiceroll critfail ">1</span>),             dice: [                {                   v: 3,                   display: <span class="basicdiceroll" style="color: #ee0086">3</span>                },                {                   v: 4,                   display: <span class="basicdiceroll">4</span>                },                {                   v: 2,                   display: <span class="basicdiceroll">2</span>                },                {                   v: 3,                   display: <span class="basicdiceroll" style="color: #ee0086">3</span>                },                {                   v: 3,                   display: <span class="basicdiceroll" style="color: #ee0086">3</span>                },                {                   v: 1,                   type: fail,                   display: <span class="basicdiceroll critfail ">1</span>                }             ]          }       ] Rolling [[ 2t[Body-Location] [Hit Location] ]]     [          {             expression: 2t[Body-Location] [Hit Location],             parsed: (Vitals+Stomach),             resultType: sum,             total: 0,             value: Vitals,             labels: [                {                   label: Hit Location,                   value:                  }             ],             tableReturns: [                {                   table: Body-Location,                   returns: [                      Vitals,                      Stomach                   ]                }             ],             display: (Vitals+Stomach),             dice: []          }       ] Formatting Differences vs Native Roll20 As previously mentioned, there are a couple of formatting differences in a roll's roll-tip that you should be aware of should you use the roll-tips provided by `libInline`. No Quantum Logo  -- Although `libInline` generates no dice and makes no rolls on its own (it only formats what was already there), it does not include the quantum roll logo (the nuclear icon). Fate Dice -- At the time of writing this help/readme, exploding + penetrating fate dice report incorrectly to the built-in Roll20 roll-tip. If a die explodes and the subsequent die rolls a `-`, the penetrating designation turns it into a double minus (a `-2`, in effect). While this is accurately reporting in the total value of the roll, the `-2` does **not** show up in the roll tip. In fact, the roll-tip seems to depict 1-fewer die for each `-2` so created. `libInline` addresses that by including one more symbol in the roll-tip equation for fate dice. Where a `1` is a `+`, and a `-1` is a `-`, a `-2` is represented by a `=`. In the image, note how the two `-2` dice are missing in the Roll20 roll-tip. There is no way, with penetrating exploding fate dice that a `+` (the highest possible outcome of a single die) could ever be followed by a `+`, so seeing the pattern of `++` is an indication that a die was left out. Similarly, the last `+` of the roll should have exploded and produced another die; in fact, it did, as you can see from the `libInline` roll-tip. Match Dice -- A matched dice roll applies a whole series of colors to the roll-tip output to designate dice involved in the various matches. As with other rolls, though, you can drop dice. Dropped dice should not be included in any match, and therefore should not be formatted as being a part of a match group. In the built-in Roll20 roll-tip, however, that's exactly what happens. `libInline` corrects this by detecting whether the die was dropped before attaching the designated CSS color to the die in the roll-tip In the image, note how on the Roll20 side the initial three `1`s were formatted as if they were part of a match, when in fact they were dropped (as demonstrated in the `libInline` rendering of the roll-tip). While there is a subtle difference of bolding between the two types of `1`s (dropped vs match group), if you do not see them side by side your eye may not detect the difference. We think it's better to see the dropped dice as dropped, and only the remaining dice that are involved in the match to be color coded as such. Change Log Version 1.0.0 - Initial Release Version 1.0.1 ( link ) - Minor change, no impact to implementation
1612388292

Edited 1612389035
timmaugh
Pro
API Scripter
Code Examples Parsing the entire inlinerolls array and assigning the items to a variable: let pir = libInline.getRollData(msg); Replacing all instances of a roll marker (ie, $[[0]]) with the roll tip from the parsed object: msg.content = msg.content.replace(/\$\[\[(\d+)]]/g, ((m, g1) => pir[g1].getRollTip())); Getting the included dice for a given roll from a parsed roll object variable: let incDice = pir[0].getDice('included'); Getting the critical failure dice from a straight call (no parsed object): let fumbleDice = libInline.getDice(msg.inlinerolls[0], 'fail'); Getting the value (number or table result) from a roll, using the parsed object: let rollval = pir[0].value; Getting the value (number or table result) from a roll using the base function (no parsed object): let rollval = libInline.getValue(msg.inlinerolls[0]);
1612454057

Edited 1620741852
timmaugh
Pro
API Scripter
Version 1.0.1 Release Updated at original link and one-click submission Date: Feb 4, 2021 Changed : Consistent with Aaron's note of versioning being tracked in APIMeta, I replaced local housing of the version (scoped to the script) to the APIMeta object. User will see no change. Version 1.0.3 Release Updated at original link and one-click submission May 11, 2021 FIXED : 0-die rolls now work, e.g, [[ 0d20 + @{selected|Strength_Dice}]]