Give this a try: Command is: !ff4init You can pass it inline rolls (or numbers) and it will add add turns for those rolls: !ff4init [[1d10]] [[1d10]] [[1d10]] Will add 3 turns for each selected token with the 3 values rolled. (probably makes sense to only select on token) You can pass 4 flags also: --clear :: This will clear out all the turns for the selected tokens before adding any rolls. So to reroll for a token, you can use: !ff4init --clear [[1d10]] [[1d10]] [[1d10]] --clear-all :: Only the GM can use this command, it will clear the initiative completely. Usually you'd want to use it alone: !ff4init --clear-all --sort-asc :: this will sort the turnorder in ascending order after adding the rolls. Only the GM can use this command: !ff4init --clear --sort-asc [[1d10]] [[1d10]] [[1d10]] --sort-desc :: this will sort the turnorder in descending order after adding the rolls. Only the GM can use this command: !ff4init --clear --sort-desc [[1d10]] [[1d10]] [[1d10]] The order of those flags doesn't matter: !ff4init [[1d10]] --sort-asc [[1d10]] [[1d10]] --clear Any arguments that are not from among the 4 supported flags will be converted to numbers (or 0) and used for the turn order. Let me know if you need any changes. =D Code: on('ready',()=>{
const playerCanControl = (obj, playerid='any') => {
const playerInControlledByList = (list, playerid) => playerIsGM(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 getTurnArray = () => ( '' === Campaign().get('turnorder') ? [] : JSON.parse(Campaign().get('turnorder')));
const addTokenTurn = (id, pr) => Campaign().set({ turnorder: JSON.stringify( [...getTurnArray(), {id,pr}]) });
const removeTokenTurn = (tid) => Campaign().set({ turnorder: JSON.stringify( getTurnArray().filter( (to) => to.id !== tid)) });
const clearTurnOrder = () => Campaign().set({turnorder:'[]'});
const sorter_asc = (a, b) => a.pr - b.pr;
const sorter_desc = (a, b) => b.pr - a.pr;
const sortTurnOrder = (sortBy = sorter_desc) => Campaign().set({turnorder: JSON.stringify(getTurnArray().sort(sortBy))});
const processInlinerolls = (msg) => {
if(_.has(msg,'inlinerolls')){
return _.chain(msg.inlinerolls)
.reduce(function(m,v,k){
let ti=_.reduce(v.results.rolls,function(m2,v2){
if(_.has(v2,'table')){
m2.push(_.reduce(v2.results,function(m3,v3){
m3.push(v3.tableItem.name);
return m3;
},[]).join(', '));
}
return m2;
},[]).join(', ');
m['$[['+k+']]']= (ti.length && ti) || v.results.total || 0;
return m;
},{})
.reduce(function(m,v,k){
return m.replace(k,v);
},msg.content)
.value();
} else {
return msg.content;
}
};
on('chat:message', (msg)=>{
if('api'===msg.type && /^!ff4init\b/i.test(msg.content)){
let cmds = processInlinerolls(msg).split(/\s+/).splice(1);
let flags = cmds.filter((o)=>/^--/.test(o)).map((s)=>s.toLowerCase());
let turns = cmds.filter((o)=>!/^--/.test(o)).map((s)=>parseFloat(s)||0.00);
let tokens = msg.selected
.map(o=>getObj('graphic',o._id))
.filter(g=>undefined !== g)
;
flags.forEach(f=>{
switch(f){
case '--clear':
tokens.forEach(t => {
if(playerCanControl(t,msg.playerid)){
removeTokenTurn(t.id);
}
});
break;
case '--clear-all':
if(playerIsGM(msg.playerid)){
clearTurnOrder();
}
break;
}
});
tokens.forEach( t => turns.forEach( pr => addTokenTurn(t.id,pr)));
flags.forEach(f=>{
switch(f){
case '--sort-desc':
if(playerIsGM(msg.playerid)){
sortTurnOrder(sorter_desc);
}
break;
case '--sort-asc':
if(playerIsGM(msg.playerid)){
sortTurnOrder(sorter_asc);
}
break;
}
});
}
});
});