You will probably want a more expressive layout for your turn order listing. I'd probably go with something like: {
round: 0,
roundFirst: null,
participants: {},
order: []
} where .round is the round number, .order is an array of token_ids in the order of who's turn it is, .participants is an object indexed by token_id where you can store data about each token, .roundFirst holds the token_id of whomever is first. Each participant might look like: {
id: <token_id>,
pr: <their initiative>,
name: <their name>,
layer: <their layer>
} So, with only one participant with id -Z13241ad1234, it might look like this: {
round: 0,
roundFirst: "-Z12341ad1234",
participants: {
"-Z13241ad1234": {
id: "-Z12341ad1234",
pr: "23.5",
name: "Sir Bob the Fractional",
layer: "objects"
}
},
order: ["-Z12341ad1234"]
} Keeping participants separate makes it easier to look them up by id (otherwise, you'd be walking an array, looking at properties for the object till you found the right one, etc). It also makes it easy to keep track of some data about people but not have the in the turn order (possible advanced features?). It gives you a nice concise place to store other info as well, like states and timeouts, etc. Having a separate order array makes it pretty easy to cycle. It's convenient to keep the id with the data, even though you're indexing by it. That allows you to pass that data out to other functions easily Then adjusting based layer changes is as simple as on('change:graphic:layer',function(obj,prev){
if(state.DXTurnOrder.participants[obj.id]){
state.DXTurnOrder.participants[obj.id].layer=obj.get('layer');
}
}); assuming you do all the right things to setup your state ahead of time. On a turn, you just look look at the top of your order list and do what's right: on('change:campaign:turnorder',function(){
// get the current turn taker
var cid = state.DXTurnOrder.order.shift();
// add them to the end for later
state.DXTurnOrder.order.push(cid);
// check for new round
if(cid === state.DXTurnOrder.roundFirst){
state.DXTurnOrder.round++;
// Announce new round
}
// announce turn
if('objects !== state.DXTurnOrder.participants[cid].layer) {
// hidden person's turn
} else {
// state.DXTurnOrder.participants[cid].name 's turn!
}
}); Sorting descending: var sortOrderDesc = function(){
// _.chain() lets you do a series of transformations on a collection
state.DXTurnOrder.order=_.chain(state.DXTurnOrder.participant)
// function is called on each entry, p is a participant
.map(function(p){
// makes a new object with the id an a numeric version of their priority
return {
id: p.id,
n: parseFloat(p.pr, 10) || 0
};
})
.sortBy('n') // sorts it by the n property
.pluck('id') // gets just the id property
.value() // returns the list of ids in ascending order from _.chain()
.reverse(); // reverses the array and returns it to be set in the .order property
}; Boom baby! Expand as needed. You'd probably want to take the turn logic out from the announce new round down and put it in a separate function so you can call it from the end of your sorting routine to get combat started (and avoid starting with the second person, or putting the first person last for the first turn so you can advance to them, or whatever).