From 1457ca10723b7ce615db27ec2f23a415697e6b5c Mon Sep 17 00:00:00 2001 From: "Aaron C. Meadows" Date: Fri, 20 Feb 2015 00:38:05 -0600 Subject: [PATCH] Squashed 'GroupInitiative/' changes from 2ef0687..bb7e26a bb7e26a prod-GroupInitiative: Updated prod version of GroupInitiative at version 0.5. git-subtree-dir: GroupInitiative git-subtree-split: bb7e26a60e965b6c9cd37694a3e4cee16a02b802 --- GroupInitiative.js | 1107 +++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 572 insertions(+), 537 deletions(-) diff --git a/GroupInitiative.js b/GroupInitiative.js index d7ed908094..675880bfef 100644 --- a/GroupInitiative.js +++ b/GroupInitiative.js @@ -5,359 +5,378 @@ var GroupInitiative = GroupInitiative || (function() { 'use strict'; - var version = 0.41, - schemaVersion = 0.5, - bonusCache = {}, - statAdjustments = { - 'Stat-DnD': { - func: function(v) { - return Math.floor((v-10)/2); - }, - desc: 'Calculates the bonus as if the value were a DnD Stat.' - }, - 'Bare': { - func: function(v) { - return v; - }, - desc: 'No Adjustment.' - }, - 'Floor': { - func: function(v) { - return Math.floor(v); - }, - desc: 'Rounds down to the nearest integer.' - }, - 'Ceiling': { - func: function(v) { - return Math.ceil(v); - }, - desc: 'Rounds up to the nearest integer.' - }, - 'Bounded': { - func: function(v,l,h) { - l=parseFloat(l,10) || v; - h=parseFloat(h) || v; - return Math.min(h,Math.max(l,v)); - }, - desc: 'Restricts to a range. Use Bounded:: for specifying bounds. Leave a bound empty to be unrestricted in that direction. Example: Bounded::5 would specify a maximum of 5 with no minimum.' - } - }, - - rollers = { - 'Least-All-Roll':{ - func: function(s,k,l){ - if(!_.has(this,'init')) { - this.init=_.chain(l) - .pluck('bonus') - .map(function(d){ - return randomInteger(20)+d; - },{}) - .min() - .value(); - } - s.init=this.init; - return s; - }, - desc: 'Sets the initiative to the lowest of all initiatives rolled for the group.' - }, - 'Mean-All-Roll':{ - func: function(s,k,l){ - if(!_.has(this,'init')) { - this.init=_.chain(l) - .pluck('bonus') - .map(function(d){ - return randomInteger(20)+d; - },{}) - .reduce(function(r,memo){ - return memo+r; - },0) - .map(function(v){ - return Math.floor(v/l.length); - }) - .value(); - } - s.init=this.init; - return s; - }, - desc: 'Sets the initiative to the mean (average) of all initiatives rolled for the group.' - }, - 'Individual-Roll': { - func: function(s,k,l){ - s.init=randomInteger(20)+s.bonus; - return s; - }, - desc: 'Sets the initiative individually for each member of the group.' - }, - 'Constant-By-Stat': { - func: function(s,k,l){ - s.init=s.bonus; - return s; - }, - desc: 'Sets the initiative individually for each member of the group to their bonus with no roll.' - } - }, - checkInstall = function() { - if( ! _.has(state,'GroupInitiative') || state.GroupInitiative.version !== schemaVersion) { - state.GroupInitiative = { - version: schemaVersion, - bonusStatGroups: [ - [ - { - attribute: 'dexterity' - } - ] - ], - rollType: 'Individual-Roll' - }; - } - }, - 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 ''; - }, - - - buildBonusStatGroupRows = function() { - return _.reduce(state.GroupInitiative.bonusStatGroups, function(memo,bsg){ - return memo + '
  • '+_.chain(bsg) - .map(function(s){ - var attr=s.attribute+'|'+( _.has(s,'type') ? s.type : 'current' ); - if(_.has(s,'adjustments')) { - attr=_.reduce(s.adjustments, function(memo2,a) { - return a+'( '+memo2+' )'; - }, attr); - } - return attr; - }) - .value() - .join(' + ') - +'
  • '; - },""); - }, - buildStatAdjustmentRows = function() { - return _.reduce(statAdjustments,function(memo,r,n){ - return memo+"
  • "+n+" — "+r.desc+"
  • "; - },""); - }, - - showHelp = function() { - var rollerRows=_.reduce(rollers,function(memo,r,n){ - var selected=((state.GroupInitiative.rollType === n) ? - '
    Selected
    ' - : '' ), - selectedStyleExtra=((state.GroupInitiative.rollType === n) ? ' style="border: 1px solid #aeaeae;background-color:#8bd87a;"' : ''); - - return memo+selected+"
  • "+n+" - "+r.desc+"
  • "; - },""), - statAdjustmentRows = buildStatAdjustmentRows(), - bonusStatGroupRows = buildBonusStatGroupRows(); - - sendChat('', - '/w gm ' - +'
    ' - +'
    ' - +'GroupInitiative v'+version - +'
    ' - +'
    ' - +'

    Rolls initiative for the selected tokens and adds them ' - +'to the turn order if they don'+ch("'")+'t have a turn yet.

    ' - - +'

    The calculation of initiative is handled by the ' - +'combination of Roller (See Roller Options below) and ' - +'a Bonus. The Bonus is determined based on an ordered list ' - +'of Stat Groups (See Bonus Stat Groups below). Stat ' - +'Groups are evaluated in order. The bonus computed by the first ' - +'Stat Group for which all attributes exist and have a ' - +'numeric value is used. This allows you to have several ' - +'Stat Groups that apply to different types of characters. ' - +'In practice you will probably only have one, but more are ' - +'there if you need them.

    ' - +'
    ' - +'Commands' - +'
    ' - +'!group-init' - +'
    ' - +'

    This command uses the configured Roller to ' - +'determine the initiative order for all selected ' - +'tokens.

    ' - +'
    ' - +'
    ' - - +'
    ' - +'!group-init --help' - +'
    ' - +'

    This command displays the help.

    ' - +'
    ' - +'
    ' - - +'
    ' - +'!group-init --set-roller '+ch('<')+'roller name'+ch('>')+'' - +'
    ' - +'

    Sets Roller to use for calculating initiative.

    ' - +'This command requires 1 parameter:' - +'
      ' - +'
    • ' - +'roller name -- The name of the Roller to use. See Roller Options below.' - +'
    • ' - +'
    ' - +'
    ' - +'
    ' - - +'
    ' - +'!group-init --promote '+ch('<')+'index'+ch('>')+'' - +'
    ' - +'

    Increases the importance the specified Bonus Stat Group.

    ' - +'This command requires 1 parameter:' - +'
      ' - +'
    • ' - +'index -- The numeric index of the Bonus Stat Group to promote. See Bonus Stat Groups below.' - +'
    • ' - +'
    ' - +'
    ' - +'
    ' - - +'
    ' - +'!group-init --del-group '+ch('<')+'index'+ch('>')+'' - +'
    ' - +'

    Deletes the specified Bonus Stat Group.

    ' - +'This command requires 1 parameter:' - +'
      ' - +'
    • ' - +'index -- The numeric index of the Bonus Stat Group to delete. See Bonus Stat Groups below.' - +'
    • ' - +'
    ' - +'
    ' - +'
    ' -+'
    ' - +'!group-init --add-group --'+ch('<')+'adjustment'+ch('>')+' [--'+ch('<')+'adjustment'+ch('>')+'] '+ch('<')+'attribute name[|'+ch('<')+'max|current'+ch('>')+']'+ch('>')+' [--'+ch('<')+'adjustment'+ch('>')+' [--'+ch('<')+'adjustment'+ch('>')+'] '+ch('<')+'attribute name[|'+ch('<')+'max|current'+ch('>')+']'+ch('>')+' ...] ' - +'
    ' - +'

    Adds a new Bonus Stat Group to the end of the list. Each adjustment operation can be followed by another adjustment operation, but eventually must end in an attriute name. Adjustment operations are applied to the result of the adjustment operations that follow them.

    ' - +'

    For example: --Bounded:-2:2 --Stat-DnD wisdom|max would first computer the DnD Stat bonus for the max field of the wisdom attribute, then bound it between -2 and +2.

    ' - +'This command takes multiple parameters:' - +'
      ' - +'
    • ' - +'adjustment -- One of the Stat Adjustment Options. See Stat Adjustment Options below.' - +'
    • ' - +'
    • ' - +'attribute name -- The name of an attribute. You can specify |max or |current on the end to target those specific fields (defaults to |current).' - +'
    • ' - +'
    ' - +'
    ' - +'
    ' - - +'Roller Options' - +'
    ' - +'
      ' - +rollerRows - +'
    ' - +'
    ' - - +'Stat Adjustment Options' - +'
    ' - +'
      ' - +statAdjustmentRows - +'
    ' - +'
    ' - - +'Bonus Stat Groups' - +'
    ' - +'
      ' - +bonusStatGroupRows - +'
    ' - +'
    ' - - +'
    ' - ); - }, - - findInitiativeBonus = function(id) { - var bonus = 0; - if(_.has(bonusCache,id)) { - return bonusCache[id]; - } - _.chain(state.GroupInitiative.bonusStatGroups) - .find(function(group){ - bonus = _.chain(group) - .map(function(details){ - var stat=parseFloat(getAttrByName(id,details.attribute, details.type||'current'),10); - - stat = _.reduce(details.adjustments || [],function(memo,a){ - var args,adjustment,func; - if(memo) { - args=a.split(':'); - adjustment=args.shift(); - args.unshift(memo); - func=statAdjustments[adjustment].func; - if(_.isFunction(func)) { - memo =func.apply({},args); - } - } - return memo; - },stat); - return stat; - }) - .reduce(function(memo,v){ - return memo+v; - },0) - .value(); - return !(_.isUndefined(bonus) && _.isNaN(bonus)); - }); - bonusCache[id]=bonus; - return bonus; - }, - - HandleInput = function(msg) { - var args, - cmds, - workgroup, - workvar, - turnorder, - error=false, - initFunc; - - if (msg.type !== "api" || !isGM(msg.playerid) ) { - return; - } - - args = msg.content.split(/\s+--/); - switch(args.shift()) { - case '!group-init': - if(args.length > 0) { - cmds=args.shift().split(/\s+/); - toString(args); - toString(cmds); - - switch(cmds[0]) { - case 'help': - showHelp(); - break; - - case 'add-group': - workgroup=[]; - workvar={}; - - _.each(args,function(arg){ - var a=arg.split(/\s+(.+)/), - b, - c=a[0].split(/:/); - + var version = 0.5, + schemaVersion = 0.6, + bonusCache = {}, + statAdjustments = { + 'Stat-DnD': { + func: function(v) { + return Math.floor((v-10)/2); + }, + desc: 'Calculates the bonus as if the value were a DnD Stat.' + }, + 'Bare': { + func: function(v) { + return v; + }, + desc: 'No Adjustment.' + }, + 'Floor': { + func: function(v) { + return Math.floor(v); + }, + desc: 'Rounds down to the nearest integer.' + }, + 'Ceiling': { + func: function(v) { + return Math.ceil(v); + }, + desc: 'Rounds up to the nearest integer.' + }, + 'Bounded': { + func: function(v,l,h) { + l=parseFloat(l,10) || v; + h=parseFloat(h) || v; + return Math.min(h,Math.max(l,v)); + }, + desc: 'Restricts to a range. Use Bounded:: for specifying bounds. Leave a bound empty to be unrestricted in that direction. Example: Bounded::5 would specify a maximum of 5 with no minimum.' + } + }, + + rollers = { + 'Least-All-Roll':{ + func: function(s,k,l){ + if(!_.has(this,'init')) { + this.init=_.chain(l) + .pluck('bonus') + .map(function(d){ + return randomInteger(20)+d; + },{}) + .min() + .value(); + } + s.init=this.init; + return s; + }, + desc: 'Sets the initiative to the lowest of all initiatives rolled for the group.' + }, + 'Mean-All-Roll':{ + func: function(s,k,l){ + if(!_.has(this,'init')) { + this.init=_.chain(l) + .pluck('bonus') + .map(function(d){ + return randomInteger(20)+d; + },{}) + .reduce(function(r,memo){ + return memo+r; + },0) + .map(function(v){ + return Math.floor(v/l.length); + }) + .value(); + } + s.init=this.init; + return s; + }, + desc: 'Sets the initiative to the mean (average) of all initiatives rolled for the group.' + }, + 'Individual-Roll': { + func: function(s,k,l){ + s.init=randomInteger(20)+s.bonus; + return s; + }, + desc: 'Sets the initiative individually for each member of the group.' + }, + 'Constant-By-Stat': { + func: function(s,k,l){ + s.init=s.bonus; + return s; + }, + desc: 'Sets the initiative individually for each member of the group to their bonus with no roll.' + } + }, + + checkInstall = function() { + if( ! _.has(state,'GroupInitiative') || state.GroupInitiative.version !== schemaVersion) { + if( state && state.GroupInitiative && state.GroupInitiative.version && 0.5 === state.GroupInitiative.version ) { + log('GroupInitiative: Updating state schema to version '+schemaVersion); + state.GroupInitiative.version = schemaVersion; + state.GroupInitiative.replaceRoll = false; + } else { + state.GroupInitiative = { + version: schemaVersion, + bonusStatGroups: [ + [ + { + attribute: 'dexterity' + } + ] + ], + rollType: 'Individual-Roll', + replaceRoll: false + }; + } + } + }, + + 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 ''; + }, + + + buildBonusStatGroupRows = function() { + return _.reduce(state.GroupInitiative.bonusStatGroups, function(memo,bsg){ + return memo + '
  • '+_.chain(bsg) + .map(function(s){ + var attr=s.attribute+'|'+( _.has(s,'type') ? s.type : 'current' ); + if(_.has(s,'adjustments')) { + attr=_.reduce(s.adjustments, function(memo2,a) { + return a+'( '+memo2+' )'; + }, attr); + } + return attr; + }) + .value() + .join(' + ') + +'
  • '; + },""); + }, + + buildStatAdjustmentRows = function() { + return _.reduce(statAdjustments,function(memo,r,n){ + return memo+"
  • "+n+" — "+r.desc+"
  • "; + },""); + }, + + showHelp = function() { + var rollerRows=_.reduce(rollers,function(memo,r,n){ + var selected=((state.GroupInitiative.rollType === n) ? + '
    Selected
    ' + : '' ), + selectedStyleExtra=((state.GroupInitiative.rollType === n) ? ' style="border: 1px solid #aeaeae;background-color:#8bd87a;"' : ''); + + return memo+selected+"
  • "+n+" - "+r.desc+"
  • "; + },""), + statAdjustmentRows = buildStatAdjustmentRows(), + bonusStatGroupRows = buildBonusStatGroupRows(); + + sendChat('', + '/w gm ' + +'
    ' + +'
    ' + +'GroupInitiative v'+version + +'
    ' + +'
    ' + +'

    Rolls initiative for the selected tokens and adds them ' + +'to the turn order if they don'+ch("'")+'t have a turn yet.

    ' + + +'

    The calculation of initiative is handled by the ' + +'combination of Roller (See Roller Options below) and ' + +'a Bonus. The Bonus is determined based on an ordered list ' + +'of Stat Groups (See Bonus Stat Groups below). Stat ' + +'Groups are evaluated in order. The bonus computed by the first ' + +'Stat Group for which all attributes exist and have a ' + +'numeric value is used. This allows you to have several ' + +'Stat Groups that apply to different types of characters. ' + +'In practice you will probably only have one, but more are ' + +'there if you need them.

    ' + +'
    ' + +'Commands' + +'
    ' + +'!group-init' + +'
    ' + +'

    This command uses the configured Roller to ' + +'determine the initiative order for all selected ' + +'tokens.

    ' + +'
    ' + +'
    ' + + +'
    ' + +'!group-init --help' + +'
    ' + +'

    This command displays the help.

    ' + +'
    ' + +'
    ' + + +'
    ' + +'!group-init --set-roller '+ch('<')+'roller name'+ch('>')+'' + +'
    ' + +'

    Sets Roller to use for calculating initiative.

    ' + +'This command requires 1 parameter:' + +'
      ' + +'
    • ' + +'roller name -- The name of the Roller to use. See Roller Options below.' + +'
    • ' + +'
    ' + +'
    ' + +'
    ' + + +'
    ' + +'!group-init --promote '+ch('<')+'index'+ch('>')+'' + +'
    ' + +'

    Increases the importance the specified Bonus Stat Group.

    ' + +'This command requires 1 parameter:' + +'
      ' + +'
    • ' + +'index -- The numeric index of the Bonus Stat Group to promote. See Bonus Stat Groups below.' + +'
    • ' + +'
    ' + +'
    ' + +'
    ' + + +'
    ' + +'!group-init --del-group '+ch('<')+'index'+ch('>')+'' + +'
    ' + +'

    Deletes the specified Bonus Stat Group.

    ' + +'This command requires 1 parameter:' + +'
      ' + +'
    • ' + +'index -- The numeric index of the Bonus Stat Group to delete. See Bonus Stat Groups below.' + +'
    • ' + +'
    ' + +'
    ' + +'
    ' + +'
    ' + +'!group-init --add-group --'+ch('<')+'adjustment'+ch('>')+' [--'+ch('<')+'adjustment'+ch('>')+'] '+ch('<')+'attribute name[|'+ch('<')+'max|current'+ch('>')+']'+ch('>')+' [--'+ch('<')+'adjustment'+ch('>')+' [--'+ch('<')+'adjustment'+ch('>')+'] '+ch('<')+'attribute name[|'+ch('<')+'max|current'+ch('>')+']'+ch('>')+' ...] ' + +'
    ' + +'

    Adds a new Bonus Stat Group to the end of the list. Each adjustment operation can be followed by another adjustment operation, but eventually must end in an attriute name. Adjustment operations are applied to the result of the adjustment operations that follow them.

    ' + +'

    For example: --Bounded:-2:2 --Stat-DnD wisdom|max would first computer the DnD Stat bonus for the max field of the wisdom attribute, then bound it between -2 and +2.

    ' + +'This command takes multiple parameters:' + +'
      ' + +'
    • ' + +'adjustment -- One of the Stat Adjustment Options. See Stat Adjustment Options below.' + +'
    • ' + +'
    • ' + +'attribute name -- The name of an attribute. You can specify |max or |current on the end to target those specific fields (defaults to |current).' + +'
    • ' + +'
    ' + +'
    ' + +'
    ' + + +'
    ' + +'!group-init --toggle-replace' + +'
    ' + +'
    '+( state.GroupInitiative.replaceRoll ? 'ON' : 'OFF' )+'
    ' + +'

    Sets whether initative scores for selected tokens replace their current scores.

    ' + +'
    ' + +'
    ' + + +'Roller Options' + +'
    ' + +'
      ' + +rollerRows + +'
    ' + +'
    ' + + +'Stat Adjustment Options' + +'
    ' + +'
      ' + +statAdjustmentRows + +'
    ' + +'
    ' + + +'Bonus Stat Groups' + +'
    ' + +'
      ' + +bonusStatGroupRows + +'
    ' + +'
    ' + + +'
    ' + ); + }, + + findInitiativeBonus = function(id) { + var bonus = 0; + if(_.has(bonusCache,id)) { + return bonusCache[id]; + } + _.chain(state.GroupInitiative.bonusStatGroups) + .find(function(group){ + bonus = _.chain(group) + .map(function(details){ + var stat=parseFloat(getAttrByName(id,details.attribute, details.type||'current'),10); + + stat = _.reduce(details.adjustments || [],function(memo,a){ + var args,adjustment,func; + if(memo) { + args=a.split(':'); + adjustment=args.shift(); + args.unshift(memo); + func=statAdjustments[adjustment].func; + if(_.isFunction(func)) { + memo =func.apply({},args); + } + } + return memo; + },stat); + return stat; + }) + .reduce(function(memo,v){ + return memo+v; + },0) + .value(); + return !(_.isUndefined(bonus) && _.isNaN(bonus)); + }); + bonusCache[id]=bonus; + return bonus; + }, + + HandleInput = function(msg) { + var args, + cmds, + workgroup, + workvar, + turnorder, + rolls, + error=false, + initFunc; + + if (msg.type !== "api" || !isGM(msg.playerid) ) { + return; + } + + args = msg.content.split(/\s+--/); + switch(args.shift()) { + case '!group-init': + if(args.length > 0) { + cmds=args.shift().split(/\s+/); + toString(args); + toString(cmds); + + switch(cmds[0]) { + case 'help': + showHelp(); + break; + + case 'add-group': + workgroup=[]; + workvar={}; + + _.each(args,function(arg){ + var a=arg.split(/\s+(.+)/), + b, + c=a[0].split(/:/); + if(_.has(statAdjustments,c[0])) { if('Bare' !== c[0]) { if(!_.has(workvar,'adjustments')) { @@ -375,198 +394,214 @@ var GroupInitiative = GroupInitiative || (function() { workvar={}; } } else { - sendChat('!group-init --add-group', '/w gm ' - +'
    ' - +'Unknown Stat Adustment: '+c[0]+'
    ' - +'Use one of the following:' - +'
      ' - +buildStatAdjustmentRows() - +'
    ' - +'
    ' - ); + sendChat('!group-init --add-group', '/w gm ' + +'
    ' + +'Unknown Stat Adustment: '+c[0]+'
    ' + +'Use one of the following:' + +'
      ' + +buildStatAdjustmentRows() + +'
    ' + +'
    ' + ); error=true; } - }); + }); if(!error) { if(!_.has(workvar,'adjustments')){ state.GroupInitiative.bonusStatGroups.push(workgroup); sendChat('GroupInitiative', '/w gm ' - +'
    ' - +'Updated Bonus Stat Group Ordering:' - +'
      ' - +buildBonusStatGroupRows() - +'
    ' - +'
    ' - ); + +'
    ' + +'Updated Bonus Stat Group Ordering:' + +'
      ' + +buildBonusStatGroupRows() + +'
    ' + +'
    ' + ); } else { - sendChat('!group-init --add-group', '/w gm ' - +'
    ' - +'All Stat Adjustments must have a final attribute name as an argument. Please add an attribute name after --'+args.pop() - +'
    ' - ); - } + sendChat('!group-init --add-group', '/w gm ' + +'
    ' + +'All Stat Adjustments must have a final attribute name as an argument. Please add an attribute name after --'+args.pop() + +'
    ' + ); + } + } + break; + + + case 'promote': + cmds[1]=Math.max(parseInt(cmds[1],10),1); + if(state.GroupInitiative.bonusStatGroups.length >= cmds[1]) { + if(1 !== cmds[1]) { + workvar=state.GroupInitiative.bonusStatGroups[cmds[1]-1]; + state.GroupInitiative.bonusStatGroups[cmds[1]-1] = state.GroupInitiative.bonusStatGroups[cmds[1]-2]; + state.GroupInitiative.bonusStatGroups[cmds[1]-2] = workvar; + } + + sendChat('GroupInitiative', '/w gm ' + +'
    ' + +'Updated Bonus Stat Group Ordering:' + +'
      ' + +buildBonusStatGroupRows() + +'
    ' + +'
    ' + ); + } else { + sendChat('!group-init --promote', '/w gm ' + +'
    ' + +'Please specify one of the following by number:' + +'
      ' + +buildBonusStatGroupRows() + +'
    ' + +'
    ' + ); + } + break; + + case 'del-group': + cmds[1]=Math.max(parseInt(cmds[1],10),1); + if(state.GroupInitiative.bonusStatGroups.length >= cmds[1]) { + state.GroupInitiative.bonusStatGroups=_.filter(state.GroupInitiative.bonusStatGroups, function(v,k){ + return (k !== (cmds[1]-1)); + }); + + sendChat('GroupInitiative', '/w gm ' + +'
    ' + +'Updated Bonus Stat Group Ordering:' + +'
      ' + +buildBonusStatGroupRows() + +'
    ' + +'
    ' + ); + } else { + sendChat('!group-init --del-group', '/w gm ' + +'
    ' + +'Please specify one of the following by number:' + +'
      ' + +buildBonusStatGroupRows() + +'
    ' + +'
    ' + ); } - break; - - - case 'promote': - cmds[1]=Math.max(parseInt(cmds[1],10),1); - if(state.GroupInitiative.bonusStatGroups.length >= cmds[1]) { - if(1 !== cmds[1]) { - workvar=state.GroupInitiative.bonusStatGroups[cmds[1]-1]; - state.GroupInitiative.bonusStatGroups[cmds[1]-1] = state.GroupInitiative.bonusStatGroups[cmds[1]-2]; - state.GroupInitiative.bonusStatGroups[cmds[1]-2] = workvar; - } - - sendChat('GroupInitiative', '/w gm ' - +'
    ' - +'Updated Bonus Stat Group Ordering:' - +'
      ' - +buildBonusStatGroupRows() - +'
    ' - +'
    ' - ); - } else { - sendChat('!group-init --promote', '/w gm ' - +'
    ' - +'Please specify one of the following by number:' - +'
      ' - +buildBonusStatGroupRows() - +'
    ' - +'
    ' - ); - } - break; - - case 'del-group': - cmds[1]=Math.max(parseInt(cmds[1],10),1); - if(state.GroupInitiative.bonusStatGroups.length >= cmds[1]) { - state.GroupInitiative.bonusStatGroups=_.filter(state.GroupInitiative.bonusStatGroups, function(v,k){ - return (k !== (cmds[1]-1)); - }); - - sendChat('GroupInitiative', '/w gm ' - +'
    ' - +'Updated Bonus Stat Group Ordering:' - +'
      ' - +buildBonusStatGroupRows() - +'
    ' - +'
    ' - ); - } else { - sendChat('!group-init --del-group', '/w gm ' - +'
    ' - +'Please specify one of the following by number:' - +'
      ' - +buildBonusStatGroupRows() - +'
    ' - +'
    ' - ); - } - break; - - case 'set-roller': - if(_.has(rollers,cmds[1])) { - state.GroupInitiative.rollType=cmds[1]; - sendChat('GroupInitiative', '/w gm ' - +'
    ' - +'Roller is now set to: '+cmds[1]+'
    ' - +'
    ' - ); - } else { - sendChat('GroupInitiative', '/w gm ' - +'
    ' - +'Not a valid Roller Name: '+cmds[1]+'
    ' - +'Please use one of the following:' - +'
      ' - +_.reduce(rollers,function(memo,r,n){ - return memo+'
    • '+n+'
    • '; - },'') - +'
    ' - +'
    ' - ); - } - break; - default: - sendChat('GroupInitiative', '/w gm ' - +'
    ' - +'Not a valid command: '+cmds[0]+'' - +'
    ' - ); - break; - } - } else { - if(_.has(msg,'selected')) { - bonusCache = {}; - turnorder = Campaign().get('turnorder'); - turnorder = ('' === turnorder) ? [] : JSON.parse(turnorder); - - initFunc=rollers[state.GroupInitiative.rollType].func; - - Campaign().set({ - turnorder: JSON.stringify( - turnorder.concat( - _.chain(msg.selected) - .map(function(s){ - return getObj(s._type,s._id); - }) - .reject(_.isUndefined) - .reject(function(s){ - return _.contains(_.pluck(turnorder,'id'),s.id); - }) - .map(function(s){ - return { - token: s, - character: getObj('character',s.get('represents')) - }; - }) - .map(function(s){ - s.bonus=s.character ? findInitiativeBonus(s.character.id) || 0 : 0; - return s; - }) - .map(initFunc,{}) - .map(function(s){ - return { - id: s.token.id, - pr: s.init, - custom: '' - }; - }) - .value() - ) - ) - } - ); - } else { - showHelp(); - } - } - break; - } - - }, - - - RegisterEventHandlers = function() { - on('chat:message', HandleInput); - }; - - return { - RegisterEventHandlers: RegisterEventHandlers, - CheckInstall: checkInstall - }; + break; + + case 'set-roller': + if(_.has(rollers,cmds[1])) { + state.GroupInitiative.rollType=cmds[1]; + sendChat('GroupInitiative', '/w gm ' + +'
    ' + +'Roller is now set to: '+cmds[1]+'
    ' + +'
    ' + ); + } else { + sendChat('GroupInitiative', '/w gm ' + +'
    ' + +'Not a valid Roller Name: '+cmds[1]+'
    ' + +'Please use one of the following:' + +'
      ' + +_.reduce(rollers,function(memo,r,n){ + return memo+'
    • '+n+'
    • '; + },'') + +'
    ' + +'
    ' + ); + } + break; + + case 'toggle-replace': + state.GroupInitiative.replaceRoll = !state.GroupInitiative.replaceRoll; + sendChat('GroupInitiative', '/w gm ' + +'
    ' + +'Replace Initiative on Roll is now: '+ (state.GroupInitiative.replaceRoll ? 'ON' : 'OFF') +'' + +'
    ' + ); + break; + + + default: + sendChat('GroupInitiative', '/w gm ' + +'
    ' + +'Not a valid command: '+cmds[0]+'' + +'
    ' + ); + break; + } + } else { + if(_.has(msg,'selected')) { + bonusCache = {}; + turnorder = Campaign().get('turnorder'); + turnorder = ('' === turnorder) ? [] : JSON.parse(turnorder); + if(state.GroupInitiative.replaceRoll) { + turnorder=_.reject(turnorder,function(i){ + return _.contains(_.pluck(msg.selected, '_id'),i.id); + }); + } + + initFunc=rollers[state.GroupInitiative.rollType].func; + + Campaign().set({ + turnorder: JSON.stringify( + turnorder.concat( + _.chain(msg.selected) + .map(function(s){ + return getObj(s._type,s._id); + }) + .reject(_.isUndefined) + .reject(function(s){ + return _.contains(_.pluck(turnorder,'id'),s.id); + }) + .map(function(s){ + return { + token: s, + character: getObj('character',s.get('represents')) + }; + }) + .map(function(s){ + s.bonus=s.character ? findInitiativeBonus(s.character.id) || 0 : 0; + return s; + }) + .map(initFunc,{}) + .map(function(s){ + return { + id: s.token.id, + pr: s.init, + custom: '' + }; + }) + .value() + ) + ) + } + ); + } else { + showHelp(); + } + } + break; + } + + }, + + + RegisterEventHandlers = function() { + on('chat:message', HandleInput); + }; + + return { + RegisterEventHandlers: RegisterEventHandlers, + CheckInstall: checkInstall + }; }()); on("ready",function(){ - 'use strict'; - - if("undefined" !== typeof isGM && _.isFunction(isGM)) { - GroupInitiative.CheckInstall(); - GroupInitiative.RegisterEventHandlers(); - } else { - log('--------------------------------------------------------------'); - log('GroupInitiative requires the isGM module to work.'); - log('isGM GIST: https://gist.github.com/shdwjk/8d5bb062abab18463625'); - log('--------------------------------------------------------------'); - } + 'use strict'; + + if("undefined" !== typeof isGM && _.isFunction(isGM)) { + GroupInitiative.CheckInstall(); + GroupInitiative.RegisterEventHandlers(); + } else { + log('--------------------------------------------------------------'); + log('GroupInitiative requires the isGM module to work.'); + log('isGM GIST: https://gist.github.com/shdwjk/8d5bb062abab18463625'); + log('--------------------------------------------------------------'); + } }); diff --git a/package.json b/package.json index 29c51e2eb3..3fa666a45c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "GroupInitiative", - "version": "0.41", + "version": "0.5", "description": "Adds the selected tokens to the turn order after rolling their initiative + configurable data.", "authors": "The Aaron", "roll20userid": "104025",