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

Run part of a macro several times

1683068406

Edited 1683068457
Hello there ! I've been playing around with my damage macros for a bit, now. The macro is now working perfectly, but I've met a new need : the need to roll it several times. See, I can stumble on situation in which I may need to roll damage up to 8 times. I have three ways to do it : - Use the macro 1-8 times. - Add a query in the macro and multiply it by the result of the damage macro, so that my players can input the multiplier themselves. - Find a way to tell the macro "run this line x times". The first solution is a big no no, it's way too tedious. The second solution would work, except for the fact that there would only be one roll, multiplied by 1-8. But the base value of the roll would stay the same, so I might as well just use a calculator. If I want each damage roll to be rolled individually, I need some way to tell the macro "repeat that line x times", and after searching around on Google, I couldn't find anything. Solutions would either call for a script, or for the character sheet to be used. I have no idea how to do it with a script, and using the sheet wouldn't be doable. So, my question boils down to : is there a way to tell a macro "run this line x times" with x being the value input in a "?{numberoftimes|0}" query ? Thanks for reading my question. Have a good one, friends !
What game are you playing and what character sheet are you using? What is the content of the macro you want to duplicate? The short answer is there’s no easy built in way to duplicate a roll multiple times. The longer answer is it may be possible to restructure your macro to get the result you want. 
1683070268
timmaugh
Forum Champion
API Scripter
I have done this with metascripts a number of times. When you share your macro I can probably provide an option in addition to what magic Jarren might be able to come up with. =D
Thank you for your answers, and apologies for the lack of macro-providing ! We are playing a Fallout game. I am using an old Fallout PnP v4.0 Character Sheet, but the official rules have changed so much, and I diverted so much from those rules, that we don't use the official sheet for attack and damage rolls. I'm not skilled enough nor do I have enough time to fix the entire sheet, which was already outdated back when we started the campaign. Using this sheet for attacks was never practical anyway because it lacked many parameters. Here it is : !?{Minimum Damage|0} ?{Maximum Damage|0} /roll (([[ 1d[[ abs([[?{Minimum Damage|0}-?{Maximum Damage|0} ]]) +1 ]] - 1 ]] + ?{Minimum Damage|0}) * ?{Damage Modifier|1} - (?{Damage Threshold|0}) * ((100 - (?{Penetration|0}))/100)) Every damage roll relies on four variables : the damage range, the damage multiplier, the damage treshold, and the penetration. So, what this does is : - The player inputs their weapon's minimum and maximum damage. The formula will use those to roll a dice with a a number of faces equal to the difference between the two values, +1. The -1 is then used to make sure that the lowest damage can be rolled, since we can't roll a 0 on a dice. - The player then inputs the Damage Modifier, which is affected by perks or critical hits. It is a plain multiplier. - The Damage Threshold is next, and is the armor value. It will be substracted from the damage dealt to the defender. - And finally, we have the Penetration, which is a percentage of the Threshold ignored by the weapon, which usually means that armor-piercing ammo/weapons have been used. In the end, this macro boils down to the following formula : Damage * DM - DT * Penetration Right now, I can't simply multiply the result by 1-8, because the Damage value will then remain the same. Let's say a weapon does 50-70 damage, and the final damage value is 63. Multiplying it by 8 would mean that the player would have essentially rolled a 63 eight times in a row, instead of rolling eight different values. This would change a lot of things. Apologies if my explanation is a tad confused. It's clear in my brain, so feel free to tell me if something is too vague. Thanks !
1683112623
David M.
Pro
API Scripter
Seems like a good candidate for Scriptcards, though Tim's metascripts will be a valid solution as well. !script {{ --#title|Fallout Damage --=minDam|?{Minimum Damage} --=maxDam|?{Maximum Damage} --=mod|?{Damage Modifier} --=threshold|?{Damage Threshold} --=penetration|?{Penetration} --=penPercent|100-[$penetration] / 100 --=numRolls|?{Number of Rolls|1} --#leftsub|Base Damage: [$minDam] - [$maxDam] --#rightsub|Modifier: [$mod] --=die|[$maxDam] - [$minDam] {ABS} +1 --=modDam|[$minDam]*[$mod] --=netArmor|[$threshold] * [$penPercent] --+|[c][b]Threshold: [$threshold] ~ Penetration: [$penetration][/b][/c] --%i|1;[$numRolls] -->RollDamage| --%| --+|[c][b][#990000]Total Damage: [/#][$totalDamage][/b][/c] --X| End Macro --:FUNCTIONS| --:RollDamage| --=damage|1d[$die] - 1 + [$modDam] - [$netArmor] {FLOOR} --+|[c][b]Damage [&i]: [$damage][/b][/c] --=totalDamage|[$totalDamage] + [$damage] --<| }}
This can also be done without mods. You don't get the breakdown that ScriptCards provides but by rolling the required number of dice and multiplying the modifiers your existing macro can become !?{Minimum Damage|0} ?{Maximum Damage|0} /roll (([[ ?{Number of Rolls|1}d[[ abs([[?{Minimum Damage|0}-?{Maximum Damage|0} ]]) +1 ]] - ?{Number of Rolls} ]] + ?{Number of Rolls}*?{Minimum Damage|0}) * ?{Damage Modifier|1} - (?{Number of Rolls}*?{Damage Threshold|0}) * ((100 - (?{Penetration|0}))/100))
1683125962
timmaugh
Forum Champion
API Scripter
And a third solution, in addition to the excellent options David and RainbowEncoder have already provided. Before I present it, though, I would say that even if you don't roll with this metascript solution, you should steal some of the ideas for set up that can reduce the number of queries you have to answer... ...every... .......time...... .........you......... ............run............ ...............the............... ..................command .................. Here's what I mean: your sheet may be outdated for running the attacks the way you want, but you can always add a new attribute or ability to the sheet. Just go to the Attributes & Abilities tab of the character sheet, then hit +Add for the left hand column (the attributes). For my setup, I gave my characters an attribute for their various weapons, with the range of damage in the Current and Max. For each of those weapons, I also gave them an attribute that represented the Penetration value of that weapon. Whatever the weapon attribute was named, I named the penetration version the same name plus "_penetration". Here is an imagined Pistol setup on a character, with a damage range of 30-50, and a penetration value of 10: I also gave every character an attribute named equipped_weapon that would house the name of the weapon they were currently wielding: Now, you can't do "extended names" (like what I'm about to show) with native Roll20 constructions -- you can't nest attribute names within attribute names, but you *can* do it with Fetch: @{selected|equipped_weapon}    => Pistol @(selected.@{selected|equipped_weapon})    =>  30 @(selected.@{selected|equipped_weapon}.max)    =>  50 @(selected.@{selected|equipped_weapon}_penetration) =>  10 Doing that reduced the number of queries I had to answer by 3. All I had to do was manage what weapon a character had equipped (for instance, if she wanted to change from a pistol to a flamethrower I would have to change the equipped_weapon to the name of the attribute representing the flamethrower)... and that can even be managed with a ChatSetAttr command if you don't want to have to open your sheet. (The Fetch constructions will work in the ScriptCards command David shared -- that's what metascripts do -- but they won't work in RainbowEncoder's solution because RE never engages the script engine.) MetaScript Solution Here's the metascript solution, including the setup. On a character named MuleCharacter , I created 2 abilities. I named them AttackParts and RepeatingAttack . The RepeatingAttack ability could be named anything; if you rename the AttackParts ability, you will need to chase that name change through the text of the RepeatingAttack ability. In my AttackParts ability, I entered the text: TemplateLine={{Attack # get.MuleCharacter.AttackParts.Counter/get = [\\][\\](([\\][\\] 1d[\\][\\] abs([\\][\\]mindmg - maxdmg \\]\\]) + 1 \\]\\] - 1 \\]\\] + mindmg) * dmgmod - (dmgthresh) * ((100 - (atkpen))/100))\\]\\]}} set\.MuleCharacter.AttackParts.Counter = {\& math get.MuleCharacter.AttackParts.Counter/get + 1}/set {\&if get.MuleCharacter.AttackParts.Counter/get < get.MuleCharacter.AttackParts.Attacks/get}get.MuleCharacter.AttackParts.TemplateLine/get{\&end} Attacks=1 Counter=1 And in RepeatingAttack I entered: !&{template:default} {\&global ([mindmg] @(selected.@{selected|equipped_weapon})) ([maxdmg] @(selected.@{selected|equipped_weapon}.max)) ([dmgmod] ?{Damage Modifier|1}) ([dmgthresh] ?{Damage Threshold|0})([atkpen] @(selected.@{selected|equipped_weapon}_penetration[0]))} {{name=@{selected|token_name} Attacks!}}{{Min/Max (Mod)=mindmg / maxdmg (dmgmod)}} {{Threshold/Penetration=dmgthresh / atkpen}}{{---------- ATTACKS =**----------**}}{&simple} get\.MuleCharacter.AttackParts.TemplateLine/get  set.MuleCharacter.AttackParts.Counter = 1/set set.MuleCharacter.AttackParts.Attacks=?{Number of Attacks?|1|2|3|4|5|6|7|8}/set REQUIRED SCRIPTS ZeroFrame, Fetch, MathOps, APILogic, Muler EXAMPLE OUTPUTS Running RepeatingAttack yields the following output: EXPLANATION We use ZeroFrame to set a few global variables (for min damage, max damage, threshold, and penetration). As mentioned, some of those values come from Fetch constructions going to get the weapon numbers for the selected character's currently equipped weapon. Initially, RepeatingAttack has a Muler construction to set values in the AttackParts mule ability. We set the Attacks variable to the number of attacks we'll need, and we set the Counter to 1. Then Muler also goes to get the TemplateLine from the AttackParts mule. The TemplateLine variable has a single line of the final template we are going to want to output, along with some meta operations. First, the attack roll for this line will be fed the global variables from ZeroFrame, so we defer the roll until we can replace those. Also in the line, we bring in the code to increment the Counter variable by 1, and we bring logic that says "if the counter is less than the number of attacks we need, go get the TemplateLine variable again." In other words, until the Counter matches the total number of attacks we need, we get another line, with all of the same meta operations. When all of the meta-work is settled, the ZeroFrame {&simple} tag in the RepeatingAttack ability triggers ZeroFrame to output the finalized template to chat. Or, as we sometimes say... "Hoocha hoocha hoocha... lobster."
timmaugh said: Now, you can't do "extended names" (like what I'm about to show) with native Roll20 constructions -- you can't nest attribute names within attribute names, but you *can* do it with Fetch: @{selected|equipped_weapon}    => Pistol @(selected.@{selected|equipped_weapon})    =>  30 @(selected.@{selected|equipped_weapon}.max)    =>  50 @(selected.@{selected|equipped_weapon}_penetration) =>  10 Doing that reduced the number of queries I had to answer by 3. All I had to do was manage what weapon a character had equipped (for instance, if she wanted to change from a pistol to a flamethrower I would have to change the equipped_weapon to the name of the attribute representing the flamethrower)... and that can even be managed with a ChatSetAttr command if you don't want to have to open your sheet. (The Fetch constructions will work in the ScriptCards command David shared -- that's what metascripts do -- but they won't work in RainbowEncoder's solution because RE never engages the script engine.) You always give amazing Metascript solutions! One of these days I'll have time to dig in and really start using them, but it's still a bit of arcane magic to me. But there is a way - without scripts - to do 'extended names' using the ' prefix trick '. So for anyone who doesn't have a Pro subscription and access to Mod scripts: On the character sheet, you'd create an attribute called 'at' with a value of ' @' , and set up other custom attributes: Equipped_Weapon       pistol /  Pistol                30 / 50 Pistol_Penetration    10 /  And you could call them by using this: @{selected|equipped_weapon}    => Pistol @{selected|at}{selected|@{selected|equipped_weapon}} =>  30 @{selected|at} {selected|@{selected|equipped_weapon}|max}  =>  50 @{selected|at} {selected|@{selected|equipped_weapon}_Penetration} =>  10 If a weapon's minimum and maximum damage are fixed numbers, then they could be set up the same way, and a macro could be constructed that shouldn't require any queries at all. (Full disclosure: I haven't played Fallout so I'm not 100% clear on some of the mechanics here.)
1683129029
timmaugh
Forum Champion
API Scripter
Jarren said: Y ou always give amazing Metascript solutions! One of these days I'll have time to dig in and really start using them, but it's still a bit of arcane magic to me. Ha! We all have our own magical schools, don't we? Jarren  said: But there is a way - without scripts - to do 'extended names' using the ' prefix trick '. So for anyone who   doesn't  have a Pro subscription and access to Mod scripts: On the character sheet, you'd create an attribute called 'at' with a value of ' @' , and set up other custom attributes: <SNIP> And my particular school of magic is quite fond of forgetting this trick, apparently!
Oh my goodness, so many answers. It's getting mighty late now, but I shall crack on tomorrow. Thank you for all your answers, friends. I'll absolutely try your solutions and keep you updated on how it went. I have to admit I'm still unfamiliar with Roll20's scripts and macros, but I won't let that stop me. I never used ScriptCards before, and didn't even know they were a thing before I Googled around earlier today.
Well, friends. I'm still working on figuring out the Scriptcards, but I can at least say that RainbowEncoder's solutions worked wonders. That was a smart idea. RainbowEncoder said: This can also be done without mods. You don't get the breakdown that ScriptCards provides but by rolling the required number of dice and multiplying the modifiers your existing macro can become !?{Minimum Damage|0} ?{Maximum Damage|0} /roll (([[ ?{Number of Rolls|1}d[[ abs([[?{Minimum Damage|0}-?{Maximum Damage|0} ]]) +1 ]] - ?{Number of Rolls} ]] + ?{Number of Rolls}*?{Minimum Damage|0}) * ?{Damage Modifier|1} - (?{Number of Rolls}*?{Damage Threshold|0}) * ((100 - (?{Penetration|0}))/100)) It works perfectly for what I wanted to do, since I was having trouble balancing the shotguns. I'm still gonna explore the other options to try and improve my combats and make them as smooth and quick as I can. The Scriptcards look quite neat, I'm currently trying them out. As for Timmaugh's Metascript solution... this looks like it would make life much easier, once it's properly set-up ! Right now, it's making my ape brain bleed, but I'm gonna figure it out. I just have to see if it goes well with frequent weapon swapping, since my players have several, and it might very well become a staple of my fighting system. Thank you all for your answers. I'm now going to go back to the ScriptCards business, and let you know how it went.
1684160336

Edited 1684160361
David M. said: Seems like a good candidate for Scriptcards, though Tim's metascripts will be a valid solution as well. !script {{ --#title|Fallout Damage --=minDam|?{Minimum Damage} --=maxDam|?{Maximum Damage} --=mod|?{Damage Modifier} --=threshold|?{Damage Threshold} --=penetration|?{Penetration} --=penPercent|100-[$penetration] / 100 --=numRolls|?{Number of Rolls|1} --#leftsub|Base Damage: [$minDam] - [$maxDam] --#rightsub|Modifier: [$mod] --=die|[$maxDam] - [$minDam] {ABS} +1 --=modDam|[$minDam]*[$mod] --=netArmor|[$threshold] * [$penPercent] --+|[c][b]Threshold: [$threshold] ~ Penetration: [$penetration][/b][/c] --%i|1;[$numRolls] -->RollDamage| --%| --+|[c][b][#990000]Total Damage: [/#][$totalDamage][/b][/c] --X| End Macro --:FUNCTIONS| --:RollDamage| --=damage|1d[$die] - 1 + [$modDam] - [$netArmor] {FLOOR} --+|[c][b]Damage [&i]: [$damage][/b][/c] --=totalDamage|[$totalDamage] + [$damage] --<| }} I really like your solution, mate. I now have a nice looking damage card ! I might modify it further so that the title is automatically pulled from the sheet's weapon line, if I ever get around to fixing that messy sheet I use. So... probably never. Thanks again mate !
1684160764
David M.
Pro
API Scripter
Great!