I have a special place in my heart for accessibility, particularly because I have a good friend who is blind. Here's a script that will store all of a players macros in a handout named "Macros: Player Display Name" so you can transmogrify them to a different game, then use this script to restore them. It requires my Base64 script, so be sure to install that. on('ready',function(){
'use strict';
var keyFormat = function(text) {
return (text && text.toLowerCase().replace(/\s+/,'')) || undefined;
},
matchKey = function (keys,subject){
return subject && !_.isUndefined(_.find(keys,(o)=>(-1 !== subject.indexOf(o))));
},
simpleObject = function(o){
return JSON.parse(JSON.stringify(o));
},
saveToHandout = function(name,data){
var handout=findObjs({
type: 'handout',
name: name
})[0] || createObj('handout',{
name: name
});
handout.set({notes: data});
},
getFromHandout = function(name,callback){
var handout=findObjs({
type: 'handout',
name: name
})[0];
if(handout){
handout.get('notes',callback);
} else {
callback('');
}
},
packForPlayer = function(player){
let mcount = 0,
macros = Base64.encode(JSON.stringify(_.chain(findObjs({type:'macro',playerid: player.id}))
.tap((o)=>{ mcount=o.length; })
.map(simpleObject)
.map((m)=>{
m.playerid=m._playerid;
m.type=m._type;
return _.omit(m,['_type','_playerid','_id']);
})
.value()));
sendChat('',`/w gm <div style="border: 1px solid #eee;background-color:white; border-radius:.25em; padding: .1em .25em;">Packing ${mcount} macros to handout: <b>Macros: ${player.get('displayname')}</b></div>`);
saveToHandout(`Macros: ${player.get('displayname')}`,macros);
},
unpackForPlayer = function(player){
getFromHandout(`Macros: ${player.get('displayname')}`,(m)=>{
if(m.length){
m=JSON.parse(Base64.decode(m));
}
let macros = _.isArray(m) ? m : [];
sendChat('',`/w gm <div style="border: 1px solid #eee;background-color:white; border-radius:.25em; padding: .1em .25em;">Unpacking ${macros.length} macros from handout: <b>Macros: ${player.get('displayname')}</b></div>`);
_.each(macros,(mdata)=>{
mdata.playerid=player.id;
createObj('macro',mdata);
});
});
};
on('chat:message',function(msg){
if('api' === msg.type && msg.content.match(/^!(?:pack|unpack)-macros/) && playerIsGM(msg.playerid) ){
let op=msg.content.match(/^!pack/) ? packForPlayer : unpackForPlayer,
args=_.map(_.rest(msg.content.split(/\s+--/)), (o)=>o && o.toLowerCase()),
keys=_.map(args,keyFormat);
_.chain(findObjs({type: 'player'}))
.reject(_.isUndefined)
.filter((o)=>{
return matchKey(keys,keyFormat(o.get('displayname')));
})
.uniq()
.each(op);
}
});
});
The commands are: !pack-macros --<player name fragment> [--<player name fragment> ...] !unpack-macros --<player name fragment> [--<player name fragment> ...] Here are some examples: Store all macros for a player named Bob the Slayer (all of these work): !pack-macros --Bob the Slayer
!pack-macros --bobtheslayer
!pack-macros --bob
!pack-macros --theSlayer In the case of the shorter name fragments, it will do every matching player (so if you did --bob and you have Bob the Slayer and Bob the not-Slayer , it would do both of them). You can specify multiple separate player fragments: !pack-macros --vince --brian --stephen --russ Unpack has identical syntax. If a handout with the same name ( Macros: Bob the Slayer ) already exists for a player, it will be overwritten with the new data. This version doesn't check if a macro already exists and will blindly create macros again, if they are in the handout. Let me know if that's an enhancement you'd like added. Cheers and ping me if you need help!