Original Script: <a href="https://app.roll20.net/forum/post/2778056/slug%7D" rel="nofollow">https://app.roll20.net/forum/post/2778056/slug%7D</a> I revised this script to support an arbitrary number of faces, arbitrary rotation, and to handle non-thumb and non-user library images gracefully. Also case-insensitive for attributes and values when configuring it. The user I revised this for is using it to have portrait tokens that can be rotated for light direction. They've got 8 images setup with each successive image rotated counter-clockwise 45 degrees, the net effect being that the token when rotated clockwise, is always right side up. Hopefully they'll post some pictures. =D Here's the revised script: on('ready',()=>{
const getCleanImgsrc = function (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;
};
on('change:token:rotation', (obj) => {
//Unless there is an attribute "Rotateable?" with the current value is
//set to on of 'yes','y','1',1,'on' (case insensitive), it will not
//attempt to change token image.
if(obj.get("represents") == "") {
return;
} else {
let rotable = (findObjs({
_type: "attribute",
_characterid: obj.get("represents"),
name: "Rotateable?"
},{caseInsensitive: true})[0]||{get:()=>''}).get("current");
if (!['yes','y','1','on'].includes(`${rotable}`.trim().toLowerCase())){
return;
}
}
let rot = parseInt(obj.get("rotation"),10)||0;
let sides = obj.get('sides');
if(sides.length){
let faces = sides.split(/\|/).map(decodeURIComponent).map(getCleanImgsrc);
let slice = 360/faces.length;
let bias = (slice/2);
let side = Math.floor(((((rot+bias)%360)+360)%360)/slice);
if(faces[side]){
obj.set({imgsrc: faces[side]});
}
}
});
});