diff --git a/TokenNameNumber/TokenNameNumber.js b/TokenNameNumber/TokenNameNumber.js index dd2fe22b80..085d1bb7b5 100644 --- a/TokenNameNumber/TokenNameNumber.js +++ b/TokenNameNumber/TokenNameNumber.js @@ -5,25 +5,259 @@ var TokenNameNumber = TokenNameNumber || (function() { 'use strict'; - var version = 0.4, - schemaVersion = 0.2, + var version = '0.5.1', + lastUpdate = 1429599526, + schemaVersion = 0.3, maxWaitTime = 1000, - randomSpace = 0, - escapeForRegexp = /(\\|\/|\[|\]|\(|\)|\{|\}|\?|\+|\*|\||\.|\^|\$)/g, + statuses = [ + 'red', 'blue', 'green', 'brown', 'purple', 'pink', 'yellow', // 0-6 + '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' + ], + statusColormap = ['#C91010', '#1076c9', '#2fc910', '#c97310', '#9510c9', '#eb75e1', '#e5eb75'], + regex = { + escape: /(\\|\/|\[|\]|\(|\)|\{|\}|\?|\+|\*|\||\.|\^|\$)/g + }, checkInstall = function() { + log('-=> TokenNameNumber v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); + if( ! _.has(state,'TokenNameNumber') || state.TokenNameNumber.version !== schemaVersion) { - state.TokenNameNumber = { - version: schemaVersion, - registry: { - } - }; + log(' > Updating Schema to v'+schemaVersion+' <'); + switch(state.TokenNameNumber && state.TokenNameNumber.version) { + case 0.2: + state.TokenNameNumber = _.defaults({ + version: schemaVersion, + config: { + randomSpace: 0, + useDots: false, + dots: ['red','brown','yellow','green','blue','pink','purple'] + } + }, state.TokenNameNumber); + break; + default: + state.TokenNameNumber = { + version: schemaVersion, + config: { + useDots: false, + dots: ['red','brown','yellow','green','blue','purple'] + }, + registry: { + } + }; + break; + } } }, esRE = function (s) { - return s.replace(escapeForRegexp,"\\$1"); + return s.replace(regex.escape,"\\$1"); + }, + + 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 ''; + }, + + getConfigOption_RandomSpace = function() { + var text = ( state.TokenNameNumber.config.randomSpace > 0 + ? ''+ state.TokenNameNumber.config.randomSpace+ '' + : 'Off' ); + return '
'+ + 'Random Space of numbers between each consecutively generated token number:'+ + text+'. '+ + ''+ + 'Set Random Space'+ + ''+ + '
'; + }, + + getConfigOption_UseDots = function() { + var text = (state.TokenNameNumber.config.useDots + ? 'On' + : 'Off'); + + return '
'+ + 'Use Dots is currently '+ + text+ + '.'+ + 'Toggle'+ + '
'; + }, + + getStatusButton = function(status) { + var i=_.indexOf(statuses,status); + if(i<7) { + return '
'; + } + return '
'; + }, + +// https://app.roll20.net/images/statussheet.png + getConfigOption_Dots = function() { + return '
'+ + '
'+ + '
Dots (Click to move between pools).
'+ + '
'+ + _.map(state.TokenNameNumber.config.dots,function(s){ + return getStatusButton(s); + }).join('')+ + '
'+ + '
'+ + '
'+ + '
Available Statuses
'+ + '
'+ + _.map(_.difference(statuses,state.TokenNameNumber.config.dots),function(s){ + return getStatusButton(s); + }).join('')+ + '
'+ + '
'+ + '
'; + }, + + getAllConfigOptions = function() { + return ''; + }, + + showHelp = function(who) { + sendChat('','/w '+who+' '+ + '
'+ + '
'+ + 'TokenNameNumber v'+version+ + '
'+ + '
'+ + '

Provides automatic numbering of tokens dragged into onto the tabletop. Token names need to have the special word %%NUMBERED%% somewhere in them.

'+ + '
'+ + 'Commands'+ + '
'+ + '!tnn [--help]'+ + '
'+ + '

Currently, this just displayed the help, which is used for configuring.

'+ + '
    '+ + '
  • '+ + '--help '+ch('-')+' Displays the help and configuration options.'+ + '
  • '+ + '
'+ + '
'+ + '
'+ + 'Config'+ + '
'+ + getAllConfigOptions()+ + '
'+ + '
' + ); }, + handleInput = function(msg) { + var args, who; + + if (msg.type !== "api" || !playerIsGM(msg.playerid)) { + return; + } + who=getObj('player',msg.playerid).get('_displayname').split(' ')[0]; + + args = msg.content.split(/\s+--/); + switch(args.shift()) { + case '!tnn': + showHelp(who); + break; + + case '!tnn-config': + if(_.contains(args,'help')) { + showHelp(who); + return; + } + if(!args.length) { + sendChat('','/w '+who+' ' ++'
' + +'
' + +'TokenNameNumber v'+version + +'
' + +getAllConfigOptions() ++'
' + ); + return; + } + _.each(args,function(a){ + var opt=a.split(/\|/); + switch(opt.shift()) { + case 'toggle-use-dots': + state.TokenNameNumber.config.useDots=!state.TokenNameNumber.config.useDots; + sendChat('','/w '+who+' ' + +'
' + +getConfigOption_UseDots() + +'
' + ); + break; + + case 'toggle-dot': + if(_.contains(state.TokenNameNumber.config.dots, opt[0])){ + state.TokenNameNumber.config.dots = _.without(state.TokenNameNumber.config.dots, opt[0]); + } else { + state.TokenNameNumber.config.dots.push(opt[0]); + } + sendChat('','/w '+who+' ' + +'
' + +getConfigOption_Dots() + +'
' + ); + break; + + + case 'random-space': + state.TokenNameNumber.config.randomSpace=parseInt(opt[0],10); + sendChat('','/w '+who+' ' + +'
' + +getConfigOption_RandomSpace() + +'
' + ); + break; + + default: + sendChat('','/w '+who+' ' + +'
Unsupported Option:
'+a+'' + ); + } + + }); + + break; + } + }, + + + getMatchers = function(pageid,represents) { var matchers = []; if(_.has(state.TokenNameNumber.registry, pageid) @@ -45,6 +279,22 @@ var TokenNameNumber = TokenNameNumber || (function() { } }, + getDotNumber = function(num) { + var base = (function (b){ + var radix = b; + return (b && function base_dot(number,digits){ + digits = digits || []; + digits.push(number % radix); + if(number < radix) { + return digits; + } + return base_dot(Math.floor(number/radix),digits); + }) || function(){return [];}; + }(state.TokenNameNumber.config.dots.length)); + + return base(num); + }, + setNumberFunction = function(id,lastTimeout) { var obj = getObj('graphic',id), matchers = (obj && getMatchers(obj.get('pageid'), obj.get('represents'))) || [], @@ -52,7 +302,8 @@ var TokenNameNumber = TokenNameNumber || (function() { matcher, renamer, parts, - num; + num, + statuspart=''; if(obj && (tokenName.match( /%%NUMBERED%%/ ) || _.some(matchers,function(m) { return m.test(tokenName);}) ) ) { @@ -87,7 +338,18 @@ var TokenNameNumber = TokenNameNumber || (function() { },0) .value() ); - num += ( randomSpace ? (randomInteger(randomSpace)-1) : 0); + num += ( state.TokenNameNumber.config.randomSpace ? (randomInteger(state.TokenNameNumber.config.randomSpace)-1) : 0); + + if(state.TokenNameNumber.config.useDots) { + statuspart = _.map(getDotNumber(num), function(n){ + return state.TokenNameNumber.config.dots[n]; + }).join(','); + if(statuspart) { + obj.set({ + statusmarkers: statuspart + }); + } + } parts=renamer.exec(tokenName); obj.set({ @@ -107,6 +369,7 @@ var TokenNameNumber = TokenNameNumber || (function() { }, registerEventHandlers = function() { + on('chat:message', handleInput); on('add:graphic', setNumberOnToken); }; diff --git a/TokenNameNumber/package.json b/TokenNameNumber/package.json index b960b874d1..6f9c6440f9 100644 --- a/TokenNameNumber/package.json +++ b/TokenNameNumber/package.json @@ -1,19 +1,18 @@ { - "name": "TokenNameNumber", - "version": "0.4", - "description": "Automatic Numbering of tokens with special placeholder.", - "authors": "The Aaron", - "roll20userid": "104025", - "dependencies": { - }, - "modifies": { - "state.TokenNameNumber": "read,write", - "graphic.name": "read,write", - "graphic.pageid": "read", - "graphic.represents": "read", - "graphic.subtype": "read", - "graphic.type": "read" - }, - "conflicts": [ - ] + "name": "TokenNameNumber", + "version": "0.5.1", + "description": "Automatic Numbering of tokens with special placeholder.", + "authors": "The Aaron", + "roll20userid": "104025", + "dependencies": [], + "modifies": { + "state.TokenNameNumber": "read,write", + "graphic.name": "read,write", + "graphic.statusmarkers": "write", + "graphic.pageid": "read", + "graphic.represents": "read", + "graphic.subtype": "read", + "graphic.type": "read" + }, + "conflicts": [] }