[help] timer.js on("ready", function () {
let lastTime = Date.now();
let lastSecond = Math.floor(lastTime / 1000) * 1000;
let rotPerSec = 360 / 60;
const updateSpeed = 250;
let bar2Splitor = /^(\w|)(\w|)(\w|)(\w|)([.]|)(\w+|)/i;
let bar2numSplitor = [/[-][-](\d+)/i];
let bar2num2Splitor = /[.](\d+)/i;
let bar1max2Splitor = [/[:]([\s\S]+)/i];
const statusLookup = [
"red",
"red,blue",
"red,blue,green",
"red,blue,green,brown",
"red,blue,green,brown,purple",
"red,blue,green,brown,purple,yellow",
"red,blue,green,brown,purple",
"red,blue,green,brown",
"red,blue,green",
"red,blue"
];
const aura1_colorLookup = [
"#ff0000", "#ffff00", "#00ff00", "#0000ff", "#ff00ff"
];
const aura1_radiusLookup = [
"0.7", "0.8", "0.9", "1", "1.1"
];
const doUpdates = () => {
try {
let time = Date.now();
let deltaS = time - lastSecond;
lastTime = time;
findObjs({
type: 'graphic',
bar1_value: 'game.clock'
}, {
caseInsensitive: true
})
.forEach((obj) => {
let key = bar2Splitor.exec(obj.get('bar2_value'));
if (key.indexOf("o") === -1) {
let c = {
bar3_value: obj.get('bar3_value') || "0",
bar2_value: obj.get('bar2_value') || "",
name: obj.get('name') || '00:00:00',
showname: true
};
let sec = parseInt(c.bar3_value);
if (key.indexOf("r") === -1) {
c.rotation =
(((((parseInt(obj.get('bar3_value')) || 0) % 60) * rotPerSec) + (rotPerSec * (deltaS / 1000)) % 360 + 360) % 360) + parseInt(key[6] || 0)
}
else {
c.rotation = parseInt(key[6] || 0);
}
if (key.indexOf("s") === -1) {
let phase = (sec % (statusLookup.length));
c.statusmarkers = statusLookup[phase];
} else {
c.statusmarkers = ""
}
if (key.indexOf("a") === -1) {
let phase = (sec % (aura1_colorLookup.length));
c.aura1_color = aura1_colorLookup[phase];
c.aura1_radius = aura1_radiusLookup[phase];
} else {
c.aura1_radius = ""
}
if (deltaS > 1000) {
++sec;
let h = Math.floor(sec / 3600);
if (h < 10) h = '0' + h;
let m = Math.floor((sec - (h * 60)) / 60);
let s = Math.floor(sec % 60);
c.bar3_value = `${sec}`;
c.name = obj.get('bar1_max') + `${`${h}`}:${`00${m}`.slice(-2)}:${`00${s}`.slice(-2)}`;
}
obj.set(c);
};
});
if (deltaS > 1000) {
lastSecond += 1000;
}
}
catch (e) { }
};
setInterval(
doUpdates,
updateSpeed
);
on('chat:message', (msg) => {
if ('api' === msg.type && /^!game.clock\b/i.test(msg.content)) {
let cmd = msg.content.toLowerCase().split(/\s+/);
let create = cmd.includes('--create') || cmd.includes('-c');
let toggle = cmd.includes('--toggle') || cmd.includes('-t');
let reset = cmd.includes('--reset') || cmd.includes('-re');
let rotation = cmd.includes('--rotation') || cmd.includes('-ro');
let marker = cmd.includes('--marker') || cmd.includes('-m');
let aura = cmd.includes('--aura') || cmd.includes('-a');
let angle = bar2numSplitor.some(check => check.test(cmd));
let name = bar1max2Splitor.some(check => check.test(cmd));
(msg.selected || [])
.map((o) => getObj('graphic', o._id))
.filter(o => undefined !== o)
.filter((o) => create || 'game.clock' === o.get('bar1_value'))
.forEach((o) => {
let c = {};
c.bar2_value = o.get('bar2_value');
if (create) {
c.bar1_value = 'game.clock';
c.showname = true;
//c.bar2_value = 1;
//c.rotation = 0;
//c.statusmarkers = '';
//c.name = '00:00:00';
}
if (reset) {
c.bar3_value = 0;
c.bar2_value = "";
c.rotation = 0;
c.statusmarkers = '';
c.name = '00:00:00';
}
if (toggle) {
c.bar2_value = (c.bar2_value.indexOf("o") === -1 ? 'o' + c.bar2_value : c.bar2_value.replace("o", ""));
}
if (rotation) {
c.bar2_value = (c.bar2_value.indexOf("r") === -1 ? 'r' + c.bar2_value : c.bar2_value.replace("r", ""));
}
if (marker) {
c.bar2_value = (c.bar2_value.indexOf("s") === -1 ? 's' + c.bar2_value : c.bar2_value.replace("s", ""));
}
if (aura) {
c.bar2_value = (c.bar2_value.indexOf("a") === -1 ? 'a' + c.bar2_value : c.bar2_value.replace("a", ""));
}
if (angle) {
c.bar2_value = (c.bar2_value.match(/[.](\d+)/i) ? (c.bar2_value.replace(bar2num2Splitor, "." + msg.content.match(/[-][-](\d+)/i)[1])) : c.bar2_value + "." + msg.content.match(/[-][-](\d+)/i)[1]);
}
if (name) {
c.bar1_max = (msg.content.match(/[:]([\s\S]+)/i)[1]);
}
o.set(c);
});
}
});
}); highlight.js // VARIABLE & FUNCTION DECLARATION
var TurnOrderAgent = TurnOrderAgent || {};
// AnnounceNewRound - Set to TRUE if you want the script to announce
// the beginning of each new round.
var AnnounceNewRound = true;
on("chat:message", function (msg) {
// Exit if not an api command
if (msg.type != "api") return;
// Get the API Chat Command
msg.who = msg.who.replace(" (GM)", "");
msg.content = msg.content.replace("(GM) ", "");
var command = msg.content.split(" ", 1);
if (command == "!eot") {
if (!Campaign().get('turnorder')) return; // Exit if the turn order tracker is not open
var turn_order = JSON.parse(Campaign().get('turnorder')); // Parse the turn order information into JSON
if (!turn_order.length) return; // Exit if there are no tokens on the tracker
var turn = turn_order.shift(); // Grab the info for the top of initiative
turn_order.push({ // Add the info to the bottom of initiative
id: turn.id,
pr: turn.pr,
custom: turn.custom
});
Campaign().set("turnorder", JSON.stringify(turn_order)); // Send the turn order back to the tracker
TurnOrderAgent();
}
});
on("change:campaign:turnorder", function () {
TurnOrderAgent();
});
on("change:graphic:left", function () {
TurnOrderAgent();
});
on("change:graphic:top", function () {
TurnOrderAgent();
});
function TurnOrderAgent() {
try {
if (!Campaign().get("turnorder")) return;
var turn_order = JSON.parse(Campaign().get("turnorder"));
if (!turn_order.length) return;
if (typeof turn_order[0].pr == "string") {
if (turn_order[0].pr.substring(0, 5) == "Round") {
var RoundTracker = turn_order[0].pr;
var CurrentRound = parseInt(RoundTracker.substring(5));
turn_order[0].pr = "Round " + (CurrentRound + 1);
Campaign().set({
turnorder: JSON.stringify(turn_order)
});
if (AnnounceNewRound == true) {
sendChat("", "/desc ");
sendChat("", "/direct <div style='width: 100%; color: #C8DE84; border: 1px solid #91bd09; background-color: #749a02; box-shadow: 0 0 15px #91bd09; display: block; text-align: center; font-size: 20px; padding: 5px 0; margin-bottom: 0.25em; font-family: Garamond;'>" + turn_order[0].pr + "<>");
}
}
}
// Exit script if custom item on turn order tracker instead of a token...
if (turn_order[0].id == -1) return;
var current_token = getObj("graphic", turn_order[0].id);
var initiative_highlighter = findObjs({
name: "InitiativeHighlight",
pageid: current_token.get("pageid")
}, {
caseInsensitive: true
})[0];
if (initiative_highlighter == undefined) {
// sendChat("ERROR", "/w gm Cannot find an initiative highlight token on this page.");
return;
}
if (initiative_highlighter.get("layer") == "gmlayer" && current_token.get("layer") != "gmlayer") {
initiative_highlighter.set({
"top": current_token.get("top"),
"left": current_token.get("left"),
"height": current_token.get("height") + 20,
"width": current_token.get("width") + 20
});
setTimeout(function () {
initiative_highlighter.set({
"layer": current_token.get("layer")
});
}, 500);
} else {
initiative_highlighter.set({
"layer": current_token.get("layer"),
"top": current_token.get("top"),
"left": current_token.get("left"),
"height": current_token.get("height") + 20,
"width": current_token.get("width") + 20
});
}
toFront(current_token);
} catch (e) {
}}; error message TypeError: Cannot read property 'substring' of undefined
TypeError: Cannot read property 'substring' of undefined
at TrackedObj._validateAttrs (/home/node/d20-api-server/api.js:878:26)
at createObj (/home/node/d20-api-server/api.js:2670:23)
at apiscript.js:82:23
at Timeout._onTimeout (apiscript.js:55:12)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)