Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

TokenResize throwing up errors for me!

Hello, my only scripts at the moment are IsGM, TokenMod, ClockTimer, and ResizeToken. I have not altered the code in any of these. Attempting to use any of TokenResize's functions aside from the help command does nothing at all, and in specific, command-line resizing of a targeted token throws up this error: /home/symbly/www/d20-api-server/node_modules/firebase/lib/firebase-node.js:1 orts, require, module, filename, dirname) { function g(a){throw a;}var j=v ^ TypeError: Cannot call method 'get' of undefined at handleInput (evalmachine. :136:40) at eval (
1431191530

Edited 1431192903
One of my players hacked at it for a few hours and got it working. This is what she came up with: // var TokenResize = TokenResize || (function() { 'use strict'; var version = 0.16, schemaVersion = 0.1, performAutoOff = function() { if (!state.AutoResize.locked) { state.AutoResize.locked = true; } sendChat('TokenResize', '/w gm ' + '&lt;div style="border: 1px solid #666666; background: #ffffee;"&gt;' + 'Auto resizing is now &lt;span style="color: #990000; font-weight: bold;"&gt;Off&lt;/span&gt;.' + '&lt;/div&gt;'); }, performAutoOn = function() { if (state.AutoResize.locked) { state.AutoResize.locked = false; } sendChat('TokenResize', '/w gm ' + '&lt;div style="border: 1px solid #666666; background: #ffffee;"&gt;' + 'Auto resizing is now &lt;span style="color: #009900; font-weight: bold;"&gt;On&lt;/span&gt;.' + '&lt;/div&gt;'); }, performPlayerOn = function(msg) { if (state.PlayerResize.locked) { state.PlayerResize.locked = false; } sendChat('TokenResize', '/w gm ' + '&lt;div style="border: 1px solid #666666; background: #ffffee;"&gt;' + 'Player manual resizing is now &lt;span style="color: #009900; font-weight: bold;"&gt;On&lt;/span&gt;.' + '&lt;/div&gt;'); }, performPlayerOff = function(msg) { if (!state.PlayerResize.locked) { state.PlayerResize.locked = true; } sendChat('TokenResize', '/w gm ' + '&lt;div style="border: 1px solid #666666; background: #ffffee;"&gt;' + 'Player manual resizing is now &lt;span style="color: #990000; font-weight: bold;"&gt;Off&lt;/span&gt;.' + '&lt;/div&gt;'); }, isSelected = function(msg) { if (!state.isSelected.locked) { state.isSelected.locked = true; } sendChat('TokenResize', '/w gm ' + '&lt;div style="border: 1px solid #666666; background: #ffffee;"&gt;' + 'Tokens can be targetted for resize is now &lt;span style="color: #990000; font-weight: bold;"&gt;Off&lt;/span&gt;.' + '&lt;/div&gt;'); }, isTargetted = function(msg) { if (state.isSelected.locked) { state.isSelected.locked = false; } sendChat('TokenResize', '/w gm ' + '&lt;div style="border: 1px solid #666666; background: #ffffee;"&gt;' + 'Tokens can be targetted for resize is now &lt;span style="color: #009900; font-weight: bold;"&gt;On&lt;/span&gt;.' + '&lt;/div&gt;'); }, ch = function(c) { var entities = { '&lt;': 'lt', '&gt;': 'gt', "'": '#39', '@': '#64', '{': '#123', '|': '#124', '}': '#125', '[': '#91', ']': '#93', '"': 'quot', '-': 'mdash', ' ': 'nbsp' }; if (_.has(entities, c)) { return ('&' + entities[c] + ';'); } return ''; }, handleInput = function(msg) { var args, obj, prev; if (msg.type !== "api") { return; } var selected = msg.selected; args = msg.content.split(" "); switch (args[0]) { case '!tr': switch (args[1]) { case '--auto-off': performAutoOff(); break; case '--auto-on': performAutoOn(); break; case '--player-off': performPlayerOff(); break; case '--player-on': performPlayerOn(); break; case '--target-on': isTargetted(); break; case '--target-off': isSelected(); break; } if ('--help' === args[1] || args.length &lt; 2 || state.PlayerResize.locked && !playerIsGM(msg.playerid)) { showHelp(); return; } else if (state.isSelected.locked && !selected) { // Only allows a token to be resized if selected. This prevents players from resizing tokens that don't belong to them. sendChat("", "/desc Select token and try again."); return; // quit if nothing selected } else if(!isNaN(parseFloat(args[1]))) { selected.forEach( function(objselected, objindex, arrayofobjs) { var obj = getObj("graphic", objselected._id) if(typeof obj === 'undefined') return; // sendChat("", "/desc Token named " + obj.get("name") + " was found!"); var ptop = obj.get("top"), pleft = obj.get("left"), pheight = obj.get("height"), hScaleSize = args[1], vScaleSize = args[1], gridSize = 70; if(!isNaN(parseFloat(args[2]))) vScaleSize = args[2]; if ((gridSize * hScaleSize) !== obj.get('width')) { obj.set({ width: (gridSize * hScaleSize) }) if ((gridSize * hScaleSize) &gt; gridSize) { obj.set({ top: (ptop + ((gridSize / 2) * (vScaleSize - (pheight / gridSize)))), left: (pleft + ((gridSize / 2) * (hScaleSize - (pheight / gridSize)))) }) } else { obj.set({ top: (ptop - ((gridSize / 2) * ((pheight / gridSize) - vScaleSize))), left: (pleft - ((gridSize / 2) * ((pheight / gridSize) - hScaleSize))) }) } } if ((gridSize * vScaleSize) !== obj.get('height')) { obj.set({ height: (gridSize * vScaleSize) }) if ((gridSize * vScaleSize) &gt; gridSize) { obj.set({ top: (ptop + ((gridSize / 2) * (vScaleSize - (pheight / gridSize)))), left: (pleft + ((gridSize / 2) * (hScaleSize - (pheight / gridSize)))) }) } else { obj.set({ top: (ptop - ((gridSize / 2) * ((pheight / gridSize) - vScaleSize))), left: (pleft - ((gridSize / 2) * ((pheight / gridSize) - hScaleSize))) }) } } } ); } break; } }, autoChange = function(obj, prev) { if ('card' !== obj.get("subtype") && obj.get("sides") && '' !== obj.get("represents")) { var aid = obj.get("imgsrc"), tid = findObjs({ type: 'tableitem', avatar: aid }, { caseInsensitive: true })[0], weight, pheight, gridSize = 70; if (tid) { weight = tid.get("weight"); pheight = obj.get("height"); if (tid.get("weight") &lt;= 0 || state.AutoResize.locked) { //showHelp(); return; // Even though we use weight for the tile size, let's make sure there is something there to avoid errors. }; if ((gridSize * weight) !== obj.get('width')) { obj.set({ width: (gridSize * weight), height: (gridSize * weight) }); if ((gridSize * weight) &gt; gridSize) { obj.set({ top: (prev.top + ((gridSize / 2) * (weight - (pheight / gridSize)))), left: (prev.left + ((gridSize / 2) * (weight - (pheight / gridSize)))) }) } else { obj.set({ top: (prev.top - ((gridSize / 2) * ((pheight / gridSize) - weight))), left: (prev.left - ((gridSize / 2) * ((pheight / gridSize) - weight))) }) } } else { return; } } } }, showHelp = function() { var playerColor = (state.PlayerResize.locked) ? ('#990000') : ('#009900'), playerName = (state.PlayerResize.locked) ? ('Locked') : ('Unlocked'), autoColor = (state.AutoResize.locked) ? ('#990000') : ('#009900'), autoName = (state.AutoResize.locked) ? ('Locked') : ('Unlocked'), selectColor = (state.isSelected.locked) ? ('#990000') : ('#009900'), selectName = (state.isSelected.locked) ? ('Off') : ('On'); sendChat('TokenResize', '/w gm ' + '&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' + '&lt;div style="font-weight: bold; border-bottom: 1px solid black;font-size: 130%;"&gt;' + 'TokenResize v' + version + '&lt;div style="clear: both"&gt;&lt;/div&gt;' + '&lt;div style="padding-left:10px;padding-top:10px;"&gt;' + '&lt;span style="font-weight:bold; font-size: 70%;"&gt;Player Resize:&lt;/span&gt;&lt;div style="float:right;width:90px;border:1px solid black;background-color:#ffc;text-align:center;font-size: 70%;"&gt;&lt;span style="color: ' + playerColor + '; font-weight:bold; padding: 0px 4px;"&gt;' + playerName + '&lt;/span&gt;&lt;/div&gt;' + '&lt;/div&gt;' + '&lt;div style="padding-left:10px"&gt;' + '&lt;span style="font-weight:bold; font-size: 70%;"&gt;Auto Resize:&lt;/span&gt;&lt;div style="float:right;width:90px;border:1px solid black;background-color:#ffc;text-align:center;font-size: 70%;"&gt;&lt;span style="color: ' + autoColor + '; font-weight:bold; padding: 0px 4px;"&gt;' + autoName + '&lt;/span&gt;&lt;/div&gt;' + '&lt;/div&gt;' + '&lt;div style="padding-left:10px;margin-bottom:10px;"&gt;' + '&lt;span style="font-weight:bold; font-size: 70%;"&gt;Can Target:&lt;/span&gt;&lt;div style="float:right;width:90px;border:1px solid black;background-color:#ffc;text-align:center;font-size: 70%;"&gt;&lt;span style="color: ' + selectColor + '; font-weight:bold; padding: 0px 4px;"&gt;' + selectName + '&lt;/span&gt;&lt;/div&gt;' + '&lt;/div&gt;' + '&lt;div style="clear: both"&gt;&lt;/div&gt;' + '&lt;/div&gt;' + '&lt;div style="padding-left:10px;margin-bottom:10px;margin-top:10px;"&gt;' + '&lt;p&gt;TokenResize allows players to resize their tokens when unlocked.' + '&lt;/div&gt;' + '&lt;b&gt;Commands&lt;/b&gt;' + '&lt;div style="padding-left:10px;"&gt;&lt;b&gt;&lt;span style="font-family: serif;"&gt;!tr&lt;/span&gt;&lt;/b&gt;' + '&lt;div style="padding-left: 10px;padding-right:20px"&gt;' + 'Executing the command with no arguments prints this help. The following arguments may be supplied in order to change the configuration. All changes are persisted between script restarts.' + '&lt;ul&gt;' + '&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;' + '&lt;b&gt;&lt;span style="font-family: serif;"&gt;--player-on&lt;/span&gt;&lt;/b&gt; -- Unlocks TokenResize to allow players to resize tokens.' + '&lt;/li&gt; ' + '&lt;li style="border-bottom: 1px solid #ccc;"&gt;' + '&lt;b&gt;&lt;span style="font-family: serif;"&gt;--player-off&lt;/span&gt;&lt;/b&gt; -- Locks TokenResize and prevents anyone but a GM from resizing tokens.' + '&lt;/li&gt; ' + '&lt;li style="border-bottom: 1px solid #ccc;"&gt;' + '&lt;b&gt;&lt;span style="font-family: serif;"&gt;--auto-on&lt;/span&gt;&lt;/b&gt; -- Unlocks TokenResize to allow resizing of rollable table based tokens, where the size of the token is defined by the weight property.' + '&lt;/li&gt; ' + '&lt;li style="border-bottom: 1px solid #ccc;"&gt;' + '&lt;b&gt;&lt;span style="font-family: serif;"&gt;--auto-off&lt;/span&gt;&lt;/b&gt; -- Locks TokenResize and prevents automatically resizing tokens.' + '&lt;/li&gt; ' + '&lt;li style="border-bottom: 1px solid #ccc;"&gt;' + '&lt;b&gt;&lt;span style="font-family: serif;"&gt;--target-on&lt;/span&gt;&lt;/b&gt; -- A token can be resized when targetting, as well as being selected.' + '&lt;/li&gt; ' + '&lt;li style="border-bottom: 1px solid #ccc;"&gt;' + '&lt;b&gt;&lt;span style="font-family: serif;"&gt;--target-off&lt;/span&gt;&lt;/b&gt; -- A token can only be resized when selected. Using this option allows players to only resize tokens they control.' + '&lt;/li&gt; ' + '&lt;/ul&gt;' + '&lt;b&gt;&lt;span style="font-family: serif;"&gt;Commands to be used when manually resizing:&lt;/span&gt;&lt;/b&gt;' + '&lt;ul&gt;' + '&lt;li style="border-bottom: 1px solid #ccc;"&gt;' + '&lt;b&gt;&lt;span style="font-family: serif;"&gt;' + ch('&lt;') + 'token_id' + ch('&gt;') + '&lt;/span&gt;&lt;/b&gt; -- Select or target the token. Set to select by default.' + '&lt;/li&gt; ' + '&lt;li style="border-bottom: 1px solid #ccc;"&gt;' + '&lt;b&gt;&lt;span style="font-family: serif;"&gt;#&lt;/span&gt;&lt;/b&gt; -- Number of squares across the creature will take up (i.e.: 1=Medium/Small, 2=Large, etc.).' + '&lt;/li&gt; ' + '&lt;/ul&gt;' + '&lt;b&gt;&lt;span style="font-family: serif;"&gt;--help&lt;/span&gt;&lt;/b&gt; -- Entering this, or entering nothing at all after !tr, will bring this help window back.' + '&lt;/div&gt;' + '&lt;/div&gt;' + '&lt;/div&gt;' ); }, CheckInstall = function() { if (!_.has(state, 'AutoResize') || !_.has(state, 'PlayerResize') || !_.has(state, 'isSelected') || TokenResize.version !== schemaVersion) { //Default Settings stored in the state. state.AutoResize = { version: TokenResize.schemaVersion, locked: false }; state.PlayerResize = { version: TokenResize.schemaVersion, locked: false }; state.isSelected = { version: TokenResize.schemaVersion, locked: true }; } }, RegisterEventHandlers = function() { on('change:graphic', autoChange); on('chat:message', handleInput); }; return { RegisterEventHandlers: RegisterEventHandlers, CheckInstall: CheckInstall }; }()); on("ready", function() { 'use strict'; var Has_IsGM = false; try { _.isFunction(isGM); Has_IsGM = true; } catch (err) { log('--------------------------------------------------------------'); log('AutoResize requires the isGM module to work.'); log('isGM GIST: <a href="https://gist.github.com/shdwjk/8d5bb062abab184636" rel="nofollow">https://gist.github.com/shdwjk/8d5bb062abab184636</a>... log('--------------------------------------------------------------'); } if (Has_IsGM) { TokenResize.CheckInstall(); TokenResize.RegisterEventHandlers(); } }); The group simply uses the following macro to resize the token they are currently selecting/targeting (always forget which is which): !tr ?{Horizontal Size} ?{Vertical Size}
1431192698
The Aaron
Pro
API Scripter
Sorry for the delay getting back to you. What ended up being the problem?
1431193005
The Aaron
Pro
API Scripter
What's the original source for this script? I was thinking it was one of mine, but It looks like it's not?
1431193180
The Aaron
Pro
API Scripter
Ah, found it.. <a href="https://app.roll20.net/forum/post/1522903/slug%7D#" rel="nofollow">https://app.roll20.net/forum/post/1522903/slug%7D#</a>...
Yeah, that was it. My friend does Javascript stuff, this was her first time doing anything with Roll20. She said that it looked like the get function was currently undefined in Roll20's API?
1431200683
The Aaron
Pro
API Scripter
Almost. It means the method .get() was being invoked on something that was undefined.
1431315474

