Ok, here's a first pass version of it. It uses the Grid Scale Distance setting on the page to rescale everything. On some maps, that's not set correctly (for example, Duergar Outpost is set to 5), so you might needs to fix that before it will run. Just make sure if the map says "1 square = 10 ft" that Grid Scale Distance says 10 in the page settings. You then just run: !nps There is also a command to do all the maps in one go, but I don't know that I'd trust it enough for that yet. =D I suggest making use of the new Duplicate Page functionality so you can test it out without screwing up your originals. Here's the code: on('ready',() => {
const s = {
gmNote: `margin-left: -40px; border: 1px solid #ccc; border-radius: .5em; padding: .1em .5em; background-color: #eee; font-size: 10px; font-weight: bold;`
};
const scgm=(msg)=>{
sendChat('NPS',`/w gm <div style="${s.gmNote}"> ${msg} </div> `);
};
const scaleGraphic = (scale) => (graphic) => {
graphic.set({
width: graphic.get('width')*scale,
height: graphic.get('height')*scale,
left: graphic.get('left')*scale,
top: graphic.get('top')*scale
});
};
const repositionGraphic = (scale) => (graphic) => {
graphic.set({
width: graphic.get('width')*scale,
height: graphic.get('height')*scale,
left: graphic.get('left')*scale,
top: graphic.get('top')*scale
});
};
const scaleText = (scale) => {
return (text) => {
text.set({
left: text.get('left')*scale,
top: text.get('top')*scale,
font_size: text.get('font_size')*scale
});
};
};
const simpleObject = (o) => JSON.parse(JSON.stringify(o));
const scalePathString = (pathstring,scale) => {
return JSON.stringify(_.map(JSON.parse(pathstring),(n)=> _.map(n,(i)=> _.isNumber(i) ? scale*i : i )));
};
const scaleDrawing = (scale) => {
return (drawing) => {
let newpath=_.omit(simpleObject(drawing),['_id','_type']);
if(_.contains(['','[]'],newpath._path)){
return;
}
newpath.path=scalePathString(newpath._path,scale);
delete newpath._path;
newpath.top*=scale;
newpath.left*=scale;
newpath.width*=scale;
newpath.height*=scale;
/*let newPathObj =*/ createObj('path',newpath);
drawing.remove();
};
};
const adjustPages = (pages) => {
let page=pages.shift(),
scale=page.get('scale_number')/5;
let mapGraphics = findObjs({
pageid: page.id,
type: 'graphic',
subtype: 'token',
represents: ''
});
let mgids = mapGraphics.map(g=>g.id);
let otherGraphics = findObjs({
pageid: page.id,
type: 'graphic'
})
.filter(o=> !mgids.includes(o.id) && o.get('subtype')!=='card' );
let allText = filterObjs((o)=>{
return o.get('pageid')===page.id &&
o.get('type')==='text';
});
let allDrawings = filterObjs((o)=>{
return o.get('pageid')===page.id &&
o.get('type')==='path';
});
otherGraphics=_.without(otherGraphics,mapGraphics);
scgm(`Adjusting page: <u>${page.get('name')}</u>`);
// scale page
scgm(`-- Scale from ${page.get('scale_number')}ft to 5ft (x${scale} size)`);
page.set({
width: page.get('width')*scale,
height: page.get('height')*scale,
scale_number: 5
});
// scale all graphics on the map layer
scgm(`-- Scaling map images: ${mapGraphics.length}`);
_.each(mapGraphics,scaleGraphic(scale));
// reposition all graphics on the other layers
scgm(`-- Repositioning other layer images: ${otherGraphics.length}`);
_.each(otherGraphics,repositionGraphic(scale));
// reposition and scale all text on all layers
scgm(`-- Scaling and Repositioning text: ${allText.length}`);
_.each(allText,scaleText(scale));
// redraw all drawings
scgm(`-- Redrawing paths to scale: ${allDrawings.length}`);
_.each(allDrawings,scaleDrawing(scale));
if(pages.length){
_.delay(adjustPages,100,pages);
}
};
on('chat:message',(msg) => {
let cmds,pages,player;
if('api' === msg.type && msg.content.match(/^!nps(?:-all)?\b/) && playerIsGM(msg.playerid)){
cmds=msg.content.split(/\s+/);
player=getObj('player',msg.playerid);
switch(cmds.shift()){
case '!nps-all':
pages=filterObjs((o)=>{
return o.get('type')==='page' &&
o.get('scale_units')==='ft' &&
o.get('scale_number')>5 ;
});
/* falls through */
case '!nps':
pages = pages || filterObjs((o)=>{
return o.get('type')==='page' &&
o.get('scale_units')==='ft' &&
o.get('scale_number')>5 &&
o.id === player.get('lastpage');
});
if(pages.length){
scgm( `Operating on pages: <ul><li>${_.map(pages,(p)=>p.get('name')).join('</li> <li>')}</li></ul>`);
_.delay(adjustPages,50,pages);
} else {
scgm( `No work to do on the specified pages.`);
}
break;
}
}
});
});