Give this a try. Note that it will only work on non-marketplace images: on('ready',()=>{
const playerCanControl = (obj, playerid='any') => {
const playerInControlledByList = (list, playerid) => list.includes('all') || list.includes(playerid) || ('any'===playerid && list.length);
let players = obj.get('controlledby')
.split(/,/)
.filter(s=>s.length);
if(playerInControlledByList(players,playerid)){
return true;
}
if('' !== obj.get('represents') ) {
players = (getObj('character',obj.get('represents')) || {get: function(){return '';} } )
.get('controlledby').split(/,/)
.filter(s=>s.length);
return playerInControlledByList(players,playerid);
}
return false;
};
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 isString = (s)=>'string'===typeof s || s instanceof String;
let tokenIds = [];
const saveTokenId = (obj) => {
tokenIds.push(obj.id);
};
const setTokenRandomSide = (obj,prev,force=false) => {
if(tokenIds.includes(obj.id) || force){
tokenIds=tokenIds.filter(id => id !== obj.id);
if( 'graphic' === obj.get('type') && 'token' === obj.get('subtype') && ! playerCanControl(obj)){
let sideText = obj.get('sides');
if( sideText.length ){
let sides = sideText.split(/\|/).map(decodeURIComponent).map(getCleanImgsrc).filter(isString);
if(sides.length){
obj.set({
imgsrc: sides[randomInteger(sides.length)-1]
});
}
}
}
}
};
on('add:graphic', saveTokenId);
on('change:graphic', setTokenRandomSide);
});
Edit: Fixed crash when Marketplace Images are present.