Lightning / thunder effect Original Source: <a href="https://app.roll20.net/forum/post/9061191/lightningfx-script/?pageforid=9061191#post-9061191" rel="nofollow">https://app.roll20.net/forum/post/9061191/lightningfx-script/?pageforid=9061191#post-9061191</a> Updated by someone else for UDL: <a href="https://app.roll20.net/forum/post/9518550/slug%7D" rel="nofollow">https://app.roll20.net/forum/post/9518550/slug%7D</a> So the code i ended up having looks like this const LightningFX = (() => {
const scriptName = "LightningFX";
const version = '0.1';
var globalKill = true;
const LIGHT_NAME = 'Lightning';
const checkInstall = function() {
log(scriptName + ' v' + version + ' initialized.');
};
const flashOff = function(src) {
src.set('bright_light_distance', 0);
src.set('low_light_distance', 0);
src.set('emits_bright_light', false);
src.set('emits_low_light', false);
}
const flashOn = function(src, dim, timeout) {
let rand = Math.random() * timeout;
if (dim) {
src.set('emits_bright_light', false);
src.set('emits_low_light', true);
src.set('low_light_distance', 500);
src.set('bright_light_distance', 0);
} else {
src.set('emits_bright_light', true);
src.set('emits_low_light', false);
src.set('bright_light_distance', 500);
}
setTimeout(flashOff, rand, src);
}
const handleFX = function(sources, minInterval, maxInterval, maxDuration, active) {
let dim = false;
if (active) {
let rand = Math.floor(Math.random() * (maxInterval - minInterval + 1) + minInterval);
if ( randomInteger(2) === 2 ) {
dim = true;
} else {
dim = false;
}
setTimeout(function() {
sources.forEach((src) => {
flashOn(src, dim, maxDuration);
});
if (!globalKill) { handleFX(sources, minInterval, maxInterval, maxDuration, true); }
}, rand);
} else {
sources.forEach((src) => {
flashOff(src);
});
}
}
const handleInput = function(msg) {
//set defaults
let minInterval = 200;
let maxInterval = 10000;
let maxDuration = 400;
try {
if(msg.type=="api" && msg.content.indexOf("!lightning") === 0 && playerIsGM(msg.playerid)) {
who = getObj('player',msg.playerid).get('_displayname');
let cmd = msg.content.split((/\s+/));
cmd.shift();
switch (cmd.length) {
case 0:
//no commands, do nothing
sendChat('Lightning',`/w "${who}" `+ 'No commands given to !Lightning script');
break;
case 1:
//on or off
break;
case 2:
//minInterval
minInterval = parseInt(cmd[1])
break;
case 3:
//minInterval maxInterval
minInterval = parseInt(cmd[1])
maxInterval = parseInt(cmd[2])
break;
case 4:
default:
//minInterval maxInterval maxDuration
minInterval = parseInt(cmd[1])
maxInterval = parseInt(cmd[2])
maxDuration = parseInt(cmd[3])
break;
}
if ( isNaN(minInterval) || isNaN(maxInterval) || isNaN(maxDuration) ) {
sendChat('Lightning',`/w "${who}" `+ 'Error. Non-Numeric timer settings detected');
return;
}
var sources = findObjs({
_pageid: Campaign().get("playerpageid"),
_type: "graphic",
name: LIGHT_NAME
});
if (!sources) {
sendChat('Lightning',`/w "${who}" `+ 'No Lightning Sources on Player Page!');
globalKill = true;
return;
}
switch (cmd[0].toLowerCase()) {
case "on":
//TURN ON FX
globalKill = false;
handleFX(sources, minInterval, maxInterval, maxDuration, true);
break;
case "off":
//TURN OFF FX
globalKill = true;
handleFX(sources, minInterval, maxInterval, maxDuration, false);
break;
default:
sendChat('Lightning',`/w "${who}" `+ 'Unrecognized command. Expected Lighting \"on\" or \"off\"');
return;
}
}
}
catch(err) {
sendChat('Lightning',`/w "${who}" `+ 'Unhandled exception: ' + err.message);
}
};
const registerEventHandlers = function() {
on('chat:message', handleInput);
};
on("ready",() => {
checkInstall();
registerEventHandlers();
});
})(); But after doing !lightning on or !lightning on 400 nothing happens I placed a transparent token, double clicked it - named it "Lightning" and I see nothing happening