StéphaneD said: Thanks for the kind words, especially coming from The (Legendary) Aaron ;) I thought the array of token properties that I am passing to the conversion function on line 121 were both covering LDL and UDL. Did I miss something ? Let the suggestions flow, they will be much appreciated. Have a terrific day ! Oh! You're absolutely right, that does cover UDL as well. I was thinking about the number of settings I had to deal with for TokenMod, but you don't need to worry about those to convert just the units. Nice. So, when doing operations on a lot of objects, you can end up hitting the "Possible infinite loop detected." error. That's caused when the script doesn't return for some amount of time (1-2 minutes). With pages that have a bunch of graphics, it can take a long time to parse them all. That might not be an issue for this script, but it could cause the API to become unresponsive if it's running while other things are also running. To avoid that, you can borrow some concepts from cooperative multitasking, namely voluntarily yielding execution so that other things can run. The easiest way to do that is through something I call "burndown queues". I'm sure it has a real name, but basically, you collect the things you want to work on, then you process one at a time and defer execute between them. It looks like this: const convertTokenToMetric = (token) => {
// filter tokens with a linked character
const charId = token.get('represents');
if (charId !== '') {
// get the linked character object
const character = findObjs({
_type: 'character',
_id: charId
});
if (character.length === 1) {
// convert the measures to metric
const converted = convert(token, [
'light_radius',
'light_dimradius',
'night_vision_distance',
'bright_light_distance',
'low_light_distance'
]);
token.set(converted);
sendChat('API', `/w gm ${character[0].get('name')} ...converted`);
}
}
};
/**
* Convert scale property values from feet to meters for all token on a page
* @param {string} pageId Page object identifier
*/
function convertToMetric(pageId) {
// get all tokens on the page
const tokens = findObjs({
_type: 'graphic',
_subtype: 'token',
_pageid: pageId
});
const burndown = ()=>{
if(tokens.length>0){
convertTokenToMetric(tokens.shift());
setTimeout(burndown,0);
}
};
burndown();
}
(I didn't test this code.) Basically, you have a list of things to operate on (tokens) and a function that will process the next one in the list and queue a call to itself (the burndown function).