Skip to content

Commit 0e9b9fd

Browse files
committed
v1.181.0
1 parent 44eade0 commit 0e9b9fd

22 files changed

+369
-184
lines changed

css/main.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

data/bestiary/bestiary-wdmm.json

-1
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,6 @@
787787
],
788788
"passive": 9,
789789
"immune": [
790-
"fire",
791790
"poison",
792791
"psychic",
793792
{

data/bestiary/traits.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@
150150
{
151151
"name": "Innate Spellcasting",
152152
"headerEntries": [
153-
"<$title_short_name$>'s innate spellcasting ability is Intelligence (spell save DC <$spell_dc__int$>). <$title_short_name$> can innately cast the following spells, requiring no material components:"
153+
"<$title_short_name$>'s innate spellcasting ability is Intelligence (spell save {@dc <$spell_dc__int$>}). <$title_short_name$> can innately cast the following spells, requiring no material components:"
154154
],
155155
"will": [
156156
"{@spell nondetection} (self only)"
@@ -316,7 +316,7 @@
316316
{
317317
"name": "Innate Spellcasting",
318318
"headerEntries": [
319-
"<$title_short_name$>'s innate spellcasting ability is Charisma (spell save DC <$spell_dc__cha$>). <$title_short_name$> can innately cast the following spells, requiring no material components:"
319+
"<$title_short_name$>'s innate spellcasting ability is Charisma (spell save {@dc <$spell_dc__cha$>}). <$title_short_name$> can innately cast the following spells, requiring no material components:"
320320
],
321321
"will": [
322322
"{@spell dancing lights}"
@@ -469,7 +469,7 @@
469469
{
470470
"name": "Innate Spellcasting",
471471
"headerEntries": [
472-
"<$title_short_name$>'s innate spellcasting ability is Wisdom (spell save DC <$spell_dc__wis$>). <$title_short_name$> can innately cast the following spells, requiring no material components:"
472+
"<$title_short_name$>'s innate spellcasting ability is Wisdom (spell save {@dc <$spell_dc__wis$>}). <$title_short_name$> can innately cast the following spells, requiring no material components:"
473473
],
474474
"rest": {
475475
"1e": [
@@ -2777,7 +2777,7 @@
27772777
{
27782778
"name": "Innate Spellcasting",
27792779
"headerEntries": [
2780-
"<$title_short_name$>'s innate spellcasting ability is Charisma (spell save DC <$spell_dc__cha$>). <$title_short_name$> can innately cast the following spells, requiring no material components:"
2780+
"<$title_short_name$>'s innate spellcasting ability is Charisma (spell save {@dc <$spell_dc__cha$>}). <$title_short_name$> can innately cast the following spells, requiring no material components:"
27812781
],
27822782
"will": [
27832783
"{@spell thaumaturgy}"
@@ -2992,7 +2992,7 @@
29922992
{
29932993
"name": "Innate Spellcasting",
29942994
"headerEntries": [
2995-
"<$title_short_name$>'s innate spellcasting ability is Charisma (spell save DC <$spell_dc__cha$>). <$title_short_name$> can innately cast the following spells, requiring no material components:"
2995+
"<$title_short_name$>'s innate spellcasting ability is Charisma (spell save {@dc <$spell_dc__cha$>}). <$title_short_name$> can innately cast the following spells, requiring no material components:"
29962996
],
29972997
"will": [
29982998
"{@spell animal friendship} (snakes only)",

data/book/book-mm.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -794,8 +794,8 @@
794794
"name": "Spellcasting",
795795
"page": 10,
796796
"entries": [
797-
"A monster with the Spellcasting class feature has a spellcaster level and spell slots, which it uses to cast its spells of 1st level and higher (as explained in the {@i Player's Handbook).} The spellcaster level is also used for any cantrips included in the feature.",
798-
"The monster has a list of spells known or prepared from a particular class. The list might also include spells from a feature in that class, such as the Divine Domain feature of the cleric or the Druid Circle feature of the druid. The monster is considered a member of that class when attuning to or using a magic item that requires member-ship in the class or access to its spell list.",
797+
"A monster with the Spellcasting class feature has a spellcaster level and spell slots, which it uses to cast its spells of 1st level and higher (as explained in the {@i Player's Handbook}). The spellcaster level is also used for any cantrips included in the feature.",
798+
"The monster has a list of spells known or prepared from a particular class. The list might also include spells from a feature in that class, such as the Divine Domain feature of the cleric or the Druid Circle feature of the druid. The monster is considered a member of that class when attuning to or using a magic item that requires membership in the class or access to its spell list.",
799799
"A monster can cast a spell from its list at a higher level if it has the spell slot to do so. For example, a drow mage with the 3rd-level {@spell lightning bolt} spell can cast it as a 5th-level spell by using one of its 5th-level spell slots.",
800800
"You can change the spells that a monster knows or has prepared, replacing any spell on a monster's spell list with a different spell of the same level and from the same class list. If you do so, you might cause the monster to be a greater or lesser threat than suggested by its challenge rating."
801801
],

data/changelog.json

+6
Original file line numberDiff line numberDiff line change
@@ -2415,5 +2415,11 @@
24152415
"date": "2023-05-04",
24162416
"title": "Displaced",
24172417
"txt": "- Added \"Misplaced Monster Volume 1\" content\n- (Fixed typos/added tags)"
2418+
},
2419+
{
2420+
"ver": "1.181.0",
2421+
"date": "2023-05-07",
2422+
"title": "Brewtal",
2423+
"txt": "- Fixed Items page resetting all other Miscellaneous filters when the \"Mundane\" or \"Magic\" side-labels are clicked\n- (Brew) Added `@sup`, `@sub`, and `@kbd` tags, which produce the matching HTML elements\n- (Brew) Added `\"credit\"` field to `\"image\"` entries, allowing art credits to be specified\n- (Brew) Added support for `\"colLabelGroups\"` on tables, allowing multiple rows of table headers to be specified\n- (Brew) Added support for array `\"by\"` in `\"quote\"` entries\n- (Brew) Switched to rendering `\"hpNote\"` in vehicle components as an entry supporting @tags (rather than as a plain string)\n- (Brew) Tweaked rendering of `\"list\"` names to avoid breaking names away from list bodies in columnar layouts\n- (Brew) Fixed \"Add/Edit Homebrew Source\" always setting a brew's color to #000000 when not specified\n- (Brew) Fixed Creature Text Converter silently removing \"(X with mage armor)\" (and similar) AC terms\n- ((Brew) Added HTML sanitization to homebrew repository, lessening the risk of scripting antics from \"official\" sources)\n- (Fixed typos/added tags)"
24182424
}
24192425
]

data/items.json

+3
Original file line numberDiff line numberDiff line change
@@ -17755,6 +17755,7 @@
1775517755
"page": 224,
1775617756
"rarity": "uncommon",
1775717757
"wondrous": true,
17758+
"weight": 3,
1775817759
"entries": [
1775917760
"An infernal puzzle box is a cube-shaped container 5 to 6 inches on a side, composed of airtight, interlocking parts made from materials found in the Nine Hells. Most of these boxes are made of infernal iron, though some are carved from bone or horn. Infernal puzzle boxes are used to safeguard diabolical contracts signed between devils and mortals, even after the terms of these contracts are fulfilled. An empty infernal puzzle box weighs 3 pounds regardless of the materials used to fashion it.",
1776017761
"When an object small enough to fit inside an infernal puzzle box is placed in it, the container magically seals shut around the object, and no magic can force the box open. The sealed box becomes immune to all damage as well. Every infernal puzzle box is constructed with a unique means of opening it. The trick to solving the puzzle is always mundane, never magical. Once a creature figures out the trick or sequence of steps needed to open a particular infernal puzzle box, that creature can open the box as an action, allowing access to the box's contents.",
@@ -30772,6 +30773,7 @@
3077230773
"page": 99,
3077330774
"type": "OTH",
3077430775
"rarity": "unknown",
30776+
"weight": 4,
3077530777
"entries": [
3077630778
"A shatterstick is a nonmagical, 12-inch-long, 4-pound stake made of blue-tinged infernal iron mined on Cania, the eighth layer of the Nine Hells. When embedded in earth or pounded into solid rock, the stake emits a seismic vibration in a 20-foot radius centered on itself for 1 minute, shaking the ground in that area for the duration. When the effects ends, the shatterstick breaks apart, becoming useless, and all structures within 20 feet of it take 35 ({@damage 10d6}) bludgeoning damage."
3077730779
]
@@ -31930,6 +31932,7 @@
3193031932
"page": 225,
3193131933
"rarity": "uncommon",
3193231934
"wondrous": true,
31935+
"weight": 0.333,
3193331936
"entries": [
3193431937
"Soul coins are about 5 inches across and about an inch thick, minted from infernal iron. Each coin weighs one-third of a pound, and is inscribed with Infernal writing and a spell that magically binds a single soul to the coin. Because each soul coin has a unique soul trapped within it, each has a story. A creature might have been imprisoned as a result of defaulting on a deal, while another might be the victim of a night hag's curse.",
3193531938
{

data/renderdemo.json

+33-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
{
2222
"type": "list",
2323
"items": [
24-
"Style tags; {@bold some text to be bolded} (alternative {@b shorthand}), {@italic some text to be italicised} (alternative {@i shorthand}), {@underline some text to be underlined} (alternative {@u shorthand}), {@strike some text to strike-through}, (alternative {@s shorthand}), {@color color|e40707}/{@color color variable|--rgb-name} tags, {@highlight highlight} tags, {@code print(&quot;hello world&quot;)} tags, misc {@style Style|small-caps;small;capitalize;dnd-font} tags",
24+
"Style tags; {@bold some text to be bolded} (alternative {@b shorthand}), {@italic some text to be italicised} (alternative {@i shorthand}), {@underline some text to be underlined} (alternative {@u shorthand}), {@strike some text to strike-through}, (alternative {@s shorthand}), {@color color|e40707}/{@color color variable|--rgb-name} tags, {@highlight highlight} tags, {@sup superscript} tags, {@sub subscript} tags, {@kbd keyboard} tags, {@code print(&quot;hello world&quot;)} tags, misc {@style Style|small-caps;small;capitalize;dnd-font} tags",
2525
"Additionally, {@note note tags}, used for adding errata or Twitter \"designer footnotes.\"",
2626
"Dice roller tags; {@dice 1d2-2+2d3+5} for regular dice rolls ({@dice 1d6;2d6} for multiple options; {@dice 1d6 + #$prompt_number:min=1,title=Enter a Number!,default=123$#} for input prompts), with extended {@dice 1d20+2|display text} and {@dice 1d20+2|display text|rolled by name}, and a special 'hit' version which assumes a d20 is to be rolled {@hit +7} (and rolls advantage on shift-click, disadvantage on alt-click). There's also {@damage 1d12+3} which will roll critical hits on shift-click and half damage (rounding down) on alt-click, and {@d20 -4} which will also roll advantage/disadvantage, although @hit tags are preferred where appropriate. Spells can have scaling-dice tags, (damage of 2d6 or 3d6 at level 1, add an extra {@scaledice 2d6;3d6|2-9|1d6} for each level beyond 2nd), for when a spell effect scales at higher levels. {@ability str 20}, {@savingThrow str 5}, and {@skillCheck animal_handling 5} are used as internal shorthand, but may be useful elsewhere.",
2727
"Auto dice tags; as above, but a result is automatically rolled upon rendering: {@autodice 2d10+2}.",
@@ -286,6 +286,36 @@
286286
"** As an extension to Bootstrap's 1-to-12 system, 1/10th subdivisions can be used, e.g. col-1-5 for 1.5/12. The total column widths should still sum to exactly 12; enjoy doing the math."
287287
]
288288
},
289+
{
290+
"type": "table",
291+
"caption": "Optional Caption",
292+
"colLabelGroups": [
293+
{
294+
"colLabels": [
295+
"Single"
296+
]
297+
},
298+
{
299+
"colLabels": [
300+
"Stacked Top",
301+
"Stacked Bottom"
302+
]
303+
},
304+
{}
305+
],
306+
"colStyles": [
307+
"col-4",
308+
"col-4",
309+
"col-4"
310+
],
311+
"rows": [
312+
[
313+
"This table has multiple header rows stacked one atop the other",
314+
"Lorem ipsum",
315+
"This column has no labels"
316+
]
317+
]
318+
},
289319
"Rollable tables can be made like so (note the 'pad' to format single digit numbers e.g. '01' for tables with >10 rows):",
290320
{
291321
"type": "table",
@@ -572,7 +602,8 @@
572602
"type": "internal",
573603
"path": "blank.png"
574604
},
575-
"title": "Optional Title"
605+
"title": "Optional Title",
606+
"credit": "Optional credit"
576607
},
577608
{
578609
"type": "entries",

js/converterutils-creature.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class AcConvert {
44
static tryPostProcessAc (mon, cbMan, cbErr) {
55
if (this._tryPostProcessAc_special(mon, cbMan, cbErr)) return;
66

7-
let nuAc = [];
7+
const nuAc = [];
88

99
const parts = mon.ac.trim().split(StrUtil.COMMAS_NOT_IN_PARENTHESES_REGEX).map(it => it.trim()).filter(Boolean);
1010
parts.forEach(pt => {
@@ -24,7 +24,7 @@ class AcConvert {
2424
// Plain number
2525
if (!fromRaw) return nuAc.push(acNum);
2626

27-
let nxtAc = null; // A distinct AC value included in this text from e.g. mage armor
27+
const nuAcTail = [];
2828
const cur = {ac: acNum};
2929
const froms = [];
3030

@@ -85,11 +85,11 @@ class AcConvert {
8585
return `{@item ${name}${source ? `|${source}` : "|"}|${mWithBarding.groups.name}}`;
8686
});
8787

88-
nxtAc = {
88+
nuAcTail.push({
8989
ac: Number(mWithBarding.groups.ac),
9090
condition: `with ${simpleFromBarding}`,
9191
braces: true,
92-
};
92+
});
9393

9494
return;
9595
}
@@ -104,11 +104,11 @@ class AcConvert {
104104
else if (numMatch[2] === "barkskin") spell = `{@spell barkskin}`;
105105
else throw new Error(`Unhandled spell! ${numMatch[2]}`);
106106

107-
nxtAc = {
107+
nuAcTail.push({
108108
ac: Number(numMatch[1]),
109109
condition: `with ${spell}`,
110110
braces: true,
111-
};
111+
});
112112

113113
return;
114114
}
@@ -137,6 +137,8 @@ class AcConvert {
137137
} else {
138138
nuAc.push(cur.ac);
139139
}
140+
141+
if (nuAcTail.length) nuAc.push(...nuAcTail);
140142
});
141143

142144
mon.ac = nuAc;

js/converterutils-spell.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class MiscTagsTagger {
138138
object: (obj) => {
139139
if (obj.type !== "table") return;
140140

141-
const rollMode = Renderer.getAutoConvertedTableRollMode(obj);
141+
const rollMode = Renderer.table.getAutoConvertedRollMode(obj);
142142
if (rollMode !== RollerUtil.ROLL_COL_NONE) this._addTag({tags, tag: "RO", options});
143143
},
144144
},

js/items.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -373,12 +373,22 @@ class ItemsPage extends ListPage {
373373
$(`.side-label--mundane`).click(() => {
374374
const filterValues = this._pageFilter.filterBox.getValues();
375375
const curValue = MiscUtil.get(filterValues, "Miscellaneous", "Mundane");
376-
this._pageFilter.filterBox.setFromValues({Miscellaneous: {Mundane: curValue === 1 ? 0 : 1}});
376+
this._pageFilter.filterBox.setFromValues({
377+
Miscellaneous: {
378+
...(filterValues?.Miscellaneous || {}),
379+
Mundane: curValue === 1 ? 0 : 1,
380+
},
381+
});
377382
});
378383
$(`.side-label--magic`).click(() => {
379384
const filterValues = this._pageFilter.filterBox.getValues();
380385
const curValue = MiscUtil.get(filterValues, "Miscellaneous", "Magic");
381-
this._pageFilter.filterBox.setFromValues({Miscellaneous: {Magic: curValue === 1 ? 0 : 1}});
386+
this._pageFilter.filterBox.setFromValues({
387+
Miscellaneous: {
388+
...(filterValues?.Miscellaneous || {}),
389+
Magic: curValue === 1 ? 0 : 1,
390+
},
391+
});
382392
});
383393
const $outVisibleResults = $(`.lst__wrp-search-visible`);
384394
const $wrpListMundane = $(`.itm__wrp-list--mundane`);

js/render-card.js

+22-10
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,20 @@ class RendererCard {
9696

9797
if (entry.caption) textStack[0] += `text | <b>${entry.caption}</b>\n`;
9898

99-
if (entry.colLabels && entry.colLabels.length) {
100-
textStack[0] += `text | `;
101-
for (let i = 0; i < entry.colLabels.length; ++i) {
102-
const label = entry.colLabels[i];
103-
this._recursiveRender(label, textStack, meta);
104-
if (i !== entry.colLabels.length - 1) textStack[0] += _VERTICAL_LINE;
99+
const headerRowMetas = Renderer.table.getHeaderRowMetas(entry);
100+
if (headerRowMetas) {
101+
for (let ixRow = 0; ixRow < headerRowMetas.length; ++ixRow) {
102+
textStack[0] += `text | `;
103+
104+
const headerRowMeta = headerRowMetas[ixRow];
105+
for (let ixCell = 0; ixCell < headerRowMeta.length; ++ixCell) {
106+
const label = headerRowMeta[ixCell];
107+
this._recursiveRender(label, textStack, meta);
108+
if (ixCell !== headerRowMeta.length - 1) textStack[0] += _VERTICAL_LINE;
109+
}
110+
111+
textStack[0] += `\n`;
105112
}
106-
textStack[0] += `\n`;
107113
}
108114

109115
if (!entry.rows || !entry.rows.length) return;
@@ -219,9 +225,15 @@ class RendererCard {
219225
this._recursiveRender(entry.entries[i], textStack, meta, {prefix: "text | <i>", suffix: "</i>"});
220226
textStack[0] += `\n`;
221227
}
222-
if (entry.by) {
223-
const tempStack = ["text | \u2014 "];
224-
this._recursiveRender(entry.by, tempStack, meta);
228+
const byArr = this._renderQuote_getBy(entry);
229+
if (byArr) {
230+
const tempStack = [];
231+
for (let i = 0, len = byArr.length; i < len; ++i) {
232+
const by = byArr[i];
233+
tempStack[0] += `text | ${!i ? `\u2014 ` : ""}`;
234+
this._recursiveRender(by, tempStack, meta);
235+
if (i < len - 1) tempStack[0] += "\n";
236+
}
225237
textStack[0] += `${tempStack.join("")}${entry.from ? `, <i>${entry.from}</i>` : ""}\n`;
226238
}
227239
}

0 commit comments

Comments
 (0)