Last active
July 26, 2018 11:37
-
-
Save bripod/5587911 to your computer and use it in GitHub Desktop.
For keeping track of diminishing fuel for light sources over time.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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