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

Torch script and GM status

1497016875
Ulti
Pro
Sheet Author
API Scripter
Hi, there. I really love the Torch script, and the fact that it comes in addition to normal token light. So I wanted to use it for the light spell of one of my players. Unfortunately, only GMs can give token ids as arguments to the !torch command. Would it be possible to add some configuration to the Torch script so that my player can cast a spell of light on one of her friends?
1497017061
Jakob
Sheet Author
API Scripter
Ulti said: Hi, there. I really love the Torch script, and the fact that it comes in addition to normal token light. So I wanted to use it for the light spell of one of my players. Unfortunately, only GMs can give token ids as arguments to the !torch command. Would it be possible to add some configuration to the Torch script so that my player can cast a spell of light on one of her friends? Use TokenMod, it has a setting that allows token ids to be given as arguments, even for players.
1497017370
The Aaron
Pro
API Scripter
Also, Torch affects tokens that are selected even if you aren't a GM.  The intent was to let players adjust the lighting on things they can control, but the GM can do it to anything.
1497019641
Kirsty
Pro
Sheet Author
I use the torch script in all of my games (thank you, Aaron!) and I have a little macro that I make visible to all of my players. I check the "set as token action" box, so it pops up whenever they select a token. That way the players can adjust their own light sources easily. The macro is: ?{Torch|Bullseye Lantern,!torch 120 60 1 @{selected|token_id} --90|Candle,!torch 10 5|Lamp,!torch 45 15|Hooded Lantern (Bright),!torch 60 30|Hooded Lantern (Dim),!torch 5 -5|Torch,!torch 40 20|Off,!snuff} This might not work for your system, but it should at least get you started!
1497019974
The Aaron
Pro
API Scripter
Very nice!  I use a similar macro in my games. =D  (though mine is based on TokenMod... )
1497073789
Ulti
Pro
Sheet Author
API Scripter
The Aaron said: Also, Torch affects tokens that are selected even if you aren't a GM.  The intent was to let players adjust the lighting on things they can control, but the GM can do it to anything. Yes, I used it like that too, but players can only select their own tokens, and I understand the intent. My players are rather well disciplined so far, and the light spell allow the wizard to attach a source of light to anything. So I though that maybe it wouldn't be too hard to have some configuration option for the script to lift that restriction that player can only adjust the lighting on things they can control. But otherwise, I'll make my own copy of your script, or look at TokenMod (although I must say I don't have a clue yet how to use TokenMod such that I can use token ids of non-controlled tokens for Torch...).
1497080117
Jakob
Sheet Author
API Scripter
You don't need Torch at all. TokenMod can set the light for tokens just fine. 1st step: enter !token-mod --help. There's a pink button relatively close to the bottom. Use it to toggle Players can IDs on. 2nd step: use TokenMod with a macro like this !token-mod --set light_radius|45 light_dimradius|25 --ids @{target|token_id}
1497102137
The Aaron
Pro
API Scripter
Ah, then as Jacob said!
1497181941
Ulti
Pro
Sheet Author
API Scripter
Jakob said: You don't need Torch at all. TokenMod can set the light for tokens just fine. 1st step: enter !token-mod --help. There's a pink button relatively close to the bottom. Use it to toggle Players can IDs on. 2nd step: use TokenMod with a macro like this !token-mod --set light_radius|45 light_dimradius|25 --ids @{target|token_id} That's not a good solution, since it overwrites the night vision. That is the main reason why I like Torch so much : you can have separate light sources for a given token.
1497183956

