campaign update

This commit is contained in:
2024-07-01 16:58:03 -04:00
parent fe50c52a7f
commit b0e81bc80d
9 changed files with 307 additions and 59 deletions

View File

@@ -12,14 +12,14 @@
<li class="dayName">Saedo</li>
<li class="firstDay">1</li>
<li class="currDay">2</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li class="currDay">9</li>
<li>10</li>
<li>11</li>
<li>12</li>

View File

@@ -1,5 +1,5 @@
<div class="todayWrapper">
As of last session, it is **the night of Tudo, the 2nd day of Porma, in the 78th year since the Eradication of King Ranulf the Just and his court**.
As of last session, it is the **early afternoon of Trado, the 9th day of Porma, in the 78th year since the Eradication of King Ranulf the Just and his court**.
</div>

View File

@@ -21,11 +21,13 @@ export default (() => {
document.documentElement.className.replace('no-js', 'js');
// Enable cached fonts ASAP
/*
if (!!Cookies.get('fonts_loaded')) {
document.documentElement.className += ' js-hasFontsLoaded';
}
*/
docReady(() => {
document.addEventListener('DOMContentLoaded', () => {
setTimeout(() => {
// Lazy-Load Media
if (typeof loadMedia === 'function') {

View File

@@ -19,6 +19,46 @@ const getRandomValue = (max = 1, min = 1) =>
const vals = [...Array(count).keys()].map(() => getRandomValue(sides)),
total = vals.reduce((v, a) => a + v, 0);
return [total, ...vals];
},
getRandomValueFromArray = (array = []) => {
if (!array.length) return '';
const roll = getRandomValue(array.length);
return `${array[roll - 1]} (${roll})`;
},
elementBuilder = (tag) => {
const el = document.createElement(tag);
return {
// need to use `function` rather than `=>` to keep `this` intact
addEventListener: function (type, fn) {
el.addEventListener(type, fn);
return this;
},
appendChild: function (child) {
el.appendChild(child);
return this;
},
appendToId: function (targetId) {
const target = document.getElementById(targetId);
if (target) target.append(el);
return this;
},
getElement: function () {
return el;
},
prependToId: function (targetId) {
const target = document.getElementById(targetId);
if (target) target.prepend(el);
return this;
},
set: function (attr, val) {
el[attr] = val;
return this;
},
setInnerHTML: function (val) {
el.innerHTML = val;
return this;
},
};
};
// Die Roller script
@@ -28,6 +68,7 @@ const addRollerForm = () => {
rollerOutput = document.getElementById('js-rollerOutput'),
isExpressionRE =
/(?:(?:^|[-+_*/])(?:\s*-?\d*d?\d+(\.\d+)?(?:[+-]\s*\d*d?\d+)?\s*))+$/i;
if (!rollerForm) return;
// double-click [x] to clear list
rollerForm.addEventListener('reset', (e) => {
@@ -47,12 +88,6 @@ const addRollerForm = () => {
.map((roll) => {
const result = dice.roll(roll),
stringifiedResult = dice.stringify(result);
/*
console.log(
{ roll, result, stringifiedResult },
isExpressionRE.test(roll)
);
*/
return `${stringifiedResult.replaceAll(
'!!!mods listing not yet complete!!!',
''
@@ -96,6 +131,8 @@ const RoomTypes = {
const roomForm = document.getElementById('js-roomForm'),
roomOutput = document.getElementById('js-roomOutput');
if (!roomForm) return;
roomForm?.addEventListener('submit', (e) => {
e.preventDefault();
@@ -130,6 +167,9 @@ const shuffleContainer = (parentId) => {
addComplicationForm = () => {
const complicationForm = document.getElementById('js-complicationForm'),
formControls = document.createElement('div');
if (!complicationForm) return;
formControls.innerHTML = [
'<button id="js-btnSetDungeon">Dungeon</button>',
'<button id="js-btnSetWilderness">Wilderness</button>',
@@ -185,6 +225,8 @@ const shuffleContainer = (parentId) => {
const complicationForm = document.getElementById(
'js-astralComplicationForm'
);
if (!complicationForm) return;
complicationForm?.addEventListener('submit', (e) => {
e.preventDefault();
shuffleContainer('js-astralComplicationList');
@@ -247,19 +289,25 @@ const reactionButtonVal = [
// combine monster roll total + surprise + roll data
const monsterRollText = `<strong>${monsterTotal}${surpriseText}</strong><br /><em>[${monsterRolls}]</em>`;
outputTable.innerHTML = [
`<thead><th colspan="2">${
type === 'W' ? 'Wilderness' : 'Dungeon'
} Encounter<br />(3d${sides}): ${dayjs().format(
'YYYY-MM-DD HH:mm:ss'
)}</th></thead>`,
'<tbody>',
`<tr><th>Monster</th><td>${monsterRollText}</td></tr>`,
`<tr><th>Distance</th><td>${distanceText}</td></tr>`,
`<tr><th>Reaction</th><td>${reactionText}</td></tr>`,
'</tbody>',
].join('\n');
outputTable.innerHTML = `
<thead>
<th colspan="2">
${type === 'W' ? 'Wilderness' : 'Dungeon'} Encounter<br />
${dayjs().format('YYYY-MM-DD HH:mm:ss')}
</th>
</thead>
<tbody>
<tr>
<th>Monster</th><td>${monsterRollText}</td>
</tr>
<tr>
<th>Distance</th><td>${distanceText}</td>
</tr>
<tr>
<th>Reaction</th><td>${reactionText}</td>
</tr>
</tbody>
`;
outputTable.classList.add('encounterResultTable');
encounterOutput.prepend(outputTable);
@@ -267,19 +315,24 @@ const reactionButtonVal = [
addEncounterRoller = () => {
const complicationForm = document.getElementById('js-encounterForm'),
formControls = document.createElement('div');
formControls.innerHTML = [
'<div class="encounterButtonsWrapper">',
'<div class="encounterButtonsDungeonWrapper"><em>Dungeon</em><br />',
'<button id="js-btnRollDungeonEncounter3d4">3d4</button>',
'<button id="js-btnRollDungeonEncounter3d6">3d6</button>',
'<button id="js-btnRollDungeonEncounter3d8">3d8</button>',
'</div>',
'<div class="encounterButtonsWildernessWrapper"><em>Wilderness</em><br />',
'<button id="js-btnRollWildernessEncounter3d4">3d4</button>',
'<button id="js-btnRollWildernessEncounter3d6">3d6</button>',
'<button id="js-btnRollWildernessEncounter3d8">3d8</button>',
'</div></div>',
].join('\n');
if (!complicationForm) return;
formControls.innerHTML = `
<div class="encounterButtonsWrapper">
<div class="encounterButtonsDungeonWrapper">
<em>Dungeon</em><br />
<button id="js-btnRollDungeonEncounter3d4">3d4</button>
<button id="js-btnRollDungeonEncounter3d6">3d6</button>
<button id="js-btnRollDungeonEncounter3d8">3d8</button>
</div>
<div class="encounterButtonsWildernessWrapper">
<em>Wilderness</em><br />
<button id="js-btnRollWildernessEncounter3d4">3d4</button>
<button id="js-btnRollWildernessEncounter3d6">3d6</button>
<button id="js-btnRollWildernessEncounter3d8">3d8</button>
</div>
</div>
`;
complicationForm?.appendChild(formControls);
@@ -334,12 +387,145 @@ const reactionButtonVal = [
});
};
// Magic Item Concept Roller
// Based on http://recedingrules.blogspot.com/2010/03/spell-like-effect-spur.html
const modeOpts = ['Wielder', 'Touch', 'Distance', 'Area Effect'],
intentOpts = ['Attack', 'Defense', 'Utility', 'Transport', 2, 3],
rangeOpts = [10, 20, 30, 40, 50, 60, 70, 'Sight'],
durationOpts = [
'Instant',
'1 round',
'1d6 rounds',
'1 turn',
'1d6 turns',
'1 hour',
'1d6 hours',
'1 day',
'1d6 days',
'Permanent',
],
effectOpts = [
'Alter',
'Animate',
'Charm / Compel',
'Conjure',
'Delude',
'Dispel / Disappear',
'Distort',
'Divine',
'Evoke',
'Shield',
'Summon',
'Transmute',
],
mediumOpts = [
'Animal',
'Vegetable',
'Mineral',
'Metal',
'Fire',
'Earth',
'Water',
'Air',
'Law',
'Chaos',
'Shadow',
'Light',
'Sound',
'Dead',
'Infernal',
'Time',
'Space / Dimension',
'Human',
'Demihuman',
'Humanoid',
'Monster',
'Terrain',
],
getIntent = () => {
const roll = getRandomValue(intentOpts.length),
idx = roll - 1;
if (typeof intentOpts[idx] === 'number') {
const [total, ...rolls] = rollDice(4, intentOpts[idx]);
return `${rolls
.map((r) => `${intentOpts[r - 1]} (${r})`)
.join(' / ')}`;
}
return `${intentOpts[idx]} (${roll})`;
},
getRange = () => {
const roll = getRandomValue(rangeOpts.length),
idx = roll - 1;
if (typeof rangeOpts[idx] === 'number') {
const val = rangeOpts[idx];
return `${val}' / ${val * 2}' / ${val * 3}' (${roll})`;
}
return `${rangeOpts[idx]} (${roll})`;
},
getResultList = () => {
return `
Magic Item Results
<em>(${dayjs().format('YYYY-MM-DD HH:mm:ss')})</em>
<ul>
<li>
Mode:
<strong>${getRandomValueFromArray(modeOpts)}</strong>
</li>
<li>
Intent:
<strong>${getIntent()}</strong>
</li>
<li>
Range:
<strong>${getRange()}</strong>
</li>
<li>
Duration:
<strong>${getRandomValueFromArray(durationOpts)}</strong>
</li>
<li>
Effect:
<strong>${getRandomValueFromArray(effectOpts)}</strong>
</li>
<li>
Medium:
<strong>${getRandomValueFromArray(mediumOpts)}</strong>
</li>
</ul>
`;
},
addMagicItemConceptRoller = () => {
const magicItemConceptForm = document.getElementById(
'js-magicItemConcept'
);
if (!magicItemConceptForm) return;
magicItemConceptForm?.appendChild(
elementBuilder('input')
.set('type', 'submit')
.set('value', 'Roll!')
.getElement()
);
magicItemConceptForm?.addEventListener('submit', (e) => {
e.preventDefault();
elementBuilder('li')
.setInnerHTML(getResultList())
.prependToId('js-magicItemConcept-output');
});
};
export default (() => {
addRollerForm();
addRoomForm();
addComplicationForm();
addAstralComplicationForm();
addEncounterRoller();
addMagicItemConceptRoller();
})();
// @license-end

View File

@@ -472,6 +472,21 @@ a.licenseLink:hover {
border-color: #e94e5c;
}
.magicItemConcept-controls {
align-items: center;
display: flex;
flex-direction: row;
}
.magicItemConcept-controls p {
margin: 0;
}
.magicItemConcept-output {
padding-left: 0;
}
.menu-icon {
display: block;
position: absolute;
@@ -1219,10 +1234,6 @@ a.pageTitle-sublink {
box-shadow: rgba(0, 0, 0, 0.35) 0px 50px 36px 28px inset;
}
.zineIssue-wrapper .table-of-contents {
display: none;
}
/****************************************************************************
* JS Overrides