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

So I'm just learning about ScriptCards after having been working in PowerCards for the past month or so and I'm running into an issue that I have with both of them, but I see in this thread that there's something odd going on with SpawnDefaultToken when it comes to both PowerCards and ScriptCards and I was wondering if any of you could shed some light onto this problem. The issue, plainly, is that while I can run SpawnDefaultToken with no issue in my games, the moment I put it into a Power or Script Card, it fails to run. No error message either, simply nothing happens. The rest of the Card executes beautifully but no token appears Here's what I'm writing and hopefully you'll see what I can't (this is for a Fathomless Warlock): --:Spawn|     --? @{selected|class_resource} -lt 1|NotEnoughCharges     --+Ability Used|Spawn Tentacle     --+Effect| As a Bonus Action, you create a 10-ft.-long Tentacle at a point you can see.     --+Range|60 ft.     --+Duration|1 minute      --@spawn _name|Purple Tentacle _offset|0,-1 _qty|1 _fx|burst-frost     --@modattr| _charid [*S:character_id] _class_resource|-1 _silent     --#emoteText| @{selected|character_name} Summons a Tentacle from the Deep! --<| This is nearly identical in syntax to what I was attempting with PowerCards before, but again to no avail. Hopefully it's just me being blind. Thanks!
1618027930

Edited 1618028202
I spent last weekend getting my version to work.  The @spawn script requires you have an actual version of the token image in your library, not just a link to the marketplace version which I suspect is your problem.  You might also look at using the SelectManager ( @forselected)  script as it does some behind the scenes magic with selected tokens inside of macros.  I downloaded all my AoE graphics and templates and all my spell assets to my PC, then, upload them up (placing them in their own special folder to stay organized) before it would work.  I also used a roll table to store my images in to minimize the number of character sheets I'd have to create:  Here is my code: !script {{ --#whisper|gm,self --#title|Spawn Spell Token --=spell|?{Spell?|Burning Hands,1|Call Lightning,2|Darkness,3|Dragon's Breath,4|Faerie Fire,5|Fear,6|Fireball,7|Flame Sphere,8|Grasping Vine,9|Healing Spirit,10|Hunger of Hadar,11|Lightning Bolt,12|Mage Hand,13|Shatter,14|Silence,15|Sleep,16|Slow,17|Spiritual Weapon Axe,20|Spiritual Weapon Hammer,21|Spiritual Weapon Mace,22|Spiritual Weapon Sword,23|Summon Demon Circle,18|Web,19} --C[$spell]|1:>BH|2:>CL|3:>DRK|4:>DBF|5:>FF|6:>FR|7:>FB|8:>FS|9:>GV|10:>HS|11:>HOH|12:>LB|13:>MH|14:>SHTR|15:>SIL|16:>SLP|17:>SLW|18:>SDC|19:>WEB|20:>SWA|21:>SWH|22:>SWM|23:>SWS| --X| Exit --:BH| 15 foot cone --#leftsub|Burning Hands (15' Cone) --@forselected+|Spawn _name|Spell-Object _offset|2,0 _side|[$spell] _expand|40,20 _size|4,4 _rotation|270 _order|ToBack --<| --:CL| 120 foot radius sphere (120' Radius Sphere) --#leftsub|Call Lightning --@forselected+|Spawn _name|Spell-Object _offset|2,0 _side|[$spell] _expand|40,20 _size|24,24 _order|ToBack --<| --:DRK| Darkness --#leftsub|Darkness (15' Sphere) --@forselected+|Spawn _name|Spell-Object _offset|3.5,-0.5 _side|[$spell] _expand|40,20 _size|8,8 _order|ToBack --<| --:DBF| Dragon's Breath - Fire --#leftsub|Dragon's Breath-Fire (60' Cone) --@forselected+|Spawn _name|Spell-Object _offset|6,0 _side|[$spell] _expand|20,20 _size|16,16 _rotation|270 _order|ToBack --<| --:FF| Fairie Fire --#leftsub|Fairie Fire (20' Cube) --@forselected+|Spawn _name|Spell-Object _offset|3,-1.5 _side|[$spell] _expand|40,20 _size|4,4 _order|ToBack --<| --:FR| Fear --#leftsub|Fear (30' Cone) --@forselected+|Spawn _name|Spell-Object _offset|3.5,0 _side|[$spell] _expand|40,20 _size|7,7 _rotation|270 _order|ToBack --<| --:FB| Fireball --#leftsub|Fireball (20' Sphere) --@forselected+|Spawn _name|Spell-Object _offset|5.5,-0.5 _side|[$spell] _expand|40,20 _size|9.5,9.5 _order|ToBack --<| --:HOH| Hunger of Hadar --#leftsub|Hunger of Hadar (20' Sphere) --@forselected+|Spawn _name|Spell-Object _offset|5.5,-0.5 _side|[$spell] _expand|40,20 _size|10,10 _order|ToBack --<| --:LB| Lightning Bolt --#leftsub|Lightning Bolt (100' Line) --@forselected+|Spawn _name|Spell-Object _offset|10.5,0 _side|[$spell] _expand|40,20 _size|1,21 _rotation|90 _order|ToBack --<| --:SHTR| Shatter --#leftsub|Shatter (10' Sphere) --@forselected+|Spawn _name|Spell-Object _offset|3,-0.5 _side|[$spell] _expand|40,20 _size|6,6 _order|ToBack --<| --:SIL| Silence --#leftsub|Silence (20' Sphere) --@forselected+|Spawn _name|Spell-Object _offset|5.5,-0.5 _side|[$spell] _expand|40,20 _size|8,8 _order|ToBack --<| --:SLP| Sleep --#leftsub|Sleep (20' Sphere) --@forselected+|Spawn _name|Spell-Object _offset|5.5,-0.5 _side|[$spell] _expand|40,20 _size|10,10 _order|ToBack --<| --:SLW| Slow --#leftsub|Slow (40' Sphere) --@forselected+|Spawn _name|Spell-Object _offset|6,-0.5 _side|[$spell] _expand|80,40 _size|10,10 _order|ToBack --<| --:WEB| --#leftsub|Web (20' Cube) --@forselected+|Spawn _name|Spell-Object _offset|3.5,-.5 _side|[$spell] _expand|40,20 _size|5,5 _order|ToBack --<| --:FS| --#leftsub|Flame Sphere --@forselected+|Spawn _name|Spell-Object _offset|1,0 _side|[$spell] _expand|40,20 _size|1,1 --<| --:GV| --#leftsub|Grasping Vine --@forselected+|Spawn _name|Spell-Object _offset|1,0 _side|[$spell] _expand|40,20 _size|1,1 _ rotation|180 --<| --:HS| --#leftsub|Healing Spirit --@forselected+|Spawn _name|Spell-Object _offset|1,0 _side|[$spell] _expand|40,20 _size|1,1 _rotation|270 --<| --:MH| --#leftsub|Mage Hand --@forselected+|Spawn _name|Spell-Object _offset|1,0 _side|[$spell] _expand|40,20 _size|1,1 --<| --:SWA| --#leftsub|Spiritual Weapon - Axe --@forselected+|Spawn _name|Spell-Object _offset|1,0 _side|[$spell] _expand|40,20 _size|1,1 --<| --:SWH| --#leftsub|Spiritual Weapon - Hammer --@forselected+|Spawn _name|Spell-Object _offset|1,0 _side|[$spell] _expand|40,20 _size|1,1 --<| --:SWM| --#leftsub|Spiritual Weapon - Mace --@forselected+|Spawn _name|Spell-Object _offset|1,0 _side|[$spell] _expand|40,20 _size|1,1 --<| --:SWS| --#leftsub|Spiritual Weapon Hammer - Sword --@forselected+|Spawn _name|Spell-Object _offset|1,0 _side|[$spell] _expand|40,20 _size|1,1 --<| --:SDC| --#leftsub|Summon Demon Spirit --@forselected+|Spawn _name|Spell-Object _offset|2,0 _side|[$spell] _expand|40,20 _size|3,3 --<| }}
Fortunately, I am aware of the Marketplace limitation and this is actually an uploaded token. I had a thought that maybe it was that my Character, the Purple Tentacle, has a space in the name, so I tried renaming it to Purple-Tentacle but to no avail. I see this 'forselected+' part of your calls to SpawnDefaultToken, what exactly is that? I thought for an api call you only needed the @ and to change all --'s to _'s?
1618029537

