`;
const openReport = `
`;
const closeReport = `
`;
const manualWarning = `
S`;
const spacer = `
`;
const stop = `
`;
const caution = `
`;
const go = `
`;
const HR = `
`;
//BUTTON: TOGGLE FOR PAGE PROPERTIES
const toggle = (size, value, pageProperty) => {
//if (pageProperty === "daylight_mode_enabled"){log ("daylight_mode_enabled = " + value)};
let toggleButton = '';
if (size === "large" && (value === true || value === "true" || value === "basic")) {
toggleButton = onButtonLarge
}
if (size === "large" && value === false) {
toggleButton = offButtonLarge
}
if (size === "small" && (value === true || value === "true" || value === "basic")) {
toggleButton = onButtonSmall
}
if (size === "small" && value === false) {
toggleButton = offButtonSmall
}
if (undefined === pageProperty) {
pageProperty = '';
}
let finalButton = `
${toggleButton}`;
if (pageProperty === "explorer_mode") {
finalButton = `
${((value === "basic") ? onButtonSmall : offButtonSmall)}`;
}
return finalButton;
};
//BUTTON: COLOR PICKETR CALLING BUTTON
const colorButton = (pageOrToken, property, value) => {
if (null === value) value = "transparent";
if (property === "gridcolor" && !value.includes("#")) value = "#"+value;
let finalButton = `
`;
return finalButton;
};
//BUTTON: TOGGLE FOR TOKEN PROPERTIES
const toggleToken = (value, tokenProperty, offCode, onCode) => {
let toggleButton = '';
let buttonCode;
if (value === true || value === "true" || value === "on") {
toggleButton = onButtonSmall;
buttonCode = offCode;
} else {
toggleButton = offButtonSmall;
buttonCode = onCode;
}
if (undefined === tokenProperty) {
tokenProperty = '';
}
let finalButton = `
${toggleButton}`;
return finalButton;
};
//BUTTON: TOGGLE FOR CONFIG PROPERTIES
const toggleConfig = (value, configPropertyName) => {
let toggleButton = '';
let buttonCode;
if (value=== true){
toggleButton = onButtonSmall;
buttonCode = "!dltool --"+configPropertyName;
}else {
toggleButton = offButtonSmall;
buttonCode = "!dltool --"+configPropertyName;
}
let finalButton = `
${toggleButton}`;
return finalButton;
};
//BUTTON: GENERIC FOR DLTOOL
const dlButton = (label, link) => {
let finalButton = `
${label}`;
return finalButton;
};
//BUTTON: SMALL INLINE BUTTON -- dropped, but keep if needed in future
/* const dlSmallButton = (label, link) => {
let finalButton = `
${label}`;
return finalButton;
};
*/
//BUTTON: TOKEN LIGHT PRESETS
const lightButton = (label, dimLight, brightLight, arc, onCode) => {
let totalLight = dimLight + brightLight;
let cautionText = ((label.includes("Bullseye")) ? " Due to a bug in the Roll20 Mod Script system, you may need to open and close the token settings manually for the changes to take effect." : "");
let finalButton = ``;
let conditionalStyle = onStyle;
let conditonalLink = `!token-mod --set emits_bright_light|off emits_low_light|off light_angle|360${repeatCommand} --report`;
if (tokenData.get("low_light_distance") === totalLight && tokenData.get("bright_light_distance") === brightLight && tokenData.get("directional_bright_light_total") === arc) {
if (tokenData.get("emits_bright_light") === false) {
conditionalStyle = disableStyle;
conditonalLink = "!token-mod --set emits_bright_light|on emits_low_light|on light_angle|360" + repeatCommand + " --report";
}
finalButton = `
${label}`;
} else {
finalButton = `
${label}`;
}
return finalButton;
};
const visionButton = (label, has_bright_light_vision, has_night_vision, night_vision_distance, hoverText) => {
let finalButton = ``;
let conditonalLink = `!token-mod --set emits_bright_light|off emits_low_light|off light_angle|360${repeatCommand} --report`;
if (tokenData.get("has_bright_light_vision") === has_bright_light_vision && tokenData.get("has_night_vision") === has_night_vision && tokenData.get("night_vision_distance") === night_vision_distance) {
conditonalLink = "!token-mod --set has_bright_light_vision|false has_night_vision|false " + repeatCommand;
finalButton = `
${label}`;
} else {
conditonalLink = "!token-mod --set has_bright_light_vision|" + has_bright_light_vision + " has_night_vision|" + has_night_vision + " night_vision_distance|" + night_vision_distance + ((night_vision_distance === 60) ? " night_vision_effect|nocturnal" : " ") + repeatCommand;
finalButton = `
${label}`;
}
return finalButton;
};
//SET VALUE BUTTON FOR ANY
const setValue = (value, property, setCode) => {
//Edge cases and Roll20 bug correctors
if (value === '') {
value = "0";
}
if (value === null) {
value = "None";
}
if (value === undefined) {
value = " - ";
}
let openTitle = "";
let closeTitle = "";
if (property === "night_vision_effect") {
switch (value) {
case "None":
openTitle = `
`;
closeTitle = ``;
break;
case "Nocturnal":
openTitle = `
`;
closeTitle = ``;
break;
default: {
let dimmingDistance = parseFloat(tokenData.get('night_vision_effect').replace(/^Dimming_/, '')) || 0;
dimmingDistance = Math.round(dimmingDistance * tokenData.get('night_vision_distance'));
openTitle = `
`;
closeTitle = `` +
`
Dimming Distance starts at: ${openTitle}${dimmingDistance}${closeTitle}`;
value = "Dimming";
}
}
}
if (property === "fog_opacity" || property === "daylightModeOpacity" || property === "dim_light_opacity") {
value = value * 100; //for display. We want the user to see percentages, not decimals
}
let finalButton = `${openTitle}
${value}${closeTitle}`;
return finalButton;
};
//GENERATES A LABEL WITH HOVERTEXT
const label = (phrase, helptext) => {
let finalLabel = `
${phrase}`;
return finalLabel;
};
//GENERATES PICTOS CHARACTER
const pictos = (character, color) => {
let pictosChar = `
${character}`;
return pictosChar;
};
//GENERATES Arc of Light
const lightArc = (degrees) => {
let imgPosition = `style= "position:relative; top:-2px;" `;
let finalButton = "";
if (degrees < 361) {
finalButton = `

