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

Using Scriptcards, CharSetAttr and SpawnDefaultToken to create Summon Beast Macro

Hi All, So, I decided to go completely overboard and automate the Summon Beast spell. The spell summons a beast based on level and type. I'm using Scriptcards, ChatSetAttr and SpawnDefaultToken to set the stats to an NPC token, spawn a summoning token to then be replaced by the beast token. I realize I could probably skip the summoning token, not a big deal though, it's an easy change. So, stats are different depending on level and type of beast, so those are the two choices to make and then I disseminate what needs to change from there. Trouble is I can't get it to work, which is why I'm here. I'm getting an error from ChatSetAttr "No target characters. You need to supply one of -all, -allgm, -sel, allplayers, -charid, or -name." I've tried using both the charid and name but can't get it recognize the NPC. I can't select the token, as it's not on the page yet, so the sel is out of the question. Can anyone give me some direction with this one? Thanks. !scriptcards {{ --#title|Healing Word --#sourceToken|@{selected|token_id} --#emoteText|[*S:character_name] Casts Healing Word on [*T:character_name] --#bodyfontface|Helvetica --#oddrowfontcolor|#290000 --#evenrowfontcolor|#290000 --#bodyfontsize|[&bodyFontSize]px --#buttonfontsize|10px --#buttonbackground|#930c10 --#buttonbackground|#672223 --#buttonbackground|rgba(103,34,35,1); display:inline-block; --/#buttonbordercolor|rgba(0,0,0,0) --/#buttonbackground|rgba(0,0,0,0); display:inline-block; border:none --/#buttontextcolor|#930c10 --#buttonfontface|Tahoma --#titlecardbackgroundcolor|#930c10 --#titlecardbackgroundcolor|#672223 --#titlefontcolor|#fffebd --#titlefontsize|1.5em --#titlefontshadow|0 --#oddrowbackground|#f7ce65 --#evenrowbackground|#f7ce65 --#oddrowbackground|#b3ab96 --#evenrowbackground|#b3ab96 --#subtitlefontcolor|#fffebd --#tablebgcolor|#fffebd --#lineheight|10pt --#buttonpadding|3px --&CharName|Summon Beast -->GetAndCheckSlotInformation| -->GetBeast| -->SetupNPC| -->DeductSpellSlot| -->SpawnBeast| --:GetBeast| --=Beast|?{What Beast Type?|Land,1|Air,2|Sea,3} --?Beast -eq 1|Land-Beast --?Beast -eq 2|Air-Beast --?Beast -eq 3|Sea-Beast --<| --:Land-Beast| --&hplvl|30 --&Speed|30ft, 30ft climb --@setattr _name|Summon Beast _repeating_npctrait_$0_name|Pack Tactics _repeating_npctrait_$0_description|The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. --<| --:Air-Beast| --&hplvl|30 --&Speed|60ft fly --@setattr _name|Summon Beast _repeating_npctrait_$0_name|Flyby _repeating_npctrait_$0_description|The beast doesn’t provoke opportunity attacks when it flies out of an enemy’s reach. --<| --:Sea-Beast| --&hplvl|30 --&Speed|30ft swim --@setattr _name|Summon Beast _repeating_npctrait_$0_name|Pack Tactics _repeating_npctrait_$0_description|The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. _repeating_npctrait_$1_name|Water Breathing _repeating_npctrait_$1_description|The beast can breathe only underwater. --<| --:SetupNPC| --@setattr| _name|Summon Beast _npc_type|Medium Beast, Unaligned _ac|11+[$SlotLevel] _hp|[&hplvl] _strength|18 _constitution|16 _dexterity|11 _intelligence|4 _wisdom|14 _charisma|5 _npc_speed|[&Speed] _repeating_npcaction_$0_name|Maul _repeating_npcaction_$0_attack_tohit|@{Telios|spell_attack_bonus} _repeating_npcaction_$0_attack_target|once creature _repeating_npcaction_$0_attack_damage|1d8+4+[$SlotLevel] _repeating_npcaction_$0_attack_damagetype|piercing _npc_senses|darkvision 60ft _npc_language|Same as Caster _repeating_npctrait_$3_name|Multiattack _repeating_npctrait_$3_description|The beast makes a number of attacks equal to half this spell’s level (rounded down). --<| --:SpawnBeast| _name|Beast Summon _offset|1,0 --<| --:GetAndCheckSlotInformation| --=SlotLevel|?{Spell Slot Level Used?|2|3|4|5|6|7|8|9} --=SlotsTotal|0 --=SlotsExpended|[*S:lvl[$SlotLevel]_slots_expended] --?[$SlotsExpended.Total] -eq [$SlotsTotal.Total]|NoSlotsLeft --<| --:DeductSpellSlot| --=SlotsExpended|[$SlotsExpended] - 1 --@setattr|_charid [*S:character_id] _lvl[$SlotLevel]_slots_expended|[$SlotsExpended] _silent --+|Level [$SlotLevel] Slots Left: [$SlotsExpended] --X|Full Stop --:NoSlotsLeft| --+|[*S:character_name] has no level [$SlotLevel.Total] spell slots available. --X|NoSlotsLeftStop }}
1703454366
David M.
Pro
API Scripter
Untested, but at first glance it looks like a few of your --@setattr lines  (in your XXXBeast functions)  are missing the vertical bar at the end, before the list of attributes.
Hey Timothy. First thing I see is I don't see the actual call to DefaultSpawnToken. I don't see a --@Spawn in the SpawnBeast label. But to your questions, since ScriptCards calls other mods asynchronously, getting things back can be tricky. For a lot of things that I used to use ChatSetAttr in ScriptCards, I've actually replaced with  ScriptCards direct object modification . Using the direct object modification in ScriptCards allows things to be called and referenced in the same ScriptCard. One option I've used with DefaultSpawnToken in a ScriptCard, is using a re-entrant button  to resume the script in a branch after the spawned token is there and available to access with ScriptCards. Another possible option, although this is not exactly tested by me would be to use SelectManager from the MetaScript Toolbox  to "select" the token by name. The MetaScripts have a way of being able to order operations to allow things that aren't normally possible via the API so it's possible that SelectManager and  ScriptCards has deferral options available for MetaScripts  
Thanks peoples. Just so we're all on the same page, I fully admit I have no idea what I'm doing. I have a basic understanding of what is happening just using my own logic, anything deeper than that I have to research for hours on end. But, you've given me some good leads. I've fixed those vertical bars and added the spawn script back in(don't know where it went), but CharSetAttr still isn't finding the character. I've tried using ScriptCards' deferral using SelectManager and have never managed to get it to work, although it was under different circumstances. Looks like I'll start over and try using ScripCards' direct object modification. I really do appreciate the help!
If you can't manage to get it working as you want, I can probably take a closer look in a couple of days and play around with it. Hopefully you get it working before then but if not, let me know and I can take a crack at it.
1703523833

Edited 1703525346
Thanks Joshua. I couldn't get ScriptCards' direct object modification to work, no idea why, but I got CharSetAttr to work. CharSetAttr is really specific about it's formatting,  right down to spaces for some reason(even though I'm using notepad++). Which I discovered after I read about the ScriptCards' debug setting and sorting through the output. I also had more stupid mistakes that I fixed up. The other thing I had to do was put placeholders in the repeating sections through the sheet for anything that didn't already have an entry, CharSetAttr wouldn't create them. I also couldn't separate the two calls to CharSetAttr and had to combine them, so the Macro grew a bit. Now I need to find a way to grab the random token image from three different tables to represent the three different Beast types. And, I need to figure out the math for the hp, which goes up by 5 for every spell level. !scriptcards {{ --#title|Summon Beast --#sourceToken|@{selected|token_id} --#emoteText|[*S:character_name] Casts Summon Beast. --#bodyfontface|Helvetica --#oddrowfontcolor|#290000 --#evenrowfontcolor|#290000 --#bodyfontsize|[&bodyFontSize]px --#titlecardbackgroundcolor|#930c10 --#titlecardbackgroundcolor|#672223 --#titlefontcolor|#fffebd --#titlefontsize|1.5em --#titlefontshadow|0 --#oddrowbackground|#f7ce65 --#evenrowbackground|#f7ce65 --#oddrowbackground|#b3ab96 --#evenrowbackground|#b3ab96 --#subtitlefontcolor|#fffebd --#tablebgcolor|#fffebd --#lineheight|10pt --#debug|1 -->GetAndCheckSlotInformation|>[$SlotLevel] -->GetBeast| --@forselected|Spawn _name|SummonBeast _offset|1,0 _side|rand -->DeductSpellSlot| --X| --:GetBeast| --=Beast|?{What Beast Type?|Land,1|Air,2|Sea,3} --?[$Beast] -eq 1|Land-Beast --?[$Beast] -eq 2|Air-Beast --?[$Beast] -eq 3|Sea-Beast --<| --:Land-Beast| --=ACCalc|11+[$SlotLevel] --&hplvl|30 --&Speed|30ft, 30ft climb --@setattr| _name SummonBeast _npc_name|Land Beast _npc_type|Medium Beast, Unaligned _npc_ac|[$ACCalc] _hp|[&hplvl]|[&hplvl] _strength_base|18 _dexterity_base|11 _constitution_base|16 _intelligence_base|4 _wisdom_base|14 _charisma_base|5 _npc_speed|[&Speed] _repeating_npcaction_$0_name|Maul _repeating_npcaction_$0_attack_tohit|@{selected|spell_attack_bonus} _repeating_npcaction_$0_attack_target|one creature _repeating_npcaction_$0_attack_damage|1d8+4+[$SlotLevel] _repeating_npcaction_$0_attack_damagetype|piercing _npc_senses|darkvision 60ft _npc_languages|Same as Caster _repeating_npctrait_$0_name|Pack Tactics _repeating_npctrait_$0_description|The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. _repeating_npcaction_$1_name|Multiattack _repeating_npcaction_$1_description|The beast makes a number of attacks equal to half this spell’s level (rounded down). _repeating_npctrait_$1_name| _repeating_npctrait_$1_description| _npc_challenge|--- --<| --:Air-Beast| --=AcCalc|11+[$SlotLevel] --&hplvl|20 --&Speed|60ft fly --@setattr| _name SummonBeast _npc_name|Air Beast _repeating_npctrait_$0_name|Flyby _repeating_npctrait_$0_description|The beast doesn’t provoke opportunity attacks when it flies out of an enemy’s reach. _npc_type|Medium Beast, Unaligned _npc_ac|[$ACCalc] _hp|[&hplvl]|[&hplvl] _strength_base|18 _dexterity_base|11 _constitution_base|16 _intelligence_base|4 _wisdom_base|14 _charisma_base|5 _npc_speed|[&Speed] _repeating_npcaction_$0_name|Maul _repeating_npcaction_$0_attack_tohit|@{Telios|spell_attack_bonus} _repeating_npcaction_$0_attack_target|once creature _repeating_npcaction_$0_attack_damage|1d8+4+[$SlotLevel]| _repeating_npcaction_$0_attack_damagetype|Piercing _npc_senses|darkvision 60ft _npc_languages|Same as Caster _repeating_npctrait_$1_name| _repeating_npctrait_$1_description| _npc_challenge|--- --<| --:Sea-Beast| --=AcCalc|11+[$SlotLevel] --&hplvl|30 --&Speed|30ft swim --@setattr| _name SummonBeast _npc_name|Sea Beast _repeating_npctrait_$0_name|Pack Tactics _repeating_npctrait_$0_description|The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. _repeating_npctrait_$1_name|Water Breathing _repeating_npctrait_$1_description|The beast can breathe only underwater. _npc_type|Medium Beast, Unaligned _npc_ac|[$ACCalc] _hp|[&hplvl]|[&hplvl] _strength_base|18 _dexterity_base|11 _constitution_base|16 _intelligence_base|4 _wisdom_base|14 _charisma_base|5 _npc_speed|[&Speed] _repeating_npcaction_$0_name|Maul _repeating_npcaction_$0_attack_tohit|@{Telios|spell_attack_bonus} _repeating_npcaction_$0_attack_target|once creature _repeating_npcaction_$0_attack_damage|1d8+4+[$SlotLevel] _repeating_npcaction_$0_attack_damagetype|piercing _npc_senses|darkvision 60ft _npc_languages|Same as Caster _repeating_npcaction_$1_name|Multiattack _repeating_npcaction_$1_description|The beast makes a number of attacks equal to half this spell’s level (rounded down). _npc_challenge|--- --<| --:GetAndCheckSlotInformation| --=SlotLevel|?{Spell Slot Level Used?|2|3|4|5|6|7|8|9} --=SlotsTotal|0 --=SlotsExpended|[*S:lvl[$SlotLevel]_slots_expended] --?[$SlotsExpended.Total] -eq [$SlotsTotal.Total]|NoSlotsLeft --<| --:DeductSpellSlot| --=SlotsExpended|[$SlotsExpended] - 1 --@setattr|_charid [*S:character_id] _lvl[$SlotLevel]_slots_expended|[$SlotsExpended] _silent --+|Level [$SlotLevel] Slots Left: [$SlotsExpended] --X|Full Stop --:NoSlotsLeft| --+|[*S:character_name] has no level [$SlotLevel.Total] spell slots available. --X|NoSlotsLeftStop }}  
Very cool that you got it working. If you are looking to grab the token image, you could do something like the following example script to set the token: !script {{ --&tableName|corman-token --#sourceToken|@{selected|token_id} --=side|[T#[&tableName]] --+DEBUG|[$side.tableEntryText] --&imgurl|[$side.tableEntryImgURL] --~imgurl|string;replace;max.png;thumb.png;[&imgurl] --!t:[*S:t-id]|imgsrc:[&imgurl] }} This works to set the selected token to a randomly rolled image from the table set in &tableName. Note that the API must use images in your library so no marketplace images or anything like that. Also the images in my table all return the max.png and tokens use thumb.png. Those restrictions are listed  here Also something like the following could work for your HP increase per spell level I think: !script {{ --=SlotLevel|?{Spell Slot Level Used?|2|3|4|5|6|7|8|9} --&base_hp|20 --=hp|5 * [= [$SlotLevel] - 2] + [&base_hp] --+DEBUG|HP: [$hp] for slot [$SlotLevel] }} That will keep the base HP for level 2 casts and increase by 5 for each level above 2. Could do something like that in your macro.
1703633405

Edited 1703633938
Thanks Joshua, the level math works great. I decided to try ScriptCards' object modification again. I was trying to use the character object type, which was the wrong one. I switched to the attribute object type and stuff started working. I have some questions about it, though, if you don't mind. Two of the attributes "hp" and "npc_ac" change the token bars for those two, but doesn't change the actual attribute on the character sheet. It looks like those two are "baked into" the script as token attributes. Do you know a way around this? Also, creating repeating sections using the "!or" command works great, but is there a way to delete repeating sections? It doesn't let you manipulate already created repeating sections. Thanks for all your help. Here's my code so far. !scriptcards {{ --#title|Summon Beast --#sourceToken|@{selected|token_id} --#emoteText|[*S:character_name] Casts Summon Beast. --#bodyfontface|Helvetica --#oddrowfontcolor|#290000 --#evenrowfontcolor|#290000 --#bodyfontsize|[&bodyFontSize]px --#titlecardbackgroundcolor|#930c10 --#titlecardbackgroundcolor|#672223 --#titlefontcolor|#fffebd --#titlefontsize|1.5em --#titlefontshadow|0 --#oddrowbackground|#f7ce65 --#evenrowbackground|#f7ce65 --#oddrowbackground|#b3ab96 --#evenrowbackground|#b3ab96 --#subtitlefontcolor|#fffebd --#tablebgcolor|#fffebd --#lineheight|10pt --#Debug|1 -->GetAndCheckSlotInformation|>[$SlotLevel] -->CommonAtt| -->GetBeast| -->RepeatExist --/>DeductSpellSlot| --X| --:CommonAtt| --=ACCalc|11+[$SlotLevel] --=hptotal|5 * [= [$SlotLevel] - 2] + 30 --&Speed|30ft, 30ft climb --!a:@{SummonBeast|character_id}| npc_name:Land Beast test| npc_type:Medium Beast, Unaligned| npc_ac:[$ACCalc]| hp:[$hptotal]|hp^:[$hptotal]| strength_base:18| dexterity_base:11| constitution_base:16| intelligence_base:4| wisdom_base:14| charisma_base:5| npc_speed:[$Speed]| npc_challenge: --<| --:GetBeast| --=Beast|?{What Beast Type?|Land,1|Air,2|Sea,3} --?[$Beast] -eq 1|Land-Beast --?[$Beast] -eq 2|Air-Beast --?[$Beast] -eq 3|Sea-Beast --<| --:Land-Beast| --!or:@{SummonBeast|character_id}:npctrait| name:Pack Tactics| description:The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. --@forselected|Spawn _name|SummonBeast _offset|1,0 _side|1 --<| --:Air-Beast| --!or:@{SummonBeast|character_id}:npctrait| name:Flyby| description:The beast doesn’t provoke opportunity attacks when it flies out of an enemy’s reach. --@forselected|Spawn _name|SummonBeast _offset|1,0 _side|3 --<| --:Sea-Beast| --!or:@{SummonBeast|character_id}:npctrait| name:Pack Tactics| description:The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. --!or:@{SummonBeast|character_id}:npctrait| name:Water Breathing| description:The beast can breathe only underwater. --@forselected|Spawn _name|SummonBeast _offset|1,0 _side|2 --<| --:RepeatExist| --Rfind|@{SummonBeast|character_id};Maul;repeating_npcaction;name --?[*R[name]] -eq Maul| --?[*R[name]] -ne Maul|RepeatSec --<| --:RepeatSec| --!or:@{SummonBeast|character_id}:npcaction| name:Maul| attack_flag:on| attack_type:melee| attack_target:one target| attack_range:5 ft.| attack_tohit:@{selected|spell_attack_bonus}| attack_damage:1d4 + 3 + [$SlotLevel]| attack_damagetype:piercing| attack_tohitrange:+5, Reach 5ft., one target| attack_onhit:5 (1d4 + 3) piercing damage| attack_crit:1d4| description:The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. --!or:@{SummonBeast|character_id}:npcaction|name:Multiattack|description:The beast makes a number of attacks equal to half this spell’s level (rounded down). --<| --:GetAndCheckSlotInformation| --=SlotLevel|?{Spell Slot Level Used?|2|3|4|5|6|7|8|9} --=SlotsTotal|0 --=SlotsExpended|[*S:lvl[$SlotLevel]_slots_expended] --?[$SlotsExpended.Total] -eq [$SlotsTotal.Total]|NoSlotsLeft --<| --:DeductSpellSlot| --=SlotsExpended|[$SlotsExpended] - 1 --@setattr|_charid [*S:character_id] _lvl[$SlotLevel]_slots_expended|[$SlotsExpended] _silent --+|Level [$SlotLevel] Slots Left: [$SlotsExpended] --X|Full Stop --:NoSlotsLeft| --+|[*S:character_name] has no level [$SlotLevel.Total] spell slots available. --X|NoSlotsLeftStop }}
1703637514

Edited 1703638375
Your script isn't changing the token properties. It's changing attributes of the character. I broke what you are doing down into smaller example scripts like so: !script {{ --#sourceToken|@{selected|token_id} --=SlotLevel|?{Spell Slot Level Used?|2|3|4|5|6|7|8|9} --=ACCalc|11+[$SlotLevel] --+DEBUG|OldAC:[*S:npc_ac] --!a:[*S:character_id]|npc_ac:[$ACCalc] --+DEBUG|NewAC:[*S:npc_ac] }} and !script {{ --#sourceToken|@{selected|token_id} --=SlotLevel|?{Spell Slot Level Used?|2|3|4|5|6|7|8|9} --=hptotal|5 * [= [$SlotLevel] - 2] + 30 --+DEBUG|OldHP:[*S:hp] --!a:[*S:character_id]|hp:[$hptotal]|hp^:[$hptotal] --+DEBUG|NewAC:[*S:hp] }} And I see the changes on the character sheet right away. I see the main sheet change the corresponding attributes on the Attributes and Abilities tab change. In script cards [*S:t- means "token" properties so  Graphic properties on the Roll20 objects  like imgsrc and top and left and the like. All other *S: properties are attributes on the character. What you are describing sounds like when you change the barX values of a token when it isn't linked to a character sheet but that's not what you are doing in the above script. For reference I am testing the above scripts on an NPC using the D&D5e sheet by Roll20 or what is still sometimes referred to as the OGL sheet and I can't seem to replicate that behavior. One thing to note in your script and other ScriptCards is that if you move to a branch with --> there is a difference when you pass values in, like -->ProcedureCall|Param1;Param2 And how that interacts with the  Return call  --<| that I see you use. Like in your conditionals for the type of beast, the return may just be falling through the next sections of your script.  :Label If just a label is specified, execution will branch to that label when the comparison is matched. NOTE: You cannot use a standard Return (--<|) statement to return to the Conditional (--?) statement and resume the script. Example: --?[$AttackRoll.Total] -ge [$TargetAC] |Hit |Miss Per the wiki section on conditionals . That is a common gotcha that not all calls to the branch are returnable. Not saying that is impacting this script, just something I noticed that may end up biting you in some way in this or future ScriptCards.  EDIT: Just wanted to add some quick examples to illustrate what I'm talking about. This code !script {{ --&number|2 --?[&number] -eq 1|FirstBranch --?[&number] -eq 2|SecondBranch --?[&number] -eq 3|ThirdBranch --+After The Conditionals| --X| --:FirstBranch| --+FirstBranch| --<| --:SecondBranch| --+SecondBranch| --<| --:ThirdBranch| --+ThirdBranch| --<| }} Generates the following: Where you see the code isn't returned back to the conditionals it just falls through the remainder of the ScriptCard. Whereas this code: !script {{ --&number|2 --?[&number] -eq 1|>FirstBranch;[&number] --?[&number] -eq 2|>SecondBranch;[&number] --?[&number] -eq 3|>ThirdBranch;[&number] --+After The Conditionals| --X| --:FirstBranch|ParamaterToPrint --+FirstBranch|Param:[%1%] --<| --:SecondBranch|ParamaterToPrint --+SecondBranch|Param:[%1%] --<| --:ThirdBranch|ParamaterToPrint --+ThirdBranch|Param:[%1%] --<| }} Generates the following: Where the gosub returns to the conditionals as expected and resumes the script from there.
1703690316

Edited 1703691810
Thanks for the tips, I am noobing all over the place... I'm trying to use this as a learning tool, I've locked a lot of it down in the 'ol brainpan. So, I've got it all working except for one thing; removing repeating traits. Because each type of beast has different or mixed traits, some need to be removed when switching beast types. Any ideas how to do that? Thanks EDIT: Spoke too soon, the hp and npc_ac are still only being changed on the token and not on the character sheet. I have no idea why. EDIT AGAIN: So, if the token is setup to use hp and npc_ac it doesn't change the character sheet attributes and only changes the token. This might be something to take up the ScriptCards author. !scriptcards {{ --#title|Summon Beast --#sourceToken|@{selected|token_id} --#emoteText|[*S:character_name] Casts Summon Beast. --#bodyfontface|Helvetica --#oddrowfontcolor|#290000 --#evenrowfontcolor|#290000 --#bodyfontsize|[&bodyFontSize]px --#titlecardbackgroundcolor|#930c10 --#titlecardbackgroundcolor|#672223 --#titlefontcolor|#fffebd --#titlefontsize|1.5em --#titlefontshadow|0 --#oddrowbackground|#f7ce65 --#evenrowbackground|#f7ce65 --#oddrowbackground|#b3ab96 --#evenrowbackground|#b3ab96 --#subtitlefontcolor|#fffebd --#tablebgcolor|#fffebd --#lineheight|10pt --#Debug|1 --&SummonBeast|@{SummonBeast|character_id} -->WhatSpellSlot|>[$SlotLevel] -->GetBeast| -->CommonAttr|>[&hplvl] -->RepeatExist| -->DeductSpellSlot| --X| --:WhatSpellSlot| --=SlotLevel|?{Spell Slot Level Used?|2|3|4|5|6|7|8|9} --=SlotsTotal|0 --=SlotsExpended|[*S:lvl[$SlotLevel]_slots_expended] --?[$SlotsExpended.Total] -eq [$SlotsTotal.Total]|NoSlotsLeft --<| --:GetBeast| --=Beast|?{What Beast Type?|Land,1|Air,2|Sea,3} --?[$Beast] -eq 1|Land-Beast --?[$Beast] -eq 2|Air-Beast --?[$Beast] -eq 3|Sea-Beast --X| --:Land-Beast| --&Type|1 --&hplvl|30 --Rfind|[&SummonBeast];Pack Tactics;repeating_npctrait;name --?[*R:name] -ninc Pack Tactics]|AddPT --<| --:Air-Beast| --&Type|3 --&hplvl|20 --Rfind|[&SummonBeast];Pack Tactics;repeating_npctrait;name --?[*R:name] -ninc Pack Tactics]|AddFB --<| --:Sea-Beast| --&Type|2 --&hplvl|30 --Rfind|[&SummonBeast];Pack Tactics;repeating_npctrait;name --?[*R:name] -ninc Pack Tactics]|AddPT --Rfind|[&SummonBeast];Water Breathing;repeating_npctrait;name --?[*R:name] -ninc Water|AddWater --<| --:CommonAttr| --=ACCalc|11+[$SlotLevel] --=hptotal|5 * [= [$SlotLevel] - 2] + [&hplvl] --&Speed|30ft, 30ft climb --!a:[&SummonBeast]|!npc_name:Land Beast|!npc_type:Medium Beast, Unaligned|!npc_ac:[$ACCalc]|!hp:[$hptotal]|!hp^:[$hptotal]|!strength_base:18|!dexterity_base:11|!constitution_base:16|!intelligence_base:4|!wisdom_base:14|!charisma_base:5|!npc_speed:[&Speed]|!npc_challenge: --@forselected|Spawn _name|SummonBeast _offset|1,0 _side|[&Type] --<| --:RepeatExist| --Rfind|[&SummonBeast];Maul;repeating_npcaction;name --&MaulExist|[*R:name] --?[&MaulExist] -ne Maul|RepeatSec --<| --:AddPT| --!or:[&SummonBeast]:npctrait|name:Pack Tactics|description:The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. --<| --:AddFB| --!or:[&SummonBeast]:npctrait| name:Flyby| description:The beast doesn’t provoke opportunity attacks when it flies out of an enemy’s reach. --<| --:AddWater| --!or:[&SummonBeast]:npctrait| name:Water Breathing| description:The beast can breathe only underwater. --<| --:RepeatSec| --!or:[&SummonBeast]:npcaction| name:Maul| attack_flag:on| attack_type:melee| attack_target:one target| attack_range:5 ft.| attack_tohit:@{selected|spell_attack_bonus}| attack_damage:1d4 + 3 + [$SlotLevel]| attack_damagetype:piercing| attack_tohitrange:+5, Reach 5ft., one target| attack_onhit:5 (1d4 + 3) piercing damage| attack_crit:1d4| description:The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. --!or:@{SummonBeast|character_id}:npcaction|name:Multiattack|description:The beast makes a number of attacks equal to half this spell’s level (rounded down). --<| --:DeductSpellSlot| --+Debug|[%1%] --=SlotsExpended|[$SlotsExpended] - 1 --@setattr|_charid [*S:character_id] _lvl[$SlotLevel]_slots_expended|[$SlotsExpended] _silent --+|Level [$SlotLevel] Slots Left: [$SlotsExpended] --X|Full Stop --:NoSlotsLeft| --+|[*S:character_name] has no level [$SlotLevel.Total] spell slots available. --X|NoSlotsLeftStop }}
I am not sure about removing attributes exactly but you can edit sections. Here is an example: !script {{ --#sourceToken|@{selected|token_id} --Rfirst|[*S:character_id];repeating_npctrait --+Before|Trait name:[*R:name][br][*R:description] --!a:[*S:character_id]|[*R>name]:NewName|[*R>description]:Description of the new thing --Rfirst|[*S:character_id];repeating_npctrait --+After|Trait name:[*R:name][br][*R:description] }} The *R syntax for repeating sections has two options. A : for getting the value and a > for getting the name. Using [*R>name] I can modify the name property of a repeating trait. The example above returns output like: And I see the changes on the d&d5e NPC character sheet: So you can certainly modify existing repeating attributes that way. I am just not sure about deleting existing. I can take a look at your script in more detail a bit later today but one thing I have noticed that is that in your conditionals of strings, you don't quote the strings and that may lead to some issues. It's a good practice to get into to quote the string variable like so: --?"[*R:name]" -ninc "Pack Tactics" Especially if you need to start checking for equality or inequality in strings that will help.
Hi Joshua, Yeah, I caught the quotes around the string variables thing, I'm learnding. Being able to rename repeating section entries changes everything... back to the drawing board. Thanks
1703713528
Kurt J.
Pro
API Scripter
 :Label If just a label is specified, execution will branch to that label when the comparison is matched. NOTE: You cannot use a standard Return (--<|) statement to return to the Conditional (--?) statement and resume the script. Example: --?[$AttackRoll.Total] -ge [$TargetAC] |Hit |Miss I just updated that section of the wiki, as it is a little unclear. You can return from a conditional branch as long as you use the >Label syntax instead just just the label name. You can pass parameters as well: !script {{   --+Before|One   --?1 -eq 1|>Say;Yes   --+After|Two   --X|   --:Say|   --+Saying|[%1%]   --<| }} Will result in:
Hey Kurt, Yeah, I kinda co-opted your ScriptCards thread with my shenanigans, but I got it to work. <a href="https://app.roll20.net/forum/post/11175456/script-scriptcards-thread-number-2/?pageforid=11737174#post-11737174" rel="nofollow">https://app.roll20.net/forum/post/11175456/script-scriptcards-thread-number-2/?pageforid=11737174#post-11737174</a>
1703892634

Edited 1703892903
Well, because I'm never happy with things the way they are and I much prefer the [rbutton] approach rather than dropdown menus I decided to do a little rewrite. I also wanted to include the creation of the rollable token table and the creation of the repeating actions as they only need to be created once as they are the same for all beast types. So, if you run the script the first time it'll check to see if the "Maul" repeating section exists on the NPC character sheet. If it doesn't, it creates the rollable table and the two repeating actions. On subsequent uses of the script it should skip the code that creates these and just run the spell code. The first time the script is run everything works out great, the rollable table and repeating actions are created, but on subsequent uses of the script it crashes the sandbox right after choosing what type of beast; the "GetBeast" section. Both scripts run fine seperately. Here's the sandbox crash message. Your scripts are currently disabled due to an error that was detected. Please make appropriate changes to your script's code and click the "Save Script" button. We will then attempt to start running the scripts again.&nbsp; More info... &nbsp;If this script was installed from the Mod Library, you might find help in the Community API Forum. For reference, the error message generated was:&nbsp; TypeError: Cannot read properties of undefined (reading '0') TypeError: Cannot read properties of undefined (reading '0') at replaceVariableContent (apiscript.js:11528:71) at apiscript.js:8232:22 at eval (eval at &lt;anonymous&gt; (/home/node/d20-api-server/api.js:168:1), &lt;anonymous&gt;:65:16) at Object.publish (eval at &lt;anonymous&gt; (/home/node/d20-api-server/api.js:168:1), &lt;anonymous&gt;:70:8) at /home/node/d20-api-server/api.js:1762: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) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546) at Id.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:489) at Ld.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:94:425) Here's the debug output. "Setting parameter debug to value 1 - 1" "Line Counter: 29, Tag:&amp;SummonBeast, Content:-NmrmQgxSXU2sJwoVJ4g" "Line Counter: 30, Tag:&gt;RepeatExist, Content:" "Line Counter: 92, Tag:Rfind, Content:-NmrmQgxSXU2sJwoVJ4g;Maul;repeating_npcaction;name" "Line Counter: 93, Tag:&amp;MaulExist, Content:Maul" "ContentIn: ?\"[&amp;MaulExist]\" -eq \"Maul\" Match: [&amp;MaulExist], vName: MaulExist, replacement Maul" "Line Counter: 94, Tag:?\"Maul\" -eq \"Maul\", Content:[" "Condition \"Maul\" -eq \"Maul\" evaluation result: true" "Line Counter: 95, Tag:&gt;WhatSpellSlot, Content:" "Line Counter: 33, Tag:+At what level is the spell being cast?, Content:" "Line Counter: 34, Tag:+, Content:[rbutton]2::WhatLVL;2[/rbutton][rbutton]3::WhatLVL;3[/rbutton][rbutton]4::WhatLVL;4[/rbutton][rbutton]5::WhatLVL;5[/rbutton][rbutton]6::WhatLVL;6[/rbutton][rbutton]7::WhatLVL;7[/rbutton][rbutton]8::WhatLVL;8[/rbutton][rbutton]9::WhatLVL;9[/rbutton]" "Line Counter: 35, Tag:&lt;, Content:" "Line Counter: 96, Tag:], Content:[" "Line Counter: 110, Tag:X, Content:" "Line Counter: 36, Tag::WhatLVL, Content:" "ContentIn: [&amp;reentryval] Match: [&amp;reentryval], vName: reentryval, replacement 2" "Line Counter: 37, Tag:=SlotLevel, Content:2" "Line Counter: 38, Tag:=SlotsTotal, Content:0" "ContentIn: [*S:lvl[$SlotLevel]_slots_expended] Match: [$SlotLevel], vName: SlotLevel, vSuffix: Total, replacement 2" "Line Counter: 39, Tag:=SlotsExpended, Content:82" "ContentIn: ?[$SlotsExpended.Raw] -eq [$SlotsTotal.Raw] Match: [$SlotsExpended.Raw], vName: SlotsExpended, vSuffix: Raw, replacement 82" "ContentIn: ?82 -eq [$SlotsTotal.Raw] Match: [$SlotsTotal.Raw], vName: SlotsTotal, vSuffix: Raw, replacement 0" "Line Counter: 40, Tag:?82 -eq 0, Content:NoSlotsLeft|MinusSlot" "Condition 82 -eq 0 evaluation result: false" "ContentIn: ?[$SlotLevel] -eq 0 Match: [$SlotLevel], vName: SlotLevel, vSuffix: Total, replacement 2" "Line Counter: 43, Tag:?2 -eq 0, Content:NoSlot" "Condition 2 -eq 0 evaluation result: false" "ContentIn: [$SlotsExpended] - 1 Match: [$SlotsExpended], vName: SlotsExpended, vSuffix: Total, replacement 82" "Line Counter: 44, Tag:=SlotsLeft, Content:82 - 1" "ContentIn: _charid -NkI_fM9DSFvkPt7oP2Z _lvl[$SlotLevel]_slots_expended|[$SlotsLeft] _silent Match: [$SlotLevel], vName: SlotLevel, vSuffix: Total, replacement 2" "ContentIn: _charid -NkI_fM9DSFvkPt7oP2Z _lvl2_slots_expended|[$SlotsLeft] _silent Match: [$SlotsLeft], vName: SlotsLeft, vSuffix: Total, replacement 81" "Line Counter: 45, Tag:@setattr, Content:_charid -NkI_fM9DSFvkPt7oP2Z _lvl2_slots_expended|81 _silent" "ScriptCards: Making API call - !setattr --charid -NkI_fM9DSFvkPt7oP2Z --lvl2_slots_expended|81 --silent" "Line Counter: 46, Tag:&gt;GetBeast, Content:" "Line Counter: 51, Tag:+What type of Beast are you summoning?, Content:[br][rbutton]Land::Land-Beast[/rbutton][rbutton]Air::Air-Beast[/rbutton][rbutton]Water::Sea-Beast[/rbutton]" "Line Counter: 52, Tag:X, Content:" "Line Counter: 53, Tag::Land-Beast, Content:" "Line Counter: 54, Tag:&amp;Type, Content:1" "Line Counter: 55, Tag:&amp;hplvl, Content:30" "ContentIn: !a:[&amp;SummonBeast] Match: [&amp;SummonBeast], vName: SummonBeast, replacement -NmrmQgxSXU2sJwoVJ4g" "Line Counter: 56, Tag:!a:-NmrmQgxSXU2sJwoVJ4g, Content:!npc_name:Land Beast" "ContentIn: [&amp;SummonBeast];repeating_npctrait Match: [&amp;SummonBeast], vName: SummonBeast, replacement -NmrmQgxSXU2sJwoVJ4g" "Line Counter: 57, Tag:Rfirst, Content:-NmrmQgxSXU2sJwoVJ4g;repeating_npctrait" "ContentIn: !a:[&amp;SummonBeast] Match: [&amp;SummonBeast], vName: SummonBeast, replacement -NmrmQgxSXU2sJwoVJ4g" "Line Counter: 58, Tag:!a:-NmrmQgxSXU2sJwoVJ4g, Content:NoRepeatingAttributeLoaded:Pack Tactics|NoRepeatingAttributeLoaded:The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated." "Line Counter: 59, Tag:Rnext, Content:" "ContentIn: !a:[&amp;SummonBeast] Match: [&amp;SummonBeast], vName: SummonBeast, replacement -NmrmQgxSXU2sJwoVJ4g" TypeError: Cannot read properties of undefined (reading '0') TypeError: Cannot read properties of undefined (reading '0') at replaceVariableContent (apiscript.js:11528:71) at apiscript.js:8232:22 at eval (eval at &lt;anonymous&gt; (/home/node/d20-api-server/api.js:168:1), &lt;anonymous&gt;:65:16) at Object.publish (eval at &lt;anonymous&gt; (/home/node/d20-api-server/api.js:168:1), &lt;anonymous&gt;:70:8) at /home/node/d20-api-server/api.js:1762: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) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546) at Id.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:489) at Ld.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:94:425) Here's the macro script. !scriptcards {{ --#title|Summon Beast --#sourceToken|@{selected|token_id} --#emoteText|[*S:character_name] Casts Summon Beast. --#bodyfontface|Helvetica --#oddrowfontcolor|#290000 --#evenrowfontcolor|#290000 --#bodyfontsize|[&amp;bodyFontSize]px --#titlecardbackgroundcolor|#930c10 --#titlecardbackgroundcolor|#672223 --#titlefontcolor|#fffebd --#titlefontsize|1.5em --#titlefontshadow|0 --#oddrowbackground|#f7ce65 --#evenrowbackground|#f7ce65 --#oddrowbackground|#b3ab96 --#evenrowbackground|#b3ab96 --#subtitlefontcolor|#fffebd --#tablebgcolor|#fffebd --#lineheight|10pt --#buttonfontsize|10px --#buttonbackground|#930c10 --#buttonbackground|#672223 --#buttonbackground|rgba(103,34,35,1); display:inline-block; --#buttonfontface|Tahoma --#buttonpadding|8px --#bodyfontface|Helvetica --#bodyfontsize|14px --#Debug|1 --&amp;SummonBeast|@{SummonBeast|character_id} --&gt;AllExist| --X| --:AllExist| --Rfind|@{SummonBeast|character_id};Maul;repeating_npcaction;name --&amp;MaulExist|[*R:name] --?"[&amp;MaulExist]" -eq "Maul"|[ --&gt;WhatSpellSlot| --]|[ --+|[b]Creating Rollable Token Table for First Run[/b] --!o#:tableid|SummonBeast --+New Table ID|[&amp;tableid] --!oe:entryid|[&amp;tableid];Land-Beast --+New Entry ID|[&amp;entryid] --!oe:entryid|[&amp;tableid];Air-Beast --+New Entry ID|[&amp;entryid] --!oe:entryid|[&amp;tableid];Water-Beast --+New Entry ID|[&amp;entryid] --+Rollable Token Table SummonBeast created.| Find the table under Collection and set up your Land, Air and Water beast tokens.[br]Don't forget to link your new rollable token to your SummonBeast character sheet and turn vision on. The next run of this macro will just cast the spell. --!or:[&amp;SummonBeast]:npcaction| name:Maul| attack_flag:on| attack_type:melee| attack_target:one target| attack_range:5 ft.| attack_tohit:@{selected|spell_attack_bonus}| attack_damage:1d8 + 4 + [$SlotLevel]| attack_damagetype:piercing| attack_tohitrange:| attack_range:5ft.| attack_target:one target| attack_onhit:1d8 + 4 + [$SlotLevel]| description:The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. --!or:[&amp;SummonBeast]:npcaction|name:Multiattack|description:The beast makes a number of attacks equal to half this spell’s level (rounded down). --]| --X| --:WhatSpellSlot| --+At what level is the spell being cast?| --+|[rbutton]2::WhatLVL;2[/rbutton][rbutton]3::WhatLVL;3[/rbutton][rbutton]4::WhatLVL;4[/rbutton][rbutton]5::WhatLVL;5[/rbutton][rbutton]6::WhatLVL;6[/rbutton][rbutton]7::WhatLVL;7[/rbutton][rbutton]8::WhatLVL;8[/rbutton][rbutton]9::WhatLVL;9[/rbutton] --&lt;| --:WhatLVL| --=SlotLevel|[&amp;reentryval] --=SlotsTotal|0 --=SlotsExpended|[*S:lvl[$SlotLevel]_slots_expended] --?[$SlotsExpended.Raw] -eq [$SlotsTotal.Raw]|NoSlotsLeft|MinusSlot --X| --:MinusSlot| --?[$SlotLevel] -eq 0|NoSlot --=SlotsLeft|[$SlotsExpended] - 1 --@setattr|_charid [*S:character_id] _lvl[$SlotLevel]_slots_expended|[$SlotsLeft] _silent --&gt;GetBeast| --X| --:NoSlot| --X| --:GetBeast| --+What type of Beast are you summoning?|[br][rbutton]Land::Land-Beast[/rbutton][rbutton]Air::Air-Beast[/rbutton][rbutton]Water::Sea-Beast[/rbutton] --X| --:Land-Beast| --&amp;Type|1 --&amp;hplvl|30 --!a:[&amp;SummonBeast]|!npc_name:Land Beast --Rfirst|[&amp;SummonBeast];repeating_npctrait --!a:[&amp;SummonBeast]|[*R&gt;name]:Pack Tactics|[*R&gt;description]:The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. --Rnext| --!a:[&amp;SummonBeast]|[*R&gt;name]:|[*R&gt;description]:description: --&gt;CommonAttr| --&lt;| --:Air-Beast| --&amp;Type|2 --&amp;hplvl|20 --!a:[&amp;SummonBeast]|!npc_name:Air Beast --Rfirst|[&amp;SummonBeast];repeating_npctrait --!a:[&amp;SummonBeast]|![*R&gt;name]:Flyby|![*R&gt;description]:The beast doesn’t provoke opportunity attacks when it flies out of an enemy’s reach. --Rnext| --!a:[&amp;SummonBeast]|[*R&gt;name]:|[*R&gt;description]:description: --&gt;CommonAttr| --&lt;| --:Sea-Beast| --&amp;Type|3 --&amp;hplvl|30 --!a:[&amp;SummonBeast]|!npc_name:Water Beast --Rfirst|[&amp;SummonBeast];repeating_npctrait --!a:[&amp;SummonBeast]|[*R&gt;name]:Pack Tactics|[*R&gt;description]:The beast has advantage on an attack roll against a creature if at least one of the beast’s allies is within 5 feet of the creature and the ally isn’t incapacitated. --Rnext| --!a:[&amp;SummonBeast]|[*R&gt;name]:Water Breathing|[*R&gt;description]:The beast can breathe only underwater. --&gt;CommonAttr| --&lt;| --:CommonAttr| --=ACCalc|11 + [$SlotLevel] --=hptotal|5 * [= [$SlotLevel] - 2] + [&amp;hplvl] --&amp;Speed|30ft, 30ft climb --!a:[&amp;SummonBeast]|!npc_type:Medium Beast, Unaligned|!npc_ac:[$ACCalc]|!hp:[$hptotal]|!hp^:[$hptotal]|!strength_base:18|!dexterity_base:11|!constitution_base:16|!intelligence_base:4|!wisdom_base:14|!charisma_base:5|!npc_speed:[&amp;Speed]|!npc_challenge: --@forselected|Spawn _name|SummonBeast _offset|1,0 _side|[&amp;Type] --+|Level [$SlotLevel] Slots Left: [$SlotsLeft] --&lt;| --:NoSlotsLeft| --+|[*S:character_name] has no level [$SlotLevel.Total] spell slots available. --X|NoSlotsLeftStop }} I definitely think this has to do with table creation because my original script without it worked fine. But, I'm not running the table creation on the runs of the script after the first time. So, I am a confused person.
Nope, removing both the table creation script and the repeating section script didn't help anything. Is it something I'm doing? I don't see anything wrong, but I'm not even at the level of understanding the crash debug output.
I've tried several different "either/or" method and they all seem to crash. --:AllExist| --Rfind|@{SummonBeast|character_id};Maul;repeating_npcaction;name --&amp;MaulExist|[*R:name] --?"[&amp;MaulExist]" -inc "Maul"|&gt;WhatSpellSlot|&gt;FirstTime --X| --:AllExist| --Rfind|@{SummonBeast|character_id};Maul;repeating_npcaction;name --&amp;MaulExist|[*R:name] --?"[&amp;MaulExist]" -inc "Maul"|WhatSpellSlot --?"[&amp;MaulExist]" -ninc "Maul"|FirstTime --X|
Discovered it has nothing to do with this but is in fact something to do with the spell script. I had it working, which is why this is so puzzling to me.
And this is why you don't create macros when you are overtired... I forgot to include creating the npc traits...