Ok, it actually supports selected tokens already. That wasn't the problem. The problem was that GroupInitiative is asynchronous, so it was only getting finished adding 1 token to the turn order before DupTurns was running. What really needs to happen is that DupTurns waits until GroupInitiative is finished and then runs. As it turns out, the easiest way to make that work is just to have it observe GroupInitiative and run automatically to dup turns for each token that was rolled, which is what I did:
/* global GroupInitiative */
on('ready', () => {
const handleGroupInit = true;
const defaultCount = 2;
const defaultAttrName = 'apm';
const multiplyTurn = (token_id,count) => {
let to = JSON.parse(Campaign().get('turnorder')||'[]');
let turn = {pr:-10000};
to = to.filter((o) => {
if(o.id !== token_id){
return true;
}
if( o.id === token_id ) {
if(o.pr>turn.pr) {
turn = o;
}
}
return false;
});
if(turn.id){
[...Array(parseInt(count)).keys()].forEach((n)=>{
to.push(Object.assign({},turn,{pr:(parseInt(turn.pr)-(20*n))}));
});
}
Campaign().set({
turnorder: JSON.stringify(to.sort((a,b)=>parseFloat(b.pr)-parseFloat(a.pr)))
});
};
on('chat:message', (msg) => {
if( 'api'===msg.type && /^!dup-turn/.test(msg.content) ){
let args = msg.content.split(/\s+/);
let count = args[1]||defaultCount;
let attrname = args[2]||defaultAttrName;
if(msg.selected){
msg.selected.forEach((m)=>{
let n = count;
let token = getObj('graphic',m._id);
if(token){
n = parseInt(getAttrByName(token.get('represents'),attrname));
}
multiplyTurn(m._id,n||count);
});
}
}
});
const maxPRLookup = (to) => {
let lookup = {};
to.forEach(o=>{
let npr = parseFloat(o.pr);
if(!lookup[o.id] || lookup[o.id]<npr){
lookup[o.id]=npr;
}
});
return lookup;
};
const handleGroupInitChange = (obj,prev) => {
let lookup = maxPRLookup(JSON.parse(prev||'[]'));
let curlist = maxPRLookup(JSON.parse(obj||'[]'));
let updateList = Object.keys(curlist).filter(id=>curlist[id]!==lookup[id]);
updateList.forEach(id=>{
let n;
let token = getObj('graphic',id);
if(token){
n = parseInt(getAttrByName(token.get('represents'),defaultAttrName));
}
multiplyTurn(id,n||defaultCount);
});
};
if(handleGroupInit && 'undefined' !== typeof GroupInitiative && GroupInitiative.ObserveTurnOrderChange){
GroupInitiative.ObserveTurnOrderChange(handleGroupInitChange);
}
});
You can change the variables at the top to set what to do if it doesn't have the attribute, and what the attribute's name is. Let me know if that works for you. I could also have it queue up a change to make, then run that change after GroupInitiative next finishes, but this seems like it should work better.
Again, sorry for the delay getting back to you!