Want to quickly add in-game time to a simple, intuitive clock? Want to add 6 seconds at the end of each combat round with the click of a button? Look no further. This script allows easy time tracking built into your Roll20 experience, along with a simple timer feature. As with all of my scripts, convenience is the key to keeping grittier, hardcore campaigns running smoothly. ------------------------------------------------------------------------------------------------- Commands: !ttsethour [0-23] - sets the hour !ttsetmin [0-59] - sets the minute of the hour !ttsetsec [0-59] - sets the second of the minute !tttime - whispers the time to the gm !ttaddsec [any integer] - the most important command. This is what you'll use for macros. For example, add a 6-second increase by writing the following in your macro: !ttaddsec 6 Need a 5 minute increment? (great for out of combat searches and the like) !ttaddsec 300 Taking a long rest? Increase the clock an hour at a time with !ttaddsec 3600 !timer [set/rem] (args) - This command sets (or removes) a timer that will follow your time increments !timer set (optional: timer #) [name] [time remaining in hours:mins:secs] ex: !timer set torch 01:00:00 - This will set a timer to track a standard, fresh 5e torch (1 hour) ex: !timer set 3 confused 00:01:00 - This will set timer #3 as "confused" for 1 minute. !timer rem (optional: timer #) - If a particular timer (order) is not specified, it will remove the most recently added timer ex: !timer rem 3 - This would remove the "confused" timer above ... ex: !timer rem - ... and this would remove the torch timer. Timers are automatically removed when their time is elapsed by the clock. ------------------------------------------------------------------------------------------------- Want to plug this in to your script (for a graphical token clock, etc.)? With this script installed, plug these values into any of your scripts: state.alehounds.clock.second state.alehounds.clock.minute state.alehounds.clock.hour ------------------------------------------------------------------------------------------------- v.0.2 (2015-01-05) Significant code reduction, removal of redundancies [bugfix] Set times no longer display erroneous results due to being parsed as strings v.0.1 (2015-01-05) Beta release. Major overhaul and code clean-up Timers added! Timers will automatically count down as time is increased and update in the chat. Changed command to show the current time v.0.0.2 (2015-01-02) Set time now persist across server/script restarts v.0.0.1 (2014-12-01) Alpha release /////////////////////////////////////////////////
/***********************************************/
var MakeYourTime = {
author: {
name: "John C." || "Echo" || "SplenectomY",
company: "Team Asshat" || "The Alehounds",
contact: "<a href="mailto:echo@TeamAsshat.com" rel="nofollow">echo@TeamAsshat.com</a>",
},
version: "0.2",
gist: "<a href="https://gist.github.com/SplenectomY/1f198a3114903d7a3271" rel="nofollow">https://gist.github.com/SplenectomY/1f198a3114903d7a3271</a>",
forum: "<a href="https://app.roll20.net/forum/post/1386741/" rel="nofollow">https://app.roll20.net/forum/post/1386741/</a>",
/***********************************************/
/////////////////////////////////////////////////
setMods: function setMods() {
if(state.alehounds.clock.hour < 10) {
var hour_mod = "0";
} else {
var hour_mod = "";
}
if(state.alehounds.clock.minute < 10) {
var min_mod = "0";
} else {
var min_mod = "";
}
if(state.alehounds.clock.second < 10) {
var sec_mod = "0";
} else {
var sec_mod = "";
}
return "/w gm Time: " + hour_mod + state.alehounds.clock.hour + ":" + min_mod + state.alehounds.clock.minute + ":" + sec_mod + state.alehounds.clock.second + ".";
},
checkError: function checkError(type) {
if (state.alehounds.clock.hour > 23 || state.alehounds.clock.hour < 0) {
if (type = "hour") {
state.alehounds.clock.hour = 0;
}
return "/w gm ERROR: The value must be an integer between 0 and 23";
} else if (state.alehounds.clock.minute > 59 || state.alehounds.clock.second > 59 || state.alehounds.clock.minute < 0 || state.alehounds.clock.second < 0) {
if (type = "minute") {
state.alehounds.clock.minute = 0;
}
else if (type = "second") {
state.alehounds.clock.second = 0;
}
return "/w gm ERROR: The value must be an integer between 0 and 59";
} else return "/w gm Value set.";
}
};
if (!_.has(state, 'alehounds')) {
state.alehounds = {
clock: {
hour: 0,
minute: 0,
second: 0
},
timers: []
};
}
on("chat:message", function(msg) {
var value;
// Begin timer functionality
if(msg.type == "api" && msg.content.indexOf("!timer") !== -1) {
timerArray = msg.content.split(" ");
var command = timerArray[timerArray.indexOf("!timer") + 1];
// Syntax: !timer set [name] (position) [value]
if (command == "set") {
if (timerArray.length == 5) {
position = timerArray[timerArray.indexOf("!timer") + 3]
value = timerArray[timerArray.indexOf("!timer") + 4]
} else {
position = state.alehounds.timers.length
value = String(timerArray[timerArray.indexOf("!timer") + 3])
}
valueArray = value.split(":")
state.alehounds.timers[position] = timerArray[2]
state.alehounds.timers[position] = {
value: (parseInt(valueArray[0]) * 3600) + (parseInt(valueArray[1]) * 60) + parseInt(valueArray[2]),
name: timerArray[2],
}
sendChat(msg.who, "/w gm Timer [" + position + ", " + timerArray[2] + "] set for " + valueArray[0] + ":" + valueArray[1] + ":" + valueArray[2])
// Syntax: !timer rem (position)
} else if (command == "rem") {
if (timerArray.length == 3) {
position = timerArray[timerArray.indexOf("!timer") + 2]
} else {
position = parseInt(state.alehounds.timers.length) - 1
}
sendChat(msg.who, "/w gm Timer [" + position + ", " + state.alehounds.timers[position].name + "] removed.")
state.alehounds.timers.splice(position,1);
}
}
//set the hour of day
if (msg.type == "api" && msg.content.indexOf("!ttsethour ") !== -1) {
state.alehounds.clock.hour = parseInt(msg.content.replace("!ttsethour ", ""));
sendChat(msg.who, MakeYourTime.checkError("hour"));
sendChat(msg.who, MakeYourTime.setMods());
}
//set the minute of the hour
if(msg.type == "api" && msg.content.indexOf("!ttsetmin ") !== -1) {
state.alehounds.clock.minute = parseInt(msg.content.replace("!ttsetmin ", ""));
sendChat(msg.who, MakeYourTime.checkError("minute"));
sendChat(msg.who, MakeYourTime.setMods());
}
//set the second of the minute
if (msg.type == "api" && msg.content.indexOf("!ttsetsec ") !== -1) {
state.alehounds.clock.second = parseInt(msg.content.replace("!ttsetsec ", ""));
sendChat(msg.who, MakeYourTime.checkError("second"));
sendChat(msg.who, MakeYourTime.setMods());
}
//Adjust the seconds by a value
if(msg.type == "api" && msg.content.indexOf("!ttaddsec ") !== -1) {
for (i = 0; i < state.alehounds.timers.length; i++) {
state.alehounds.timers[i].value = state.alehounds.timers[i].value - parseInt(msg.content.replace("!ttaddsec ", ""));
if (state.alehounds.timers[i].value > 0) {
state.alehounds.timers[i].hours = Math.floor(state.alehounds.timers[i].value / 3600);
state.alehounds.timers[i].valueNew = state.alehounds.timers[i].value - (state.alehounds.timers[i].hours * 3600);
state.alehounds.timers[i].mins = Math.floor(state.alehounds.timers[i].valueNew / 60);
state.alehounds.timers[i].valueNew = state.alehounds.timers[i].valueNew - (state.alehounds.timers[i].mins * 60);
if (state.alehounds.timers[i].hours == 0) {
state.alehounds.timers[i].hours = "00"
} else {
state.alehounds.timers[i].hours = String(state.alehounds.timers[i].hours / 100)
if (!state.alehounds.timers[i].hours.charAt(3)) {
state.alehounds.timers[i].hours = state.alehounds.timers[i].hours + "0"
}
}
if (state.alehounds.timers[i].mins == 0) {
state.alehounds.timers[i].mins = "00"
} else {
state.alehounds.timers[i].mins = String(state.alehounds.timers[i].mins / 100)
if (!state.alehounds.timers[i].mins.charAt(3)) {
state.alehounds.timers[i].mins = state.alehounds.timers[i].mins + "0"
}
}
state.alehounds.timers[i].valueNew = String(state.alehounds.timers[i].valueNew / 100);
if (!state.alehounds.timers[i].valueNew.charAt(3)) {
state.alehounds.timers[i].valueNew = state.alehounds.timers[i].valueNew + "0"
}
sendChat(msg.who, "/w gm [" + i + ", " + state.alehounds.timers[i].name + "] : " + state.alehounds.timers[i].hours.replace("0.","") + ":" + state.alehounds.timers[i].mins.replace("0.","") + ":" + state.alehounds.timers[i].valueNew.replace("0.","") + " remains.")
} else {
sendChat(msg.who, "/w gm [" + i + ", " + state.alehounds.timers[i].name + "] has ended!")
state.alehounds.timers.splice(i,1)
}
}
state.alehounds.clock.second = state.alehounds.clock.second + parseInt(msg.content.replace("!ttaddsec ", ""));
//If minutes or seconds are over 60, translate to hours or minutes and add the remainder
if (state.alehounds.clock.second > 59) {
state.alehounds.clock.minute = state.alehounds.clock.minute + Math.floor(state.alehounds.clock.second / 60)
state.alehounds.clock.second = state.alehounds.clock.second - (Math.floor(state.alehounds.clock.second / 60) * 60);
}
if (state.alehounds.clock.minute > 59) {
state.alehounds.clock.hour = state.alehounds.clock.hour + Math.floor(state.alehounds.clock.minute / 60);
state.alehounds.clock.minute = state.alehounds.clock.minute - (Math.floor(state.alehounds.clock.minute / 60) * 60);
}
//If hours are over 23, reset the hour timer and add the remainder
if (state.alehounds.clock.hour > 23) {
state.alehounds.clock.hour = state.alehounds.clock.hour - (Math.floor(state.alehounds.clock.hour / 24) * 24);
}
//Add pretty formatting for single digits
if(state.alehounds.clock.hour < 10) {
var hour_mod = "0";
}
if(state.alehounds.clock.minute < 10) {
var min_mod = "0";
}
if(state.alehounds.clock.second < 10) {
var sec_mod = "0";
}
if(state.alehounds.clock.hour > 9) {
var hour_mod = "";
}
if(state.alehounds.clock.minute > 9) {
var min_mod = "";
}
if(state.alehounds.clock.second > 9) {
var sec_mod = "";
}
sendChat(msg.who, "/w gm Time: " + hour_mod + state.alehounds.clock.hour + ":" + min_mod + state.alehounds.clock.minute + ":" + sec_mod + state.alehounds.clock.second + ".");
}
//Show the in-game time by using !time
if(msg.type == "api" && msg.content.indexOf("!tttime") !== -1) {
if(state.alehounds.clock.hour < 10) {
var hour_mod = "0"
}
if(state.alehounds.clock.minute < 10) {
var min_mod = "0"
}
if(state.alehounds.clock.second < 10) {
var sec_mod = "0"
}
if(state.alehounds.clock.hour > 9) {
var hour_mod = ""
}
if(state.alehounds.clock.minute > 9) {
var min_mod = ""
}
if(state.alehounds.clock.second > 9) {
var sec_mod = ""
}
sendChat(msg.who, "/w gm Time: " + hour_mod + state.alehounds.clock.hour + ":" + min_mod + state.alehounds.clock.minute + ":" + sec_mod + state.alehounds.clock.second + ".");
}
});