Skip to content

Instantly share code, notes, and snippets.

@bripod
Last active July 26, 2018 11:37
Show Gist options
  • Save bripod/5587911 to your computer and use it in GitHub Desktop.
Save bripod/5587911 to your computer and use it in GitHub Desktop.
For keeping track of diminishing fuel for light sources over time.
// Time and Torch Tracker
// roll20 API script for tracking time elapsed in rounds or turns, and tracking
// consumption of finite light sources
// The basics:
// The script assumes that any tokens on the current player page with the "All Players See Light"
// button checked is a light source that will gradually run out of fuel.
// As the fuel is reduced, the light will shrink and grow dim, and players will get a message
// when a light source goes from one stage to the next -- normal, dim, flickering, and about to go out.
// Chat commands are used to advance or reset the round counter, or to check how much time has passed.
// To set a token as a light source:
// - Set "All Players See Light" on the token used for the light source.
// - bar1_max indicates the maximum burning time of a fresh torch or a full lantern, and is the
// - basis for determining when to switch to the next state
// - bar1_value indicates the burn time remaining
// - bar2_value is used to indicate whether the light source is on (1) or off (2). When this is
// changed, the light source will be updated.
// - bar2_max is set to "1" to help identify light source tokens (though this may be overkill)
// Chat commands:
// !time: display the time elapsed in hours and minutes
// !time x: set the time elapsed to x minutes.
// !r x: advance time elapsed by 1 round (= 1 minute)
// !t x: advance time elapsed by 1 turn (= 10 minutes)
function updateLights(lightSource,elapsedTime) {
var lightSourceName = lightSource.get("name");
var brightRadius = lightSource.get("bar3_max");
var dimRadius = lightSource.get("bar3_value");
var burningTimeTotal = lightSource.get("bar1_max");
var burningTimeRemaining = lightSource.get("bar1_value");
var trigger_dim = Math.floor(burningTimeTotal * 0.3);
var trigger_flicker = Math.floor(burningTimeTotal * 0.15);
var trigger_almostOut = Math.floor(burningTimeTotal * 0.05);
var newBurningTimeRemaining = burningTimeRemaining - (1.0 * elapsedTime);
if (burningTimeRemaining == 0 || lightSource.get("bar2_value") == 0) return; // make sure light source is lit & has fuel remaining
if (newBurningTimeRemaining >= trigger_dim && lightSource.get("light_radius") !== brightRadius) {
lightSource.set({ light_radius: brightRadius, light_dimradius: dimRadius});
} else if (newBurningTimeRemaining <= trigger_dim && newBurningTimeRemaining > trigger_flicker && (burningTimeRemaining > trigger_dim || burningTimeRemaining == newBurningTimeRemaining)) {
sendChat("","/emas " + lightSourceName + " grows dim. ");
lightSource.set({ light_dimradius: Math.floor(dimRadius * 0.66)});
} else if (newBurningTimeRemaining <= trigger_flicker && newBurningTimeRemaining > trigger_almostOut && (burningTimeRemaining > trigger_flicker || burningTimeRemaining == newBurningTimeRemaining)) {
sendChat("","/emas " + lightSourceName + " begins to flicker. ");
lightSource.set({ light_radius: Math.floor(brightRadius * 0.75), light_dimradius: Math.floor(dimRadius * 0.5)});
} else if (newBurningTimeRemaining <= trigger_almostOut && newBurningTimeRemaining > 0&& (burningTimeRemaining > trigger_almostOut || burningTimeRemaining == newBurningTimeRemaining)) {
sendChat("","/emas " + lightSourceName + " is about to go out. ");
lightSource.set({ light_radius: Math.floor(brightRadius * 0.5), light_dimradius: 0 });
} else if (newBurningTimeRemaining <= 0) {
newBurningTimeRemaining = 0;
sendChat("","/emas " + lightSourceName + " goes out!");
lightSource.set({
bar2_value: 0,
light_radius: "",
light_dimradius: ""
});
};
lightSource.set({
bar1_value: newBurningTimeRemaining
});
};
function getLights(numRounds) {
var playerVisibleLights = filterObjs(function(obj) {
if(obj.get("_pageid") == Campaign().get("playerpageid") && obj.get("_subtype") == "token" && obj.get("bar2_value") == "1" && obj.get("bar2_max") == "1" && obj.get("light_otherplayers") == true) return true;
else return false;
});
_.each(playerVisibleLights, function(obj) {
updateLights(obj,numRounds);
});
};
function displayTimeElapsed(numRounds) {
sendChat("Chronos","/w gm " + Math.floor(state.timeElapsed / 60) + " hours, " + Math.floor(state.timeElapsed % 60) + " minutes.");
}
function moveTimer(numRounds) {
state.timeElapsed = parseInt(state.timeElapsed) + parseInt(numRounds);
getLights(numRounds);
}
on('ready', function(){
state.timeElapsed = 0;
});
on("chat:message", function(msg) {
if (msg.type == "api" && msg.who.indexOf("(GM)") !== -1 && msg.content.indexOf("!time") !== -1) {
var n = msg.content.split(" ", 2);
if (n.length == 2 && isNaN(n[1]) == false) { // i.e., "!time x" where "x" is a number
state.timeElapsed = n[1];
};
displayTimeElapsed();
};
if (msg.type == "api" && msg.who.indexOf("(GM)") !== -1 && msg.content.indexOf("!r ") !== -1) {
var n = msg.content.split(" ", 2)
var numRounds = n[1].toLowerCase();
moveTimer(numRounds);
};
if (msg.type == "api" && msg.who.indexOf("(GM)") !== -1 && msg.content.indexOf("!t ") !== -1) {
var n = msg.content.split(" ", 2)
var numRounds = n[1].toLowerCase() * 10;
moveTimer(numRounds);
};
});
on("change:graphic:bar1_value", function(obj) {
if (obj.get("_pageid") == Campaign().get("playerpageid") && obj.get("_subtype") == "token" && obj.get("bar2_max") == "1" && obj.get("light_otherplayers") == true) {
var maxValue = obj.get("bar1_max");
if (obj.get("bar1_value") < maxValue ) {
obj.set({bar1_value: maxValue});
};
updateLights(obj,0);
};
});
on("change:graphic:bar2_value", function(obj) {
if (obj.get("_pageid") == Campaign().get("playerpageid") && obj.get("_subtype") == "token" && obj.get("bar2_max") == "1" && obj.get("light_otherplayers") == true) {
if (obj.get("bar2_value") > 0 ) {
if (obj.get("bar1_value") > 0) {
obj.set({bar2_value: 1});
} else {
obj.set({bar2_value: 0})
};
updateLights(obj,0);
} else if (obj.get("bar2_value") <= 0 ) {
obj.set({bar2_value: 0});
obj.set({light_radius: "",light_dimradius: ""});
};
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment