Ok, #1 was an interesting problem to solve during an all hands meeting... =D Command: !marshal-tokens [ <token id> ... ] Select a bunch of tokens and run !marshal-tokens to build the tightest geometric shape for the given number of tokens. Uses the "first" token as the top left corner (correcting its alignment if necessary). You can also supply a group of token ids on the command line, or some combination of the two. Code: on('ready',function(){
"use strict";
var positioner=function(x,y){
var shell = (n) => Math.ceil(Math.sqrt(n)),
xyforn = (n) => {
var s=shell(n),
sm=s-1,
sSeq=n-(Math.pow(sm,2)),
pSeq=Math.ceil(sSeq/2);
return {
x: (sSeq%2 ? pSeq : s)-1,
y: (sSeq%2 ? s : pSeq)-1
};
},
startx=x,
starty=y,
count=0;
return function(obj){
var coord=xyforn(++count);
obj.set({
top: starty+(coord.y*70),
left: startx+(coord.x*70)
});
};
},
normalizer=function(n) {
return (Math.max(0,Math.floor((n-35)/70))*70)+35;
};
on('chat:message',function(msg){
var cmd,ids,poser;
if('api' !== msg.type || !playerIsGM(msg.playerid) ){
return;
}
ids = msg.content.split(/\s+/);
cmd = ids.shift();
ids = _.union(ids, ((msg.selected && _.pluck(msg.selected,'_id')) || []) );
switch(cmd){
case '!marshal-tokens':
_.chain(ids)
.uniq()
.map( (id) => getObj('graphic',id) )
.reject(_.isUndefined)
.tap(function(a){
let o=_.first(a)||{get:()=>0},
x=normalizer(o.get('left')),
y=normalizer(o.get('top'));
poser=positioner(x,y);
})
.each( poser);
}
});
});