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

Auto Assign Imported Characters

Is there a script that would either automatically assign imported (through the vault) to the player that imported them, or that would allow a player to specify the character name and have it assign that character to their journal/give control? It boggles my mind why characters imported through the vault don't default to the person importing them. We have a large shared game with multiple DMs so nearly every game all the players are importing their sheets. Thanks!
1556832360
The Aaron
Roll20 Production Team
API Scripter
I can write you a script that does the latter, the former isn't possible as there is nothing in the API that would let me identify who did the import.
1556847476
The Aaron
Roll20 Production Team
API Scripter
Here it is.&nbsp; Use the API command: !claim-character SOME TEXT It will find any characters that have the supplied text (case-insensitive) contiguously, ignoring punctuation or spaces, for example: !claim-character bob the would match any of: "Bob the Slayer" "Mr Bob the happy" "thisbobthekiller" It will then whisper a list of the matching characters with a claim button: If there are no matches, it will tell you: Clicking a "Claim" button will assign the character to the person clicking it (and put it in their journal), and whisper a link to the player and notice they claimed the character, as well as whisper the GM to let them know the player claimed it: Probably having a macro with: !claim-character ?{character name} for your players would make this pretty easy. Code: on('ready',()=&gt;{ const keyname = t =&gt; t.replace(/[^a-z0-9]/ig,'').toLowerCase(); const s = { choice: "max-width: 6em; border: 1px solid #999; border-radius: .5em; background-color: white; padding: .5em;float:left;min-height: 10em;", nomatch: "max-width: 6em; border: 1px solid #999; border-radius: .5em; background-color: white; padding: .5em;float:left;min-height: 10em;", image: 'display: inline-block;', name: 'display: block; font-weight: bold;', message: '', button: '' }; const choice = c=&gt;`&lt;div style="${s.choice}"&gt;&lt;img style="${s.image}" src="${c.get('avatar')}" /&gt;&lt;div style="${s.name}"&gt;${c.get('name')}&lt;/div&gt;&lt;div style="${s.button}"&gt;&lt;a href="!claim-character-by-id ${c.id}"&gt;Claim&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;`; const nomatch = n=&gt;`&lt;div style="${s.nomatch}"&gt;&lt;div style="${s.message}"&gt;No match for name:&lt;/div&gt;&lt;div style="${s.name}"&gt;${n}&lt;/div&gt;&lt;/div&gt;`; on('chat:message', msg =&gt; { if('api'===msg.type) { if(/^!claim-character\b\s/i.test(msg.content)){ let who = getObj('player',msg.playerid).get('_displayname'); let output=''; let name = msg.content .split(/\s+/) .slice(1) .join(' ') ; let key = keyname(name); findObjs({ type: 'character' }) .filter(c=&gt;-1 !== (keyname(c.get('name'))).indexOf(key)) .forEach(c=&gt; output += choice(c)); if(!output.length){ output += nomatch(name); } sendChat('',`/w "${who}" &lt;div style="${s.container}"&gt;${output}&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;/div&gt;`); } if(/^!claim-character-by-id\b\s/i.test(msg.content)){ let who = getObj('player',msg.playerid).get('_displayname'); let args = msg.content.split(/\s+/); let character = getObj('character', args[1]); if(character){ character.set({ controlledby: `${[...new Set([...character.get('controlledby').split(','), msg.playerid])].join(',')}`, inplayerjournals: `${[...new Set([...character.get('inplayerjournals').split(','), msg.playerid])].join(',')}` }); sendChat('',`/w "${who}" You can now control &lt;a style="color: #07c;" href="<a href="http://journal.roll20.net/character/${character.id}&quot;&gt;${character.get('name')}&lt;/a&gt;`" rel="nofollow">http://journal.roll20.net/character/${character.id}"&gt;${character.get('name')}&lt;/a&gt;`</a>); sendChat('',`/w gm Player &lt;b&gt;${who}&lt;/b&gt; has claimed &lt;a style="color: #07c;" href="<a href="http://journal.roll20.net/character/${character.id}&quot;&gt;${character.get('name')}&lt;/a&gt;.`" rel="nofollow">http://journal.roll20.net/character/${character.id}"&gt;${character.get('name')}&lt;/a&gt;.`</a>); } else { sendChat('',`/w "${who}" No character found for &lt;code&gt;${args[1]}&lt;/code&gt;.`); } } } }); });
@The Aaron - Somehow I knew it'd be you that provided a solution. &lt;3
1556902985
The Aaron
Roll20 Production Team
API Scripter
It's not ideal, as players can pretty much claim anyone.&nbsp; I'm trying to think of a way to identify a vaulted character, or at least a PC, but there really isn't a generic way to handle it.&nbsp; I could restrict it to only characters that have been imported in the last X timeframe, or something similar, but that might be over thinking it.&nbsp; I'm interested in any feedback to improve it though. =D
1556913511

Edited 1556913557
Mike
Pro
So far it's working great! I'm not really worried about players claiming sheets that aren't their, but I suppose a second command to remove that access from yourself if you claimed by accident could be useful.&nbsp; You could also check if the sheet is already claimed or check if it's NPC, and optionally prevent them from claiming. That said, I'd make that an option as I could see this being useful in game when players want to shape shift or summon creatures. It'd be nice to let them just claim the creature. The only other problem we have, and I can't think of a clean solution, is that oftentime because players are constantly rotating into games we'll end up with 2 or 3 copies of the same PC. Letting players delete sheets they own could be useful, though that could be risky/problematic.
1556914622
The Aaron
Roll20 Production Team
API Scripter
Can definitely check if it's already claimed by someone else.&nbsp; Telling if it's an NPC is a difficult task, and very game/sheet dependent.&nbsp; From the point of the API, all characters appear the same.&nbsp; I was hoping that imported characters would retain the controlling character id from the other game, which would simply not match any in the new game allowing imported characters to be identified.&nbsp; Sadly that was not the case.&nbsp; Another option would be to let the script be turned on and off by a GM, and queue request when off.&nbsp; That could also be applied for queueing requests for deletes, letting the GM do the actual delete via the API (still easy, but would prevent players accidentally deleting NPCs they'd taken control of by mistake, etc). I'll think on that, let me know how it plays out as is.
1556919867

Edited 1556921082
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Maybe the script could index existing characters at spin-up time and hold the names in state. If you want to claim a character, it needs to be not on that list. Then a player could claim any character they vaulted in during that session. They'd probably have to load the campaign, and then vault?
1556921867
The Aaron
Roll20 Production Team
API Scripter
I thought about doing something with the creation time in the character. I think that would be easier.&nbsp;
It's worked perfectly for game today. :-)