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);
if('undefined' !== typeof GroupInitiative && GroupInitiative.ObserveTurnOrderChange){
GroupInitiative.ObserveTurnOrderChange(handleTurnOrderChange);
}
on('chat:message', (msg) => {
if('api'===msg.type && /^!eot\b/.test(msg.content)){
let prev = JSON.parse(JSON.stringify(Campaign()));
setTimeout(()=>handleTurnOrderChange(Campaign(),prev),1000);
}
});
// check for legendary creatures on startup
FindLegendaryCreaturesInTurnOrder(
getTurnArrayFromString(Campaign().get('turnorder'))
);
});
})();