diff --git a/package.json b/package.json index 95ce92c..40da982 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "planar-vagabond", - "version": "0.14.2", + "version": "0.14.3", "description": "", "main": "index.js", "scripts": { diff --git a/src/assets/fragments/bestiary/herd-mammal.md b/src/assets/fragments/bestiary/herd-mammal.md new file mode 100644 index 0000000..466e203 --- /dev/null +++ b/src/assets/fragments/bestiary/herd-mammal.md @@ -0,0 +1,11 @@ +- Exact species depends on terrain. +- In groups of 3+, only 25% are male. +- Females and young do not have a butt attack, and will typically try to flee. + +### Stampede + +Herds of 20+ can stampede, trampling nearly anything in their path. + +- 75% chance each round. +- +4 to hit humanoid (or smaller) creatures. +- Deals 1d20 damage. diff --git a/src/assets/fragments/bestiary/werebeast.md b/src/assets/fragments/bestiary/werebeast.md index 53c94df..3c96f83 100644 --- a/src/assets/fragments/bestiary/werebeast.md +++ b/src/assets/fragments/bestiary/werebeast.md @@ -1,13 +1,20 @@ -- Humanoid form usually retains some characteristics from their animal form. -- While in animal form, immune to mundane, non-silver weapons. +- Immune to mundane, non-silver weapons. +- Capable of shifting between their (natural) humanoid form, animal form, and a hybrid form. + - Must change into and remain in hybrid or animal form during a full moon. +- Humanoid form usually retains some characteristics from animal form. - While in animal form, can only speak with animals of that type. -- Cannot where armor, as it limits their ability to shapeshift. +- Cannot wear armor, as it limits their ability to shapeshift. +- Cannot use weapons while in animal form. - May summon 1d2 animals associated with their animal form from the surrounding area. - Animals arrive in 1d4 rounds. - When hit with wolfsbane, must **Save vs Poison** or flee, as with the [Scare spell](/spells/calm.html#scare). -- When killed in animal form, reverts to humanoid form. +- When killed in animal or hybrid form, reverts to humanoid form. +- Can smell other werebeasts. - Some animals can smell werebeasts, and are afraid of them. -- When a humanoid loses more than 1/2 of their max hit points from the natural attacks of a werebeast (ex: bite or claw), they must **Save vs Poison** or become infected with therianthropy. - - The disease takes 2d12 days to full infect, with signs of infection appearing halfway through. - - Humanoids become the same type of werebeasts (and typically run by the referee). +### Infection + +When a humanoid loses more than 1/2 of their max hit points from the natural attacks of a werebeast (ex: bite or claw), they must **Save vs Poison** or become infected with therianthropy. + +- The disease takes 2d12 days to fully infect, with signs of infection appearing halfway through. +- Humanoids become the same type of werebeasts (and are typically run by the referee, at least while transformed). diff --git a/src/assets/scripts/tools.js b/src/assets/scripts/tools.js index 99b26f8..907c14c 100644 --- a/src/assets/scripts/tools.js +++ b/src/assets/scripts/tools.js @@ -8,11 +8,17 @@ * https://www.itsericwoodward.com/licenses/mit ****************************************************************************/ +// TODO: Add quick buttons to roll specific dice and add them to the box, along with [X] to clear +// 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 + // Die Roller script const addRollerForm = () => { const rollerForm = document.getElementById('js-rollerForm'), rollerInput = document.getElementById('js-rollerInput'), - rollerOutput = document.getElementById('js-rollerOutput'); + rollerOutput = document.getElementById('js-rollerOutput'), + isExpressionRE = + /(?:(?:^|[-+_*/])(?:\s*-?\d*d?\d+(\.\d+)?(?:[+-]\s*\d*d?\d+)?\s*))+$/i; // double-click [x] to clear list rollerForm.addEventListener('reset', (e) => { @@ -26,18 +32,24 @@ const addRollerForm = () => { const newEl = document.createElement('li'), // support multiple sets of dice - rolls = rollerInput.value.split(/,\s+/); + rolls = rollerInput.value.split(/,\s*/); newEl.innerText = rolls .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!!!', '' )}${ // only show total if there's multiple dice thrown in a set - stringifiedResult.includes(',') ? ` = ${+result}` : '' + stringifiedResult.includes(',') || isExpressionRE.test(roll) + ? ` = ${+result}` + : '' }`; }) .join(', '); @@ -75,7 +87,7 @@ const RoomTypes = { const roomForm = document.getElementById('js-roomForm'), roomOutput = document.getElementById('js-roomOutput'); - roomForm.addEventListener('submit', (e) => { + roomForm?.addEventListener('submit', (e) => { e.preventDefault(); const newEl = document.createElement('li'), @@ -87,7 +99,7 @@ const RoomTypes = { newEl.innerText = `${roomType}${ hasTreasure ? ' (Treasure)' : '' } {${roomVal},${treasureVal}}`; - roomOutput.prepend(newEl); + roomOutput?.prepend(newEl); }); }; @@ -104,7 +116,7 @@ const shuffleContainer = (parent) => { }, addComplicationForm = () => { const complicationForm = document.getElementById('js-complicationForm'); - complicationForm.addEventListener('submit', (e) => { + complicationForm?.addEventListener('submit', (e) => { e.preventDefault(); shuffleContainer('js-complicationList'); }); @@ -113,7 +125,7 @@ const shuffleContainer = (parent) => { const complicationForm = document.getElementById( 'js-astralComplicationForm' ); - complicationForm.addEventListener('submit', (e) => { + complicationForm?.addEventListener('submit', (e) => { e.preventDefault(); shuffleContainer('js-astralComplicationList'); }); diff --git a/src/layouts/partials/bottom.ejs b/src/layouts/partials/bottom.ejs index 38ec025..f13fcca 100644 --- a/src/layouts/partials/bottom.ejs +++ b/src/layouts/partials/bottom.ejs @@ -1,6 +1,5 @@ - + + + + + +
+
+ +

Die Roller

+
+
+ + + +
+ + +
+
+ +**Total** => Which Creature + +### D6: Group Size + +Based on TPL + +
+ +| d6 | Result | +| :-: | :------: | +| 1 | 50% TPL | +| 2 | 75% TPL | +| 3 | 100% TPL | +| 4 | 125% TPL | +| 5 | 150% TPL | +| 6 | 175% TPL | + +[Group Size] + +
+ +### D8: Reaction + +- -1 for aggressive NPCs, +1 for passive / friendly ones + +
+ +| d8 | Result | +| :-: | :--------------------------------------: | +| 1 | Attack => -2 to 2d6 | +| 2-3 | Hostile (may attack) => -1 to 2d6 | +| 4-5 | Uncertain, neutral | +| 6-7 | Indifferent (may negotiate) => +1 to 2d6 | +| 8 | Friendly => +2 to 2d6 | + +[Reaction] + +
+ +### D10: Distance + +- Starting Distance = result x 10' + +### Special Results + +**Doubles** => Surprise, which doubles determines who gets it: + +- low doubles (d6 + d8): monsters get it +- mixed doubles (d6 + d10): PCs get it +- high doubles (d8 + d10): double surprise, miss each other + +**Triples** => Roll again, two encounters are happening at same time. + +https://playfulvoid.game.blog/2024/03/27/double-overloading-the-random-encounter-table/ diff --git a/src/pages/tools/index.md b/src/pages/tools/index.md index 3d76ea0..daad77a 100644 --- a/src/pages/tools/index.md +++ b/src/pages/tools/index.md @@ -74,6 +74,6 @@ short_code: t1 -- [Referee's Screen](/tools/referee-screen) +- [Referee's Screen](/tools/referee-screen.html)