ScriptCards
1.0.0 is Live on the GIST Version 1.0.0 is here, and this is a big one. There were some things I wanted to get completed before officially calling this 1.0.0, hence the sequence of 0.0.x versions prior to this. I do have some plans for what is next (Referencing Roll20 Objects directly from a ScriptCards script), but the development pace will probably slow down quite a bit now that I've got most of what I was planning on implemented. That is, at least the development pace on the API script itself. See the Procedure Libraries section below :) Behind
the Scenes Implemented The Aaron’s API_Meta system with the name “ScriptCards”.
This is more of a troubleshooting feature than an actual usable feature of the
script. Removed the changelog from the comments portion of the
script itself, as it was growing very long. Replaced this with some general
information about ScriptCards scripts and a link to the Wiki page. Bug Fixes The “R” statement type (repeating section) will now be
recognized as either “R” or “r”. It is now possible to include the same roll variable
reference multiple times in a line (i.e., [$Roll.Total] [$Roll.Total] will now
work correctly). Previously the first use of the reference would work, and the
second and beyond would simply return the text of the reference. Cosmetic
Change In text output (The .Text property) for roll variables, the
"*" operator will now appear as "x" because the
"*" character was not being displayed properly in the tooltip for
rolls. This change is not applied to the RollText property. Pre-Defined
String Variables There are a handful of pre-defined string variables created
when a script is run to provide some potentially useful information based on
the player running the script: [&SendingPlayerID] – The object ID of the player running
the script
[&SendingPlayerName] – The Display Name of the player running the script
[&SendingPlayerColor] – The hex code for the color associated with the
player running the script
[&SendingPlayerSpeakingAs] – The entity (usually in “character|-idgoeshere”
format) that the player had selected from the Speaking As dropdown menu when
the script was run.
[&SendingPlayerIsGM] – Will be set to “1” if the player running the script
is a GM, and “0” if not. New
Statement Type: Case Statement (--C) The case statement (--c) allows you to specify a value to
test as the tag and a list of possible matches. These matches are case-insensitive.
Matching groups are separated with vertical bars and matches and their branch
labels are separated by a colon (:). Each match condition includes a branch
label that will be used if the test value matches the item. If none of the
values are matches, the script will simply proceed onto the next line. Both
direct and procedure branches are supported, and procedure branches can include
parameters as normal. Example: !script {{ --#title|Case Statement Testing --=Roll|1d4 --C[$Roll.Total]|1:>One;[$Roll]|2:>Two;[$Roll]|3:>Three;[$Roll]|4:>Four;[$Roll] --X| --:One| --+Value|was One ([%1%]) --<| --:Two| --+Value|was Two ([%1%]) --<| --:Three| --+Value|was Three ([%1%]) --<| --:Four| --+Value|was Four ([%1%]) --<| }} This script uses the value of [$Roll.Total] and compares it
against 1, 2, 3, and 4, using a gosub branch to the matching value. The first
match test is “1:>One;[$Roll]”, where “1” is the value being matched, followed
by a procedure branch to “One” which gets the roll variable as a parameter. Procedure
Libraries You can now create handouts in your game in Roll 20 with the
name format "ScriptCards Library NAME", where name is a name you
assign to the library. Library names are case sensitive. It is my hope that the
more proficient ScriptCards scripters out there will provide procedure
libraries (or procedures that can be included in libraries) for others to use
to make their scripting life easier. Be they specific to a game system, or to a
type of activity, I think a robust set of libraries that GMs could use to
enhance their scripting capabilities would be very valuable to the community. Should
such things begin to emerge, I’ll create a portion of the ScriptCards Wiki page
to house them.
To include one or more libraries in a script, use the +++libname+++ directive
(does not need a -- line associated with it). Multiple library names can be
specified by separating them with semicolons (i.e., +++General;5E
Tools;Colorize+++ would include three libraries (General, 5E Tools, and
Colorize).
Included libraries are separated from the main script code by the automatic
inclusion of "--X|" before the first library is appended to the
script, and all libraries are loaded at the end of the script before script
processing takes place.
Procedures and labels in libraries can be used just as if they were included in
the body of your script. Note that this DOES mean that you could,
technically, jump into a library with a direct branch (--^) or direct branch
conditional, but I recommend using libraries to store reusable procedures. The Notes section of the library handout stores the library
code, and is written just like any other ScriptCards code except: -
They cannot use roll queries (?{Some Prompt:})
to get information from the user at execution time. -
They cannot use @{} notation to access character
and token information. Both of these limitation stem from the fact that Procedure
Libraries are not processed by the chat server, which is what handles these
items. Here is an example of handling damage modifications
(resistance, vulnerability, and immunity) in D&D 5E with a library: !script {{ +++5E Tools+++ --#|Damage Modifiers Test --#targettoken|@{target|token_id} -->Lib5E_CheckDamageModifiers|ResistType;fire --=DamageRoll|2d10 [&ResistType] --+Test:|[$DamageRoll] fire damage -->Lib5E_CheckDamageModifiers|ResistType;cold --=DamageRoll|2d10 [&ResistType] --+Test:|[$DamageRoll] cold damage -->Lib5E_CheckDamageModifiers|ResistType;poison --=DamageRoll|2d10 [&ResistType] --+Test:|[$DamageRoll] poison damage -->Lib5E_CheckDamageModifiers|ResistType;acid --=DamageRoll|2d10 [&ResistType] --+Test:|[$DamageRoll] acid damage --X| }} Library content (In a handout called “ScriptCards Library 5E
Tools” NOTE: Paste into Notepad first and then paste into the
handout in Roll20 to avoid bringing over HTML formatting from the web site) : --/|ScriptCards Library: 5E Tools version 0.0.1 --/|Provides various utility procedures for D&D 5E games --/|Lib5E_CheckDamageModifiers handle damage resistance, vulnerability, and immunity. --/|Pass a string variable to be filled with a string to be appended to a dice roll and the damage type --:Lib5E_CheckDamageModifiers|damageVariableName;damageType --&[%1%]|
--?"[*T:npc_vulnerabilities]" -inc "[%2%]"|>_Lib5E_IsVulnerable;[%1%] --?"[*T:npc_resistances]" -inc "[%2%]"|>_Lib5E_IsResistant;[%1%] --?"[*T:npc_immunities]" -inc"[%2%]"|>_Lib5E_IsImmune;[%1%] --<|
--:_Lib5E_IsVulnerable| --&[%1%]| * 2 [Vulnerable] --<| --:_Lib5E_IsResistant| --&[%1%]| \ 2 [Resistant] --<| --:_Lib5E_IsImmune| --&[%1%]| * 0 [Immune] --<| T he idea is that the functions in the library create a
string that can be appended to a roll to modify the output based on
resistances, so you pass Lib5E_CheckDamageModifiers the name of the string
variable you want to use and the damage type. The variable (ResistType in this
case) will include either nothing, “* 2 [Vulnerable]”, “\ 2 [Resistant]”, or “*
0 [Immune]” which can be included in a roll assignment (--=) to modify the
damage as appropriate. The order here might be important if an NPC is misconfigured
to be both resistant and immune to the same damage type. Since immune is an
absolute, having it last ensures that it will override resistant or vulnerable.
A creature that is both vulnerable and resistant (again, misconfigured) will
come back as resistant since that condition is checked after vulnerable. Some notes : I prefix my library labels with either “Lib5E_”
or “_Lib5E_” as a clarity convention. This isn’t strictly necessary but you
should be aware that if two libraries (or if your script and a library) define
the same label, the last label defined will win. Since libraries
are appended to the end of the script in the order you include them in the
+++libname+++ directive, you can somewhat control this, but it is probably best
to avoid re-declaring labels. In my case, items beginning with “Lib5E_” are intended to be
called by scripts, while items beginning with “_Lib5E_” are intended to be used
as subroutines by the “public” procedures. Of course, there is no reason you couldn’t
call them directly.
You might also note that I’ve included some library information
in comment lines (--/|) at the top of the library. These are ignored by
ScriptCards, and are a good way to convey requirements, parameters, usage
information, etc.