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

[SCRIPT REQUEST] Legendary monster in turn tracker?

Good morning all of you helpful script writers! I have difficulty remembering to use 5E legendary actions (LA) sometimes, as I’m sure is common.  Lots to track and remember for a DM during battle. :-) What I would like is a whisper to myself to think about using a LA at the end of each players turn, but only if there is a creature with LAs in the turn tracker. I already have the OnMyTurn script that triggers an arbitrary macro at the start of a creature’s turn; I could use that to trigger a script. What I’m missing is a way to check if there is a creature with legendary actions in the turn tracker, and then somehow trigger a small, one-line GM whisper if there is. Anyone feel like taking on that challenge? :-)
1608376201

Edited 1608376219
Joe
Pro
It did just occur to me that I could put tokens called “Legendary Action?” on the DM layer and add them to the turn order after every PC, but that would require me to remember this trick the next time a LA boss battle arrives, and takes setup time during the session (after PCs roll init) for every LA battle, whereas this script would be set and forget forever. :-)
If you know the map where they will encounter the creature with Legendary Actions, you could put a big text object that says "Don't forget Legendary Actions!" on the GM Layer in the middle of your map. Then only you would see it, and you could not miss it.
1608419263
The Aaron
Roll20 Production Team
API Scripter
Technically, it's " only at the end of another creature's turn " which means it could be another monster's turn. Here's a script that handles what you asked for.  By default, it will only notify at the end of a player controllable token's turn.  if you change OnlyNotifyOnPlayerTurnEnds to false, it will notify after any token's turn (not custom turns though, and not after a legendary creature's turn, unless there is more than one). This script will find any legendary creatures in the turn order, and will only be active it there are any.  If you add one, it will become active, if you remove the last one, it will become inactive.  It also supports !eot for turn order changes, so if you're using a script for that, it should still work. Cheers! Code: const LegendaryActionReminder = (()=>{ // eslint-disable-line no-unused-vars // config const OnlyNotifyOnPlayerTurnEnds = true; //////////////////////////////////////// const notifyStyle="background-color:black;color:yellow;font-weight:bold;line-height:1em;padding:.3em;text-align:center;border:3px dashed yellow;border-radius:1em;font-size:.8em;"; let NumLegendaryCreaturesInTurnOrder = false; const getTurnArrayFromString = (str) => ( '' === str ? [] : JSON.parse(str)); 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 NotifyGMOfLegendaryAction = () => sendChat('Legendary Actions', `/w gm <div style="${notifyStyle}">Don't forget your Legendary Actions</div>`); const isLegendaryCreature = (() => { const cache = {["-1"]: false}; return (token_id) => { if(!cache.hasOwnProperty(token_id)){ let t = getObj('graphic',token_id); let a = findObjs({ type: 'attribute', name: 'npc_legendary_actions', characterid: (t||{get:()=>{}}).get('represents') })[0]; cache[token_id] = (a && (parseInt(a.get('current'))||0) > 0); } return cache[token_id]; }; })(); const FindLegendaryCreaturesInTurnOrder = (to) => { NumLegendaryCreaturesInTurnOrder = to.reduce((m,e) => m + (isLegendaryCreature(e.id) ? 1 : 0), 0); }; const handleTurnOrderChange = (obj,prev) => { let to = getTurnArrayFromString(obj.get('turnorder')); let po = getTurnArrayFromString(prev.turnorder); if(to.length !== po.length){ FindLegendaryCreaturesInTurnOrder(to); } if(NumLegendaryCreaturesInTurnOrder>0) { const toID = (to[0]||{id:'to'}).id; const poID = (po[0]||{id:'po'}).id; // turn changed if(toID !== poID){ if(OnlyNotifyOnPlayerTurnEnds){ let t = getObj('graphic',poID); if(t && playerCanControl(t)){ NotifyGMOfLegendaryAction(); } } else if("-1"!==poID && (!isLegendaryCreature(poID) || NumLegendaryCreaturesInTurnOrder > 1)){ NotifyGMOfLegendaryAction(); } } } }; const handleInitiativePageChange = (obj) => { if(obj.get('initiativepage')){ let to = getTurnArrayFromString(obj.get('turnorder')); FindLegendaryCreaturesInTurnOrder(to); } else { NumLegendaryCreaturesInTurnOrder = false; } }; on('chat:message',(msg)=>{ if('api' === msg.type && /^!eot(\b\s|$)/i.test(msg.content)){ let prev = JSON.parse(JSON.stringify(Campaign())); setTimeout(()=>handleTurnOrderChange(Campaign(),prev),100); } }); on('ready',()=>{ on('change:campaign:initiativepage',handleInitiativePageChange); on('change:campaign:turnorder', handleTurnOrderChange); // check for legendary creatures on startup FindLegendaryCreaturesInTurnOrder( getTurnArrayFromString(Campaign().get('turnorder')) ); }); })();
Sweet, thanks Aaron! As always, your arcane scriptomancy and generosity with your time never fail to impress me. :-)
1608447495
The Aaron
Roll20 Production Team
API Scripter
No problem! =D
The Aaron said: Technically, it's " only at the end of another creature's turn " which means it could be another monster's turn. Good point! This is another reason why big bad guys have minions - to give them more opportunities to use those Legendary Actions!
True, but by only taking them at the end of the PCs’ turns, I can feel confident that I’m keeping close to my house rule of "# legendary actions = #PCs-1" (needed due to having 6 players), adjusted when I use an ability that costs multiple LAs, since I’m generally too lazy to track them. ;-)  (Don't worry for my players, I have trouble challenging them most of the time).