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

Way to lock tokens (for movement only) on token layer

I'm planning to use the Check It Out script for a future dungeon, but I'm worried that having a bunch of objects on the token layer (available for players to click with Check It Out) will lead to me accidentally selecting and moving something by accident. Is there a way (API or otherwise) to "lock" an object? That is, to fix in a specific place on the map, but still make it selectable? Apologies if this is basic info. I've looked online, but I haven't been able to find info that relates.
// Github: <a href="https://github.com/shdwjk/Roll20API/blob/master/MapLock/MapLock.js" rel="nofollow">https://github.com/shdwjk/Roll20API/blob/master/MapLock/MapLock.js</a> // By: The Aaron, Arcane Scriptomancer // Contact: <a href="https://app.roll20.net/users/104025/the-aaron" rel="nofollow">https://app.roll20.net/users/104025/the-aaron</a> var MapLock = MapLock || (function() { 'use strict'; var version = '0.4.4', lastUpdate = 1490707622, schemaVersion = 0.4, checkInstall = function() { log('-=&gt; MapLock v'+version+' &lt;=- ['+(new Date(lastUpdate*1000))+']'); if( ! _.has(state,'MapLock') || state.MapLock.version !== schemaVersion) { log(' &gt; Updating Schema to v'+schemaVersion+' &lt;'); state.MapLock = { version: schemaVersion, highlighting: false, locked: {} }; } }, ch = function (c) { var entities = { '&lt;' : 'lt', '&gt;' : 'gt', "'" : '#39', '@' : '#64', '{' : '#123', '|' : '#124', '}' : '#125', '[' : '#91', ']' : '#93', '"' : 'quot', '-' : 'mdash', ' ' : 'nbsp' }; if(_.has(entities,c) ){ return ('&amp;'+entities[c]+';'); } return ''; }, showHelp = function(who) { sendChat('', '/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +'&lt;div style="font-weight: bold; border-bottom: 1px solid black;font-size: 130%;"&gt;' +'MapLock v'+version +'&lt;/div&gt;' +'&lt;div style="padding-left:10px;margin-bottom:3px;"&gt;' +'&lt;p&gt;MapLock provides a way to lock individual graphics in place. This prevents them from being moved, resized, or rotated by reverting any of those changes that are made to them. It also provides tinting of locked items.&lt;/p&gt;' +'&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; Even though it'+ch("'")+'s called MapLock, it works for any graphics on any layers.' +'&lt;/div&gt;' +'&lt;b&gt;Commands&lt;/b&gt;' +'&lt;div style="padding-left:10px;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;!map-lock '+ch('&lt;')+' &lt;i&gt;lock&lt;/i&gt; '+ch('|')+' &lt;i&gt;unlock&lt;/i&gt; '+ch('|')+' &lt;i&gt;toggle&lt;/i&gt; '+ch('|')+' &lt;i&gt;toggle-highlight&lt;/i&gt; '+ch('|')+' &lt;i&gt;--help&lt;/i&gt; '+ch('&gt;')+'&lt;/span&gt;&lt;/b&gt;' +'&lt;div style="padding-left: 10px;padding-right:20px"&gt;' +'&lt;p&gt;Adjusts locking options for selected graphics.&lt;/p&gt;' +'&lt;ul&gt;' +'&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;lock&lt;/span&gt;&lt;/b&gt; '+ch('-')+' Adds these graphics to the list of locked items.' +'&lt;/li&gt; ' +'&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;unlock&lt;/span&gt;&lt;/b&gt; '+ch('-')+' Removes these graphics from the list of locked items.' +'&lt;/li&gt; ' +'&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;toggle&lt;/span&gt;&lt;/b&gt; '+ch('-')+' Switched the selected graphics from locked to unlocked or vice versa.' +'&lt;/li&gt; ' +'&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;toggle-highlight&lt;/span&gt;&lt;/b&gt; '+ch('-')+' Turns on or off the red tinting of locked graphics.' +'&lt;/li&gt; ' +'&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;--help&lt;/span&gt;&lt;/b&gt; '+ch('-')+' Shows the help.' +'&lt;/li&gt; ' +'&lt;/ul&gt;' +'&lt;/div&gt;' +'&lt;/div&gt;' +'&lt;/div&gt;' ); }, msgPlayer = function(who,msg) { sendChat('MapLock','/w "'+who+'" '+ '&lt;div style="font-weight:bold;font-size: 90%; border: 1px solid #999999; background-color: #ffcccc;"&gt;'+ msg + '&lt;/div&gt;' ); }, tintGraphics = function(gids, highlight) { _.chain(gids) .map(function(id){ return getObj('graphic',id); }) .reject(_.isUndefined) .each(function(o){ var t = state.MapLock.locked[o.id]; o.set({ tint_color: ( highlight ? '#ff0000' : t || 'transparent') }); }); }, handleInput = function(msg) { var args,who,ids,cnt=0; if (msg.type !== "api" || !playerIsGM(msg.playerid)) { return; } args = msg.content.split(/\s+/); switch(args.shift()) { case '!map-lock': who=(getObj('player',msg.playerid)||{get:()=&gt;'API'}).get('_displayname'); ids=_.pluck(msg.selected,'_id'); switch(args.shift()) { case 'toggle': if(ids) { _.each(ids,function(id){ var o=getObj('graphic',id); ++cnt; if( o &amp;&amp; !_.has(state.MapLock.locked,id) ){ state.MapLock.locked[id]=o.get('tint_color'); tintGraphics([id], state.MapLock.highlighting); } else { tintGraphics([id], false); delete state.MapLock.locked[id]; } }); msgPlayer(who, 'Toggled '+cnt+' token'+(1 === cnt ? '' : 's')); } else { msgPlayer(who, '&lt;span style="font-color: #ff0000;"&gt;ERROR:&lt;/span&gt; Nothing selected.'); } break; case 'lock': if(ids) { _.each(ids,function(id){ var o=getObj('graphic',id); if( o &amp;&amp; !_.has(state.MapLock.locked,id) ){ ++cnt; state.MapLock.locked[id]=o.get('tint_color'); } }); tintGraphics(ids, state.MapLock.highlighting); msgPlayer(who, 'Locked '+cnt+' token'+(1 === cnt ? '' : 's')); } else { msgPlayer(who, '&lt;span style="font-color: #ff0000;"&gt;ERROR:&lt;/span&gt; Nothing selected.'); } break; case 'unlock': if(ids) { ids=_.intersection(ids,_.keys(state.MapLock.locked)); tintGraphics(ids, false); _.each(ids,function(id){ delete state.MapLock.locked[id]; ++cnt; }); msgPlayer(who, 'Unlocked '+cnt+' token'+(1 === cnt ? '' : 's')); } else { msgPlayer(who, '&lt;span style="font-color: #ff0000;"&gt;ERROR:&lt;/span&gt; Nothing selected.'); } break; case 'toggle-highlight': state.MapLock.highlighting = !state.MapLock.highlighting; tintGraphics(_.keys(state.MapLock.locked), state.MapLock.highlighting); break; case '--help': default: showHelp(who); break; } break; } }, HandleMove = function(obj,prev) { if(_.has(state.MapLock.locked, obj.id) &amp;&amp; ( obj.get('left') !== prev.left || obj.get('top') !== prev.top || obj.get('height') !== prev.height || obj.get('width') !== prev.width || obj.get('rotation') !== prev.rotation ) ) { obj.set({ left: prev.left, top: prev.top, height: prev.height, width: prev.width, rotation: prev.rotation }); } }, registerEventHandlers = function() { on('chat:message', handleInput); on('change:graphic', HandleMove); }; return { CheckInstall: checkInstall, RegisterEventHandlers: registerEventHandlers }; }()); on('ready',function() { 'use strict'; MapLock.CheckInstall(); MapLock.RegisterEventHandlers(); }); I think this is the droid you are looking for! I use this to lock my doors in place on the token map! Should work for the exact purpose you are looking for. The commands are !map-lock lock for Locking in Position and !map-lock unlock to free it up again!
Thanks so much! Will test this out tonight.
1563387391
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
That's what I use. It doesn't exactly lock the tokens, but if they are moved, it immediately moves them back. So if you use it for a token that provides vision to players, it can give them a quick glimpse of something they might not otherwise be able to see. But for locking doors and notes, its great!
Thanks, Keith. I'm actually surprised that the ability to lock an object isn't built into Roll20 itself. But this is a great solution.
1563391199
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Thank Anthony V. :)
If you only update on drop players can't scout with the locked tokens.
1563408669
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Actually, I just tested this a few days ago. There is a very brief amount of time between the drop and the move-back when the vision flashes. That's why I said "quick glimpse".
Tried the script out, and I like it a lot. My only request (for the future) is to be able to make the tint less overwhelming. Currently, it's either no tint or a red tint that fills up the whole token space, which I don't like for aesthetic reasons. Having control of the tint -- or better yet, being able to replace tint with a status marker -- would be optimal. Other than that, it works great, and it will really help me with the next dungeon!
1563418883
The Aaron
Roll20 Production Team
API Scripter
The tint was only intended as a way to see what wasn't locked, not really meant to be left on. I could adjust it to be something less garish, or provide a way to set it. Are you leaving it on all the tine? &nbsp;You could tint them with TokenMod to a different shade.&nbsp;
The Aaron said: The tint was only intended as a way to see what wasn't locked, not really meant to be left on. I could adjust it to be something less garish, or provide a way to set it. Are you leaving it on all the tine? &nbsp;You could tint them with TokenMod to a different shade.&nbsp; Ohhh my mistake. I was leaving it on. Now it makes sense.
One feature request: the ability to toggle locked state for a token with one command. Right now you have to do map-lock lock or map-lock unlock, which means either a menu or two macro buttons. I'd prefer to be able to have just one button to lock or unlock a token, similar to SimpleDoorControls or what have you.
1563494098
The Aaron
Roll20 Production Team
API Scripter
Ah, good point! &nbsp;I'll add a toggle.&nbsp;
1563494846
The Aaron
Roll20 Production Team
API Scripter
Actually.. it looks like there's already a toggle option: !map-lock toggle That should add things that aren't locked, and remove things that are locked out of the selected set of tokens.
The Aaron said: Actually.. it looks like there's already a toggle option: !map-lock toggle That should add things that aren't locked, and remove things that are locked out of the selected set of tokens. Oh, didn't see that! I only thought the toggle applied to the highlight state. That's great. Saves me a macro button. Thanks.
1563506586
The Aaron
Roll20 Production Team
API Scripter
No worries! =D