Here's a little script I wrote that builds a Rollable Table Token out of images you select on the tabletop. It contains all the basic concepts needed to do the above. on('ready',()=>{
const s = {
err: "padding: 1px 1em; size:.8em; font-weight:bold; background: #cccccc; border:2px solid black; border-radius:1em; color: #990000;"
};
const getCleanImgsrc = (imgsrc) => {
let parts = imgsrc.match(/(.*\/images\/.*)(thumb|med|original|max)([^?]*)(\?[^?]+)?$/);
if(parts) {
return parts[1]+'thumb'+parts[3]+(parts[4]?parts[4]:`?${Math.round(Math.random()*9999999)}`);
}
return;
};
const positionalSorter = (a,b) => {
let at = Math.round((a.get('top')+17)/35);
let bt = Math.round((b.get('top')+17)/35);
let al = Math.round((a.get('left')+17)/35);
let bl = Math.round((b.get('left')+17)/35);
let abt = at-bt;
let abl = al-bl;
return (0 === abt ? abl : abt);
};
const findTraits = (b) => (o) => {
let x = parseFloat(o.get('left'));
let y = parseFloat(o.get('top'));
let w = parseFloat(o.get('width'));
let h = parseFloat(o.get('height'));
b.minX = Math.min(b.minX,x-(w/2));
b.minY = Math.min(b.minY,y-(h/2));
b.maxX = Math.max(b.minX,x+(w/2));
b.maxY = Math.max(b.minY,y+(h/2));
b.layer = o.get('layer');
b.pageid = o.get('pageid');
return o;
};
on('chat:message',msg=>{
if('api'===msg.type && /^!make-rtt(\b\s|$)/i.test(msg.content) && playerIsGM(msg.playerid)){
let who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname');
let traits = {
minX: Number.MAX_SAFE_INTEGER,
minY: Number.MAX_SAFE_INTEGER,
maxX: -Number.MAX_SAFE_INTEGER,
maxY: -Number.MAX_SAFE_INTEGER,
layer: 'objects',
pageid: ''
};
if(0===(msg.selected||[].length)){
sendChat('',`/w "${who}" <div style="${s.err}">Please selected some tokens.</div>`);
return;
}
let tableName = msg.content.split(/\s+--/).slice(1)[0];
let images = (msg.selected || [])
.map(o=>getObj('graphic',o._id))
.filter(g=>undefined !== g)
.sort(positionalSorter)
.map(findTraits(traits))
.reduce((m,g)=>{
let i = getCleanImgsrc(g.get('imgsrc'));
if(i){
m.push(i);
} else {
g.set('status_dead',true);
}
return m;
},[])
;
if(images.length){
let token = createObj('graphic',{
pageid: traits.pageid,
layer: traits.layer,
left: traits.minX||0,
top: traits.minY||0,
width: 70,
height: 70,
imgsrc: images[0],
sides: images.map(encodeURIComponent).join('|')
});
if(token){
toFront(token);
} else {
sendChat('',`/w "${who}" <div style="${s.err}">Failed to create token!</div>`);
}
if (tableName) {
let table = createObj('rollabletable',{
name: tableName,
showplayers: false
});
if (table) {
let tableID = table.get('_id');
images.forEach(img => {
let tableItem = createObj('tableitem',{
rollabletableid: tableID,
avatar: img,
name: '',
weight: 1
});
});
} else {
sendChat('',`/w "${who}" <div style="${s.err}">Failed to create rollable table!</div>`);
}
}
} else {
sendChat('',`/w "${who}" <div style="${s.err}">Only marketplace images found!</div>`);
}
}
});
});