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
This post has been closed. You can still view previous posts, but you can't post any new replies.

[Script] 5e Shaped Support Script

1459239744
Kryx
Pro
Sheet Author
API Scripter
Damage not working looks like a sheet issue so ignore it. Mutliattack: As Lucian pointed out neither consider this much of a priority. It's just there to inform you of which attacks to click. If anything I'd parse the names of those attacks and set them up to automatically run, but there isn't a ton of value there imo.
Hmmm seems to be bugging out for me now. I used the 1.0 script just fine, but when I just updated to 1.0.8 and changed back the FifthSpells to fifthSpells for my spells list. Yet now it throws this error so I'm unclear as to what to do to change it.  /home/symbly/www/d20-api-server/node_modules/firebase/lib/firebase-node.js:1 orts, require, module, __filename, __dirname) { function g(a){throw a;}var j=v ^ TypeError: Cannot call method 'split' of undefined at versionCompare (evalmachine.<anonymous>:21238:21) at evalmachine.<anonymous>:21283:9 at eval (
1459248056

Edited 1459248101
Will it be possible for spells to get auto imported when doing !shaped-import-monster?
1459248406
Lucian
Pro
API Scripter
Robert said: Will it be possible for spells to get auto imported when doing !shaped-import-monster? Yes, it's on the todo list. To avoid excess noise here, it would be great if people could check out the list of known issues and intended enhancements here:&nbsp; <a href="https://github.com/symposion/roll20-api-scripts/is" rel="nofollow">https://github.com/symposion/roll20-api-scripts/is</a>... before posting. Thanks!
1459248695
Lucian
Pro
API Scripter
Saevar L. "Liquid-Sonic" said: Hmmm seems to be bugging out for me now. I used the 1.0 script just fine, but when I just updated to 1.0.8 and changed back the FifthSpells to fifthSpells for my spells list. Yet now it throws this error so I'm unclear as to what to do to change it.&nbsp; /home/symbly/www/d20-api-server/node_modules/firebase/lib/firebase-node.js:1 orts, require, module, __filename, __dirname) { function g(a){throw a;}var j=v ^ TypeError: Cannot call method 'split' of undefined at versionCompare (evalmachine.&lt;anonymous&gt;:21238:21) at evalmachine.&lt;anonymous&gt;:21283:9 at eval ( If anyone else has this issue, it's because you have an old version of the data, and then I made a mistake in my version comparison code that is causing it to explode rather than print a nice error message. You need to update the JSON data to a more recent format (there have been changes to simplify the way things work). PM me if you need help with updating the data.
No luck on the Represents/Avatar. Using Support Script 0.1.8, Shaped Sheet 2.2.23. I do get the image error every time even on the freshly uploaded directly to map image. Everything else seems to work great. If there is anything I can provide, let me know.
Noticed something else When importing, it looks like your putting in line breaks which break the GM whisper The same happens for importing spells. You get the " Added the following spells:" in whisper, but the spell name is in open chat. For reference for others, the Represents/Avatar setting only functions for the !shaped-import-statblock, not !shaped-import-monster. I exclusively used the monster import, which is why nothing was set. The statblock import works.
1459270554
Lucian
Pro
API Scripter
@BP Thanks for the heads-up : I'll add that to the buglist.
1459342589

