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

[Help] Torch script and darkvision

August 05 (6 years ago)

Edited August 05 (6 years ago)

So I recently got pro and have been adding features to my campaign rapidly one of which is proving problematic however. I am attempting to use Aarons torch script for the convenient lighting of torches candles and lanterns however all but one of my players has darkvison. The current setup i have been using for player vision is for each person with dark vision to emit light for 30ft that is dim starting at 0ft and that only they can see. They all have a vision multiplier of x2 to try and make map light sources interact with dark vision properly. however this is making conveniently lighting torches and the like difficult as whenever I try and set the players back to dark vision with the script IE snuff then add a new light source matching the baseline the start of dim radius always defaults to half of the maximum radius instead of the defined variable. The macro is set up as : !Torch 30 0 false and then the command for at specific token which I can't remember off the top of my head. The other issue is that darkvison appears to be worded so that the player can see 60ft in darkness beyond the furthest source of dim light so if a torch emits 40ft of light 20 of which is bright and 20 is dim the player with darkvison can see 40ft of bright light then another 60ft of dim light. 

Currently I am just using characters acting as torches to be light sources however whenever my players move them they tend to just fly around the map randomly instead of following them. Would the Carry token script be a good idea for this? If so how can I easily add and remove the torches with a macro? 

Summary of questions:

Do I need to have seperate macros for dark vision and non darkvison players? 

Should I just find a way to give my Lizardfolk paladin dark vision so everyone has it?

Would a different script work better? 

How can I force the script to accept 0 as the starting radius for dim light? 

Ditch torch and just use carry token  and a torch character? 

August 05 (6 years ago)
The Aaron
Roll20 Production Team
API Scripter

Hmm. Try using:

!torch 30 -5 no

The only option for the "sees farther in dim light" is the multiplier, if x2 doesn't cut it, there isn't much that can be done about it in the API. Carry script can be a good option for having dark vision and a torch. 

You probably need different macros for different visions. I use a TokenMod macro that has quite a few options, you can find it in the forums or I can dig it out later tonight. I'll try to go through this post again and recreate your specific use cases. There's probably a bug in Torch with using 0 for dim radius. 

Yeah that sounds like a bit of a bug I'll do some testing but the more I think about it the more I think I have been over thinking it honestly. I'll take another look at it tonight and see if the -5 fixes things thanks for the suggestion! 

August 06 (6 years ago)

Edited August 06 (6 years ago)
The Aaron
Roll20 Production Team
API Scripter

Ok, found the bug, here's an updated version:

// Github:   https://github.com/shdwjk/Roll20API/blob/master/Torch/Torch.js
// By:       The Aaron, Arcane Scriptomancer
// Contact:  https://app.roll20.net/users/104025/the-aaron