`;
}
if (degrees < 290) {
finalButton = `

`;
}
if (degrees < 220) {
finalButton = `

`;
}
if (degrees < 150) {
finalButton = `

`;
}
if (degrees === 0) {
finalButton = `

`;
}
return finalButton;
};
const getGMPlayers = (pageid) => findObjs({
type: 'player'
})
.filter((p) => playerIsGM(p.id))
.filter((p) => undefined === pageid || p.get('lastpage') === pageid)
.map(p => p.id);
//BECAUSE ROLL20
const stringToBoolean = function(string) {
switch (string.toLowerCase().trim()) {
case "true":
case "yes":
case "1":
return true;
case "false":
case "no":
case "0":
case null:
return false;
default:
return Boolean(string);
}
};
//UTILITY INFO BLOCK
let gmUtilityInfo = openSection +
((tokenData !== '') ? dlButton("Why can't this token see?", "!dltool --report|checklist") : dlButton("Why can't this token see?", "!dltool --report|checklist")) +
dlButton("Config", "!dltool --report|config") +
dlButton("Other things to check for", "!dltool --checklist") +
dlButton("Help Center", "https://help.roll20.net/hc/en-us/articles/360045793374-Dynamic-Lighting-Requirements-Best-Practices") + ` ` +
dlButton("DL Report ", "!dltool --report") + ` | ` + dlButton("Vision", "!dltool --report|vision") + dlButton("Light", "!dltool --report|light") + dlButton("Page", "!dltool --report|page") + dlButton(" + ", "!dltool --report|extra") +
(isProd? "
Prod Wiz: "+dlButton("Main Menu ", "!prod") + " " +dlButton("Map Menu ", "!prod map") : "")+
`
`;
let utilityInfo = gmUtilityInfo;
on('chat:message', (msg) => {
if ('api' !== msg.type) {
return;
}
msg.content = processInlinerolls(msg);
let msgTxt = msg.content;
repeatCommand = `
!dltool`;
let pageData = getObj('page', getPageForPlayer(msg.playerid));
if (msg.content.match(/report\|extra/m)) {
repeatCommand = `
!dltool --report|extra`;
}
if (msg.content.match(/report\|setscale/m)) {
repeatCommand = `
!dltool --report|setscale`;
}
if (msg.content.match(/report\|light/m)) {
repeatCommand = `
!dltool --report|light`;
}
if (msg.content.match(/report\|vision/m)) {
repeatCommand = `
!dltool --report|vision`;
}
if (msg.content.match(/report\|page/m)) {
repeatCommand = `
!dltool --report|page`;
}
//let repeatCommandChecklist = `
!dltool --report|checklist`;
//BUTTON: DAYLIGHT PRESETS
const daylightButton = (label, value, code) => {
let finalButton = "";
let conditionalStyle = onStyle;
if (pageData.get("daylightModeOpacity") * 100 === value) {
if (pageData.get("daylight_mode_enabled") === false) {
conditionalStyle = disableStyle;
}
finalButton = `
`;
}
return finalButton;
};
//BUTTON: GRID PRESETS
const gridButton = (label, cellwidth, color, transparency, code) => {
let finalButton = "";
let conditionalStyle = onStyle;
if (pageData.get("grid_opacity") === transparency) {
conditionalStyle = onStyle;
finalButton = `
`;
}
return finalButton;
};
const cellWidthButton = (label, value, code) => {
let finalButton = "";
let conditionalStyle = onStyle;
if (pageData.get("snapping_increment") === value) {
if (pageData.get("snapping_increment") !== value) {
conditionalStyle = disableStyle;
}
finalButton = `
`;
}
return finalButton;
};
//MESSAGE HANDLING
// if ((msg.type == "api" && msgTxt.indexOf(cmdName) !== -1 && playerIsGM(msg.playerid)) || (msgTxt === "!dltool --pcchecklist")) {
if (msg.type == "api" && msgTxt.indexOf(cmdName) !== -1) {
let APIMessage = msg.content;
if (APIMessage === "!dltool" || APIMessage === "!dltools") {
APIMessage = "!dltool --report";
}
let args = APIMessage.split(/\s--/);
// let commands = args[1].split(/\s+/);
let commands = args[1].match(/(?:[^\s"]+|"[^"]*")+/g);
let theMessage = args[2];
let checkLightButton = "";
tokenData = '';
if (msg.selected) {
tokenData = getObj('graphic', msg.selected[0]._id);
if(!tokenData) {
tokenData ='';
}
}
pageData.set('force_lighting_refresh', true);
commands.forEach(c => {
theCommand = c.split(/\|/)[0];
theOption = c.split(/\|/)[1];
let checklistTokenInfo;
let pagePlusInfo;
let scaleInfo;
//CASES FOR COMMANDS
switch (theCommand) {
//CASE - REPORT
case 'report': {
//FULL REPORT
//VISION SECTON
if (tokenData !== '') {
let lightData = '';
if (typeof checkLightLevel !== "undefined") {
lightData = checkLightLevel.isLitBy(tokenData.get("id"));
checkLightButton = HR +
"
" +
dlButton("Report", "!checklight");
} else {
checkLightButton = '
' + dlButton("Check Amount of Light on the Token", "!dltool --message --If you want this functionality, you will need to install checkLightLevel, an external script by Oosh. You can find it in One Click install on your Mod page.");
}
let controllerNames = "";
let controllers = '';
let char = false;
if (tokenData.get("represents")) {
char = ((tokenData.get("represents")) ? getObj("character", tokenData.get("represents")) : false);
} else {
char = false;
}
if (char) {
controllers = char.get("controlledby").split(",");
if (char.get("controlledby")) {
controllers.forEach(c => {
controllerNames = controllerNames + ((c === "all") ? "All players" : getObj("player", c).get("_displayname")) + " • ";
});
}
} else {
controllers = tokenData.get("controlledby").split(",");
if (tokenData.get("controlledby")) {
controllers.forEach(c => {
controllerNames = controllerNames + ((c === "all") ? "All players" : getObj("player", c).get("_displayname")) + " • ";
});
}
}
controllerNames = controllerNames + "•";
controllerNames = controllerNames.split(" • •")[0].replace(/\s•\s/g, ", ").replace(/•/, "");
if (controllerNames === '')(controllerNames = "None (GM only by default)");
let tokenName = (tokenData.get("name") || "unnamed");
//REGULAR REPORT
tokenInfo =
openSection +
openSubhead + 'Token Vision