We use Cookies to help personalize and improve Roll20. For more information on our use of non-essential Cookies, visit our Privacy Policy here.
Accept
Advertisement Create a free account

[Request] Random Token Locations

lets say I want select some tokens and randomize their location on the page? can it be done? I'm sure. I just don't know how to code. I'd think it would go something like detect the size of the page to use as the bounds and then send them to a random location within the bounds.  is this too elementary of thinking?  is there a script that handles this?  thanks!
1581660564

Edited 1581660726
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Token mod can move tokens around, on a page, and you can use math formulas to randomly specify the location. If you inadvertently move a token off the edge of the map, it can be retrieved with a script the Aaron wrote. I'm trying to track that down... Edit: Here it is.
1581664512
GiGs
Pro
Sheet Author
API Scripter
There's another script someone posted ages ago, probably Aaron, originally for randomising the location of tavern patrons, but IIRC you could use it for randomising anything. Unfortunately I cant remember what it was called.
1581691660
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Aaron's script can be found here . Interesting to note that he begins the post with "If I were writing a script for this", and ends the post with a fully realized script, github page and documentation, indicating that he wrote the script before finishing the post . I believe the Aaron is a mythological creature that inhales ideas and exhales code.
1581709780

Edited 1581709912
I think the code below might have been the particular The Aaron script that GiGs was thinking about (but I didn't know about the tavern one, so thanks for linking that!): // Github: <a href="https://github.com/shdwjk/Roll20API/blob/master/RandomRotate/RandomRotate.js" rel="nofollow">https://github.com/shdwjk/Roll20API/blob/master/RandomRotate/RandomRotate.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 RandomRotate = RandomRotate || (function(){ 'use strict'; var version = '0.2.3', lastUpdate = 1565053927, checkInstall = function(){ log('-=&gt; RandomRotate v'+version+' &lt;=- ['+(new Date(lastUpdate*1000))+']'); }, showHelp = function() { sendChat('', '/w gm ' +'&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;' +'RandomRotate v'+version +'&lt;div style="clear: both"&gt;&lt;/div&gt;' +'&lt;/div&gt;' +'&lt;div style="padding-left:10px;margin-bottom:3px;"&gt;' +'&lt;p&gt;Allows the GM to easily randomize the rotation of the selected tokens.&lt;/p&gt;' +'&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;!random-rotate&lt;/span&gt;&lt;/b&gt;' +'&lt;div style="padding-left: 10px;padding-right:20px"&gt;' +'Adjusts the rotation of all the selected tokens to a random angle.' +'&lt;/div&gt;' +'&lt;/div&gt;' +'&lt;div style="padding-left:10px;"&gt;&lt;b&gt;&lt;span style="font-family: serif;"&gt;!random-spread&lt;/span&gt;&lt;/b&gt;' +'&lt;div style="padding-left: 10px;padding-right:20px"&gt;' +'Adjusts the location of the selected tokens to a random location within the bounds of the current token positions.' +'&lt;/div&gt;' +'&lt;/div&gt;' +'&lt;/div&gt;' ); }, handleInput = function(msg) { var args, tok, lx = 100000, ly = 100000, hx = 0, hy = 0, optionRotate = false, optionGrid = false; if ( "api" !== msg.type || !playerIsGM(msg.playerid) ) { return; } args = msg.content.split(/\s+/); switch(args[0]) { case '!random-spread': if(!( msg.selected &amp;&amp; msg.selected.length &gt; 0 ) ) { showHelp(); return; } args = msg.content.split(/\s+--/); args.shift(); while(args.length) { tok = args.shift().split(/\s+/); switch(tok[0]) { case 'rotate': optionRotate = true; break; case 'grid': optionGrid = true; break; } } _.chain(msg.selected) .map(function (o) { return getObj(o._type,o._id); }) .filter(function(o){ return 'token' === o.get('subtype'); }) .map(function(o){ lx=Math.min(lx,o.get('left')) || 0; ly=Math.min(ly,o.get('top')) || 0; hx=Math.max(hx,o.get('left')) || 0; hy=Math.max(hy,o.get('top')) || 0; return o; }) .each(function(o){ var x = (randomInteger(hx-lx)+lx), y = (randomInteger(hy-ly)+ly), mod = { top: y, left: x }; if(optionRotate) { mod.rotation = (randomInteger(360)-1); } o.set(mod); }) ; break; case '!random-rotate': if(!( msg.selected &amp;&amp; msg.selected.length &gt; 0 ) ) { showHelp(); return; } _.chain(msg.selected) .map(function (o) { return getObj(o._type,o._id); }) .filter(function(o){ return 'token' === o.get('subtype'); }) .each(function(o){ o.set({rotation: (randomInteger(360)-1)}); }) ; break; } }, registerEventHandlers = function() { on('chat:message', handleInput); }; return { CheckInstall: checkInstall, RegisterEventHandlers: registerEventHandlers }; }()); on("ready",function(){ 'use strict'; RandomRotate.CheckInstall(); RandomRotate.RegisterEventHandlers(); }); It has two commands:&nbsp; !random-spread !random-rotate Running either of those without a token selected will bring up the help in-game which reads: RandomRotate v0.2.3 Allows the GM to easily randomize the rotation of the selected tokens. Commands !random-rotate Adjusts the rotation of all the selected tokens to a random angle. !random-spread Adjusts the location of the selected tokens to a random location within the bounds of the current token positions. Because it bases its bounding box for the spread action on the starting position of the selected tokens, you'll first want to move two tokens to diagonally-opposed corners of the area you'd like to affect with all of the tokens (whether that's the whole map or just a particular room).&nbsp; It's also worth noting that running either command will deselect the tokens after it's finished so it's a good idea to make a macro that calls both commands at the same time if you know you'll frequently want to run those steps together and don't want to bother having to select all the tokens multiple times.