Edited 1618029771
David M.
Pro
API Scripter
Hi non, to get Spawn to work from a scriptcard/powercard, the easiest method is to also use the "meta"-script called SelectManager  (like Will shows in his example). This allows the selected token to be "remembered" by the api for the subsequent api call to Spawn. Otherwise, the api "forgets" which token(s) were selected by the time Spawn is called from your scriptcard. The !forselected syntax is used by SelectManager to iterate through the selected tokens for whatever api script follows. See the description in the Selectmanager thread linked above for details.  @Will M: A rollable table token is definitely the way to go to store multiple spell AoEs. Nice work!
That did it! The whole 'forgetting' thing certainly explains why I couldn't figure any of this out. Thanks so much!
1618030184
David M.
Pro
API Scripter
Great! Yeah, it's just one of the many quirks of the api to remember :)
That's awesome!
@Kurt - Okay, so linear left-to-right calculations and no operators needed (but recommended) in some circumstances, I can see that. My mind balked at that for a moment but I can see now that parenthetical ordering isn't really needed in RPG as nothing rises much beyond addition, multiplication, subtraction and division.  I tried to think of a situation where parenthetical ordering would be required or necessary but can't.  Thanks.
Kurt J. said: Woombak said: Kurt J. said: 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! }} Hi Kurt, How would you adapt your scrit above to only feed your array with selected tokens and not all the tokens present on a page ? Thx in advance (i'm lazy, I could have tried to figure out but i had a few beers at lunch and my brain is screwed-up)! Regards, As it stands, it wouldn't be straightforward... you would need to use the getselected string function and then loop through them and add them to the array. So...... ScriptCards v1.1.14 Now Available Up on the Development GIST is a small update that makes the following changes: New array function : selectedtokens:  --~count|array;selectedtokens;myarrayname will return the number of selected tokens as the string variable "count", and create an array called "myarrayname" with the token IDs in it. Updated the behavior of the "pagetokens" array function to also return the number of tokens it found to the assigned string variable. Potentially important change: I found a bug in that arraysand array index values were not being properly cleared between macro executions, meaning that arrays created in one script could potentially be showing up in later scripts. Which could cause issues (like if you were expecting an array to be empty and looking at the length and finding items in it). Thanks man you're the best !
1618070593

Edited 1618070653
David M.
Pro
API Scripter
FYI, a separate thread asked for an example of how to store and retrieve variables from the State object using the stateitem functions. Linking the example here in case it is useful to any of you. It allows a single roll variable and/or a single string variable to be stored in the persistent State object, allowing it to be retrieved by a separate scriptcard at a later time, even in later game sessions. Basically creates a persistent global variable. Thinking about it a bit more: What would be cool is to be able to store a third variable type (array) , which would effectively allow multiple string and/or roll variables to be stored without bloating the State object. Subsequent parsing could later turned some of these array elements into roll variables if the string element was a number or in a nDx format. Hm, I suppose this is already possible by using the split function on a string variable stateitem, although you couldn't use any of the shiny new array commands. Possible application : You could store an array of tokens that were affected by "something" that caused an ongoing effect (e.g. acid damage), and have a subsequent scriptcard continue the effect for only those tokens (even if they moved out of the initial AoE), removing token array elements as they made their saving throws or some other condition (like one more turn for Melf's Acid Arrow). Or the effect could change if subsequent saves were made/failed, like a slow->petrification save tree, or an ongoing damage escalation/de-escalation (e.g. 1d4->1d6->1d8->1d10). Just thinking out loud :)
1618071285

Edited 1618072381
I like the idea of an array.  I'm running "Out of the Abyss" which has a ton of tracking requirements (Food, Water, Madness/player, Drow Pursuit, ...).  I guess I could store something like a madness level for each party member and have a set of macros that lets me inc/dec the levels over time and this would persist between sessions.  I've not used this functionality yet, was just starting to think about how to track and easily report in games instead of in excel.  Question: Do variables stored persist after a sandbox restart? If not, it may be better for me to create a custom handout and use the notes area to persist this kind of information between sessions, almost like reading/writing to a system registry for an operating system like MS-Windows.  Unless it already exists somewhere, my next project might be to develop a set of scripts or a single API to Add/Del/Read/Write keys and their values to a handout for persistent storage.  Something that could be used inside of ScriptCards and piggybacks off of SuperNotes.  
1618072311

Edited 1618072568
David M.
Pro
API Scripter
Will, it would be easier with a stored array, but you could probably do this with a string variable and split approach like I mentioned above. Your stateitem string variable could be something like a series of comma-delimited tokenID, MadnessLevel pairs. Or use charName, whatever is easier. Read it from State, use the split function and turn every other element into a roll variable, then modify the roll variable (possibly for only the selected token), and finally re-assemble the stateitem string variable to store with the modified roll value(s) using [$roll.text].  Multiple things could be tracked in a single stateitem variable by increasing the number of elements between "id's" and parsing appropriately. EDIT - yes, items stored in State do persist between sessions.
1618073034

Edited 1618075148
I was reading the description of the State Object , as I'd never used it before and saw this warning in it's description and use: Warning:  While functions will appear to work when stored in the state initially, they will disappear the first time the  state  is restored from persistence, such as on a sandbox restart. Not sure what they mean by "functions" as it states in the example, only simple JSON objects like strings, numbers, arrays and objects can be stored.  I'll have to test this out and get back with you all. EDIT - David, you are correct, it persisted even after I bounced the sandbox.  And now I see how handy reading/writing arrays would be! EDIT 2 - I also wanted to know how large a string could be and stopped testing after it successfully wrote and returned over 100,000 characters, more than enough for my needs.  
1618088032
Kurt J.
Pro
API Scripter
You can kind of do this by using the stringify array command to turn the array into a semi-colon separated string, and restore it using array define and passing that the restored string variable. That said, adding the array type to the storage commands would be easy to do (I'd probably internally stringiy it and save it that way!), so I'll look at that for the next update. @Will M. As far as what they mean by functions and state, in Javascript functions are just objects like anything else, and can be stored in variables. The state storage is just a bunch of javascript objects that (I assume) get converted to JSON data for storage between sessions. That is likely what breaks functions that get restored from state. I can't think of a reason you would want to store a function in state anyway, but I'm sure there is a use case that just hasn't occurred to me.
1618088744
David M.
Pro
API Scripter
Dang, I swear I looked for a stringify function but must have missed it in the array description post :)  
@Kurt J. - That's what I figured, but wasn't sure if the documentation was also referring to all state variable types.  I see no use case for storing an object with functions in a state variable at this time.
1618098449
Kurt J.
Pro
API Scripter
David M. said: Dang, I swear I looked for a stringify function but must have missed it in the array description post :)   It was added in 1.1.13 :)
I know this might be a stupid question, but, i thought, is there a way to change all my Powercard script to Scriptcards, withut having to rewrite all of them?  Or there is a fast way ?
1618142778
Kurt J.
Pro
API Scripter
andrea d. said: I know this might be a stupid question, but, i thought, is there a way to change all my Powercard script to Scriptcards, withut having to rewrite all of them?  Or there is a fast way ? The implementations are too different for an automatic conversion process, but ScriptCards and PowerCards can run side-by-side, so you would only really need to convert scripts that you wanted to update to take advantage of features in ScriptCards that aren't possible with PowerCards. 
1618144986

