add dinosaurs, dragons, and werebeasts
add some more campaign info add encounter generators (alpha)
This commit is contained in:
@@ -12,6 +12,15 @@
|
||||
// adding a dice looks for a matching die in the pattern and increments how many there are, or appends (if no match)
|
||||
// so clicking "d6" 3x gives you "3d6" in box
|
||||
|
||||
// utilities
|
||||
const getRandomValue = (max = 1, min = 1) =>
|
||||
Math.round(Math.random() * (max - min)) + min,
|
||||
rollDice = (sides = 1, count = 1) => {
|
||||
const vals = [...Array(count).keys()].map(() => getRandomValue(sides)),
|
||||
total = vals.reduce((v, a) => a + v, 0);
|
||||
return [total, ...vals];
|
||||
};
|
||||
|
||||
// Die Roller script
|
||||
const addRollerForm = () => {
|
||||
const rollerForm = document.getElementById('js-rollerForm'),
|
||||
@@ -81,8 +90,6 @@ const RoomTypes = {
|
||||
if (room <= RoomTypes.SPECIAL) return false;
|
||||
return treasure <= 2;
|
||||
},
|
||||
getRandomValue = (max = 1, min = 1) =>
|
||||
Math.round(Math.random() * (max - min)) + min,
|
||||
addRoomForm = () => {
|
||||
const roomForm = document.getElementById('js-roomForm'),
|
||||
roomOutput = document.getElementById('js-roomOutput');
|
||||
@@ -104,8 +111,8 @@ const RoomTypes = {
|
||||
};
|
||||
|
||||
// Complication Randomizer scripts
|
||||
const shuffleContainer = (parent) => {
|
||||
const container = document.getElementById(parent),
|
||||
const shuffleContainer = (parentId) => {
|
||||
const container = document.getElementById(parentId),
|
||||
children = container.children,
|
||||
length = children.length,
|
||||
shuffled = [...children];
|
||||
@@ -114,12 +121,60 @@ const shuffleContainer = (parent) => {
|
||||
shuffled.sort(() => 0.5 - Math.random());
|
||||
for (let i = 0; i < length; i++) container.appendChild(shuffled[i]);
|
||||
},
|
||||
setContainerContents = (parentId, content = '') => {
|
||||
const container = document.getElementById(parentId);
|
||||
if (container?.innerHTML) container.innerHTML = content;
|
||||
},
|
||||
addComplicationForm = () => {
|
||||
const complicationForm = document.getElementById('js-complicationForm');
|
||||
const complicationForm = document.getElementById('js-complicationForm'),
|
||||
formControls = document.createElement('div');
|
||||
formControls.innerHTML = [
|
||||
'<button id="js-btnSetDungeon">Dungeon</button>',
|
||||
'<button id="js-btnSetWilderness">Wilderness</button>',
|
||||
'<input type="submit" value="Randomize!" />',
|
||||
].join('\n');
|
||||
|
||||
complicationForm?.appendChild(formControls);
|
||||
|
||||
complicationForm?.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
shuffleContainer('js-complicationList');
|
||||
});
|
||||
|
||||
const setDungeonButton = document.getElementById('js-btnSetDungeon'),
|
||||
setWildernessButton = document.getElementById(
|
||||
'js-btnSetWilderness'
|
||||
);
|
||||
|
||||
setDungeonButton?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
setContainerContents(
|
||||
'js-complicationList',
|
||||
[
|
||||
'<li>Encounter</li>',
|
||||
'<li>Signs / Portents</li>',
|
||||
'<li>Locality</li>',
|
||||
'<li>Exhaustion *</li>',
|
||||
'<li>Light Source *</li>',
|
||||
'<li>No Complications</li>',
|
||||
].join('\n')
|
||||
);
|
||||
});
|
||||
|
||||
setWildernessButton?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
setContainerContents(
|
||||
'js-complicationList',
|
||||
[
|
||||
'<li>Encounter</li>',
|
||||
'<li>Encounter *</li>',
|
||||
'<li>Signs / Portents</li>',
|
||||
'<li>Locality / Weather (2d4)</li>',
|
||||
'<li>Lose Way (1d3 hrs)</li>',
|
||||
'<li>No Complications</li>',
|
||||
].join('\n')
|
||||
);
|
||||
});
|
||||
},
|
||||
addAstralComplicationForm = () => {
|
||||
const complicationForm = document.getElementById(
|
||||
@@ -131,11 +186,146 @@ const shuffleContainer = (parent) => {
|
||||
});
|
||||
};
|
||||
|
||||
const reactionButtonVal = [
|
||||
'Attack!',
|
||||
'Hateful',
|
||||
'Leery',
|
||||
'Rude',
|
||||
'Aloof',
|
||||
'Uncertain',
|
||||
'Confused',
|
||||
'Indifferent',
|
||||
'Cordial',
|
||||
'Amiable',
|
||||
'Friendly!',
|
||||
],
|
||||
rollEncounter = (sides = 1) => {
|
||||
// roll 3d8 for monsters, note doubles (first 2 / last 2 / first & last) / triples
|
||||
const [monsterTotal, ...monsterRolls] = rollDice(sides, 3),
|
||||
hasStealthParty =
|
||||
monsterRolls.length > 1 && monsterRolls[0] === monsterRolls[1],
|
||||
hasStealthMonster =
|
||||
monsterRolls.length > 2 && monsterRolls[1] === monsterRolls[2],
|
||||
hasDoubleSurprise = hasStealthParty && hasStealthMonster,
|
||||
hasDoubles = hasStealthParty || hasStealthMonster,
|
||||
// roll 2d6 for reaction, note string & numeric value
|
||||
[reactionTotal, ...reactionRolls] = rollDice(6, 2),
|
||||
// roll 4d6 (or 1d4, if any doubles above) for starting distance
|
||||
[distanceTotal, ...distanceRolls] = hasDoubles
|
||||
? rollDice(4)
|
||||
: rollDice(6, 4),
|
||||
// Derived string and scores
|
||||
reactionText = `<strong>${
|
||||
reactionButtonVal[reactionTotal - 2]
|
||||
} (${reactionTotal})</strong><br /><em>[${reactionRolls}]</em>`,
|
||||
distanceText = `<strong>${
|
||||
distanceTotal * 10
|
||||
} yards</strong><br /><em>[${distanceRolls}]</em>`,
|
||||
encounterOutput = document.getElementById('js-encounterOutput'),
|
||||
outputTable = document.createElement('table');
|
||||
|
||||
// additional text denoting surprise results.
|
||||
let surpriseText = '';
|
||||
if (hasDoubleSurprise) surpriseText = 'Double Surprise';
|
||||
else if (hasStealthMonster) surpriseText = 'Monster has stealth';
|
||||
else if (hasStealthParty) surpriseText = 'Party has stealth';
|
||||
if (surpriseText) surpriseText = `<br />${surpriseText}!`;
|
||||
|
||||
// combine monster roll total + surprise + roll data
|
||||
const monsterRollText = `<strong>${monsterTotal}${surpriseText}</strong><br /><em>[${monsterRolls}]</em>`;
|
||||
|
||||
outputTable.innerHTML = [
|
||||
`<thead><th colspan="2">Encounter (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.classList.add('encounterResultTable');
|
||||
|
||||
encounterOutput.prepend(outputTable);
|
||||
},
|
||||
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');
|
||||
|
||||
complicationForm?.appendChild(formControls);
|
||||
|
||||
const rollDungeonEncounter3d4Button = document.getElementById(
|
||||
'js-btnRollDungeonEncounter3d4'
|
||||
),
|
||||
rollDungeonEncounter3d6Button = document.getElementById(
|
||||
'js-btnRollDungeonEncounter3d6'
|
||||
),
|
||||
rollDungeonEncounter3d8Button = document.getElementById(
|
||||
'js-btnRollDungeonEncounter3d8'
|
||||
),
|
||||
rollWildernessEncounter3d4Button = document.getElementById(
|
||||
'js-btnRollWildernessEncounter3d4'
|
||||
),
|
||||
rollWildernessEncounter3d6Button = document.getElementById(
|
||||
'js-btnRollWildernessEncounter3d6'
|
||||
),
|
||||
rollWildernessEncounter3d8Button = document.getElementById(
|
||||
'js-btnRollWildernessEncounter3d8'
|
||||
);
|
||||
|
||||
if (rollDungeonEncounter3d4Button)
|
||||
rollDungeonEncounter3d4Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(4);
|
||||
});
|
||||
if (rollDungeonEncounter3d6Button)
|
||||
rollDungeonEncounter3d6Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(6);
|
||||
});
|
||||
if (rollDungeonEncounter3d8Button)
|
||||
rollDungeonEncounter3d8Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(8);
|
||||
});
|
||||
if (rollWildernessEncounter3d4Button)
|
||||
rollWildernessEncounter3d4Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(4);
|
||||
});
|
||||
if (rollWildernessEncounter3d6Button)
|
||||
rollWildernessEncounter3d6Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(6);
|
||||
});
|
||||
if (rollWildernessEncounter3d8Button)
|
||||
rollWildernessEncounter3d8Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(8);
|
||||
});
|
||||
};
|
||||
|
||||
export default (() => {
|
||||
addRollerForm();
|
||||
addRoomForm();
|
||||
addComplicationForm();
|
||||
addAstralComplicationForm();
|
||||
addEncounterRoller();
|
||||
})();
|
||||
|
||||
// @license-end
|
||||
|
Reference in New Issue
Block a user