Try this, it should cover everything on the To do list: on('ready',function(){
"use strict";
var auraColors = [
'#FF0000', /* Red */
'#FF7F00', /* Orange */
'#FFFF00', /* Yellow */
'#00FF00', /* Green */
'#0000FF', /* Blue */
'#4B0082', /* Indigo */
'#9400D3' /* Violet */
],
getRanges = function(desc){
return _.chain((desc||'').match(/(\d+[\s\/\d]*)/g))
.reduce((m,s)=> {
let t=s.split(/\s*\/\s*/);
return (t.length > m.length ? t : m);
},[])
.map((n)=>parseInt(n,10))
.value();
},
bound = (v,l,h) => Math.min(h,Math.max(l,v)),
attrLookup = function(character,name){
let match=name.match(/^(repeating_.*)_\$(\d+)_.*$/);
if(match){
let index=match[2],
attrMatcher=new RegExp(`^${name.replace(/_\$\d+_/,'_([-\\da-zA-Z]+)_')}$`),
createOrderKeys=[],
attrs=_.chain(findObjs({type:'attribute', characterid:character.id}))
.map((a)=>{
return {attr:a,match:a.get('name').match(attrMatcher)};
})
.filter((o)=>o.match)
.each((o)=>createOrderKeys.push(o.match[1]))
.reduce((m,o)=>{ m[o.match[1]]=o.attr; return m;},{})
.value(),
sortOrderKeys = _.chain( ((findObjs({
type:'attribute',
characterid:character.id,
name: `_reporder_${match[1]}`
})[0]||{get:_.noop}).get('current') || '' ).split(/\s*,\s*/))
.intersection(createOrderKeys)
.union(createOrderKeys)
.value();
if(index<sortOrderKeys.length && _.has(attrs,sortOrderKeys[index])){
return attrs[sortOrderKeys[index]];
}
return;
}
return findObjs({ type:'attribute', characterid:character.id, name: name})[0];
};
on('chat:message',function(msg){
if('api' === msg.type && msg.content.match(/^!aura-range\b/) ){
let args=_.rest(msg.content.split(/\s+/)),
attrName=(args.shift()||''),
aura1Index = args.shift()||0,
aura2Index = args.shift()||1;
_.chain(msg.selected)
.pluck('_id')
.map( (id) => getObj('graphic',id) )
.reject(_.isUndefined)
.map( (t) => {return {token:t, character:getObj('character',t.get('represents'))};} )
.reject( (o)=>_.isUndefined(o.character))
.map( (o) => { o.attribute = attrLookup(o.character, attrName); return o;} )
.reject( (o)=>_.isUndefined(o.attribute))
.map( (o) => { o.ranges = getRanges(o.attribute.get('current')); return o; })
.each( (o) => {
o.token.set({
aura1_color: auraColors[bound(aura1Index,0,auraColors.length-1)],
aura1_radius: o.ranges[bound(aura1Index,0,o.ranges.length-1)]||0,
aura2_color: auraColors[bound(aura2Index,0,auraColors.length-1)],
aura2_radius: o.ranges[bound(aura2Index,0,o.ranges.length-1)]||0
});
});
}
});
});