Skip to content

Commit 9f583d1

Browse files
committed
v1.181.3
1 parent e8565f5 commit 9f583d1

26 files changed

+585
-344
lines changed

data/adventure/adventure-cos.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -30497,11 +30497,11 @@
3049730497
"Strahd has returned to the temple several times to learn new magic and to find a means of escaping his fate, but the Dark Powers have no intention of giving him up. These recent years have been difficult for {@creature Exethanter|CoS}, whose body and mind have been falling apart. The lich has grown weak and forgetful. He no longer remembers his name or his spells. He knows only that the Dark Powers that created Strahd's domain were born in the temple, and that these entities feed on the evil that Strahd represents. Strahd is the darkness that sustains them.",
3049830498
"Characters who visit the temple can sense the presence of great evil. The dark vestiges imprisoned within the temple will try to corrupt them, offering them secrets and gifts in exchange for a taste of the evil that lurks within their true hearts.",
3049930499
{
30500-
"type": "quote",
30500+
"type": "insetReadaloud",
3050130501
"entries": [
30502-
"I would not be called 'death' so soon. I made a pact with death, a pact of blood."
30503-
],
30504-
"by": "Tome of Strahd"
30502+
"I would not be called 'death' so soon. I made a pact with death, a pact of blood.",
30503+
"\u2014Tome of Strahd"
30504+
]
3050530505
},
3050630506
{
3050730507
"type": "section",

data/changelog.json

+5
Original file line numberDiff line numberDiff line change
@@ -2431,5 +2431,10 @@
24312431
"ver": "1.181.2",
24322432
"date": "2023-05-25",
24332433
"txt": "- Added more options to the Classes Page \"Filter...\" dropdown\n - \"View Official\" renamed to \"View Default\"\n - Added \"View Official\" which shows official sources only (no homebrew)\n - Added \"View Homebrew\" which shows homebrew\n- Added resource consumption display to Optional Features\n- Fixed pinned lists being displayed when printing\n- (Brew) Added support for `\"bonus\"` spellcasting `\"displayAs\"`\n- (Fixed typos/added tags)"
2434+
},
2435+
{
2436+
"ver": "1.181.3",
2437+
"date": "2023-05-28",
2438+
"txt": "- Fixed Spells Page failing to filter combined class/class variant spells in some cases\n- (Brew) Added support for `\"reaction\"` spellcasting `\"displayAs\"`\n- (Fixed typos/added tags)"
24342439
}
24352440
]

data/class/class-artificer.json

