diff --git a/CthulhuTechDice/CthulhuTechDice.js b/CthulhuTechDice/CthulhuTechDice.js new file mode 100644 index 0000000000..c65f41f1bf --- /dev/null +++ b/CthulhuTechDice/CthulhuTechDice.js @@ -0,0 +1,297 @@ +// Github: https://github.com/shdwjk/Roll20API/blob/master/CthulhuTechDice/CthulhuTechDice.js +// By: The Aaron, Arcane Scriptomancer +// Contact: https://app.roll20.net/users/104025/the-aaron + +var CthulhuTechDice = CthulhuTechDice || (function() { + 'use strict'; + + var version = '0.1.6', + lastUpdate = 1434815201, + schemaVersion = 0.1, + + checkInstall = function() { + log('-=> CthulhuTechDice v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); + + if( ! _.has(state,'CthulhuTechDice') || state.CthulhuTechDice.version !== schemaVersion) { + log(' > Updating Schema to v'+schemaVersion+' <'); + state.CthulhuTechDice = { + version: schemaVersion + }; + } + }, + + getDiceCounts = function(msg,idx) { + return ( msg.inlinerolls + && msg.inlinerolls[idx] + && msg.inlinerolls[idx].results + && msg.inlinerolls[idx].results.rolls[0] + && msg.inlinerolls[idx].results.rolls[0].results + && (_.reduce(_.map(msg.inlinerolls[idx].results.rolls[0].results, function(r){ + return r.v; + }).sort() || [], function(m,r){ + m[r]=(m[r]||0)+1; + return m; + },{}))); + }, + + getDiceArray = function(c) { + return _.reduce(c,function(m,v,k){ + _.times(v,function(){m.push(k);}); + return m; + },[]); + }, + + + + handleInput = function(msg_orig) { + var msg = _.clone(msg_orig), + args, + diceCounts, + maxSingle=0, + maxMultiple=0, + maxRun=0, + diceArray, + bonus, + result, + w=false; + + if (msg.type !== "api") { + return; + } + + if(_.has(msg,'inlinerolls')){ + msg.content = _.chain(msg.inlinerolls) + .reduce(function(m,v,k){ + m['$[['+k+']]']=v.results.total || 0; + return m; + },{}) + .reduce(function(m,v,k){ + return m.replace(k,v); + },msg.content) + .value(); + } + + args = msg.content.split(/\s+/); + switch(args.shift()) { + case '!wct': + w=true; + /* break; */ // Intentional drop through + case '!ct': + + if(args.length>1){ + bonus = parseInt(args[1],10); + bonus = _.isNaN(bonus) ? undefined : bonus; + } + + diceCounts=getDiceCounts(msg,0); + if(!diceCounts){ + return; + } + diceArray=getDiceArray(diceCounts); + + maxMultiple=_.chain(diceCounts) + .map(function(c,r){ + return { + label: 'Best Set', + roll: r, + count: c, + total: (r*c) + }; + }) + .sortBy('total') + .reverse() + .first() + .value(); + + maxRun=_.chain(_.keys(diceCounts)) + .map(function(r){ + return parseInt(r,10); + }) + .tap(function(s){ + var m=_.max(s); + maxSingle={ + label: 'High Roll', + roll: m, + count: 1, + total: m + }; + }) + .reduce(function(m,r){ + if(0 === _.last(m).length) { + _.last(m).push(r); + } else if( r === _.last(_.last(m))+1) { + _.last(m).push(r); + } else { + m.push([r]); + } + return m; + },[[]]) + .map(function(r){ + return { + label: 'Best Run', + run: r, + total: _.reduce(r,function(m,v){return m+v;},0) + }; + }) + .filter(function(o){ + return o.run.length>2; + }) + .sortBy('total') + .reverse() + .first() + .value(); + + result=_.reduce([maxMultiple,maxRun],function(m,e){ + return ( (e && m && e.total>m.total ) ? e : m); + },maxSingle); + + + sendChat( msg.who, (w ? '/w gm ' : '/direct ')+ + '