const Torch = (() => { // eslint-disable-line no-unused-vars

    const version = '0.8.13';
    const lastUpdate = 1565053382;
    const schemaVersion = 0.1;
	const flickerURL = 'https://s3.amazonaws.com/files.d20.io/images/4277467/iQYjFOsYC5JsuOPUCI9RGA/thumb.png?1401938659';
	const flickerPeriod = 400;
	const flickerDeltaLocation = 2;
	const flickerDeltaRadius = 0.1;
	const flickerDeltaAngle = 5;

    const ch = (c) => {
        const entities = {
            '<' : 'lt',
            '>' : 'gt',
            "'" : '#39',
            '@' : '#64',
            '{' : '#123',
            '|' : '#124',
            '}' : '#125',
            '[' : '#91',
            ']' : '#93',
            '"' : 'quot',
            '*' : 'ast',
            '/' : 'sol',
            ' ' : 'nbsp'
        };

        if( entities.hasOwnProperty(c) ){
            return `&${entities[c]};`;
        }
        return '';
    };

	const showHelp = (who) => {
        sendChat('',
            '/w "'+who+'" '+
    '<div style="border: 1px solid black; background-color: white; padding: 3px 3px;">'+
        '<div style="font-weight: bold; border-bottom: 1px solid black;font-size: 130%;">'+
            'Torch v'+version+
        '</div>'+
        '<div style="padding-left:10px;margin-bottom:3px;">'+
            '<p>Torch provides commands for managing dynamic lighting.  Supplying a first argument of <b>help</b> to any of the commands displays this help message, as will calling !torch or !snuff with nothing supplied or selected.</p>'+
            '<p>Torch now supports <b><i>Jack Taylor</i></b> inspired flickering lights.  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.  Flicker lights can be used in addition to regular lights as they are implemented on a separate invisible token that follows the nomal token.</p>'+
        '</div>'+
        '<b>Commands</b>'+
        '<div style="padding-left:10px;">'+
            '<b><span style="font-family: serif;">!torch '+ch('[')+ch('<')+'Radius'+ch('>')+' '+ch('[')+ch('<')+'Dim Start'+ch('>')+' '+ch('[')+ch('<')+'All Players'+ch('>')+'  '+ch('[')+ch('<')+'Token ID'+ch('>')+ch('|')+ch('<')+'--Angle'+ch('>')+' ... '+ch(']')+ch(']')+ch(']')+ch(']')+'</span></b>'+
            '<div style="padding-left: 10px;padding-right:20px">'+
                '<p>Sets the light for the selected/supplied tokens.  Only GMs can supply token ids to adjust.</p>'+
                '<p><b>Note:</b> 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.  The duplicates will be removed.</p>'+
                '<ul>'+
                    '<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'+
                        '<b><span style="font-family: serif;">'+ch('<')+'Radius'+ch('>')+'</span></b> '+ch('-')+' The radius that the light extends to. (Default: 40)'+
                    '</li> '+
                    '<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'+
                        '<b><span style="font-family: serif;">'+ch('<')+'Dim Start'+ch('>')+'</span></b> '+ch('-')+' The radius at which the light begins to dim. (Default: Half of Radius )'+
                    '</li> '+
                    '<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'+
                        '<b><span style="font-family: serif;">'+ch('<')+'All Players'+ch('>')+'</span></b> '+ch('-')+' Should all players see the light, or only the controlling players (Darkvision, etc). Specify one of <i>1, on, yes, true, sure, yup, or -</i> for yes, anything else for no.  (Default: yes)'+
                    '</li> '+
                    '<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'+
                        '<b><span style="font-family: serif;">'+ch('<')+'Token ID'+ch('>')+'</span></b> '+ch('-')+' A Token ID, usually supplied with something like '+ch('@')+ch('{')+'target'+ch('|')+'Target 1'+ch('|')+'token_id'+ch('}')+'.'+
                    '</li> '+
                    '<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'+
                        '<b><span style="font-family: serif;">'+ch('<')+'--Angle'+ch('>')+'</span></b> '+ch('-')+' The angle of the light arc of the light. (Default: 360)'+
                    '</li> '+
                '</ul>'+
            '</div>'+
            '<b><span style="font-family: serif;">!snuff '+ch('[')+ch('<')+'Token ID'+ch('>')+' ... '+ch(']')+'</span></b>'+
            '<div style="padding-left: 10px;padding-right:20px">'+
                '<p>Turns off light for the selected/supplied tokens. Only GMs can supply token ids to adjust.</p>'+
                '<p><b>Note:</b> 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.  The duplicates will be removed.</p>'+
                '<ul>'+
                    '<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'+
                        '<b><span style="font-family: serif;">'+ch('<')+'Token ID'+ch('>')+'</span></b> '+ch('-')+' A Token ID, usually supplied with something like '+ch('@')+ch('{')+'target'+ch('|')+'Target 1'+ch('|')+'token_id'+ch('}')+'.'+
                    '</li> '+
                '</ul>'+
            '</div>'+
            '<b><span style="font-family: serif;">!flicker-on '+ch('[')+ch('<')+'Radius'+ch('>')+' '+ch('[')+ch('<')+'Dim Start'+ch('>')+' '+ch('[')+ch('<')+'All Players'+ch('>')+'  '+ch('[')+ch('<')+'Token ID'+ch('>')+ch('|')+ch('<')+'--Angle'+ch('>')+' ... '+ch(']')+ch(']')+ch(']')+ch(']')+'</span></b>'+
            '<div style="padding-left: 10px;padding-right:20px">'+
                '<p>Behaves identically to !torch, save that it creates a flickering light.</p>'+
            '</div>'+
            '<b><span style="font-family: serif;">!flicker-off '+ch('[')+ch('<')+'Token ID'+ch('>')+' ... '+ch(']')+'</span></b>'+
            '<div style="padding-left: 10px;padding-right:20px">'+
                '<p>Behaves identically to !snuff, save that it affects the flickering light.</p>'+
            '</div>'+
            '<b><span style="font-family: serif;">!daytime '+ch('[')+ch('<')+'Token ID'+ch('>')+ch(']')+'</span></b>'+
            '<div style="padding-left: 10px;padding-right:20px">'+
                '<p>Turns off dynamic lighting for the current player page, or the page of the selected/supplied token.</p>'+
                '<ul>'+
                    '<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'+
                        '<b><span style="font-family: serif;">'+ch('<')+'Token ID'+ch('>')+'</span></b> '+ch('-')+' A Token ID, usually supplied with something like '+ch('@')+ch('{')+'target'+ch('|')+'Target 1'+ch('|')+'token_id'+ch('}')+'.'+
                    '</li> '+
                '</ul>'+
            '</div>'+
            '<b><span style="font-family: serif;">!nighttime '+ch('[')+ch('<')+'Token ID'+ch('>')+ch(']')+'</span></b>'+
            '<div style="padding-left: 10px;padding-right:20px">'+
                '<p>Turns on dynamic lighting for the current player page, or the page of the selected/supplied token.</p>'+
                '<ul>'+
                    '<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'+
                        '<b><span style="font-family: serif;">'+ch('<')+'Token ID'+ch('>')+'</span></b> '+ch('-')+' A Token ID, usually supplied with something like '+ch('@')+ch('{')+'target'+ch('|')+'Target 1'+ch('|')+'token_id'+ch('}')+'.'+
                    '</li> '+
                '</ul>'+
            '</div>'+
            '<b><span style="font-family: serif;">!global-light '+ch('[')+ch('<')+'Token ID'+ch('>')+ch(']')+'</span></b>'+
            '<div style="padding-left: 10px;padding-right:20px">'+
                '<p>Toggles Global Illumination for the current player page, or the page of the selected/supplied token.</p>'+
                '<ul>'+
                    '<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'+
                        '<b><span style="font-family: serif;">'+ch('<')+'Token ID'+ch('>')+'</span></b> '+ch('-')+' A Token ID, usually supplied with something like '+ch('@')+ch('{')+'target'+ch('|')+'Target 1'+ch('|')+'token_id'+ch('}')+'.'+
                    '</li> '+
                '</ul>'+
            '</div>'+
        '</div>'+
    '</div>'
            );
    };
	const setFlicker = (o,r,d,p,a) => {
		let found = _.findWhere(state.Torch.flickers, {parent: o.id});
		let fobj;

		if( found ) {
			fobj = getObj('graphic',found.id);
			if(fobj) {
				fobj.set({
                    layer: 'walls',
					showname: false,
					aura1_radius: '',
					showplayers_aura1: false,
					light_radius: r,
					light_dimradius: d,
					light_otherplayers: p,
                    light_angle: a
				});
			} else {
				delete state.Torch.flickers[found.id];
			}
		} 
		
		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,
                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,
            light_angle: a

		};
	};

	const clearFlicker = (fid) => {
		const f = getObj('graphic',fid);
        if(f) {
            f.remove();
        }
		delete state.Torch.flickers[fid];
	};
	
	const handleInput = (msg) => {
		let radius, dim_radius, arc_angle=360, other_players, page, objs=[];

		if (msg.type !== "api") {
			return;
		}
        let whoChar = (getObj('player',msg.playerid)||{get:()=>'API'});
        let who=whoChar.get('_displayname');

		let args = msg.content.split(" ");
		switch(args[0]) {
			case '!torch':
				if((args[1]||'').match(/^(--)?help$/) || ( !_.has(msg,'selected') && args.length < 5)) {
					showHelp(who);
					return;
				}
                radius = parseInt(args[1],10) || 40;
                dim_radius = ( (undefined === args[2] || '-' === args[2]) ? (radius/2) : parseInt(args[2],10) );
				other_players = _.contains([1,'1','on','yes','true','sure','yup','-'], args[3] || 1 );

                objs = _.chain(args)
                    .rest(4)
                    .uniq()
                    .filter(function(a){
                        let angle=a.match(/^--(\d+)$/);
                        if(angle){
                            arc_angle=(Math.min(360,Math.max(0,angle[1])));
                            return false;
                        }
                        return true;
                    })
                    .map(function(t){
                        return getObj('graphic',t);
                    })
                    .filter(()=>playerIsGM(msg.playerid))
                    .reject(_.isUndefined)
                    .value();

                _.each(_.union(objs,_.map(msg.selected,function (o) {
                    return getObj(o._type,o._id);
                })), function(o){
                    o.set({
                        light_radius: radius,
                        light_dimradius: dim_radius,
                        light_otherplayers: other_players,
                        light_angle: arc_angle
                    });
				});
				break;

            case '!snuff':
				if((args[1]||'').match(/^(--)?help$/) || ( !_.has(msg,'selected') && args.length < 2)) {
					showHelp(who);
					return;
				}

				if(playerIsGM(msg.playerid)) {
					_.chain(args)
						.rest(1)
						.uniq()
						.map(function(t){
							return getObj('graphic',t);
						})
						.reject(_.isUndefined)
						.each(function(t) {
							t.set({
								light_radius: '',
								light_dimradius: '',
								light_otherplayers: false,
                                light_angle: 360
							});
						});
				}
				_.each(msg.selected,function (o) {
                    getObj(o._type,o._id).set({
                        light_radius: '',
                        light_dimradius: '',
                        light_otherplayers: false,
                        light_angle: 360
                    });
                });
                break;

			case '!daytime':
				if((args[1]||'').match(/^(--)?help$/) ) {
					showHelp(who);
					return;
				}
				if(playerIsGM(msg.playerid)) {
                    page = getObj('page', whoChar.get('lastpage'));

					if(page) {
						page.set({
							showlighting: false
						});
						sendChat('','/w gm It is now <b>Daytime</b> on '+page.get('name')+'!');
					}
				}
				break;

			case '!nighttime':
				if((args[1]||'').match(/^(--)?help$/) ) {
					showHelp(who);
					return;
				}
				if(playerIsGM(msg.playerid)) {
                    page = getObj('page', whoChar.get('lastpage'));

					if(page) {
						page.set({
							showlighting: true
						});
						sendChat('','/w gm It is now <b>Nighttime</b> on '+page.get('name')+'!');
					}
				}
				break;

			case '!global-light':
				if((args[1]||'').match(/^(--)?help$/) ) {
					showHelp(who);
					return;
				}
				if(playerIsGM(msg.playerid)) {
                    page = getObj('page', whoChar.get('lastpage'));

					if(page) {
						page.set({
							lightglobalillum: !(page.get('lightglobalillum'))
						});
						sendChat('','/w gm Global Illumination is now '+(page.get('lightglobalillum')?'<span style="font-weight:bold;color:#090;">ON</span>':'<span style="font-weight:bold;color:#900;">OFF</span>' )+' on page <b>'+page.get('name')+'</b>!');
					}
				}
				break;

			case '!flicker-on':
				if((args[1]||'').match(/^(--)?help$/) || ( !_.has(msg,'selected') && args.length < 5)) {
					showHelp(who);
					return;
				}
                radius = parseInt(args[1],10) || 40;
                dim_radius = ( (undefined === args[2] || '-' === args[2]) ? (radius/2) : parseInt(args[2],10) );
				other_players = _.contains([1,'1','on','yes','true','sure','yup','-'], args[3] || 1 );

                objs=_.chain(args)
                    .rest(4)
                    .uniq()
                    .filter(function(a){
                        let angle=a.match(/^--(\d+)$/);
                        if(angle){
                            arc_angle=(Math.min(360,Math.max(0,angle[1])));
                            return false;
                        }
                        return true;
                    })
                    .filter(()=>playerIsGM(msg.playerid))
                    .map(function(t){
                        return getObj('graphic',t);
                    })
                    .reject(_.isUndefined)
                    .value();

                _.each(_.union(objs,_.map(msg.selected,function (o) {
                    return getObj(o._type,o._id);
                })), 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 < 2)) {
					showHelp(who);
					return;
				}
                
				if(playerIsGM(msg.playerid)) {
					objs=_.chain(args)
						.rest(1)
						.uniq()
						.value();
				}
                objs=_.union(objs,_.pluck(msg.selected,'_id'));
				_.each(state.Torch.flickers, function(f) {
					if( _.contains(objs, f.parent)) {
						clearFlicker(f.id);
					}
				});
				break;

		}
	};

    const getActivePages = () => [...new Set([
        Campaign().get('playerpageid'),
        ...Object.values(Campaign().get('playerspecificpages')),
        ...findObjs({
                type: 'player',
                online: true
            })
            .filter((p)=>playerIsGM(p.id))
            .map((p)=>p.get('lastpage'))
        ])
    ];

	const animateFlicker = () => {
		let pages = getActivePages();

		_.chain(state.Torch.flickers)
			.where({active:true})
			.filter(function(o){
				return _.contains(pages,o.page);
			})
			.each(function(fdata){
				let 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,
                            rotation: o.get('rotation')
						});
					}
				}
			});
	};

	const handleTokenDelete = (obj) => {
		let 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];
			}
		}
	};

	const checkInstall = () => {
        log('-=> Torch v'+version+' <=-  ['+(new Date(lastUpdate*1000))+']');

        if( ! _.has(state,'Torch') || state.Torch.version !== schemaVersion) {
            log('  > Updating Schema to v'+schemaVersion+' <');
            /* Default Settings stored in the state. */
            state.Torch = {
				version: schemaVersion,
				flickers: {}
			};
		}

		setInterval(animateFlicker,flickerPeriod);
	};

	const registerEventHandlers = () => {
		on('chat:message', handleInput);
		on('destroy:graphic', handleTokenDelete);
	};

    on("ready",() => {
        checkInstall();
        registerEventHandlers();
    });

	return { };
})();

