Here's a little script I threw together for this. Run it with: !show-hands Output looks like: Code: on('ready',()=>{
const HE = (() => {
const esRE = (s) => s.replace(/(\\|\/|\[|\]|\(|\)|\{|\}|\?|\+|\*|\||\.|\^|\$)/g,'\\$1');
const e = (s) => `&${s};`;
const entities = {
'<' : e('lt'),
'>' : e('gt'),
"'" : e('#39'),
'@' : e('#64'),
'{' : e('#123'),
'|' : e('#124'),
'}' : e('#125'),
'[' : e('#91'),
']' : e('#93'),
'"' : e('quot')
};
const re = new RegExp(`(${Object.keys(entities).map(esRE).join('|')})`,'g');
return (s) => s.replace(re, (c) => (entities[c] || c) );
})();
const s = {
num: `position:absolute;top:3px;right:3px;z-index:100;font-weight:bold;color:white;font-size:2em;text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;`,
card: `max-width: 5em;max-height:7em;position:relative;display:inline-block;margin:.5em;box-shadow:.2em .2em .4em .4em;`,
title: `font-weight:bold;color:black;font-size:1.3em;`,
title2: `bottom:3px;left:3px;z-index:100;font-weight:bold;color:white;font-size:1em;text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;`,
player: `padding:.5em;margin-bottom: 1em;`,
deck: `border:1px solid #333;background-color: #999; margine-left:1em;padding:.5em;`
};
const f = {
t : (c) => `<div style="${s.title}">${c}</div>`,
t2 : (c) => `<div style="${s.title2}">${c}</div>`,
player : (p,b) => `<div style="${s.player}">${f.t(p)}${b}</div>`,
deck : (d,b) => `<div style="${s.deck}">${f.t2(d)}${b}</div>`,
card : (t,i) => `<div style="${s.card}">${f.hover(t,f.image(i))}</div>`,
hover : (t,b) => `<span class="tipsy showtip" title="${HE(HE(t))}">${b}</span>`,
image : (i) => `<img src="${i}">`,
};
const showCard = (card) => f.card(card.get('name'),card.get('avatar'));
const getPlayerByID= (()=>{
let cache = {};
return (pid) => {
if(!cache.hasOwnProperty(pid)){
cache[pid] = getObj('player',pid);
}
return cache[pid];
};
})();
const getDeckByID = (()=>{
let cache = {};
on('destroy:deck',(did)=>{
delete cache[did];
});
return (did) => {
if(!cache.hasOwnProperty(did)){
cache[did] = getObj('deck',did);
}
return cache[did];
};
})();
on('chat:message',msg=>{
if('api'===msg.type && /^!show-hands(\b\s|$)/i.test(msg.content) && playerIsGM(msg.playerid)){
let who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname');
let hands=findObjs({type:'hand'})
.reduce((m,h)=>{
let p = (getPlayerByID(h.get('parentid'))||{get:()=>`Unknown Player: ${h.get('parentid')}`}).get('displayname');
let ds = h.get('currentHand')
.split(/\s*,\s*/)
.filter(s=>s.length)
.map(cid=>getObj('card',cid))
.filter(o=>o!==undefined)
.reduce((m,c)=>({...m,[c.get('deckid')]:[...(m[c.get('deckid')]||[]),c]}), {})
;
let deckOutput = Object.keys(ds).map(id=>{
let d = (getDeckByID(id)||{get:()=>`Unknown Deck: ${id}`}).get('name');
let cards = ds[id]
.map(showCard)
.join('')
;
return f.deck(d,cards);
}).join('');
return [...m,f.player(p,deckOutput)];
},[]);
sendChat('',`/w "${who}" ${hands.join('')}`);
}
});
});