// Github: https://github.com/shdwjk/Roll20API/blob/master/FateDots/FateDots.js
// By: The Aaron, Arcane Scriptomancer
// Contact: https://app.roll20.net/users/104025/the-aaron
var FateDots = FateDots || (function(){
'use strict';
var version = '0.2.2',
lastUpdate = 1487692335,
schemaVersion = 0.3,
regex = {
statuses: /^(?:red|blue|green|brown|purple|pink|yellow|skull|sleepy|half-heart|half-haze|interdiction|snail|lightning-helix|spanner|chained-heart|chemical-bolt|death-zone|drink-me|edge-crack|ninja-mask|stopwatch|fishing-net|overdrive|strong|fist|padlock|three-leaves|fluffy-wing|pummeled|tread|arrowed|aura|back-pain|black-flag|bleeding-eye|bolt-shield|broken-heart|cobweb|broken-shield|flying-flag|radioactive|trophy|broken-skull|frozen-orb|rolling-bomb|white-tower|grab|screaming|grenade|sentry-gun|all-for-one|angel-outfit|archery-target)$/
},
ch = function (c) {
var entities = {
'<' : 'lt',
'>' : 'gt',
"'" : '#39',
'@' : '#64',
'{' : '#123',
'|' : '#124',
'}' : '#125',
'[' : '#91',
']' : '#93',
'"' : 'quot',
'-' : 'mdash',
' ' : 'nbsp'
};
if(_.has(entities,c) ){
return ('&'+entities[c]+';');
}
return '';
},
showHelp = function() {
sendChat('',
'/w gm '+
'
'+
'
'+
'FateDots v'+version+
'
'+
'
'+
'
'+
'
Allows statues to be used like Fate stress boxes by repeating them.
'+
'
By default, Blue and Red will be treated specially. Assigning a number to them will cause them to be duplicated that many times, and numbered in decreasing order. Changing the number will change the number of pips that appear.
'+
'
'+
'
Commands'+
'
!fate-dots '+ch('<')+ch('[')+'+'+ch('|')+'-'+ch(']')+'Status Marker'+ch('>')+''+
'
'+
'Adds or removes a status to be treated as a multibox.'+
'
'+
'
Available Status Markers:
'+
'
red
'+
'
blue
'+
'
green
'+
'
brown
'+
'
purple
'+
'
pink
'+
'
yellow
'+
'
skull
'+
'
sleepy
'+
'
half-heart
'+
'
half-haze
'+
'
interdiction
'+
'
snail
'+
'
lightning-helix
'+
'
spanner
'+
'
chained-heart
'+
'
chemical-bolt
'+
'
death-zone
'+
'
drink-me
'+
'
edge-crack
'+
'
ninja-mask
'+
'
stopwatch
'+
'
fishing-net
'+
'
overdrive
'+
'
strong
'+
'
fist
'+
'
padlock
'+
'
three-leaves
'+
'
fluffy-wing
'+
'
pummeled
'+
'
tread
'+
'
arrowed
'+
'
aura
'+
'
back-pain
'+
'
black-flag
'+
'
bleeding-eye
'+
'
bolt-shield
'+
'
broken-heart
'+
'
cobweb
'+
'
broken-shield
'+
'
flying-flag
'+
'
radioactive
'+
'
trophy
'+
'
broken-skull
'+
'
frozen-orb
'+
'
rolling-bomb
'+
'
white-tower
'+
'
grab
'+
'
screaming
'+
'
grenade
'+
'
sentry-gun
'+
'
all-for-one
'+
'
angel-outfit
'+
'
archery-target
'+
'
'+ch(' ')+'
'+
'
Adding purple and skull, removing blue.
'+
'
'+
'
'+
'!fate-dots +purple +skull -blue'+
'
'+
'
'+
'
'+
'
'
);
},
handleInput = function(msg) {
var args;
if ( "api" !== msg.type || !playerIsGM(msg.playerid) ) {
return;
}
args = msg.content.split(/\s+/);
switch(args.shift()) {
case '!fate-dots':
if( !args.length ) {
showHelp();
return;
}
_.each(args,function(s){
var op = s[0],
st = s.substring(1);
if(st.match(regex.statuses)) {
switch(op) {
case '+':
state.FateDots.statuses=_.union( state.FateDots.statuses,[st] );
break;
case '-':
state.FateDots.statuses=_.without( state.FateDots.statuses, st );
break;
}
}
});
break;
}
},
statusmarkersToObject = function(stats) {
return _.reduce(stats.split(/,/),function(memo,st){
var parts=st.split(/@/),
num=parseInt(parts[1]||'0',10);
if(parts[0].length) {
memo[parts[0]]=Math.max(num,memo[parts[0]]||0);
}
return memo;
},{});
},
statusChangeHandler = function(obj) {
var nstat = statusmarkersToObject(obj.get('statusmarkers')),
rstat = _.reduce(nstat,function(m,c,s){
if(_.contains(state.FateDots.statuses,s)) {
m.push(_.reduce(_.range(1,c+1),function(m2,n){
m2.push(s+'@'+n);
return m2;
},[]).join(','));
} else {
m.push('dead' === s ? s : s+'@'+c);
}
return m;
},[]).join(',');
obj.set({
statusmarkers: rstat
});
},
checkInstall = function() {
log('-=> FateDots v'+version+' <=- ['+(new Date(lastUpdate*1000))+']');
if( ! _.has(state,'FateDots') || state.FateDots.version !== schemaVersion) {
log(' > Updating Schema to v'+schemaVersion+' <');
state.FateDots = {
version: schemaVersion,
statuses: ['blue','red']
};
}
},
registerEventHandlers = function() {
on('chat:message', handleInput);
on('change:graphic:statusmarkers',statusChangeHandler);
};
return {
CheckInstall: checkInstall,
RegisterEventHandlers: registerEventHandlers
};
}());
on("ready",function(){
'use strict';
FateDots.CheckInstall();
FateDots.RegisterEventHandlers();
});