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 - Thread #2

Hey Tristan, So I did a stripped down example. Obviously your scriptcard will generate the weapons and do all that you need it to do but I wanted to show a couple things that might work for you with the reentrant buttons. !script {{ --/|DUMMY VARIABLES FOR THE EXAMPLE --/|IN YOUR REAL SCRIPT THESE WOULD ALL BE GENERATED --~|array;define;WeaponArr;Small Wood Blowgun;Medium Wood Bard's Friend;Medium Stone Pick, heavy;Medium Stone Urgrosh, dwarven --h:WeaponHash("Small Wood Blowgun-weight")|1.00 lbs. --h:WeaponHash("Small Wood Blowgun-cost")|2.5 cp --h:WeaponHash("Medium Wood Bard's Friend-weight")|0.50 lbs. --h:WeaponHash("Medium Wood Bard's Friend-cost")|10 cp --h:WeaponHash("Medium Stone Pick, heavy-weight")|4.50 lbs. --h:WeaponHash("Medium Stone Pick, heavy-cost")|6 cp --h:WeaponHash("Medium Stone Urgrosh, dwarven-weight")|9.00 lbs. --h:WeaponHash("Medium Stone Urgrosh, dwarven-cost")|37.5 cp --#title|Re-Entry Whisper Example --~ts|system;date;getdatetime --#reentrant|WeaponGeneration[&ts] --%weapon|foreach;WeaponArr --+|[rbutton][&weapon]::WhisperDescription;[&weapon][/rbutton] --%| --:Done| --X| --:WhisperDescription|WeaponName --#whisper|self --+DEBUG|Sending Player: [&SendingPlayerName] --+|[c][b][&reentryval] Description[/b][/c] --+Weight|[:WeaponHash("[&reentryval]-weight")] --+Cost|[:WeaponHash("[&reentryval]-cost")] --^Done| }} So you can see that all players will get the original Scriptcard output with the buttons but when a player clicks, you can see that --#whisper|self is used to limit the output of the descriptions to just the player that clicked. I added the DEBUG output line with the &SendingPlayerName variable to illustrate that only the clicking player sees the description they clicked. Since you mentioned that variable collision was an issue, I used a timestamp in the --#reentrant parameter to help prevent that. I am guessing that you had a static phrase for --#reentrant| previously, eg. `--#reentrant|WeaponGenerator` and that was keeping variables in the same namespace. With a timestamp, each time you call the ScriptCard it should set reentrant to a unique value to help prevent collisions in the variable stash. Hopefully those things are helpful to you.
1725500206

Edited 1725543639
Joshua thank you so much! I managed to get them working! I used [&LoopCounter] saved as the reentryval. it was actually pretty simple!
1725634386

Edited 1725634556
Hello, is there a way to have a button in a Handout link? Currently, when I write : `!scriptcard  {{ --#titleCardBackground|#66482d --#oddRowBackground|#FFF3E7 --#evenRowBackground|#ECD2BA --#tableBorderRadius|1 --+|[c][button]Test INT::!cof-jet INT 10 _succes Se souvient du code _echec Malus cumulatif de -2 pour le prochain essai (1 fois/j.)[/button][/c] --] }} It generates this : The problem is that it replaces the ":" with the character ":", which seems to prevent the button from appearing. Is there a way to work around this? Thanks in advance!
Hey all,  I'm experiencing a weird error and I want to know if the error is mine.  So this is the code running: --&TargetID|-O698TaFKp3FUDiw6OdM --&TokenID|[*[&TargetID]:t-id] --!t:[&TokenID]|bar1_value:-=[$DamageAmount] And this odd error appears in the Mod console: "ContentIn: [*[&TargetID]:t-id] Match: [&TargetID], vName: TargetID, replacement -O698TaFKp3FUDiw6OdM" "Line Counter: 76, Tag:&TokenID, Content:" "ContentIn: !t:[&TokenID] Match: [&TokenID], vName: TokenID, replacement " "ContentIn: bar1_value:-=[$DamageAmount] Match: [$DamageAmount], vName: DamageAmount, vSuffix: Total, replacement 7" "Line Counter: 77, Tag:!t:, Content:bar1_value:-=7" "Error updating/adding object Unexpected token u in JSON at position 0, thisTag: !t:, thisContent: bar1_value:-=7" "ContentIn: ?[*[&TokenID]:t-bar1_value] -le 0 Match: [&TokenID], vName: TokenID, replacement " It looks like it correctly replaces the Target ID in the first line, but it isn't passing any token ID to the &TokenID string variable.  Why? Thanks!
Erik, What is the TargetID value you have, is that a character id? A token id? Are you hardcoding it in your original ScriptCard or is this a test? If it was just a test, can you post the original code you were trying to use and how you are getting that ID?
It's a character ID hardcoded for a test of a much larger subroutine. The snippet I posted is just the test code. 
I don't think you can get a token id directly from a character id in that object lookup. A character could have any number of tokens on any given page or spread out over multiple pages. Quick example: !script {{ --&CharID|@{selected|character_id} --+CharID|[&CharID] --+Token Property|[*[&CharID]:t-top] --+Character Attribute|[*[&CharID]:hp] }} One typical way would be to compare against the `array;pagetokens` function. Kurt has a procedure in his system neutral library  LibSN_GET_TOKENS_REPRESENTING  that uses pagetokens function to get a character id's tokens on a page. Here is a function I wrote before I knew about Kurt's snlib function to do much the same thing for the currently active page with the player ribbon. --/|GetTokenIDForCharacter returns the token-id for the current page with the player's ribbon for the corresponding character id --:GetTokenIDForCharacter|CharacterID;StringVariableToSetTokenID --~libTokenNum|array;pagetokens;libTokenArr;[*C:playerpageid];char --?[&libTokenNum] -eq 0|&[%2%];NoTokensError --=LastIndex|[&libTokenNum] - 1 --&[%2%]|NotFoundError --%loopCounter|0;[$LastIndex] --&libTID|[*[@libTokenArr([&loopCounter])]:t-id] --&Reps|[*[@libTokenArr([&loopCounter])]:t-represents] --?[&Reps] -eq [%1%]|[ --&[%2%]|[&libTID] --%!| --]| --%| --<|
Super useful, thanks!
1725987546

Edited 1726121247
I have made a D&D 3.5 (AD&D 2e works too) and PF1e  non-euclidean distance card, hopefully it will be useful for someone else! It uses the #sourceToken/#targetToken to work. It now counts from the closest edge of tokens and with my testing works with all sized tokens! Seriously useful! !script {{ --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --?[*S:t-height] -gt 70|BigBoi --?[*S:t-width] -gt 70|BigBoi --=source_Height|[*S:t-height]/70 / 2 - 1 {CEIL} --=source_Width|[*S:t-width]/70 / 2 - 1 {CEIL} --=target_Height|[*T:t-height]/70 / 2 - 1 {CEIL} --=target_Width|[*T:t-width]/70 / 2 - 1 {CEIL} --=source_Y|[*S:t-top]/70 --=source_X|[*S:t-left]/70 --=token_diff_height|[$target_Height] + [$source_Height] --=token_diff_width|[$target_Width] + [$source_Width] --=target_Y|[*T:t-top]/70 --=target_X|[*T:t-left]/70 --=Y_diff|[$source_Y]-[$target_Y] {ABS} {FLOOR} --=X_diff|[$source_X]-[$target_X] {ABS} {FLOOR} --?[$Y_diff] -lt [$token_diff_height]|[ --=Y_diff|1 --]|[ --=Y_diff|[$Y_diff] - [$token_diff_height] {ABS} --]| --?[$X_diff] -lt [$token_diff_width]|[ --=X_diff|1 --]|[ --=X_diff|[$X_diff] - [$token_diff_width] {ABS} --]| --?[$Y_diff] -lt [$X_diff]|[ --=X_diff_non_euclidean|[$X_diff]-[$Y_diff] --=X_diff_non_euclidean|[$X_diff_non_euclidean] *5 --=Y_diff_non_euclidean|[$Y_diff]*1.5 {FLOOR} *5 --=Total_distance_non_euclidean|[$X_diff_non_euclidean]+[$Y_diff_non_euclidean] --+|[$Total_distance_non_euclidean] TOTAL FT. --]|[ --=Y_diff_non_euclidean|[$Y_diff]-[$X_diff] --=Y_diff_non_euclidean|[$Y_diff_non_euclidean]*5 --=X_diff_non_euclidean|[$X_diff]*1.5 {FLOOR} *5 --=Total_distance_non_euclidean|[$X_diff_non_euclidean] + [$Y_diff_non_euclidean] --+|[$Total_distance_non_euclidean] TOTAL FT. --]| --X| --:BigBoi| --=source_Height_even_odd|[*S:t-height]/70 --%loop|until;[$source_Height_even_odd] -lt 1 --=source_Height_even_odd|[$source_Height_even_odd]-2 --%| --=source_Width_even_odd|[*S:t-width]/70 --%loop|until;[$source_Width_even_odd] -lt 1 --=source_Width_even_odd|[$source_Width_even_odd]-2 --%| --=target_Height_even_odd|[*T:t-height]/70 --%loop|until;[$target_Height_even_odd] -lt 1 --=target_Height_even_odd|[$target_Height_even_odd]-2 --%| --=target_Width_even_odd|[*T:t-width]/70 --%loop|until;[$target_Width_even_odd] -lt 1 --=target_Width_even_odd|[$target_Width_even_odd]-2 --%| --?[$source_Height_even_odd] -eq 0|[ --=source_Height|[*S:t-height]/70 / 2 {CEIL} --]|[ --=source_Height|[*S:t-height]/70 / 2 - 1 {CEIL} --]| --?[$source_Width_even_odd] -eq 0|[ --=source_Width|[*S:t-width]/70 / 2 {CEIL} --]|[ --=source_Width|[*S:t-width]/70 / 2 - 1 {CEIL} --]| --?[$target_Height_even_odd] -eq 0|[ --=target_Height|[*T:t-height]/70 / 2 {CEIL} --]|[ --=target_Height|[*T:t-height]/70 / 2 - 1 {CEIL} --]| --?[$target_Width_even_odd] -eq 0|[ --=target_Width|[*T:t-width]/70 / 2 {CEIL} --]|[ --=target_Width|[*T:t-width]/70 / 2 - 1 {CEIL} --]| --?[$source_Height] -gt 0|[ --=source_Height|[$source_Height]-1 --]|[ --]| --?[$source_Width] -gt 0|[ --=source_Width|[$source_Width]-1 --]|[ --]| --=source_Y|[*S:t-top]/70 --=source_X|[*S:t-left]/70 --=token_diff_height|[$target_Height] + [$source_Height] --=token_diff_width|[$target_Width] + [$source_Width] --=target_Y|[*T:t-top]/70 --=target_X|[*T:t-left]/70 --=Y_diff|[$source_Y]-[$target_Y] {ABS} {FLOOR} --=X_diff|[$source_X]-[$target_X] {ABS} {FLOOR} --?[$Y_diff] -lt [$token_diff_height]|[ --=Y_diff|1 --]|[ --=Y_diff|[$Y_diff] - [$token_diff_height] {ABS} --]| --?[$X_diff] -lt [$token_diff_width]|[ --=X_diff|1 --]|[ --=X_diff|[$X_diff] - [$token_diff_width] {ABS} --]| --?[$Y_diff] -lt [$X_diff]|[ --=X_diff_non_euclidean|[$X_diff]-[$Y_diff] --=X_diff_non_euclidean|[$X_diff_non_euclidean] *5 --=Y_diff_non_euclidean|[$Y_diff]*1.5 {FLOOR} *5 --=Total_distance_non_euclidean|[$X_diff_non_euclidean]+[$Y_diff_non_euclidean] --+|[$Total_distance_non_euclidean] TOTAL FT. --]|[ --=Y_diff_non_euclidean|[$Y_diff]-[$X_diff] --=Y_diff_non_euclidean|[$Y_diff_non_euclidean]*5 --=X_diff_non_euclidean|[$X_diff]*1.5 {FLOOR} *5 --=Total_distance_non_euclidean|[$X_diff_non_euclidean] + [$Y_diff_non_euclidean] --+|[$Total_distance_non_euclidean] TOTAL FT. --]| }}
Hi, I current use this  !setattr --sel --modb --class_resource|+1 charsetattr command to add to a resource without exceeding it's maximum. How would a replicate this command in a script card ?
1726224672

Edited 1726261647
You can call the same API in scriptcards --@setattr| _sel _modb _class_resource|+1
Tristan, Thanks for this. I've tried it out and If I keep running then same command the resource total goes onto exceed the maximum. Interesting this also happen just running the CharSetAttr command as well so don't believe this is a scriptcard issue. If I change the command to hp the hp maximum isn't exceeded regardless of how many times I run the command. Any ideas ? Maybe I need to raise it a separate ChatSetAttr question 
1726247022

Edited 1726248032
--@modbattr|_charid @{selected|character_id} _water|1 --@setattr| _sel _modb _water|1 They both work with in attribute that has a |max in my game. Replace 1 with -1 and try again, does the go below 0? If not then its working as intended and that attribute does not have a max value set. Most character sheets will have a separate value next to it called (same_name)|max for when it is relevant, check if that is how it is labeled. I also added another way of writing the command as well. scriptcards has there own form at of changing attributes that you can check here --!a:@{selected|token_id}|water:+=-1 this is an example of what scriptcards uses, it doesn't check for max and min values so easily.
Tristan, Cracked it. I had the max value linked to pb. I removed that and entered 2 instead and now all works fine. Cheers for your help
1726371833

Edited 1726371897
Has anyone managed to get a "status marker tracker" working? I have one that works fantastic in my opinion but it has one MAJOR issue, token markers over counter 9 (green@9) do NOT display on token, they DO still exist on the token and I can decrement normally but the token will not be displayed until the counter has hit 9 or lower. My immediate thought is to add another identical counter through custom markers (that has a different name) to the token but strip all numbers but the last number and simply use that token? I haven't tried decrementing multiple tokens, maybe displaying multiple markers to represent digits similar to the Fly api? I'm worried I'll be running too much code and slowing my game down. I was hoping to be able to share this when it is better coded and fully implemented so if you have a better solution than adding custom markers I would love to hear it.  I am also interested in cleaning up my code as I'm planning to add more scriptcard automation to my game but I don't want to bog down the sandbox with needless loops my code so far is bellow. Uses token-mod to trigger when needed.  -->BlindedPlayerRemove| just gets code to print and alter either attributes/tokens, depending on the status. ----ScriptCards_Triggers---- ----change:graphic---- !script {{ --#title|Status +++D&D_3.5e+++ --/|TRIGGER_REPLACEMENTS --&CharId|[*[&GraphicNew_id]:character_id] --&Sheet|[*[&GraphicNew_id]:npc-show] --&NewMarkers|[&GraphicNewstatusmarkers] --&OldMarkers|[&GraphicOldstatusmarkers] --%RemovalLoop|until;[$LoopsToRemove] -eq 9 --=LoopsToRemove|[$LoopsToRemove]+1 --&LoopsToRemoveString|[$LoopsToRemove.Raw] --~NewMarkers|string;replace;@[&LoopsToRemoveString];;[&NewMarkers] --~OldMarkers|string;replace;@[&LoopsToRemoveString];;[&OldMarkers] --~NewMarkers|string;replace;[&LoopsToRemoveString]@;;[&NewMarkers] --~OldMarkers|string;replace;[&LoopsToRemoveString]@;;[&OldMarkers] --%| --~|array;fromstring;NewMarkersArray;,;[&NewMarkers] --~|array;fromstring;OldMarkersArray;,;[&OldMarkers] --~NewMarkerString|array;stringify;NewMarkersArray --~OldMarkerString|array;stringify;OldMarkersArray --~|array;remove;NewMarkersArray;[&OldMarkerString] --~|array;remove;OldMarkersArray;[&NewMarkerString] --~NewMarkerString|array;stringify;NewMarkersArray --~OldMarkerString|array;stringify;OldMarkersArray --/|DEBUG --+|New Marker|[&NewMarkerString] --+|Removed Marker|[&OldMarkerString] --?"[&NewMarkerString]" -eq "bleeding-eye"|BlindedAdd --?"[&OldMarkerString]" -eq "bleeding-eye"|BlindedRemove --?"[&NewMarkerString]" -eq "tread"|FlatFootedAdd --?"[&OldMarkerString]" -eq "tread"|FlatFootedRemove --:Return| --X| --:BlindedAdd| --+|[&GraphicNewname] has been [b]Blinded[/b] -->Blinded| --?:"[&Sheet]" -eq "1"|-->BlindedPlayerAdd| --?:"[&Sheet]" -eq "2"|-->BlindedNpcAdd| --^Return| --:BlindedRemove| --+|[&GraphicNewname] is no longer [b]Blinded[/b] --@token-mod| _ids [&GraphicNew_id] _set statusmarkers|-bleeding-eye --?:"[&Sheet]" -eq "1"|-->BlindedPlayerRemove| --?:"[&Sheet]" -eq "2"|-->BlindedNpcRemove| --^Return| }} To decrement , I have added this code to the change:campaign:turnorder script under trigger examples on the gihub found here --:Decrement_Marker| --@token-mod| _ids [&TID] _set statusmarkers|bleeding-eye:-1 --+|[&TID] [&name] --^Return_Decrement|
1726425858

Edited 1726425928
I’ve written a generic Script that works well for me.  There is a limitation to numeric values 0 through 9.  I’ve seen some people use the red/blue/green dots to represent 100’s/10’s/1’s spot.  To represent the number 193 you would place a Red 1, Blue 9 and Green 3 status marker on the token.   As a side note, I’ve been pondering my next big project and it does have some relationship to status markers.  That being an Event Tracker , where the events could be short lived (Vex, Frightened, Held, Stunned, …), medium length (Rage, Inspired, Guidance, Spells, …) and some are longer term (cursed, exhausted, multi-day countdown, …).   The interface to add them would likely be a Wizard (step by step) implemented with Scriptcards. I would output the results to a sorted table via handout, which would also support the removal of events.   I would store the events in State Memory, so the data persists across sessions. For short term, combat, and fixed length events (“Until the end of players next turn”), it would automatically remove itself from the Events log at the right time, using the Turnorder tracker. It would also automatically add/remove status markers based on the type of Event being created, if one was required.  
1726434922

Edited 1726447826
That definitely sounds great! Tracking statuses through multiple events sounds wild! A lot of people would love that level of automation. With my limited capabilities I might have to stick to if marker is added/removed do X while I wait for someone more capable lol. I'm planning to change the 'remove from string' loop to just use 'contains "x"' to process less tho I'm a bit worried it will cause issues. Contains 'green" but if there is a marker called "green_clover_01:0002222" it would false trigger. I have noticed that markers sometimes print with #@ or @#. I'm not sure if it's the processing I have done to the string that has caused that tho. I like the idea of using colors as a denomination, it takes up a lot of space on the token but the statuses will be printed on each turn anyway so I doubt it matters too much.
Hi, I wonder if someone could help me debug an issue that I am currently having retrieving values from an object in a 5e by Roll20 Character Sheet. Here is an example code snippet.  In the actual code, I am retrieving the currentSource dynamically. !script{{ --title|Wand Charges --#sourcetoken|@{selected|token_id} --&charID|@{selected|character_id} --&currentSource|repeating_resource_$0_resource_left --=currentCharges|[*O:[&charID]:attribute:[&currentSource]] --=maxCharges|[*O:[&charID]:attribute:[&currentSource]_max] --+Seeker Wand Charges|[$curCharges.Text] / [$maxCharges.Text] }} I intend to set up the script to be able to eventually be used to check if charges are either maxed out, or are down to 0 before applying an effect that would either use or boost the charges.  I have tried several variants of * references to try to retrieve the data, but I always seem to get an empty string for the currentCharges, and "false" for the max charges, although those values are currently 3 and 7 respectively on that character sheet
Hey Lawrence, For that section of the 2014 5e sheet I recommend using Lib5E_FIND_RESOURCE from Kurt's 5e library . Make a handout, change the name to ScriptCards Library 5eLib, copy that raw github output into the Description & Notes section, and then you can add +++5eLib+++ to your ScriptCard and use those functions.  Wiki link to Library section Also  Nick Olivo has a video on ScriptCard libraries  if you haven't used them before. Once you have the library handout created, your ScriptCard above would look more like: !script {{ --&ResourceName|WandName +++5eLib+++ --#title|Wand Charges --#sourcetoken|@{selected|token_id} -->Lib5E_FIND_RESOURCE|[*S:character_id];[&ResourceName];ResName;ResValue --+Seeker Wand Charges|[$ResValue.Text] / [*S:[&ResValue]^] }} where you'd change the top line to set the string variable &ResourceName to whatever the name of your wand's resource is. Using that library will search for the name in that section where the top 2 resources are standard attributes with names like class_resource and other_resource and the other resources are repeating attributes with names like repeating_resource_-MyVdiK6ZDROJtMHGdfs_resource_left. Let me know if you have any questions.
1726928932
timmaugh
Pro
API Scripter
Tristan P. said: Has anyone managed to get a "status marker tracker" working? I have one that works fantastic in my opinion but it has one MAJOR issue, token markers over counter 9 (green@9) do NOT display on token, they DO still exist on the token and I can decrement normally but the token will not be displayed until the counter has hit 9 or lower. My immediate thought is to add another identical counter through custom markers (that has a different name) to the token but strip all numbers but the last number and simply use that token? I haven't tried decrementing multiple tokens, maybe displaying multiple markers to represent digits similar to the Fly api? I'm worried I'll be running too much code and slowing my game down. Hey Tristan... just to throw one possibility at you... I don't know if ScriptCards takes advantage of (and exposes to you) the ability to put multiple instances of the same marker on a token the way TokenMod does, but if so, Fetch offers a construction to get all of the values as if they were a single number (100s place, 10s place, and 1s place). For instance, for the selected token's "blue" markers, you could use: @(selected.status.blue?all) You can use other token references other than selected, and obviously other token names. Again, not sure if ScriptCards offers the functionality itself to implement multiple copies of the same marker, or if you have to use TokenMod, but here is how TokenMod might do it: !token-mod --set statusmarkers|-blue[]|blue[]:2|blue[]:4|blue[]:2 So you'd just have to segment your value over various powers of 10 in the application, removing all "blue" markers that were there, first. This comes with the caveat that metascripts run before ScriptCards, so you can't use ScriptCards to generate/modify the value IN THE SAME MESSAGE where you want to use the Fetch construction to read the concatenated value. If you use the Fetch construction in *that* message, it will process first, before ScriptCards has time to work. But you could use reentrant syntax. Or you could set the value using one scriptcard call, and then use the Fetch construction anywhere you needed to later refer to that new value (as shown in the image, simply appending it to a string message output to chat).
Joshua N. said: Hey Lawrence, For that section of the 2014 5e sheet I recommend using Lib5E_FIND_RESOURCE from Kurt's 5e library . Make a handout, change the name to ScriptCards Library 5eLib, copy that raw github output into the Description & Notes section, and then you can add +++5eLib+++ to your ScriptCard and use those functions.  Wiki link to Library section Also  Nick Olivo has a video on ScriptCard libraries  if you haven't used them before. Once you have the library handout created, your ScriptCard above would look more like: !script {{ --&ResourceName|WandName +++5eLib+++ --#title|Wand Charges --#sourcetoken|@{selected|token_id} -->Lib5E_FIND_RESOURCE|[*S:character_id];[&ResourceName];ResName;ResValue --+Seeker Wand Charges|[$ResValue.Text] / [*S:[&ResValue]^] }} where you'd change the top line to set the string variable &ResourceName to whatever the name of your wand's resource is. Using that library will search for the name in that section where the top 2 resources are standard attributes with names like class_resource and other_resource and the other resources are repeating attributes with names like repeating_resource_-MyVdiK6ZDROJtMHGdfs_resource_left. Let me know if you have any questions. Hi Joshua, Thank you for your help.  I am actually using code taken from that library and modified to find and return the value that I am using for "currentSource".  What I am doing is to return that to the calling code, and then work with the value and the max individually. However, your suggested code made me look at some alternatives, and I got the following to work: !script{{ --title|Wand Charges --#sourcetoken|@{selected|token_id} --&charID|[*S:character_id] --&currentSource|repeating_resource_$0_resource_left --=curCharges|[*[&charID]:[&currentSource]] --=maxCharges|[*[&charID]:[&currentSource]^] --+Seeker Wand Charges|[$curCharges.Text] / [$maxCharges.Text] }} I am not sure why [*S:character_id] worked, where @{selected|character_id} didn't, but I also found that I could get the code to work with the * object_id: syntax. I also had missed that "_max" was unreliable, and the substitution of ^ did the trick there.
Question. Using the 5E Sheet - testing the ScriptCard Libraries functions. I loaded the dnd5elib and was using the Lib5E_DeductSpellSlot function to deduct a LVL 1 slot however the function bumps up the slots_expended by two(??? see the code) and the sheet show a plus 2 amount in slots remaining which is incorrect. Is there a character attribute that corresponds to the "slots" remaining" field? It looks like "slots_expeneded" is tied to slots remaining which is weird. Could be me! !script {{ +++dnd5elib+++ --Lsettings|@{selected|token_name} --#title|Update Spell Slot --#emoteState|1 --#sourceToken|@{selected|token_id} --&CharID|@{selected|character_id} -->Lib5E_DeductSpellSlot|@{selected|character_id};1 }}
1727790917

Edited 1727791006
I was going to post this in the Working and Sharing forum, but it aged out. This script creates a hashtable of all of the characters in the journal, with their name as the keys, and their ID as the value, allowing you to look up character IDs by name. It checks the journal folder for all objects in the journal, then scans through those objects for ones with an ID that starts with a - (required for a valid object ID).  If it appears to have a valid object ID, then it  checks if it has a type of "character".  If an object is a character, it then gets the name and adds the character and its ID to the hash table.  Once it has finished checking all objects, it then stores the hashtable in persistent storage for later use. !script {{ --&folders|[*C:journalfolder] --~|array;fromstring;objArray;,;[&folders] --=testValue|1 --%curItem|foreach;objArray --=itemIndex|[&curItem(indexof,-)] --?[$itemIndex] -ge [$testValue]|[ --~curItem|string;after;-;[&curItem] --~curItem|string;before;";[&curItem] --&curType|[*-[&curItem]:type] --?[&curType] -eq character|[ --&curName|[*O:-[&curItem]:character:name] --h:fullCharList("[&curName]")|-[&curItem] --]| --]| --%| --s:|fullCharList }} to retrieve the hash table, add this line to your script: --l:|fullCharList You can then look up character IDs with code like this: --&curChar| <a character name> --&charID| [:fullCharList("[&curChar]")] One problem that I still have with this script is that it throws an error into the API for each object that isn't a character, although none of them cause the script to fail. This script uses the ScriptCards persistent storage function, so you need to have a " ScriptCards_Storage" character in your game to persist the index
1728843705

Edited 1728844459
I'm playing with Jumpgate right now and just a heads up, it looks like Scriptcards are working, but sub-routines do not: This works! !scriptcard  {{   --#title|Quarterstaff   --#sourceToken|@{selected|token_id}   --#targetToken|@{target|token_id}   --#emoteText|@{selected|token_name}   --=TestRoll|1d20   --+Test Roll|[$TestRoll] }} This is broken: !scriptcard  {{   --#title|Quarterstaff   --#sourceToken|@{selected|token_id}   --#targetToken|@{target|token_id}   --#emoteText|@{selected|token_name}   -->MakeRoll|   --X|     --:MakeRoll|         --=TestRoll|1d20         --+Test Roll|[$TestRoll]     --<| }} ***Update*** I was wrong! It was the --X| that was breaking the script - not the subroutine, the following does work: !scriptcard  {{   --#title|Quarterstaff   --#sourceToken|@{selected|token_id}   --#targetToken|@{target|token_id}   --#emoteText|@{selected|token_name}   -->MakeRoll|     --:MakeRoll|         --=TestRoll|1d20         --+Test Roll|[$TestRoll]     --<| }} Let me know if this should be reported as a bug.  I'm not sure what else is broken yet, but I'm going to try to write some automated attacks and spells to work with 5e 2024 and Jumpgate. Thanks to scriptcards my combat encounters are insanely fast, which allows me to run games with more people, and I can't see myself going on without them. To get 2024 content, I'd rather disable the character mancer, than go without scriptcards. I have a ton of rolls premade  here , which are setup to be easily modified, in case you want to check out what I've made in the past.
1728945964

Edited 1728957605
Alright I'm making a lot of progress and I got some rolls working with 2024 sheets and Jumpgate!  --X| works today, when it didn't yesterday, so I'm not sure what changed there... Something I learned: @{target|npc_ac} no longer works and using it throws an error in the console,   sheet.js:659 Uncaught TypeError: Cannot read properties of undefined (reading 'attributes')     at Object.vdr [as convertLegacyMacroAttributes] (sheet.js:659:17190)     at l.onmessage (sheet.js:431:31540) but can be changed to @{target|ac}
Alright - I've worked out some of what's broken, and hit a point where I probably won't be using Jumpgate to run my next game .  Built in function to create an array of all the page tokens is totally broken - meaning AOE spells wont work: --~|array;pagetokens;alltokens 'alltokens' variable is now undefined and attempts to loop through it fail. I confirmed Kurt Jaegers Fireball example which relies on this also does not work. The following attributes appear to no longer exist, all throw errors when used except spellcasting_ability: npc_ac (replace with just 'ac' to fix) npc_vulnerabilities,  npc_resistances,  npc_immunities,  spellcasting_ability Bonus problem - it appears all tokens of the same image/sheet have the same token Id now, so using the TokenMod to auto-apply damage from the script, applies that damage to all of the tokens with the same sheet / image - see below, both the Kobold tokens on the right took the 2 damage, even though only one target was selected:
1728987838
Kurt J.
Pro
API Scripter
Michael O. said: Alright - I've worked out some of what's broken, and hit a point where I probably won't be using Jumpgate to run my next game .  Built in function to create an array of all the page tokens is totally broken - meaning AOE spells wont work: --~|array;pagetokens;alltokens 'alltokens' variable is now undefined and attempts to loop through it fail. I confirmed Kurt Jaegers Fireball example which relies on this also does not work. The following attributes appear to no longer exist, all throw errors when used except spellcasting_ability: npc_ac (replace with just 'ac' to fix) npc_vulnerabilities,  npc_resistances,  npc_immunities,  spellcasting_ability Bonus problem - it appears all tokens of the same image/sheet have the same token Id now, so using the TokenMod to auto-apply damage from the script, applies that damage to all of the tokens with the same sheet / image - see below, both the Kobold tokens on the right took the 2 damage, even though only one target was selected: Not sure what you are running into here, but in my test Jumpgate game, all of this is working as expected (including the --X|): !script {{   --+TokenID|@{selected|token_id}   --#sourcetoken|@{selected|token_id}   --+Name|[*S:t-name]   --+npc_ac|[*S:npc_ac]   --+npc_vulnerabilities|[*S:npc_vulnerabilities]   --+npc_resistances|[*S:npc_resistances]   --+npc_immunities|[*s:npc_immunities] }} For the HP getting updated on all tokens, if the HP bar is linked to the HP attribute, then yes - modifying it will modify all tokens that are also linked. The HP bar should not be linked on the token. Are you attempting to use the 2024 sheet? If so, absolutely *nothing* should be working because none of the attributes have been exposed from Beacon at this time.
Yes --X| was causing cards to fail for at least two days, but seems to be working now. Using npc_ac results in an error in the Google Console: sheet.js:659 Uncaught TypeError: Cannot read properties of undefined (reading 'attributes')     at Object.Adr [as convertLegacyMacroAttributes] (sheet.js:659:17190)     at l.onmessage (sheet.js:431:31540) For resist/vuln:  Note  I'm using *T not *S, but here's the API error output (from Scriptcards): "Error: No attribute or sheet field found for character_id -O95bVPpPSLJjX1prLih named npc_resistances" "Error: No attribute or sheet field found for character_id -O95bVPpPSLJjX1prLih named npc_immunities" "Error: No attribute or sheet field found for character_id -O95bVPpPSLJjX1prLih named npc_vulnerabilities" Spellcasting_ability doesn't throw an error, but the value is null, using a wizard token. As far as the token ID issue - I ran a test - clicking each token and outputting the associated token ID. Same image/sheet => same token ID. I am not using any sheet attributes for the bars.
I think this post explains my problems: <a href="https://app.roll20.net/forum/post/12099109/mod-api-issues-in-jumpgate-w-slash-tokens/?pageforid=12099217#post-12099217" rel="nofollow">https://app.roll20.net/forum/post/12099109/mod-api-issues-in-jumpgate-w-slash-tokens/?pageforid=12099217#post-12099217</a>
Some of the Visual effects no longer work once I switched to Jumpage. Still work manually, but not in Scriptcards. For example: &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} beam-fire Works fine, but &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} rocket-fire or &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} custom does not. Any ideas?
1730107293
Kurt J.
Pro
API Scripter
Kaspar K. said: Some of the Visual effects no longer work once I switched to Jumpage. Still work manually, but not in Scriptcards. For example: &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} beam-fire Works fine, but &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} rocket-fire or &nbsp;&nbsp;--vbetweentokens|@{selected|token_id} @{target|token_id} custom does not. Any ideas? Are you certain you are on the ribbon page? And are you using the 2024 sheet? If so, @target doesn't work at all. I have not made changes to ScriptCards yet for Jumpgate and/or the 2024 sheet because they are both in such a poor state both functionality-wise and from a documentation standpoint. I'm waiting until they have ironed out some of the issues before looking into required coding changes.
Me again, with another brain teaser! Is there a way to transfer a repeating row from one character to another using Scriptcards and the !or or hash commands? I'm trying to move an item from a shared party loot character to a PC.&nbsp; Thanks!
1733834840
Kurt J.
Pro
API Scripter
Erik M. said: Me again, with another brain teaser! Is there a way to transfer a repeating row from one character to another using Scriptcards and the !or or hash commands? I'm trying to move an item from a shared party loot character to a PC.&nbsp; Thanks! It should be possible with --!or, but it would be a little messy. You would have to get references to each of the source values in the same line. Let me think about this, as I might be able to streamline it.
1734876069
Kurt J.
Pro
API Scripter
ScriptCards 2.7.31 Queued for One Click A new update for ScriptCards is queued for OneClick and just waiting on Roll20 to update the mod library. Here is a summary of the changes since 2.7.29a: New function group : "roll". one subfunction for now: setrollhighlight, which will set the highlight color for a roll variable. The syntax is: &nbsp; --~|roll;setrollhighlight;Roll Var Name;identifier Where roll var name is the case sensitive name of the roll variable and identifier is one of: none, crit, fumble, both Code standardization and cleanup , slight performance improvements When using --!t you can prefix the property names with t- or T- and they will be mapped to the right values. This requires no code changes and is simply for convenience. Added a log message if you try to set imgsrc to a marketplace image, as this isn't supported by Roll20 thru the API Bug fix for --!ot : when the property value has a | in it. Like values with a :, the value should be in double quotes. When setting the sides property through --!ot:, each side image will be checked for Roll20 validity (requires a ?... at the end) Added the ability to create graphic objects (tokens, maps, etc.) with --!ot:. The syntax for this is: --!ot:ReturnTID|Property1=Value1|Property2=Value2;... If a property value contains (or could contain) a colon (:) character, enclose it in double quotes ("). Numeric values will be checked for validity and assigned 0 if the passed value is not convertable to a number (ie, left=HELLO will result in left=0). Boolean values will be converted from "true", "yes", "on", or "1" to true and will otherwise be false. A handful of graphic properties, if not specified will have defaults: &nbsp; subtype = token &nbsp; layer = objects &nbsp; pageid = current player ribbon page &nbsp; left = 200 &nbsp; top = 200 &nbsp; width = 70 &nbsp; height = 70 Example: copy a token and place it 1 square to the right of the selected token (does not copy ALL properties, just the ones specified): !script {{ &nbsp; --&amp;sourceTID|@{selected|token_id} &nbsp; --#sourcetoken|[&amp;sourceTID] &nbsp; --!ot:NewTID|name:"[*S:t-name] Copy"|left:[=[*S:t-left]+70]|top:[*S:t-top]|width:[*S:t-width]|height:[*S:t-height]|imgsrc:"[*S:t-imgsrc]"|tooltip:"[*S:t-tooltip]"|bar1_value:"[*S:t-bar1_value]"|bar1_value:"[*S:t-bar1_value]"| bar1_max:"[*S:t-bar1_max]"| bar2_value:"[*S:t-bar2_value]"| bar2_max:"[*S:t-bar2_max]"| bar3_value:"[*S:t-bar3_value]"| bar3_max:"[*S:t-bar3_max]"|bar1_link:[*S:t-bar1_link]|bar2_link:[*S:t-bar2_link]|bar3_link:[*S:t-bar3_link]|represents:[*S:t-represents]|controlledby:[*S:t-controlledby]|showname:1|statusmarkers:[*S:t-statusmarkers] &nbsp; --+TID|[&amp;NewTID] }} Added the "object" function class , which right now has one subfunction and one operation for that subfunction - the deletion of tokens: &nbsp; --~|object;token;delete;tokenid1;tokenid2;... If used, a log entry will be written to the console stating the player that deleted to token and the token id. Added initial testing for "Beacon" character sheets by modifying the [*...] code to allow nested name references. For example, the Candela Obscura character sheet defines an attribute named "role" which looks like this internally: {"name":"role","current": &nbsp; {"role":{"description":"","name":"Face"}, &nbsp; &nbsp;"specialty":{"description":"","name":"Magician"} }, "max":"","_id":"-O4tZZXLjeIL3uex_74R","_type":"attribute","_characterid":"-O4tZTQ4Cyb5rBB5M0Wj"} So "role" contains two entities: role and specialty. Each of these contains two items: description and name. To access the name of the role, you would use [*S:role-&gt;role-&gt;name], while to access the name of the specialty, you would use [*S:role-&gt;specialty-&gt;name]. This will return "Face" and "Magician" respectively. This can be used in any [*...] reference, so you can use it in a --+ line, etc. Here is an example of a script that will display the role and specialty of the selected token:&nbsp; !script {{&nbsp; &nbsp; --#sourcetoken|[@SC_SelectedTokens(0)] &nbsp; --+Role|[*S:role-&gt;role-&gt;name] &nbsp; --+Specialty|[*S:role-&gt;specialty-&gt;name] }} If the field(s) you are specifying don't exist, you will likely get either "undefined" (if the base attribute doesn't exist) or "Object.object" (if one of t he fields doesn't exist). Ex: [*S:role-&gt;focus-&gt;name] will return "Object.object" if the "focus" field doesn't exist in the "role" attribute, while [*S:superpower-&gt;name] will return "undefined" if the "superpower" attribute doesn't exist. Updated the code that separates tags from content to allow for | characters to be used by escaping them with a double backslash (\\). Any \\| sequence will be replaced with a | character. Added two new conditional operators : -match and -imatch, which accept Regex as the right side of a comparison. Use \\| to escape the | character in the regex. The -match operator is case sensitive, while -imatch is case insensitive. A few examples: --?"[&amp;name]" -match "(Medusa\\|Fred\\|Pixie)"|+Yes|+No &nbsp; Will be true if the [&amp;name] variable has "Medusa", "Fred" or "Pixie" in it (case sensitive) --?"[&amp;name]" -imatch "^(Medusa\\|Fred\\|Pixie)"|+Yes|+No &nbsp; Will be true if the [&amp;name] variable starts with "Medusa", "Fred" or "Pixie" (case insensitive) &nbsp; --?"[&amp;name]" -imatch "^a.*n$"|+Yes|+No &nbsp; Will be true if the [&amp;name] variable starts with "a" and ends with "n" (case insensitive) (ex: Ancient Red Dragon, Aragorn, etc.)&nbsp; &nbsp; --?[$Roll.Raw] -match "^[1-2]$"|+Yes|+No &nbsp; Will be true if the roll is a 1 or a 2 (won't match 12, or 20, etc because the 1 or 2 has to be the first AND last character) &nbsp; Regex values should be enclosed in quotes. If you want to actually look for a literal | in your regex, use \\\| (the first \ is included in the regex to escape the |, which will be the result of \\|)
Hi everyone, I've got a really weird issue with Information Requests and Targeting. For the seek of testing I'm using this simple code here !script{{ --INeed more infos;Click|t;MyNewTarget;Target --#targetToken|[&amp;MyNewTarget] --+DEBUG ttoken|[&amp;MyNewTarget] --+DEBUG Target id|[*T:character_id] --+DEBUG Target name|[*T:character_name] }} Now, if i run this into a PF1 (community) game everything goes just fine as expected. An example is below But if I run the very same script ina PF2 (Roll20 ed) game...it gets quite weird No matter which token I target, I always get the same ID you can see in the picture. I don't know what that ID is, but it's not a Character ID for sure. Just to be clear...I get this very same ID if I run the script and try to target ANY token! Is there anything wrong with PF2? I'm getting quite desperate, can't think of anything that could cause this. Thanks!
1736096652
Kurt J.
Pro
API Scripter
Valerio I. said: Hi everyone, I've got a really weird issue with Information Requests and Targeting. For the seek of testing I'm using this simple code here !script{{ --INeed more infos;Click|t;MyNewTarget;Target --#targetToken|[&amp;MyNewTarget] --+DEBUG ttoken|[&amp;MyNewTarget] --+DEBUG Target id|[*T:character_id] --+DEBUG Target name|[*T:character_name] }} Now, if i run this into a PF1 (community) game everything goes just fine as expected. An example is below But if I run the very same script ina PF2 (Roll20 ed) game...it gets quite weird No matter which token I target, I always get the same ID you can see in the picture. I don't know what that ID is, but it's not a Character ID for sure. Just to be clear...I get this very same ID if I run the script and try to target ANY token! Is there anything wrong with PF2? I'm getting quite desperate, can't think of anything that could cause this. Thanks! Is your PF2 game using Jumpgate? I know jumpgate used to have issues with this kind of thing. Don't know if it was ever fixed.
1736111895

Edited 1736112045
vÍnce
Pro
Sheet Author
I mentioned this in a PF2e thread ;&nbsp; I was able to use Valerio's test script and get the proper token info using either sheet.&nbsp;(PF1 Community and PF2e Official)&nbsp; I also tested in legacy and jumpgate.
1736780469

Edited 1736804228
Tristan P. said: I have made a D&amp;D 3.5 (AD&amp;D 2e works too) and PF1e&nbsp; non-euclidean distance card, hopefully it will be useful for someone else! It uses the #sourceToken/#targetToken to work. It now counts from the closest edge of tokens and with my testing works with all sized tokens! Seriously useful! Thanks for this! I had a simpler script that I thought was working, but then I tried with larger tokens and realised it was only working from the center of the token, and that it was incurring errors (probably rounding) when tokens got larger. This is exactly what I needed. Edit : After testing this for a bit, there seems to be issues with source tokens that are 3x3 or 5x5. 1x1, 2x2, 4x4 all seem good. But for 3x3 and 5x5 the distance is over estimated in many cases. But even then, that seems to be dependent on target size. For example a 3x3 measuring a 1x1 that is 10' away, shows 20'. But make that 1x1 a 2x2 and keep it the same 10' away (in the same direction) it measures the correct distance.&nbsp;
1736811181

Edited 1736811660
Sir you are correct! The issue is Jumpgate! I tryed it in a PF2e without it and it works just fine. Also, I've ported my PF1 (community) game into Jumpgate and...it deleted EVERY single item in my library in the "Legacy Backup"game, no characters, no handouts, nothing...4 years of playing throwed right out the window...thank you "out of beta Dumbgate"!!! Thank you very much... Transmogrifier won't work, as it cannot copy things between Jumpgate and non-Jumpgate games so even if I tried to create a new "non Jumpgate" game I cannot copy items. I know it's not the right place to complain..but...I've lost over 100 maps when "map folders" were created and now I lose all my characaters, NPCs, handouts with jumpgate...it's SO frustrating... Kurt J. said: Is your PF2 game using Jumpgate? I know jumpgate used to have issues with this kind of thing. Don't know if it was ever fixed.
1736815145
vÍnce
Pro
Sheet Author
Valerio I. said: Sir you are correct! The issue is Jumpgate! I tryed it in a PF2e without it and it works just fine. Also, I've ported my PF1 (community) game into Jumpgate and...it deleted EVERY single item in my library in the "Legacy Backup"game, no characters, no handouts, nothing...4 years of playing throwed right out the window...thank you "out of beta Dumbgate"!!! Thank you very much... Transmogrifier won't work, as it cannot copy things between Jumpgate and non-Jumpgate games so even if I tried to create a new "non Jumpgate" game I cannot copy items. I know it's not the right place to complain..but...I've lost over 100 maps when "map folders" were created and now I lose all my characaters, NPCs, handouts with jumpgate...it's SO frustrating... Kurt J. said: Is your PF2 game using Jumpgate? I know jumpgate used to have issues with this kind of thing. Don't know if it was ever fixed. That's crazy.&nbsp; Contact roll20 ASAP!&nbsp; They still might have a way to restore your data.
1736995104

Edited 1737548574
vÍnce said: That's crazy.&nbsp; Contact roll20 ASAP!&nbsp; They still might have a way to restore your data. Thanks to Vince and Kurt for your answers! Done, they said they are aware of the "targeting issue" and they are hoping to release a fix within the next two weeks. About this issue, I've created a brand-new game PF2e (roll20) with jumpgate and there's no targeting issue at all. So it seems it could be more likely to affect larger games transitioning from "normal" to Jumpgate (that's what I inferred by their answer). About the lost items, NPCs, handouts etc...they said the "transition" may cause issues if the game is large. Well...had I known... They will try and recover what they can...I'm giving them a link to the game. Let's hope for the best. Other than that...I've got a new ScriptCards related question now, sorry to bother you again: So, I've got an attribute with some sort of Sheet reference in it. For the sake of simplicity let's say I have an attribute named "damage_dice" and inside that attribute there's something like "[[@{level}d8]]". The sheet works just fine, as expected, computing the number of dice dinamically with levels if I press the attack button. But if I try and get that value with ScriptCards using [*S:damage_dice] I get an "Array reference error" from ScriptCards. I assume ScriptCards tries to read "[@" as an array reference. Now, what I would like to do is reading "[[@{level}d8]]" as a string, just as it is (I don't need actually to resolve @{level}, just to be clear} because I'm trying to copy that simple "formula" into another CharacterSheet, and not the actual "level" value. Is there a way to tell ScriptCards to consider [*S:damage_dice] content as a pure text? EDIT: hello everyone. I have some news about my attempt to read the variable with @[ in it. Kurt was very kind, he explained to me that at the moment it is not possible to read elements with formulas inside them. So in general if you have an attribute on your character sheet that contains the sequence [@ it will be impossible for ScriptCards to read the string without attempting to interpret or resolve it.
1738493507
Andrew R.
Pro
Sheet Author
I've been trying to eliminate a call to TokenMod from my ScriptCards script that sets the Daunted status on a The One Ring 2e Character Sheet and sets a suitable Token Marker too. I got it to work tonight, so I'm posting it here as a simple example. !scriptcard {{ --/| Daunted --#debug|0 --#emoteState|invisible --#hidecard|0 --#hideTitleCard|1 --#sourcetoken|@{selected|token_id} --&amp;DAUNTED|"Frightened::243695" --&amp;PLAYERHERO|[*S:t-name] --+|[&amp;PLAYERHERO] is Daunted! --!a:[*S:character_id]|daunted:1 --!t:[*S:t-id]|statusmarkers:[&amp;DAUNTED] }}
1739453771
Kurt J.
Pro
API Scripter
Andrew R. said: I've been trying to eliminate a call to TokenMod from my ScriptCards script that sets the Daunted status on a The One Ring 2e Character Sheet and sets a suitable Token Marker too. I got it to work tonight, so I'm posting it here as a simple example. !scriptcard {{ --/| Daunted --#debug|0 --#emoteState|invisible --#hidecard|0 --#hideTitleCard|1 --#sourcetoken|@{selected|token_id} --&amp;DAUNTED|"Frightened::243695" --&amp;PLAYERHERO|[*S:t-name] --+|[&amp;PLAYERHERO] is Daunted! --!a:[*S:character_id]|daunted:1 --!t:[*S:t-id]|statusmarkers:[&amp;DAUNTED] }} This will do the job, but if there are other status markers on the token they will be removed and only Daunted will remain. The systemneutrallib on the github contains functions to check for, add, remove, and increment/decrement counters on status markers individually if you need to preserve other markers
1739492951
Andrew R.
Pro
Sheet Author
Thanks! I haven’t used the library yet, so that’s an incentive.&nbsp;
Hi, Hoping someone can help.&nbsp; I'm trying to get a scriptcard output to display the tooltip text of a selected token. I have this entry in the scriptcard but it doesn't work&nbsp; &nbsp; --+Conditions|@{selected|t-tooltip} Any ideas what I'm doing wrong ? Cheers
I have been streaming 2d6 Dungeon and have been using ScriptCards to makes things easier for myself...also to give myself practice on more advanced scripcard usage. And I have come upon a bit of a conundrum. Let me me give you the conceptual set up and some code and then the conundrum. I want to have a button that executes script and also passes along information so the script can work...I figured out how to do this in one context, but not another. 2d6 Dungeon has lots and lots of Oracle tables, some are 1d6, some are 2d6, some are d66. Some take mods, some don't.&nbsp; My goal with my coding was to try and not be super repetitive--reusability! I am currently using hash-tables, macro mules, and the ScriptCards_Storage Mule rather than libraries...though I image it would be fine to move to libraries as well it that would work better. Let's go backwards.&nbsp; Knowing that I would need to roll dice in other games and contesxts as well, I set up a general macro mule that would hold things useful regardless of the game I'm playing. That one is called SC_SetUp.&nbsp; It has the following relevant macros-- z-fantasy-format (This is just formatting stuff for the cards, I also have z-space-format and will probably build more over time. It isn't a full script card because I think of it as a subroutine for other scriptcards.) &nbsp; --#titleCardBackground|#eae1d3 &nbsp; --#titleFontFace|IM Fell DW Pica &nbsp; --#titleFontColor|#f00 &nbsp; --#titleFontSize|2em &nbsp; --#subtitleFontColor|#000 &nbsp; --#bodyBackgroundImage|url('<a href="https://i.imgur.com/RxSjMBr.png" rel="nofollow">https://i.imgur.com/RxSjMBr.png</a>'); background-size: 100% 100%; background-repeat: no-repeat; lineheight: 1.5em; &nbsp; --#bodyFontFace|IM Fell DW Pica &nbsp; --#bodyFontSize|1.7em &nbsp; --#evenRowFontColor|#b50000 &nbsp; --#oddRowFontColor|#b50000 &nbsp; --#evenRowBackground|#eae1d3 &nbsp; --#buttonBackground|#f00 &nbsp; --#buttonFontFace|IM Fell DW Pica &nbsp; --#buttonFontColor|#fff &nbsp; --#buttonFontSize|1.2em &nbsp; --#buttonPadding|2px The next relevant macro in SetUp is z-Xd6-loop . (I use my own images for the dice that are in rollable tables, so this macro rolls however many dice are specified and builds the images and base output and so on. There is the option to deal with a modifier, but that is set in the calling macro. When this subroutine is done, the important updates variables will be &amp;DieOutput, &amp;Ref, and) &nbsp; --:String Building Vars | Will store table graphics. Pre-pend opening format tag &nbsp; &nbsp; --&amp;DieOutput | +[c] &nbsp; --%LoopCounter | 1;[$NumDice];1 &nbsp; &nbsp; --=ThisRoll | [T#D6-Red] &nbsp; &nbsp; --=Total | [$Total] + [$ThisRoll.tableEntryValue] &nbsp; &nbsp; --&amp;DieOutput | + [img width=55][$ThisRoll.tableEntryImgURL][/img] &nbsp; --%| &nbsp; &nbsp; --?[$Mod] -eq 0 | [ &nbsp; &nbsp; &nbsp; &nbsp; --&amp;Result | [c][b][$Total.Raw] &nbsp; &nbsp; &nbsp; &nbsp; --&amp;Ref | [$Total.Raw] &nbsp; &nbsp; --]|[ &nbsp; &nbsp; &nbsp; &nbsp; --=Final | [$Total] + [$Mod] &nbsp; &nbsp; &nbsp; &nbsp; --&amp;Result | [c][b][$Total.Raw] + [$Mod.Raw] = [$Final.Raw] &nbsp; &nbsp; &nbsp; &nbsp; --&amp;Ref | [$Final.Raw] &nbsp; &nbsp; --]| Here is the final relevant subroutine in SetUp, z-die-output , which plays a die rolling sound and outputs the die results. &nbsp; --:Output Main Dice | But first append closing format tag &nbsp; &nbsp; --&amp;DieOutput | +[/c] &nbsp; &nbsp; --a | DiceRolling &nbsp; &nbsp; --+ | [f10][br][/f] [&amp;DieOutput][f10][br][/f]&nbsp; &nbsp; &nbsp; --+ | [&amp;Result] Next up is the Macro Mule that has all the specific stuff for 2d6Dungeon, called SC_2d6Dungeon. There are a LOT of Oracles that vary by level and on and on. So I have some macros that just hold hash tables of those Oracles that are then loaded into ScriptCards_Storage. For this example, the relevant macro is hash-2d6dungeon-loot . It currently only has 2 tables in it...but there are many, many more to add, slowly over time. !script {{ &nbsp; --~|array;define;LootTables;SECT2;SLT2 &nbsp; --s@|LootTables &nbsp; --/|SECT2 -Secret Hatch Table 2 &nbsp; --h:SECT2("Title")|SECT2 - Secret Hatch Table 2 &nbsp; --h:SECT2("Desc")|You slide the hatch open and… &nbsp; --h:SECT2("2")|There is an empty hollow. It has been robbed already. &nbsp; --h:SECT2("3")|You see two imprints in the dust where a couple of items once stood. It's empty. &nbsp; --h:SECT2("4")|For some reason there is a pile of sand here. Nothing more. &nbsp; --h:SECT2("5")|There are two half burnt candles in the hatch next to a MQ Garnet. &nbsp; --h:SECT2("6")|There is a small, gold embossed book inside. It appears to be a religious text worth 2D6 GC. &nbsp; --h:SECT2("7")|There is a silver candle stick here worth 8D6 SC. It is a large item. &nbsp; --h:SECT2("8")|There is a box here. Inside it are some items including a fang and a dragon scale. &nbsp; --h:SECT2("9")|Inside you find a cobweb covered Potion of Further Health. &nbsp; --h:SECT2("10")|There is some silver and gold jewellery shoved in here worth 10D6 SC and 2D6+20 GC &nbsp; --h:SECT2("11")|Placed in the centre, in a glass casket is a rune stone. Roll on RUNE2. &nbsp; --h:SECT2("12")|Inside is what appears to be a wand resting on a small pillow. Roll on MW1. &nbsp; --s:|SECT2 &nbsp; --/|SLT2 - Sarcophagus Loot Table 2 &nbsp; --h:SLT2("Title")|SLT2 - Sarcophagus Loot Table 2 &nbsp; --h:SLT2("Desc")|You peer inside and search around to find… &nbsp; --h:SLT2("2")|The inside seems as if it has been cleaned out. You find nothing. &nbsp; --h:SLT2("3")|There is a pile of bones at the foot of the tomb. &nbsp; --h:SLT2("4")|The rats have somehow made their way in. Their droppings are all that remain. &nbsp; --h:SLT2("5")| There is a long red robe here, and a scroll in a pocket. Roll on SCT3. &nbsp; --h:SLT2("6")|In a small box, at the head of the sarcophagus, are some Dankoma Stems. &nbsp; --h:SLT2("7")| There is a pouch here full of coins, 3D6 GC and 4D6 SC. &nbsp; --h:SLT2("8")|Lying clear to see on the stone base is a necklace lined with 4 MQ gems, roll on GMT1 -2. &nbsp; --h:SLT2("9")|Lying in amongst some bones and splinters is a rune stone. Roll on RUNE1. &nbsp; --h:SLT2("10")|A small stone statue of Nevazator is here. You can correctly make an offering and smash it for 1 FP. &nbsp; --h:SLT2("11")|Clenched in a bony fist is a rune stone. You prise the fingers open. Roll on RUNE2. &nbsp; --h:SLT2("12")|There is a discarded piece of armour here. It is surprisingly in good condition. Roll on ART3 -1. &nbsp; --s:|SLT2 &nbsp; --X | End Macro }} Everything is great so far.&nbsp; The next thing I did was create a subroutine to process 2d6 rolls that have modifiers but where the final result is constrained to 2-12. 2d6Mod-TableRoll I had to use the --i command for the Modifier query elsewise it would trigger as soon as the master macro was loaded...which I didn't want. This fixes that problem...but it does make me sad to have to use --i commands because I like the aesthetic of the rollquery better...oh well. Not the worst. This sets all the variables one needs for the Xd6 subroutine, adds any extra info you wouldn't have in a basic 2d6 roll, like the description of the table result from the hash table. I'll note that this assumes there is a variable called &amp;Table--which allows me to use this subroutine regardless of whatever table I'm thinking of. &nbsp; --:Initialize Roll Vars| &nbsp; &nbsp; --=NumDice | 2 &nbsp; &nbsp; --=Mod| 0 &nbsp; &nbsp; --=Total | 0 &nbsp; &nbsp; --&amp;Result |&nbsp; &nbsp; --iRegister Modifiers ;Click|q;Entry;Modifier? &nbsp; --=Mod| [&amp;Entry] &nbsp; %{SC_SetUp|z-Xd6-loop} &nbsp; --?[&amp;Ref] -lt 2 | &amp;Ref;2 | &nbsp; --?[&amp;Ref] -gt 12 | &amp;Ref;12 | &nbsp; --&amp;Result | +[br][:[&amp;Table]("[&amp;Ref]")][/b][/c] &nbsp; %{SC_SetUp|z-die-output} Finally, I have the Loot-Menu macro. This is the master macro that iterates through the array that lists all the loot tables, and makes an rbutton for each one. The rbutton sets the &amp;table Variable and then calls the first subroutine that calls the rest. !script {{ &nbsp;%{SC_SetUp|z-fantasy-format} &nbsp; --#title | Loot Tables &nbsp; --l@|LootTables &nbsp; --&amp;Table| &nbsp; --&amp;Output| [t width=100%] &nbsp; --=Col|1 &nbsp; --#reentrant|LootM &nbsp; --%loop|foreach;LootTables &nbsp; &nbsp; --?[$Col] -eq 1 | [ &nbsp; &nbsp; &nbsp; --&amp;Output|+[tr][td][rbutton][&amp;loop]::TABLE_SET;[&amp;loop][/rbutton][/td] &nbsp; &nbsp; &nbsp; --=Col|[$Col] +1 &nbsp; &nbsp; --] | [ &nbsp; &nbsp; &nbsp; --&amp;Output|+[td][rbutton][&amp;loop]::TABLE_SET;[&amp;loop][/rbutton][/td][/tr] &nbsp; &nbsp; &nbsp; --=Col|[$Col] -1&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; --] | &nbsp; --%| &nbsp; --&amp;Output| +[/t] &nbsp; --+|[&amp;Output] &nbsp; --:|Done &nbsp; --X| &nbsp; --:TABLE_SET| &nbsp; &nbsp; --&amp;Table| [&amp;reentryval] &nbsp; &nbsp; --l:|[&amp;Table] &nbsp; &nbsp; --#title | [:[&amp;Table]("Title")] &nbsp; &nbsp; &nbsp;%{@{character_name}|2d6Mod-TableRoll} &nbsp; --^|Done }} Everything works perfectly and I am happy and this set up allows me to add as many new tables and everything is fine. Yay! Though if people have any fun tips to make this code better I'm certainly all ears. So what is the problem? The problem is...the first thing you do in this game is roll on a Room encounter Oracle...which I have all programmed and that works great too. A scriptcard is output with the description of the room and a description of the encounter which comes from a hash table of the room oracles. Some of those descriptions tell you to roll on other tables...for example, the loot table. What I wanted to do was to have the named table be a button to press which then checks that table. And here is where I've come upon my problem. Here is one entry on the Normal Room Oracle: !script {{ &nbsp;--/|L4R - Level 4 Rooms - Human Ancestry - The Haunted &nbsp; --h:L4R("11-Type")|Ornate Tomb &nbsp; --h:L4R("11-Desc")|There is an ornate sarcophagus in this space. The surface is covered in runes. &nbsp; --h:L4R("11-Encounter")|Roll a d6: [roll][=1d6][/roll]. 1-4=The lid falls away and a corpse sits up. Roll on [sheetbutton]L4UN::@{character_name}::L4Patrol-Menu[/sheetbutton]. If you survive, roll on [sheetbutton]SLT2::@{character_name}::Loot-Menu[/sheetbutton] &nbsp; --h:L4R("11-Exits")|Archways &nbsp; --h:L4R("11-Unique")|No You can see that I turned the "Roll a d6" part of the description into a roll to make things quicker. Then I get into my trouble. I would like to have a button there that will just roll on my relevant table...but to do that in needs to pass along the table name parameter...but I can't see a way to do that with a sheet button. At the moment, I'm just calling the sheetbutton that brings up the menu of all the sheet buttons in that category (Patrol, Loot, etc)...which then requires the player to pick the actual loot table they are supposed to roll on. This works...but it inelegant. Is there some way to just pass that parameter along from the button in the hash table so I can bypass the menu? I haven't figured out how to do that--and I don't want to create a separate macro for each Oracle table...there are hundreds of them and that seems super inefficient. If there were a way to trigger the menu macro...but passing in the relevant &amp;Table name, thus bypassing actually making the menu and just going to the meat of the matter...that would do it...but I don't know how to make that work. Any ideas? Thought? Suggestions? Thanks in advance!
1739580587
Kurt J.
Pro
API Scripter
FFR said: Hi, Hoping someone can help.&nbsp; I'm trying to get a scriptcard output to display the tooltip text of a selected token. I have this entry in the scriptcard but it doesn't work&nbsp; &nbsp; --+Conditions|@{selected|t-tooltip} Any ideas what I'm doing wrong ? Cheers This is a mix of roll20 referencing and scriptcards referencing. @selected|tooltip} will return the tooltip from Roll20 before the execution. Using [*@{selected|token_id}|t-tooltip} would be the ScriptCards notation.
1739580779
Kurt J.
Pro
API Scripter
TrooperSJP said: *snip* Thanks in advance! It isn't really possible to pass data between scripts/macros. The storage stuff would seem an obvious choice at first glance, but you can't guarantee what order things will be executed in. My suggestion would be to build you code into a library, which is stored in a handout. Your scripts can include the library and call its function, so there is no duplication between scripts and if you update the library, all of your scripts benefit from the changes.