Edited 1431316280
I need to work on streamlining this more... Maybe I'll have the time when this semester ends this week, and before my summer semester picks up in 3 weeks....
1431317060

Edited 1431321406
However, if you were setting your argument like that: !tr ?{Horizontal Size} ?{Vertical Size} -- it was going to fail. arg[1] is the &lt;token_id&gt; in the original script. I only designed it to use a singular scale factor for both horizontal and vertical. Thus, the format was: !tr &lt;token_id&gt; #, making arg[0] as !tr, arg[1] as the token_id (through either target or select), and # as the singular scale factor. I just checked, and that worked fine with the original script.
Yeah, this is that script you helped me fix Aaron... stupid single line of code....
1431321139

Edited 1431322060
When did you make edits? I'm asking because the original reads as: args.length &lt; 3 , not args.length &lt; 2 . When you changed that to 2, you lowered the threshold to actually run the script. As such, when parameters weren't being met, it was calling before being defined. As mentioned above, I had 3 arguments being looked for to run the script. Remember, 0 is still an argument. Changing it to 2, it was running the resize portion when there were only 2 arguments in the message. The script was then running getObj("graphic", args[1]) , but there was no &lt;token_id&gt; generated from a select/target. So, anytime you tried to use a command after !tr , e.g.: --target-on , it read that as args[1] , and crashed accordingly. I fixed it to clear that up as follows: handleInput = function(msg) { var args, obj, prev; if (msg.type !== "api") { return; } var selected = msg.selected; args = msg.content.split(" "); switch(args[0]) { case '!tr': switch(args[1]) { case '--auto-off': performAutoOff(); break; case '--auto-on': performAutoOn(); break; case '--player-off': performPlayerOff(); break; case '--player-on': performPlayerOn(); break; case '--target-on': isTargetted(); break; case '--target-off': isSelected(); break; case '--help': showHelp(); break; } if( state.PlayerResize.locked && !playerIsGM(msg.playerid) ) { sendChat("", "/desc Check Player lock."); return; } else if ( state.isSelected.locked && !selected ) { // Only allows a token to be resized if selected. This prevents players from resizing tokens that don't belong to them. sendChat("", "/desc Select token and try again."); return; // quit if nothing selected } else { if(args[2]){ var obj = getObj("graphic", args[1]), ptop = obj.get('top'), pleft = obj.get('left'), pheight = obj.get('height'), scaleSize = args[2], gridSize = 70; if( (gridSize * scaleSize) !== obj.get('width') ) { obj.set({ width: (gridSize * scaleSize), height: (gridSize * scaleSize) }) if( (gridSize * scaleSize) &gt; gridSize ) { obj.set({ top: (ptop + ((gridSize / 2) * (scaleSize - (pheight / gridSize)))), left: (pleft + ((gridSize / 2) * (scaleSize - (pheight / gridSize)))) }) } else { obj.set({ top: (ptop - ((gridSize / 2) * ((pheight / gridSize) - scaleSize))), left: (pleft - ((gridSize / 2) * ((pheight / gridSize) - scaleSize))) }) } }} } break; } }, Granted, this doesn't reflect the changes you made to separate horizontal/vertical scale differences, nor the changes you made for hardcoding the selected token_id lookup. If nothing else, it lets me know I need to make the change to the original script and reminds me to work on cleaning it up in a week.