August 06 (6 years ago)
The Aaron
Roll20 Production Team
API Scripter

I've pushed it up as a pull request, hopefully it will get in the one-click soon.

August 06 (6 years ago)

Edited August 06 (6 years ago)
The Aaron
Roll20 Production Team
API Scripter

Here's the TokenMod command I use for Vision selection.  I give this to my players so they can manage it themselves, YMMV.

!token-mod --set ?{Vision|Torch, light_radius#40 light_dimradius#20 light_hassight#yes light_angle#360 light_otherplayers#yes|Hooded Lantern, light_radius#60 light_dimradius#30 light_hassight#yes light_angle#360 light_otherplayers#yes|Bullseye Lantern, light_radius#120 light_dimradius#60 light_angle#60 light_hassight#yes light_otherplayers#yes|Lamp, light_radius#30 light_dimradius#15 light_hassight#yes light_angle#360 light_otherplayers#yes|Candle, light_radius#5 light_dimradius#=0 light_hassight#yes light_angle#360 light_otherplayers#yes|Darkvision (30'), light_radius#30 light_dimradius#=-5 light_hassight#yes light_angle#360 light_otherplayers#no|Darkvision (60'), light_radius#60 light_dimradius#=-5 light_hassight#yes light_angle#360 light_otherplayers#no|Darkvision (90'), light_radius#90 light_dimradius#=-5 light_hassight#yes light_angle#360 light_otherplayers#no|Warlock Devil's Sight, light_radius#120 light_dimradius#=120 light_hassight#yes light_angle#360 light_otherplayers#no|No light source(Dusk), light_radius#120 light_dimradius#=-5 light_hassight#yes light_angle#360 light_otherplayers#no|Fog, light_radius#200 light_dimradius#=5 light_hassight#yes light_angle#360 light_otherplayers#no|No light source, light_radius#5 light_dimradius#=-5 light_hassight#yes light_angle#360 light_otherplayers#no|Blinded, light_hassight#no light_angle#360 light_otherplayers#no}


August 07 (6 years ago)
The Aaron
Roll20 Production Team
API Scripter

This version of Torch is now in the 1-Click installs.

August 07 (6 years ago)
keithcurtis
Forum Champion
Marketplace Creator
API Scripter


The Aaron said:

Here's the TokenMod command I use for Vision selection.  I give this to my players so they can manage it themselves, YMMV.

!token-mod --set ?{Vision|Torch, light_radius#40 light_dimradius#20 light_hassight#yes light_angle#360 light_otherplayers#yes|Hooded Lantern, light_radius#60 light_dimradius#30 light_hassight#yes light_angle#360 light_otherplayers#yes|Bullseye Lantern, light_radius#120 light_dimradius#60 light_angle#60 light_hassight#yes light_otherplayers#yes|Lamp, light_radius#30 light_dimradius#15 light_hassight#yes light_angle#360 light_otherplayers#yes|Candle, light_radius#5 light_dimradius#=0 light_hassight#yes light_angle#360 light_otherplayers#yes|Darkvision (30'), light_radius#30 light_dimradius#=-5 light_hassight#yes light_angle#360 light_otherplayers#no|Darkvision (60'), light_radius#60 light_dimradius#=-5 light_hassight#yes light_angle#360 light_otherplayers#no|Darkvision (90'), light_radius#90 light_dimradius#=-5 light_hassight#yes light_angle#360 light_otherplayers#no|Warlock Devil's Sight, light_radius#120 light_dimradius#=120 light_hassight#yes light_angle#360 light_otherplayers#no|No light source(Dusk), light_radius#120 light_dimradius#=-5 light_hassight#yes light_angle#360 light_otherplayers#no|Fog, light_radius#200 light_dimradius#=5 light_hassight#yes light_angle#360 light_otherplayers#no|No light source, light_radius#5 light_dimradius#=-5 light_hassight#yes light_angle#360 light_otherplayers#no|Blinded, light_hassight#no light_angle#360 light_otherplayers#no}


You let your players control their own vision? Mine would find some way to totally mess that up.

August 07 (6 years ago)
The Aaron
Roll20 Production Team
API Scripter

Yeah.. It's usually me that ends up doing it, but it's pretty hard to mess up the drop down. =D

Unless you don't have your token selected.. lately I've been adding the --ids @{target|token_id} to the end to make it more obvious...

August 07 (6 years ago)
keithcurtis
Forum Champion
Marketplace Creator
API Scripter

I meant more they'd wind up blinding themselves, and then panic. I prefer to be the lighting and sound director.

Thanks for all the help Aaron glad you managed to find the big and get the one click working!