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

Help with retrieving specific inline-roll value using roll indexing in custom roll template

1699184070

Edited 1699191783
Hello,  I've had a look at historic posts and whilst there are some people with similar issues posting i haven't seen many / any from recent years so some more eyes on the problem would be appreciated. I feel like i'm 99% of the way there but this last piece is stumping me. The games resolution system is roll under 1d10 with a variable comparator & variable target numbers. This also means that I need to retrieve multiple "complex" bits of info from the core resolution roll (there's also a secondary target number for full/partial successes but that's not causing any issues): Roll 1d10(r) & compare to character attribute(a) and target difficulty(D). if r>a then roll is bust. Perform (a-r-D) to get a negative margin of success. if r<a then perform (r-D) to get a potentially (normally) positive margin of success. 10 is always a fumble, exactly (a) is a crit success. The rub comes in that as far as I can tell, when using roll templates only the first major inline roll group can perform mathematical operations. This has lead me to try and condense all of the above logic into a single operation with mixed success into:     [a-(1d10-D)-2D] The value of the round brackets provides the "success" margin of success, and the value of the square brackets gives the "bust" margin of success. I'm succesfully able to retrieve all of my desired information EXCEPT for the " bust " margin of success, i suspect this is because i am trying to call an index number for an inline roll that is both earlier in the order of operations but also part of the same overall inline roll operation. In the below code snippet @{awareness} is the character attribute being targeted by this particular roll: value = "&{template:checks} [[ @{awareness}-[[ [[d10cs@{awareness}cf10]]-[[?{Difficulty|1}]] ]]-(2*$[[1]]) ]] {{bustmos=$[[6]]}} {{mos=$[[2]]}} {{title=Awareness (@{awareness})}} {{roll=$[[0]]}} {{aspect=[[@{awareness}]]}} {{subtitle=@{character_name}}} {{difficulty=$[[1]]}} {{risk=[[?{Risk|1}]]}}" < rolltemplate class = "sheet-rolltemplate-checks" >   < div class= "sheet-container" >     < div class= "sheet-header" >       {{ #title }} < div class= "sheet-title" > {{ title }} </ div > {{ /title }}       {{ #name }} < div class= "sheet-name" > {{ name }} </ div > {{ /name }}       {{ #subtitle }} < div class= "sheet-subtitle" > {{ subtitle }} </ div > {{ /subtitle }}     </ div >     < div class= "sheet-content" >       < div class= "sheet-targets" >< span > Difficulty: </ span > {{ difficulty }} Risk: {{ risk }} </ div >       {{ #roll }}         < div class= "sheet-roll" >           < span > Roll: </ span > {{ roll }}         </ div >       {{ /roll }}       {{ #rollLess () roll difficulty }}         < span class= "sheet-fumble" > Difficulty not met. MOS: </ span > {{ mos }}       {{ /rollLess () roll difficulty }}       {{ #rollLess () roll risk }}         < span class= "sheet-fumble" > Risk not met. </ span >       {{ /rollLess () roll risk }}       {{ #rollBetween () roll risk aspect }}         < span class= "sheet-success" > Full Success. MOS: </ span > {{ mos }}       {{ /rollBetween () roll risk aspect }}       {{ #rollGreater () roll aspect }}         < span class= "sheet-bust" > Roll is bust. MOS: </ span > {{ bustmos }}       {{ /rollGreater () roll aspect }}       {{ #rollWasFumble () roll }}         < span class= "sheet-fumble" > Complication. </ span >       {{ /rollWasFumble () roll }}       {{ #rollWasCrit () roll }}         < span class= "sheet-critical" > Crit Success. </ span >       {{ /rollWasCrit () roll }}     </ div >   </ div > </ rolltemplate > This gives outputs as below in the sheet sandbox: Full success: And bust: It isn't obvious from the screenshot above but the output of {{bustmos}} appears to be currently picking up the value of the {{aspect}} inline roll. But counting out the order of operations myself, it looks like I should want $[[3]]. Much appreciation for anyone who read all of the above and anyone that's able to provide some assistance / clarity.
Appreciate this is a niche question but by my own counting the inline rolls would be numbered as follows: value = "&{template:checks} [[ 3 @{awareness}-[[ 2 [[ 0 d10cs@{awareness}cf10]] 0 -[[ 1 ?{Difficulty|1}]] 1 ]] 2 -(2*$[[1]]) ]] 3 {{bustmos=$[[6]]}} {{mos=$[[2]]}} {{title=Awareness (@{awareness})}} {{roll=$[[0]]}} {{aspect=[[ 4 @{awareness}]] 4 }} {{subtitle=@{character_name}}} {{difficulty=$[[1]]}} {{risk=[[ 5 ?{Risk|1}]] 5 }}" Anyone able to spot any obvious mistakes with this?
1699199200

Edited 1699201205
I'll continue to document in this thread in case it turns out to be useful for anyone else. Mods can tell me off if they'd rather I did this inside edits / not at all. I attempted to move the {{bustmos}} variable from being the pipeline output of an inline roll to being the container variable for the whole operation. This gave me a new output: value = "&{template:checks} {{bustmos=[[ @{awareness}-[[ [[d10cs@{awareness}cf10]]-[[?{Difficulty|1}]] ]]-(2*$[[1]]) ]]}} {{mos=$[[2]]}} {{title=Awareness (@{awareness})}} {{roll=$[[0]]}} {{aspect=[[@{awareness}]]}} {{subtitle=@{character_name}}} {{difficulty=$[[1]]}} {{risk=[[?{Risk|1}]]}}" This demonstrates that the program was succesfully able to expand all the sub-rolls inside the exterior roll. But the exterior roll itself is not being calculated, instead it is being displayed as is / as string. Next thought is to try incorporating (1d1-1) into the exterior roll in order to force the dice engine to interpret it as a roll with modifiers. EDIT: This did not work.
1699203013

Edited 1699208456
Having gone back to the community wiki it appears that my problem is trying to re-use the result of an in-line roll. Specifically the user inputted difficulty. These resources helped me in figuring out why I was having problems: <a href="https://wiki.roll20.net/Reusing_Rolls" rel="nofollow">https://wiki.roll20.net/Reusing_Rolls</a> <a href="https://app.roll20.net/forum/post/10693202/macro-curiosities-or-how-to-overcomplicate-everything/?pageforid=10693208#post-10693208" rel="nofollow">https://app.roll20.net/forum/post/10693202/macro-curiosities-or-how-to-overcomplicate-everything/?pageforid=10693208#post-10693208</a> However, they are beyond my ability to interpret them such that I can make them useful for my own project.
1699210417
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Since you are building a custom character sheet, I would recommend not using the reuse rolls trick. Instead use custom roll parsing to do this complex logic via JavaScript.
Thanks Scott, I was taking things step by step in my sheet construction and hadn't gotten to sheetworkers yet so hadn't considered them as an option for this, especially as my desired result had seemed so close... Appreciate the input.
1699224661

Edited 1699243094
GiGs
Pro
Sheet Author
API Scripter
Scott's suggestion of Custom Roll Parsing seems like the way to go here. You want to extract multiple pieces of information from the roll, and use them in different ways, and CRP excels at that kind of thing. It might be possible by other means, but it'll be more elegant with CRP. Here's a guide: <a href="https://cybersphere.me/guide-to-custom-roll-parsing/" rel="nofollow">https://cybersphere.me/guide-to-custom-roll-parsing/</a>
1699239210
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
I'll also add that CRP will be easier to maintain and update. Using the reuse rolls, if you change the roll expression you then have to go update all your indices, and. With CRP, as long as you keep the same field names, your js code won't change other than whatever you need to add for sending and handling the additions.
1699347815

Edited 1699350709
Final update to say that I was succesfully able to perform this action using CRP. Thanks to Scott for the suggestion and GiGs for the learning resource. For anyone else trying to learn how CRP works <a href="https://cybersphere.me/guide-to-custom-roll-parsing/" rel="nofollow">https://cybersphere.me/guide-to-custom-roll-parsing/</a> is far superior to the wiki.roll20.net resources. I'm sure my work is a bit rough and ready for most but it may help someone illustrate a point. For reference: Button definition on the charsheet: &nbsp; &nbsp; &lt; div class = "f-row nowrap" &gt; &nbsp; &nbsp; &nbsp; &lt; label for = "awareness_input" &gt; Awareness &lt;/ label &gt; &nbsp; &nbsp; &nbsp; &lt; input type = "number" name = "attr_awareness" value = "3" min = "1" max = "9" id = "awareness_input" /&gt; &nbsp; &nbsp; &nbsp; &lt; button type = "roll" name = "roll_awareness" value = "@{awareness_check_attrib}" &gt;&lt;/ button &gt; &nbsp; &nbsp; &nbsp; &lt; button type = "action" name = "act_awareness_check" class = "hidden" &gt;&lt;/ button &gt; &nbsp; &nbsp; &nbsp; &lt; input type = "hidden" name = "attr_awareness_check_attrib" value = "%{Name|awareness_check}" &gt; &nbsp; &nbsp; &lt;/ div &gt; Roll template: &lt; rolltemplate class = "sheet-rolltemplate-checks" &gt; &nbsp; &lt; div class= "sheet-container" &gt; &nbsp; &nbsp; &lt; div class= "sheet-header" &gt; &nbsp; &nbsp; &nbsp; {{ #title }} &lt; div class= "sheet-title" &gt; {{ title }} &lt;/ div &gt; {{ /title }} &nbsp; &nbsp; &nbsp; {{ #name }} &lt; div class= "sheet-name" &gt; {{ name }} &lt;/ div &gt; {{ /name }} &nbsp; &nbsp; &nbsp; {{ #subtitle }} &lt; div class= "sheet-subtitle" &gt; {{ subtitle }} &lt;/ div &gt; {{ /subtitle }} &nbsp; &nbsp; &lt;/ div &gt; &nbsp; &nbsp; &lt; div class= "sheet-content" &gt; &nbsp; &nbsp; &nbsp; &lt; div class= "sheet-targets" &gt;&lt; span &gt; Difficulty: &lt;/ span &gt; {{ difficulty }} Risk: {{ risk }} &lt;/ div &gt; &nbsp; &nbsp; &nbsp; {{ #roll }} &nbsp; &nbsp; &nbsp; &nbsp; &lt; div class= "sheet-roll" &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt; span &gt; Roll: &lt;/ span &gt; {{ roll }} &nbsp; &nbsp; &nbsp; &nbsp; &lt;/ div &gt; &nbsp; &nbsp; &nbsp; {{ /roll }} &nbsp; &nbsp; &nbsp; {{ #rollLess () roll difficulty }} &nbsp; &nbsp; &nbsp; &nbsp; &lt; div &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt; span class= "sheet-fumble" &gt; Difficulty not met. &lt;/ span &gt;&lt; span class= "sheet-mos" &gt; MOS: {{ mos }} &lt;/ span &gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/ div &gt; &nbsp; &nbsp; &nbsp; {{ /rollLess () roll difficulty }} &nbsp; &nbsp; &nbsp; {{ #rollBetween () roll difficulty computed :: risk }} &nbsp; &nbsp; &nbsp; &nbsp; &lt; div &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt; span class= "sheet-fumble" &gt; Partial Success. &lt;/ span &gt;&lt; span class= "sheet-mos" &gt; MOS: {{ computed :: mos }} &lt;/ span &gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/ div &gt; &nbsp; &nbsp; &nbsp; {{ /rollBetween () roll difficulty computed::risk }} &nbsp; &nbsp; &nbsp; {{ #rollBetween () roll risk aspect }} &nbsp; &nbsp; &nbsp; &nbsp; &lt; div &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt; span class= "sheet-success" &gt; Full Success. &lt;/ span &gt;&lt; span class= "sheet-mos" &gt; MOS: {{ computed :: mos }} &lt;/ span &gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/ div &gt; &nbsp; &nbsp; &nbsp; {{ /rollBetween () roll risk aspect }} &nbsp; &nbsp; &nbsp; {{ #rollGreater () roll aspect }} &nbsp; &nbsp; &nbsp; &nbsp; &lt; div &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt; span class= "sheet-bust" &gt; Roll is bust. &lt;/ span &gt;&lt; span class= "sheet-mos" &gt; MOS: {{ computed :: bustmos }} &lt;/ span &gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/ div &gt; &nbsp; &nbsp; &nbsp; {{ /rollGreater () roll aspect }} &nbsp; &nbsp; &nbsp; {{ #rollWasFumble () roll }} &nbsp; &nbsp; &nbsp; &nbsp; &lt; div &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt; span class= "sheet-fumble" &gt; Complication. &lt;/ span &gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/ div &gt; &nbsp; &nbsp; &nbsp; {{ /rollWasFumble () roll }} &nbsp; &nbsp; &nbsp; {{ #rollWasCrit () roll }} &nbsp; &nbsp; &nbsp; &nbsp; &lt; div &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt; span class= "sheet-critical" &gt; Crit Success. &lt;/ span &gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/ div &gt; &nbsp; &nbsp; &nbsp; {{ /rollWasCrit () roll }} &nbsp; &nbsp; &lt;/ div &gt; &nbsp; &lt;/ div &gt; &lt;/ rolltemplate &gt; Relevant section of CRP script block: &lt; script type = "text/worker" &gt; &nbsp; function capitalizeFirstLetter ( string ) { &nbsp; &nbsp; return string . charAt ( 0 ). toUpperCase () + string . slice ( 1 ); &nbsp; } &nbsp; const aspects = [ "awareness" , "brawn" , "grit" , "logic" , "presence" , "reflex" , "aim" , "cqc" ]; &nbsp; aspects . forEach ( function ( aspect ) { &nbsp; &nbsp; on ( "clicked:" + aspect + "_check" , function () { &nbsp; &nbsp; &nbsp; let capital_aspect = capitalizeFirstLetter ( aspect ) &nbsp; &nbsp; &nbsp; startRoll ( "&amp;{template:checks} {{roll=[[d10cs@{" + aspect + "}cf10]]}} {{difficulty=[[?{Difficulty|1}]]}} {{risk=[[?{Risk|1}]]}} {{title=" + capital_aspect + " (@{" + aspect + "})}} {{aspect=[[@{" + aspect + "}]]}} {{subtitle=@{character_name}}} {{mos=[[0]]}} {{bustmos=[[0]]}}" , basecheck =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; const roll_value = parseInt ( basecheck . results . roll . result ); &nbsp; &nbsp; &nbsp; &nbsp; const difficulty_value = parseInt ( basecheck . results . difficulty . result ); &nbsp; &nbsp; &nbsp; &nbsp; const aspect_value = parseInt ( basecheck . results . aspect . result ); &nbsp; &nbsp; &nbsp; &nbsp; const succ_mos = roll_value - difficulty_value ; &nbsp; &nbsp; &nbsp; &nbsp; const bust_mos = aspect_value - roll_value - difficulty_value ; &nbsp; &nbsp; &nbsp; &nbsp; finishRoll ( basecheck . rollId , { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mos: succ_mos , &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bustmos : bust_mos &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }); &nbsp; }); &lt;/ script &gt; Final Output: