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

[Script] ScriptCards - My "Spiritual Successor" to PowerCards

1617037451
David M.
Pro
API Scripter
Ah, thanks for the clarification/correction, Tim!
David M.  Ok - I think I understand and I see what you did to fix it: you assigned the entire attribute to the string variable rather than the element.  Smart.  I used the second suggestion so I could use it for damage also.  Worked like a charm.  Thanks!
Sorry, new problem: Trying to query Normal|Advantage|Disadvantage for roll.  The following calculates the roll as kh1 (Advantage) regardless of query response:   --&NormalAdvDis|?{Advantage?|Normal|Advantage|Disadvantage}   --?[$NormalAdvDis] -eq Advantage|Adv   --?[$NormalAdvDis] -eq Disadvantage|Dis     --:Normal|   --=AttackRoll|1d20 [BASE] + [$[&Attribute]] [MOD] + @{selected|pb} [PROF] + @{selected|global_attack_mod}   --^Result|     --:Dis|   --=AttackRoll|2d20kl1 [BASE] + [$[&Attribute]] [MOD] + @{selected|pb} [PROF] + @{selected|global_attack_mod}   --^Result|     --:Adv|   --=AttackRoll|2d20kh1 [BASE] + [$[&Attribute]] [MOD] + @{selected|pb} [PROF] + @{selected|global_attack_mod}     --:Result|   --+Attack|@{selected|token_name} rolls [$AttackRoll] vs AC [$TargetAC].   --?[$AttackRoll.Base] -eq 20|Crit   --?[$AttackRoll.Base] -eq 1|Fumble   --?[$AttackRoll.Total] -ge [$TargetAC.Total]|Hit   --+Miss|The attack missed.   --^Final| TIA
1617060244
David M.
Pro
API Scripter
Michael, your NormalAdvDis variable is initialized as a string variable, but you are referencing it with a dollar sign as a roll variable i.e. [$NormalAdvDis]. Try using [&NormalAdvDis]. You might need to use -inc instead of -eq, but I'm not sure. So: --?[&NormalAdvDis] -inc Advantage|Adv You could also compact your code a little bit by using the following two lines to determine the roll --&RollType|?{Advantage?|Normal,1d20|Advantage,2d20kh1|Disadvantage,2d20kl1} --=AttackRoll|[&RollType][BASE] + [$[&Attribute]][MOD] + @{selected|pb} [PROF] + @{selected|global_attack_mod} This would take the place of the current query->conditionals->separate Normal/Adv/Dis blocks which is a little redundant. That is, unless you wanted to use the actual text "Normal/Advantage/Disadvantage" somewhere else in your card output in which case what you have is fine. Though in that case I'd probably create a single Roll procedure and pass in the roll text as a parameter. NBD either way, though, as long as it works! :)  If you use the two-line method, your full card would be something like this? !scriptcards {{ --:VARIABLE ASSIGNMENT| --&Attribute|?{Attribute|Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma} --=Strength|@{selected|strength_mod} --=Dexterity|@{selected|dexterity_mod} --=Constitution|@{selected|constitution_mod} --=Intelligence|@{selected|intelligence_mod} --=Wisdom|@{selected|wisdom_mod} --=Charisma|@{selected|charisma_mod} --=TargetAC|@{target|ac} --&RollType|?{Advantage?|Normal,1d20|Advantage,2d20kh1|Disadvantage,2d20kl1} --=AttackRoll|[&RollType][BASE] + [$[&Attribute]][MOD] + @{selected|pb} [PROF] + @{selected|global_attack_mod} --:OUTPUT| --+Attack|@{selected|token_name} rolls [$AttackRoll] vs AC [$TargetAC]. --?[$AttackRoll.Base] -eq 20|Crit --?[$AttackRoll.Base] -eq 1|Fumble --?[$AttackRoll.Total] -ge [$TargetAC.Total]|Hit --+Miss|The attack missed. --X| --:Crit| --+Do stuff on crit|Moar damage! --X| --:Fumble| --+Do stuff on fumble|Butterfingers! --X| --:Hit| --+Do stuff on hit|Yay! --X| }}
Thanks to the script ninjas here, I was able to get this scriptcard working. It calls an entry from a lingering injury table, assigns that injury to the character's bio field, and (with SelectManager enabled) adds a Combat Master condition to the token. (Have I mentioned how much I love the Case statement??) !scriptcard {{ --#title|Lingering Injury --#sourceToken|@{selected|token_id} --#emoteText|*@{selected|token_name} suffers an injury that will not go away!* --=Event|[T#Lingering-Injuries] --+[$Event.tableEntryText]|[r][img width=28][$Event.tableEntryImgURL][/img][/r] --&InjuryName|[$Event.tableEntryText] --C[&InjuryName]|Minor Scar:>MinorScar|Limp:>Limp|Broken Ribs:>BrokenRibs|Festering Wound:>FesteringWound|Broken Arm:>BrokenArm|Broken Foot:>BrokenFoot|Concussion:>Concussion|Horrible Scar:>HorribleScar] --X| --:MinorScar| --@forselected+|add-bio [$Event.tableEntryText] --@forselected+|cmaster _add,condition=minor scar --<| --:Limp| --@forselected+|add-bio [$Event.tableEntryText] --@forselected+|cmaster _add,condition=limp --<| --:BrokenRibs| --@forselected+|add-bio [$Event.tableEntryText] --@forselected+|cmaster _add,condition=broken ribs --<| --:FesteringWound| --@forselected+|add-bio [$Event.tableEntryText] --@forselected+|cmaster _add,condition=festering wound --<| --:BrokenArm| --@forselected+|add-bio [$Event.tableEntryText] --@forselected+|cmaster _add,condition=broken arm --<| --:BrokenFoot| --@forselected+|add-bio [$Event.tableEntryText] --@forselected+|cmaster _add,condition=broken foot --<| --:Concussion| --@forselected+|add-bio [$Event.tableEntryText] --@forselected+|cmaster _add,condition=concussion --<| --:HorribleScar| --@forselected+|add-bio [$Event.tableEntryText] --@forselected+|cmaster _add,condition=horrible scar --<| --<| }}
1617106432

Edited 1617107529
David M.  You Da Man!  That did work and was much more elegant than what I concocted.  I see my confusion...I expected the 2d20kh1 to be parsed as a numeric value rather than string - hence I treated the drop down as a string and the roll as a separate numeric variable.  In retrospect that's obviously an alphanumeric and would be a string variable. So, if I wanted to add a drop down to select damage, would this then work?      --&WeaponDamage|?{Weapon Damage?|1d4|1d6|1d8|1d10|1d12|2d6} followed by     --=Damage|[&WeaponDamage]+ [$[&Attribute]] [MOD]  I am a little bit confused about the  [$[&Attribute],  numeric within a string ?   Thanks!
1617108832
David M.
Pro
API Scripter
Michael, the [$[&Attribute]] syntax is a bit of an advanced trick, but basically it works because of this: In the example posted above, we made a bunch of roll variables like  --=Strength  ,  --=Dexterity  , etc. We also made a string variable named "Attribute" that contains the result of a query. We set up our query to only return the names of our roll variables from the first bullet point. Normally, we reference a roll variable using [$rollVarName] syntax. But, when Scriptcards sees "[&Attribute], it substitutes the value of the Attribute string variable into the expression.  So, if we selected "Strength" from our query (Attribute = "Strength"), then [$[&Attribute]] is the same as writing [$Strength]. These will be case-sensitive, btw. For your question about &WeaponDamage, you wouldn't need to use this trick. The following is a valid roll variable assignment with a hardcoded value:  --=Damage|1d4 So, to use a string variable in the --=Damage assignment, we can just use the standard string variable syntax to substitute for the hardcoded value:  --=Damage|[& WeaponDamage] So, if you wanted to keep WeaponDamage as a string variable, you would do this: --&WeaponDamage|?{Weapon Damage?|1d4|1d6|1d8|1d10|1d12|2d6} --=Damage|[&WeaponDamage] + [$[&Attribute]] [MOD] You could optionally have made WeaponDamage a roll variable, like this: --=WeaponDamage|?{Weapon Damage?|1d4|1d6|1d8|1d10|1d12|2d6} --=Damage|[$ WeaponDamage ] + [$[&Attribute]] [MOD] or like this  --=WeaponDamage|?{Weapon Damage?|1d4|1d6|1d8|1d10|1d12|2d6} --=Damage|[$ WeaponDamage.Text ] + [$[&Attribute]] [MOD] You can play around with it, mousing over the roll results to see how this affects the tooltips, etc. Using [$WeaponDamage] directly would probably lose the "1d4", etc. in your [$Damage] roll, as the result of the [$WeaponDamage] roll would be substituted in. Using [$WeaponDamage.Text] would substitute the text of the roll and preserve the source of the roll for tooltip purposes. If you didn't need to display WeaponDamage as it's own roll, then using the string variable type instead would probably make more sense. Finally,  you could have just baked the query directly in your Damage line, like this: --=Damage|?{Weapon Damage?|1d4|1d6|1d8|1d10|1d12|2d6} + [$[&Attribute]] [MOD] It's really just a matter of preference, readability (what makes the most sense to you), and whether you want to re-use WeaponDamage somewhere else in your card. The choice of variable type (string or roll) would be based on how you want to re-use it. I know that's a lot, but hopefully it gives you some insight!
David M.  Ok, it took me awhile to wrap my mind around it but I think I get it now.   [$[&Attribute]] is telling the script to take the numeric value contained within the string &Attribute (e.g. the value of  @{selected|strength_mod}) and use it in the calculation. That makes sense. I am most appreciative of the time you have spent helping me on this project.
1617120864
David M.
Pro
API Scripter
Michael, I think you got it, but just wanted to clarify semantics: [$[&Attribute]] is telling the script to use the value of the roll variable whose name is the value of the  string variable named "Attribute" [&Attribute]. The roll variable is the one that contains the @{selected|...} value, while the string variable just holds the name :)
David M. said: Michael, I think you got it, but just wanted to clarify semantics: [$[&Attribute]] is telling the script to use the value of the roll variable whose name is the value of the  string variable named "Attribute" [&Attribute]. The roll variable is the one that contains the @{selected|...} value, while the string variable just holds the name :) Hey David,  I'd like to ask for some clarification.  Can you do this with any 2 variables as well? For instance, I have 2 token ids stored as string variables; Victim1 and Victim2. I want to do some looping around and sometime want the ID [&Victim1] or [&Victim2]. If I set a variable equal to a number ( --=Number|1 ), can I use that number and math operations to switch between the 2 IDs like [&Victim[$Number]] for Number 1 then --=Number|[$Number] + 1 to get to Victim2 for [&Victim[$Number]]?
1617125579

Edited 1617125945
David M.
Pro
API Scripter
That should work, although you would prob need to use [&Victim[$Number.Total]], since you just want the value the roll variable interpreted as a string and not all the extra stuff that comes along with roll variables. Simple example: !scriptcards {{ --&Victim1|I'm Victim 1 --&Victim2|I'm Victim 2 --=NumLoops|5 --=i|0 --=VicNum|1 --:Loop| --+Value|[&Victim[$VicNum.Total]] --=i|[$i]+1 --=VicNum|[$i] % 2 +1 --?[$i.Total] -lt [$NumLoops.Total]|Loop }}
David M.  I think I get it - much like a pointer in C++
Thanks, David. That makes sense. And I also see that not capitalizing the "Total" is why most of my other cards have been failing miserably. 
1617137280

Edited 1617137500
Kurt J.
Pro
API Scripter
I've been working on a new major feature for ScriptCards - Array support. Right now, arrays can be defined directly, adding and removing items, iterating over them, etc.There is also a definition command that gets all of the tokens on a page so you can do something with them. If anyone has additional ideas for definition sources, please let me know. As an example, the test macro used in this video creates an array of all of the tokens on the same page as the target token. it then iterates through them and builds a new array of all of the tokens within 20 feet (4 units) of the target. Finally, it iterates through that array and rolls Dex saves against the caster's DC, calculates and applies damage, and shows some video effects: (not sure why all of the videos I convert to GIFs run at half speed... just pretend it is twice as fast as shown here... maybe I need a new GIF converter) Still a little work to do making sure everything is as sandbox friendly as I can make it, but this is what's up next :) One idea I've been toying with for this is finding an "empty" space on the VTT... If I set up an array of the spaces around a character and then get all of the tokens and check their positions, I should be able to simply remove the positions from the array that match. I'll be left with a list of open spaces. Fireball was flashier as a demo, though :)
1617149684
David M.
Pro
API Scripter
Awesome, can't wait to try this out, Kurt! Your fireball example seems like great potential synergy with the Spawn script, too ;) This sounds super cool - looking forward to it! 
Looks very good, Kurt and I look forward to seeing the final product.  I note that it does highlight one "problem" I have always had with AOE - the focal point always has to be set to a token rather than a place.  Though there are work-arounds it would be nice to be able to set a focus to any part of the page.
1617157221
David M.
Pro
API Scripter
Yeah, that is unfortunately a limitation of the api. There is no api access to the mouse or other UI, so all we have are workarounds :/
David M. said: Yeah, that is unfortunately a limitation of the api. There is no api access to the mouse or other UI, so all we have are workarounds :/  I'm working on -admittedly also a workaround- to fix this by having invisible tokens on each square of your grid (so only works on grid).  I have a question on a dice roll option I am missing: 1d12r<2 (reroll 1's and 2's). My fighter has a Brutal weapon with this property (dnd 4e), and I've been trying to make a workaround including conditional branching but it's messy at best... Any chance of this being added or a method I am not aware of to do this?  Just a run-of-the-mill example of one of his powers: !scriptcard  {{   --#title|Crushing Surge   --#leftsub|Fighter   --#rightsub|Attack 1   --#sourceToken|@{selected|token_id}   --#targetToken|@{target|token_id}   --#emoteText|I break through my enemy's armor and deal a painful bleeding wound.   --+At-Will ♦|Invigorating, Martial, Weapon   --+Standard Action|Melee Weapon   --+Target:|@{target|token_name}   --=TargetAC|@{target|ac}   --=AttackRoll|1d20 + 6 [STR+LVL] + 2 [Weapon] + 1 [Fighter] + 2 [Proficiency] + ?{Modifier to hit?|0} [Mod]   --+Attack|[$AttackRoll] vs AC.   --?[$AttackRoll.Base] -eq 20|Crit   --?[$AttackRoll.Base] -eq 1|Fumble   --?[$AttackRoll.Total] -ge [$TargetAC.Total]|Hit   --+Miss|The attack missed.   --^Final|   --:Fumble|   --+Fumble!|The attack went horribly wrong.   --^Final|   --:Hit|   --=Damage|1d12 + 4 [STR] + 2 [Weapon] + ?{Modifier to dam?|0} [Mod]   --+Hit!|The attack hit @{target|token_name} for [$Damage] damage.   --+Invigorating:|[b]+3[/b] [Con] Temporary Hit Points   --@token-mod|_ids @{selected|token_id} _ignore-selected _set bar3_value|3   --^Final|   --:Crit|   --=Damage|12 + 4 [STR] + 1d12 [High Crit] + 2d6 [Crit Bonus] + ?{Modifier to dam?|0}   --+Critical Hit!|The attack hit @{target|token_name} for [$Damage] damage.   --+Invigorating:|[b]+3[/b] [Con] Temporary Hit Points   --@token-mod|_ids @{selected|token_id} _ignore-selected _set bar3_value|3   --:Final|   --@token-mod|_ids @{target|token_id} _ignore-selected _set statusmarkers|markblue }}
1617216727
David M.
Pro
API Scripter
You can simulate the brutal roll syntax with a simple loop. See bold text below. Created a procedure called BrutalDamageRoll that you pass the die size and the brutal quality number, referenced as [%1%] and [%2%] respectively. The full Damage variable uses the result of the DieRoll variable that was determined in the BrutalDamageRoll procedure. Added a tooltip for the base damage die, as it would otherwise not show where the number came from. !scriptcard {{ --#title|Crushing Surge --#leftsub|Fighter --#rightsub|Attack 1 --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --#emoteText|I break through my enemy's armor and deal a painful bleeding wound. --+At-Will ♦|Invigorating, Martial, Weapon --+Standard Action|Melee Weapon --+Target:|@{target|token_name} --=TargetAC|@{target|ac} --=AttackRoll|1d20 + 6 [STR+LVL] + 2 [Weapon] + 1 [Fighter] + 2 [Proficiency] + ?{Modifier to hit?|0} [Mod] --+Attack|[$AttackRoll] vs AC. --?[$AttackRoll.Base] -eq 20|Crit --?[$AttackRoll.Base] -eq 1|Fumble --?[$AttackRoll.Total] -ge [$TargetAC.Total]|Hit --+Miss|The attack missed. --^Final| --:Fumble| --+Fumble!|The attack went horribly wrong. --^Final| --:Hit| -->BrutalDamageRoll|1d12;2 --=Damage|[$DieRoll] [1d12] [ + 4 [STR] + 2 [Weapon] + ?{Modifier to dam?|0} [Mod] --+Hit!|The attack hit @{target|token_name} for [$Damage] damage. --+Invigorating:|[b]+3[/b] [Con] Temporary Hit Points --@token-mod|_ids @{selected|token_id} _ignore-selected _set bar3_value|3 --^Final| --:Crit| --=Damage|12 + 4 [STR] + 1d12 [High Crit] + 2d6 [Crit Bonus] + ?{Modifier to dam?|0} --+Critical Hit!|The attack hit @{target|token_name} for [$Damage] damage. --+Invigorating:|[b]+3[/b] [Con] Temporary Hit Points --@token-mod|_ids @{selected|token_id} _ignore-selected _set bar3_value|3 --:Final| --@token-mod|_ids @{target|token_id} _ignore-selected _set statusmarkers|markblue --X| --:PROCEDURES| --:BrutalDamageRoll| Accepts die roll and brutal value as parameters, re-roll results -le the second parameter --:Loop| --=DieRoll|[%1%] --?[$DieRoll.Total] -le [%2%]|Loop --<| }}
1617220435
Richard M.
Pro
Sheet Author
Firstly, thanks Kurt, this is terrific. I've only been dabbling for a couple of days and managed to replicate a particularly fiddly set of game mechanics that needed conditionals and roll variables to replicate. One question - has anyone managed to solve the conundrum of sending a result to the turn-tracker? I managed to crowbar something using a mixture of ChatSetAttr in the Scriptcard and then GroupInit, called one after the other in a macro - but for some reason, it only works when I 'Test Macro' in the editor and not when it runs from the bar, token action or character sheet - I think because group-init is operating in chat and therefore somehow outpacing the script. I also found that I couldn't seem to call group-init directly from a scriptcard, although that might be me making a hash of the syntax... Grateful for any advice that anyone can offer.
1617220854
Kurt J.
Pro
API Scripter
David M. said: You can simulate the brutal roll syntax with a simple loop. See bold text below. Created a procedure called BrutalDamageRoll that you pass the die size and the brutal quality number, referenced as [%1%] and [%2%] respectively. The full Damage variable uses the result of the DieRoll variable that was determined in the BrutalDamageRoll procedure. Added a tooltip for the base damage die, as it would otherwise not show where the number came from. !scriptcard {{ --#title|Crushing Surge --#leftsub|Fighter --#rightsub|Attack 1 --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --#emoteText|I break through my enemy's armor and deal a painful bleeding wound. --+At-Will ♦|Invigorating, Martial, Weapon --+Standard Action|Melee Weapon --+Target:|@{target|token_name} --=TargetAC|@{target|ac} --=AttackRoll|1d20 + 6 [STR+LVL] + 2 [Weapon] + 1 [Fighter] + 2 [Proficiency] + ?{Modifier to hit?|0} [Mod] --+Attack|[$AttackRoll] vs AC. --?[$AttackRoll.Base] -eq 20|Crit --?[$AttackRoll.Base] -eq 1|Fumble --?[$AttackRoll.Total] -ge [$TargetAC.Total]|Hit --+Miss|The attack missed. --^Final| --:Fumble| --+Fumble!|The attack went horribly wrong. --^Final| --:Hit| -->BrutalDamageRoll|1d12;2 --=Damage|[$DieRoll] [1d12] [ + 4 [STR] + 2 [Weapon] + ?{Modifier to dam?|0} [Mod] --+Hit!|The attack hit @{target|token_name} for [$Damage] damage. --+Invigorating:|[b]+3[/b] [Con] Temporary Hit Points --@token-mod|_ids @{selected|token_id} _ignore-selected _set bar3_value|3 --^Final| --:Crit| --=Damage|12 + 4 [STR] + 1d12 [High Crit] + 2d6 [Crit Bonus] + ?{Modifier to dam?|0} --+Critical Hit!|The attack hit @{target|token_name} for [$Damage] damage. --+Invigorating:|[b]+3[/b] [Con] Temporary Hit Points --@token-mod|_ids @{selected|token_id} _ignore-selected _set bar3_value|3 --:Final| --@token-mod|_ids @{target|token_id} _ignore-selected _set statusmarkers|markblue --X| --:PROCEDURES| --:BrutalDamageRoll| Accepts die roll and brutal value as parameters, re-roll results -le the second parameter --:Loop| --=DieRoll|[%1%] --?[$DieRoll.Total] -le [%2%]|Loop --<| }} In addition to supporting arrays, the next version will also support the roll syntax XdYr>Z and XdYr<Z where Z will act as a roll threshold, so <2 will reroll dice of 2 or lower, while >5 would reroll dice of 5 or higher. Adding die formulae is fairly straightforward :) (Adding this took me about 10 minutes)... I just need to know what kinds of things people want the roll parser to support.  That isn't to invalidate David's workaround... it is pretty clever that it simulates showing the die formula to keep the tooltip looking correct!
1617223943
Kurt J.
Pro
API Scripter
Richard M. said: Firstly, thanks Kurt, this is terrific. I've only been dabbling for a couple of days and managed to replicate a particularly fiddly set of game mechanics that needed conditionals and roll variables to replicate. One question - has anyone managed to solve the conundrum of sending a result to the turn-tracker? I managed to crowbar something using a mixture of ChatSetAttr in the Scriptcard and then GroupInit, called one after the other in a macro - but for some reason, it only works when I 'Test Macro' in the editor and not when it runs from the bar, token action or character sheet - I think because group-init is operating in chat and therefore somehow outpacing the script. I also found that I couldn't seem to call group-init directly from a scriptcard, although that might be me making a hash of the syntax... Grateful for any advice that anyone can offer. Let me figure out how the tracker works and I'll see what I can do to support it.
1617225978
David M.
Pro
API Scripter
Kurt J. said: In addition to supporting arrays, the next version will also support the roll syntax XdYr>Z and XdYr<Z where Z will act as a roll threshold, so <2 will reroll dice of 2 or lower, while >5 would reroll dice of 5 or higher. Adding die formulae is fairly straightforward :) (Adding this took me about 10 minutes)... I just need to know what kinds of things people want the roll parser to support.  Great, Kurt! Another one that has come up before is exploding dice (e.g. 3d6! and 3d6!!). Again, could be solved with loops and trickery but innate support would lessen card complexity and make tooltips easier :)
Great, Kurt.  I was just going to ask the same thing about the turn tracker.
David M. said: Kurt J. said: In addition to supporting arrays, the next version will also support the roll syntax XdYr>Z and XdYr<Z where Z will act as a roll threshold, so <2 will reroll dice of 2 or lower, while >5 would reroll dice of 5 or higher. Adding die formulae is fairly straightforward :) (Adding this took me about 10 minutes)... I just need to know what kinds of things people want the roll parser to support.  Great, Kurt! Another one that has come up before is exploding dice (e.g. 3d6! and 3d6!!). Again, could be solved with loops and trickery but innate support would lessen card complexity and make tooltips easier :) Halflings in 5e and Great Weapon Fighting Style give you a single reroll (format XdYro<Z) that would be useful.
timmaugh said: All of that said, the manner by which SelectManager (and the other meta scripts) shin-kicks its way to the front of the message queue to be able to fiddle in the message before the other scripts see it works with the way *most* other scripts are built. I'll look at CM to see if there could be a problem. Are there specific cases you can point to, @Colin, where forselected doesn't work? I'll have to get back to you once I've replicated the problem again.
I am having troubles using the abbreviated token assignment *S and *T. For example, below is a portion of spell slot report  from the Youtube video.  Anytime that I use the  -- #sourceToken ​ |@{selected|token_id} and *S replacement (or the target equivalent) I get an undefined or no target error. Am I missing a needed script or is there some other issue? !scriptcards {{ -- #title ​ |Spell Slot Report -- #sourceToken ​ |@{selected|token_id} -- #leftsub ​ |@{selected|character_name} -- #emotestate ​ |hidden --?[*S:lvl1_slots_total] -eq 0|Done --=SlotsLeft|[*S:lvl1_slots_total] - [*S:lvl1_slots_expended] --+Level 1|[$SlotsLeft.Total] of [*S:lvl1_slots_total] slots remaining }} TIA
Thanks David M. for the [Brutal] solution! Great to hear Kurt J. that it will become possible to do it straight from the roll parser!
1617276174

