Skip to content

Instantly share code, notes, and snippets.

@BaldarSilveraxe
Last active April 23, 2021 08:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BaldarSilveraxe/57de44c1262965d502780b9539de7e15 to your computer and use it in GitHub Desktop.
Save BaldarSilveraxe/57de44c1262965d502780b9539de7e15 to your computer and use it in GitHub Desktop.
/*jshint esversion: 9 */
// OPen and Blind Checks for the 5th Edition OGL by Roll20
// Create a token action macro called "OpenChecks" with the action "!OpenChecks"
// Create a token action macro called "BlindChecks" with the action "!BlindChecks"
// Give all your players access to both.
const OpenBlindChecks = (() => {
const buildTable = (values) => {
let getMod = (g) => {
return g ? g.mod : -5;
};
let s = {
div: `display: block; ` +
`min-height:60px; ` +
`margin: 5px 0px 0px -30px; ` +
`padding:0px 5px 0px 5px; ` +
`border: 0px none; ` +
`border-radius: 6px 6px 6px 6px; ` +
`box-shadow: 2px 2px 4px 2px #000; ` +
`background-color: #fff; ` +
`background-image: url('${values.blind ? "https://i.imgur.com/UCIUXyr.jpg" : "https://i.imgur.com/vjL1blE.jpg" }'); ` + //https://i.imgur.com/UCIUXyr.jpg https://i.imgur.com/vjL1blE.jpg
`text-align: left; ` +
`white-space: pre-wrap;`,
tbl_top: `width: 90%; margin: auto;`,
img: `background-color: transparent; ` +
`border: none ;` +
`max-height: 60px; ` +
`padding: 5px; ` +
`margin: auto; !important`,
name: `font-weight: bold; ` +
`font-size: 120%; ` +
`font-style: italic; ` +
`text-align: center; ` +
`line-height: 18px; ` +
`padding: 0px 5px 0px;`,
blurb: `font-style: italic; ` +
`text-align: center; ` +
`line-height:18px; ` +
`padding: 0px 5px 0px;`,
rolls: `text-align: center; ` +
`line-height:18px; ` +
`padding: 0px 5px 0px;`,
inlinestyle: `display: inline-block; ` +
`min-width:18px; ` +
`min-height:18px; ` +
`background: white; ` +
`border: 1px solid black; ` +
`font-style: normal; ` +
`text-align: center; ` +
`line-height:18px; ` +
`padding: 0px:` +
`color: black;`,
inlineclass: `inlinerollresult showtip tipsy-n-right`,
tbl_abl: `width: 90%; margin: auto;`,
th: `font-weight: bold; ` +
`text-align: center; ` +
`line-height:18px; ` +
`padding: 0px 5px 0px;`,
td: `text-align: center; ` +
`line-height:18px; ` +
`padding: 0px 5px 0px;"`,
tbl_skl: `width: 90%; margin: auto;`,
tr_even: `background-color: ${values.blind ? "#cfd2d0" : "#e0e5c1" };`, //cfd2d0 //e0e5c1 ${values.blind ? "cfd2d0" : "e0e5c1" }
tr_odd: `background-color: ${values.blind ? "#eeeeee" : "#ffffff" };` //transparent #ffffff ${values.blind ? "#eeeeee" : "#ffffff" }
};
let passive = `Passive Wisdom: ` +
`<span class="${s.inlineclass}" style="${s.inlinestyle}" title="10 + ${getMod(values.mods.perception_bonus)}">` +
`${10 + getMod(values.mods.perception_bonus)}` +
`</span>`;
let inlineRoll = (props) => {
return `<span class="${s.inlineclass}" style="${s.inlinestyle}" title="${props.t1}">${props.r1}</span>&#171;-&#187;<span class="${s.inlineclass}" style="${s.inlinestyle}" title="${props.t2}">${props.r2}</span>`;
};
let rawRoll = inlineRoll({
t1: `Rolling 1d20(${values.frst})`,
r1: values.frst,
t2: `Rolling 1d20(${values.scnd})`,
r2: values.scnd});
let abilityRow = (oe, l, m, sa) => {
return `<tr style="${oe}">` +
`<td style="${s.td}">` +
`${l}` +
`</td>` +
`<td style="${s.rolls}">` +
`${inlineRoll({
t1: `Rolling 1d20(${values.frst})+${m}`,
r1: values.frst + m,
t2: `Rolling 1d20(${values.scnd})+${m}`,
r2: values.scnd + m
})}` +
`</td>` +
`<td style="${s.rolls}">` +
`${inlineRoll({
t1: `Rolling 1d20(${values.frst})+${sa}`,
r1: values.frst + sa,
t2: `Rolling 1d20(${values.scnd})+${sa}`,
r2: values.scnd + sa
})}` +
`</td>` +
`</tr>`;
};
let abilityList = [
{oddeven: s.tr_even, label: 'Strength', mod: getMod(values.mods.strength_mod), save: getMod(values.mods.strength_save_bonus)},
{oddeven: s.tr_odd, label: 'Dexterity', mod: getMod(values.mods.dexterity_mod), save: getMod(values.mods.dexterity_save_bonus)},
{oddeven: s.tr_even, label: 'Constitution', mod: getMod(values.mods.constitution_mod), save: getMod(values.mods.constitution_save_bonus)},
{oddeven: s.tr_odd, label: 'Intelligence', mod: getMod(values.mods.intelligence_mod), save: getMod(values.mods.intelligence_save_bonus)},
{oddeven: s.tr_even, label: 'Wisdom', mod: getMod(values.mods.wisdom_mod), save: getMod(values.mods.wisdom_save_bonus)},
{oddeven: s.tr_odd, label: 'Charisma', mod: getMod(values.mods.charisma_mod), save: getMod(values.mods.charisma_save_bonus)}
];
let skillRow = (oe, l, m, sa) => {
return `<tr style="${oe}">` +
`<td style="${s.td}">` +
`${l}` +
`</td>` +
`<td style="${s.rolls}">` +
`${inlineRoll({
t1: `Rolling 1d20(${values.frst})+${m}`,
r1: values.frst + m,
t2: `Rolling 1d20(${values.scnd})+${m}`,
r2: values.scnd + m
})}` +
`</td>` +
`</tr>`;
};
let skillList = [
{oddeven: s.tr_even, label: 'Athletics', mod: getMod(values.mods.athletics_bonus)},
{oddeven: s.tr_odd, label: 'Acrobatics', mod: getMod(values.mods.acrobatics_bonus)},
{oddeven: s.tr_even, label: 'Animal Handling', mod: getMod(values.mods.animal_handling_bonus)},
{oddeven: s.tr_odd, label: 'Arcana', mod: getMod(values.mods.arcana_bonus)},
{oddeven: s.tr_even, label: 'Deception', mod: getMod(values.mods.deception_bonus)},
{oddeven: s.tr_odd, label: 'History', mod: getMod(values.mods.history_bonus)},
{oddeven: s.tr_even, label: 'Insight', mod: getMod(values.mods.insight_bonus)},
{oddeven: s.tr_odd, label: 'Intimidation', mod: getMod(values.mods.intimidation_bonus)},
{oddeven: s.tr_even, label: 'Investigation', mod: getMod(values.mods.investigation_bonus)},
{oddeven: s.tr_odd, label: 'Medicine', mod: getMod(values.mods.medicine_bonus)},
{oddeven: s.tr_even, label: 'Nature', mod: getMod(values.mods.nature_bonus)},
{oddeven: s.tr_odd, label: 'Perception', mod: getMod(values.mods.perception_bonus)},
{oddeven: s.tr_even, label: 'Performance', mod: getMod(values.mods.performance_bonus)},
{oddeven: s.tr_odd, label: 'Persuasion', mod: getMod(values.mods.persuasion_bonus)},
{oddeven: s.tr_even, label: 'Religion', mod: getMod(values.mods.religion_bonus)},
{oddeven: s.tr_odd, label: 'Sleight of Hand', mod: getMod(values.mods.sleight_of_hand_bonus)},
{oddeven: s.tr_even, label: 'Stealth', mod: getMod(values.mods.stealth_bonus)},
{oddeven: s.tr_odd, label: 'Survival', mod: getMod(values.mods.survival_bonus)}
];
values.message = `` +
`<div style="${s.div}">` +
`<table style="${s.tbl_top}">` +
`<tr>` +
`<td rowspan="3">` +
`<img style="${s.img}" src="${values.url}">` +
`</td>` +
`<td style="${s.name}">` +
`${values.name}` +
`</td>` +
`</tr>` +
`<tr>` +
`<td style="${s.blurb}">` +
`${passive}` +
`</td>` +
`</tr>` +
`<tr>` +
`<td style="${s.rolls}">` +
`${rawRoll}` +
`</td>` +
`</tr>` +
`</table>` +
`<br>` +
`<table style="${s.tbl_abl}">` +
`<tr>` +
`<td style="${s.th}">` +
`Ability` +
`</td><td style="${s.th}">` +
`Check` +
`</td>` +
`<td style="${s.th}">` +
`Save` +
`</td>` +
`</tr>`;
abilityList.forEach( (row) => {
values.message = values.message + abilityRow(row.oddeven, row.label, row.mod, row.save);
});
values.message = values.message + `</table>` +
`<br>` +
`<table style="${s.tbl_abl}">` +
`<tr>` +
`<td style="${s.th}">` +
`Ability` +
`</td><td style="${s.th}">` +
`Check` +
`</td>` +
`</tr>`;
skillList.forEach( (row) => {
values.message = values.message + skillRow(row.oddeven, row.label, row.mod);
});
values.message = values.message + `</table>` +
`<br>` +
`</div>`;
return values.message;
};
const getAttributes = (values) => {
let attrNames = [
'strength_mod',
'dexterity_mod',
'constitution_mod',
'intelligence_mod',
'wisdom_mod',
'charisma_mod',
'strength_save_bonus',
'dexterity_save_bonus',
'constitution_save_bonus',
'intelligence_save_bonus',
'wisdom_save_bonus',
'charisma_save_bonus',
'athletics_bonus',
'acrobatics_bonus',
'animal_handling_bonus',
'arcana_bonus',
'deception_bonus',
'history_bonus',
'insight_bonus',
'intimidation_bonus',
'investigation_bonus',
'medicine_bonus',
'nature_bonus',
'perception_bonus',
'performance_bonus',
'persuasion_bonus',
'religion_bonus',
'sleight_of_hand_bonus',
'stealth_bonus',
'survival_bonus',
'passive_wisdom'
];
values.attr = filterObjs( (a) => {
if ( a.get('characterid') == values.cid &&
a.get('type') === 'attribute' &&
attrNames.includes(a.get('name')) )
{
return true;
} else {
return false;
}
});
values.mods = {};
values.attr.forEach( (a) => {
let key = a.get('name');
let mod = a.get('current');
let lbl = a.get('name')
.replace(/_mod/gi,'')
.replace(/_bonus/gi,'')
.replace(/_/g, ' ');
values.mods[a.get('name')] = {
key: a.get('name'),
mod: (Number(mod)||~~mod) || 0,
lbl: lbl
};
});
sendChat('QuantumRoll', '[[2d20]]', function(qr) {
values.frst = qr[0].inlinerolls[0].results.rolls[0].results[0].v;
values.scnd = qr[0].inlinerolls[0].results.rolls[0].results[1].v;
buildTable(values);
if (values.blind) {
sendChat(values.who, `/w gm ${values.message}`);
sendChat('API - QuantumRoll', `/w "${values.who}" Secret roll sent to GM. I'm sure its fine.`);
}else{
sendChat(values.who, values.message);
}
});
};
const handleInput = (msg) => {
let values = {};
values.msg = msg;
values.tok = getObj(
values.msg.selected[0]._type,
values.msg.selected[0]._id);
values.cha = getObj(
'character',
values.tok.get('represents'));
if (values.cha) {
values.cid = values.cha.get('id');
let imgsrc = values.tok.get('imgsrc');
values.url = imgsrc === '/images/character.png' ?
'https://i.imgur.com/MpqETqe.png' :
imgsrc;
values.name = values.cha.get('name');
values.blind = msg.content.startsWith("!BlindChecks");
values.who = values.msg.who
.substring(0, values.msg.who.indexOf(' (GM)'));
}
getAttributes(values);
};
on("ready",() => {
on('chat:message', (msg_orig) => {
if (msg_orig.type === 'api' &&
(msg_orig.content.startsWith("!OpenChecks") ||
msg_orig.content.startsWith("!BlindChecks")) &&
msg_orig.selected && msg_orig.selected.length == 1 )
{
handleInput(_.clone(msg_orig));
}
});
});
return {
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment