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

1679228295
Kurt J.
Pro
API Scripter
Kaspar K. said: If I have buttons to increase or decrease a variable, only the original value of the variable gets modified. I cant increment it multi times by pressing the same button. Here’s the example code: !script {{ --#hideTitleCard|1 --#nominmaxhighlight|1 --=TEST|1 --+Testing| [rbutton]+1::Inc[/rbutton] [rbutton]-1::Dec[/rbutton] --+TEST=|[$TEST] --X| --:Inc| --=TEST|[$TEST]+1 --+Increased to=|[$TEST] --^Skip1| --X| --:Dec| --=TEST|[$TEST]-1 --+Decreased to=|[$TEST] --^Skip1| --X| --:Skip1| --+TEST=|[$TEST] }} Any way to get it to work? So that pressing the +1 button 3 times would increment the TEST value to 2 then 3 then 4. At the end of the Skip1 branch, add --X| Essentially, an X command triggers a reentrant script to store everything in the script cache, while simply running out of commands to execute does not. I may change that behavior, as it is a bit unintuitive, but adding and explicit exit will do what you are trying to do.
Erik M. said: Dagnabbit. New campaign, new need to turn on PlayersCanUseIds. Thanks Kurt.  I'll make a note of the code block issue. Do you think there is a way I could use the library in that way without the code blocks? You should be able to do something like this: --:ApplyCondition| --^[&ConditionName]| --:Blinded| --+Blinded|[*[&Affected]:t-name] is blinded by the spell. They  suffer a –3 penalty to any rolls that rely on vision - including attack rolls - and halves their Defense. --@token-mod|_ignore-selected _ids [&Affected] _set statusmarkers|broken-skull --<| --:Charmed| --+Charmed|[*[&Affected]:t-name]'s luck may spare them from serious injury, ensure that she meets someone whose acquaintance will be valuable to them later, guarantee that she isn’t the one who gets the short straw, or help them win an important game of chance. You may invoke this twist of fate at any time as a reflexive action. If used to avoid injury, resolving this Condition reduces the damage to 1. Otherwise, no one knows the exact nature this good fortune will take when it manifests — only that it will have a significant impact. --@token-mod|_ignore-selected _ids [&Affected] _set statusmarkers|angel-outfit --<| --]|
Brilliant, Colin. Hadn't even considered that.  Thanks!
When a script (or a subscript from a button) is executed, and there is no text to output in chat, a black line still shows up. Any way to avoid that?
1680827685

Edited 1680832300
Cerubois
Pro
Sheet Author
Is there a way to add an image to the Title field? I found that it's possible in Subtitles, but not in the Title field for some reason. e.g.  --#title| [img]<picture link>[/img] Does not work.  --#leftsub| [img]<picture link>[/img] Works! While the Subtitle displays the image properly, the Title only prints the inline as a string. Is that intended? Thanks in advance! Edit: Figured I should mention I'm also using Supernotes, in case that changes things.
Test
This dagger attack script prompts the player to choose between a Melee and a Ranged attack. It then displays a unique leftsub, rightsub, and emoteText for each option. Next, it asks the player to select which modifier to use for the Finesse weapon: Strength or Dexterity. It calculates, assigns, and displays the attack and damage values based on the modifier chosen. Everything works well except it doesn't display the textEntry for a critical hit rollable table I setup on the Macros tab of Roll20. Any recommendations or assistance will be much appreciated. !scriptcard {{   --#title|Dagger --#titlecardbackground|#d110d2 --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --i;Select|q;Usage;How are you using this dagger?|Melee|Ranged   --?[&Usage] -eq Melee|[ --#emoteText|[*S:character_name] jabs his dagger at [*T:character_name] --#leftsub|Melee Weapon Attack --#rightsub|5 ft Range --]|[ --#emoteText|[*S:character_name] flings his dagger towards [*T:character_name] --#leftsub|Thrown Weapon Attack --#rightsub|20/60 ft Range --]| --i;Select|q;Skill;Use which ability?|Strength|Dexterity --?[&Skill] -eq Dexterity|[ --=Atk|?{Attack Type|Standard,1d20|Advantage, 2d20kh1|Disadvantage,2d20kl1} + @{selected|dexterity_mod} [Dex] + @{selected|pb} [Prof] --+Attack:|[$Atk] --?[$Atk.base] -eq 20|Critical --?[$Atk.base] -eq 1|Fumble --?[$Atk] -gt @{target|ac}|Damage   --+Miss:|Your attack missed --X|   --:Fumble| --+Critical Fail:|Something went wrong! --X|   --:Damage| --=Dmg|1d4 + @{selected|dexterity_mod} [Dex] --+Hit:|[$Dmg] Piercing to @{target|token_name} --X|   --:Critical| --=Dmg|1d4 + @{selected|dexterity_mod} [Dex] --+Hit:|[$Dmg] Piercing to @{target|token_name} --=Crit|[T#PiercingHit10] --+|[$Crit.tableEntryText] --X| --]|[ --=Atk|?{Attack Type|Standard,1d20|Advantage, 2d20kh1|Disadvantage,2d20kl1} + @{selected|strength_mod} [Str] + @{selected|pb} [Prof] --+Attack:|[$Atk] --?[$Atk.base] -eq 20|StrCrit --?[$Atk.base] -eq 1|StrFail --?[$Atk] -gt @{target|ac}|StrDmg   --+Miss:|Your attack missed --X|   --:StrFail| --+Critical Fail:|Something went wrong! --X|   --:StrDmg| --=Dmg|1d4 + @{selected|strength_mod} [Str] --+Hit:|[$Dmg] Piercing to @{target|token_name} --X|   --:StrCrit| --=Dmg|1d4 + @{selected|strength_mod} [Str] --+Hit:|[$Dmg] Piercing to @{target|token_name} --=Crit|[T#PiercingHit10] --+|[$Crit.tableEntryText] --X| --]|   }} Normal 0 false false false EN-US KO TH /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin-top:0in; mso-para-margin-right:0in; mso-para-margin-bottom:8.0pt; mso-para-margin-left:0in; line-height:107%; mso-pagination:widow-orphan; font-size:11.0pt; mso-bidi-font-size:14.0pt; font-family:"Calibri",sans-serif; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Cordia New"; mso-bidi-theme-font:minor-bidi;}
Is there a way to roll for failures in a scriptcard? Specifically for OWoD dice where you roll with any die over a certain value adding a success and any roll of 1 subtracting a success.  In the roll20 parser, it would be Xd10>6f<1
Randall S. said: Is there a way to roll for failures in a scriptcard? Specifically for OWoD dice where you roll with any die over a certain value adding a success and any roll of 1 subtracting a success.  In the roll20 parser, it would be Xd10>6f<1 I'm not familiar with OWoD. Does Xd10>6f<1 equate to success only on rolls over 6?
A roll of 6 or more is a success and a roll of 1 removes one success
1680981701
David M.
Pro
API Scripter
I don't see that syntax in the wiki, but here's a quick brute force function you could use. I didn't bother sorting the roll output string, but you could assign to an array and sort prior to building the string in a secondary loop.  !script {{ --#title|Successes and Failures Example --=dieSize|10 --=numDice|?{How many dice?|3} --#leftsub|Rolling [$numDice]d[$dieSize]... --=successThreshold|6 --=failureThreshold|1 --:CALL THE FUNCTION| -->RollSuccessFailures|[$numDice.Raw];[$dieSize.Raw];[$successThreshold.Raw];[$failureThreshold.Raw] --:OUTPUT| --+Die Rolls|[&rollOutputStr] --+Successes|[$numSuccesses] --+Failures|[$numFailures] --+Roll Total|[$RollTotal] --X| End macro --:FUNCTIONS| --:RollSuccessFailures|numDice, dieSize, successThreshold, failureThreshold --=numSuccesses|0 --=numFailures|0 --:ROLL DICE AND COUNT SUCCESSES/FAILURES| also builds an output string to display raw roll results on one line --%i|1;[%1%] --=thisRoll|1d[%2%] --&rollOutputStr|+[$thisRoll] --?[$thisRoll] -ge [%3%]|[ --=numSuccesses|[$numSuccesses]+1 --]| --?[$thisRoll] -le [%4%]|[ --=numFailures|[$numFailures]+1 --]| --%| --:CALCULATE ROLL RESULT| --=RollTotal|[$numSuccesses] - [$numFailures] --<| }}
Thank you! That will do the trick
1681687441

Edited 1681692952
I figured out that I needed to change [$Atk.base] to [$Atk.Base]. I also tried to clean up the script and reduce the number times it asked for user input. Everything works now for sure. Here's the new version of the script. If anyone knows any other ways in which I can simplify the script, please let me know. !scriptcard {{   --#title|Dagger --#titlecardbackground|#d110d2 --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --i;Select|q;Usage;How are you using this dagger?|MeleeDex|MeleeStr|Ranged   --?[&Usage] -eq Ranged|[ --#emoteText|[*S:character_name] flings his dagger towards [*T:character_name] --#leftsub|Thrown Weapon Attack --#rightsub|20/60 ft Range --]|[ --#emoteText|[*S:character_name] jabs his dagger at [*T:character_name] --#leftsub|Melee Weapon Attack --#rightsub|5 ft Range --]|   --?[&Usage] -eq MeleeStr|Str Attack   --=Atk|?{Attack Type|Standard,1d20|Advantage, 2d20kh1|Disadvantage,2d20kl1} + [*S:dexterity_mod] [Dex] + [*S:pb] [Prof] --+Attack:|[$Atk] --?[$Atk.Base] -eq 20|Critical --?[$Atk.Base] -eq 1|Fumble --?[$Atk] -gt [*T:ac]|Damage   --+Miss:|Your attack missed --X|   --:Fumble| --+Critical Fail:|Something went wrong! --X|   --:Damage| --=Dmg|1d4 + [*S:dexterity_mod] [Dex] --+Hit:|[$Dmg] Piercing to [*T:token_name] --X|   --:Critical| --=Dmg|1d4 + [*S:dexterity_mod] [Dex] --+Hit:|[$Dmg] Piercing to [*T:token_name] --=Crit|[T#PiercingHit10] --+|[$Crit.tableEntryText] --X|   --:Str Attack| --=Atk|?{Attack Type|Standard,1d20|Advantage, 2d20kh1|Disadvantage,2d20kl1} + [*S:strength_mod] [Str] + [*S:pb] [Prof] --+Attack:|[$Atk] --?[$Atk.Base] -eq 20|StrCrit --?[$Atk.Base] -eq 1|StrFail --?[$Atk] -gt [*T:ac]|StrDmg   --+Miss:|Your attack missed --X|   --:StrFail| --+Critical Fail:|Something went wrong! --X|   --:StrDmg| --=Dmg|1d4 + [*S:strength_mod] [Str] --+Hit:|[$Dmg] Piercing to [*T:token_name] --X|   --:StrCrit| --=Dmg|1d4 + [*S:strength_mod] [Str] --+Hit:|[$Dmg] Piercing to [*T:token_name] --=Crit|[T#PiercingHit10] --+|[$Crit.tableEntryText] --X|   }} Darth Fenris said: This dagger attack script prompts the player to choose between a Melee and a Ranged attack. It then displays a unique leftsub, rightsub, and emoteText for each option. Next, it asks the player to select which modifier to use for the Finesse weapon: Strength or Dexterity. It calculates, assigns, and displays the attack and damage values based on the modifier chosen. Everything works well except it doesn't display the textEntry for a critical hit rollable table I setup on the Macros tab of Roll20. Any recommendations or assistance will be much appreciated.
Hi all,  I'm using this scriptcard (can't remember who created it) for Turn Undead :  !script {{ --#title|@{selected|character_name} Repousse les Impies! --#leftsub|Save DC @{selected|spell_save_dc} --:(0) CREATE AN ANIMATED EFFECT WITH SPAWN SCRIPT| uses SelectManager to retain selected token --@forselected|Spawn _name|HolyBurst _expand|50,30, true _size|13,13 _order|tofront --:(1) DETERMINE CR OF UNDEAD THAT CAN BE DESTROYED| --=charLevel|@{selected|level} --?[$charLevel] -lt 5|>SetCRdestroy;0 --?[$charLevel] -ge 5 -and [$charLevel] -lt 8|>SetCRdestroy;0.5 --?[$charLevel] -ge 8 -and [$charLevel] -lt 11|>SetCRdestroy;1 --?[$charLevel] -ge 11 -and [$charLevel] -lt 14|>SetCRdestroy;2 --?[$charLevel] -ge 14 -and [$charLevel] -lt 17|>SetCRdestroy;3 --?[$charLevel] -ge 17|>SetCRdestroy;4 --:(2) GET ALL TOKENS INTO THE "allTokens" ARRAY| will have blank 1st element to be removed later --~|array;pagetokens;allTokens;@{selected|token_id} --:(3) CREATE THE "inRange" ARRAY TO HOLD TOKENS IN RANGE| --~|array;define;inRange; --:(4) PREP ARRAY FOR LOOP| if no array elements then end macro --~tokenid|array;getfirst;allTokens --?[&tokenid] -eq ArrayError|endOutput --:(5) FIND ALL TOKENS IN RANGE| --:RangeLoop| --:TOKEN MUST BE ON OBJECTS OR GMLAYER AND TYPE MUST INCLUDE UNDEAD| --?[*[&tokenid]:t-layer] -ne objects -and [*[&tokenid]:t-layer] -ne gmlayer|NextToken --?"[*[&tokenid]:npc_type]" -ninc "undead"|NextToken --:CHECK DISTANCE IN UNITS. 30ft is 6UNITS| --~dist|distance;@{selected|token_id};[&tokenid] --?[$dist] -gt 5|NextToken --:ADD TO THE "inRange" ARRAY| --~|array;add;inRange;[&tokenid] --:NextToken| --~tokenid|array;getnext;allTokens --?[&tokenid] -ne ArrayError|RangeLoop --:(6) REMOVE DUMMY FIRST ITEM IN inRange ARRAY| --~|array;removeat;inRange;0 --:(7) ROLL SAVES FOR EACH TOKEN IN RANGE| if fail, set a token condition marker to denote turned --~tokenid|array;getfirst;inRange --?[&tokenid] -eq ArrayError|End --=i|0 --:SaveLoop| --=i|[$i]+1 --&FailureText| -->GetSaveBonus|[&tokenid];wisdom;wis --=SaveRoll|1d20 + [$saveBonus] [BONUS] --?[$SaveRoll.Total] -ge @{selected|spell_save_dc}|>MadeSave;[$i]|>FailedSave;[$i] --~tokenid|array;getnext;inRange --?[&tokenid] -ne ArrayError|SaveLoop --:End| --X| --:PROCEDURES| --:SetCRdestroy| accepts CR as parameter --=CRdestroy|[%1%] --<| --:GetSaveBonus| accepts tokenid, full attribute name, short attribute name as parameters --:TAKE THE GREATER OF "attribute_save_bonus" OR "npc_attr_save_base"| --=bonus1|[*[%1%]:[%2%]_save_bonus] --&bonus2|[*[%1%]:npc_[%3%]_save_base] --:SOMETIMES "npc_attr_save_base" IS BLANK, SO SET TO -99. OTHERWISE USE ATTR VALUE| --?X[&bonus2] -eq "X"|>Set_npc_attr_save_bonus;-99|>Set_npc_attr_save_bonus;[&bonus2] --:FINALLY SET THE SAVE BONUS| --?[$bonus2] -gt [$bonus1]|>SetSaveBonus;[$bonus2]|>SetSaveBonus;[$bonus1] --<| --:Set_npc_attr_save_bonus| blank value is set to -99, otherwise use value stored in attribute --=bonus2|[%1%] --<| --:SetSaveBonus| --=saveBonus|[%1%] --<| --:MadeSave| --*[*[&tokenid]:character_name]:|[#009900][b]JP Réussi[/b][/#] [$SaveRoll] --+Creature [%1%]:|[#009900][b]JP Réussi[/b][/#] [$SaveRoll] --<| --:FailedSave| add either a dead or fear condition marker to the token, depending on CR --=CR|[*[&tokenid]:npc_challenge] --?[$CR] -le [$CRdestroy]|>AddConditionMarker;[&tokenid];dead;-Dest.|>AddConditionMarker;[&tokenid];Terrorise::3359274;-Peur --*[*[&tokenid]:character_name]:|[#990000][b]JP Raté[/b][/#] [$SaveRoll] [b][&FailureText][/b] --+Creature [%1%]:|[#990000][b]JP Raté[/b][/#] [$SaveRoll] [b][&FailureText][/b] --<| --:AddConditionMarker| accepts tokenID, condition marker, and descriptive text as parameters --@token-mod|_ignore-selected _ids [%1%] _set statusmarkers|[%2%] --&FailureText|[%3%] --<| }} I have a question about this.  Some monsters are "resistant" to be turned (ghast for example has an advantage on saving throws) and some others (in ravenloft) are immune to it.  Can there be a possibility of adding a text in the npc sheet (like "turn" in resistance or immunities) and have the scriptcard verify if this text is present when doing the saving throw ? It is verifying if the monster is an undead type already so i was wondering if something like that can be added.. how can the scriptcard  be re-written/amended to include this parameter ? Thank you for your help if anyone can. 
Without diving into the character sheets directly to see exactly where that is listed, I can't give you the specific calls to make. But! You should be able to do something like this: Use the repeating row search function to look through the NPC ability section Check each repeating row for the name of the ability and compare it against the specific named abilities you're looking for If match immunity--> end script (or message to chat) If match resistance-->alter the roll portion of the script to account for advantage If never found-->end sub
1681905195
David M.
Pro
API Scripter
Following up on Colin's advice, I would probably pull the SaveRoll part out of the SaveLoop and turn that into its own subprocedure (called MakeSave?) that accepts the tokenid and an advantage flag as parameters. Put all of Colin's logic into another procedure (called CheckResistanceImmunity?) that assigns a variable based on one of the three cases (Normal/Resistant/Immune). If immune, then skip calling the MakeSave procedure. Otherwise, pass the variable to your MakeSave function and handle the actual roll type with conditionals.
Thank to you both fro your answers. All right i understand the full theory.  May be it's easier to add something like "turn" in the resistance or the immunities lines in the npc sheet (and making it the default token afterwards)  than checking in the abilities of the npc sheet as this ability seems to change name depending on the monster... But even though i get the full theory, i'm absolutely not capable of programming that.  Programming this is beyond my capacities, but checking for immunities or resistances might be interesting for the type of damages in all the other scriptacrds, don't you think ?  @David M. I know that this check it is something that you installed on smart AoE to check for immunities or resistances, but i haven't been able to find something like this in scriptcards.  Creating these procedures of checks and saves would be interesting to insert in the other scriptcards, wouldn't it ? If any of you scriptomancers could create these loops and checking procedures, (at least in the turn undead scriptcard) that'd be wonderfully helpful.  Thanks in advance.
I have a attack damage SC that has a lot of extra modifiers.  Including options for changing how damage is handled.  My current question. I have an option where if a "button" on the character sheet is toggled, the damage output is changed from a default of XdY+Z format to roll twice and take the higher of the two.  I've searched this thread and its previous for a way to do this, and I cant seem to find a way that doesn't involve exploding dice. The code I'm currently using to handle the toggle check is: --/| ===== Tearing QUALITY =========== |\ --?@{q-tearing} -eq 1|Tearing --?@{q-tearing} -eq 0|NoTearing --:Tearing| --&DmgTearing| --^TearingDone| --:NoTearing| --&DmgTearing|0 --^TearingDone| --:TearingDone| --=DmgTearing|[&DmgTearing] I realize that the following is just a wall of text and probably wont help much without my character sheet, but for reference here is the overall code I'm using.  I understand it is kinda a mess.  And there probably a better to write what I want to do, however, I know just enough code to be... dangerous. Any help on getting it so that it displays the proper value.  Roll twice take the better value. !scriptcard {{ --/| === ScriptCard Layout for Combined Hit/Damage === |\-- --/| === Version 1.0 === |\-- --/| === Date: 04/20/2023 === |\-- --/| Local Variables --|\ --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} --/| ===== Roll Queries / Information Lookup =========== |\ --&AimType|?{Aim | No aim (+0),+0 | Half aim (+10),+10| Full aim (+20),+20} --&RoFType|?{Rate of Fire/Attack Type| Standard (+0),+0 | Semi auto (+10),+10 | Full Auto (+20),+20 | Called Shot (-20),-20 | Suppressing Fire (-20),-20} --&AtkMod|?{Modifier|0} --&HitLocation|?{Hit Location|Head, Head|Left Arm, LeftArm|Right Arm, RightArm|Body, Body|Left Leg, LeftLeg|Right Leg, RightLeg} --/| ===== Convert RQ Value into int variables --=AtkModNum|[&AtkMod] --=AimTypeNum|[&AimType] --=RangeNum|[&RangeType] --=RoFNum|[&RoFType] --/| ===== Degrees of Success --&DoSNum|?{Degrees of Success?|0} --=DegSuccess|[&DoS] --/| ===== Strings =========== |\ --&AtkName|@{atkName} --&DmgRoll|@{damage} --&WeapNotes|@{notes} --/| ===== Numbers =========== |\ --=AtkType|0 --=DmgPen|@{penetration} --=clip|@{clip} --=clipMax|@{clip|max} --/| ===== Numbers =========== |\ --=DmgPen|@{penetration} --&DamageRoll|@{damage} --&DamageMod|@{damagemod} --&TotalDam|@{damage}!+@{damagemod} --=FinalDamRoll|0 --=TBon|@{target|tou-mod} --=HAV|[*T:headArmourvalue] --=LAAV|[*T:LeftArmArmourvalue] --=BAV|[*T:BodyArmourvalue] --=RAAV|[*T:RightArmArmourvalue] --=LLAV|[*T:LeftLegArmourvalue] --=RLAV|[*T:RightLegArmourvalue] --=HSoak|[*T:armor-head-soak] --=LASoak|[*T:armor-leftarm-soak] --=BSoak|[*T:armor-body-soak] --=RASoak|[*T:armor-rightarm-soak] --=LLSoak|[*T:armor-leftleg-soak] --=RLSoak|[*T:armor-rightleg-soak] --=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^] --/| ===== Weapon Proficiency Full Display =========== |\ --?@{wProficiency} -eq Yes|Yes --?@{wProficiency} -eq No|No --:Yes| --&wProficiency|Yes --^wProficiencyDisplayDone| --:No| --&wProficiency|No --^wProficiencyDisplayDone| --:wProficiencyDisplayDone| --/| ===== DAMAGE TYPE Full Display =========== |\ --?@{wType} -eq E|E --?@{wType} -eq I|I --?@{wType} -eq R|R --?@{wType} -eq X|X --?@{wType} -eq N|N --:E| --&DmgTypeDisplay|Energy --^DMGTypeDone| --:I| --&DmgTypeDisplay|Impact --^DMGTypeDone| --:R| --&DmgTypeDisplay|Rending --^DMGTypeDone| --:X| --&DmgTypeDisplay|Explosive --^DMGTypeDone| --:N| --&DmgTypeDisplay|None --^DMGTypeDone| --:DMGTypeDone| --/| ===== Weapon Type Full Display =========== |\ --?@{wClass} -eqi basic|Basic --?@{wClass} -eqi heavy|Heavy --?@{wClass} -eqi melee|Melee --?@{wClass} -eqi pistol|Pistol --?@{wClass} -eqi thrown|Thrown --:Basic| --&wClassDisplay|Basic --&AtkType|[*S:bs-base] [BS] --^wClassDisplayDone| --:Heavy| --&wClassDisplay|Heavy --&AtkType|[*S:bs-base] [BS] --^wClassDisplayDone| --:Melee| --&wClassDisplay|Melee --&AtkType|[*S:ws-base] [WS] --&MeleePenalty|-30 --^wClassDisplayDone| --:Pistol| --&wClassDisplay|Pistol --&AtkType|[*S:bs-base] [BS] --^wClassDisplayDone| --:Thrown| --&wClassDisplay|Thrown --&AtkType|[*S:bs-base] [BS] --^wClassDisplayDone| --:wClassDisplayDone| --/| ===== Functions =========== |\ --~sqRange|distance;@{selected|token_id};@{target|token_id} --=Range|[$sqRange] [Squares] * 1 [meters] --?[$Range] -le 3|RngPB --?[$Range] -ge 3 -and [$Range] -le @{range-s}|RngShort --?[$Range] -ge @{range-s} -and [$Range] -le @{range-n}|RngNormal --?[$Range] -ge @{range-n} -and [$Range] -le @{range-m}|RngMed --?[$Range] -ge @{range-m} -and [$Range] -le @{range-l}|RngLong --?[$Range] -ge @{range-e}|RngExtreme --:RngPB| --&AtkRange|30+[&MeleePenalty] [Point Blank] --&RngDisplay|Point Blank --^RngDone|Done --:RngShort| --&AtkRange|10 [Short] --^RngDone|Done --&RngDisplay|Short --:RngNormal| --&AtkRange|0 [Normal] --&RngDisplay|Normal --^RngDone|Done --:RngMed| --&AtkRange|0 [Medium] --&RngDisplay|Medium --^RngDone|Done --:RngLong| --&AtkRange|-10 [Long] --&RngDisplay|Long --^RngDone|Done --:RngExtreme| --&AtkRange|-30 [Extreme] --&RngDisplay|Extreme --^RngDone|Done --:RngDone| --/| ============== DAMAGE CALCULATIONS ========== --/| ===== SOAK DETAILS =========== --?[&HitLocation] -eqi Head|H --?[&HitLocation] -eqi LeftArm|LA --?[&HitLocation] -eqi Body|B --?[&HitLocation] -eqi RightArm|RA --?[&HitLocation] -eqi LeftLeg|LL --?[&HitLocation] -eqi RightLeg|RL --:H| --&LocDisplay|Head --=LocAV|[$HAV] --=LocSoak|[$HSoak] --^LocationDone| --:LA| --&LocDisplay|Left Arm --=LocAV|[$LAAV] --=LocSoak|[$LASoak] --^LocationDone| --:RA| --&LocDisplay|Right Arm --=LocAV|[$RAAV] --=LocSoak|[$RASoak] --^LocationDone| --:B| --&LocDisplay|Body --=LocAV|[$BAV] --=LocSoak|[$BSoak] --^LocationDone| --:LL| --&LocDisplay|Left Leg --=LocAV|[$LLAV] --=LocSoak|[$LLSoak] --^LocationDone| --:RL| --&LocDisplay|Right Leg --=LocAV|[$RLAV] --=LocSoak|[$RLSoak] --^LocationDone| --:LocationDone| --/| === DAMAGE CALCULATIONS === --=DmgPen|@{penetration} --=LocPen|[$LocAV] - [$DmgPen] {MIN:0} --/| ===== ACCURATE QUALITY =========== |\ --=DegSuccess|[&DoSNum] --=AccuracyNumDice|[$DegSuccess] / 2 {MAX:2} --?[$AimTypeNum] -gt 0 -and @{q-accurate} -eq 1|Accurate --?[$AimTypeNum] -eq 0 -or @{q-accurate} -eq 0|NoAccurate --:Accurate| --&DmgAccurate|[$AccuracyNumDice]d10! [Accurate] --^AccurateDone| --/| Fail Catch not working..... --:NoAccurate| --&DmgAccurate|0 --^AccurateDone| --:AccurateDone| --=DmgAccurate|[&DmgAccurate] --/| ======== Sheet Workers Title/Subtitle Code ======== |\ --#title|@{atkName} --#titlecardbackground|#993333 --#leftsub|[$Range] m. [&RngDisplay] --#rightsub|Ammo @{clip}/@{clip|max} --#emoteText|[*S:t-name] attacks [*T:t-name] --/| ===== Special Qualites that effect the attack roll ====== |\ --/| ===== Tearing QUALITY =========== |\ --?@{q-tearing} -eq 1|Tearing --?@{q-tearing} -eq 0|NoTearing --:Tearing| --&DmgTearing| --^TearingDone| --:NoTearing| --&DmgTearing|0 --^TearingDone| --:TearingDone| --=DmgTearing|[&DmgTearing] --/| ===== Inaccurate QUALITY =========== |\ --/| @@ DETAILS: This overides the AIMTYPE variable to ZERO (0) instead of adding a new component to the AtkTarget string. --?@{q-inaccurate} -eq 1|Inaccurate --?@{q-inaccurate} -eq 0|NoInaccurate --?@{q-defensive} -eq 1|Defensive --?@{q-defensive} -eq 0|NoDefensive --:Inaccurate| --&AimType|0 --^InaccurateDone| --:NoInaccurate| --^InaccurateDone| --:InaccurateDone| --?@{q-defensive} -eq 1|Defensive --?@{q-defensive} -eq 0|NoDefensive| --:Defensive| --&AtkDefensive|-10 [Defensive] --^DefensiveDone| --:NoDefensive| --&AtkDefensive|0 --^DefensiveDone| --:DefensiveDone| --=AtkTarget|[&AtkType] + [&AimType] [Aim] + [&AtkAccurate] [Accuracy] + [&AtkRange] + [&RoFType] [Rate of Fire] + [&AtkDefensive] + [&AtkMod] [Modifier] --=AtkRoll|1d100 --&BodyHit|Null --=DegSuccess|[$AtkTarget] - [$AtkRoll] \ 10 --/| ===== TEARING QUALITY =========== |\ --/| ===== The Tearing Quality Cannot be Implemented at this Time. --/| @@@ FINAL DAMAGE ROLL ===================================== |\ --=TotalSoak|[$TBon] + [$LocPen] --=FinalDamRoll|@{damage}!+@{damagemod} --/| === WEAPON NOTES === --+|[c][#f00][&WeapNotes][/#][/c] --/| === WEAPON DETAILS === --+|[c]● Weapon Details ●[/c] --+[t border=1 width=100%][tr][td][c]Class[/c][/td][td][c]Type[/c][/td][td][c]Damage[/c][/td][td][c]Pen[/c][/td][/tr][tr][td][c][&wClassDisplay][/c][/td][td][c][&DmgTypeDisplay][/c][/td][td][c]@{damage}[/c][/td][td][c][$DmgPen][/c][/td][/tr][/t]| --/| === Roll Details Tables --+|[c]● Roll Details ●[/c] --+[c][t border=2 width=95% align=center][tr][td][b]Skill [/b][/td][td][b]Aim [/b][/td][td][b]Range [/b][/td][td][b]RoF [/b][/td][td][b]Modifier [/b][/td][/tr][tr][td][&AtkType][/td][td][&AimType][/td][td][&AtkRange][/td][td][&RoFType][/td][td][&AtkMod][/td][/tr][/t][/c]| --/| ======= Test Output for Debugging (Hide When Code is Complete) ======== --/|[c][t border=2 width=95% align=center][tr][td][b]Skill [/b][/td][td][b]Aim [/b][/td][td][b]Range [/b][/td][td][b]RoF [/b][/td][td][b]Modifier [/b][/td][/tr][tr][td]XX[/td][td][$AimTypeNum][/td][td][$RangeNum][/td][td][$RoFNum][/td][td][$AtkModNum][/td][/tr][/t][/c]| --+|[c][t border=2 width=95% align=center][tr][td][b]Total [/b][/td][td][b]Target [/b][/td][/tr][tr][td][$AtkRoll] [/td][td][$AtkTarget] [/td][/tr][/t][/c] --/| ====== Count the Number of Allowed Attacks --/| The Rate of fire is 1 + [Rate of Fire Modifier] + [Scatter Modifier] * [Storm Weapon Modifier] --/| Rate of Fire Mods -> --/| Automatic = 1 per 1 degrees of success --/| Semi-Automatic = 1 per 2 degrees of success --/| Point-Blank + Scatter = Base * 2 --/| Storm (Blood of Martyrs) = Base * 2 (Doubles the Number of Shots Fired) --/| The number of extra shots fired is cannot exceed the number of rounds in the gun (its overall rate of fire) or charge capacity for energy weapons. --/| Regardless of successful hits the amount of ammo expended is 1 per shot fired. --/| ====== Check And Assign Number of Attacks based on rate of fire. --/| Number of Attacks - Addititve --?[$RoFNum] -le 0|NoExtra --?[$RoFNum] -eq 10 -and [$DegSuccess.Total] -ge 0|SemiAuto --?[$RoFNum] -eq 20 -and [$DegSuccess.Total] -ge 0|FullAuto --:SemiAuto| --=MaxAtk|@{rof2} --=RoFMod|[$DegSuccess.Total] [Successes] / 2 {CEIL} {MAX:@{rof2}} [Semi Auto] --^RoFDone| --:FullAuto| --=MaxAtk|@{rof3} --=RoFMod|[$DegSuccess.Total] [Successes] / 1 {CEIL} {MAX:@{rof3}} [Full Auto] --^RoFDone| --/| Reserved for possible Future Use and Error Checking --:NoExtra| --=MaxAtk|@{rof1} --=RoFMod|0 [No Extra Attacks] --^RoFDone| --:RoFDone| --/| ====== Check if the number of sucesses is at least 0 (a non-negative number) --?[$DegSuccess.Total] -le -1|DegDone --?[$DegSuccess.Total] -ge 0|Continue --:Continue| --=NumAtkBase|1 --^DegDone| --/| ==== Reserved for possible Future Use and Error Checking --:DegError| --^DegDone| --:DegDone| --/| Number of Attacks - Multiplicative --=NumAtks|[$NumAtkBase.Total] [Base] + [$RoFMod.Total] [Rate of Fire] --/| ====== Check and assign number of attacks based on SCATTER and RANGE. --/| @@ DETAILS: It is set to "30" because the output of the Roll Query is +30, as in thats how much the bonus to hit is. --/| @@ DETAILS: The equation basically is checking if the range is Point Blank and is Scatter selected. --?[$RangeNum] -ge 30 -and @{q-scatter} -eq 1|Scatter --?[$RangeNum] -lt 30 -or @{q-scatter} -eq 0|NoScatter --:Scatter| --=NumAtkScatter|[$NumAtks] * 2 --^ScatterDone| --:NoScatter| --=NumAtkScatter|0 --^ScatterDone| --:ScatterDone| --/| ====== Check and assign number of attacks based on STORM --?@{q-storm} -eq 1|Storm --?@{q-storm} -eq 0|NoStorm --:Storm| --=MaxAtk|[$MaxAtk]*2 --=NumAtkStorm|[$NumAtks] * 2 --^StormDone| --:NoStorm| --=NumAtkStorm|0 --^StormDone| --:StormDone| --+[c] ● Number of HITS ● [/c]| --=NumAtksTotal|[$RoFMod] [RoF] + [$NumAtkBase.Total] [Base] + [$NumAtkScatter] [Scatter] + [$NumAtkStorm] [Storm] {MAX:[$MaxAtk]} --/| +Num|[$RoFMod] [RoF] + [$NumAtkBase.Total] [Base] + [$NumAtkScatter] [Scatter] + [$NumAtkStorm] [Storm] = --+|[c][b][$NumAtksTotal.Total][/b][/c] --/| ====== Check if AttackRoll is less than the test THRESHOLD --?[$AtkRoll.Total] -le [$AtkTarget.Total]|Success --?[$AtkRoll.Total] -gt [$AtkTarget.Total]|Failure --:Success| --+[c][#3FB315]HIT! ([$DegSuccess.Total])[/#][/c]| --^Done| --:Failure| --+[c][#B31515]MISS! ([$DegSuccess.Total])[/#][/c]| --^Done| --:Jam| --+[c]JAM![/c]| --^Done| --:Done| --?[$AtkRoll] -lt 10|[ --&rollStr|0[$AtkRoll.Raw] --]|[ --&rollStr|[$AtkRoll.Raw] --]| --~len|string;length;[&rollStr] --%i|[$len];1;-1 --~s|string;substring;[&i];1;[&rollStr] --&revStr|+[&s] --%| --=revRoll|[&revStr] --/| === Out of Range Values Included for Debugging === --<| --?[$revRoll] -le 0|>SetHitLocation;Error - Out of Range --?[$revRoll] -le 10|>SetHitLocation;Head --?[$revRoll] -ge 11 -and -le 20|>SetHitLocation;Right Arm --?[$revRoll] -ge 21 -and -le 30|>SetHitLocation;Left Arm --?[$revRoll] -ge 31 -and -le 70|>SetHitLocation;Body --?[$revRoll] -ge 71 -and -le 85|>SetHitLocation;Right Leg --?[$revRoll] -ge 86|>SetHitLocation;Left Leg --?[$revRoll] -ge 101|>SetHitLocation;Error - Out of Range --+[c][b][#3FB315][&BodyHit][/#][/b][/c]| --X| End Macro --:PROCEDURES| --:SetHitLocation| accepts hit location as parameter --&BodyHit|[%1%] --<| --/| The HTML escape code is required because the "<>" is being interprated as an html tag. It sucks. --+|[c] ● [&LocDisplay] ● [/c] --+[t border=1 width=100%] [tr] [td][c]Toughness[/c][/td] [td][c]Armor[/c][/td] [td][c]Pen[/c][/td] [td][c]Soak[/c][/td] [/tr] [tr] [td][c][$TBon][/c][/td] [td][c] [$LocAV] [/c][/td] [td][c][$DmgPen][/c][/td] [td][c][$TotalSoak][/c][/td] [/tr] [/t]| --/|[b]Tou:[/b] [$TBon] [b]AV:[/b] [$LocAV] [b]Weap Pen[/b] [$DmgPen] --+|[c] ● DMG Details ● [/c] --+|[f18][c][b][$FinalDamRoll] + [$DmgAccurate][/b][/c][/f] --/|Degrees of Success|[$DegSuccess] }}
Lionel V. said: Thank to you both fro your answers. All right i understand the full theory.  May be it's easier to add something like "turn" in the resistance or the immunities lines in the npc sheet (and making it the default token afterwards)  than checking in the abilities of the npc sheet as this ability seems to change name depending on the monster... But even though i get the full theory, i'm absolutely not capable of programming that.  Programming this is beyond my capacities, but checking for immunities or resistances might be interesting for the type of damages in all the other scriptacrds, don't you think ?  @David M. I know that this check it is something that you installed on smart AoE to check for immunities or resistances, but i haven't been able to find something like this in scriptcards.  Creating these procedures of checks and saves would be interesting to insert in the other scriptcards, wouldn't it ? If any of you scriptomancers could create these loops and checking procedures, (at least in the turn undead scriptcard) that'd be wonderfully helpful.  Thanks in advance. So, anyone willing/able/interested to write this turn undead scriptacrd with the resistance or immunity conditional ? thanks 
1682452163
Kurt J.
Pro
API Scripter
ScriptCards 2.3.4 The latest dev version of ScriptCards is on the repo  with the following changes since the last OneClick update (this is also queued for OneClick): Object modification (--!) now supports setting the defaulttoken property for a character Corrected a bug in [*P:...] referencing when an active page has not been set Exiting a foreach loop as the result of a conditional will now preserve the control variable after the loop ends. Previously it would be cleared. For consistency, a foreach loop that exits normally will leave the final value intact. [button], [sheetbutton], and [rbutton] structures now support setting a tooltip. Include the tooltip in the opening tag after the button declaration: [button:My Tooltip Text!]Button Capton::Action[/button] . Your tool tip text cannot start with # or end with px so it doesn't get confused with color and pixel signifiers. ScriptCards now supports "Roll with Emphasis" via the XdYe roll formula. For example, 2d20e. Rolling with emphasis returns the result furthest away from the middle number on the die, so 2d20e that rolls 8 and 19 will be a 19 since it is further away from 10. If the two numbers are equidistant from the middle number, the higher value is returned.
NICE! Kurt J. said: ScriptCards 2.3.4 The latest dev version of ScriptCards is on the repo  with the following changes since the last OneClick update (this is also queued for OneClick): Object modification (--!) now supports setting the defaulttoken property for a character Corrected a bug in [*P:...] referencing when an active page has not been set Exiting a foreach loop as the result of a conditional will now preserve the control variable after the loop ends. Previously it would be cleared. For consistency, a foreach loop that exits normally will leave the final value intact. [button], [sheetbutton], and [rbutton] structures now support setting a tooltip. Include the tooltip in the opening tag after the button declaration: [button:My Tooltip Text!]Button Capton::Action[/button] . Your tool tip text cannot start with # or end with px so it doesn't get confused with color and pixel signifiers. ScriptCards now supports "Roll with Emphasis" via the XdYe roll formula. For example, 2d20e. Rolling with emphasis returns the result furthest away from the middle number on the die, so 2d20e that rolls 8 and 19 will be a 19 since it is further away from 10. If the two numbers are equidistant from the middle number, the higher value is returned.
Is there a command to take the roll x number of times and keep the better/worse of the two rolls, when the roll is not hardcoded it is user entered in text field. Lets say there is a weapon damage field for a repeating section and the damage is listed as 1d10.  When the weapon crits it is rolled 2x and takes it rolls 2x and takes the better of the two.  But not all weapons will have the same damage, obviously.  I posted this question earlier, but I think I might have posted too much extra shit and no one saw the question for the unneeded junk.
1682495287
Kurt J.
Pro
API Scripter
Toby said: Is there a command to take the roll x number of times and keep the better/worse of the two rolls, when the roll is not hardcoded it is user entered in text field. Lets say there is a weapon damage field for a repeating section and the damage is listed as 1d10.  When the weapon crits it is rolled 2x and takes it rolls 2x and takes the better of the two.  But not all weapons will have the same damage, obviously.  I posted this question earlier, but I think I might have posted too much extra shit and no one saw the question for the unneeded junk. 2d10kh1 will roll 2d10 and keep the highest number, but unless there is a separate "crit damage" field on the sheet that is used instead of the normal damage, you would need to pull the 1d10 apart and modify it in code to turn it into 2d10kh1. Not terribly difficult, but certainly not automatic.
Kurt J. said: 2d10kh1 will roll 2d10 and keep the highest number, but unless there is a separate "crit damage" field on the sheet that is used instead of the normal damage, you would need to pull the 1d10 apart and modify it in code to turn it into 2d10kh1. Not terribly difficult, but certainly not automatic. So... How does one "pull it apart?"
1682777680
Kurt J.
Pro
API Scripter
Toby said: Kurt J. said: 2d10kh1 will roll 2d10 and keep the highest number, but unless there is a separate "crit damage" field on the sheet that is used instead of the normal damage, you would need to pull the 1d10 apart and modify it in code to turn it into 2d10kh1. Not terribly difficult, but certainly not automatic. So... How does one "pull it apart?" Here is a sample. Assuming the damage die from the character sheet is in "RollBase" as a string variable (the first line) you can use before and after along with inline calculations to double the number of dice rolled and keep the highest number of original count dice. This could be very much condensed, but I wrote it verbosely to make each step more obvious. !script {{ --&RollBase|2d10 --&Count|[&RollBase(before,d)] --+Count|[&Count] --&DieType|[&RollBase(after,d)] --+DieType|[&DieType] --&NewRoll|[=[&Count]*2]d[&DieType]kh[&Count] --+NewRoll|[&NewRoll] --=CritDamage|[&NewRoll] --+Crit Damage|[$CritDamage] }}
Kurt J. said: Here is a sample. Assuming the damage die from the character sheet is in "RollBase" as a string variable (the first line) you can use before and after along with inline calculations to double the number of dice rolled and keep the highest number of original count dice. This could be very much condensed, but I wrote it verbosely to make each step more obvious. 00: !script {{ 01: --&RollBase|2d10 02: --&Count|[&RollBase(before,d)] 03: --+Count|[&Count] 04: --&DieType|[&RollBase(after,d)] 05: --+DieType|[&DieType] 06: --&NewRoll|[=[&Count]*2]d[&DieType]kh[&Count] 07: --+NewRoll|[&NewRoll] 08: --=CritDamage|[&NewRoll] 09: --+Crit Damage|[$CritDamage] 10: }} So let me make sure I have somewhat of an understanding of how this works.. 01: Variable &RollBase pulls the value of the damage field.  I assume I could use |@{damageRoll} or |[*T:damageRoll] just as easily. 02: Performs a strlen() style command to get the result of everything before the character "d" within the variable &RollBase. 03: Does the same as above but for after the letter "d". 06: I am NOT entirely sure I understand the syntax construction for line 6.  Although, the basic purpose I get.  It doubles the number of dice then re-adds the dice type and then add the keep highest dice roll command. 08: Assigns the final value to the variable named &CritDamage. So from what I'm understanding, that each time the script executes the calculation is performed regardless of weather or not the "CritDamage" is used.  So, in theory I could have this function run at the start of a scriptcards.. save the "CritDamage" and only display it the scriptcard detects a critical? Also, you mentioned that this could be condensed I'm assuming condensing it would be something like: --=CritDamage| [[&RollBase(before,d)]*2]d [&RollBase(after,d)]kh[&RollBase] Thanks again for the help!
Okay here is an interesting question, When I use &RollBase[*S:damage] it comes out as undefined.  But if I use  &RollBase| @{damage} it works.  Are they not the same thing?  Is their a quirk of the script cards that would cause one to work intermittently?
Hi Toby! If I understood correctly, you're trying to set the variable "&RollBase" to "[*S:damage]," but I don't see a | in between these two like I do for your @{damage} example that worked. Not sure if that was a simple typo or an actual copy-paste, but I thought it might be worth pointing out just in case.
a typo, since I was typing out the code fast in the forum post.  And this isn't the first time where I've had this issue where the [*S:attributename] or [*T:attributename] didn't work and @{target|xxxx}, @{xxxx} and or @{selected|xxxx} does function.  I'm not sure what the issue is, but I am 100% certain it is breaking other sections of my code. I'm tying to keep track of all the interactions between ScriptCards and character sheets and rolltemplates so I can become an expert on how they interact.  I already know that ScriptCards cannot work with autoCalc fields but can work with SheetWorkers calculated fields.  And I also know that ScriptCards output displays differently on the Live Server vs. the Character Sheet Sandbox.  I've asked about that several times and NEVER gotten an answer or even a response.
Fair enough! Sorry to hear it wasn't as simple as forgetting the correct "punctuation," so to speak. I'm unfortunately not well-versed enough to give more guidance, but I hope someone else can drop by with better insight.
1683030055
Kurt J.
Pro
API Scripter
Toby said: a typo, since I was typing out the code fast in the forum post.  And this isn't the first time where I've had this issue where the [*S:attributename] or [*T:attributename] didn't work and @{target|xxxx}, @{xxxx} and or @{selected|xxxx} does function.  I'm not sure what the issue is, but I am 100% certain it is breaking other sections of my code. I'm tying to keep track of all the interactions between ScriptCards and character sheets and rolltemplates so I can become an expert on how they interact.  I already know that ScriptCards cannot work with autoCalc fields but can work with SheetWorkers calculated fields.  And I also know that ScriptCards output displays differently on the Live Server vs. the Character Sheet Sandbox.  I've asked about that several times and NEVER gotten an answer or even a response. Have you set --#sourcetoken prior to using [*S:damage]? If not, [*S:...] will have no meaning.
Yes.
I've run into a small snag with a pair of procedures.  I am trying to use the hit roll to determine what part of the body is struck by an attack.  While this part works, when I try to some of the output elements based on this.  Everything starts to break down.  The below section of code is the relevant areas with the two procedures that are attempting to handle this.  They each work seperately on their own but when combined they fail. !scriptcards {{     ......     ......     ......     Lots irrelevant code goes before..     ..... --+[c] ●  Number of HITS  ● [/c]| --=NumAtksTotal|[$RoFMod] [RoF] + [$NumAtkBase.Total] [Base] + [$NumAtkScatter] [Scatter] + [$NumAtkStorm] [Storm] {MAX:[$MaxAtk]}     --/| +Num|[$RoFMod] [RoF] + [$NumAtkBase.Total] [Base] + [$NumAtkScatter] [Scatter] + [$NumAtkStorm] [Storm] =  --+|[c][b][$NumAtksTotal.Total][/b][/c] --/| ====== Check if AttackRoll is less than the test THRESHOLD --?[$AtkRoll.Total] -le [$AtkTarget.Total]|Success --?[$AtkRoll.Total] -gt [$AtkTarget.Total]|Failure --:Success| --+[c][#3FB315]HIT! ([$DegSuccess.Total])[/#][/c]| --^Done| --:Failure| --+[c][#B31515]MISS! ([$DegSuccess.Total])[/#][/c]| --^Done| --:Jam| --+[c]JAM![/c]| --^Done| --:Done|         --/| Is the attack a SUCCESS a FAIL or a JAM. The code to detect JAMS is incomplete, treat all JAMS as simple failures. --?[$AtkRoll] -lt 10|[ --&rollStr|0[$AtkRoll.Raw] --]|[ --&rollStr|[$AtkRoll.Raw] --]| --~len|string;length;[&rollStr] --%i|[$len];1;-1 --~s|string;substring;[&i];1;[&rollStr] --&revStr|+[&s] --%| --=revRoll|[&revStr]             --/| This code takes the two or three digit HIT value, reverses it 53 becomes 35 and uses that value to match against a table         --/| in the DARK HERESY CORE book to tell where the hit struck on a normal bipedal creature. --/| === Out of Range Values Included for Debugging, however, there is no code to catch out or range values so it should never return one.. --<| --?[$revRoll] -le 0|>SetHitLocation;Error - Out of Range --?[$revRoll] -le 10|>SetHitLocation;Head --?[$revRoll] -ge 11 -and -le 20|>SetHitLocation;Right Arm --?[$revRoll] -ge 21 -and -le 30|>SetHitLocation;Left Arm --?[$revRoll] -ge 31 -and -le 70|>SetHitLocation;Body --?[$revRoll] -ge 71 -and -le 85|>SetHitLocation;Right Leg --?[$revRoll] -ge 86|>SetHitLocation;Left Leg --?[$revRoll] -ge 101|>SetHitLocation;Error - Out of Range --X| End Macro --:PROCEDURES| --:SetHitLocation| accepts hit location as parameter     --&HitLocation|[%1%]             --/| HITLOCATION is properly recorded! So it should be usable everywhere... But... it isnt... wierd. --/| ===== SOAK DETAILS ===========  --?[&HitLocation] -eqi Head|H --?[&HitLocation] -eqi LeftArm|LA --?[&HitLocation] -eqi Body|B --?[&HitLocation] -eqi RightArm|RA --?[&HitLocation] -eqi LeftLeg|LL --?[&HitLocation] -eqi RightLeg|RL --:H| --&LocDisplay|Head --=LocAV|[$HAV] --=LocSoak|[$HSoak] --^LocationDone| --:LA| --&LocDisplay|Left Arm --=LocAV|[$LAAV] --=LocSoak|[$LASoak] --^LocationDone| --:RA| --&LocDisplay|Right Arm --=LocAV|[$RAAV] --=LocSoak|[$RASoak] --^LocationDone| --:B| --&LocDisplay|Body --=LocAV|[$BAV] --=LocSoak|[$BSoak] --^LocationDone| --:LL| --&LocDisplay|Left Leg --=LocAV|[$LLAV] --=LocSoak|[$LLSoak] --^LocationDone| --:RL| --&LocDisplay|Right Leg --=LocAV|[$RLAV] --=LocSoak|[$RLSoak] --^LocationDone| --:LocationDone| --<|The HTML escape code is required because the "<>" is being interprated as an html tag.  It sucks. --+[c][b][#3FB315][&LocDisplay][/#][/b][/c]| --/| sdf I dont know whats going on &LOCDISPLAY should be set to the correct location and all relevant fields below along with it. --/| But for some reason no matter what I do or where I move the SOAK DETAILS procedure?/Function? it doesnt work.  It just defaults --/| to "HEAD" which is obviously not correct. --+|[c] ● [&HitLocation] ● [/c] --+[t border=1 width=100%] [tr] [td][c]Toughness[/c][/td] [td][c]Armor[/c][/td] [td][c]Pen[/c][/td] [td][c]Soak[/c][/td] [/tr] [tr] [td][c][$TBon]+[$UnTBon][/c][/td] [td][c] [$LocAV] [/c][/td] [td][c][$DmgPen][/c][/td] [td][c][$TotalSoak][/c][/td] [/tr] [/t]| --/|[b]Tou:[/b] [$TBon] [b]AV:[/b] [$LocAV] [b]Weap Pen[/b] [$DmgPen] --+|[c] ● DMG Details ● [/c] --+|[f18][c][b][&FinalDamage] + [$DmgAccurate][/b][/c][/f] }} Basically, what is supposed to happen is the player rolls the attack, with all the modifiers, added in by the code in previous sections of the script, not shown above.  Then the number is sent to a function that reverses the order of the numbers... so 53 becomes 35...  Then checks against a table, assigns that to a body location. The code works fine up to this point.  However, when the next section tries to take the assigned location and use it to properly display the correct information (the armor value of the specific body part and the body party currently targeted).  It fails, defaulting to the HEAD. It will work when the body part is selected using a rollquery, but other than that.  Nothing.  I have tried moving the Soak Code before, in the middle and directly after the attack roll code.  I've tried blending the two together so the targeting code sets the information directly.  I've tried everything I can think of. I'm just not sure whats wrong.  Is there something I am not seeing?  Or is this a limitation of the code I only barely understand?  Like perhaps the variables arent functioning globally because its a procedure/function?
1683142010
David M.
Pro
API Scripter
You are passing strings that have spaces in them to your SetHitLocation function, then checking the values against strings that don't have spaces. So, the code never skips to the correct location block and does the "Head" block each time. These two blocks don't jive: --?[$revRoll] -le 0|>SetHitLocation;Error - Out of Range --?[$revRoll] -le 10|>SetHitLocation;Head --?[$revRoll] -ge 11 -and -le 20|>SetHitLocation;Right Arm --?[$revRoll] -ge 21 -and -le 30|>SetHitLocation;Left Arm --?[$revRoll] -ge 31 -and -le 70|>SetHitLocation;Body --?[$revRoll] -ge 71 -and -le 85|>SetHitLocation;Right Leg --?[$revRoll] -ge 86|>SetHitLocation;Left Leg --?[$revRoll] -ge 101|>SetHitLocation;Error - Out of Range --X| End Macro For example, If left arm: you pass in "Left Arm" but check against "LeftArm" --?[&HitLocation] -eqi Head|H --?[&HitLocation] -eqi LeftArm|LA --?[&HitLocation] -eqi Body|B --?[&HitLocation] -eqi RightArm|RA --?[&HitLocation] -eqi LeftLeg|LL --?[&HitLocation] -eqi RightLeg|RL
Well, after extensive examination and assistance I have found the a solution.  However, another issue arises.  The end of procedure code seems to cause the roll20 chat engine to freak out.  The entire document comes to a screeching halt and nothing more displays in the script cards.  If I attempt to use an escape code to get around the chat problem the procedure doesnt properly execute. !scriptcard {{ --/| === ScriptCard Layout for Combined Hit/Damage === |\-- --/| === Version 1.0                               === |\-- --/| === Date: 05/02/2023                          === |\-- --/| Local Variables --|\ --#sourceToken|@{selected|token_id} --#targetToken|@{target|token_id} .... .... .... --+[c] ●  Number of HITS  ●[/c]| --=NumAtksTotal|[$RoFMod] [RoF] + [$NumAtkBase.Total] [Base] + [$NumAtkScatter] [Scatter] + [$NumAtkStorm] [Storm] {MAX:[$MaxAtk]}     --/| +Num|[$RoFMod] [RoF] + [$NumAtkBase.Total] [Base] + [$NumAtkScatter] [Scatter] + [$NumAtkStorm] [Storm] =  --+|[c][b][$NumAtksTotal.Total][/b][/c] --/| ====== Check if AttackRoll is less than the test THRESHOLD --?[$AtkRoll.Total] -le [$AtkTarget.Total]|Success --?[$AtkRoll.Total] -gt [$AtkTarget.Total]|Failure --:Success| --+[c][#3FB315]HIT! ([$DegSuccess.Total])[/#][/c]| --^Done| --:Failure| --+[c][#B31515]MISS! ([$DegSuccess.Total])[/#][/c]| --^Done| --:Jam| --+[c]JAM![/c]| --^Done| --:Done| --?[$AtkRoll] -lt 10|[ --&rollStr|0[$AtkRoll.Raw] --]|[ --&rollStr|[$AtkRoll.Raw] --]| --~len|string;length;[&rollStr] --%i|[$len];1;-1 --~s|string;substring;[&i];1;[&rollStr] --&revStr|+[&s] --%| --=revRoll|[&revStr] --<|     --?[$revRoll] -le 10|>SetHitLocation;Head     --?[$revRoll] -ge 11 -and -le 20|>SetHitLocation;Right Arm     --?[$revRoll] -ge 21 -and -le 30|>SetHitLocation;Left Arm     --?[$revRoll] -ge 31 -and -le 70|>SetHitLocation;Body     --?[$revRoll] -ge 71 -and -le 85|>SetHitLocation;Right Leg     --?[$revRoll] -ge 86|>SetHitLocation;Left Leg     --?[$revRoll] -ge 101|>SetHitLocation;Error - Out of Range          --+[c][b][#3FB315][&BodyHit][/#][/b][/c]|     --X| End Macro  --:PROCEDURES|     --:SetHitLocation| accepts hit location as parameter         --?"[&HitLocation]" -eqi "Head"|H         --?"[&HitLocation]" -eqi "Left Arm"|LA         --?"[&HitLocation]" -eqi "Body"|B         --?"[&HitLocation]" -eqi "Right Arm"|RA         --?"[&HitLocation]" -eqi "Left Leg"|LL         --?"[&HitLocation]" -eqi "Right Leg"|RL              --:H|             --&LocDisplay|Head             --=LocAV|[$HAV]             --=LocSoak|[$HSoak]             --^LocationDone|         --:LA|             --&LocDisplay|Left Arm             --=LocAV|[$LAAV]             --=LocSoak|[$LASoak]             --^LocationDone|         --:RA|             --&LocDisplay|Right Arm             --=LocAV|[$RAAV]             --=LocSoak|[$RASoak]             --^LocationDone|         --:B|             --&LocDisplay|Body             --=LocAV|[$BAV]             --=LocSoak|[$BSoak]             --^LocationDone|         --:LL|             --&LocDisplay|Left Leg             --=LocAV|[$LLAV]             --=LocSoak|[$LLSoak]             --^LocationDone|         --:RL|             --&LocDisplay|Right Leg             --=LocAV|[$RLAV]             --=LocSoak|[$RLSoak]             --^LocationDone|         --:LocationDone|          --&BodyHit|[%1%]  --<|  Nothing below this point is sent to the chat... unless the "<" is escaped as <  But then the procedure is not evealuated properly. --+|[c] ● [&LocDisplay] ● [/c] --+|[c] ● DMG Details ● [/c] --+|[f18][c][b][&FinalDamage] + [$DmgAccurate][/b][/c][/f] }}
hi Again, So nobody is able/willing to rewrite that turn undead scriptcard to include a resistance or immunity in the check loop ? I desperately need this for a Ravenloft campaign (where undead are pretty numerous lol) Thanks for anyone's help. Lionel V. said: Thank to you both fro your answers. All right i understand the full theory.  May be it's easier to add something like "turn" in the resistance or the immunities lines in the npc sheet (and making it the default token afterwards)  than checking in the abilities of the npc sheet as this ability seems to change name depending on the monster... But even though i get the full theory, i'm absolutely not capable of programming that.  Programming this is beyond my capacities, but checking for immunities or resistances might be interesting for the type of damages in all the other scriptacrds, don't you think ?  @David M. I know that this check it is something that you installed on smart AoE to check for immunities or resistances, but i haven't been able to find something like this in scriptcards.  Creating these procedures of checks and saves would be interesting to insert in the other scriptcards, wouldn't it ? If any of you scriptomancers could create these loops and checking procedures, (at least in the turn undead scriptcard) that'd be wonderfully helpful.  Thanks in advance.
1683632329
David M.
Pro
API Scripter
Lionel, I think the biggest obstacle is that Turn Resistance and Turn Immunity is not easily accessible in a character sheet attribute (for the 5e sheet, which I believe you are using from previous interaction).  Rather, the macro would have to loop through each repeating_npctrait for that character sheet and search the _name property for "Turn Resistance" or "Turn Immunity", then update the logic for that character/token accordingly. Not impossible, just a pain because working with repeating items is not very user friendly. I don't have time to work on this at the moment, but I'm putting this approach out there in case somebody wants to tackle it before I have a chance to take a look at it. Here is a link to the Turn Undead scriptcard that Lionel is referring to.   
1683641212
timmaugh
Pro
API Scripter
What if you could update something on the token to point you at the correct repeating attribute? I'm thinking about a forselected loop where you set the gmnotes (or another single point of access ScriptCards will have access to) equal to either the repeating attribute name or the results of rolling the equation in the repeating attribute (I'm not familiar with 5E rules to know whether the contents would be a true/false, a value, or a roll equation). Here is what it would look like to set the gmnotes to the name of the repeating attribute: !forselected(^) token-mod --set gmnotes|*^(selected.npctrait.[name~`Turn `].name[None]) Provided there were no other potential npctraits that would include "Turn ", that would get one of 3 values into the gmnotes of the tokens on an individual basis: Turn Resistance Turn Immunity None (...and if there were other potential repeating npctraits that would foul that retrieval, we could be more specific and maybe use APILogic to test if either repeating attribute existed...) If you have gmnotes potentially dedicated to something else, you could do this same procedure and use one of the token bars or even the tooltip. Alternately, you could use ChatSetAttr instead of TokenMod and stash the value in a fixed attribute ScriptCards could read. Even if the npc tokens all referenced the same sheet, they'll still have the same immunity/resistance, so that would work. The point is, you'd only have to run this once for all tokens, outside of combat... like a game-setup step. Then, modifying the existing ScriptCards example might be more straightforward than reading a repeating attribute in a loop... you'd just have to reference the fixed location you put the resistance/immunity info on the token/sheet.
Hello David and Timmaugh,  Yeah, i've already been thinking about that and i was thinking of just adding the"Turn" Word either in the resistance or the immunities field on the npc character sheet, so the idea would be to only go through like "if resistances field include "turn" then advantage the save roll" or if immunities include "turn" then save is a success". Because some of the npcs traits are named differently for the same effect... unfortunately... And this save check could also be used in other scriptcards as well checking for resistances and immunities (fire, cold etc....) a little bit the way SmartAOE is working... couldn't it ? Thank you for your help on looking after this.
1683647787

Edited 1683647978
Gauss
Forum Champion
Lionel V. said: hi Again, So nobody is able/willing to rewrite that turn undead scriptcard to include a resistance or immunity in the check loop ? I desperately need this for a Ravenloft campaign (where undead are pretty numerous lol) Until there is a script to do this here how I would handle this:  After using something like Token Action Maker to make the saves in all the characters I would then go through each character's Saves macro and add this to the end of the saves macro: "/w GM Advantage on saves vs Turning!!" OR "/w GM Immune to Turning!"
1683649621
David M.
Pro
API Scripter
Gauss, one issue with that is that the turn undead scriptcard macro automatically checks all the creatures in a certain radius, makes the saves, and puts status markers on turned creatures or "kills" them if high enough level to destroy undead. So, the logic needs to be added to the macro itself. The macro isn't instantiated on a token-by-token basis.
1683651758
Gauss
Forum Champion
David M. said: Gauss, one issue with that is that the turn undead scriptcard macro automatically checks all the creatures in a certain radius, makes the saves, and puts status markers on turned creatures or "kills" them if high enough level to destroy undead. So, the logic needs to be added to the macro itself. The macro isn't instantiated on a token-by-token basis. Ahhh, ok. Thanks for the clarification.
1683713949
David M.
Pro
API Scripter
Lionel, the following Turn Undead update checks for resistance/immunity in the npctrait repeating section of the 5e npc character sheet and updates the logic accordingly. Note: this macro requires scriptcards and radar scripts (though the latter can be removed from the macro if you don't want the animation). It also uses a custom statusmarker (Fear::1510130). You should change that to a statusmarker of your choosing, found in the FailedSave procedure.  !script {{ --#title|@{selected|character_name} Turns Undead! --#leftsub|Save DC @{selected|spell_save_dc} --:(0) CREATE AN ANIMATED WAVEFRONT WITH RADAR SCRIPT| uses SelectManager to retain selected token --@forselected|radar_range|30ft _pinglife|0 _wavedelay|20 _wavespacing|10 _silent|true --:(1) DETERMINE CR OF UNDEAD THAT CAN BE DESTROYED| --=charLevel|@{selected|level} --?[$charLevel] -lt 5|>SetCRdestroy;0 --?[$charLevel] -ge 5 -and [$charLevel] -lt 8|>SetCRdestroy;0.5 --?[$charLevel] -ge 8 -and [$charLevel] -lt 11|>SetCRdestroy;1 --?[$charLevel] -ge 11 -and [$charLevel] -lt 14|>SetCRdestroy;2 --?[$charLevel] -ge 14 -and [$charLevel] -lt 17|>SetCRdestroy;3 --?[$charLevel] -ge 17|>SetCRdestroy;4 --:(2) GET ALL TOKENS INTO THE "allTokens" ARRAY| will have blank 1st element to be removed later --~|array;pagetokens;allTokens;@{selected|token_id} --:(3) CREATE THE "inRange" ARRAY TO HOLD TOKENS IN RANGE| --~|array;define;inRange; --:(4) PREP ARRAY FOR LOOP| if no array elements then end macro --~tokenid|array;getfirst;allTokens --?[&tokenid] -eq ArrayError|endOutput --:(5) FIND ALL TOKENS IN RANGE| --:RangeLoop| --:TOKEN MUST BE ON OBJECTS OR GMLAYER AND TYPE MUST INCLUDE UNDEAD| --?[*[&tokenid]:t-layer] -ne objects -and [*[&tokenid]:t-layer] -ne gmlayer|NextToken --?"[*[&tokenid]:npc_type]" -ninc "undead"|NextToken --:CHECK DISTANCE IN UNITS. 30ft is 6UNITS| --~dist|euclideandistance;@{selected|token_id};[&tokenid] --?[$dist] -gt 6|NextToken --:ADD TO THE "inRange" ARRAY| --~|array;add;inRange;[&tokenid] --:NextToken| --~tokenid|array;getnext;allTokens --?[&tokenid] -ne ArrayError|RangeLoop --:(6) REMOVE DUMMY FIRST ITEM IN inRange ARRAY| --~|array;removeat;inRange;0 --:(7) ROLL SAVES FOR EACH TOKEN IN RANGE| if fail, set a token condition marker to denote turned --~tokenid|array;getfirst;inRange --?[&tokenid] -eq ArrayError|End --:SaveLoop| -->CheckResistImmunity|[&tokenid] --?[$immune] -eq 1|>PrintImmune -->GetSaveBonus|[&tokenid];wisdom;wis --?[$resistant] -eq 1|[ --=SaveRoll|2d20kh1 + [$saveBonus] [BONUS] --]|[ --=SaveRoll|1d20 + [$saveBonus] [BONUS] --]| --?[$SaveRoll.Total] -ge @{selected|spell_save_dc} -and [$immune] -eq 0|>MadeSave| --?[$SaveRoll.Total] -lt @{selected|spell_save_dc} -and [$immune] -eq 0|>FailedSave --~tokenid|array;getnext;inRange --?[&tokenid] -ne ArrayError|SaveLoop --:End| --X| --:PROCEDURES| --:CheckResistImmunity| --Rfirst|[*[%1%]:character_id];repeating_npctrait --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|[ --=resistant|0 --=immune|0 --^LIST_END| --]| --:CheckTraits| Start of loop --=resistant|0 --=immune|0 --?"[*R:name]" -inc "Turn Immunity"|=immune;1 --?"[*R:name]" -inc "Turn Resistance"|=resistant;1 --?[$immune] -eq 1 -or [$resistant] -eq 1|[ --<| early return --]| --Rnext| --?"[*R:[&Rname]]" -ne "NoRepeatingAttributeLoaded"|CheckTraits --:LIST_END | --<| --:SetCRdestroy| accepts CR as parameter --=CRdestroy|[%1%] --<| --:GetSaveBonus| accepts tokenid, full attribute name, short attribute name as parameters --:TAKE THE GREATER OF "attribute_save_bonus" OR "npc_attr_save"| --=bonus1|[*[%1%]:[%2%]_save_bonus] --&bonus2|[*[%1%]:npc_[%3%]_save_base] --:SOMETIMES "npc_attr_save_base" IS BLANK, SO SET TO -99. OTHERWISE USE ATTR VALUE| --?X[&bonus2] -eq "X"|>Set_npc_attr_save_bonus;-99|>Set_npc_attr_save_bonus;[&bonus2] --:FINALLY SET THE SAVE BONUS| --?[$bonus2] -gt [$bonus1]|>SetSaveBonus;[$bonus2]|>SetSaveBonus;[$bonus1] --<| --:Set_npc_attr_save_bonus| blank value is set to -99, otherwise use value stored in attribute --=bonus2|[%1%] --<| --:SetSaveBonus| --=saveBonus|[%1%] --<| --:MadeSave| --+[*[&tokenid]:character_name]:|[#009900][b]Made Save[/b][/#] [$SaveRoll] --<| --:PrintImmune| --+[*[&tokenid]:character_name]:|[#009900][b]Immune![/b][/#] --<| --:FailedSave| add either a dead or fear condition marker to the token, depending on CR --+[*[&tokenid]:character_name]:|[#990000][b]Failed Save[/b][/#] [$SaveRoll] --=CR|[*[&tokenid]:npc_challenge] --?[$CR] -le [$CRdestroy]|>AddConditionMarker;[&tokenid];dead|>AddConditionMarker;[&tokenid];Fear::1510130 --<| --:AddConditionMarker| accepts tokenID and condition marker as parameter --@token-mod|_ignore-selected _ids [%1%] _set statusmarkers|[%2%] --<| }}
Hi all. Apologies if this has been answered before, but I can't find it for the life of me. I am attempting to wrote a script that does 2 things. The first is ask a question that, if answer 1 is given it rolls a d20 with a success/fail DC, on a success nothing happens, but on a fail advise/state that disadvantage is applied to the next part of the script.(reporting this to both the player and GM) if answer 2 is given it skips straight to the second part of the script. The second thing I want the script to do is pull a players attacks from their character sheet and present them as clickable buttons in the chat window whispered to the player that runs the script. Thanks in advance. Aaron.
David M. said: Lionel, the following Turn Undead update checks for resistance/immunity in the npctrait repeating section of the 5e npc character sheet and updates the logic accordingly. Note: this macro requires scriptcards and radar scripts (though the latter can be removed from the macro if you don't want the animation). It also uses a custom statusmarker (Fear::1510130). You should change that to a statusmarker of your choosing, found in the FailedSave procedure.  !script {{ --#title|@{selected|character_name} Turns Undead! --#leftsub|Save DC @{selected|spell_save_dc} --:(0) CREATE AN ANIMATED WAVEFRONT WITH RADAR SCRIPT| uses SelectManager to retain selected token --@forselected|radar_range|30ft _pinglife|0 _wavedelay|20 _wavespacing|10 _silent|true --:(1) DETERMINE CR OF UNDEAD THAT CAN BE DESTROYED| --=charLevel|@{selected|level} --?[$charLevel] -lt 5|>SetCRdestroy;0 --?[$charLevel] -ge 5 -and [$charLevel] -lt 8|>SetCRdestroy;0.5 --?[$charLevel] -ge 8 -and [$charLevel] -lt 11|>SetCRdestroy;1 --?[$charLevel] -ge 11 -and [$charLevel] -lt 14|>SetCRdestroy;2 --?[$charLevel] -ge 14 -and [$charLevel] -lt 17|>SetCRdestroy;3 --?[$charLevel] -ge 17|>SetCRdestroy;4 --:(2) GET ALL TOKENS INTO THE "allTokens" ARRAY| will have blank 1st element to be removed later --~|array;pagetokens;allTokens;@{selected|token_id} --:(3) CREATE THE "inRange" ARRAY TO HOLD TOKENS IN RANGE| --~|array;define;inRange; --:(4) PREP ARRAY FOR LOOP| if no array elements then end macro --~tokenid|array;getfirst;allTokens --?[&tokenid] -eq ArrayError|endOutput --:(5) FIND ALL TOKENS IN RANGE| --:RangeLoop| --:TOKEN MUST BE ON OBJECTS OR GMLAYER AND TYPE MUST INCLUDE UNDEAD| --?[*[&tokenid]:t-layer] -ne objects -and [*[&tokenid]:t-layer] -ne gmlayer|NextToken --?"[*[&tokenid]:npc_type]" -ninc "undead"|NextToken --:CHECK DISTANCE IN UNITS. 30ft is 6UNITS| --~dist|euclideandistance;@{selected|token_id};[&tokenid] --?[$dist] -gt 6|NextToken --:ADD TO THE "inRange" ARRAY| --~|array;add;inRange;[&tokenid] --:NextToken| --~tokenid|array;getnext;allTokens --?[&tokenid] -ne ArrayError|RangeLoop --:(6) REMOVE DUMMY FIRST ITEM IN inRange ARRAY| --~|array;removeat;inRange;0 --:(7) ROLL SAVES FOR EACH TOKEN IN RANGE| if fail, set a token condition marker to denote turned --~tokenid|array;getfirst;inRange --?[&tokenid] -eq ArrayError|End --:SaveLoop| -->CheckResistImmunity|[&tokenid] --?[$immune] -eq 1|>PrintImmune -->GetSaveBonus|[&tokenid];wisdom;wis --?[$resistant] -eq 1|[ --=SaveRoll|2d20kh1 + [$saveBonus] [BONUS] --]|[ --=SaveRoll|1d20 + [$saveBonus] [BONUS] --]| --?[$SaveRoll.Total] -ge @{selected|spell_save_dc} -and [$immune] -eq 0|>MadeSave| --?[$SaveRoll.Total] -lt @{selected|spell_save_dc} -and [$immune] -eq 0|>FailedSave --~tokenid|array;getnext;inRange --?[&tokenid] -ne ArrayError|SaveLoop --:End| --X| --:PROCEDURES| --:CheckResistImmunity| --Rfirst|[*[%1%]:character_id];repeating_npctrait --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|[ --=resistant|0 --=immune|0 --^LIST_END| --]| --:CheckTraits| Start of loop --=resistant|0 --=immune|0 --?"[*R:name]" -inc "Turn Immunity"|=immune;1 --?"[*R:name]" -inc "Turn Resistance"|=resistant;1 --?[$immune] -eq 1 -or [$resistant] -eq 1|[ --<| early return --]| --Rnext| --?"[*R:[&Rname]]" -ne "NoRepeatingAttributeLoaded"|CheckTraits --:LIST_END | --<| --:SetCRdestroy| accepts CR as parameter --=CRdestroy|[%1%] --<| --:GetSaveBonus| accepts tokenid, full attribute name, short attribute name as parameters --:TAKE THE GREATER OF "attribute_save_bonus" OR "npc_attr_save"| --=bonus1|[*[%1%]:[%2%]_save_bonus] --&bonus2|[*[%1%]:npc_[%3%]_save_base] --:SOMETIMES "npc_attr_save_base" IS BLANK, SO SET TO -99. OTHERWISE USE ATTR VALUE| --?X[&bonus2] -eq "X"|>Set_npc_attr_save_bonus;-99|>Set_npc_attr_save_bonus;[&bonus2] --:FINALLY SET THE SAVE BONUS| --?[$bonus2] -gt [$bonus1]|>SetSaveBonus;[$bonus2]|>SetSaveBonus;[$bonus1] --<| --:Set_npc_attr_save_bonus| blank value is set to -99, otherwise use value stored in attribute --=bonus2|[%1%] --<| --:SetSaveBonus| --=saveBonus|[%1%] --<| --:MadeSave| --+[*[&tokenid]:character_name]:|[#009900][b]Made Save[/b][/#] [$SaveRoll] --<| --:PrintImmune| --+[*[&tokenid]:character_name]:|[#009900][b]Immune![/b][/#] --<| --:FailedSave| add either a dead or fear condition marker to the token, depending on CR --+[*[&tokenid]:character_name]:|[#990000][b]Failed Save[/b][/#] [$SaveRoll] --=CR|[*[&tokenid]:npc_challenge] --?[$CR] -le [$CRdestroy]|>AddConditionMarker;[&tokenid];dead|>AddConditionMarker;[&tokenid];Fear::1510130 --<| --:AddConditionMarker| accepts tokenID and condition marker as parameter --@token-mod|_ignore-selected _ids [%1%] _set statusmarkers|[%2%] --<| }} Hey David thank you so much that will help grandly in achieving what i needed.  I'll have to insert in the npc traits a text that says turn immunity or turn resistance so it is found properly in the script. I've modified the radar part to a spawn holyburst thing. and i've also added the function in hiding the name of the creature in the results for the players, but not for the gm I see that you refer to npc_repeatingtraits in the script, How would i refer to Resistances or immunities field ? would it need to look in 2 different places and thus would complicate the script ? It works fine like that for the turn undead, but i'm already thinking of using this procedure in checking for damages resistances or immunities in some scriptcards (scorching ray for example) here's my resulting scriptcard :  !script {{ --#title|@{selected|character_name} Renvoie les Impies! --#leftsub|JP DD @{selected|spell_save_dc} --:(0) CREATE AN ANIMATED EFFECT WITH SPAWN SCRIPT| uses SelectManager to retain selected token --@forselected|Spawn _name|HolyBurst _expand|50,50, true _size|13,13 _order|tofront --:(1) DETERMINE CR OF UNDEAD THAT CAN BE DESTROYED| --=charLevel|@{selected|level} --?[$charLevel] -lt 5|>SetCRdestroy;0 --?[$charLevel] -ge 5 -and [$charLevel] -lt 8|>SetCRdestroy;0.5 --?[$charLevel] -ge 8 -and [$charLevel] -lt 11|>SetCRdestroy;1 --?[$charLevel] -ge 11 -and [$charLevel] -lt 14|>SetCRdestroy;2 --?[$charLevel] -ge 14 -and [$charLevel] -lt 17|>SetCRdestroy;3 --?[$charLevel] -ge 17|>SetCRdestroy;4 --:(2) GET ALL TOKENS INTO THE "allTokens" ARRAY| will have blank 1st element to be removed later --~|array;pagetokens;allTokens;@{selected|token_id} --:(3) CREATE THE "inRange" ARRAY TO HOLD TOKENS IN RANGE| --~|array;define;inRange; --:(4) PREP ARRAY FOR LOOP| if no array elements then end macro --~tokenid|array;getfirst;allTokens --?[&tokenid] -eq ArrayError|endOutput --:(5) FIND ALL TOKENS IN RANGE| --:RangeLoop| --:TOKEN MUST BE ON OBJECTS OR GMLAYER AND TYPE MUST INCLUDE UNDEAD| --?[*[&tokenid]:t-layer] -ne objects -and [*[&tokenid]:t-layer] -ne gmlayer|NextToken --?"[*[&tokenid]:npc_type]" -ninc "undead"|NextToken --:CHECK DISTANCE IN UNITS. 30ft is 6UNITS| --~dist|distance;@{selected|token_id};[&tokenid] --?[$dist] -gt 6|NextToken --:ADD TO THE "inRange" ARRAY| --~|array;add;inRange;[&tokenid] --:NextToken| --~tokenid|array;getnext;allTokens --?[&tokenid] -ne ArrayError|RangeLoop --:(6) REMOVE DUMMY FIRST ITEM IN inRange ARRAY| --~|array;removeat;inRange;0 --:(7) ROLL SAVES FOR EACH TOKEN IN RANGE| if fail, set a token condition marker to denote turned --~tokenid|array;getfirst;inRange --?[&tokenid] -eq ArrayError|End --:SaveLoop| -->CheckResistImmunity|[&tokenid] --?[$immune] -eq 1|>PrintImmune -->GetSaveBonus|[&tokenid];wisdom;wis --?[$resistant] -eq 1|[ --=SaveRoll|2d20kh1 + [$saveBonus] [BONUS] --]|[ --=SaveRoll|1d20 + [$saveBonus] [BONUS] --]| --?[$SaveRoll.Total] -ge @{selected|spell_save_dc} -and [$immune] -eq 0|>MadeSave| --?[$SaveRoll.Total] -lt @{selected|spell_save_dc} -and [$immune] -eq 0|>FailedSave --~tokenid|array;getnext;inRange --?[&tokenid] -ne ArrayError|SaveLoop --:End| --X| --:PROCEDURES| --:CheckResistImmunity| --Rfirst|[*[%1%]:character_id];repeating_npctrait --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|[ --=resistant|0 --=immune|0 --^LIST_END| --]| --:CheckTraits| Start of loop --=resistant|0 --=immune|0 --?"[*R:name]" -inc "Turn Immunity"|=immune;1 --?"[*R:name]" -inc "Turn Resistance"|=resistant;1 --?[$immune] -eq 1 -or [$resistant] -eq 1|[ --<| early return --]| --Rnext| --?"[*R:[&Rname]]" -ne "NoRepeatingAttributeLoaded"|CheckTraits --:LIST_END | --<| --:SetCRdestroy| accepts CR as parameter --=CRdestroy|[%1%] --<| --:GetSaveBonus| accepts tokenid, full attribute name, short attribute name as parameters --:TAKE THE GREATER OF "attribute_save_bonus" OR "npc_attr_save"| --=bonus1|[*[%1%]:[%2%]_save_bonus] --&bonus2|[*[%1%]:npc_[%3%]_save_base] --:SOMETIMES "npc_attr_save_base" IS BLANK, SO SET TO -99. OTHERWISE USE ATTR VALUE| --?X[&bonus2] -eq "X"|>Set_npc_attr_save_bonus;-99|>Set_npc_attr_save_bonus;[&bonus2] --:FINALLY SET THE SAVE BONUS| --?[$bonus2] -gt [$bonus1]|>SetSaveBonus;[$bonus2]|>SetSaveBonus;[$bonus1] --<| --:Set_npc_attr_save_bonus| blank value is set to -99, otherwise use value stored in attribute --=bonus2|[%1%] --<| --:SetSaveBonus| --=saveBonus|[%1%] --<| --:MadeSave| --*[*[&tokenid]:character_name]:|[#009900][b]JP Réussi[/b][/#] [$SaveRoll] --+Creature [%1%]:|[#009900][b]JP Réussi[/b][/#] [$SaveRoll] --<| --:PrintImmune| --*[*[&tokenid]:character_name]:|[#009900][b]Immunisé![/b][/#] --+Creature [%1%]:|[#009900][b]Immunisée![/b][/#] [$SaveRoll] --<| --:FailedSave| add either a dead or fear condition marker to the token, depending on CR --=CR|[*[&tokenid]:npc_challenge] --?[$CR] -le [$CRdestroy]|>AddConditionMarker;[&tokenid];Mort::4017244;-Dest.|>AddConditionMarker;[&tokenid];Effraye2::4023355;-Peur --*[*[&tokenid]:character_name]:|[#990000][b]JP Raté[/b][/#] [$SaveRoll] [b][&FailureText][/b] --+Creature [%1%]:|[#990000][b]JP Raté[/b][/#] [$SaveRoll] [b][&FailureText][/b] --<| --:AddConditionMarker| accepts tokenID, condition marker, and descriptive text as parameters --@token-mod|_ignore-selected _ids [%1%] _set statusmarkers|[%2%] --&FailureText|[%3%] --<| }}
1683807441
David M.
Pro
API Scripter
@Lionel: yes, the macro above looks in the npc_trait repeating field. 5e compendium creatures will have these traits populated there by default. Custom creatures would need those traits added in the same location. There are lots of examples of how to search npc_resistances (and related fields) via scriptcards. For example, Kurt wrote a dragonborn breath weapon scriptcard that checks for resistance/immunity/vulnerability - you can find it here .
@Lionel  must point out a flaw in the check range system that I have discovered that might throw off your calculation.  The size of tokens, anything larger than a single square/unit.  I've not found any way to get around this, although I imagine that it might be possible by getting the size of the tokens and subtracting (or something) from the range calculation.  Honestly, it would be easier if the range check function could have a second version. One for checking distance from the center of a token, one checking the distance from the EDGE of a token.  Now this is just an observation, and may or may not be relevant to your use case. P.S., Is your name a Legends of Chima or a Warhammer reference?  Both are amazing!
1684005403
Senjak
Pro
Sheet Author
Call of Cthulhu: Skill and Luck Level Up script I really liked the one button skill level up on the Delta Green character sheet.  This isn't quite the same, but it does cut down on chat clutter. This works with the character sheet for Call of Cthulhu from Roll20.  You'd need to make changes to get it to work with other sheets. The Roll20 sheet is in many ways what I think of as really ugly. The skills are forcefully fixed in order with numerous sub-tables of skills fit in the middle. It doesn't update the skills or uncheck the used skill marker, but it tells you what to do.  The script does implement the rules from the keeper's book for maximum luck and skill advancement. Page 94 and page 99. As always, I'm very open to any suggestions for improvement, comments about badly coded parts and the like. Click on it and you get the following: !script {{ --/| --/| Script to determine level up percentages for Call of Cthulhu. --/| --/| Depends on the "Call of Cthulhu 7th Edition by Roll20" character sheet --/| Depends on "Scriptcards" Mod for Roll20 by Kurt Jaegers. --/| --/| Version 2.0 by Senjak on Roll20. --/| --/| --/| Setup how the output will look. --/| --name|@{selected|token_name} --#leftsub|@{selected|character_name} --#rightsub|v2.0 --#titlefontlineheight|1.8em --#lineheight|1.3em --#buttonbackground|#C9DAF8 --#titleCardBackground|#000000 --#buttontextcolor|#000000 --#buttonbordercolor|#000000 --#titlefontsize|24px --#subtitlefontsize|16px --#bodyfontsize|16px --#buttonfontsize|18px --#title|Skill Improvements --#sourceToken|@{selected|token_id} --/| --/| Start of main loop --/| --&skill|null --&update|null --&level|null --&status|null --&skill_up|null --/| --/| The Luck Stat --/| --+[c]Luck Stat[/c]| --=cur_luck|@{selected|luck} --=check_me|1d100 --?[$check_me] -gt [$cur_luck]|[ --=add_me|2d10 --]|[ --=add_me|1d10 --]| --=new_luck|[$cur_luck]+[$add_me] --?[$new_luck] -gt 95|[ --=new_luck|99 --]| --+Luck ([$new_luck])|[r]Gain [$add_me][/r] --/| --/| own is the character's own language --/| --~|array;define;skills;accounting;anthropology;appraise;archaeology;charm;climb;disguise;dodge;drive_auto;electrical_repair;fast_talk;first_aid;history;intimidate;jump;own;law;library_use;listen;locksmith;mechanical_repair;medicine;natural_world;navigate;occult;operate_heavy_machinery;persuade;psychoanalysis;psychology;ride;sleight_of_hand;spot_hidden;stealth;swim;throw;track;brawl;handgun;rifle_shotgun --+[c]Standard Skills[/c]| --~|array;sort;skills --%LoopCounter|0;37;1 --&skill|[@skills([&LoopCounter])] --&update|[&skill] --&update|+-check --&level|[*s:[&skill]] --&status|[*s:[&update]] --=improved|[$improved] --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --=improved|[$improved] + 1 --%|End of LoopCounter --/|r_artcraft_count --+[c] Arts and Craft Skills [/c]| --Rfirst|@{selected|character_id};repeating_artcraft --:ARTCRAFT_LOOP| --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|DONE_ARTCRAFT --&status|[*R:artcraft-check] --&skill|[*R:name] --=level|[*R:value] --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rnext| --^ARTCRAFT_LOOP| --:DONE_ARTCRAFT| --/|r_fighting_count --+[c] Fighting Skills [/c]| --/|three hard coded fighting skills --&skill|@{selected|fighting_skill_1_name} --&status|@{selected|fighting_skill_1-check} --=level|@{selected|fighting_skill_1} --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --&skill|@{selected|fighting_skill_2_name} --&status|@{selected|fighting_skill_2-check} --=skill|@{selected|fighting_skill_2} --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --&skill|@{selected|fighting_skill_3_name} --&status|@{selected|fighting_skill_3-check} --=skill|@{selected|fighting_skill_3} --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rfirst|@{selected|character_id};repeating_fighting --:FIGHT_LOOP| --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|DONE_FIGHT --&status|[*R:fighting-check] --&skill|[*R:name] --=level|[*R:value] --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rnext| --^FIGHT_LOOP| --:DONE_FIGHT| --/|r_firearms_count --+[c] Firearm Skills [/c]| --/|two hard coded firearm skills --&name|@{selected|firearms_skill_1_name} --&status|@{selected|firearms_skill_1-check} --=level|@{selected|firearms_skill_1} --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --&name|@{selected|firearms_skill_2_name} --&status|@{selected|firearms_skill_2-check} --=level|@{selected|firearms_skill_2} --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rfirst|@{selected|character_id};repeating_firearms --:GUN_LOOP| --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|DONE_GUN --&status|[*R:firearms-check] --&skill|[*R:name] --=level|[*R:value] --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rnext| --^GUN_LOOP| --:DONE_GUN| --/|Language Skills --+[c] Language Skills [/c]| --Rfirst|@{selected|character_id};repeating_languages --:LANG_LOOP| --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|DONE_LANG --&status|[*R:languages-check] --&skill|[*R:name] --=level|[*R:value] --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rnext| --^LANG_LOOP| --:DONE_LANG| --/|r_pilot_count --+[c] Piloting Skills [/c]| --Rfirst|@{selected|character_id};repeating_pilot --:PILOT_LOOP| --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|DONE_PILOT --&status|[*R:pilot-check] --&skill|[*R:name] --=level|[*R:value] --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rnext| --^PILOT_LOOP| --:DONE_PILOT| --/|r_sciences_count --+[c] Science Skills [/c]| --Rfirst|@{selected|character_id};repeating_sciences --:SCI_LOOP| --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|DONE_SCI --&status|[*R:sciences-check] --&skill|[*R:name] --=level|[*R:value] --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rnext| --^SCI_LOOP| --:DONE_SCI| --/|r_survival_count --+[c] Survival Skills [/c]| --Rfirst|@{selected|character_id};repeating_survival --:SURVIVAL_LOOP| --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|DONE_SURVIVAL --&status|[*R:survival-check] --&skill|[*R:name] --=level|[*R:value] --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rnext| --^SURVIVAL_LOOP| --:DONE_SURVIVAL| --/|r_additionalskills_count --+[c] Additional Skills [/c]| --/|three hard coded additional skills --&name|@{selected|additional_skill_1_name} --&status|@{selected|additional_skill_1-check} --=cur|@{selected|additional_skill_1} --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --&name|@{selected|additional_skill_2_name} --&status|@{selected|additional_skill_2-check} --=cur|@{selected|additional_skill_2} --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --&name|@{selected|additional_skill_3_name} --&status|@{selected|additional_skill_3-check} --=cur|@{selected|additional_skill_3} --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rfirst|@{selected|character_id};repeating_additionalskills --:ADDS_LOOP| --?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|DONE_ADDS --&status|[*R:additionalskills-check] --&skill|[*R:name] --=level|[*R:value] --=improved|0 --?[&status] -inc on|>Level_Up;[&skill];[&level];[$improved] --Rnext| --^ADDS_LOOP| --:DONE_ADDS| --X --/| --/| Subroutine to calculate the amount of level up. --/| Luck can not go above 99. Always add to luck. --/| Skills can go above 100. Any skill roll above 95 counts as a success! --/| --:Level_Up| --&skill_name|[%1%] --=cur_skill|[%2%] --=check_me|1d100 --?[$cur_skill] -eq ""|[ --]|[ --?[$check_me] -gt [$cur_skill]|[ --=add_me|1d10 --=new_skill|[$cur_skill]+[$add_me] --+[&skill_name] ([$new_skill])|[r]Gain [$add_me][/r] --]|[ --?[$check_me] -gt 95|[ --=add_me|1d10 --=new_skill|[$cur_skill]+[$add_me] --+[&skill_name] ([$new_skill]) (rolled [$check_me])|[r]Gain [$add_me][/r] --]| --]| --]| --<|End of Level_Up }}
1684005694
Senjak
Pro
Sheet Author
A Section Break Script Sometimes my players are rolling lots of the same types of dice and I like to have a quick visual indicator between sets of Sanity Rolls. So I put together this.  Not terribly complicated, but it is also nice to have simple examples in our code base!  Enjoy! P.S. I use large fonts because everyone in my gaming group has old eyes.   !script {{ --/|Advanced Show Break --#titlefontsize|24px --#subtitlefontsize|18px --#bodyfontsize|18px --#buttonfontsize|18px --#title|Section Break --#timezone|America/Chicago --~datetime|system;date;getdatetime --+It is now:|[&datetime] }}
1684005939
Senjak
Pro
Sheet Author
I was looking through the docs but couldn't find a way to increase the size of the token.  Is there a way to do that?  For reference: The token that shows up at the top with the  --#sourceToken|@{selected|token_id}  command. Thanks!