Edited 1617277248
David M.
Pro
API Scripter
Michael, it looks like there is some kind of strange non-visible character immediately preceding the vertical bars in your --# card parameters. When I copied your code, I noticed that the title was not being read properly and the sourceToken graphic was not displayed. Starting on the beginning of those lines, if you right arrow over each character, you'll notice an extra character where the cursor appears to pause for one of the arrow presses. Anyway, when I deleted those extra characters your card started working. Due to that weird character, your sourceToken was not being assigned, so *S was undefined. While the following looks the same to our eyes, the weird characters have been removed and should work: !scriptcards {{ --#title|Spell Slot Report --#sourceToken|@{selected|token_id} --#leftsub|@{selected|character_name} --#emotestate|hidden --?[*S:lvl1_slots_total] -eq 0|Done --=SlotsLeft|[*S:lvl1_slots_total] - [*S:lvl1_slots_expended] --+Level 1|[$SlotsLeft.Total] of [*S:lvl1_slots_total] slots remaining }}
1617278633
Kurt J.
Pro
API Scripter
Just a quick update that I've got exploding dice (XdY!, XdY!>Z and XdY!<Z) and reroll-once (XdYro<Z and XdYro>Z) in and working, so they will be coming in the next release as well. I did work out turn tracker support, so it will also be possible to manipulate the turn tracker in the next version.
@David M.  Thanks once again, David.  Well, I'll be the fraternal relative of the father of a primate.  You are correct but I sure as #$%@ don't know where that came from?  I have used both Notepad and Word for the macro and the same issue occurs.  I know Word often injects white space code but thought Notepad did not.  Some other cause?
1617279929
David M.
Pro
API Scripter
No idea, Michael. I usually edit everything directly in a macro window (expanded to very large size so I can just barely see the Test Macro button). But, I just tested editing then copying from Notepad and it seemed to work fine for me. A mystery! Kurt: great work, looking forward to the update!
1617280070

