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

1654814960
David M.
Pro
API Scripter
Michael, once I replaced all the [S:...] and [R:...] with [*S:...] and [*R:...] it seems to be working for me? Tested with "Healing Word" and "Magic Missile". When spell is prepared the following prints just the title card, and when not prepared it prints the not prepared statement. !script {{ --#sourceToken|@{selected|token_id} --&spell|Magic Missile -->CheckSpellPrepared|[&spell] --:EndMacro| --X| --:CheckSpellPrepared| --%loop|1;9 --?[*S:lvl[&loop]_slots_total] -eq 0|EndMacro --rfirst|[*S:character_id];repeating_spell-[&loop] --:DisplayLoop| --?"[*R:spellname]" -eq NoRepeatingAttributeLoaded|% --?"[*R:spellname]" -inc "[%1%]" -and [*R:spellprepared] -ne 1|>NotPrepared;[%1%] --rnext| --^DisplayLoop| --%| --<| --:NotPrepared| --+|[*S:character_name] Does Not Have The [%1%] Spell Prepared --<| }}
@ David M - Thanks!  Well, I was beating myself up for pulling another "stupid" then realized that the script I had did have the * in front of the S and R.  Apparently, these were entered as white spaces somehow in my editor and did not transfer over when I posted here.  Lesson learned.
Roast my code! It's actually a cobbled mess of other people's code (Kurt, GM Goss and Will M) but it works! I have used SimpleSOund in this script not realising I could have just been using the --a function (will have to add your own sound if you use this)... Here's a working explodey ThunderWave that moves any tokens that fail their save 10ft. I haven't tested properly with resistant/immune edge cases. Feel free to fix or make it more elegant... !script {{ --/|GM Goss' Thunder Wave script based on Kurt's Burning Hands script. --/|Have tacked on Will M.'s Shove script mechanics to make ThunderWave work as intended (I think) --/|YMMV --&spellName|Thunderwave --/|Note: because the spell will be cast at a min level of 1, we use 2 here to get the total dice (2+1=3) --&spellL0DamageDice|1 --/|Prompt for the spell level. Update this to account for the minimum level of the spell --=SpellLevel|?{Spell Slot Level?|1|2|3|4|5|6|7|8|9} --&spellDamageDieType|8 --&damageType|thunder --&saveType|constitution --/|Source Token is the caster, and target token is the "end of the line". Can be a non-creature (no represents) token. --#sourcetoken|@{selected|token_id} -->GetAndCheckSlotInformation| -->DeductSpellSlot| --/|Get all of the tokens on the page so we can cache their positions --~|array;pagetokens;alltokens;@{selected|token_id} --#leftsub|Save DC @{selected|spell_save_dc} --#rightsub|Slot Level: [$SpellLevel] --#title|[&spellName] --/|Calculate damage based on spell slot. --=DamageDice|[$SpellLevel.Total] + [&spellL0DamageDice] --=Damage|[$DamageDice.Total]d[&spellDamageDieType] --=HalfDamage|[$Damage.Total] \ 2 --=DoubleDamage|[$Damage.Total] * 2 --=QuarterDamage|[$Damage.Total] \ 4 --/|Since we want to be able to hover over a roll and see the dice details, output the rolled damage at the --/|top of the card. If all critters make their save, the half damage roll won't contain the details. --+|[c][b]Damage Roll: [/b][$Damage][/c] --+|  --/|Create an array to hold the tokens that are intersected by the line. --~|array;define;tokensHit; -->createTokenLookup| --/|Prompt for a direction for hte cast, and define arrays that indicate the relative spaces that will be hit. --&direction|?{Direction|⬆ (UP),U|↗ (UP-RIGHT),UR|➡ (RIGHT),R|↘ (DOWN-RIGHT),DR|⬇ (DOWN),D|↙ (DOWN-LEFT),DL|⬅ (LEFT),L|&#x2196 (UP-LEFT);,UL|} --~|array;define;U;0,-1;0,-2;0,-3;-1,-1;-1,-2;-1,-3;1,-1;1,-2;1,-3 --~|array;define;D;0,1;0,2;0,3;-1,1;-1,2;-1,3;1,1;1,2;1,3 --~|array;define;R;1,0;2,0;3,0;1,-1;2,-1;3,-1;1,1;2,1;3,1 --~|array;define;L;-1,0;-2,0-;-3,0;-1,-1;-2,-1;-3,-1;-1,1;-2,1;-3,1 --~|array;define;UR;1,-1;1,-2;1,-3;2,-1;2,-2;2,-3;3,-1;3,-2;3,-3 --~|array;define;DR;1,1;1,2;1,3;2,1;2,2;2,3;3,1;3,2;3,3 --~|array;define;UL;-1,-1;-1,-2;-1,-3;-2,-1;-2,-2;-2,-3;-3,-1;-3,-2;-3,-3 --~|array;define;DL;-1,1;-1,2;-1,3;-2,1;-2,2;-2,3;-3,1;-3,2;-3,3 --/|Call the "checkForTokenHits" subroutine. The passed parameter will be the per-space VFX. Leave blank for none. -->checkForTokenHits|burn-smoke --@splay| ThunderWave --/|The first item in the array will be a blank dummy item, so remove it. --~|array;removeat;tokensHit;0 --/|Loop through the tokensHit tokens and roll saves for each one and apply damage --~tokenid|array;getfirst;tokensHit --?[&tokenid] -eq ArrayError|endOutput --:loopDisplay| --=SaveRoll|1d20 + [*[&tokenid]:[&saveType]_save_bonus] --/|Compare the save roll to the save DC and either apply full or half damage --?"[*[&tokenid]:npc_immunities]" -inc "[&damageType]"|Immune --?"[*[&tokenid]:npc_resistances]" -inc "[&damageType]"|Resistant --?"[*[&tokenid]:npc_vulnerabilities]" -inc "[&damageType]"|Vulnerable --?[$SaveRoll.Total] -lt @{selected|spell_save_dc}|>ApplyDamageTokenmod;[&tokenid];1;-[$Damage.Total]|>ApplyDamageTokenmod;[&tokenid];1;-[$HalfDamage.Total] --?[$SaveRoll.Total] -ge @{selected|spell_save_dc}|madeSave --/|Here are various damage applications if the creature is immune, resistant, or vulnerable. In some cases, we will reuse output lines, --/|for example, a resistant creature that fails its save will jump to "madeSave", since that is the correct damage amount. (half), while --/|a vulnerable creature that makes its save will jump to "FailedSave" since that will be normal damage. --/|Output a line for a failed saving throw (we will also jump here for a vulnerable creature that MAKES its save) --:FailedSave| --+[*[&tokenid]:t-name]:|Save [$SaveRoll] [r][$Damage] [&damageType][/r] -->MOVE_TOKEN|@{selected|token_id};[&tokenid];2 --^afterSave| --:Immune| --+[*[&tokenid]:t-name]:|is not affected by the spell! --^afterSave| --:Resistant| --?[$SaveRoll.Total] -lt @{selected|spell_save_dc}|>ApplyDamageTokenmod;[&tokenid];1;-[$HalfDamage.Total]|>ApplyDamageTokenmod;[&tokenid];1;-[$QuarterDamage.Total] --?[$SaveRoll.Total] -lt @{selected|spell_save_dc}|madeSave --+[*[&tokenid]:t-name]:|Save [$SaveRoll] [r][$QuarterDamage] [&damageType][/r] --^afterSave| --:Vulnerable| --?[$SaveRoll.Total] -lt @{selected|spell_save_dc}|>ApplyDamageTokenmod;[&tokenid];1;-[$DoubleDamage.Total]|>ApplyDamageTokenmod;[&tokenid];1;-[$Damage.Total] --?[$SaveRoll.Total] -ge @{selected|spell_save_dc}|FailedSave --+[*[&tokenid]:t-name]:|Save [$SaveRoll] [r][$DoubleDamage] [&damageType][/r] --^afterSave| --/|Output a line for a successful saving throw --:madeSave| --+[*[&tokenid]:t-name]:|Save [$SaveRoll] [r][$HalfDamage] [&damageType][/r] --:afterSave| --~tokenid|array;getnext;tokensHit --?[&tokenid] -ne ArrayError|loopDisplay --:endOutput| --X| --:ApplyDamageTokenmod|Parameters are tokenid;bar#;amount --@token-mod|_ignore-selected _ids [%1%] _set bar[%2%]_value|[%3%] --<| --:ApplyDamageAlterbars|Parameters are tokenid;bar#;amount --@alter|_target|[%1%] _bar|[%2%] _amount|-[%3%] _show|none --<| --:checkForTokenHits|parameter is vfx descriptor --=baseX|[*S:t-left] - 1 \ 70 --=baseY|[*S:t-top] - 1 \ 70 --~offset|array;getfirst;?{Direction} --:checkTokenLoop| --?"[&offset]" -eq "ArrayError"|endCheckForTokenHits --~split|string;split;,;[&offset] --=thisX|[$baseX] + [&split1] --=thisY|[$baseY] + [&split2] --/|IF we passed a visual effect specifier in %1%, create a point VFX in the square --?"X[%1%]X" -ne "XX" |[ --=VX|[$thisX] * 70 + 35 --=VY|[$thisY] * 70 + 35 --vpoint|[$VX] [$VY] [%1%] --]| -->checkTokens|[$thisX];[$thisY] --~offset|array;getnext;?{Direction} --^checkTokenLoop| --:endCheckForTokenHits| --<| --/|Reads the variables created by createTokenLookup to find any tokens that occupy a given space. --:checkTokens|x;y --?"X[&tok[%1%]-[%2%]]X" -ne "XX"|[ --~split|string;split;!;[&tok[%1%]-[%2%]] --%P|1;[$splitCount.Total];1 --=var|split[&P] --?"X[&[$var.RollText]]X" -eq "XX"|% --~exists|array;indexof;tokensHit;[&[$var.RollText]] --?[&exists] -ne ArrayError|skipAdd --?[&[$var.RollText]] -eq ArrayError|skipAdd --~|array;add;tokensHit;[&[$var.RollText]] --:skipAdd| --%| --<| --/|Creates a series of string variables with names like 'tok12-15' which represent the various squares that are --/|occupied by tokens on the page. Handle 1x1, 2x2, and 3x3 tokens by simply adding extra squares in the appropriate --/|pattern around the center point location. The result is that if there are two tokens at 12,15, the tok12-15 string --/|will contain something like "-asln34njfn2nafd!-sdnfklaserfs" (IDs separated by exclamation points) that we can use to --/|quickly evaluate hits by essentially asking "what is in square 12x15" by just reading the variable. --:createTokenLookup| --~tokenid|array;getfirst;alltokens --:tokenSetupLoop| --?[&tokenid] -eq ArrayError|endSetupLoop --=tLeft|[*[&tokenid]:t-left] - 1 \ 70 --=tTop|[*[&tokenid]:t-top] - 1 \ 70 --=tWidth|[*[&tokenid]:t-width] --?[$tWidth] -eq 70|[ --&tok[$tLeft]-[$tTop]|+[&tokenid]! --/+[*[&tokenid]:character_name]|At [$tLeft],[$tTop] : [&tok[$tLeft.Total]-[$tTop.Total]] --]| --?[$tWidth] -eq 140|[ --=NX|[$tLeft] + 1 --=NY|[$tTop] + 1 --&tok[$tLeft]-[$tTop]|+[&tokenid]! --&tok[$tLeft]-[$NY]|+[&tokenid]! --&tok[$NX]-[$tTop]|+[&tokenid]! --&tok[$NX]-[$NY]|+[&tokenid]! --]| --?[$tWidth] -eq 210|[ --=PX|[$tLeft] - 1 --=PY|[$tTop] - 1 --=NX|[$tLeft] + 1 --=NY|[$tTop] + 1 --&tok[$tLeft]-[$tTop]|+[&tokenid]! --&tok[$PX]-[$PY]|+[&tokenid]! --&tok[$tLeft]-[$PY]|+[&tokenid]! --&tok[$NX]-[$PY]|+[&tokenid]! --&tok[$PX]-[$tTop]|+[&tokenid]! --&tok[$NX]-[$tTop]|+[&tokenid]! --&tok[$PX]-[$NY]|+[&tokenid]! --&tok[$tLeft]-[$NY]|+[&tokenid]! --&tok[$NX]-[$NY]|+[&tokenid]! --]| --~tokenid|array;getnext;alltokens --^tokenSetupLoop| --:endSetupLoop| --<| --:MOVE_TOKEN|STokenid, TTokenId, Units --&TId1|[%1%] --&TId2|[%2%] --&Units|[%3%] --/| Angle function returns a string variable (&) with lots of decimal points. --~A|math;angle;[&TId1];[&TId2] --/| I've found that TokenMod chokes on a movement angle with lots of decimal points, so rounding is needed --/|$Ar will now contain a rounded integer version of &A --~Ar|math;round;[&A] --/|&Angle will end up being one of the common directions which may work better for grids --?[$Ar] -gt 337.5 -or [$Ar] -le 22.5|&Angle;0 --?[$Ar] -gt 22.5 -and [$Ar] -le 67.5|&Angle;45 --?[$Ar] -gt 67.5 -and [$Ar] -le 112.5|&Angle;90 --?[$Ar] -gt 112.5 -and [$Ar] -le 157.5|&Angle;135 --?[$Ar] -gt 157.5 -and [$Ar] -le 202.5|&Angle;180 --?[$Ar] -gt 202.5 -and [$Ar] -le 247.5|&Angle;225 --?[$Ar] -gt 247.5 -and [$Ar] -le 292.5|&Angle;270 --?[$Ar] -gt 292.5 -and [$Ar] -le 337.5|&Angle;315 --/| Added for dealing with a SC 1.39a bug (returns negative angles beteen 270 and 360) --?[$Ar] -gt -90 -and [$Ar] -le -67.5|&Angle;270 --?[$Ar] -gt -67.5 -and [$Ar] -le -22.5|&Angle;315 --?[$Ar] -gt -22.5 -and [$Ar] -le 0|&Angle;0 --&UnitsFactor|1 --?[&Angle] -eq 45|&UnitsFactor;1.4142 --?[&Angle] -eq 135|&UnitsFactor;1.4142 --?[&Angle] -eq 225|&UnitsFactor;1.4142 --?[&Angle] -eq 315|&UnitsFactor;1.4142 --=U|[&Units] * [&UnitsFactor] --/|*Angles|[&Angle] ([&A]) ([$Ar]) --/| Time to call the magic TokenMod function to make the target token move across the screen --@token-mod|_move =[&Angle]|[$U.Raw]g _ids [&TId2] _ignore-selected --<| --:GetAndCheckSlotInformation| --=SlotLevel|[$SpellLevel] --=SlotsTotal|[*S:lvl[$SlotLevel]_slots_total] --=SlotsExpended|[*S:lvl[$SlotLevel]_slots_expended] --?[$SlotsExpended.Total] -lt 0|NoSlotsLeft --?[$SlotsExpended.Total] -eq [$SlotsTotal.Total]|NoSlotsLeft --/|@roll20AM|_audio,play,nomenu|Fire Blast --<| --:DeductSpellSlot| --=SlotsExpended|[$SlotsExpended] +1 --@setattr|_charid [*S:character_id] _lvl[$SlotLevel]_slots_expended|[$SlotsExpended] _silent --=SlotsRemaining|[$SlotsTotal] - [$SlotsExpended] --+|[c][b]Level [$SpellLevel.Total] Spell Slots Left: [/b][$SlotsRemaining][/c] --<| --X| --:NoSlotsLeft| --+|[b][*S:character_name] has no level [$SlotLevel.Total] spell slots available.[/b] --X|NoSlotsLeftStop }}
1655588571

Edited 1655588624
Kurt J.
Pro
API Scripter
ScriptCards 2.0.0 is now live on the GitHub The next major update for ScriptCards is now available as ScriptCards 2.0.0 on the main branch of the code. The following changes have been made since 1.7.7a (the previous normal code version): New Feature ScriptCards Triggers - You can now create a character named "ScriptCards_Triggers" (case sensitive) and have ScriptCards monitor for in-game events, firing off an ability macro on that character when the event happens. The macro can be a ScriptCard or anything else. Bug Fix When rolling dice that included a reroll value (ie, 6d6ro2 to reroll 1's and 2's once) the roll parser was giving the correct roll result, but was not including the discarded rerolled dice in the tooltip output. That behavior has been fixed. Enhanced Feature The VFX command (--v) now has the ability to send pings to the VTT. Pings are supported for the "token" and "point" vfx types and are triggered by using the word "ping" in place of the effect specifier (like burst-fire). Optionally, you can include "moveall" as an additional parameter to zoom all players to the pinged location (Example: --vtoken|@{selected|token_id} ping moveall) New Settings You can now specify values for titlefontstyle (defaults to "normal") and titlefontweight (defaults to "strong"). These are used with CSS specifiers "font-style" and "font-weight". Enhanced Feature You can now set button font sizes inline with the button declaration. Appending :??px (ie, :24px) to a button Opening tag will set the font size for that button : [button:24px] for example. IF you use in-line button colors, they must be specified before the font size (so [button:#f00:24px] is fine, but [button:24px:#f00] will not generate a button)
1655596035

Edited 1655604227
I'm really loving the new Trigger logic in Scriptcards 2.0.0.  Example use: change:campaign:turnorder  Event (Each time you click next on the Turnorder Dialog, the dialog below is generated) - It also whispers to the next player and player on deck that their turns are up or next.
1655596133
David M.
Pro
API Scripter
Nice, Will!
@Will - very nice.   @Kurt - I see that you put a note in wiki and are working on the function descriptions and all in addition to the description above - which I really appreciate.  I apologize for my denseness but I don't understand some of it (Will and David are smarter than I am). 1.  The Scriptcards Trigger sounds amazing but I don't see how to access the feature.  I create a character with the appropriate name then create an ability macro on the character sheet like with a mule? Then if I want to trigger the macro when an event occurs how do I connect the two?  Does the macro have to have a line that specifies the specific event it is tracking and how would it do that? How would I call the macro.  Sorry, I am confused. 2.  I am not sure what the new VFX enhanced feature does.  In your example  (Example: --vtoken|@{selected|token_id} ping moveall) , do I understand that the ping is used to determine the location of the selected token in order to move the other tokens to the token location? If so, how does it specify order, stacking, offset and the like?
1655647710
Kurt J.
Pro
API Scripter
Michael C. said: @Will - very nice.   @Kurt - I see that you put a note in wiki and are working on the function descriptions and all in addition to the description above - which I really appreciate.  I apologize for my denseness but I don't understand some of it (Will and David are smarter than I am). 1.  The Scriptcards Trigger sounds amazing but I don't see how to access the feature.  I create a character with the appropriate name then create an ability macro on the character sheet like with a mule? Then if I want to trigger the macro when an event occurs how do I connect the two?  Does the macro have to have a line that specifies the specific event it is tracking and how would it do that? How would I call the macro.  Sorry, I am confused. 2.  I am not sure what the new VFX enhanced feature does.  In your example  (Example: --vtoken|@{selected|token_id} ping moveall) , do I understand that the ping is used to determine the location of the selected token in order to move the other tokens to the token location? If so, how does it specify order, stacking, offset and the like? For #1, once the trigger mule is created (and you'll need to restart your sandbox after doing so for ScriptCards to recognize it), you create abilities on the character with names that mirror the API event names you can watch for, so things like "change:graphic" or "change:campaign:turnorder". These events are fired by the API whenever something happens on the VTT that matches the description. ScriptCards listens to these events and checks to see if the mule has a matching ability, and if so executes it. There is a special comment that should be included in the ability script (--/|TRIGGER_REPLACEMENTS) that ScriptCards will substitute with variable assignment statements so your script can get the details of the event. For #2, if someone holds their mouse down on the VTT, Roll20 sends out a "ping" (an expanding circle) from that spot to draw attention to it. If the person sending the ping holds down shift while doing it, it zooms everyone (GMs and Players) to focus their VTT window on that spot. This option programmatically duplicates that effect. No tokens get moved, just the viewport of the user's windows.
Hello i'm kinda butting in cause i'm beginning on scriptcard with the help of the wiki but i can't seems to make some of my stuff work  it's for a homebrew game based on d100 dice. the closer to 1 is the roll the better it is, of course i have crit and fumble activating rolling table for effect. but it seems like my condition statement can't work ... while i had something similar working on powercard. ``` !scriptcard  {{   --#title|Morsure   --#leftsub|Melee Attack   --#sourceToken|@{selected|token_id}   --#targetToken|@{target|token_id}   --#emoteText|@{selected|token_name} attaque @{target|token_Name}   --= Attack | 1d100   --+ attaque | [$Attack]   --=Succes | [[@{siffleur|Physique}+?{Modificateur|0}]]   --=Crit | @{selected|Réussitcrit}   --=Fumble | @{selected|Echeccrit}   --+Succes | [$Succes]   --= Degat | 3d6+4   --= result | [$Degat]-@{Target|RésistancePhy}   --= crit-melee | [[1t[crit-melee]]]   --= fumble-melee | [[1t[Fumble-melee]]]   --?[$Attack.base] -le [$Crit.base]|[$crit-melee]   --?[$Attack.base] -le [Succes.total]| =deals [$result.total]   --?[$Attack.base] -gt [Succes.total] -and [$Attack.base] -lt [[[Succes.total]+10]]|you can finish your turn   --?[$Attack.base] -gt [[[Succes.total]+10]]|it's the end of your turn   --?[$Attack.base] -ge [$Fumble.base]|[$fumble-melee] it's ain't your lucky day }} ``` and well i have been working on it with some of my player and ... well we can't figure out were is the problems... so thanks for the help in advance !
1655732938
Kurt J.
Pro
API Scripter
dragon said:   --?[$Attack.base] -le [$Crit.base]|[$crit-melee]   --?[$Attack.base] -le [Succes.total]| =deals [$result.total]   --?[$Attack.base] -gt [Succes.total] -and [$Attack.base] -lt [[[Succes.total]+10]]|you can finish your turn   --?[$Attack.base] -gt [[[Succes.total]+10]]|it's the end of your turn   --?[$Attack.base] -ge [$Fumble.base]|[$fumble-melee] it's ain't your lucky day Roll suffixes (like .Base) are case sensitive, so you'll need to use .Base and .Total instead of .base and .total, with the first letter of the suffix capitalized.
1655735111

Edited 1655735221
hum i applied what you told me and had to do a little change on a line or two. but it still do not show my result . am i missing something ? here's the new line :  !scriptcard {{ --#title|Morsure --#leftsub|Melee Attack --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --#emoteText|@{selected|token_name} attaque @{target|token_Name} --= Attack | 1d100 --+ attaque | [$Attack] --=Succes | [[@{siffleur|Physique}+?{Modificateur|0}]] --=Nffail | [$succes]+10 --=Crit | @{selected|Réussitcrit} --=Fumble | @{selected|Echeccrit} --+Succes | [$Succes] --= Degat | 3d6+4 --= result | [$Degat]-@{Target|RésistancePhy} --= crit-melee | [[1t[crit-melee]]] --= fumble-melee | [[1t[Fumble-melee]]] --?[$Attack.Base] -le [$Crit.Base]|<[$crit-melee] --?[$Attack.Base] -le [Succes.Total]| =deals [$result.total] --?[$Attack.Base] -gt [Succes.Total] -and [$Attack.Base] -lt [$Nffail.Total]|you can finish your turn --?[$Attack.Base] -gt [Succes.Total]|it's the end of your turn --?[$Attack.Base] -ge [$Fumble.Base]|[$fumble-melee] it's ain't your lucky day }}   that is the only result i get ... no additionnal line or anything! so i was wondering if i was lacking any of the branch format you mentioned in your wiki ... but i tried them and nothing more appeared !
1655743849

Edited 1655747350
Kurt J.
Pro
API Scripter
@dragon - I don't have your game system, so I can't actually test this, but here is a cleaned up script, followed by some explanation: !scriptcard {{ --#title|Morsure --#leftsub|Melee Attack --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --#emoteText|@{selected|token_name} attaque @{target|token_Name} --=Attack|1d100 --+attaque|[$Attack] --=Succes|[[@{siffleur|Physique}+?{Modificateur|0}]] --=Nffail|[$Succes] + 10 --=Crit|@{selected|Réussitcrit} --=Fumble|@{selected|Echeccrit} --+Succes|[$Succes] --=Degat|3d6 + 4 --=result|[$Degat] - @{Target|RésistancePhy} --=crit-melee|[[1t[crit-melee]]] --=fumble-melee|[[1t[Fumble-melee]]] --&Output| --?[$Attack.Base] -le [$Crit.Base]|&Output;+[$crit-melee] --?[$Attack.Base] -le [$Succes.Total]|&Output;+deals [$result.Total] --?[$Attack.Base] -gt [$Succes.Total] -and [$Attack.Base] -lt [$Nffail.Total]|&Output;+you can finish your turn --?[$Attack.Base] -gt [$Succes.Total]|&Output;+it's the end of your turn --?[$Attack.Base] -ge [$Fumble.Base]|&Output;+[$fumble-melee] it's ain't your lucky day --+Result|[&Output] }} I removed the extra spaces before Roll Variable names and around the | characters Roll Variable names are case sensitive, so I changed one instance of [$succes] to [$Succes] Roll Variable assignement lines need each of their components separated by spaces, so "3d6+4" should be "3d6 + 4" (the die specifier, the operator, and the bonus are all separate components). In PowerCards (almost) every line of the script produces output. In ScriptCards, ONLY --+ lines produce output, so I've created a string variable called "Output" that starts blank. Each of the conditional can append something to the Output variable which is then displayed with the --+ line at the end. EDIT - Added $ before the variable names in some of the conditionals that were missing them.
i don't have a set game systeme it's a homebrew systeme so i'm mainly playing with the attribute and abilitie that i create on the charcter sheet i see what you did ! hum it seems the problem come from my side after this cause only the last line come out ... every time!  thanks for the help, i'll look into it a lil more !!
@Kurt - Thanks for the response, that helped a lot. #1 - Ok, I see now and got a rudimentary practice script to work for "change:campaign:turnorder" and can work with it.  Still a couple of things - apologies in advance, but I kind of feel like someone who has a manual but the middle pages are missing - I put the comment line in but the output remained the same so I am not sure how that works.  Also is there a reference list of API event names somewhere?   #2 - (face slap)  Arggh. Of course.  I use it all the time.  
1655757106
David M.
Pro
API Scripter
Michael, this  wiki page on API events should help!
1655769128

Edited 1656012681
I want to have a button on one script card that opens a Handout. I know the URL for the handout, how do I format this in the button? Not Smart.  Lol.
I've had a small issue with scriptcards throwing strange errors and giving unexpected results, I think I've narrowed the problem down to the fact that I'm trying to pull an autocalculated roll from a disabled field. The error I'm recieving is: "ERROR: Did not specify an attribute name when referencing attribute using @{TouMod}" "Error at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:172:1), <anonymous>:575:11) at String.replace (<anonymous>) at Object.d20.textchat.doChatInput (eval at <anonymous> (/home/node/d20-api-server/api.js:172:1), <anonymous>:549:29) at sendChat (/home/node/d20-api-server/api.js:1897:16) at apiscript.js:2402:9 at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:70:8) at /home/node/d20-api-server/api.js:1739:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147)" "ERROR: Did not specify an attribute name when referencing attribute using @{LeftLegarmourvalue}" "Error at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:172:1), <anonymous>:575:11) at String.replace (<anonymous>) at Object.d20.textchat.doChatInput (eval at <anonymous> (/home/node/d20-api-server/api.js:172:1), <anonymous>:549:29) at sendChat (/home/node/d20-api-server/api.js:1897:16) at apiscript.js:2402:9 at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:70:8) at /home/node/d20-api-server/api.js:1739:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147)" "ERROR: Did not specify an attribute name when referencing attribute using @{TouMod}" "Error at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:172:1), <anonymous>:575:11) at String.replace (<anonymous>) at Object.d20.textchat.doChatInput (eval at <anonymous> (/home/node/d20-api-server/api.js:172:1), <anonymous>:549:29) at sendChat (/home/node/d20-api-server/api.js:1897:16) at apiscript.js:2402:9 at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:168:1), <anonymous>:70:8) at /home/node/d20-api-server/api.js:1739:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147)" Which is repeated over and over x6 for Head, Left Arm, Body, Right Arm, Left Leg, and Right Leg.  It keeps telling me a didn't specify an attribute name, but I'm not understanding, because I specifically did supply an attribute name. The scriptcards script in question is: !scriptcards {{ --/| === ScriptCard Layout for Attack Rolls === |\-- --/| === Version 0.1a === |\-- --/| === Date: 06/22/2022 === |\-- --/| Local Variables --|\ --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --/| ===== Numbers =========== |\ --=DmgPen|@{pen} --=RollDamage|@{damage} --=TBon|[*T:T]/10 --=HAV|[*T:headArmourvalue] --=LAAV|[*T:LeftArmArmourvalue] --=BAV|[*T:BodyArmourvalue] --=RAAV|[*T:RightArmArmourvalue] --=LLAV|[*T:LeftLegArmourvalue] --=RLAV|[*T:RightLegArmourvalue] --=HSoak|[*T:HeadSoak] --=LASoak|[*T:LeftArmSoak] --=BSoak|[*T:BodyArmSoak] --=RASoak|[*T:RightArmSoak] --=LLSoak|[*T:LeftLegSoak] --=RLSoak|[*T:LeftLegSoak] --=HCrit|[*T:headCritDam] --=LACrit|[*T:LeftArmCritDam] --=BCrit|[*T:BodyCritDam] --=RACrit|[*T:RightArmCritDam] --=LLCrit|[*T:LeftLegCritDam] --=RLCrit|[*T:RightLegCritDam] --=HCritM|[*T:headCritDam^] --=LACritM|[*T:LeftArmCritDam^] --=BCritM|[*T:BodyCritDam^] --=RACritM|[*T:RightArmCritDam^] --=LLCritM|[*T:LeftLegCritDam^] --=RLCritM|[*T:RightLegCritDam^] --+|[c] ● Soak Details ● [/c] --+Toughness Mod|[$TBon] --+|[c] ● Head ● [/c] --+|[B]AV[/B] [$HAV] [B]SOAK[/B] [$HSoak] [B]CRIT[/B] [$HCrit] / [$HCritM] --+|[c] ● Left Arm ● [/c] --+|[B]AV[/B] [$LAAV] [B]SOAK[/B] [$LASoak] [B]CRIT[/B] [$LACrit] / [$LACritM] --+|[c] ● Body ● [/c] --+|[B]AV[/B] [$BAV] [B]SOAK[/B] [$BSoak] [B]CRIT[/B] [$BCrit] / [$BCritM] --+|[c] ● Right Arm ● [/c] --+|[B]AV[/B] [$RAAV] [B]SOAK[/B] [$RASoak] [B]CRIT[/B] [$RACrit] / [$RACritM] --+|[c] ● Left Leg ● [/c] --+|[B]AV[/B] [$LLAV] [B]SOAK[/B] [$LLSoak] [B]CRIT[/B] [$LLCrit] / [$LLCritM] --+|[c] ● Right Leg ● [/c] --+|[B]AV[/B] [$RLAV] [B]SOAK[/B] [$RLSoak] [B]CRIT[/B] [$RLCrit] / [$RLCritM] }} I should note, that I have not included about 70% of the script, only the code the specifically uses the referenced variables. So, is it not possible to reference an attribute in a disabled field?  What exactly are those error messages trying to tell me?
1656847758
Kurt J.
Pro
API Scripter
@Toby - I just pushed an update to the GitHub for version 2.0.2b which attempts to address fields that refer to other fields. I don't know if it will help with your particular case since I don't know what sheet you are using, but they were definitely not being gracefully handled before and would produce the same type of error (at least the "ERROR: Did not specify an attribute name when referencing attribute using @{TouMod}" part... the other error seems to be coming from the base chat input routines in Roll20, but that could be a side effect of ScriptCards trying to display things like @{TouMod})
Thank you.  That seemed to partially fix it, although. I need to use: @{target|VariableName} instead of  [*T:VariableName] I am entirely fine with this.  With this particular attribute otherwise it seems to try and out put it to the chat as a string rather than parse and calculate.  Perhaps it has to do with the fact I am trying to pull the value from an auto-calculated field which uses roll20's roll engine to do the math. Also, I am using a heavily modified version of the Dark Heresy 1e character sheet.  I want to add auto-calculations to alot of the output rolls as Dark Heresy has ALOT of chart lookups based on the result of the roll.  Especially for things such as Critical Strike tables.  I feel it slows down combat to rather disruptive degree.  I like Roleplay not Rollplay. Once I finish my work on this I'd be happy to share, and will reach out to the sheet's original creator.  Especially since my alterations would also be compatible with the DH 1e and the DH 2e sheets. Anyways, thank you again.
Firstly, I just wanted to say that I'm incredibly grateful for these new (to me) ReEntrant buttons, they've made my life a billion times easier, as now I can prompt my players for input in the middle of execution without going through those clunky Information Requests. IR's will still be useful for Text or Number inputs, but mostly I've needed just 'Yes/No' or multiple choice questions so these ReEntrant buttons are far more useful, and so far my players love the changes! Secondly, I wanted to ask: is there any way to get token values for multi-sided tokens? One of my players has a Changeling PC and they like to take on the forms of NPCs they find, and so I'd like to give them a way aside from the Multi-Side interface to manage those Sides. I looked in both the Token-Mod and Scriptcards documentation and didn't see anything (apologies if there actually is, I am notoriously blind) so I figured I'd ask about it here. Thanks in advance!
1657022127
David M.
Pro
API Scripter
With token-mod you can use something like this. Obviously, you could call token-mod via scriptcards !token-mod --set currentside|2 With scriptcards directly, there is a way to change token properties using Object Modification , though it doesn't seem to be working for the currentside property? Maybe I've typo-ed or something. A list of all api-accessible token properties can be found here .   --!t:@{selected|token_id}|currentside:2                //this isn't working? Kurt, is currentside supported?
@non & David M - yes, reentrant buttons rule. As to the question - apologies if I am not responding to the question asked - if non is asking what I think s/he is then I use TokenMod often with multisided characters (Druids mostly).  The token is treated the same as single sided and has responded to my calls for, and changes to, attributes of the token using TokenMod, Chatsetattr, etc..  An example would be (starry form):      --@token-mod| _ids [*S:t-id] _set currentside|10 bright_vision|on bright_distance|10 low_distance|10 statusmarkers|WildShaped      --@token-mod| _ids [*S:t-id] _set represents|@{Sandy|character_id} currentside|1 bright_vision|off statusmarkers|-WildShaped Hope that helped.
1657038147

Edited 1657038188
Kurt J.
Pro
API Scripter
While it was possible to set currentSide via --!t, there were a couple of issues. I did work up a ScriptCard that would account for all of these, but it was a bit ugly :) Setting currentSide via the API doesn't actually do anything :) It is essentially only useful for reading what was set by the UI. The list of images for the various sides are kept as URLs in the "sides" property separated by | and this must be parsed to get the correct image to set to imgsrc. Side numbers are zero-based, except that 0 is stored in the attribute as a null. Because the --! command tries to be as forward-proof as possible, currentSide would have been case sensitive since that's how it is in the object. All of that said, I just uploaded 2.0.2e to the GitHub, which supports setting currentSide (non-case sensitive) which will also update imgsrc based on the "sides" attribute. The side numbers are zero-based, so --!t:@{selected|token_id}|currentside:0 will set the first image, :1 the second, etc.
1657044139
David M.
Pro
API Scripter
Cool, thanks for the version update & explanation, and for the clarification on the 0-based currentside! Those porting over token-mod macros (1-based) will need to offset accordingly.
Thanks for the replies! Part of the question that got lost in translation was: is there a way to tell how many sides are available? I imagine that's something regarding that 'sides' property? What kind of syntax should I be using if I wanted to make a macro that displays all of the available sides for a token?
1657146028

Edited 1657146196
Kurt J.
Pro
API Scripter
non said: Thanks for the replies! Part of the question that got lost in translation was: is there a way to tell how many sides are available? I imagine that's something regarding that 'sides' property? What kind of syntax should I be using if I wanted to make a macro that displays all of the available sides for a token? You can get the number of sides with: --~sides|string;split;|;[*S:t-sides] After which, [$sidesCount] will contain the total number of sides. Keep in mind that currentSide starts at 0, so a token with 6 sides will have side numbers 0, 1, 2, 3, 4, and 5. If anyone is curious, this is the ScriptCard I worked out to set the side before  adding the code to 2.0.2e :) !script {{ --#sourcetoken|@{selected|token_id} --#hidecard|1 --~sides|string;split;|;[*S:t-sides] --=NewSide|1d[$sidesCount.Raw] - 1 --&SideText|[$NewSide.Raw] --?[&SideText] -eq 0|&SideText; --=NewSidePlus|[$NewSide.Raw] + 1 --!t:@{selected|token_id}|currentSide:[&SideText] --&newImgSrc|[&sides[$NewSidePlus.Raw]] --~newImgSrc|string;replace;%3A;:;[&newImgSrc] --~newImgSrc|string;replace;%3F;?;[&newImgSrc] --!t:@{selected|token_id}|imgsrc:[&newImgSrc] }} This just sets a random side on the token, but it had to take into account the number of sides, setting blank for 0, and fixing the URI encoding in the strings in sides.
This is exactly what I needed, thanks!
1657478736

Edited 1657478823
non
Pro
So, I'm attempting to add in some features for rerolling dice, and I'm having trouble with reroll once ( XdYro<Q) and it seems to be ignoring the '<' and further, like so: !scriptcard{{      --=TEST|3d4ro<1      --+TEST|[$TEST] }} Am I doing something wrong here? It also doesn't save the string if I do it this way either: !scriptcard{{     --&RollString|3d4ro<1     --=Roll|[&RollString]     --+TEST|[$Roll] }}
1657484145
Kurt J.
Pro
API Scripter
@non, what version of ScriptCards are you using? The latest version on OneClick has a bug in the reroll code - An update has been queued since last weekend, but apparently they didn't do an API push because of the 4th of July. Using the latest development version those scripts appear to be functioning normally for me. I would expect that OneClick will get updated to 2.0.2g Tuesday or Wednesday this week.
Huh, well turns out I was on 1.19, but I updated to Latest and still no dice. Thanks for the update!
@non - the following is functioning correctly on v2.0.0: !script {{ --=Test|10d6ro<2 --+|[$Test] }} One thing - I have found that I have had to switch editors (particularly wp such as Word and Pages) because the one I was using was throwing in unseen or different characters than those displayed.  That might be the cause.  
Try notepad++ for and editor. 
1657665766
Andrew R.
Pro
Sheet Author
Never use a word processor for editing code. Never . I use the Sublime editor, but there are many others. 
1657695877

Edited 1657696151
vÍnce
Pro
Sheet Author
I've been working with another roll20 user that is trying to make an attack macro with scriptcards for a beta sheet I've been working on and he pointed out that many of the repeating attributes were not being detected by scriptCards.  I know that repeating attributes won't show up until you add a repeating row and actually enter each field on the sheet.  Another method is to use sheetworkers to set defaults.  I've tried adding a sheetworker that creates the repeating default values (tests if newValue === previousValue on a detected change event)  It appears to work as expected but it seems that most of the repeating attributes are still not being detected by scriptCards. As a comparison; command used; !script {{   --Rfirst|@{selected|character_id};repeating_weapon   --Rdump| }} produces; "weapon_name|Test" "weapon_name_max|" "weapon_damagesmallmedium_chat_menu|[Roll Damage](~@{character_id}|repeating_weapon_-n6qh1pmv8zuw8cbk6eq_weapon_damagesmallmedium_roll)" "weapon_damagesmallmedium_chat_menu_max|" "weapon_damagelarge_chat_menu|[Roll Damage vs LG](~@{character_id}|repeating_weapon_-n6qh1pmv8zuw8cbk6eq_weapon_damagelarge_roll)" "weapon_damagelarge_chat_menu_max|" "weapon_damagesmallmedium_npc_chat_menu|[Damage](~@{character_id}|repeating_weapon_-n6qh1pmv8zuw8cbk6eq_weapon_damagesmallmedium_npc_roll)" "weapon_damagesmallmedium_npc_chat_menu_max|" "weapon_damagelarge_npc_chat_menu|[Damage vs LG](~@{character_id}|repeating_weapon_-n6qh1pmv8zuw8cbk6eq_weapon_damagelarge_npc_roll)" "weapon_damagelarge_npc_chat_menu_max|" "weapon_dual|" "weapon_dual_max|" "weapon_whisper_to_hit|<br>/w gm &{template:attacks-table} {{color=@{color_option}}} {{ToHitAC-10to0=ToHit:[[ @{thac-10} ]]|[[ @{thac-9} ]]|[[ @{thac-8} ]]|[[ @{thac-7} ]]|[[ @{thac-6} ]]|[[ @{thac-5} ]]|[[ @{thac-4} ]]|[[ @{thac-3} ]]|[[ @{thac-2} ]]|[[ @{thac-1} ]]|[[ @{thac0} ]]}} {{ToHitAC1to10=ToHit:[[ @{thac0} ]]|[[ @{thac1} ]]|[[ @{thac2} ]]|[[ @{thac3} ]]|[[ @{thac4} ]]|[[ @{thac5} ]]|[[ @{thac6} ]]|[[ @{thac7} ]]|[[ @{thac8} ]]|[[ @{thac9} ]]|[[ @{thac10} ]] }}" "weapon_whisper_to_hit_max|" Using another script (Scott C. hooked me up with a little script that shows all repeating attributes and values detected. Note that it won't output attributes that contain rolls or attribute/ability calls) // Scott C. on('chat:message',(orig_msg)=>{ let msg = _.clone(orig_msg); if(msg.content.startsWith('!checkRepeats')){ const characterName = msg.content.replace(/!checkRepeats\s+/,''); const character = findObjs({type:'character',name:characterName},{caseInsensitive:true})[0]; if(character){ const attributes = findObjs({type:'attribute',characterid:character.id}); const output = attributes .reduce((memo,attr)=>{ if(attr.get('name').startsWith('repeating_') && !/\[\[|@\{|%\{/.test(attr.get('current'))){ memo.push(`\`<li>${attr.get('name')}:${attr.get('current')}/${attr.get('max')}</li>`); } return memo; },[]) .join('<br>'); const finalMsg = `<div><p>The following repeating attributes were found</p><ul>${output}</ul></div>`; sendChat('Attr Checker',finalMsg); } } }) command used; !checkRepeats @{selected|character_name} produces; Attr Checker: The following repeating attributes were found repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_name:Test/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_attack_type:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_dual:/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_range_small:1/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_range_medium:2/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_whisper_to_hit_select:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_dual_pen:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_backstab_var:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_tohitbonus:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_magicbonus:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_prof:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_backstab:1/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_attackdmgbonus:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_quantity:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_weight:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_cost:0/ repeating_weapon_-N6qH1PMV8Zuw8CBK6Eq_weapon_range_long:3/ Thoughts? TIA
1657705896
Kurt J.
Pro
API Scripter
@vince - I'll do some experimenting and see if I can determine what might be happening.
1657743009
vÍnce
Pro
Sheet Author
Kurt J. said: @vince - I'll do some experimenting and see if I can determine what might be happening. Thanks Kurt.  It's very possible that my sheetworker chops could be suspect as well...  Let me know if you need anything from me.  Much appreciated.
1657752175
Kurt J.
Pro
API Scripter
vÍnce said: Kurt J. said: @vince - I'll do some experimenting and see if I can determine what might be happening. Thanks Kurt.  It's very possible that my sheetworker chops could be suspect as well...  Let me know if you need anything from me.  Much appreciated. Nope... 100% an error on my part. There was a bug in the code that filled out the information for repeating sections. I was using .replace on the "current" field, without .toString() first, so when a value was purely numeric it was tossing it out (the try...catch was triggering so the sandbox didn't crash, but the value would not get included in the repeating attributes list). I've fixed this in 2.0.2i (which is now added to the queued update for OneClick as well as in the beta game.
1657752396
vÍnce
Pro
Sheet Author
Thanks for getting to the bottom of this Kurt.  Now I can move on to break something else. ;-)
1657860179
vÍnce
Pro
Sheet Author
@Kurt I installed your v2.0.2i code and re-tested. The update looks like it fixes the missing repeating attributes issue for me.  Thanks
1657910424

Edited 1657910695
I have one question for all the script writers. I'm using the example that kurt posted in his trigger examples github and i'd like to know if someone can help me modify it in some aspects : !script {{ --/|TRIGGER_REPLACEMENTS --/|If there are no entries in the turn order, don't do anything --?"X[*C:turnorder]X" -eq "X[]X"|SKIP --/|Split the turn order up into its components --~order|string;split;},{;[*C:turnorder] --/|Extract the first item from the turn order and grab the ID --~order1|string;replace;[{;;[&order1] --~order1|string;replaceall;";;[&order1] --~ThisTurn|string;split;,;[&order1] --~ThisTurnID|string;after;id:;[&ThisTurn1] --/|Set the card's title to the name of the token whose turn it is --#title|[*[&ThisTurnID]:t-name] --/|Display the token and an alert that it is that token's turn --+[img width=70][*[&ThisTurnID]:t-imgsrc][/img]|[b][*[&ThisTurnID]:t-name]'s turn[/b] --/|Display status effects active on the token (if any) --?"X[*[&ThisTurnID]:t-statusmarkers]" -eq "X"|NOSTATUS --+Current Effects|[*[&ThisTurnID]:t-statusmarkers] --:NOSTATUS| --/|If there was only one entry in the turn order, don't display the "on deck..." text --?[$orderCount] -eq 1|SKIP --~order2|string;replace;[{;;[&order2] --~order2|string;replaceall;";;[&order2] --~NextTurn|string;split;,;[&order2] --~NextTurnID|string;after;id:;[&NextTurn1] --+|[b][*[&NextTurnID]:t-name][/b] is on deck... --:SKIP| --X| }} 1. i'd like the message box to show "Ennemy" or anything else but the name of the npc token so my players don't know exactly what ennemy they are facing. so i guess there must be a NPC detection at some point and thus replace the npc name by another word. 2. I'd like this script to only show what's next in the turn order if it's on the Token Layer. If something is hiding on the gm layer, i'd like it to stay hidden. There's one thing i Don't know ; how will it react with a Bumped Character (as there is an invisible token on the token layer)... Can someone have a look at the script and see what's possible to modify to achieve these 2 goals ? Thanks for your help(s)
Hello, I would like some help, for a very simple macro. But, as I am a newbie, I don't success. Actually, my code is this one : !scriptcard {{ --=HowFear|?{How fear ?} [Fear] --!a:@{selected|token_id}|Fear:[$HowFear] }} It's work fine if I type directly a number at the query. Ok... good. But now, I want the text "1d4" in the attribute Fear. It doesn't work if I type "1d4" in the query, because the script roll 1d4 and keep the result. All I want is the text "1d4" in the attribute... How can I do that ? Thanks in advance if you can help me.
1657919905

Edited 1657920314
David M.
Pro
API Scripter
Lionel, does this work for you? I'm going from memory that you play 5e, so it uses the "npc" attribute (values are 0 or 1) to determine npc status. If equals 1, then turn order card will use "npc" instead of the actual token name. If an npc is on the GM layer, then no icon will be shown, though it still will say "Next turn npc". I kept that in there since if omitted, the players would know something "invisible" was next anyway as the absence of a "next turn" would tell them anyway!    You'll notice I'm parsing the turnorder a little differently. This is to handle two things: (1) if there is a custom turn (manually added) in the order, this will show it, and (2) if you use the Group Initiative script then this will handle the way that this script populates the campaign turnorder object.  !script {{ --/|TRIGGER_REPLACEMENTS --/|If there are no entries in the turn order, don't do anything --?"X[*C:turnorder]X" -eq "X[]X"|SKIP --&turnOrderStr|[*C:turnorder] --~turnOrderStr|string;replaceall;";;[&turnOrderStr] --~turnOrder|string;split;},{;[&turnOrderStr] --%i|1;2;1 -->ParseTurnOrder|[&turnOrder[&i]];[&i] --%| --:OUTPUT| --#title|[&name1] --+[&imgStr1]|[b][&name1]'s Turn[/b] --?"X[&currentEffects1]" -eq "X"|NOSTATUS --+Current Effects|[&currentEffects1] --:NOSTATUS| --+Next Turn|[&name2] --:SKIP| --X| End macro --:FUNCTIONS| --:ParseTurnOrder| accepts turnorder entry string and item number as parameters --~str|string;split;:;[%1%] --~ids|string;split;,;[&str2] --~customVals|string;split;,;[&str4] --=isNPC|[*[&ids1]:npc] --?[$isNPC] -eq 1|[ --&name[%2%]|npc --]| --?[$isNPC] -eq 0 -and [&ids1] -ne -1|[ --&name[%2%]|[*[&ids1]:t-name] --]| --?[$isNPC] -eq 0 -and [&ids1] -eq -1|[ --&name[%2%]|[&customVals1] --]| --?[*[&ids1]:t-layer] -eq gmlayer -and [$isNPC] -eq 1|[ --&imgStr[%2%]| --]|[ --&imgStr[%2%]|[img width=70][*[&ids1]:t-imgsrc][/img] --]| --&currentEffects[%2%]|[*[&ids1]:t-statusmarkers] --<| }}
1657920083

Edited 1657920092
David M.
Pro
API Scripter
Corbak, try changing your "HowFear" variable into a string type instead of a roll type. Note the ampersands ("&") instead of "=" and "$". !scriptcard {{ --&HowFear|?{How fear ?} [Fear] --!a:@{selected|token_id}|Fear:[&HowFear] }}
David M. said: Lionel, does this work for you? I'm going from memory that you play 5e, so it uses the "npc" attribute (values are 0 or 1) to determine npc status. If equals 1, then turn order card will use "npc" instead of the actual token name. If an npc is on the GM layer, then no icon will be shown, though it still will say "Next turn npc". I kept that in there since if omitted, the players would know something "invisible" was next anyway as the absence of a "next turn" would tell them anyway!    Hey David, Thanks for your answer.And thank you for remembering i'm playing 5e Just a note, I understand your point of view about the invisble guy ! On my side, i would react a little differently, more like what the players see on the turn tracker when this happens : the next player is the next visible (npc or pc). They only know something invisible is/was here when they get targeted by a vicious and tricky fireball haha. So the idea would be to show on the "next player" scriptcard the name of the next on-the-token-layer item. does that make sense ?
David M. said: Corbak, try changing your "HowFear" variable into a string type instead of a roll type. Note the ampersands ("&") instead of "=" and "$". !scriptcard {{ --&HowFear|?{How fear ?} [Fear] --!a:@{selected|token_id}|Fear:[&HowFear] }} Yes ! It works well !! Thanks you so much, David ! It helps me to understand a little bit better how works (and how fantastic) is ScriptCards.
1657923223
David M.
Pro
API Scripter
Lionel, try this? I think it does what you are asking. Bolded lines were changed. For the next turn output, we're looping through the turn entries and checking the [$hideTurn#] value, incrementing the next turn until hideTurn=0. Uses modulo division to allow "wrap around" of the turn order. I put a maxIterations limit on that loop in case there were only gmlayer npcs in the turn order to avoid an infinite loop. !script {{ --/|TRIGGER_REPLACEMENTS --/|If there are no entries in the turn order, don't do anything --?"X[*C:turnorder]X" -eq "X[]X"|SKIP --&turnOrderStr|[*C:turnorder] --~turnOrderStr|string;replaceall;";;[&turnOrderStr] --~turnOrder|string;split;},{;[&turnOrderStr] --%i|1;[$turnOrderCount];1 -->ParseTurnOrder|[&turnOrder[&i]];[&i] --%| --:OUTPUT| --#title|[&name1] --+[&imgStr1]|[b][&name1]'s Turn[/b] --?"X[&currentEffects1]" -eq "X"|NOSTATUS --+Current Effects|[&currentEffects1] --:NOSTATUS| --=t|2 --=done|0 --=maxIterations|100 --:VisibleTurnLoop| --=maxIterations|[$maxIterations] - 1 --?[$hideTurn[$t.Raw]] -eq 1|[ --=t|[$t]+1 % [$turnOrderCount] --]|[ --+Next Turn|[&name[$t.Raw]] --=done|1 --]| --?[$done] -ne 1 -and [$maxIterations] -ne 0|VisibleTurnLoop --:SKIP| --X| End macro --:FUNCTIONS| --:ParseTurnOrder| accepts turnorder string and item number as parameters --~str|string;split;:;[%1%] --~ids|string;split;,;[&str2] --~customVals|string;split;,;[&str4] --=isNPC|[*[&ids1]:npc] --?[$isNPC] -eq 1|[ --&name[%2%]|npc --]| --?[$isNPC] -eq 0 -and [&ids1] -ne -1|[ --&name[%2%]|[*[&ids1]:t-name] --]| --?[$isNPC] -eq 0 -and [&ids1] -eq -1|[ --&name[%2%]|[&customVals1] --]| --?[*[&ids1]:t-layer] -eq gmlayer -and [$isNPC] -eq 1|[ --&imgStr[%2%]| --=hideTurn[%2%]|1 --]|[ --&imgStr[%2%]|[img width=70][*[&ids1]:t-imgsrc][/img] --=hideTurn[%2%]|0 --]| --&currentEffects[%2%]|[*[&ids1]:t-statusmarkers] --<| }}
1657954084

Edited 1657958313
Hey David, It doesn't seem to do the job, i still see a announcement for a gm layer token appearing. I tried to look through the code, and i can't seem to find what's wrong, but of course my coding abilities (close to 0 :() probably don't make it jump to my eyes.... EDIT : actually, i see an invisible token annoucement when it's an invisible token's turn only, not when it's pc's turn prior to the invisible token.  For example : I have a PC, a hidden NPC, a npc. when it's pc's turn, the next turn annoucement is correct, as it annouces the visible ennemy to be next, but then i click on the next button in turn order, and i suddenly see it's an ennemy's turn, and next is the second ennemy, thus revealing there are 2 ennemies instead of only one visible. maybe an easy work around would be to "whisper to gm only" when the token is on the gm layer ?
1657972927
David M.
Pro
API Scripter
Lionel V. said: 2. I'd like this script to only show what's next in the turn order if it's on the Token Layer. If something is hiding on the gm layer, i'd like it to stay hidden. Ok, I was going off of your description that you wanted the "next turn" hidden. The following should skip the display of invisible npc turns entirely, whether it is their turn or not. Though note that when you advance the turn order from one of these tokens to the next visible token, you will get card output that looks identical to the previous one (since the "visible turn" order remains the same). I don't see an easy way around this.  !script {{ --/|TRIGGER_REPLACEMENTS --/|If there are no entries in the turn order, don't do anything --?"X[*C:turnorder]X" -eq "X[]X"|SKIP --&turnOrderStr|[*C:turnorder] --~turnOrderStr|string;replaceall;";;[&turnOrderStr] --~turnOrder|string;split;},{;[&turnOrderStr] --%i|1;[$turnOrderCount];1 -->ParseTurnOrder|[&turnOrder[&i]];[&i] --?[$hideTurn[&i]] -ne 1|[ --&visibleTurns|+[&i], --]| --%| --~turns|string;split;,;[&visibleTurns] --:OUTPUT| --?X[&turns1] -eq "X"|[ --^SKIP| --]|[ --#title|[&name[&turns1]] --+[&imgStr[&turns1]]|[b][&name[&turns1]]'s Turn[/b] --?"X[&currentEffects[&turns1]]" -eq "X"|NOSTATUS --+Current Effects|[&currentEffects[&turns1]] --]| --:NOSTATUS| --?X[&turns2] -eq "X"|[ --^SKIP| --]|[ --+Next Turn|[&name[&turns2]] --]| --:SKIP| --X| End macro --:FUNCTIONS| --:ParseTurnOrder| accepts turnorder string and item number as parameters --~str|string;split;:;[%1%] --~ids|string;split;,;[&str2] --~customVals|string;split;,;[&str4] --=isNPC|[*[&ids1]:npc] --?[$isNPC] -eq 1|[ --&name[%2%]|npc --]| --?[$isNPC] -eq 0 -and [&ids1] -ne -1|[ --&name[%2%]|[*[&ids1]:t-name] --]| --?[$isNPC] -eq 0 -and [&ids1] -eq -1|[ --&name[%2%]|[&customVals1] --]| --?[*[&ids1]:t-layer] -eq gmlayer -and [$isNPC] -eq 1|[ --&imgStr[%2%]| --=hideTurn[%2%]|1 --]|[ --&imgStr[%2%]|[img width=70][*[&ids1]:t-imgsrc][/img] --=hideTurn[%2%]|0 --]| --&currentEffects[%2%]|[*[&ids1]:t-statusmarkers] --<| }}