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

A way to display a picture to only one player, or to only specific players.

There are some instances where I want to show a picture to only one player, for instance: The rogue or scout peeks into a room or around a corner and sees a creature that the party has not seen before, then goes back to verbally describe what he saw. In practice, I have a macro (show below) that displays the picture in a whisper to the player in the chat window (thanks to The Aaron and keithcurtis for posting info that helped me create this: /w GM ?{Choose Image| /w "@{target|character_name}" Orc_Zombie [x](<a href="https://s3.amazonaws.com/files.d20.io/images/259923163/WNm8Bn9S2u3Q8paUx1J69Q/original.png)|" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/259923163/WNm8Bn9S2u3Q8paUx1J69Q/original.png)|</a> /w "@{target|character_name}" Djannis [x](<a href="https://s3.amazonaws.com/files.d20.io/images/292041123/m5NNQGmRkSaXErHDruyZkQ/original.png)|" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/292041123/m5NNQGmRkSaXErHDruyZkQ/original.png)|</a> /w "@{target|character_name}" Maksim [x](<a href="https://s3.amazonaws.com/files.d20.io/images/292042223/Aig05MvKzeta8-HHsGtyfQ/original.png)|" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/292042223/Aig05MvKzeta8-HHsGtyfQ/original.png)|</a> /w "@{target|character_name}" Konstantin [x](<a href="https://s3.amazonaws.com/files.d20.io/images/292041785/Q5-bnIXoFbUCom7FegTF1Q/original.png)|" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/292041785/Q5-bnIXoFbUCom7FegTF1Q/original.png)|</a> /w "@{target|character_name}" Wraith [x](<a href="https://s3.amazonaws.com/files.d20.io/images/288120462/YQbvjbCFQvI4hjozlwuh4g/original.png?)|" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/288120462/YQbvjbCFQvI4hjozlwuh4g/original.png?)|</a> /w "@{target|character_name}" Necromancer [x](<a href="https://s3.amazonaws.com/files.d20.io/images/259394404/QCy2mGgnvQOAbx_N4368rA/original.jpg" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/259394404/QCy2mGgnvQOAbx_N4368rA/original.jpg</a>) } This works fine, but is cumbersome because I have to prepare the macro ahead of time for individual maps, and the "Shift-Z -&gt; get image address -&gt; copy/past into the code -&gt; edit extraneous info from the address" routine is a PITA. What I would like is a way to select the character token/tokens, then select the picture, which I keep outside of the map border where the players can't 'see. The picture would then display to only the selected player, either privately in the chat window or otherwise.
1660491916
Kraynic
Pro
Sheet Author
If you have the image on a handout, you can do this by clicking the "Show to Players" button.&nbsp; If you don't have any players already set for the view permissions, that button will set the view permission to "All Players" and make it pop up for everyone.&nbsp; If you already have view permissions set, then it will only show the handout to that player or players that are specified by the view permission field.&nbsp; When I have an image that will only be shown to certain players, I simply use a handout and set permissions as needed.
1660493041

Edited 1660493107
Oosh
Sheet Author
API Scripter
You're probably fine doing what Kraynic said, but I had a spare minute so I bashed this together in case it's useful: /* globals on, getObj, sendChat */ on('ready', () =&gt; { const getControlledBy = (tokenArray) =&gt; { const playerIds = tokenArray.reduce((out, t) =&gt; { let controlledBy = ''; const represents = t.get('represents'); if (represents) { const char = getObj('character', represents); controlledBy = char.get('controlledby'); } else controlledBy = t.get('controlledby'); const ids = controlledBy.split(/\s*,\s*/g).filter(v =&gt; /^-/.test(v)); ids.forEach(id =&gt; { if (!out.includes(id)) out.push(id); }); return out; }, []); return playerIds; } const chatTemplate = `/w "%%player%%" [img](%%url%%)`, summaryTemplate = `/w gm &amp;{template:default} {{name=whisperArt Summary}} {{Players=%%playerNames%%}} {{Art=%%artNames%%}}`; on('chat:message', (msg) =&gt; { if (msg.type === 'api' &amp;&amp; /^!whisperArt/i.test(msg.content)) { const selectedTokens = msg.selected ? msg.selected.map(o =&gt; getObj('graphic', o._id)) : null; let artKeyword = (msg.content.match(/--keyword\s*(\w+)/)||[])[1]; artKeyword = artKeyword || 'Artwork'; if (selectedTokens &amp;&amp; artKeyword) { const { artTokens, playerTokens } = selectedTokens.reduce((out, t) =&gt; { const targetCategory = t.get('tooltip') === artKeyword ? 'artTokens' : 'playerTokens'; out[targetCategory].push(t); return out; }, { artTokens: [], playerTokens: [] }); const artLinks = artTokens.map(t =&gt; t.get('imgsrc').replace(/(\.\w+)\?.*/, '$1')), artNames = artTokens.map((t,i) =&gt; t.get('name') || `img${i+1}`); const playerIds = getControlledBy(playerTokens), playerNames = playerIds.map(id =&gt; (getObj('player', id)||{}).get('displayname')); artLinks.forEach(url =&gt; { playerNames.forEach(name =&gt; { const msg = chatTemplate.replace('%%player%%', name).replace('%%url%%', url); sendChat('GM', msg); }); }); const summaryMsg = summaryTemplate .replace('%%playerNames%%', playerNames.length ? playerNames.join(', ') : '---') .replace('%%artNames%%', artNames.length ? artNames.join(', ') : '---'); sendChat('whisperArt', summaryMsg); } } }); }); The artwork tokens need a tiny bit of setup - they need a keyword entered into their tooltip (Artwork with a capital A is the default), and you'll get a better summary if you give the token a name as well. Then all you need to do is select the artwork, and any players' tokens you want to send the artwork(s) to, and type !whisperArt Multiple art tokens and player tokens are fine - all selected art will be sent to all selected players. The GM gets a summary of what was sent (it's sent from the API 'player', not from the GM so you won't see the message yourself). There's only one CLI command - if you don't want to use the word Artwork as the keyword in the tooltips for all the art tokens, you can use something else and then run it with: !whisperArt --keyword MyKeyword
1660497102
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
This would probably be a useful addition to Supernotes. I may steal some of your code, Oosh, for that mythical point in the future where coding time exists.
Kraynic said: If you have the image on a handout, you can do this by clicking the "Show to Players" button.&nbsp; If you don't have any players already set for the view permissions, that button will set the view permission to "All Players" and make it pop up for everyone.&nbsp; If you already have view permissions set, then it will only show the handout to that player or players that are specified by the view permission field.&nbsp; When I have an image that will only be shown to certain players, I simply use a handout and set permissions as needed. I'll keep this method in mind. It's already&nbsp;the method I use for items that only specific players know about, such as items that their characters possess but the others' characters don't know about. The trouble here is that if I set up the handout visibility&nbsp;before hand (during game prep) the handout will be visible in the player's journal, and if it's noticed they will sneak a peek ahead of time. Also, I may not correctly predict which player will see the McGuffin first. I could set the permissions on the fly during game play, but that's not quite as streamlined as I would like. Thanks for the idea though!
Oosh said: You're probably fine doing what Kraynic said, but I had a spare minute so I bashed this together in case it's useful: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; Thanks! I will try this out. It looks like exactly what I was looking for. I'm going to have to learn how to code; being retired, I have the time to learn new stuff! This looks like fun
1660502362
Kraynic
Pro
Sheet Author
Rick A. said: The trouble here is that if I set up the handout visibility&nbsp;before hand (during game prep) the handout will be visible in the player's journal, and if it's noticed they will sneak a peek ahead of time. Also, I may not correctly predict which player will see the McGuffin first. I could set the permissions on the fly during game play, but that's not quite as streamlined as I would like. I tend to not leave things visible in the journal for players unless I intend for them to be able to reference it on their own later.&nbsp; You can show them things like this without it showing in their journal by simply archiving the handout.&nbsp; If you use any index/gm notes type handouts of your own, you can keep a categorized list of links for yourself to view and access, while players won't see any of it in their journals even if they have view permissions.&nbsp; If your players are familiar with Roll20 UI mechanics, that won't keep them from making their own link if they know how.&nbsp; You could simply remove the permissions later if you don't want them to view it on their own, since links to archived handouts only work when the person clicking the link has the view permission.
Kraynic said: ...&nbsp; You can show them things like this without it showing in their journal by simply archiving the handout.&nbsp; If you use any index/gm notes type handouts of your own, you can keep a categorized list of links for yourself to view and access, while players won't see any of it in their journals even if they have view permissions. I did not know that about archived handouts. Thanks!
Oosh said: You're probably fine doing what Kraynic said, but I had a spare minute so I bashed this together in case it's useful: Worked like a charm!
1660525080

Edited 1660526648
Oosh
Sheet Author
API Scripter
Awesome! I wasn't particularly thorough checking for errors (it should at least be able to be run with nothing selected and not crash the sandbox :D ) so let me know if it causes any issues. I haven't worked with tokens much, there could be some edge cases that cause problems. keithcurtis said: This would probably be a useful addition to Supernotes. I may steal some of your code, Oosh, for that mythical point in the future where coding time exists. Steal away! Though I'd say Aaron has likely written better functions to do each of those required tasks somewhere along the line.
1660536423

Edited 1660536642
Oosh said: Awesome! I wasn't particularly thorough checking for errors (it should at least be able to be run with nothing selected and not crash the sandbox :D ) so let me know if it causes any issues. I haven't worked with tokens much, there could be some edge cases that cause problems. No issues have come up and I've tried it out several times. I had to restart the sandbox once, but other weird things were happening a that time so I doubt that your script was the culprit. I played with it some more a couple of hours later and the issue didn't repeat. I did alter your summary template a bit to change the output: I judged that the players don't always need to know who else can see the McGuffin. const chatTemplate = `/w "%%player%%" [img](%%url%%)`, summaryTemplate = `/w gm &amp;{template:default} {{name=You See:}} {{%%artNames%%}}`; The ability to use the name field of the token for descriptive text is a nice bonus! I changed the summary's title to "You See:" so that the output can read: "a 3' tall stone marker" or "this person dart around a corner"
1660543206
Oosh
Sheet Author
API Scripter
Ah ok - that summaryTemplate is currently only whispered to the GM - the players never get that one. The 'you see' template might need to move to chatTemplate if you want the players to see it. I only mostly put the summary in there so you (the GM) actually get some feedback that something was sent. Also, if the script doesn't find a player or art token in your selection, it'll let you know that as well.
Oosh said: Ah ok - that summaryTemplate is currently only whispered to the GM - the players never get that one. The 'you see' template might need to move to chatTemplate if you want the players to see it. I only mostly put the summary in there so you (the GM) actually get some feedback that something was sent. Also, if the script doesn't find a player or art token in your selection, it'll let you know that as well. I did not realize that. Only seeing the output as the GM, I thought the player saw both whispers. I'll play around with it and see if I can get it to display the contents of the token name field to the players as well. Thanks again for writing this!