Edited 1617281733
Cool, Kurt! I appreciate the hard work. Is it possible for a scriptcard to call another scriptcard as a subroutine?  For example, it would be much more efficient to have each spell scriptcard that requires deduction of a spell slot to call another scriptcard slot usage subroutine and then return to the spell scriptcard rather than incorporate the spell slot deduction in every spell scriptcard. Also, I noticed vfx incorporated into the scriptcards but is audio?
1617293908
Richard M.
Pro
Sheet Author
Kurt J. said: I did work out turn tracker support, so it will also be possible to manipulate the turn tracker in the next version. Nice work, that's amazing.
1617294792

Edited 1617298080
Kurt J.
Pro
API Scripter
ScriptCards version 1.1.2 Now Availble The development GIST now contains the latest updates for ScriptCards. There are a number of changes time time around, and I'll update the Wiki as I get the time to do so (likely over the weekend). As always, bug reports and feedback before I prep this for a push to OneClick are appreciated. Now on with the goodness: New Dice Roll Syntax : XdYr<Z and XdYr>Z. This type of dice syntax will reroll values depending on the result. For example, 5d6r<2 will reroll 1s and 2s on 5d6. 5d6r>5 will reroll 6s on the roll. Note that Z is inclusive (ie, z=2 means reroll 1s and 2s). New Dice Roll Syntax : XdY! or XdY!>Z or XdY!<Z for exploding dice. With the standard syntax (XdY!), any max rolls on the die will be rerolled and added to the total, potentially triggering additional rerolls. With the exteneded syntax (XdY!>Z or XdY!<Z) results >= or <= Z will be rerolled and added. Note that Z is inclusive. New Dice Roll Syntax : XdYro<Z or XdYro>Z allows for reroll-once mechanics. For example, 1d20ro<1 will roll a d20. If the result is a 1, the d20 will be rolled again, and the second result will be kept. The value of Z is inclusive in the greater than/less than check.  Turn Tracker Support   There are new function (--~) statements available for manipulating the turn tracker. These are: --~|turnorder;clear     clears the turn tracker --~|turnorder;addtoken;tokenid;trackervalue     adds token "tokenid" to the turn tracker with a value of "trackervalue" (but see the next entry) --~|turnorer;replacetoken;tokenid;trackervalue     replaces the tracker entry for token "tokenid" to the turn tracker with a value of "trackervalue". Adds the token if it isn't in the tracker already. --~|turnorder;removetoken;tokenid     removes (all) entries for token "tokenid" from the turn tracker --~|turnorder;addcustom;textlabel;trackervalue     adds a new row to the turn tracker named "textlabel" with a value of "trackervalue". Will not be associated with a token. Array Support ScriptCards now supports creation and manipulation of arrays. Things to keep in mind about arrays: Arrays are a lists of strings. Items in an array cannot contain the semi-colon (;) character, as that is used to separate parameters in the function code that deals with arrays. Arrays are accessed via the --~ script command. In some cases, the value of the tag (variable name) for array commands is not used, and can be a dummy value or simply omitted. I have omitted them in the statements below. All commands that DO return a value return string values, even if the content is numeric. If a command returns a value and there is some sort of reason that it isn't an array value, you will get "ArrayError" in the return value. This can happen if you reach the end of an array while stepping through it, for example, so checking for "ArrayError" can serve as the end condition for a loop. Each array keeps track of its current index, allowing you to step forward and backwards through arrays. Any number of arrays can be defined. Unlike string variables and roll variables, arrays cannot be persisted between scripts. The following commands are available for working with arrays: --~|array;define;arrayname;val1;val2;val3;val4     Defines an array called "arrayname" and adds four values to it. Sets the array index to 0. --~|array;add;arrayname;val5;val6;val7     Adds additional elements to an already defined "arrayname" array. --~|array;remove;arrayname;val3;val4     Removes "val3" and "val4" from the arrayname array. Resets the array index to 0. --~|array;replace;arrayname;currentval;newval     Replaces "currentval" in arrayname with "newval". All occurrences will be replaced. --~myindex|array;getindex;arrayname     Retrieves the current index for arrayname and stores it in myindex (string variable) --~|array;setindex;arrayname;newindex     If newindex is a valid index for arrayname, the index will be set to that value. Otherwise nothing will  be changed (for example, setting the index of an array of 5 items to 100 won't modify anything). --~myvalue|array;getcurrent;arrayname     Gets the value of the current index item in arrayname and returns it to myvalue (string variable). --~myvalue|array;getnext:arrayname     Increases the index by 1 and returns the new current item. If the next item in the array doesn't exist, myvalue (string variable) will be set to "ArrayError" --~myvalue|array;getprevious;arrayname     Decreases the index by 1 and returns the new current item. If the previous item in the array doesn't exist, myvalue (string variable) will be set to "ArrayError" --~myvalue|array;getfirst;arrayname     Sets the index to 0 and returns the new current item to myvalue (string variable). --~myvalue|array;getlast;arrayname     Sets the index to the last item in the array and returns the new current item to myvalue (string variable). --~|array;removeat;arrayname;index     removes the item at index "index" from "arrayname" --~itemindex|array;indexof;arrayname;searchvalue     Sets "itemindex" (string variable) to the index in the array for the first item that matches "searchvalue" --~length|array;getlength;arrayname     Sets "length" (string variable) to the number of items in the array Finally, I'm working on integrating some object-related commands into the Array support. The first of these is: --~|array;pagetokens;arrayname;@{selected|token_id}     The last parameter is any token ID on the page you are interested in. It will be used to get all graphics objects on the page and fill the array with their IDs. Samples Here are a couple of examples for working with arrays. This one creates a simple array, adds an item to it, iterates over the array, replaces one of the items, and then re-iterates over the array in reverse order. !script {{  --~dummy|array;define;myarray;Apple;Bananna;Pear;Pumpkin  --~dummy|array;add;myarray;Onion  --~testvar|array;getfirst;myarray  --:loop|  --+Value|[&testvar]  --~testvar|array;getnext;myarray  --?[&testvar] -ne ArrayError|loop  --+Loop1|Is Done!  --~dummy|array;replace;myarray;Apple;Potato  --~testvar|array;getlast;myarray  --:loop2|  --+Value|[&testvar]  --~testvar|array;getprevious;myarray  --?[&testvar] -ne ArrayError|loop2  --+Done|All done! }} Next, we get all of the tokens on the page for the selected token and display their names: !script {{  --~dummy|array;pagetokens;myarray;@{selected|token_id}  --~count|array;getcount;myarray  --+Total:|There are [&count] graphical objects on the page  --~testvar|array;getfirst;myarray  --:loop|  --+Value|[*[&testvar]:character_name]  --~testvar|array;getnext;myarray  --?[&testvar] -ne ArrayError|loop  --+Loop1|Is Done! }} I'll post the Fireball macro I used above a when I get the chance to clean it up a bit.
1617295376
David M.
Pro
API Scripter
Hey Kurt, with your new additions what are your thoughts on adding blind roll option(s) for whisper output. The player rolls something but doesn't see the results as they are whispered to the GM. Player receives some kind of whispered notification that a roll was sent. i.e. from the "broll" scriptlet: on("chat:message", function(msg) { var cmdName = "!broll "; var msgTxt = msg.content; var msgWho = msg.who; var msgArgs = msgTxt.slice(cmdName.length).split(/\s+--/); if(msg.type == "api" && msgTxt.indexOf(cmdName) !== -1) { sendChat(msgWho, `/w gm [[${msgArgs[0]}]]${msgArgs.length>1?` ${msgArgs[1]}`:''}`); sendChat(msgWho, `/w "${msgWho}" secret roll sent to GM ( ${msgArgs[0]} )${msgArgs.length>1?` [${msgArgs[1]}]`:''}`); }; }); Now if you want to get really crazy: From your fireball token array example, it would be awesome to have the player be able to see the damage rolls while only the GM is sent the saves. Currently the player will see token/character names (potential spoilers) and could mouse over the save results to know the save bonus. This variation might be asking a lot vs a relatively simple blind roll card parameter, though, as it would probably require a different type of --+ output command for those lines that are for GM eyes only, like --++ or something? I dunno, just thinking out loud. It may not play nicely with your current data structure. I imagine it would have to build two separate rowData arrays of output and copy the rest of the card structure/formatting except for the output type (public/whisper/blind). Just curious on your thoughts.
1617295425
David M.
Pro
API Scripter
v1.1.2 - Woohoo!
1617295603
Kurt J.
Pro
API Scripter
David M. said: Hey Kurt, with your new additions what are your thoughts on adding blind roll option(s) for whisper output. The player rolls something but doesn't see the results as they are whispered to the GM. Player receives some kind of whispered notification that a roll was sent. i.e. from the "broll" scriptlet: on("chat:message", function(msg) { var cmdName = "!broll "; var msgTxt = msg.content; var msgWho = msg.who; var msgArgs = msgTxt.slice(cmdName.length).split(/\s+--/); if(msg.type == "api" && msgTxt.indexOf(cmdName) !== -1) { sendChat(msgWho, `/w gm [[${msgArgs[0]}]]${msgArgs.length>1?` ${msgArgs[1]}`:''}`); sendChat(msgWho, `/w "${msgWho}" secret roll sent to GM ( ${msgArgs[0]} )${msgArgs.length>1?` [${msgArgs[1]}]`:''}`); }; }); Now if you want to get really crazy: From your fireball token array example, it would be awesome to have the player be able to see the damage rolls while only the GM is sent the saves. Currently the player will see token/character names (potential spoilers) and could mouse over the save results to know the save bonus. This variation might be asking a lot vs a relatively simple blind roll card parameter, though, as it would probably require a different type of --+ output command for those lines that are for GM eyes only, like --++ or something? I dunno, just thinking out loud. It may not play nicely with your current data structure. I imagine it would have to build two separate rowData arrays of output and copy the rest of the card structure/formatting except for the output type (public/whisper/blind). Just curious on your thoughts. I'll give it some thought... it might not be too difficult to build parallel cards with some output lines only show on the "GM" version of the card. Let me ponder. One caveat about spoilers, though, is that if a player really wants to spoil something for themselves, they can always "/w self @{target|wisdom_save_bonus}" or something along those lines, so it won't stop the dedicated from gleaning too much information, but I like the idea of the dual card output.
1617295998
David M.
Pro
API Scripter
Yeah, I hear you with the spoilers. It's like a cheap lock - it only keeps the honest people out :)
1617296434

