Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[HELP] Advance turn order via API?

1422933831

Edited 1422935745
DXWarlock
Sheet Author
API Scripter
Is there a way to advance the turn order via API? My group has decided to forgo seeing the turn order since I use a complex script that isn't round robin style combat they have realized they are using metagaming from it. Like " Ok what do I want to do, I go, then bob, then bob again, then an NPC ...so bob can shoot it twice and me once before it goes again " to make plans. But I cant seem to find a way to make it advance with a !command. And I cant open the turn order just for me. if I have it open, the players see it. sure they can shrink it down to nothing, but to make sure all play fair would like to just close it totally. Anyone have any ideas how to do this without a built in API call that I can do it with? I tried a form of array.push() and array.shift(), which seems to move top item to the bottom how I wish, but it doesnt seem to trigger on("change:campaign:turnorder") which I also need. Or a simple checkbox of "show to players" in its options would be nice (wink wink) :P
1422945208
The Aaron
Pro
API Scripter
There isn't a way to trigger the on("change:campaign:turnorder") event from a script. I do modify the turn order in my TurnMarker script, but that doesn't trigger the event. I'm not sure what you want to happen on that event, but here are two ideas for you: You could maintain your own turn order list in the state, use a single custom entry in the turn order as a place holder, named something like "Combat" and give it an increment of +1. Then you just advance the turn order as normal and it counts up. That would cause the event to trigger, and you could catch the event yourself in your script and advance things in your turn order list of state. (You could probably even take the modulus of it's PR to get the offset into your array of combatants, if you were so inclined and started it's count at 0). Another option would be to create tokens on the GM layer for each thing in the combat, and just use those for your turn order. You would see them, but the players would have an empty list since the hidden tokens wouldn't show up in their turn order box. You could automate the process of creating them or updating them whenever a token is added to the turn order, replacing the visible token with it's invisible counterpart.
1422988622
DXWarlock
Sheet Author
API Scripter
Those are great ideas Aaron, I figured youd have some input that was useful :) I need the turn order change trigger for moving the turn marker to whatever markers turn it is. and for announcing in chat whos turn it is. The state idea would probably be the best, as GM layer one I cant use either :\ Anything on the GM layer the turn marker doesn't highlight, and says "unknown's turn" in chat. So everyone, including PC's would be "unknowns" :) Ill try the state idea. I can probably do the normal turn order, set it, store the entire array from JSON.parse(Campaign().get("turnorder")); into the state, and clear the actual turn order..then do all my reading of whose turn it is, and such from the state. Just got to figure out how to update the state when a layer changes..say a token from GM to object when they see it..so it now says who it is, instead of unknown, and such.
1422997258
The Aaron
Pro
API Scripter
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).
1423010191
DXWarlock
Sheet Author
API Scripter
Oh nice, lot more versatile than the way I was going to do it, just store the turn array and push new guy to end every attack. Going to go play with it now to try to mash it together when the stuff I need to do with it. Thank again Aaron!
1423012741
The Aaron
Pro
API Scripter
Yup! No problem!!