Edited 1497184074
Jakob
Sheet Author
API Scripter
Right, that makes sense. Okay, easy hacky solution to your problem: do a CTRL-F on the Torch source code and replace "playerIsGM(msg.playerid)" by "true".
1497185804
The Aaron
Pro
API Scripter
Ulti said: That's not a good solution, since it overwrites the night vision. That is the main reason why I like Torch so much : you can have separate light sources for a given token. Which version of torch are you using?
1497200680
Ulti
Pro
Sheet Author
API Scripter
I think I use the latest. That is, the one from the one-click install. In the console, it says Torch v0.8.11
1497203053
The Aaron
Pro
API Scripter
Yup, that's the latest. &nbsp;Jakob's Hacky solution is the easiest way to get what you want. &nbsp;Here's a version where that's done: // Github: &nbsp; <a href="https://github.com/shdwjk/Roll20API/blob/master/Torch/Torch.js" rel="nofollow">https://github.com/shdwjk/Roll20API/blob/master/Torch/Torch.js</a> // By: &nbsp; &nbsp; &nbsp; The Aaron, Arcane Scriptomancer // Contact: &nbsp;<a href="https://app.roll20.net/users/104025/the-aaron" rel="nofollow">https://app.roll20.net/users/104025/the-aaron</a> var Torch = Torch || (function() { &nbsp; &nbsp; 'use strict'; &nbsp; &nbsp; var version = '0.8.11-playerfreedom', &nbsp; &nbsp; &nbsp; &nbsp; lastUpdate = 1490871046, &nbsp; &nbsp; &nbsp; &nbsp; schemaVersion = 0.1, flickerURL = '<a href="https://s3.amazonaws.com/files.d20.io/images/4277467/iQYjFOsYC5JsuOPUCI9RGA/thumb.png?1401938659" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/4277467/iQYjFOsYC5JsuOPUCI9RGA/thumb.png?1401938659</a>', flickerPeriod = 400, flickerDeltaLocation = 2, flickerDeltaRadius = 0.1, flickerDeltaAngle = 5, flickerInterval = false, 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 ''; }, showHelp = function(who) { &nbsp; &nbsp; &nbsp; &nbsp; sendChat('', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '/w "'+who+'" '+ &nbsp; &nbsp; '&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="font-weight: bold; border-bottom: 1px solid black;font-size: 130%;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Torch v'+version+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left:10px;margin-bottom:3px;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Torch provides commands for managing dynamic lighting. &nbsp;Supplying a first argument of &lt;b&gt;help&lt;/b&gt; to any of the commands displays this help message, as will calling !torch or !snuff with nothing supplied or selected.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Torch now supports &lt;b&gt;&lt;i&gt;Jack Taylor&lt;/i&gt;&lt;/b&gt; inspired flickering lights. &nbsp;Flicker lights are only active on pages where a player is (GMs, drag yourself to other pages if you don'+ch("'")+'t want to move the party.) and are persisted in the state. &nbsp;Flicker lights can be used in addition to regular lights as they are implemented on a separate invisible token that follows the nomal token.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;Commands&lt;/b&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left:10px;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;!torch '+ch('[')+ch('&lt;')+'Radius'+ch('&gt;')+' '+ch('[')+ch('&lt;')+'Dim Start'+ch('&gt;')+' '+ch('[')+ch('&lt;')+'All Players'+ch('&gt;')+' &nbsp;'+ch('[')+ch('&lt;')+'Token ID'+ch('&gt;')+ch('|')+ch('&lt;')+'--Angle'+ch('&gt;')+' ... '+ch(']')+ch(']')+ch(']')+ch(']')+'&lt;/span&gt;&lt;/b&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Sets the light for the selected/supplied tokens. &nbsp;Only GMs can supply token ids to adjust.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; If you are using multiple '+ch('@')+ch('{')+'target'+ch('|')+'token_id'+ch('}')+' calls in a macro, and need to adjust light on fewer than the supplied number of arguments, simply select the same token several times. &nbsp;The duplicates will be removed.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;'+ch('&lt;')+'Radius'+ch('&gt;')+'&lt;/span&gt;&lt;/b&gt; '+ch('-')+' The radius that the light extends to. (Default: 40)'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/li&gt; '+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;'+ch('&lt;')+'Dim Start'+ch('&gt;')+'&lt;/span&gt;&lt;/b&gt; '+ch('-')+' The radius at which the light begins to dim. (Default: Half of Radius )'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/li&gt; '+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;'+ch('&lt;')+'All Players'+ch('&gt;')+'&lt;/span&gt;&lt;/b&gt; '+ch('-')+' Should all players see the light, or only the controlling players (Darkvision, etc). Specify one of &lt;i&gt;1, on, yes, true, sure, yup, or -&lt;/i&gt; for yes, anything else for no. &nbsp;(Default: yes)'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/li&gt; '+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;'+ch('&lt;')+'Token ID'+ch('&gt;')+'&lt;/span&gt;&lt;/b&gt; '+ch('-')+' A Token ID, usually supplied with something like '+ch('@')+ch('{')+'target'+ch('|')+'Target 1'+ch('|')+'token_id'+ch('}')+'.'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/li&gt; '+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;'+ch('&lt;')+'--Angle'+ch('&gt;')+'&lt;/span&gt;&lt;/b&gt; '+ch('-')+' The angle of the light arc of the light. (Default: 360)'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/li&gt; '+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;!snuff '+ch('[')+ch('&lt;')+'Token ID'+ch('&gt;')+' ... '+ch(']')+'&lt;/span&gt;&lt;/b&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Turns off light for the selected/supplied tokens. Only GMs can supply token ids to adjust.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; If you are using multiple '+ch('@')+ch('{')+'target'+ch('|')+'token_id'+ch('}')+' calls in a macro, and need to adjust light on fewer than the supplied number of arguments, simply select the same token several times. &nbsp;The duplicates will be removed.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;'+ch('&lt;')+'Token ID'+ch('&gt;')+'&lt;/span&gt;&lt;/b&gt; '+ch('-')+' A Token ID, usually supplied with something like '+ch('@')+ch('{')+'target'+ch('|')+'Target 1'+ch('|')+'token_id'+ch('}')+'.'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/li&gt; '+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;!flicker-on '+ch('[')+ch('&lt;')+'Radius'+ch('&gt;')+' '+ch('[')+ch('&lt;')+'Dim Start'+ch('&gt;')+' '+ch('[')+ch('&lt;')+'All Players'+ch('&gt;')+' &nbsp;'+ch('[')+ch('&lt;')+'Token ID'+ch('&gt;')+ch('|')+ch('&lt;')+'--Angle'+ch('&gt;')+' ... '+ch(']')+ch(']')+ch(']')+ch(']')+'&lt;/span&gt;&lt;/b&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Behaves identically to !torch, save that it creates a flickering light.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;!flicker-off '+ch('[')+ch('&lt;')+'Token ID'+ch('&gt;')+' ... '+ch(']')+'&lt;/span&gt;&lt;/b&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Behaves identically to !snuff, save that it affects the flickering light.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;!daytime '+ch('[')+ch('&lt;')+'Token ID'+ch('&gt;')+ch(']')+'&lt;/span&gt;&lt;/b&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Turns off dynamic lighting for the current player page, or the page of the selected/supplied token.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;'+ch('&lt;')+'Token ID'+ch('&gt;')+'&lt;/span&gt;&lt;/b&gt; '+ch('-')+' A Token ID, usually supplied with something like '+ch('@')+ch('{')+'target'+ch('|')+'Target 1'+ch('|')+'token_id'+ch('}')+'.'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/li&gt; '+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;!nighttime '+ch('[')+ch('&lt;')+'Token ID'+ch('&gt;')+ch(']')+'&lt;/span&gt;&lt;/b&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Turns on dynamic lighting for the current player page, or the page of the selected/supplied token.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;'+ch('&lt;')+'Token ID'+ch('&gt;')+'&lt;/span&gt;&lt;/b&gt; '+ch('-')+' A Token ID, usually supplied with something like '+ch('@')+ch('{')+'target'+ch('|')+'Target 1'+ch('|')+'token_id'+ch('}')+'.'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/li&gt; '+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;!global-light '+ch('[')+ch('&lt;')+'Token ID'+ch('&gt;')+ch(']')+'&lt;/span&gt;&lt;/b&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Toggles Global Illumination for the current player page, or the page of the selected/supplied token.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;'+ch('&lt;')+'Token ID'+ch('&gt;')+'&lt;/span&gt;&lt;/b&gt; '+ch('-')+' A Token ID, usually supplied with something like '+ch('@')+ch('{')+'target'+ch('|')+'Target 1'+ch('|')+'token_id'+ch('}')+'.'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/li&gt; '+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; '&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; }, setFlicker = function(o,r,d,p,a) { var found = _.findWhere(state.Torch.flickers, {parent: o.id}), fobj; if( found ) { fobj = getObj('graphic',found.id); if(fobj) { fobj.set({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; layer: 'walls', showname: false, aura1_radius: '', showplayers_aura1: false, light_radius: r, light_dimradius: d, light_otherplayers: p, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_angle: a }); } else { delete state.Torch.flickers[found.id]; } }&nbsp; if(!fobj) { // new flicker fobj =createObj('graphic',{ imgsrc: flickerURL, subtype: 'token', name: 'Flicker', pageid: o.get('pageid'), width: 70, height: 70, top: o.get('top'), left: o.get('left'), layer: 'walls', light_radius: r, light_dimradius: d, light_otherplayers: p, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_angle: a }); } toBack(fobj); state.Torch.flickers[fobj.id]={ id: fobj.id, parent: o.id, active: true, page: o.get('pageid'), light_radius: r, light_dimradius: d, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_angle: a }; }, clearFlicker = function(fid) { var f = getObj('graphic',fid); &nbsp; &nbsp; &nbsp; &nbsp; if(f) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f.remove(); &nbsp; &nbsp; &nbsp; &nbsp; } delete state.Torch.flickers[fid]; }, handleInput = function(msg) { var args, radius, dim_radius, arc_angle=360, other_players, page, obj, objs=[],who; if (msg.type !== "api") { return; } &nbsp; &nbsp; &nbsp; &nbsp; who=(getObj('player',msg.playerid)||{get:()=&gt;'API'}).get('_displayname'); args = msg.content.split(" "); switch(args[0]) { case '!torch': if((args[1]||'').match(/^(--)?help$/) || ( !_.has(msg,'selected') && args.length &lt; 5)) { showHelp(who); return; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; radius = parseInt(args[1],10) || 40; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dim_radius = parseInt(args[2],10) || (radius/2); other_players = _.contains([1,'1','on','yes','true','sure','yup','-'], args[3] || 1 ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objs = _.chain(args) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .rest(4) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .uniq() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(function(a){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var angle=a.match(/^--(\d+)$/); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(angle){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; arc_angle=(Math.min(360,Math.max(0,angle[1]))); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(function(t){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return getObj('graphic',t); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .reject(_.isUndefined) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .value(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(_.union(objs,_.map(msg.selected,function (o) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return getObj(o._type,o._id); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })), function(o){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; o.set({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_radius: radius, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_dimradius: dim_radius, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_otherplayers: other_players, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_angle: arc_angle &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); }); break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case '!snuff': if((args[1]||'').match(/^(--)?help$/) || ( !_.has(msg,'selected') && args.length &lt; 2)) { showHelp(who); return; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.chain(args) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .rest(1) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .uniq() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(function(t){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return getObj('graphic',t); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .reject(_.isUndefined) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .each(function(t) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t.set({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_radius: '', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_dimradius: '', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_otherplayers: false, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_angle: 360 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); _.each(msg.selected,function (o) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getObj(o._type,o._id).set({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_radius: '', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_dimradius: '', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_otherplayers: false, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; light_angle: 360 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; case '!daytime': if((args[1]||'').match(/^(--)?help$/) ) { showHelp(who); return; } if(playerIsGM(msg.playerid)) { if(msg.selected) { obj=getObj('graphic', msg.selected[0]._id); } else if(args[1]) { obj=getObj('graphic', args[1]); } page = getObj('page', (obj && obj.get('pageid')) || Campaign().get('playerpageid')); if(page) { page.set({ showlighting: false }); sendChat('','/w gm It is now &lt;b&gt;Daytime&lt;/b&gt; on '+page.get('name')+'!'); } } break; case '!nighttime': if((args[1]||'').match(/^(--)?help$/) ) { showHelp(who); return; } if(playerIsGM(msg.playerid)) { if(msg.selected) { obj=getObj('graphic',msg.selected[0]._id); } else if(args[1]) { obj=getObj('graphic', args[1]); } page = getObj('page', (obj && obj.get('pageid')) || Campaign().get('playerpageid')); if(page) { page.set({ showlighting: true }); sendChat('','/w gm It is now &lt;b&gt;Nighttime&lt;/b&gt; on '+page.get('name')+'!'); } } break; case '!global-light': if((args[1]||'').match(/^(--)?help$/) ) { showHelp(who); return; } if(playerIsGM(msg.playerid)) { if(msg.selected) { obj=getObj('graphic', msg.selected[0]._id); } else if(args[1]) { obj=getObj('graphic', args[1]); } page = getObj('page', (obj && obj.get('pageid')) || Campaign().get('playerpageid')); if(page) { page.set({ lightglobalillum: !(page.get('lightglobalillum')) }); sendChat('','/w gm Global Illumination is now '+(page.get('lightglobalillum')?'&lt;span style="font-weight:bold;color:#090;"&gt;ON&lt;/span&gt;':'&lt;span style="font-weight:bold;color:#900;"&gt;OFF&lt;/span&gt;' )+' on page &lt;b&gt;'+page.get('name')+'&lt;/b&gt;!'); } } break; case '!flicker-on': if((args[1]||'').match(/^(--)?help$/) || ( !_.has(msg,'selected') && args.length &lt; 5)) { showHelp(who); return; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; radius = parseInt(args[1],10) || 40; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dim_radius = parseInt(args[2],10) || (radius/2); other_players = _.contains([1,'1','on','yes','true','sure','yup','-'], args[3] || 1 ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objs=_.chain(args) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .rest(4) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .uniq() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(function(a){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var angle=a.match(/^--(\d+)$/); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(angle){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; arc_angle=(Math.min(360,Math.max(0,angle[1]))); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(function(t){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return getObj('graphic',t); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .reject(_.isUndefined) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .value(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(_.union(objs,_.map(msg.selected,function (o) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return getObj(o._type,o._id); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })), function(o){ setFlicker(o, radius, dim_radius, other_players,arc_angle); }); break; case '!flicker-off': if((args[1]||'').match(/^(--)?help$/) || ( !_.has(msg,'selected') && args.length &lt; 2)) { showHelp(who); return; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objs=_.chain(args) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .rest(1) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .uniq() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .value(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objs=_.union(objs,_.pluck(msg.selected,'_id')); _.each(state.Torch.flickers, function(f) { if( _.contains(objs, f.parent)) { clearFlicker(f.id); } }); break; } }, animateFlicker = function() { var pages = _.union([Campaign().get('playerpageid')], _.values(Campaign().get('playerspecificpages'))); _.chain(state.Torch.flickers) .where({active:true}) .filter(function(o){ return _.contains(pages,o.page); }) .each(function(fdata){ var o = getObj('graphic',fdata.parent), f = getObj('graphic',fdata.id), dx, dy, dr, da; if(!o) { clearFlicker(fdata.id); } else { if(!f) { delete state.Torch.flickers[fdata.id]; } else { dx = randomInteger(2 * flickerDeltaLocation)-flickerDeltaLocation; dy = randomInteger(2 * flickerDeltaLocation)-flickerDeltaLocation; dr = randomInteger(2 * (fdata.light_radius*flickerDeltaRadius)) - (fdata.light_radius*flickerDeltaRadius); da = randomInteger(2 * flickerDeltaAngle)-flickerDeltaAngle; f.set({ top: o.get('top')+dy, left: o.get('left')+dx, light_radius: fdata.light_radius+dr, light_angle: ((360 === fdata.light_angle) ? (360) : (Math.min(360,Math.max(fdata.light_angle+da,0)))) || 360, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rotation: o.get('rotation') }); } } }); }, handleTokenDelete = function(obj) { var found = _.findWhere(state.Torch.flickers, {parent: obj.id}); if(found) { clearFlicker(found.id); } else { found = _.findWhere(state.Torch.flickers, {id: obj.id}); if(found) { delete state.Torch.flickers[obj.id]; } } }, checkInstall = function() { &nbsp; &nbsp; &nbsp; &nbsp; log('-=&gt; Torch v'+version+' &lt;=- &nbsp;['+(new Date(lastUpdate*1000))+']'); &nbsp; &nbsp; &nbsp; &nbsp; if( ! _.has(state,'Torch') || state.Torch.version !== schemaVersion) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log(' &nbsp;&gt; Updating Schema to v'+schemaVersion+' &lt;'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* Default Settings stored in the state. */ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.Torch = { version: schemaVersion, flickers: {} }; } flickerInterval = setInterval(animateFlicker,flickerPeriod); }, registerEventHandlers = function() { on('chat:message', handleInput); on('destroy:graphic', handleTokenDelete); }; return { CheckInstall: checkInstall, RegisterEventHandlers: registerEventHandlers }; }()); on("ready",function(){ 'use strict'; Torch.CheckInstall(); Torch.RegisterEventHandlers(); }); I'll try to get a config added at some point to allow that...
1497203538
Ulti
Pro
Sheet Author
API Scripter
Many thanks, you break the back of the work for me :)
1497204364
The Aaron
Pro
API Scripter
Well, this was more like the World's Sister's half-brother's pinky toe.. but no problem! &nbsp;=D Happy Rolling!