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 .
×

Reusing a single Roll20 query for both target number and damage output?

Hello I have noticed the following, Roll20 : cannot reuse queries with different return types (text vs integers), does not support variables, only merges identical query strings. I am trying to optimise a Roll20 macro so that the player is only prompted once for range , but that value is then used to control multiple outputs: To-hit target number (e.g. 8+, 10+) Damage dice (e.g. 4d6 or 2d6) (Optionally) modifiers such as scatter bonus Currently I use two separate queries: ?{Range (to-hit target number)|0–20 m,**8+**|20–40 m,**10+**} ?{Range (roll damage at)|0–1.5 m,[ [4d6] ]|1.5–20 m,[ [4d6] ]|20–40 m,[ [2d6] ]} This results in multiple prompts , which I want to avoid. Question: What is the best practice in Roll20 macros to: Prompt for range only once Reuse that value to drive both: displayed target number (text like “8+”) dice roll output (e.g. [ [4d6] ] vs [ [2d6] ] ) Is the correct approach to encode the query as a numeric value and derive all outputs from it, or is there a cleaner pattern? A working example would be highly appreciated.
1775395786

Edited 1775395829
Jens
Pro
PS Even if i stick to the same data type it will only reuse the first output for the other two, scatter bonus and damage. Example, the following macro for a Cepheus Deluxe game, will roll 8d6 damage dice for effective range within twenty meters, where it should roll 4d6:  /w gm &{template:default} {{name=**TL-4 Shotgun Task Check**  *@{selected|character_name} fires at @{target|Foe|token_name}*}}{{Difficulty target number:=**?{Range|0 ‒ 20 m,8|20 ‒ 40 m,1}+**}}{{Modified to-hit roll:= [[2d6 + ([[floor((@{selected|dexterity}-6)/3)]] [dex-mod]) + (@{selected|gun_combat1} [Gun skill]) + (?{Range|0 ‒ 20 m,1|20 ‒ 40 m,0} [scatter bonus]) + (?{Target's stance|Not prone,0|Prone in the open, 2|Prone behind cover, 1|Running,1} [target's stance]) + (?{Target's cover is|None (in the open),0|Obscured,-1|Behind hard cover, -2|Behind heavy cover, -3|Behind total cover, -4} [target's cover]) + (?{Number of aiming actions|0,0|1,1|2,2|3,3} [aiming]) + (?{Ambient light is|Daylight,0|Dim light,-1|Darkness,-2} [ambient light])]]}}{{Damage:=[[?{Range|0 ‒ 20 m,4|20 ‒ 40 m,2}d6]]}}}}
1775409510
Gauss
Forum Champion
You can combine a query with a Rollable Table to provide different results, and use the query to act as a switch.  So if your ranges are:  0 - 1.5m  1.5 - 20m 20 - 40m  Then I would set the values to:  0 - 1.5m = 4 1.5 - 20m = 4 20 - 40m = 2 So for the range it would be (shortening the query here):  **[[1t[?{Range|0-1.5m,4|1.5-20m,4|20-40m,2}Range]]]**  With tables called 4Range and 2Range 4Range would have an output of 8+ 2Range would have an output of 10+ Then for the dice calculation:  [[?{Range|0-1.5m,4|1.5-20m,4|20-40m,2}d6]] So we now have the same query putting two different outputs.  This was an example based on your example, but it should give you an idea how to do it.
1775449008
timmaugh
Pro
API Scripter
As Gauss said, the "standard" way to get around this is to use rollable tables (or a character)... something with a name that can help discretize the data based on your query. Alternatively, you can pipe your template command line (including your query) through a script. There are a number of ways to do this with the Metascript Toolbox depending on how complex your output data needs to be. For instance, if there were 10 options in the query vs only 2 or 3. Since you only have a couple of options in the query, you could do it with a simple IF/THEN block (IF/THEN logic is not natively available from Roll20 syntax, but is made available by having the Toolbox installed in your game. From your example, here is the first query, giving the difficulty target number: ?{Range|0 ‒ 20 m,8|20 ‒ 40 m,1} Later you want to use it in a roll where it affects the To-Hit Roll: [[2d6 + ([[floor((@{selected|dexterity}-6)/3)]] [dex-mod]) + (@{selected|gun_combat1} [Gun skill]) + (?{Range|0 ‒ 20 m,1|20 ‒ 40 m,0} [scatter bonus]) + (?{Target's stance|Not prone,0|Prone in the open, 2|Prone behind cover, 1|Running,1} [target's stance]) + (?{Target's cover is|None (in the open),0|Obscured,-1|Behind hard cover, -2|Behind heavy cover, -3|Behind total cover, -4} [target's cover]) + (?{Number of aiming actions|0,0|1,1|2,2|3,3} [aiming]) + (?{Ambient light is|Daylight,0|Dim light,-1|Darkness,-2} [ambient light])]] Then your last usage is to contribute to damage figuring: [[?{Range|0 ‒ 20 m,4|20 ‒ 40 m,2}d6]] Each of those present 2 different outcomes that could happen... one with a Range of 0-20, and one with a Range between 20-40. So let's put each roll in a separate branch of an IF block. Since we're going to test the query in each instance, let's just give each potential output a value that we will be able to easily reference. For the sake of simplicity, I'll rewrite the query as: ?{Range|0 - 20 m,near|20 - 40 m,far} That way I can test the value of the query as the condition of my IF block (rolls replaced with ellipsis to focus on just the IF block construction: {&if ?{Range|0 - 20 m,near|20 - 40 m,far} = near} ... {&else} ... {&end} Now subbing back in the syntax of presenting the "Difficulty Target Number", you'd be looking at: {{Difficulty target number:=**{&if ?{Range|0 - 20 m,near|20 - 40 m,far} = near}8{&else}1{&end}+**}} For the To-Hit roll, putting the options into the IF block would mean having a roll in each branch of the logic... each just with the correct value represeted. That means you'd get: {&if ?{Range} = near}[[2d6 + ([[floor((@{selected|dexterity}-6)/3)]] [dex-mod]) + (@{selected|gun_combat1} [Gun skill]) + 1 [scatter bonus]) + (?{Target's stance|Not prone,0|Prone in the open, 2|Prone behind cover, 1|Running,1} [target's stance]) + (?{Target's cover is|None (in the open),0|Obscured,-1|Behind hard cover, -2|Behind heavy cover, -3|Behind total cover, -4} [target's cover]) + (?{Number of aiming actions|0,0|1,1|2,2|3,3} [aiming]) + (?{Ambient light is|Daylight,0|Dim light,-1|Darkness,-2} [ambient light])]] {&else}[[2d6 + ([[floor((@{selected|dexterity}-6)/3)]] [dex-mod]) + (@{selected|gun_combat1} [Gun skill]) + 0 [scatter bonus]) + (?{Target's stance|Not prone,0|Prone in the open, 2|Prone behind cover, 1|Running,1} [target's stance]) + (?{Target's cover is|None (in the open),0|Obscured,-1|Behind hard cover, -2|Behind heavy cover, -3|Behind total cover, -4} [target's cover]) + (?{Number of aiming actions|0,0|1,1|2,2|3,3} [aiming]) + (?{Ambient light is|Daylight,0|Dim light,-1|Darkness,-2} [ambient light])]]{&end} (Note that since we used the query once already in this macro AND we are matching the name exactly, we don't have to include all of the options.) Similarly, for the Damage calculation, you'd use the IF block to present the correct roll that would align with the choice from the query: {&if ?{Range|0 - 20 m,near|20 - 40 m,far} = near}[[4d6]]{&else}[[2d6]]{&end} TL;DR Your full macro would have to start with a bang ("!") to trigger script processing; it would need to be a single line (so your line breaks would have to be managed via different syntax); and you'd have to have a {&simple} in the message to dump your message out to chat (rather than allow it to remain in the scripts, never to be seen in the chat output). Adding those 2 components to the changes I just outlined, your finished macro would look like: !/w gm &{template:default} {{name=**TL-4 Shotgun Task Check**%NEWLINE%*@{selected|character_name} fires at @{target|Foe|token_name}*}} {{Difficulty target number:=**{&if ?{Range|0 - 20 m,near|20 - 40 m,far} = near}8{&else}1{&end}+**}}{{Modified to-hit roll:= {&if ?{Range} = near}[[2d6 + ([[floor((@{selected|dexterity}-6)/3)]] [dex-mod]) + (@{selected|gun_combat1} [Gun skill]) + 1 [scatter bonus]) + (?{Target's stance|Not prone,0|Prone in the open, 2|Prone behind cover, 1|Running,1} [target's stance]) + (?{Target's cover is|None (in the open),0|Obscured,-1|Behind hard cover, -2|Behind heavy cover, -3|Behind total cover, -4} [target's cover]) + (?{Number of aiming actions|0,0|1,1|2,2|3,3} [aiming]) + (?{Ambient light is|Daylight,0|Dim light,-1|Darkness,-2} [ambient light])]] {&else}[[2d6 + ([[floor((@{selected|dexterity}-6)/3)]] [dex-mod]) + (@{selected|gun_combat1} [Gun skill]) + 0 [scatter bonus]) + (?{Target's stance|Not prone,0|Prone in the open, 2|Prone behind cover, 1|Running,1} [target's stance]) + (?{Target's cover is|None (in the open),0|Obscured,-1|Behind hard cover, -2|Behind heavy cover, -3|Behind total cover, -4} [target's cover]) + (?{Number of aiming actions|0,0|1,1|2,2|3,3} [aiming]) + (?{Ambient light is|Daylight,0|Dim light,-1|Darkness,-2} [ambient light])]]{&end}}}{{Damage:={&if ?{Range|0 - 20 m,near|20 - 40 m,far} = near}[[4d6]]{&else}[[2d6]]{&end}}}}} Caveat For different reasons (with different command lines), it could become necessary to have the query within the inline roll (rather than using an IF block to enclose 2 different versions of the same roll). For instance, if you needed to re-use a roll, you'd have to refer to it by its index... meaning you couldn't always be picking between 2 different rolls that each had their own index. In this cases, the metascript syntax can get a little more complicated, but it's still very doable. If you want to go this route and you have a question or need help, just post back.