various updates
This commit is contained in:
6
src/assets/fragments/classes/combat-expertise.md
Normal file
6
src/assets/fragments/classes/combat-expertise.md
Normal file
@@ -0,0 +1,6 @@
|
||||
1. **Berserker**: After striking a killing blow while in melee with multiple foes, may immediately make a free attack against another foe at –2.
|
||||
2. **Dual-Wielder**: Gains [Dual Wielding](/rules/combat.md#dual-wielding). If DEX > 13 and wielding both a one-handed weapon and a Light weapon in off hand, may make an attack with each one.
|
||||
3. **Hunter**: +1 to attack and damage rolls when in combat with foes of a specific type (ex: undead, clerics, dragons, giants, etc.). The type must be chosen when this talent is selected.
|
||||
4. **Leader**: Mercenaries or retainers under command and within 60' gain a +1 bonus to morale and loyalty checks. All allies within 60' get +1 bonus to saves against fear effects.
|
||||
5. **Specialist**: Expertise with a specific type of weapon (ex: whips, one-handed swords, crossbows, etc.) grants +1 to attack and damage rolls when using one.
|
||||
6. **Tank**: When in melee with a foe, any attacks the foe makes at anyone else get –2.
|
@@ -47,10 +47,12 @@ 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!!!',
|
||||
''
|
||||
@@ -163,17 +165,20 @@ const shuffleContainer = (parentId) => {
|
||||
|
||||
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')
|
||||
);
|
||||
(distanceText = `<strong>${
|
||||
distanceTotal * 10
|
||||
} yards</strong><br /><em>[${distanceRolls}]</em>`),
|
||||
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 = () => {
|
||||
@@ -199,7 +204,15 @@ const reactionButtonVal = [
|
||||
'Amiable',
|
||||
'Friendly!',
|
||||
],
|
||||
rollEncounter = (sides = 1) => {
|
||||
rollDistance = (type = 'W', hasDoubles) => {
|
||||
// roll 2d6 for starting dungeon distance
|
||||
if (type !== 'W') return rollDice(6, 2);
|
||||
|
||||
// roll 4d6 (or 1d4, if any doubles above) for starting wilderness distance
|
||||
return hasDoubles ? rollDice(4) : rollDice(6, 4);
|
||||
},
|
||||
rollEncounter = (sides = 1, type = 'W') => {
|
||||
type = `${type}`.toUpperCase();
|
||||
// roll 3d8 for monsters, note doubles (first 2 / last 2 / first & last) / triples
|
||||
const [monsterTotal, ...monsterRolls] = rollDice(sides, 3),
|
||||
hasStealthParty =
|
||||
@@ -210,17 +223,18 @@ const reactionButtonVal = [
|
||||
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),
|
||||
// roll for distance, see above
|
||||
[distanceTotal, ...distanceRolls] = rollDistance(type, hasDoubles),
|
||||
// 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>`,
|
||||
distanceText = [
|
||||
`<strong>${distanceTotal * 10}`,
|
||||
type === 'W' ? ' yards' : "'",
|
||||
'</strong>',
|
||||
`<br /><em>[${distanceRolls}]</em>`,
|
||||
].join(''),
|
||||
encounterOutput = document.getElementById('js-encounterOutput'),
|
||||
outputTable = document.createElement('table');
|
||||
|
||||
@@ -235,7 +249,9 @@ const reactionButtonVal = [
|
||||
const monsterRollText = `<strong>${monsterTotal}${surpriseText}</strong><br /><em>[${monsterRolls}]</em>`;
|
||||
|
||||
outputTable.innerHTML = [
|
||||
`<thead><th colspan="2">Encounter (3d${sides}): ${dayjs().format(
|
||||
`<thead><th colspan="2">${
|
||||
type === 'W' ? 'Wilderness' : 'Dungeon'
|
||||
} Encounter<br />(3d${sides}): ${dayjs().format(
|
||||
'YYYY-MM-DD HH:mm:ss'
|
||||
)}</th></thead>`,
|
||||
'<tbody>',
|
||||
@@ -253,13 +269,11 @@ const reactionButtonVal = [
|
||||
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>',
|
||||
@@ -291,32 +305,32 @@ const reactionButtonVal = [
|
||||
if (rollDungeonEncounter3d4Button)
|
||||
rollDungeonEncounter3d4Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(4);
|
||||
rollEncounter(4, 'D');
|
||||
});
|
||||
if (rollDungeonEncounter3d6Button)
|
||||
rollDungeonEncounter3d6Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(6);
|
||||
rollEncounter(6, 'D');
|
||||
});
|
||||
if (rollDungeonEncounter3d8Button)
|
||||
rollDungeonEncounter3d8Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(8);
|
||||
rollEncounter(8, 'D');
|
||||
});
|
||||
if (rollWildernessEncounter3d4Button)
|
||||
rollWildernessEncounter3d4Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(4);
|
||||
rollEncounter(4, 'W');
|
||||
});
|
||||
if (rollWildernessEncounter3d6Button)
|
||||
rollWildernessEncounter3d6Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(6);
|
||||
rollEncounter(6, 'W');
|
||||
});
|
||||
if (rollWildernessEncounter3d8Button)
|
||||
rollWildernessEncounter3d8Button.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
rollEncounter(8);
|
||||
rollEncounter(8, 'W');
|
||||
});
|
||||
};
|
||||
|
||||
|
@@ -392,10 +392,10 @@ table th {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.encounterButtonsWildernessWrapper {
|
||||
.encounterButtonsWrapper > * {
|
||||
/* margin-left: auto; */
|
||||
border: 1px solid #e94e5c;
|
||||
border-radius: .3rem;
|
||||
@@ -403,6 +403,7 @@ table th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.feature hr {
|
||||
border: 1px 0 0 0;
|
||||
border-color: #885c68;
|
||||
|
Reference in New Issue
Block a user