Here's one you can start with. MarshalTokens -- groups selected tokens together into a tight formation: on('ready',()=>{
const positioner = (x,y) => {
const shell = (n) => Math.ceil(Math.sqrt(n));
const xyForN = (n) => {
let s = shell(n);
let sm = s-1;
let sSeq=n-(Math.pow(sm,2));
let pSeq=Math.ceil(sSeq/2);
return {
x: (sSeq%2 ? pSeq : s)-1,
y: (sSeq%2 ? s : pSeq)-1
};
};
let startx = x;
let starty = y;
let count=0;
return (obj)=>{
let coord = xyForN(++count);
obj.set({
top: starty+(coord.y*70),
left: startx+(coord.x*70)
});
};
};
const normalizer = (n) => {
return (Math.max(0,Math.floor((n-35)/70))*70)+35;
};
on('chat:message',function(msg){
if('api'===msg.type && /^!marshal-tokens(\b\s|$)/i.test(msg.content) && playerIsGM(msg.playerid)){
let tokens = [...new Set([
...msg.content.split(/\s+/).slice(1),
...((msg.selected && msg.selected.map(s=>s._id)) || [])
])]
.map(id=>getObj('graphic',id))
.filter(g=>undefined !== g)
;
let firstToken = (tokens[0]||{get:()=>0});
let x=normalizer(firstToken.get('left'));
let y=normalizer(firstToken.get('top'));
let poser = positioner(x,y);
tokens.forEach(poser);
}
});
});
You call it with: !marshal-tokens For your changes, add this after the filter call (might need to swap a and b to get desc order but I think that's right): .sort((a, b) => b.get('currentSide') - a.get('currentSide'))
Then replace the positioner with one that just puts them in a line: const asALine = (x,y) => {
let offset = x;
return (obj) => {
obj.set({
top: y,
left: offset
});
offset += obj.get('width');
};
};
and you get something like (which I didn't test yet): on('ready',()=>{
const asALine = (x,y) => {
let offset = x;
return (obj) => {
obj.set({
top: y,
left: offset
});
offset += obj.get('width');
};
};
const normalizer = (n) => {
return (Math.max(0,Math.floor((n-35)/70))*70)+35;
};
on('chat:message',function(msg){
if('api'===msg.type && /^!marshal-in-line(\b\s|$)/i.test(msg.content) && playerIsGM(msg.playerid)){
let tokens = [...new Set([
...msg.content.split(/\s+/).slice(1),
...((msg.selected && msg.selected.map(s=>s._id)) || [])
])]
.map(id=>getObj('graphic',id))
.filter(g=>undefined !== g)
.sort((a, b) => b.get('currentSide') - a.get('currentSide'))
;
let firstToken = (tokens[0]||{get:()=>0});
let x=normalizer(firstToken.get('left'));
let y=normalizer(firstToken.get('top'));
let poser = asALine(x,y);
tokens.forEach(poser);
}
});
});
call with: !marshal-in-line