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

Hex facing Script

I am wondering if a script writer can look at this. I have used this script for years off of Roll20 that was written by someone. I have been getting an infinite loop error lately and now the script will not work at all even after loading a new game and reinstalling my scripts. Can someone look at it an maybe offer some help. It is now having the facing ring appear for a moment and then vanish. &nbsp;Facing // Github: <a href="https://github.com/shdwjk/Roll20API/blob/master/Facing/Facing.js" rel="nofollow">https://github.com/shdwjk/Roll20API/blob/master/Facing/Facing.js</a> // By: The Aaron, Arcane Scriptomancer // Contact: <a href="https://app.roll20.net/users/104025/the-aaron" rel="nofollow">https://app.roll20.net/users/104025/the-aaron</a> var Facing = Facing || (function() { 'use strict'; var version = '0.1.3', lastUpdate = 1490707181, schemaVersion = 0.1, defaults = { image: '<a href="https://s3.amazonaws.com/files.d20.io/images/9183999/XcViJVf7-cGOXcZq1KWp-A/thumb.png?1430541914" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/9183999/XcViJVf7-cGOXcZq1KWp-A/thumb.png?1430541914</a>', attributeName: 'facing', scale: 2.5 }, checkInstall = function() { log('-=&gt; Facing v'+version+' &lt;=- ['+(new Date(lastUpdate*1000))+']'); if( ! _.has(state,'Facing') || state.Facing.version !== schemaVersion) { log(' &gt; Updating Schema to v'+schemaVersion+' &lt;'); switch(state.Facing &amp;&amp; state.Facing.version) { case 0: default: state.Facing = { version: schemaVersion, config: { image: defaults.image, attributeName: defaults.attributeName, relative: true, scale: defaults.scale }, ringed: {} }; break; } } }, ch = function (c) { var entities = { '&lt;' : 'lt', '&gt;' : 'gt', "'" : '#39', '@' : '#64', '{' : '#123', '|' : '#124', '}' : '#125', '[' : '#91', ']' : '#93', '"' : 'quot', '-' : 'mdash', ' ' : 'nbsp' }; if(_.has(entities,c) ){ return ('&amp;'+entities[c]+';'); } return ''; }, getCleanImgsrc = function (imgsrc) { var parts = imgsrc.match(/(.*\/images\/.*)(thumb|max)(.*)$/); if(parts) { return parts[1]+'thumb'+parts[3]; } return; }, getRingedPair = function(id) { var ringed; _.find(state.Facing.ringed,function(slaveid,masterid){ if(id === masterid || id === slaveid) { ringed = { master: getObj('graphic',masterid), slave: getObj('graphic',slaveid) }; ringed.attribute = findObjs({ type: 'attribute', name: state.Facing.config.attributeName, characterid: ringed.master &amp;&amp; ringed.master.get('represents') })[0] || {set:function(){}}; return true; } return false; }); return ringed; }, getRinged = function(id) { var ringed; _.find(state.Facing.ringed,function(slaveid,masterid){ if(id === masterid){ ringed = getObj('graphic',slaveid); return true; } if(id === slaveid) { ringed = getObj('graphic',masterid); return true; } return false; }); return ringed; }, createRinged = function(id) { // get root obj var master = getObj('graphic',id), slave = getRinged(id), layer, dim; if(!slave &amp;&amp; master) { layer=( 'gmlayer' === master.get('layer') ? 'gmlayer' : 'map'); dim=(Math.max(master.get('height'),master.get('width'))*state.Facing.config.scale); slave = createObj('graphic',{ imgsrc: state.Facing.config.image, layer: layer, pageid: master.get('pageid'), top: master.get('top'), left: master.get('left'), height: dim, width: dim, rotation: master.get('rotation') }); master.set({ rotation: 0 }); ( findObjs({ type: 'attribute', name: state.Facing.config.attributeName, characterid: master.get('represents') })[0] || (master.get('represents') &amp;&amp; createObj('attribute',{ name: state.Facing.config.attributeName, characterid: master.get('represents') })) || { set: function(){} }).set({ current: slave.get('rotation') }); if('gmlayer' === layer) { toBack(slave); } else { toFront(slave); } state.Facing.ringed[master.id]=slave.id; } }, removeRinged = function(id) { var pair=getRingedPair(id); if(pair) { if(id === pair.master.id ) { pair.slave.remove(); } delete state.Facing.ringed[pair.master.id]; } }, zeroToken = function(id) { var pair=getRingedPair(id); if(pair) { pair.slave.set({ rotation: 0 }); } }, facingToken = function(id) { var pair=getRingedPair(id); if(pair) { removeRinged(id); } else { createRinged(id); } }, handleRemoveToken = function(obj) { // special handling for deleting slaves? removeRinged(obj.id); }, handleTokenChange = function(obj,prev) { var pair = getRingedPair(obj.id), layer, dim, rot; if(pair) { if(pair.master.id === obj.id) { layer=( 'gmlayer' === pair.master.get('layer') ? 'gmlayer' : 'map'); dim=(Math.max(pair.master.get('height'),pair.master.get('width'))*state.Facing.config.scale); rot=pair.master.get('rotation'); if(rot !== prev.rotation ) { if(state.Facing.config.relative) { rot = (pair.slave.get('rotation') + rot + 360) % 360; } } else { rot = pair.slave.get('rotation'); } pair.attribute.set({ current: rot }); pair.slave.set({ layer: layer, top: pair.master.get('top'), left: pair.master.get('left'), height: dim, width: dim, rotation: rot }); pair.master.set({ rotation: 0 }); if('gmlayer' === layer) { toBack(pair.slave); } else { toFront(pair.slave); } } else { pair.slave.set({ width: prev.width, height: prev.height, top: prev.top, left: prev.left, layer: prev.layer, flipv: prev.flipv, fliph: prev.fliph }); pair.attribute.set({ current: pair.slave.get('rotation') }); } } }, getConfigOption_RingImage = function() { var text = state.Facing.config.image; return '&lt;div&gt;'+ 'Direction Indicator:'+ '&lt;img src="'+text+'" style="width: 70px; height: 70px;"&gt;'+ '&lt;a href="!facing-config --set-image|@{target|token_id}"&gt;'+ 'Pick'+ '&lt;/a&gt;'+ '&lt;a href="!facing-config --set-image|"&gt;'+ 'Default'+ '&lt;/a&gt;'+ '&lt;/div&gt;'; }, getConfigOption_AttributeName = function() { var text = state.Facing.config.attributeName; return '&lt;div&gt;'+ 'Attribute Name to set facing value: &lt;b&gt;'+ text+ '&lt;/b&gt;&lt;a href="!facing-config --set-attribute-name|?{What attribute should the facing be stored in (empty for default):|'+state.Facing.config.attributeName+'}"&gt;'+ 'Set Name'+ '&lt;/a&gt;'+ '&lt;/div&gt;'; }, getConfigOption_Relative = function() { var text = (state.Facing.config.relative ? 'On' : 'Off' ); return '&lt;div&gt;'+ 'Relative Rotation is currently &lt;b&gt;'+ text+ '&lt;/b&gt; '+ '&lt;a href="!facing-config --toggle-relative"&gt;'+ 'Toggle'+ '&lt;/a&gt;'+ '&lt;/div&gt;'; }, getConfigOption_Scale = function() { var text = state.Facing.config.scale; return '&lt;div&gt;'+ 'Scale is currently &lt;b&gt;'+ text+ '&lt;/b&gt; '+ '&lt;a href="!facing-config --set-scale|?{Scale to adjust Facing Token to (empty for default):|'+state.Facing.config.scale+'}"&gt;'+ 'Set'+ '&lt;/a&gt;'+ '&lt;/div&gt;'; }, getAllConfigOptions = function() { return getConfigOption_RingImage()+ getConfigOption_AttributeName()+ getConfigOption_Relative()+ getConfigOption_Scale(); }, showHelp = function(who) { sendChat('','/w "'+who+'" ' +'&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;' +'Facing v'+version +'&lt;/div&gt;' +'&lt;div style="padding-left:10px;margin-bottom:3px;"&gt;' +'&lt;p&gt;Facing adds a ring below the selected token with a pointer for the direction the token is facing. Rotating the token will rotate the ring and then the token will reset to no rotation. If the token is associated with a character, Facing will maintain an attribute on the character with the current facing stored in it.&lt;/p&gt;' +'&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;!facing [--help]&lt;/span&gt;&lt;/b&gt;' +'&lt;div style="padding-left: 10px;padding-right:20px"&gt;' +'&lt;p&gt;Adds or removes the Facing ring below a token.&lt;/p&gt;' +'&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;--help&lt;/span&gt;&lt;/b&gt; '+ch('-')+' Shows the Help screen' +'&lt;/li&gt; ' +'&lt;/ul&gt;' +'&lt;/div&gt;' +'&lt;/div&gt;' +'&lt;div style="padding-left:10px;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;!zero [--help]&lt;/span&gt;&lt;/b&gt;' +'&lt;div style="padding-left: 10px;padding-right:20px"&gt;' +'&lt;p&gt;Aligns the indicator to north.&lt;/p&gt;' +'&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;--help&lt;/span&gt;&lt;/b&gt; '+ch('-')+' Shows the Help screen' +'&lt;/li&gt; ' +'&lt;/ul&gt;' +'&lt;/div&gt;' +'&lt;/div&gt;' +getAllConfigOptions() +'&lt;/div&gt;' ); }, handleInput = function(msg) { var args, who; if (msg.type !== "api" ) { return; } who=(getObj('player',msg.playerid)||{get:()=&gt;'API'}).get('_displayname'); args = msg.content.split(/\s+/); switch(args.shift()) { case '!facing': if(!msg.selected || _.contains(args,'--help')) { showHelp(who); return; } _.each(msg.selected,function(s){ facingToken(s._id,who); }); break; case '!zero': if(!msg.selected || _.contains(args,'--help')) { showHelp(who); return; } _.each(msg.selected,function(s){ zeroToken(s._id,who); }); break; case '!facing-config': if(!playerIsGM(msg.playerid)) { sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +'&lt;div&gt;&lt;b&gt;Error:&lt;/b&gt; Only the GM may configure Facing.&lt;/div&gt;' +'&lt;/div&gt;' ); return; } if(_.contains(args,'--help')) { showHelp(who); return; } if(!args.length) { sendChat('','/w "'+who+'" ' +'&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;' +'Facing v'+version +'&lt;/div&gt;' +getAllConfigOptions() +'&lt;/div&gt;' ); return; } _.each(args,function(a){ var opt=a.split(/\|/), tmp,omsg=''; switch(opt.shift()) { case '--set-image': if(opt.length &amp;&amp; opt[0].length) { tmp=getObj('graphic',opt[0]); if(tmp &amp;&amp; getCleanImgsrc(tmp.get('imgsrc')) ) { state.Facing.config.image = getCleanImgsrc(tmp.get('imgsrc')); } else { omsg='&lt;div&gt;&lt;b&gt;Error:&lt;/b&gt; '+ ( tmp ? 'Cannot use Marketplace Images.' : 'Not a valid ID: '+opt[0]) +'&lt;/div&gt;'; } } else { state.Facing.config.image = defaults.image; } sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +omsg +getConfigOption_RingImage() +'&lt;/div&gt;' ); break; case '--set-attribute-name': if(opt.length &amp;&amp; opt[0].length) { state.Facing.config.attributeName = opt[0]; } else { state.Facing.config.attributeName = defaults.attributeName; } sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +getConfigOption_AttributeName() +'&lt;/div&gt;' ); break; case '--toggle-relative': state.Facing.config.relative=!state.Facing.config.relative; sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +getConfigOption_Relative() +'&lt;/div&gt;' ); break; case '--set-scale': if(opt.length &amp;&amp; opt[0].length) { tmp = parseFloat(opt[0]); if(tmp) { state.Facing.config.scale = tmp; } else { omsg='&lt;div&gt;&lt;b&gt;Error:&lt;/b&gt; Not a valid number: '+opt[0]+'&lt;/div&gt;'; } } else { state.Facing.config.scale = defaults.scale; } sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +omsg +getConfigOption_Scale() +'&lt;/div&gt;' ); break; default: sendChat('','/w "'+who+'" ' +'&lt;div&gt;&lt;b&gt;Unsupported Option:&lt;/div&gt; '+a+'&lt;/div&gt;' ); } }); break; } }, registerEventHandlers = function() { on('chat:message', handleInput); on('change:graphic', handleTokenChange); on('destroy:graphic', handleRemoveToken); }; return { CheckInstall: checkInstall, RegisterEventHandlers: registerEventHandlers }; }()); on('ready',function() { 'use strict'; Facing.CheckInstall(); Facing.RegisterEventHandlers(); });
Update to the above: Disabled sheet detector and it seems better will see if that works.
1676077743
The Aaron
Roll20 Production Team
API Scripter
My latest version (v0.1.6) is here:&nbsp; <a href="https://github.com/shdwjk/Roll20API/blob/master/Facing/Facing.js" rel="nofollow">https://github.com/shdwjk/Roll20API/blob/master/Facing/Facing.js</a> Try that and see if it works?