Edited 1617296863
David M.
Pro
API Scripter
Minor typo in your examples? Looks like the 3 "-ne EndOfArray" lines should be "-ne ArrayError"? I was getting infinite loop errors otherwise. EDIT - hmm just saw the bit in the documentation about EndOfArray for getnext and getprevious. Possible bug or is it a card syntax issue?
1617298020

Edited 1617298038
Kurt J.
Pro
API Scripter
David M. said: Minor typo in your examples? Looks like the 3 "-ne EndOfArray" lines should be "-ne ArrayError"? I was getting infinite loop errors otherwise. EDIT - hmm just saw the bit in the documentation about EndOfArray for getnext and getprevious. Possible bug or is it a card syntax issue? Oops... I changed "EndOfArray" to "ArrayError"  so there is only ever one thing to check for, but didn't update the examples. I changed them above.
Great work! Would love to see a couple of examples of a multiattack/AoE ;) Also, and this is just a thought, but since this thread is so popular wouldn't it be better organized if it had it's own (sub)forum?
Worry to keep bothering you all.&nbsp; Am trying to work out a scriptcard for Cure Wounds.&nbsp; Not elegant but am just trying to learn the ropes.&nbsp; Everything works except the section branching to handle hp restored &gt; or &lt; max hp.&nbsp; Also a line error.&nbsp; I have gone over this for hours and cannot figure out where I have gone wrong.&nbsp; Would appreciate any help. !scriptcards {{&nbsp; &nbsp; --#title|Cure Wounds &nbsp; --#sourceToken|@{selected|token_id} &nbsp; --#targetToken|@{target|token_id} &nbsp; --#emoteText|[*S:character_name] Casts Cure Wounds on [*T:character_name] &nbsp; --#titleCardBackground|#006400 &nbsp; --#evenRowBackground|#58D68D &nbsp; --#evenRowFontColor|#FF0000 &nbsp; --#oddRowBackground|#440000 &nbsp; --#oddRowFontColor|#F4D03F &nbsp; --&gt;GetAndCheckSlotInformation| &nbsp; --&gt;AbilityAssign| &nbsp; --:CureWounds| &nbsp; --=HPRecovered|[$SlotLevel]d8 + [$[&amp;Attribute]] &nbsp; --=Wounds|[*T:hp^] - [*T:hp] &nbsp; --+|[*T:character_name] has [*T:hp] out of [*T:hp^] HP &nbsp; --?[$HPRecovered] &lt;= [$Wounds]|StillWounded &nbsp; --@setattr|_charid [*T:character_id] _hp|hp^ _silent &nbsp; --+[*T:character_name] received [$HPRecovered] HP and is now at full health! &nbsp; --&gt;DeductSpellSlot| &nbsp; --X| &nbsp; --:StillWounded| &nbsp; --+|No &nbsp; --@setattr|_charid [*S:character_id] _hp|+[$HPRecovered] _silent &nbsp; --+[*T:character_name] recovered [$HPRecovered] of [$Wounds] lost HP! &nbsp; --&gt;DeductSpellSlot| &nbsp; --X| &nbsp; --:GetAndCheckSlotInformation| &nbsp; --=SlotLevel|?{Spell Slot Level Used?|1|2|3|4|5|6|7|8|9} &nbsp; --=SlotsTotal|[*S:lvl[$SlotLevel]_slots_total] &nbsp; --=SlotsExpended|[*S:lvl[$SlotLevel]_slots_expended] &nbsp; --?[$SlotsExpended.Total] -ge [$SlotsTotal.Total]|NoSlotsLeft &nbsp; --&lt;| &nbsp; --:DeductSpellSlot| &nbsp; --=SlotsExpended|[$SlotsExpended] + 1 &nbsp; --@setattr|_charid [*S:character_id] _lvl[$SlotLevel]_slots_expended|[$SlotsExpended] _silent &nbsp; --=SlotsRemaining|[$SlotsTotal] - [$SlotsExpended] &nbsp; --+|Level [$SlotLevel] Slots Left: [$SlotsRemaining]&nbsp; &nbsp; --X|Full Stop &nbsp; --:NoSlotsLeft| &nbsp; --+|[*S:character_name] has no level [$SlotLevel.Total] spell slots available. &nbsp; --X|NoSlotsLeftStop &nbsp; --:AbilityAssign| &nbsp; --&amp;Attribute|?{Spellcasting Ability?|Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma} &nbsp; --=Strength|@{selected|strength_mod} &nbsp; --=Dexterity|@{selected|dexterity_mod} &nbsp; --=Constitution|@{selected|constitution_mod} &nbsp; --=Intelligence|@{selected|intelligence_mod} &nbsp; --=Wisdom|@{selected|wisdom_mod} &nbsp; --=Charisma|@{selected|charisma_mod} &nbsp; --&lt;| }} rror - No Line Tag Specified: Error - No Line Content Specified Silk Van Halen Casts Cure Wounds on Zephyr Amanodel Cure Wounds Zephyr Amanodel has 10 out of 45 HP Level&nbsp;<span class="userscript-showtip userscript-tipsy" title="Roll: 1 Result: 1 " style="box-sizing: content-box; min-width: 1.75em; font-family: undefined; text-align: center; display: inline-block; font-weight: bold; height: 1em; margin-top: -1px; margin-bottom: 1px; padding: 0px 2px; border: 1px solid rgb(135, 133, 10); border-radius: 3px; background-color: rgb(255, 254, 162); color: rgb(0, 0, 0);">1 &nbsp;Slots Left:&nbsp;<span class="userscript-showtip userscript-tipsy" title="Roll: 4 - 4 Result: 4 - 4 " style="box-sizing: content-box; min-width: 1.75em; font-family: undefined; text-align: center; display: inline-block; font-weight: bold; height: 1em; margin-top: -1px; margin-bottom: 1px; padding: 0px 2px; border: 1px solid rgb(135, 133, 10); border-radius: 3px; background-color: rgb(255, 254, 162); color: rgb(0, 0, 0);">0
1617326532
Kurt J.
Pro
API Scripter
&nbsp; --?[$HPRecovered] &lt;= [$Wounds]|StillWounded &nbsp; --+[*T:character_name] received [$HPRecovered] HP and is now at full health! These two lines are the issue. ScriptCards doesn't support "&lt;=" as a comparison. You'll need to use PowerShell style operators. In this case, the comparison operator would be "-le". In the output line, there is no vertical bar, which is why you are getting the no tag error.
I'm have a little trouble trying to figure out how to get the Button feature to work with activating a macro from a character sheet ability section. I know how to make a Button to work with Macros (an example) --+|[button]Light/Vision::!&amp;#13;#Light/Vision[/button] One of my players is playing a battle master and I am trying to add the maneuvers he has as buttons in his attack card. I'm trying to keep his macros on his character sheet in the ability section.
1617365622

Edited 1617369897
@Kurt J.&nbsp; Thank you for the answer.&nbsp; With the changes you recommended it now works without error but I notice it will not actually increase hp on the target.&nbsp; I think the issue is in the two lines: &nbsp; --@setattr|_charid [*T:character_id] _hp|hp^ _silent &nbsp; --@setattr|_charid [*T:character_id] _hp|+[$HPRecovered] _silent I tried another approach: &nbsp; --@token-mod| _ignore|selected _ids [*T:token_id] _set bar1_value|hp_max&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (also hp^) &nbsp; --@token-mod| _ignore|selected _ids [*T:token_id] _set bar1_value|+[$HPRecovered]&nbsp; (also +HPRecovered) without success. TIA
@Snow.&nbsp; I don't know if it helps and it might not be on point but in using powercards I would not have to use the&nbsp; !&amp;#13;# &nbsp;&nbsp;prefix by creating a character sheet (e.g. "Macros") with the powercard "LightVision" in the Macros character attributes.&nbsp; The call then changes to (~Macros|LightVision).&nbsp; I made this change at the suggestion of another Pro user when I found that editing a macro with the prefix required me to reenter the prefix every time I opened the macro.
@Michael C. Thanks for suggesting that. I already to have a Character sheet named Macro &amp; Macros with my old powercards macros using the (~Macros|LightVision) trick for transferring my macros from one game to another. I am liking scriptcards now and trying to convert my powercards macros over to scriptcard.&nbsp; I have tried --+|[button]Maneuvers::(~Rossweisse Lochmere|Maneuver)[/button] I get small button you can't click
Snow said: @Michael C. Thanks for suggesting that. I already to have a Character sheet named Macro &amp; Macros with my old powercards macros using the (~Macros|LightVision) trick for transferring my macros from one game to another. I am liking scriptcards now and trying to convert my powercards macros over to scriptcard.&nbsp; I have tried --+|[button]Maneuvers::(~Rossweisse Lochmere|Maneuver)[/button] I get small button you can't click Snow, omit the parentheses in your button command and it should work.
@Jay R. Thank you that worked. I thought I had tried that but I guess I didn't.