Ok. As GM, you can do that with Group Initiative by configuring it to sort Ascending:
!group-init-config --sort-option|Ascending
Then for handling a player's turn, you can use:
!group-init --adjust-current ?{Add how much}
!group-init --sort
That will only work for the GM though, so if you want players to be able to adjust their own turns, you'll need a custom script...
...like this!
Just set up a macro with:
!forward-init ?{Adjustment}
For players, it will let them adjust the turn for the first token if they can control it. For the GM, you can adjust anyone's turn, or even custom turn entries. It also supports inline rolls, if that's something you need:
!forward-init [[@{selected|base}+1d3]]
Here's the code:
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 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;
}
};
/* eslint-disable no-unused-vars */
const getTurnArray = () => ( '' === Campaign().get('turnorder') ? [] : JSON.parse(Campaign().get('turnorder')));
const setTurnArray = (ta) => Campaign().set({turnorder: JSON.stringify(ta)});
const addTokenTurn = (id, pr) => Campaign().set({ turnorder: JSON.stringify( [...getTurnArray(), {id,pr}]) });
const addCustomTurn = (custom, pr) => Campaign().set({ turnorder: JSON.stringify( [...getTurnArray(), {id:-1,custom,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))});
/* eslint-enable no-unused-vars */
on('chat:message',msg=>{
if('api'===msg.type && /^!forward-init(\b\s|$)/i.test(msg.content)){
//let who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname');
let args = processInlinerolls(msg).split(/\s+/);
let to = getTurnArray();
let token = getObj('graphic',(to[0]||{}).id);
if( playerIsGM(msg.playerid) || (token && playerCanControl(token,msg.playerid)) ){
let adjust = parseFloat(args[1])||0;
to[0].pr = parseFloat(to[0].pr)+(adjust);
setTurnArray(to.sort(sorter_asc));
}
}
});
});