Edited 1459349956
I have a statblock in the GM notes of a character. ANIMATED ARMOR Medium construct, unaligned Armor Class 18 (natural armor) Hit Points 33 (6d8 + 6) Speed 25ft. STR 14 (+2) DEX 11 (+0) CON 13 (+1) INT 1 (-5) WIS 3 (-4) CHA 1 (-5) Damage Immunities poison, psychic Condition Immunities blinded, charmed, deafened, exhaustion, frightened, paralyzed, petrified, poisoned Senses blindsight 60ft. (blind beyond the is radius), passive Perception 6 Languages - Challenge 1 (200 XP) Antimagic Susceptibility. The armor is incapacitated while in the area of an anti magic field. If targeted by dispel magic, the armor must succeed on a Constitution saving throw against the caster's spell save DC or fall unconscious for 1 minute. False Appearance. While the armor remains motion less, it is indistinguishable from a normal suit of armor. ACTIONS Multiattack. The armor makes two melee attacks. Slam. Melee Weapon Attack: +4 to hit, reach 5 ft ., one target. Hit: 5 (1d6 + 2) bludgeoning damage. I have selected a token that represents that character sheet I type in: !shaped-import-statblock Nothing happens Below is what I get from Api output. What am I doing wrong? **EDIT** When I don't select something I do get something back from ShapedScripts. Otherwise nothing. "ShapedScripts 1459342225399 INFO : Importing statblocks for tokens [{\"_id\":\"-KE6SyT_9PmoWZHCfDzU\",\"_pageid\":\"-KBP27jjGYTZDZ_xv171\",\"left\":481,\"top\":874,\"width\":70,\"height\":70,\"rotation\":0,\"layer\":\"objects\",\"isdrawing\":false,\"flipv\":false,\"fliph\":false,\"imgsrc\":\"<a href="https://s3.amazonaws.com/files.d20.io/images/17667230/QlvomPSHV8pE7y9DlyDuDg/med.jpg?1459340432\&quot;,\&quot;name\&quot;:\&quot;Eokrew" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/17667230/QlvomPSHV8pE7y9DlyDuDg/med.jpg?1459340432\",\"name\":\"Eokrew</a> Egriunut\",\"gmnotes\":\"\",\"controlledby\":\"\",\"bar1_value\":\"\",\"bar1_max\":\"\",\"bar1_link\":\"\",\"bar2_value\":\"\",\"bar2_max\":\"\",\"bar2_link\":\"\",\"bar3_value\":\"\",\"bar3_max\":\"\",\"bar3_link\":\"\",\"represents\":\"-KE6Sg4y0BbSVyRv3i09\",\"aura1_radius\":\"\",\"aura1_color\":\"#FFFF99\",\"aura1_square\":false,\"aura2_radius\":\"\",\"aura2_color\":\"#59E594\",\"aura2_square\":false,\"tint_color\":\"transparent\",\"statusmarkers\":\"\",\"showname\":false,\"showplayers_name\":false,\"showplayers_bar1\":false,\"showplayers_bar2\":false,\"showplayers_bar3\":false,\"showplayers_aura1\":false,\"showplayers_aura2\":false,\"playersedit_name\":true,\"playersedit_bar1\":true,\"playersedit_bar2\":true,\"playersedit_bar3\":true,\"playersedit_aura1\":true,\"playersedit_aura2\":true,\"light_radius\":\"\",\"light_dimradius\":\"\",\"light_otherplayers\":false,\"light_hassight\":false,\"light_angle\":\"\",\"light_losangle\":\"\",\"light_multiplier\":1,\"sides\":\"\",\"currentSide\":0,\"lastmove\":\"506,760\",\"_type\":\"graphic\",\"_subtype\":\"token\",\"_cardid\":\"\"}]"
Lucian H. said: Updating existing sheet: As Kryx says, if you want duplicate tokens, you should be dragging and dropping from the journal. I think the script overwriting existing characters is dangerous - it has the potential for people to lose a lot of work. I'll consider adding a --overwrite option so that you can do it if you really want to, but I'd discourage you from using the approach - the alternative is much safer! For those people who are planning to upgrade an existing campaign, the overwrite option would definitely be beneficial.
1459351240
Lucian
Pro
API Scripter
@Rick: The statblock goes in the GM notes for a token, not a character. The script will make the character for you automatically.
That was it. Working on a small screen so I didn't see it. Thanks a bunch.
1459351928
Lucian
Pro
API Scripter
@Kevin & @Tim <a href="https://github.com/symposion/roll20-api-scripts/issues/28" rel="nofollow">https://github.com/symposion/roll20-api-scripts/issues/28</a> . Just to be sure, the expected behaviour here with --overwrite is that the importer looks for a character with the same name, and if one exists anywhere in the campaign, it gets overwritten without possibility of recovery? Seems like a pretty dangerous option to me. I guess having to select an existing token to overwrite a character would make it substantially less useful to you?
1459352265
Kryx
Pro
Sheet Author
API Scripter
It wouldn't be dangerous as you require the overwrite keyword. However my concern would be that everything gets imported properly. The sheet expects a clean slate and if it isn't clean it may present problems. I would never use it and don't quite see the need as one just delete the old one.
Let me explain what I am trying to do, maybe there is simply a better workflow for me to follow. I have a campaign that I would like to upgrade to the latest sheet. &nbsp;This campaign has ~100 or so NPC/Monsters with the token setup and ready to go (using the old sheet). Characters I am not worried about, there is 6... that can be handled manually if required, but the NPC needs some level of automation or it will be overwhelming. &nbsp;This will have to be done once the configuration portion is completed, but here is what I thought to do: 1) pull monster from the journal to the tabletop 2) execute the import --overwrite command with the existing token selected Now I could optionally do the following: 1) pull monster from the journal to the tabletop 2) delete the existing journal entry 3) import the new character If it is better to use the workflow that deletes the existing journal entry, then maybe I can create a script that will do step 2 for me automatically, so I could create a macro that would simply be: !deletechar --?{name} !shaped-import-monster --?{name} Then it is a matter of pulling the token out, executing the macro.
1459354938
Lucian
Pro
API Scripter
Hi Kevin, If &nbsp;you delete the character you will then need to set up the default token by hand again. Kryx, if I delete all of the attributes from a character in this situation before doing the import, that should prevent any lag issues, right? That's probably the best option to achieve what Kevin wants. If he's doing it with the token selected I think that's pretty safe - there's really no ambiguity there about which journal entry is intended (which is my main worry with overwriting based on name) Lucian
1459355369
Kryx
Pro
Sheet Author
API Scripter
Ah, there is a use case there. I really wish roll20 API could set default tokens - it would solve a lot of problems. @Lucian: If you delete (remove, not set to empty) everything then the sheetworkers should be totally fine.
1459355482
Lucian
Pro
API Scripter
Ok, will do that as part of the --overwrite enhancement.
I believe what some people are referring too was when a Token was selected it would be set as a default Image for the character bios rather than the tokens default.
1459362547
Lucian
Pro
API Scripter
Saevar L. "Liquid-Sonic" said: I believe what some people are referring too was when a Token was selected it would be set as a default Image for the character bios rather than the tokens default. Yep, that works for statblock import, but not JSON import. It's on my list to make it work with JSON import.
Thanks guys, glad the use case made sense, this feature will make it much easier now as essentially you will only need to: 1) &nbsp;Pull the token from the journal. 2) &nbsp;!shaped-import-monster --@{selected|character_name}
1459374679
Tim
Pro
Sheet Author
Compendium Curator
A small feature request - might it be possible one day to have something like a "populate-bars" command or similar? I like to use diverse token art (for, say, a group of 12 commoners - they'll all have unique tokens). But if I want them properly created, I have to go through and set all three bars on all the tokens (I like to have AC/Speed/HP, personally), which can become quite time-consuming. An API command to automatically fill out a token's bars based on its linked character sheet would be awesome (bar1/bar2/bar3 as per customizable settings, ideally). Certainly not a priority but I just thought I'd throw it out there.
Is there a patreon or something set up so we can thank Lucian for his efforts?
1459377276
Lucian
Pro
API Scripter
Tim said: A small feature request - might it be possible one day to have something like a "populate-bars" command or similar? I like to use diverse token art (for, say, a group of 12 commoners - they'll all have unique tokens). But if I want them properly created, I have to go through and set all three bars on all the tokens (I like to have AC/Speed/HP, personally), which can become quite time-consuming. An API command to automatically fill out a token's bars based on its linked character sheet would be awesome (bar1/bar2/bar3 as per customizable settings, ideally). Certainly not a priority but I just thought I'd throw it out there. Already on the list :-)
1459377801
Lucian
Pro
API Scripter
Robert said: Is there a patreon or something set up so we can thank Lucian for his efforts? I don't have anything like that - I've spent considerably less effort on this than people like Kryx or Aaron have contributed here, so it's really not necessary at all. If anyone is particularly keen and has money burning a hole in their pocket, you shouldn't give it to me anyway, there are much better things to spend it on... but you could make a donation to my wife's efforts to improve the lot of local animals:&nbsp;<a href="https://www.gofundme.com/catslasalpujarras" rel="nofollow">https://www.gofundme.com/catslasalpujarras</a> .&nbsp;
1459378674
Lars K.
Pro
Sheet Author
API Scripter
Tim said: A small feature request - might it be possible one day to have something like a "populate-bars" command or similar? I like to use diverse token art (for, say, a group of 12 commoners - they'll all have unique tokens). But if I want them properly created, I have to go through and set all three bars on all the tokens (I like to have AC/Speed/HP, personally), which can become quite time-consuming. An API command to automatically fill out a token's bars based on its linked character sheet would be awesome (bar1/bar2/bar3 as per customizable settings, ideally). Certainly not a priority but I just thought I'd throw it out there. I just use&nbsp; TokenMod and a quick macro like&nbsp; !token-mod {{ --set bar3|@{selected|hp} bar2_value|@{selected|npc_speed} bar1_value|@{selected|ac} }}
1459379009
Lars K.
Pro
Sheet Author
API Scripter
Kryx said: Ah, there is a use case there. I really wish roll20 API could set default tokens - it would solve a lot of problems. @Lucian: If you delete (remove, not set to empty) everything then the sheetworkers should be totally fine. Lucian H. said: Ok, will do that as part of the --overwrite enhancement. Could we get this delete as a separate (from overwrite) command in the script? I have a similar use case to Kevin, but I'm not using the import. I'm either doing manual entering (for custom NPCs) or importing from SRD. I just want to get rid of the cruft from the old character sheet (not the shaped sheet in this case).
1459379743
Lucian
Pro
API Scripter
Lars K. said: Could we get this delete as a separate (from overwrite) command in the script? I have a similar use case to Kevin, but I'm not using the import. I'm either doing manual entering (for custom NPCs) or importing from SRD. I just want to get rid of the cruft from the old character sheet (not the shaped sheet in this case). Hi Lars, I don't think that this really belongs in the shaped script - it's a generic utility for cleaning character sheets. It's trivial to write however: on('chat:message', function(msg) { &nbsp; &nbsp;if(msg.type === 'api' && msg.content === '!clean-char') { &nbsp; &nbsp; &nbsp; &nbsp;_.chain(msg.selected) &nbsp; &nbsp; &nbsp; &nbsp;.where({_type:'graphic'}) &nbsp; &nbsp; &nbsp; &nbsp;.map(function(selectedItem) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var graphic = getObj('graphic', selectedItem._id); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(graphic.get('represents')) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return findObjs({type:'attribute', characterid:graphic.get('represents')}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp;}) &nbsp; &nbsp; &nbsp; &nbsp;.compact() &nbsp; &nbsp; &nbsp; &nbsp;.flatten() &nbsp; &nbsp; &nbsp; &nbsp;.invoke('remove'); &nbsp; &nbsp;} }); (No warranties, this is a throwtogether, but you get the idea)
1459380014
Lars K.
Pro
Sheet Author
API Scripter
Thanks Lucian! Just what I was looking for :)
1459446391
Lucian
Pro
API Scripter
Version 0.2: <a href="https://github.com/symposion/roll20-api-scripts/is" rel="nofollow">https://github.com/symposion/roll20-api-scripts/is</a>... - Overwrite option to replace existing characters (NB: this is currently displaying some strange behaviours, I believe there may be a Roll20 bug lurking here. If you have trouble, rerun the import a second time and it should fix itself) <a href="https://github.com/symposion/roll20-api-scripts/is" rel="nofollow">https://github.com/symposion/roll20-api-scripts/is</a>... - Support lair actions and regional effects from the JSON. Note that the sheet does not yet display regional effects (Kryx will add this at some point I believe) <a href="https://github.com/symposion/roll20-api-scripts/is" rel="nofollow">https://github.com/symposion/roll20-api-scripts/is</a>... - Fix multiline outputs to not break GM whispers <a href="https://github.com/symposion/roll20-api-scripts/is" rel="nofollow">https://github.com/symposion/roll20-api-scripts/is</a>... - Fix unhelpful error message on bad JSON version <a href="https://github.com/symposion/roll20-api-scripts/is" rel="nofollow">https://github.com/symposion/roll20-api-scripts/is</a>... - Populate GM Notes on new characters <a href="https://github.com/symposion/roll20-api-scripts/is" rel="nofollow">https://github.com/symposion/roll20-api-scripts/is</a>... - Set default options for characters and tokens + provide config interface for this (see OP for more instructions) <a href="https://github.com/symposion/roll20-api-scripts/is" rel="nofollow">https://github.com/symposion/roll20-api-scripts/is</a>... - Support TokenNameNumber Various minor tweaks and bugfixes. Apologies for the rather techie command line interface for setting options. I'm too lazy to write a proper UI and a little bird tells me that a certain Scriptomancer might have something in the works that will make this easier, so I'm holding out for that!
1459447583
Lucian
Pro
API Scripter
PS. As usual, please ensure that you are on the latest version of the sheet before testing the new script!
1459449628
Lucian
Pro
API Scripter
Version 0.2.1: Bug fix for broken HP rolling - sorry!
Sorry... was testing 0.2.0 when you posted 0.2.1... you can ignore at least one of the bugs I opened then as I will retest it on 0.2.1 later tonight.
1459454823
Jakob
Sheet Author
API Scripter
Lucian H. said: Version 0.2: *snip* Amazing work! Supporting TokenNameNumber is something I didn't even remember I wanted, and here you go and implement it.
1459455185
Lucian
Pro
API Scripter
Version 0.2.2: Fix bugs with rollHPOnDrop and newCharSettings.autoAmmo config options - Thanks to Kevin for doing the testing that I should have done before releasing it!
1459465472

Edited 1459468802
I tried this with a beholder and some dragons. I don't think the lair actions are importing from JSON. Nevermind. Have to update sheet
Do we just treat each json file as a new script since there are multiple files for the monsters?
@Lucian: found a bug with tokenSettings.barX.ShowPlayers &nbsp; &nbsp;sent you a pull request. I think that should resolve both issues.
Ah so the previous data files for spells and monsters won't parse with the entire set present - I just assumed I was doing it wrong.
Ahh just after I made every monster in MM you now come with an Avatar ability. And there we go doing it all again. :P
1459510461
Lucian
Pro
API Scripter
Rick V. said: Ahh just after I made every monster in MM you now come with an Avatar ability. And there we go doing it all again. :P So wait, you have all the monsters as characters, and you have a default token set up for each one, which has "represents" pointing back to the character? If so, you could drag all your characters to the canvas, select all the tokens and run an API command to fix the avatar from the token. Something like this would probably work: on('chat:message', function(msg) { &nbsp; &nbsp; if (msg.type === 'api' && msg.content === '!set-avatar') { &nbsp; &nbsp; &nbsp; &nbsp; _.chain(msg.selected) &nbsp; &nbsp; &nbsp; &nbsp;.where({_type:'graphic'}) &nbsp; &nbsp; &nbsp; &nbsp;.each(function(selectedItem) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var graphic = getObj('graphic', selectedItem._id); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var character = getObj('character', graphic.get('represents')); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(character) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;character.set('avatar', graphic.get('imgsrc')); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp;}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } }); Run !set-avatar with the relevant tokens selected. No warranties express or implied, minimal testing, yada yada. Also, this will only work if the tokens are using images from your own library, not the marketplace or the web.
Hi Lucian. No sadly I didn't have any avatars set for all the monsters! I made all the monsters from JSON. They come without an avatar. I was now adding an avatar to each one manually. (wish your update come sooner, or way later so I didnt feel that my time was wasted :P) I am know going to --overwrite each monster/character with a generic token that I selected. Is there by the way a mode where I can just import and overwrite all the monsters from a JSON?
1459515610
Lucian
Pro
API Scripter
Hey Rick, You're going to have to be more precise about what you are trying to achieve, and what state you're in right now. You've imported monsters from JSON - do you have any tokens connected to them at all? I know you don't have avatars - am asking about whether you've linked tokens to the characters. If you don't, I'm really not sure what you're hoping to achieve with an overwrite - you'd still have to set all the images up manually anyway? Have you customised the monsters heavily after import or something? If you can describe *exactly* where you are now, and then lay out the sequence of steps you'd ideally like to follow, I might be able to sort something out for you. Cheers, Lucian
@ Lucian, Sure thing. So what I have done is following. I have imported every monster from JSON using !shaped-import-monster. I imported them 10 at a time. One separate command on each line. When I did more it couldn't handle it each time. This created an entire list of monsters without a default token and avatar. To use these monsters in roll20 on the canvas they at least need to have an avatar or token set for them. This means allot of manual clicking: opening up the character, edit, and then set either the avatar or token. I thought of using tokenmod and TokenActionCreator each time a drag a character on the canvas to set them up quickly (even if it made a token from the avatar image) What I would like is the following: To have every single character/monster from the JSON have either an default avatar or token image (something generic.) If those characters would have default tokens that those tokens would have Actions Macro's made just like TokenActionCreator does and their bars set to specific stats (which you can already do now). Doing this by either altering all current characters/monsters (quite hard I think?) or overwriting all current characters/monsters with new info/tokens. Does this make any sense? Thanks for trying out to help!
1459518970

Edited 1459519276
Lucian
Pro
API Scripter
@Rick - Ah, I think I see now. You want a default avatar for each token (the same for every one) - just so it's draggable to the canvas? Sadly there is no way for the script to set up a new default token on a character - that's a Roll20 limitation - but I could set an avatar.&nbsp; Here's the best I think I can do: I give you an API command that you provide an image URL to (from your library). It will run through all characters in the campaign and set the avatar to the supplied image for all characters that do not already have an avatar You drag the the characters to the tabletop en masse &nbsp;and run !shaped-token-defaults with them all selected - this will configure your tokens as you want them You select each token in turn, shift-double-click to open the character info, edit, set default token to currently selected The result will be that all your monsters have a single stock image for their token, but at least they all have the correct setup. It's still a fair amount of manual work, but the roll20 limitation means you have to the default token yourself by hand. If you don't do that, there's no way to ensure that the new tokens will be set up the way you want when you drag and drop to the canvas from the journal. But at least it's better than having to do *everything* manually! Would that work for you?
1459519091
Lucian
Pro
API Scripter
Out of interest, you say that the script didn't work if you passed more than about 10 monsters at a time - can you tell me what error it gave you? Or did it just take a really long time?
That would be awesome Lucian! How do I drag en masse en&nbsp; though :P Uhm it didn't give an error. It just stopped doing it. I put the following in chat and it stopped after the 16th or something. 10 just was easier to keep track of. I get the commands out of an excel sheet btw. !shaped-import-monster --Wererat !shaped-import-monster --Weretiger !shaped-import-monster --Werewolf !shaped-import-monster --Adult White Dragon !shaped-import-monster --Ancient White Dragon !shaped-import-monster --White Dragon Wyrmling !shaped-import-monster --Young White Dragon !shaped-import-monster --Wight !shaped-import-monster --Will-O'-Wisp !shaped-import-monster --Winged Kobold !shaped-import-monster --Winter Wolf !shaped-import-monster --Wolf !shaped-import-monster --Worg !shaped-import-monster --Wraith !shaped-import-monster --Wyvern !shaped-import-monster --Xorn !shaped-import-monster --Yeti
1459520161
Lucian
Pro
API Scripter
For future reference you want to do !shaped-import-monster --Worg --Wraith --Wyvern --Xorn etc. rather than running each as a separate command - it will be faster and it should work with an unlimited number at once. As for dragging en masse ... well... perhaps I was glossing over the reality of it slightly. Yes, sorry, you're going to have to drag them one by one. But you can selected them all at once and run the !shaped-token-defaults as a single command, so that's at least something. I'll look into this later - I'm currently doing something else that you probably want to wait for anyway - auto spell import for NPCs.