+33
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@
5050
"{@item tinker's tools|PHB}",
5151
"one type of {@item artisan's tools|PHB} of your choice"
5252
],
53+
"toolProficiencies": [
54+
{
55+
"thieves' tools": true,
56+
"tinker's tools": true,
57+
"anyArtisansTool": 1
58+
}
59+
],
5360
"skills": [
5461
{
5562
"choose": {
@@ -445,6 +452,13 @@
445452
"{@item tinker's tools|PHB}",
446453
"one type of {@item artisan's tools|PHB} of your choice"
447454
],
455+
"toolProficiencies": [
456+
{
457+
"thieves' tools": true,
458+
"tinker's tools": true,
459+
"anyArtisansTool": 1
460+
}
461+
],
448462
"skills": [
449463
{
450464
"choose": {
@@ -515,6 +529,12 @@
515529
"tools": [
516530
"{@item thieves' tools|PHB}",
517531
"{@item tinker's tools|PHB}"
532+
],
533+
"toolProficiencies": [
534+
{
535+
"thieves' tools": true,
536+
"tinker's tools": true
537+
}
518538
]
519539
}
520540
},
@@ -995,6 +1015,13 @@
9951015
"{@item tinker's tools|PHB}",
9961016
"one type of {@item artisan's tools|PHB} of your choice"
9971017
],
1018+
"toolProficiencies": [
1019+
{
1020+
"thieves' tools": true,
1021+
"tinker's tools": true,
1022+
"anyArtisansTool": 1
1023+
}
1024+
],
9981025
"skills": [
9991026
{
10001027
"choose": {
@@ -1065,6 +1092,12 @@
10651092
"tools": [
10661093
"{@item thieves' tools|PHB}",
10671094
"{@item tinker's tools|PHB}"
1095+
],
1096+
"toolProficiencies": [
1097+
{
1098+
"thieves' tools": true,
1099+
"tinker's tools": true
1100+
}
10681101
]
10691102
}
10701103
},

data/class/class-bard.json

+10
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@
111111
"tools": [
112112
"three {@item musical instrument|PHB|musical instruments} of your choice"
113113
],
114+
"toolProficiencies": [
115+
{
116+
"anyMusicalInstrument": 3
117+
}
118+
],
114119
"skills": [
115120
{
116121
"any": 3
@@ -203,6 +208,11 @@
203208
],
204209
"tools": [
205210
"one {@item musical instrument|PHB} of your choice"
211+
],
212+
"toolProficiencies": [
213+
{
214+
"anyMusicalInstrument": 1
215+
}
206216
]
207217
}
208218
},

data/class/class-druid.json

+5
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@
6969
"tools": [
7070
"{@item Herbalism kit|PHB}"
7171
],
72+
"toolProficiencies": [
73+
{
74+
"herbalism kit": true
75+
}
76+
],
7277
"skills": [
7378
{
7479
"choose": {

data/class/class-monk.json

+8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@
2121
"tools": [
2222
"any one type of {@item artisan's tools|PHB} or any one {@item musical instrument|PHB} of your choice"
2323
],
24+
"toolProficiencies": [
25+
{
26+
"anyArtisans": 1
27+
},
28+
{
29+
"anyMusicalInstrument": 1
30+
}
31+
],
2432
"skills": [
2533
{
2634
"choose": {

data/class/class-mystic.json

-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919
"weapons": [
2020
"simple"
2121
],
22-
"tools": [
23-
"None"
24-
],
2522
"skills": [
2623
{
2724
"choose": {

data/class/class-ranger.json

+5
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,11 @@
12851285
"tools": [
12861286
"{@item herbalism kit|PHB}"
12871287
],
1288+
"toolProficiencies": [
1289+
{
1290+
"herbalism kit": true
1291+
}
1292+
],
12881293
"skills": [
12891294
{
12901295
"choose": {

data/class/class-rogue.json

+10
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
"tools": [
2929
"{@item thieves' tools|PHB}"
3030
],
31+
"toolProficiencies": [
32+
{
33+
"thieves' tools": true
34+
}
35+
],
3136
"skills": [
3237
{
3338
"choose": {
@@ -129,6 +134,11 @@
129134
],
130135
"tools": [
131136
"{@item thieves' tools|PHB}"
137+
],
138+
"toolProficiencies": [
139+
{
140+
"thieves' tools": true
141+
}
132142
]
133143
}
134144
},

data/class/class-rune-scribe.json

+7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@
2323
"{@item calligrapher's supplies|PHB}",
2424
"{@item mason's tools|PHB}",
2525
"{@item woodcarver's tools|PHB}"
26+
],
27+
"toolProficiencies": [
28+
{
29+
"calligrapher's supplies": true,
30+
"mason's tools": true,
31+
"woodcarver's tools": true
32+
}
2633
]
2734
},
2835
"classTableGroups": [

data/renderdemo.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"items": [
2424
"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("hello world")} tags, misc {@style Style|small-caps;small;capitalize;dnd-font} tags, {@font alternate font|Comic Sans MS} tags",
2525
"Additionally, {@note note tags}, used for adding errata or Twitter \"designer footnotes.\"",
26-
"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.",
26+
"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 {@scaledamage 2d6;3d6|2-9|1d6} for each level beyond 2nd; or, roll 2d6 when using 1 psi point, add an {@scaledice 2d6|1,3,5,7,9|1d6|psi|extra amount} for each additional psi point spent), 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}.",
2828
"Chance tags; similar to dice roller tags, but output success/failure. Similar syntax as dice tags: {@chance 50}; {@chance 50|display text}; {@chance 50|display text|rolled by name}; {@chance 50|display text|rolled by name|on success text}; {@chance 50|display text|rolled by name|on success text|on failure text}.",
2929
"Recharge tags; output success/failure for ability recharge. {@recharge} in an ability title for '(Recharge 6)', {@recharge 4} for '(Recharge 4\u20136)'.",

data/variantrules.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4748,7 +4748,7 @@
47484748
"page": 176,
47494749
"ruleType": "V",
47504750
"entries": [
4751-
"The rules for lifting and carrying are intentionally simple. Here is a variant if you are looking for more detailed rules for determining how a character is hindered by the weight of equipment. When you use this variant, ignore the Strength column of the Armor table in chapter 5.",
4751+
"The rules for lifting and carrying are intentionally simple. Here is a variant if you are looking for more detailed rules for determining how a character is hindered by the weight of equipment. When you use this variant, ignore the Strength column of the Armor table in {@book chapter 5|PHB|5|Armor and Shields}.",
47524752
"If you carry weight in excess of 5 times your Strength score, you are encumbered, which means your speed drops by 10 feet.",
47534753
"If you carry weight in excess of 10 times your Strength score, up to your maximum carrying capacity, you are instead heavily encumbered, which means your speed drops by 20 feet and you have disadvantage on ability checks, attack rolls, and saving throws that use Strength, Dexterity, or Constitution."
47544754
]

js/bestiary.js

+15-17
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ class BestiaryPage extends ListPageMultiSource {
184184
return brew;
185185
}
186186

187+
static _tableView_getEntryPropTransform ({mon, fnGet}) {
188+
const fnGetSpellTraits = Renderer.monster.getSpellcastingRenderedTraits.bind(Renderer.monster, Renderer.get());
189+
const allEntries = fnGet(mon, {fnGetSpellTraits});
190+
return (allEntries || []).map(it => it.rendered || Renderer.get().render(it, 2)).join("");
191+
}
192+
187193
constructor () {
188194
const pFnGetFluff = Renderer.monster.pGetFluff.bind(Renderer.monster);
189195

@@ -232,32 +238,24 @@ class BestiaryPage extends ListPageMultiSource {
232238
_cr: {name: "CR", transform: mon => Parser.monCrToFull(mon.cr, {isMythic: !!mon.mythic})},
233239
_trait: {
234240
name: "Traits",
235-
transform: mon => {
236-
const fnGetSpellTraits = Renderer.monster.getSpellcastingRenderedTraits.bind(Renderer.monster, Renderer.get());
237-
const allTraits = Renderer.monster.getOrderedTraits(mon, {fnGetSpellTraits});
238-
return (allTraits || []).map(it => it.rendered || Renderer.get().render(it, 2)).join("");
239-
},
241+
transform: mon => BestiaryPage._tableView_getEntryPropTransform({mon, fnGet: Renderer.monster.getOrderedTraits}),
240242
flex: 3,
241243
},
242244
_action: {
243245
name: "Actions",
244-
transform: mon => {
245-
const fnGetSpellTraits = Renderer.monster.getSpellcastingRenderedTraits.bind(Renderer.monster, Renderer.get());
246-
const allActions = Renderer.monster.getOrderedActions(mon, {fnGetSpellTraits});
247-
return (allActions || []).map(it => it.rendered || Renderer.get().render(it, 2)).join("");
248-
},
246+
transform: mon => BestiaryPage._tableView_getEntryPropTransform({mon, fnGet: Renderer.monster.getOrderedActions}),
249247
flex: 3,
250248
},
251-
bonus: {
249+
_bonus: {
252250
name: "Bonus Actions",
253-
transform: mon => {
254-
const fnGetSpellTraits = Renderer.monster.getSpellcastingRenderedTraits.bind(Renderer.monster, Renderer.get());
255-
const allBonusActions = Renderer.monster.getOrderedBonusActions(mon, {fnGetSpellTraits});
256-
return (allBonusActions || []).map(it => it.rendered || Renderer.get().render(it, 2)).join("");
257-
},
251+
transform: mon => BestiaryPage._tableView_getEntryPropTransform({mon, fnGet: Renderer.monster.getOrderedBonusActions}),
252+
flex: 3,
253+
},
254+
_reaction: {
255+
name: "Reactions",
256+
transform: mon => BestiaryPage._tableView_getEntryPropTransform({mon, fnGet: Renderer.monster.getOrderedReactions}),
258257
flex: 3,
259258
},
260-
reaction: {name: "Reactions", transform: it => (it || []).map(x => Renderer.get().render(x, 2)).join(""), flex: 3},
261259
legendary: {name: "Legendary Actions", transform: it => (it || []).map(x => Renderer.get().render(x, 2)).join(""), flex: 3},
262260
mythic: {name: "Mythic Actions", transform: it => (it || []).map(x => Renderer.get().render(x, 2)).join(""), flex: 3},
263261
_lairActions: {

js/classes.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -1269,23 +1269,29 @@ class ClassesPage extends MixinComponentGlobalState(MixinBaseComponent(MixinProx
12691269
// endregion
12701270
}
12711271

1272-
_doSelectAllSubclasses () {
1272+
_doSelectAllSubclasses ({allowlistMods = null} = {}) {
12731273
const cls = this.activeClass;
1274-
const allStateKeys = cls.subclasses.map(sc => UrlUtil.getStateKeySubclass(sc));
1274+
const allStateKeys = cls.subclasses
1275+
.map(sc => {
1276+
return {
1277+
stateKey: UrlUtil.getStateKeySubclass(sc),
1278+
isSelected: allowlistMods == null || allowlistMods.has(ClassesPage.getSubclassCssMod(cls, sc)),
1279+
};
1280+
});
12751281

12761282
this._pageFilter.sourceFilter.doSetPillsClear();
12771283
this.filterBox.fireChangeEvent();
1278-
this._proxyAssign("state", "_state", "__state", allStateKeys.mergeMap(stateKey => ({[stateKey]: true})));
1284+
this._proxyAssign("state", "_state", "__state", allStateKeys.mergeMap(({stateKey, isSelected}) => ({[stateKey]: isSelected})));
12791285
}
12801286

12811287
async _render_pInitSubclassControls ($wrp) {
12821288
const cls = this.activeClass;
12831289

1284-
const $btnSelAll = $(`<button class="btn btn-xs btn-default" title="Select All (SHIFT to include most recent UA/etc.; CTRL to select official only)"><span class="glyphicon glyphicon-check"/></button>`)
1290+
const $btnSelAll = $(`<button class="btn btn-xs btn-default" title="Select All (SHIFT to filter for and include most recent; CTRL to select official plus homebrew)"><span class="glyphicon glyphicon-check"/></button>`)
12851291
.click(evt => {
12861292
const allStateKeys = cls.subclasses.map(sc => UrlUtil.getStateKeySubclass(sc));
12871293
if (evt.shiftKey) {
1288-
this._doSelectAllSubclasses();
1294+
this._doSelectAllSubclasses({allowlistMods: new Set(["fresh", "brew", "spicy"])});
12891295
} else if (evt.ctrlKey || evt.metaKey) {
12901296
const nxtState = {};
12911297
allStateKeys.forEach(k => nxtState[k] = false);

js/filter-backgrounds.js

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
class PageFilterBackgrounds extends PageFilter {
44
static _getToolDisplayText (tool) {
55
if (tool === "anyArtisansTool") return "Any Artisan's Tool";
6+
if (tool === "anyMusicalInstrument") return "Any Musical Instrument";
67
return tool.toTitleCase();
78
}
89

js/filter-items.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class PageFilterEquipment extends PageFilter {
7171
static mutateForFilters (item) {
7272
item._fSources = SourceFilter.getCompleteFilterSources(item);
7373

74-
item._fProperties = item.property ? item.property.map(p => Renderer.item.propertyMap[p].name).filter(n => n) : [];
74+
item._fProperties = item.property ? item.property.map(p => Renderer.item.getProperty(p).name).filter(n => n) : [];
7575

7676
item._fMisc = [];
7777
if (item._isItemGroup) item._fMisc.push("Item Group");

js/filter-spells.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,8 @@ class PageFilterSpells extends PageFilter {
496496
...s._fClasses,
497497
...s._fVariantClasses
498498
.map(it => (it.userData.definedInSource && !SourceUtil.isNonstandardSource(it.userData.definedInSource)) ? new FilterItem({item: it.userData.equivalentClassName}) : null)
499-
.filter(Boolean),
499+
.filter(Boolean)
500+
.filter(it => !s._fClasses.some(itCls => itCls.item === it.item)),
500501
];
501502
s._fRaces = Renderer.spell.getCombinedGeneric(s, {propSpell: "races", prop: "race"}).map(PageFilterSpells.getRaceFilterItem);
502503
s._fBackgrounds = Renderer.spell.getCombinedGeneric(s, {propSpell: "backgrounds", prop: "background"}).map(it => it.name);

js/makecards.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ class MakeCards extends BaseComponent {
444444
const allTraits = Renderer.monster.getOrderedTraits(mon, {fnGetSpellTraits});
445445
const allActions = Renderer.monster.getOrderedActions(mon, {fnGetSpellTraits});
446446
const allBonusActions = Renderer.monster.getOrderedBonusActions(mon, {fnGetSpellTraits});
447+
const allReactions = Renderer.monster.getOrderedReactions(mon, {fnGetSpellTraits});
447448

448449
return [
449450
this._ct_subtitle(Renderer.monster.getTypeAlignmentPart(mon)),
@@ -470,8 +471,8 @@ class MakeCards extends BaseComponent {
470471
...(allActions?.length ? this._ct_renderEntries(allActions, 2) : []),
471472
allBonusActions?.length ? this._ct_section("Bonus Actions") : null,
472473
...(allBonusActions?.length ? this._ct_renderEntries(allBonusActions, 2) : []),
473-
mon.reaction ? this._ct_section("Reactions") : null,
474-
...(mon.reaction ? this._ct_renderEntries(mon.reaction, 2) : []),
474+
allReactions?.length ? this._ct_section("Reactions") : null,
475+
...(allReactions?.length ? this._ct_renderEntries(mon.reaction, 2) : []),
475476
mon.legendary ? this._ct_section("Legendary Actions") : null,
476477
mon.legendary ? this._ct_text(this._ct_htmlToText(Renderer.monster.getLegendaryActionIntro(mon, {renderer}))) : null,
477478
...(mon.legendary ? this._ct_renderEntries(mon.legendary, 2) : []),
@@ -860,9 +861,9 @@ MakeCards.utils = class {
860861
static enhanceItemAlt (item) {
861862
delete item._fullEntries;
862863

863-
if (item.type && (MakeCards.utils.itemPropertyMap[item.type] || Renderer.item.typeMap[item.type])) {
864+
if (item.type && (MakeCards.utils.itemPropertyMap[item.type] || Renderer.item.getType(item.type))) {
864865
Renderer.item._initFullEntries(item);
865-
(((MakeCards.utils.itemTypeMap[item.type] || Renderer.item.typeMap[item.type]) || {}).entries || []).forEach(e => item._fullEntries.push(e));
866+
(((MakeCards.utils.itemTypeMap[item.type] || Renderer.item.getType(item.type)) || {}).entries || []).forEach(e => item._fullEntries.push(e));
866867
}
867868

868869
if (item.property) {
@@ -872,9 +873,9 @@ MakeCards.utils = class {
872873
Renderer.item._initFullEntries(item);
873874
MakeCards.utils.itemPropertyMap[p].entries.forEach(e => item._fullEntries.push(e));
874875
}
875-
} else if (Renderer.item.propertyMap[p].entries) {
876+
} else if (Renderer.item.getProperty(p).entries) {
876877
Renderer.item._initFullEntries(item);
877-
Renderer.item.propertyMap[p].entries.forEach(e => item._fullEntries.push(e));
878+
Renderer.item.getProperty(p).entries.forEach(e => item._fullEntries.push(e));
878879
}
879880
});
880881
}

0 commit comments

Comments
 (0)