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

Is there a way to make popup or graphic that can cycle through a list at the end of a round of combat using the API or even a macro?

As the title says really, I am wondering if there is a way to create a popup using either the API or macro that displays a single option from a list which cycles at the end of a combat round? essentially the group I am DMing for is using a NPC/Sidekick to make up the groups numbers, but they have decided to each take control of the NPC for a single round of combat, and to continue the pattern on through multiple encounters and was thinking this would be a convenient way to keep track of who is currently in control and stop any arguments that may ensue due to people forgetting who was controlling them. I ask because my knowledge of code is, at best, rudimentary and at worst, none existent, and was hoping that some of the code wizards that make up this community would be able to help. Many thanks, Aaron.
1608082189

Edited 1608237696
The Aaron
Roll20 Production Team
API Scripter
The API can likely approximate what you're asking.  Certainly it can: Change the controlled by property of a Token. Take actions based on the Turn Order Changing. Display things in the chat. If I were writing this, I'd have a "Rotate Players" entry in the Turn Order... Ok, never mind, I'd do this: For the characters that are to be shared, set their In Player Journals field to the people that should be cycled for control.  Set the Controlledby to just the player that should be initially controlling them. On the token for the character, add [SHARED] in the GM Notes and set it back as the default token. This script will add an entry named "Rotate Players" to the end of the turn (put it wherever you like except first).  When its turn comes up, it will cycle the players in the Controlledby field to the next one in the In Player Journals box, announce to chat, and then skip to the next turn. Script: on('ready',()=>{ const CustomTurnName = 'Rotate Players'; const CustomTurnPR = -1; const parseTurnToArray = (orderStr) => ( '' === orderStr ? [] : JSON.parse(orderStr)); const getTurnArray = () => ( '' === Campaign().get('turnorder') ? [] : JSON.parse(Campaign().get('turnorder'))); const setTurnArray = (ta) => Campaign().set({turnorder: JSON.stringify(ta)}); const addCustomTurn = (custom, pr) => Campaign().set({ turnorder: JSON.stringify( [...getTurnArray(), {id:"-1",custom,pr}]) }); const assureTurnOrder = () => { if(Campaign().get('initiativepage')){ // get tyo let to = getTurnArray(); let idx = to.findIndex(o=>CustomTurnName === o.custom); if(idx === -1){ addCustomTurn(CustomTurnName, CustomTurnPR); } } }; const cyclePlayer = (c) => { let ids = c.get('inplayerjournals').split(/\s*,\s*/); let cid = c.get('controlledby').split(/\s*,\s*/)[0]; let idx = ids.findIndex(o=>cid===o)+1; cid = ids[(ids.length === idx) ? 0 : idx]; c.set({controlledby: cid}); let p = getObj('player',cid); return `<b>${c.get('name')}</b> is now controlled by <b>${p.get('displayname')}</b>.`; }; const handleTurnOrderChange = (obj) => { let to = parseTurnToArray(obj.get('turnorder')); let idx = to.findIndex(o=>CustomTurnName === o.custom); if(0===idx){ // get token ids let messages = to.map(o=>getObj('graphic',o.id)) .filter(g=>undefined !== g) .filter(t=>/\[shared\]/i.test(unescape(t.get('gmnotes')))) .map(t=>getObj('character',t.get('represents'))) .filter(c=>undefined !== c) .map(cyclePlayer); if(messages.length){ sendChat('',`<div><ul>${messages.map(m=>`<li>${m}</li>`).join('')}</ul></div>`); } let e = to.shift(); to.push(e); setTurnArray(to); } }; on('chat:message',(msg)=>{ if('api' === msg.type && /^!eot(\b\s|$)/i.test(msg.content)){ setTimeout(()=>handleTurnOrderChange(Campaign()),0); } }); on('change:campaign:initiativepage',assureTurnOrder); on('change:campaign:turnorder',handleTurnOrderChange); assureTurnOrder(); }); Let me know if you have any issues.
Wow...that's amazing! Thank you very much! I was honestly expecting a "yeah you can do this with the API, look at this tutorial / use a certain script in this way" not a fully written script, I am both amazed and truly thankful :-). Aaron. 
1608143646
The Aaron
Roll20 Production Team
API Scripter
Hahahaha. =D  No problem.   It was easier to just write it than explain how I would write it.  Also, I enjoy writing little one-off scripts to solve interesting problems, and this was definitely interesting.
Well my players certainly keep me on my toes, it is nice to know they keep others on theirs with their weird ideas as well :-)
1608153378
The Aaron
Roll20 Production Team
API Scripter
Yeah, now I'm looking for an opportunity to use this. =D
Give your players a sidekick / NPC that joins them for a series of short quests maybe. I don't know how other systems work, but the rules for Sidekicks in Tasha's for 5e are really good, hence what led to needing this!
1608234408

Edited 1608234517
So I believe I am experiencing the a clash with another script of yours I am using, Token Marker. both scripts are setting a custom turn order and both of them are at -1 during the turn, but the script doesn't automatically move the turn on and it doesn't seem to change control of the token. sorry for the bother Aaron.
OK ignore that, I just have to use the button on the initiative tracker and it all works fine :) I can add a "place holder character with a low Dex scor to make sure they are always last so it all works together.
1608236543
The Aaron
Roll20 Production Team
API Scripter
Hmm.  I've confirmed that behavior, let me see about a fix for that...
1608237798
The Aaron
Roll20 Production Team
API Scripter
Ok. sorted it out.  I made a minor correction to the code above to make it work with !eot. Other than that, just make sure the Rotate Player turn is before the Round one, and it should work fine.
thanks! I am planning on having the rotate players directly below the last character who is being controlled so it changes after the players have taken the sidekicks turn so that should be fine :)