Edited 1618147999
Kurt J.
Pro
API Scripter
ScriptCards Version 1.1.15 is now available Up on the Development GIST . This version adds: It is now possible to persist a single array between cards/sessions/api restarts with the "stateitem" function read and write subfunctions. Simply specify "array" as the data type. The current index in the array is also preserved. Also: version 1.1.16 is underway, and will include some bug fixes (currently, the --i command doesn't account for arrays. That is fixed in 1.1.16) and a new statement type/feature :)
1618156086

Edited 1618162958
I have been working on scriptcard calls to other macros and reviewed Mark C. and David M's discussion (in 9 in this forum), the API Call and Ability call wikis and the scriptcard wiki on inline formating of "buttons."  I noted David M. suggested: [Macro](!
#MacroName) and I tried:   --+[button]Divine Smite::!
#DivineSmite[/button] which worked fine for global macros.  Edit: Except it requires me to select the token a second time after the button is called. First, is there a way to use the "~" in place of the !
# as in powercards?  I have previously used: [command name](~Macros|macro-to-call) using a character sheet's attribute section to avoid the issues with using !
# but none of these worked:    --+[button]Divine Smite::(~MacrosPaladin|DivineSmite)[/button]   --+[button]Divine Smite::(~MacrosPaladin;#DivineSmite)[/button] Second, how would you call a non-global macro? I made several tries using !
# and most of them did post a scriptcard with a button in the chat but selecting the button would cause an error message, show no response or would open another tab in the browser.   Last, Is there a better way to do this? I tried a version of Mark C.'s suggestion:   --+Link|[Divine Smite](!
#DivineSmite)  which did not work for me as it put a scriptcard button out in chat but did not call the global macro when the button was selected. Suggestions? TIA
1618167771
Kurt J.
Pro
API Scripter
Michael C. said: I have been working on scriptcard calls to other macros and reviewed Mark C. and David M's discussion (in 9 in this forum), the API Call and Ability call wikis and the scriptcard wiki on inline formating of "buttons."  I noted David M. suggested: [Macro](!
#MacroName) and I tried:      --+[button]Divine Smite::!
#DivineSmite[/button] The issue here is that the line doesn't contain a vertical bar. The following will produce the button (added a bar right after the --+): --+|[button]Divine Smite::!
#DivineSmite[/button] That is actually an issue with several of the lines in your post above. They will likely work with that change. First, is there a way to use the "~" in place of the !
# as in powercards?  I have previously used: [command name](~Macros|macro-to-call) using a character sheet's attribute section to avoid the issues with using !
# but none of these worked:  Yes, this should work just as it did in PowerCards. ScriptCards [button]::[/button] syntax is really nothing but a wrapper around normal API buttons. It takes the text before the :: and puts it in square brackets and text after the :: and puts it in parenthesis  after that. I am adding a new formatting command in an upcoming release; [sheetbutton][/sheetbutton] that will help with this formatting by taking a label, a character id/token id/character name, and a sheet macro name on that character and creating a button for you.
1618170687
timmaugh
Pro
API Scripter
Kurt J. said: To make things weirder, I was playing around with a script I was testing for a "bag of tricks" that would check for unoccupied spaces in which to spawn the new tokens. Sometimes it works fine, and then sometimes I get the error above (which I tracked down to coming from SelectManager). I'm not using targeting at all, and about 40% of the time (just arrowing up and hitting enter again) I get the "no tokens selected" error, with it firing normally the other 60% of the time. Hey, Kurt, David pointed out to me that I had missed this part of your usage case -- that you don't use targeting at all. I don't want to pollute the thread with a bunch of SM stuff, so if you have the details around a minimum reproducible case you can PM me, that would be great. I'll dig into what might be going on.
Kurt, Have you considered a ScriptCards syntax checking/warning pre-processor capability when debug mode is turned on? It would create warnings in the console or directly to the chat window when: Missing | after --  (E.g.  "--:MySubroutine" , sould be "--:MySubroutine|"  or "--+Text to output" should be "--+Text| to output")     Warning would say something like "missing | on line xx"" Warning when same spelling but different case is used in variable and label names? (E.g. MyVar vs myvar or -->Loop|  --:LOOP) Warning when there is a label referenced via the -->Label|, --^Label|, or --? (conditional)|Label commands but there exists no Label to jump to No space between script command and {{.  (E.g. script{{ ) Other ?  I use SubLime for text editing, and have thought about developing an addon module for it to recognize your new language. I've made these mistakes so many times I've started using the following syntax rules to reduce my errors: Labels: All Uppercase Roll Variables: r+InitCase (E.g. rMyRollVar) String Variables: s+InitCase (E.g. sMyStringVar) Will
1618176430
Kurt J.
Pro
API Scripter
Will M. said: Kurt, Have you considered a ScriptCards syntax checking/warning pre-processor capability when debug mode is turned on? It would create warnings in the console or directly to the chat window when: Missing | after --  (E.g.  "--:MySubroutine" , sould be "--:MySubroutine|"  or "--+Text to output" should be "--+Text| to output")     Warning would say something like "missing | on line xx"" Warning when same spelling but different case is used in variable and label names? (E.g. MyVar vs myvar or -->Loop|  --:LOOP) Warning when there is a label referenced via the -->Label|, --^Label|, or --? (conditional)|Label commands but there exists no Label to jump to No space between script command and {{.  (E.g. script{{ ) Other ?  I use SubLime for text editing, and have thought about developing an addon module for it to recognize your new language. I've made these mistakes so many times I've started using the following syntax rules to reduce my errors: Labels: All Uppercase Roll Variables: r+InitCase (E.g. rMyRollVar) String Variables: s+InitCase (E.g. sMyStringVar) Will I will see what kinds of debugging I can add to the script. The missing | thing is easy... there is already an error message that gets ouptut, but it goes to the chat window and isn't very clear :) It says " rror - No Line Tag Specified: Error - No Line Content Specified" ( yes, with the "E" missing in Error :)) Adding something to look at variable and label names to see if there are any case-based collisions should be feasible as well, though it would probably be an end-of-card report that would say something like "Warning: Fred and fred defined as string variables", or "Warning: Fred defined as both a string and roll variable" Warning for labels that are jumped to by don't exist is super simple. I'll add that now. For no space after the !script command, I'll just have it accept the command if there isn't a space and {{ follows right after the trigger word. I just went to look at what SubLime is, and it looks practically identical to Visual Studio Code, which is what I'm using right now. I thought about writing an intellisense module for ScriptCards, but when I started looking into how to do that it seemed really complicated. 
You might check to see if the "Missing | " logic is working for Labels.  I had that issue recently, and don't recall seeing the warning.  
1618185080
Kurt J.
Pro
API Scripter
Will M. said: You might check to see if the "Missing | " logic is working for Labels.  I had that issue recently, and don't recall seeing the warning.   The error that was being sent to chat was actually a bug, so I've fixed that in my internal build :) Here is what I've got working so far as far as errors/warnings in the console log: If you redefine a label, you will get a warning ("ScriptCards Warning: redefined label Fred" for example) If you use define labels with the same name in different cases you will get a warning ("ScriptCards Warning: Similar labels Joe and joe") If you try to jump to a label (--^, -->, --?) that doesn't exist you will get an error ("ScriptCards Error: Label NotALabel is not defined on line 5") If you leave out a vertical bar, you will get an error ("ScriptCards Error: Line 13 is missing a | character. (+Missing a vertical bar!  )") All of these show up even outside of debug mode, since technically they are problems that should be fixed in the script code, and I found that having debug mode on caused me to have trouble finding some of the message because of the large volume of output in debug mode. I still need to contemplate how to handle the variable naming checks, so that is in the works. I'll probably release a new build either late tonight or some time tomorrow with the features above, the --i bug fixes for arrays, the new statement type (--*, which works just like --+ except that it adds lines to a separate card that is only sent to GMs), and the [sheetbutton] syntax.
This is great.  I bet we see a huge reduction of people asking about why their code doesn't work on this forum as a result.  The downside of righting a new language is you have to debug everyone's code ;).
1618206551
Senjak
Pro
Sheet Author
Hello! For various reasons I'm needing to adjust the turn tracker and I'm trying a very simple example to get started. !scriptcard {{ --#title|Setting Initiative --#sourceToken|@{selected|token_id} --#leftsub|@{selected|token_name} --=Init_Roll|?{Initiative?|10} --=Token|@{selected|token_id} --~|turnorder;addtoken;@{selected|token_id};?{Initiative?} --+Goes on:|[$Init_Roll] }} As you might be able to guess from my code, I was trying to assign the initiative and token id to a couple of variables and then call them.  I know I'm getting the results I want but it feels like brute force.  I tried a number of different ways to do the variable in the command line, but I must be missing something very basic, so help please! --~|turnorder;addtoken;@{selected|token_id};?{Initiative?} How do I correctly rewrite the above line to use Token and Init_Roll? Thanks for any assistance you can offer.
1618215324
Senjak
Pro
Sheet Author
In the spirit of sharing, here is a fairly simple example that I'm using in one of my 5e games. It isn't nearly as advanced as some of the examples, but it does show some parts that I had trouble with at first. !scriptcard {{ --#titlefontlineheight|1.5em --#lineheight|1.1em --#buttonbackground|#C9DAF8 --#titleCardBackground|#000000 --#buttontextcolor|#000000 --#buttonbordercolor|#000000 --#titlefontsize|24px --#subtitlefontsize|18px --#bodyfontsize|18px --#title|Available Actions --#sourceToken|@{selected|token_id} --#leftsub|@{selected|token_name} --#rightsub|@{Selected|class_display} --=Sneak_dmg|1d6 --+Sneak Attack Damage|[$Sneak_dmg] --+|[button]Select!::~selected|repeating_attack_$0_attack[/button] @{selected|repeating_attack_$0_atkname} --+|[button]Select!::~selected|repeating_attack_$1_attack[/button] @{selected|repeating_attack_$1_atkname} --+|[button]Select!::~selected|repeating_attack_$2_attack[/button] @{selected|repeating_attack_$2_atkname} --+|[button]Select!::~selected|repeating_attack_$3_attack[/button] @{selected|repeating_attack_$3_atkname} --+|[button]Select!::~selected|repeating_attack_$4_attack[/button] @{selected|repeating_attack_$4_atkname} --+|[button]Select!::~selected|repeating_attack_$5_attack[/button] @{selected|repeating_attack_$5_atkname} --+|[button]Select!::~selected|repeating_attack_$6_attack[/button] @{selected|repeating_attack_$6_atkname} --+|[button]Use It!::!
#Healer-Kit[/button] Healer's Kit --+|[button]Fix It!::!
#Fix-Initiative[/button] Fix Initiative Order }} I still need to read up some more as I wasn't able to get the ceiling function to work correctly so that I could use the level of the character from their character sheet divided by 2 and then rounded up as the number of d6 to roll; however, I'm pretty happy with it as it. As always I welcome suggestions on how to improve this. Note that just showing 0 through 6 was a design function as my character rarely will need to use the items beyond 6. Eventually I'll make it a loop so it isn't quite as limited. Senjak
1618215542
Senjak
Pro
Sheet Author
I'm slightly confused as the link points to a file that includes: const APIVERSION = "1.1.5" ; Is the difference in numbering intentional, or is it a typing error that stuck a while ago? Thanks, Senjak Kurt J. said: ScriptCards Version 1.1.15 is now available Up on the Development GIST . This version adds: It is now possible to persist a single array between cards/sessions/api restarts with the "stateitem" function read and write subfunctions. Simply specify "array" as the data type. The current index in the array is also preserved. Also: version 1.1.16 is underway, and will include some bug fixes (currently, the --i command doesn't account for arrays. That is fixed in 1.1.16) and a new statement type/feature :)
1618223224
Kurt J.
Pro
API Scripter
Senjak said: --~|turnorder;addtoken;@{selected|token_id};?{Initiative?} How do I correctly rewrite the above line to use Token and Init_Roll? Thanks for any assistance you can offer. After assigning the variable, it can be referenced later with the [$rollVariableName] notation, so: --~|turnorder;addtoken;[$Token.Total];[$Init_Roll.Total] Technically you shouldn't need the ".Total" suffixes, but it is clearer to include them.
1618223427
Kurt J.
Pro
API Scripter
Senjak said: In the spirit of sharing, here is a fairly simple example that I'm using in one of my 5e games. It isn't nearly as advanced as some of the examples, but it does show some parts that I had trouble with at first. !scriptcard {{ --#titlefontlineheight|1.5em --#lineheight|1.1em --#buttonbackground|#C9DAF8 --#titleCardBackground|#000000 --#buttontextcolor|#000000 --#buttonbordercolor|#000000 --#titlefontsize|24px --#subtitlefontsize|18px --#bodyfontsize|18px --#title|Available Actions --#sourceToken|@{selected|token_id} --#leftsub|@{selected|token_name} --#rightsub|@{Selected|class_display} --=Sneak_dmg|1d6 --+Sneak Attack Damage|[$Sneak_dmg] --+|[button]Select!::~selected|repeating_attack_$0_attack[/button] @{selected|repeating_attack_$0_atkname} --+|[button]Select!::~selected|repeating_attack_$1_attack[/button] @{selected|repeating_attack_$1_atkname} --+|[button]Select!::~selected|repeating_attack_$2_attack[/button] @{selected|repeating_attack_$2_atkname} --+|[button]Select!::~selected|repeating_attack_$3_attack[/button] @{selected|repeating_attack_$3_atkname} --+|[button]Select!::~selected|repeating_attack_$4_attack[/button] @{selected|repeating_attack_$4_atkname} --+|[button]Select!::~selected|repeating_attack_$5_attack[/button] @{selected|repeating_attack_$5_atkname} --+|[button]Select!::~selected|repeating_attack_$6_attack[/button] @{selected|repeating_attack_$6_atkname} --+|[button]Use It!::!
#Healer-Kit[/button] Healer's Kit --+|[button]Fix It!::!
#Fix-Initiative[/button] Fix Initiative Order }} I still need to read up some more as I wasn't able to get the ceiling function to work correctly so that I could use the level of the character from their character sheet divided by 2 and then rounded up as the number of d6 to roll; however, I'm pretty happy with it as it. As always I welcome suggestions on how to improve this. Note that just showing 0 through 6 was a design function as my character rarely will need to use the items beyond 6. Eventually I'll make it a loop so it isn't quite as limited. Senjak As a shortcut, you can set the RoundUp parameter prior to rolling the dice and use integer division: --=Down|5 \ 2 will equal 2 by default, but --#roundup|1 --=Up|5 \ 2 will be three.
1618223504
Kurt J.
Pro
API Scripter
Senjak said: I'm slightly confused as the link points to a file that includes: const APIVERSION = "1.1.5" ; Is the difference in numbering intentional, or is it a typing error that stuck a while ago? Thanks, Senjak Kurt J. said: ScriptCards Version 1.1.15 is now available Up on the Development GIST . This version adds: It is now possible to persist a single array between cards/sessions/api restarts with the "stateitem" function read and write subfunctions. Simply specify "array" as the data type. The current index in the array is also preserved. Also: version 1.1.16 is underway, and will include some bug fixes (currently, the --i command doesn't account for arrays. That is fixed in 1.1.16) and a new statement type/feature :) This is a typo. It shouldn't hurt anything, but I'll update it for the next release.
Kurt J. said: Michael C. said: I have been working on scriptcard calls to other macros and reviewed Mark C. and David M's discussion (in 9 in this forum), the API Call and Ability call wikis and the scriptcard wiki on inline formating of "buttons."  I noted David M. suggested: [Macro](!
#MacroName) and I tried:      --+[button]Divine Smite::!
#DivineSmite[/button] The issue here is that the line doesn't contain a vertical bar. The following will produce the button (added a bar right after the --+): --+|[button]Divine Smite::!
#DivineSmite[/button] That is actually an issue with several of the lines in your post above. They will likely work with that change. First, is there a way to use the "~" in place of the !
# as in powercards?  I have previously used: [command name](~Macros|macro-to-call) using a character sheet's attribute section to avoid the issues with using !
# but none of these worked:  Yes, this should work just as it did in PowerCards. ScriptCards [button]::[/button] syntax is really nothing but a wrapper around normal API buttons. It takes the text before the :: and puts it in square brackets and text after the :: and puts it in parenthesis  after that. I am adding a new formatting command in an upcoming release; [sheetbutton][/sheetbutton] that will help with this formatting by taking a label, a character id/token id/character name, and a sheet macro name on that character and creating a button for you. Hi Kurt, By the way I used to be Mangouste but I thought it would be a good idea to rename as I had made too much post to asks stupid questions...^^ Following many advices (mainly yours & David's) I created a script to simulate the game system I shared a while ago... I roll 3 dices, 1 blue, 1 red & 1 Yellow. The target value to roll against is dependant on the domain you need to test (in my case, below, I'm simulating a test in Gears (Engrenages in French) which is a Technique' skill.Technique is a domain that pertains to SPIRIT (yellow dice) so The yellow dice will be the "action" dice (the main one) for that roll. In that rpg you can rely on the 2 other dices in case you're not satisfied with your result, but at a cost ! You can use one (or both if you're skilled enough) of the 2 remaining dices to replace/complete your current yellow dice.... So basically, what my script below does is to compare each dice value (against the target which is Technique in this case) and display accordingly potential actions (keep/replace/complete). So I figured out how to deal with comparisons to simulate various cases and I thought I would allow my player to then click on the dired button to launch the roll calculation... But I'm stuck with the action part of the buttons (UESPRIT, PRAME, PCAME,....). When I click on a button it just quit my game & try yo open a new window... Thanks in advance for your help (once again ^^)! !scriptcards {{ --:FORMATTING|   --#sourceToken|@{selected|token_id}   --#title|Engrenages (Technique: [*S:technique_base])   --#evenRowBackground|#abceed   --#oddRowBackground|#eeeeee   --#noMinMaxHilight|1 --:USER INPUT|   --&TypeJet|Esprit   --=BonusSpec|[*S:EngrenagesPJ_Bonus]   --=BonusAcquis|[*S:EngrenagesPJ_Acquis]   --=BonusTotal|[$BonusSpec]+[$BonusAcquis]   --#leftsub|Spécialisation: [$BonusSpec]   --#rightsub|Acquis: [$BonusAcquis] --:INITIALIZE ROLL & STRING VARIABLES|   --=Esprit|[*S:Esprit]   --=Ame|[*S:Ame]   --=Corps|[*S:Corps]   --=Technique|[*S:technique_base]   --=Savoir|[*S:savoir_base]   --=Social|[*S:social_base]   --=Arts|[*S:art_base]   --=Shaan|[*S:shaan_base]   --=Magie|[*S:magie_base]   --=Rituels|[*S:rituel_base]   --=Survie|[*S:survie_base]   --=Combat|[*S:combat_base]   --=Necrose|[*S:necrose_base]   --=DéAme|[T#Ame]   --=DéCorps|[T#Corps]   --=DéEsprit|[T#Esprit]   --=DéNecrose|[T#Necrose]      --&Jaune|FEF68E   --&Bleu|1C6EA4   --&Rouge|990000   --&Vert|007700   --&Noir|000000   --+|[img][$DéEsprit.tableEntryImgURL][/img] - [img width=40 height=40][$DéAme.tableEntryImgURL][/img]- [img width=40 height=40][$DéCorps.tableEntryImgURL][/img]      --#emoteText|[*S:character_name] utilise Engrenages   -->CompareJE|[$DéEsprit.tableEntryValue];[$DéAme.tableEntryValue];[$DéCorps.tableEntryValue];[$Technique]   --X|             --:PROCEDURES|      --:CompareJE| accepts DéEsprit(1), DéAme (2), DéCorps(3), target(4)   --=E|[%1%]   --=A|[%2%]   --=C|[%3%]   --=EA|[%1%]+[%2%]   --=EC|[%1%]+[%3%]   --=AC|[%2%]+[%3%]    --=EAC|[%1%]+[%2%]+[%3%]      --:S0|y a t-il symbiose ?        --?[%1%] -eq [%2%] -and [%2%] -eq [%3%]|S1|B1   --:S1|Symbiose -> vérifions s'il s'agit d'une symbiose de 10        --?[%1%] -eq 10|Symb10|Symb   --:Symb10|Symbiose de 10 ?   --+Résultat|       --+|[c][#[&Rouge]][b]~~~Symbiose de 10 - Echec critique ! !~~~[/b][/#][/c]       --=HitScore|[$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis] -10   --+Score final|[$HitScore]   --^End|Jumps to the end   --:Symb|si pas symbiose de 10 quel type de Symbiose (parfaite ou normale)?       --?[%1%] -le [%4%]|Symbp|Symbn    --:Symbp|Symbiose parfaite -> Réussite critique !       --+Résultat|       --+|[c][#[&Vert]][b]~~~Symbiose parfaite!~~~[/b][/#][/c]       --=HitScore|[$E][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis] +10   --+Score final|[$HitScore]   --^End|Jumps to the end    --:Symbn|Symbiose  -> Belle Réussite  !       --+Résultat|       --+|[c][#[&Vert]][b]~~~Symbiose !~~~[/b][/#][/c]       --=HitScore|[$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis] +10   --+Score final|[$HitScore]   --^End|Jumps to the end    --:B1|branche 1 -> vérifions s'il ya maîtrise (puiser dans 2 trihns) ou non (puiser dans un seul trihn)        --?[%4%] -ge 10|MAIT|NOMAIT    --:MAIT|  --+|boucle Maitrise --?[%1%] -le [%4%]|Keep|SkipToAme --:Keep| --+|[l][b]Garder dé d'Action[/b][/l][r][button]Keep::>UESPRIT[/button][/r] --:SkipToAme| --?[%2%] -le [%4%]|Aff_PxAME|SkipToCorps --:Aff_PxAME| --+|[l][b]Remplacer Par Ame[/b][/l][r][button]R_A::>PRAME[/button][/r] --?[$EA] -le [%4%]|SkipToEA|SkipToCorps --:SkipToEA| --+|[l][b]Compléter par Ame[/b][/l][r][button]C_A::>PCAME[/button][/r] --:SkipToCorps| --?[%3%] -le [%4%]|Aff_PxCORPS|SkipToBoth --:Aff_PxCORPS| --+|[l][b]Remplacer Par Corps[/b][/l][r][button]R_C::>PRCORPS[/button][/r] --?[$EC] -le [%4%]|SkipToEC|SkipToBoth --:SkipToEC| --+|[l][b]Compléter par Corps[/b][/l][r][button]C_C::>PCCORPS[/button][/r] --:SkipToBoth| --?[$EAC] -le [%4%]|Aff_PCAMECORPS|SkipToAC --:Aff_PCAMECORPS| --+|[l][b]Compléter par Ame+Corps[/b][/l][r][button]C_AC::>PCAMECORPS[/button][/r] --:SkipToAC| --?[$AC] -le [%4%]|Aff_PRAMECORPS|SkipToFinal --:Aff_PRAMECORPS| --+|[l][b]Remplacer Par Ame+Corps[/b][/l][r][button]R_AC::>PRAMECORPS[/button][/r] --:SkipToFinal| --^End|Jumps to the end    --:NOMAIT|           --+|boucle Normale --?[%1%] -le [%4%]|Keep2|SkipToAme2 --:Keep2| --+|[l][b]Garder dé d'Action[/b][/l][r][button]Keep::>UESPRIT[/button][/r] --:SkipToAme2| --?[%2%] -le [%4%]|Aff_PxAME2|SkipToCorps2 --:Aff_PxAME2| --+|[l][b]Remplacer Par Ame[/b][/l][r][button]R_A::>PRAME[/button][/r] --?[$EA] -le [%4%]|SkipToEA2|SkipToCorps2 --:SkipToEA2| --+|[l][b]Compléter par Ame[/b][/l][r][button]C_A::>PCAME[/button][/r] --:SkipToCorps2| --?[%3%] -le [%4%]|Aff_PxCORPS2|End --:Aff_PxCORPS2| --+|[l][b]Remplacer Par Corps[/b][/l][r][button]R_C::>PRCORPS[/button][/r] --?[$EC] -le [%4%]|SkipToEC2|End --:SkipToEC2| --+|[l][b]Compléter par Corps[/b][/l][r][button]C_C::>PCCORPS[/button][/r]    --:End|    --X|    --:UESPRIT| -> choix de conserver le dé d'esprit       --=HitScore|[$E][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis]   --+Score final|[$HitScore]   --<|   --:PRAME| -> choix de puiser en Ame       --=HitScore|[$A][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis]   --+Score final|[$HitScore]   --<|   --:PCAME| -> choix de compléter avec Ame       --=HitScore|[$EA][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis]   --+Score final|[$HitScore]   --<|   --:PRCORPS| -> choix de puiser en Corps       --=HitScore|[$C][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis]   --+Score final|[$HitScore]   --<|   --:PCCORPS| -> choix de compléter avec Corps       --=HitScore|[$EC][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis]   --+Score final|[$HitScore]   --<|   --:PRAMECORPS| -> choix de remplacer par Ame + Corps       --=HitScore|[$AC][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis]   --+Score final|[$HitScore]   --<|   --:PCAMECORPS| -> choix de compléter par Ame + Corps       --=HitScore|[$EAC][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis]   --+Score final|[$HitScore]   --<|   --:Echec|       --+Result|       --+|[c][#[&Rouge]][b]~~~Echec!~~~[/b][/#][/c]   --<|   --:Succès|       --+Result|       --+|[c][#[&Vert]][b]~~~Succès!~~~[/b][/#][/c]       --=HitScore|[$JetBase][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis]       --+Score final|[$HitScore]   --<| }}   
1618233604
David M.
Pro
API Scripter
Woombak, it seems like the problem is with your button syntax. Buttons have this format : [button]caption::action[/button]     ...but you have put a procedure call in for the "action" statement (example below), which is not valid as a standalone command. Your scriptcard is already "done" before the user would click the button, so there is no valid context for the command.  --+|[l][b]Garder dé d'Action[/b][/l][r][button]Keep::>UESPRIT[/button][/r] Valid actions would be things like macro calls or api calls (Note: the latter not tested, but I don't see why it wouldn't work).  So, it might be best to either make separate macros (which could be scriptcards as well) for your buttons to fire off, or otherwise restructure your current card using queries, etc. Haven't studied your card very closely, but if the user needs to see existing output before making the decision which button to push, then the first option is probably the way to go.
I would encourage you to try using a loop to display the buttons dynamically, rather than hardcoding them. Something like: --Rfirst|@{selected|character_id};repeating_attack --:ButtonDisplayLoop| --+|[button]Select!::~selected|[*R:attack][/button] [*R:atkname] --Rnext| --? "[*R:atkname]" -ne NoRepeatingAttributeLoaded|ButtonDisplayLoop Senjak said: In the spirit of sharing, here is a fairly simple example that I'm using in one of my 5e games. It isn't nearly as advanced as some of the examples, but it does show some parts that I had trouble with at first. !scriptcard {{ --#titlefontlineheight|1.5em --#lineheight|1.1em --#buttonbackground|#C9DAF8 --#titleCardBackground|#000000 --#buttontextcolor|#000000 --#buttonbordercolor|#000000 --#titlefontsize|24px --#subtitlefontsize|18px --#bodyfontsize|18px --#title|Available Actions --#sourceToken|@{selected|token_id} --#leftsub|@{selected|token_name} --#rightsub|@{Selected|class_display} --=Sneak_dmg|1d6 --+Sneak Attack Damage|[$Sneak_dmg] --+|[button]Select!::~selected|repeating_attack_$0_attack[/button] @{selected|repeating_attack_$0_atkname} --+|[button]Select!::~selected|repeating_attack_$1_attack[/button] @{selected|repeating_attack_$1_atkname} --+|[button]Select!::~selected|repeating_attack_$2_attack[/button] @{selected|repeating_attack_$2_atkname} --+|[button]Select!::~selected|repeating_attack_$3_attack[/button] @{selected|repeating_attack_$3_atkname} --+|[button]Select!::~selected|repeating_attack_$4_attack[/button] @{selected|repeating_attack_$4_atkname} --+|[button]Select!::~selected|repeating_attack_$5_attack[/button] @{selected|repeating_attack_$5_atkname} --+|[button]Select!::~selected|repeating_attack_$6_attack[/button] @{selected|repeating_attack_$6_atkname} --+|[button]Use It!::!
#Healer-Kit[/button] Healer's Kit --+|[button]Fix It!::!
#Fix-Initiative[/button] Fix Initiative Order }} I still need to read up some more as I wasn't able to get the ceiling function to work correctly so that I could use the level of the character from their character sheet divided by 2 and then rounded up as the number of d6 to roll; however, I'm pretty happy with it as it. As always I welcome suggestions on how to improve this. Note that just showing 0 through 6 was a design function as my character rarely will need to use the items beyond 6. Eventually I'll make it a loop so it isn't quite as limited. Senjak
David M. said: Woombak, it seems like the problem is with your button syntax. Buttons have this format : [button]caption::action[/button]     ...but you have put a procedure call in for the "action" statement (example below), which is not valid as a standalone command. Your scriptcard is already "done" before the user would click the button, so there is no valid context for the command.  --+|[l][b]Garder dé d'Action[/b][/l][r][button]Keep::>UESPRIT[/button][/r] Valid actions would be things like macro calls or api calls (Note: the latter not tested, but I don't see why it wouldn't work).  So, it might be best to either make separate macros (which could be scriptcards as well) for your buttons to fire off, or otherwise restructure your current card using queries, etc. Haven't studied your card very closely, but if the user needs to see existing output before making the decision which button to push, then the first option is probably the way to go. Hi David! Mangouste is back ^^  TBH I thought about using macros but the problem is that I need to pass over the dice values that I store in my variables (E,A, C, EA, AC, AC, EAC). And something I haven't mentionned yet is that I will add a query in the final roll depending on the choice made by the user.... So UESPRIT (one of the choice would be): --:UESPRIT| -> choix de conserver le dé d'esprit       --=HitScore|[$E][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis] +?{Bonus/Malus|0}[Bonus]   --+Score final|[$HitScore]   --<| instead of --:UESPRIT| -> choix de conserver le dé d'esprit       --=HitScore|[$E][Jet] + [$BonusSpec][Spécialisation] + [$BonusAcquis][Acquis]   --+Score final|[$HitScore]   --<| So I can't use a querry before ! Any idea how could call upon a macro and be able to pass over arguments (dice values)? (That's mainly why I tried subroutines in the first place)
1618243247
David M.
Pro
API Scripter
Woombak, you could use some trickery with scriptcard stateitems, as discussed recently on this thread. Version 1.1.15 can now store an array as a persistent "global" variable. You could create an array with elements equal to the [$roll.Total] of each of the rolls you want to reference later. You would still have to create at least one more scriptcard macro that would read the array that was stored in the State object, then have that macro iterate over the array and re-assign roll variables based on the stored values. Then proceed as you wanted. I'm at work right now so can't dig into it, but that sounds like one potential solution.
1618244640
Kurt J.
Pro
API Scripter
David M. said: Woombak, you could use some trickery with scriptcard stateitems, as discussed recently on this thread. Version 1.1.15 can now store an array as a persistent "global" variable. You could create an array with elements equal to the [$roll.Total] of each of the rolls you want to reference later. You would still have to create at least one more scriptcard macro that would read the array that was stored in the State object, then have that macro iterate over the array and re-assign roll variables based on the stored values. Then proceed as you wanted. I'm at work right now so can't dig into it, but that sounds like one potential solution. Before you go too far down that road, stay tuned :) What if you COULD have a button that would re-enter the same script with all of the same values in place and pick up processing... Just sayin'... :)
1618245829

Edited 1618245840
David M.
Pro
API Scripter
1618246044
Senjak
Pro
Sheet Author
This old dyslectic Unix administrator after a lifetime of dealing with people just making the leap from Windows to Unix, automatically swapped the '\' with to the '/' having not thoroughly digested the documentation. Kurt J. said: As a shortcut, you can set the RoundUp parameter prior to rolling the dice and use integer division: --=Down|5 \ 2 will equal 2 by default, but --#roundup|1 --=Up|5 \ 2 will be three.
1618256130
Senjak
Pro
Sheet Author
Colin C. said: I would encourage you to try using a loop to display the buttons dynamically, rather than hardcoding them. Something like: --Rfirst|@{selected|character_id};repeating_attack --:ButtonDisplayLoop| --+|[button]Select!::~selected|[*R:attack][/button] [*R:atkname] --Rnext| --? "[*R:atkname]" -ne NoRepeatingAttributeLoaded|ButtonDisplayLoop I followed your advice and rewrote it to use a loop; however I keep getting an error that I'm having trouble with: No ability was found for %{selected|} 2:30PM Senjak (GM): selected I suspect that the answer is in this thread.  Sadly it is many pages to search individually!
1618259386

Edited 1618259516
Whoops! --Rfirst|@{selected|character_id};repeating_attack --:ButtonDisplayLoop| --+|[button]Select!::~selected|[ *R>attack ][/button] [*R:atkname] --Rnext| --? "[*R:atkname]" -ne NoRepeatingAttributeLoaded|ButtonDisplayLoop You need to use > instead of : when you want the attribute name, rather than its value. Senjak said: Colin C. said: I would encourage you to try using a loop to display the buttons dynamically, rather than hardcoding them. Something like: --Rfirst|@{selected|character_id};repeating_attack --:ButtonDisplayLoop| --+|[button]Select!::~selected|[*R:attack][/button] [*R:atkname] --Rnext| --? "[*R:atkname]" -ne NoRepeatingAttributeLoaded|ButtonDisplayLoop I followed your advice and rewrote it to use a loop; however I keep getting an error that I'm having trouble with: No ability was found for %{selected|} 2:30PM Senjak (GM): selected I suspect that the answer is in this thread.  Sadly it is many pages to search individually!
1618261009

Edited 1618265599
Kurt J.
Pro
API Scripter
ScriptCards version 1.1.18 now Available The Development GIST has been updated with version 1.1.18 of ScriptCards. This version of contains several fixes and enhancements, and will likely be the version (pending bugs) that ends up being pushed to OneClick. The changes include: Errors and Warnings : To aid in debugging your scripts, the following issues will now log an error or warning to the console log:    - A label is redefined (warning)    - Two labels with the same name but different case are defined (warning)   - A line does not contain a vertical bar separator (error)   -  A branch (goto, gosub, case, conditional, or reentrant button (see below) is attempted to a label that does not exist (error) Bug Fix : The information statement (--i) now properly stashes and restores arrays. New Statement Type : The GM Text statement type (--*) works just like the Direct Output (--+) statement, except that it builds a separate card without a title or emote that is sent to the GM after the main card is displayed. New Formatting Option : [sheetbutton]ButtonCaption::Character::AbilityMacro[/sheetbutton] . This works similarly to [button], but takes three parameters instead of two and is used for easily creating buttons that refer to macros on character sheets. The Character parameter can be a character ID, a token ID that represents a character, or a character name. ScriptCards will try to find a match and generate the button. New Feature : Reentrant scripts. You can now define a setting called “reentrant” and give it a name. This will stash the script in memory (the same way the –i statement does). You can then use the new [rbutton]ButtonCaption::ReentryLabel[/rbutton] syntax to create buttons that the user can press to resume execution of the script at the specified label with the variables, settings and arrays intact. Reentrant scripts modify the behavior of the exit (–X) statement to stash the script as it currently exists in preparation for reentry later. Stashed reentrant scripts last as long as the current sandbox is running. They do not persist between sessions or between sandbox restarts. When a script is reentered, the output lines (both public and GM) are cleared to prevent repetition of the same information over again in the chat window. You could always re-output them if that is desired. The new Reentrant scripts can allow for some very powerful and flexible scripts. Here is an example that utilizes Reentrantcy (obviously) and the GM Text statement for a standard 5E attack. !script {{ --#reentrant|LongswordAttack --#sourcetoken|@{selected|token_id} --#targettoken|@{target|token_id} --#emotestate|visible --#hidetitlecard|0 --#emotetext|@{selected|character_name} swings a Longsword at @{target|character_name} --#title|Longsword Attack --#leftsub|Range: 5 Feet --#rightsub|Melee Weapon Attack --=Attack|1d20 + [*S:strength_mod] [STR] + [*S:pb] [PROF] --+Attack Roll|[$Attack] vs [*T:character_name]'s AC --*Attack Roll|[$Attack] vs AC [*T:npc_ac] --?[$Attack.Base] -eq 20|CritButton --+|[c][rbutton]Roll Damage::RollDamage[/rbutton][/c] --^Skip| --:CritButton| --+|[c][rbutton]Roll Damage::RollCritDamage[/rbutton][/c] --:Skip| --X| --:RollDamage| --#hidetitlecard|1 --=Damage|1d8 + [*S:strength_mod] --#title|Longsword Damage --#emotestate|hidden --+Hit|[*S:character_name] hits [*T:character_name] for [$Damage] slashing damage -->ReportDamageToGM| --X| --:RollCritDamage| --#hidetitlecard|1 --=Damage|1d8 + [*S:strength_mod] [STR] + 1d8 [Crit] --#title|Longsword Damage --#emotestate|hidden --+Critical Hit|[*S:character_name] hits [*T:character_name] for [$Damage] slashing damage -->ReportDamageToGM| --X| --:ReportDamageToGM| --=Result|[$Damage] --&DamageChanged|0 --?"[*T:npc_resistances]" -inc slashing|>HalfDamage --?"[*T:npc_vulnerabilities]" -inc slashing|>DoubleDamage --?"[*T:npc_immunities]" -inc slashing|>NoDamage --?[&DamageChanged] -eq 0|SkipDMDamage --*|After resistances and immunities, [*T:character_name] takes [$Result] slashing damage --:SkipDMDamage| --<| --:DoubleDamage| --&DamageChanged|1 --=Result|[$Damage] * 2 --<| --:HalfDamage| --&DamageChanged|1 --=Result|[$Damage] \ 2 --<| --:NoDamage| --&DamageChanged|1 --=Result|0 --<| }} \In this script, we begin by setting up a fairly standard 5E attack script, saving a source and target token (note that saving the tokens is necessary since we won’t necessarily have them selected again when we hit reentrant buttons. Important to note here is the setting of “reentrant” to “LongswordAttack” the name itself isn’t critical, but this is the name that will be used internally to reference this stashed script later. As long as the names of the scripts are different, any number of reentrant scripts can be defined. I am also setting some card settings to their default values, which probably isn’t strictly necessary but I want to make it clear what is going to be output (like --#hidetitlecard|0 at the top of the script). We roll an attack roll, taking the source character into account, and display the result of the dice roll on the card. We send a separate card to the GM with the attack roll vs the target’s AC so they can determine if the attack hit or not. We also generate a “Roll Damage” button at the end of the card that is reentrant to either “RollDamage” or “RollCritDamage” depending on the value of the d20 roll. This is our reentrant button, and will cause the script to resume execution at the indicated label when the button is clicked. At this point, the script exits (--X) and the resulting output is displayed to chat, including a card everyone can see and the whisper to the GM. If the GM tells the player that the attack hit, the player can click the “Roll Damage” button which will relaunch the script to either the “RollDamage” or the “RollCritDamage” label and roll the dice, reporting to the player how much damage they rolled in the form of a new card that does not contain a title or emote and simply reports the amount of damage dealt. If the target has resistance, vulnerability, or immunity, we calculate the appropriate modifier to the damage and report that on a GM-Only card letting the GM know the real amount of damage that the target takes.  Finally, just a note that this script could be tightened up a bit, like a subroutine for creating the button that is passed the desired label, but I wanted to clearly illustrate how [rbutton] works, so I left the longer version in the script. Here is a GIF with an example hitting a non-resistant creature and a creature that is immune to slashing damage:
1618262361
David M.
Pro
API Scripter
Groovy!
Kurt, thank you so much....You rock man !  this is what it looks like now : Yellow dice being < 10 (Technique), Yaemial's options are : Keep 7 as a basis to add 1 for the skill & 2 for the object's bonus for a final result of 10 Replace by Ame (the blue dice) for a final result of 9 Replace by Corps (the red dice) for a final result of 7 Replace by Ame + Corps (Sum of the 2 other dices) for a final result of 13 Yaemial obviously clicked on the best (highest) option (the last one) which results in : Now I need to figure out how to enable this for the 99 other skills in my rpg. I'm thinking of Transforming the main card in a function to be stored in a library and to be called passing the skill name as the reentrant tag. I'll let you know how it goes but thanks again for this !
1618267922
Kurt J.
Pro
API Scripter
Woombak said: Kurt, thank you so much....You rock man !  this is what it looks like now : Yellow dice being < 10 (Technique), Yaemial's options are : Keep 7 as a basis to add 1 for the skill & 2 for the object's bonus for a final result of 10 Replace by Ame (the blue dice) for a final result of 9 Replace by Corps (the red dice) for a final result of 7 Replace by Ame + Corps (Sum of the 2 other dices) for a final result of 13 Yaemial obviously clicked on the best (highest) option (the last one) which results in : Now I need to figure out how to enable this for the 99 other skills in my rpg. I'm thinking of Transforming the main card in a function to be stored in a library and to be called passing the skill name as the reentrant tag. I'll let you know how it goes but thanks again for this ! Thats great 😀 and thank you for the feature idea. How about a reenterant card that starts off with a menu to choose the skill category, then shows the skills in that category, and finally does the roll? You could even whisper everything to "self" for the first couple of entries and then set whisper to 0 for the final ourput.
Kurt,  A quick question: Is there a reason when there is a repeating row loaded that some of the attributes of the row don't get accessed or loaded? Specifically, the Pathfinder 2 character sheet has the damage for weapons split into 2 attributes (for some reason) called damage_dice and damage_dice_size.  When I run this card for a rapier (weapon damage 1d6): !scriptcard {{    --#sourceToken|@{selected|token_id}   --#whisper|GM   --Rfirst|[*S:character_id];repeating_melee-strikes   --+Damage|Number of dice: [*R:damage_dice] and Dice Size [*R:damage_dice_size] for [*R:weapon] }} This is output that I get: I made sure the names were correct by running:  @{selected|repeating_melee-strikes_$0_damage_dice} @{selected|repeating_melee-strikes_$0_damage_dice_size} And that gave me the correct 1D6. I've also tried running the Rdump command and the damage_dice attribute isn't even listed. Could this be a problem with the sheet as it interacts with the API?
1618272722
Senjak
Pro
Sheet Author
Colin C. said: Whoops! --Rfirst|@{selected|character_id};repeating_attack --:ButtonDisplayLoop| --+|[button]Select!::~selected|[ *R>attack ][/button] [*R:atkname] --Rnext| --? "[*R:atkname]" -ne NoRepeatingAttributeLoaded|ButtonDisplayLoop Thank you!  And now I know what I need to read closer. !scriptcard {{ --#titlefontlineheight|1.5em --#lineheight|1.1em --#buttonbackground|#C9DAF8 --#titleCardBackground|#000000 --#buttontextcolor|#000000 --#buttonbordercolor|#000000 --#titlefontsize|24px --#subtitlefontsize|18px --#bodyfontsize|18px --#title|Available Actions --#sourceToken|@{selected|token_id} --#leftsub|@{selected|token_name} --#rightsub|@{Selected|class_display} --=WpnCount|0 --=MaxWeapons|6 --+|[button]Stab It!::!
#Sneak-Attack-Damage[/button] Sneak Attack Damage --Rfirst|@{selected|character_id};repeating_attack --:ButtonDisplayLoop| --=WpnCount|[$WpnCount] + 1 --?[$WpnCount] -gt [$MaxWeapons]|Final --+|[button]Select!::~selected|[*R>attack][/button] [*R:atkname] --Rnext| --? "[*R:atkname]" -ne NoRepeatingAttributeLoaded|ButtonDisplayLoop --:Final| --+|[button]Use It!::!
#Thrusting-Wind[/button] Cast Thrusting Wind --+|[button]Use It!::!
#Healer-Kit[/button] Healer's Kit --+|[button]Fix It!::!
#Fix-Initiative[/button] Fix Initiative Order }} I've put a version on my GF's sheet that is pinkish, and one on my sheet that is blueish.  She has more items of interest, so the MAXWeapons is larger. Thank you for the assistance!