@optolith/entity-descriptions 0.13.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/lib/creator.js +1 -1
- package/lib/entities/activatable.d.ts +1 -1
- package/lib/entities/activatable.js +28 -18
- package/lib/entities/culture.js +3 -3
- package/lib/entities/curriculum.js +1 -1
- package/lib/entities/elixir.js +1 -1
- package/lib/entities/equipment.js +1 -1
- package/lib/entities/liturgicalChant.d.ts +2 -2
- package/lib/entities/liturgicalChant.js +4 -0
- package/lib/entities/partial/adventurePointsValue.js +8 -7
- package/lib/entities/partial/dice.js +2 -2
- package/lib/entities/partial/enhancements.js +2 -2
- package/lib/entities/partial/herbary.js +1 -1
- package/lib/entities/partial/prerequisites/index.d.ts +6 -1
- package/lib/entities/partial/prerequisites/index.js +24 -1
- package/lib/entities/partial/prerequisites/single/personalityTrait.js +1 -1
- package/lib/entities/partial/prerequisites/single/ratedSum.js +1 -1
- package/lib/entities/partial/profession/options/combatTechniquesForAdventurePoints.d.ts +16 -0
- package/lib/entities/partial/profession/options/combatTechniquesForAdventurePoints.js +43 -0
- package/lib/entities/partial/profession/options/numberOfSpellworksTotalingAdventurePoints.d.ts +16 -0
- package/lib/entities/partial/profession/options/numberOfSpellworksTotalingAdventurePoints.js +39 -0
- package/lib/entities/partial/profession/packages.d.ts +67 -0
- package/lib/entities/partial/profession/packages.js +84 -0
- package/lib/entities/partial/profession/variants.d.ts +21 -0
- package/lib/entities/partial/profession/variants.js +31 -0
- package/lib/entities/partial/rated/activatable/cost.js +11 -9
- package/lib/entities/partial/rated/activatable/effect.js +2 -2
- package/lib/entities/partial/reader.d.ts +25 -1
- package/lib/entities/partial/reader.js +20 -0
- package/lib/entities/partial/units/energy.js +2 -1
- package/lib/entities/partial/units/length.js +6 -3
- package/lib/entities/partial/units/timeSpan.js +11 -7
- package/lib/entities/partial/unknown.d.ts +4 -0
- package/lib/entities/partial/unknown.js +4 -0
- package/lib/entities/poison.js +1 -1
- package/lib/entities/profession.js +44 -62
- package/lib/entities/spell.d.ts +2 -2
- package/lib/entities/spell.js +3 -1
- package/lib/index.d.ts +69 -68
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -2,7 +2,7 @@ import { allSame } from "@elyukai/utils/array/filters";
|
|
|
2
2
|
import { ensureNonEmpty, isEmpty, isNotEmpty, } from "@elyukai/utils/array/nonEmpty";
|
|
3
3
|
import { deepEqual, equal } from "@elyukai/utils/equality";
|
|
4
4
|
import { on } from "@elyukai/utils/function";
|
|
5
|
-
import { isNotNullish, isNullish, mapNullable
|
|
5
|
+
import { isNotNullish, isNullish, mapNullable } from "@elyukai/utils/nullable";
|
|
6
6
|
import { omitKeys } from "@elyukai/utils/object";
|
|
7
7
|
import { compareNumber } from "@elyukai/utils/ordering";
|
|
8
8
|
import { Reader } from "@elyukai/utils/reader";
|
|
@@ -13,16 +13,13 @@ import { combineNameComponents, getNameComponents, renderActivatableNameComponen
|
|
|
13
13
|
import { renderCommonnessRatedAdvantagesOrDisadvantages, renderValueWithPossibleTranslation, } from "./partial/commonnessRatedAdvantagesAndDisadvantages.js";
|
|
14
14
|
import { attributedCustomName, attributedInstance, attributedName, attributedNameFromInstance, } from "./partial/markdown.js";
|
|
15
15
|
import { printProfessionPrerequisites, printProfessionVariantPrerequisites, } from "./partial/prerequisites/index.js";
|
|
16
|
+
import { renderBaseCombatTechniquesForAdventurePointsOption, renderVariantCombatTechniquesForAdventurePointsOption, } from "./partial/profession/options/combatTechniquesForAdventurePoints.js";
|
|
17
|
+
import { renderBaseNumberOfSpellworksTotalingAdventurePoints, renderVariantNumberOfSpellworksTotalingAdventurePoints, } from "./partial/profession/options/numberOfSpellworksTotalingAdventurePoints.js";
|
|
18
|
+
import { prepareProfessionPackages, } from "./partial/profession/packages.js";
|
|
19
|
+
import { insteadOfR, renderVariantOption, renderVariantOptionPaths, } from "./partial/profession/variants.js";
|
|
16
20
|
import { parensIf } from "./partial/rated/activatable/parensIf.js";
|
|
17
|
-
import { attributedCustomNameR, attributedNameR, customNameR, formatR, getChildInstancesForInstanceIdFnR, getChildInstancesForInstanceIdR, getInstanceByIdR, localeCompareR, localeJoinR, localeSortR, strictNameR, translateMapFnR, translateR, translationR, } from "./partial/reader.js";
|
|
21
|
+
import { attributedCustomNameR, attributedNameR, customNameR, fixedNumberOrString, formatAPValue, formatR, getChildInstancesForInstanceIdFnR, getChildInstancesForInstanceIdR, getInstanceByIdR, localeCompareR, localeJoinR, localeSortR, strictNameR, translateMapFnR, translateR, translationR, } from "./partial/reader.js";
|
|
18
22
|
import { MISSING_VALUE, UNHANDLED_VALUE } from "./partial/unknown.js";
|
|
19
|
-
const prepareProfessionPackages = (professionId) => Reader.asks(({ getInstanceById, getChildInstancesForInstanceId }) => getChildInstancesForInstanceId("ProfessionPackage", professionId)
|
|
20
|
-
.map((professionPackage) => ({
|
|
21
|
-
...professionPackage,
|
|
22
|
-
experienceLevel: getInstanceById("ExperienceLevel", professionPackage.content.experience_level),
|
|
23
|
-
}))
|
|
24
|
-
.filter((professionPackage) => professionPackage.experienceLevel !== undefined)
|
|
25
|
-
.toSorted(on(item => item.experienceLevel.adventure_points, compareNumber)));
|
|
26
23
|
const renderNumericListAcrossPackages = (packages, selector, equalityFn, renderText, defaultValue) => packages
|
|
27
24
|
.reduce((accR, pkg, pkgIndex) => accR.map2(selector(pkg), (acc, selected) => selected.reduce((filledAcc, [values, number]) => {
|
|
28
25
|
const existing = filledAcc.findIndex(([value]) => equalityFn(value, values));
|
|
@@ -48,7 +45,6 @@ const renderNumericListAcrossPackages = (packages, selector, equalityFn, renderT
|
|
|
48
45
|
.thenW(list => localeSortR(list))
|
|
49
46
|
.map(list => ensureNonEmpty(list)?.join(", "));
|
|
50
47
|
const renderSinglePackageValue = (professionPackages, selector, equalityFn, renderText) => Reader.traverse(professionPackages, selector).thenW(selected => (allSame(selected, equalityFn) ? renderText([selected[0]]) : renderText(selected)));
|
|
51
|
-
const insteadOfR = (replacement, base) => translateR("{$replacement} instead of {$base}", { replacement, base });
|
|
52
48
|
/**
|
|
53
49
|
* If the selected values of the base and the variant are equal, only renders the value once. Otherwise, renders both values as the variant value replacing the base value.
|
|
54
50
|
*/
|
|
@@ -59,23 +55,14 @@ const plainOrInsteadOfR = (base, variant, selector, equality, render) => {
|
|
|
59
55
|
? render(baseValue)
|
|
60
56
|
: render(variantValue).thenW(replacement => render(baseValue).thenW(baseRendered => insteadOfR(replacement, baseRendered)));
|
|
61
57
|
};
|
|
62
|
-
const renderVariantOptionPaths = (base, variant, paths) => {
|
|
63
|
-
switch (variant.kind) {
|
|
64
|
-
case "Remove":
|
|
65
|
-
return base === undefined ? Reader.of(MISSING_VALUE) : paths.remove(base);
|
|
66
|
-
case "Override":
|
|
67
|
-
return base === undefined ? paths.add(variant.Override) : paths.update(base, variant.Override);
|
|
68
|
-
default:
|
|
69
|
-
return assertExhaustive(variant);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
58
|
const renderVariantLanguagesScriptsOption = (baseOptions, variantOptions) => renderVariantOptionPaths(baseOptions, variantOptions, {
|
|
73
|
-
remove: base => translateR("no Languages and Literacy totaling {$apValue} AP", {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
})
|
|
59
|
+
remove: base => translateR("no Languages and Literacy totaling {$apValue} AP", {
|
|
60
|
+
apValue: base.ap_value.toFixed(),
|
|
61
|
+
}),
|
|
62
|
+
add: override => translateR("Languages and Literacy totaling {$apValue} AP", {
|
|
63
|
+
apValue: override.ap_value.toFixed(),
|
|
64
|
+
}),
|
|
65
|
+
update: (base, override) => insteadOfR(override.ap_value, base.ap_value).then(apValue => translateR("Languages and Literacy totaling {$apValue} AP", {
|
|
79
66
|
apValue,
|
|
80
67
|
})),
|
|
81
68
|
});
|
|
@@ -101,17 +88,17 @@ const renderSkillSpecializationOption = (option) => Reader.asks(({ format, trans
|
|
|
101
88
|
const renderCombatTechniquesOption = (option) => isNotEmpty(option.fixed)
|
|
102
89
|
? (() => {
|
|
103
90
|
const [first, ...others] = option.fixed;
|
|
104
|
-
const firstTextR = translateR(".input {$count :number} {{{$count} of the following combat techniques {$rating}}}", { count: first.number, rating: first.rating_modifier + 6 });
|
|
91
|
+
const firstTextR = translateR(".input {$count :number} {{{$count} of the following combat techniques {$rating}}}", { count: first.number, rating: (first.rating_modifier + 6).toFixed() });
|
|
105
92
|
const fixedTextR = others.reduce((accTextR, other) => accTextR.then(accText => translateR(".input {$count :number} {{{$previous}, {$count} others {$rating}}}", {
|
|
106
93
|
count: other.number,
|
|
107
94
|
previous: accText,
|
|
108
|
-
rating: other.rating_modifier + 6,
|
|
95
|
+
rating: (other.rating_modifier + 6).toFixed(),
|
|
109
96
|
})), firstTextR);
|
|
110
97
|
const completeTextR = fixedTextR.then(fixedText => option.rest_rating_modifier === undefined
|
|
111
98
|
? Reader.of(fixedText)
|
|
112
99
|
: translateR("{$previous}, the others {$rating}", {
|
|
113
100
|
previous: fixedText,
|
|
114
|
-
rating: option.rest_rating_modifier + 6,
|
|
101
|
+
rating: (option.rest_rating_modifier + 6).toFixed(),
|
|
115
102
|
}));
|
|
116
103
|
const listR = Reader.traverse(option.options, id => attributedNameR("profession", id).map(name => name ?? MISSING_VALUE))
|
|
117
104
|
.thenW(list => localeSortR(list))
|
|
@@ -134,13 +121,13 @@ const renderSkillsOption = (professionPackages, skillGroup) => allSame(professio
|
|
|
134
121
|
? pkg.content.options.skills
|
|
135
122
|
: undefined), apValue => professionPackages[0].content.options?.skills?.specific === undefined
|
|
136
123
|
? translateR("{$apValue} AP to improve other {$skillsOfGroup}", {
|
|
137
|
-
apValue,
|
|
124
|
+
apValue: fixedNumberOrString(apValue),
|
|
138
125
|
skillsOfGroup: skillGroup.nameOfSkillsOfGroup,
|
|
139
126
|
})
|
|
140
127
|
: Reader.traverse(professionPackages[0].content.options.skills.specific, id => attributedNameR("profession", "Skill", id).map(name => name ?? MISSING_VALUE))
|
|
141
128
|
.thenW(localeSortR)
|
|
142
|
-
.thenW(list => translateR("maximum SR per skill: {$maxSR}", { maxSR: 8 }).then(maxSRText => translateR("{$apValue} AP to distribute among the following skills: {$list}", {
|
|
143
|
-
apValue,
|
|
129
|
+
.thenW(list => translateR("maximum SR per skill: {$maxSR}", { maxSR: "8" }).then(maxSRText => translateR("{$apValue} AP to distribute among the following skills: {$list}", {
|
|
130
|
+
apValue: fixedNumberOrString(apValue),
|
|
144
131
|
list: list.join(", ") + parensIf(maxSRText),
|
|
145
132
|
})))) ?? Reader.of(undefined))
|
|
146
133
|
: Reader.traverse(professionPackages, pkg => {
|
|
@@ -149,13 +136,13 @@ const renderSkillsOption = (professionPackages, skillGroup) => allSame(professio
|
|
|
149
136
|
? Reader.of("—")
|
|
150
137
|
: skillsOption.specific === undefined
|
|
151
138
|
? translateR("{$apValue} AP to improve other {$skillsOfGroup}", {
|
|
152
|
-
apValue: skillsOption.ap_value,
|
|
139
|
+
apValue: skillsOption.ap_value.toFixed(),
|
|
153
140
|
skillsOfGroup: skillGroup.nameOfSkillsOfGroup,
|
|
154
141
|
})
|
|
155
142
|
: Reader.traverse(skillsOption.specific, id => attributedNameR("profession", "Skill", id).map(name => name ?? MISSING_VALUE))
|
|
156
143
|
.thenW(localeSortR)
|
|
157
|
-
.thenW(list => translateR("maximum SR per skill: {$maxSR}", { maxSR: 8 }).then(maxSRText => translateR("{$apValue} AP to distribute among the following skills: {$list}", {
|
|
158
|
-
apValue: skillsOption.ap_value,
|
|
144
|
+
.thenW(list => translateR("maximum SR per skill: {$maxSR}", { maxSR: "8" }).then(maxSRText => translateR("{$apValue} AP to distribute among the following skills: {$list}", {
|
|
145
|
+
apValue: skillsOption.ap_value.toFixed(),
|
|
159
146
|
list: list.join(", ") + parensIf(maxSRText),
|
|
160
147
|
})));
|
|
161
148
|
}).map(list => list.join(" / "));
|
|
@@ -175,10 +162,7 @@ const renderVariantCantripsOption = (baseOptions, variantOptions) => renderVaria
|
|
|
175
162
|
}).then(baseCount => translateR(".input {$count :number} {{{$count} cantrips}}", {
|
|
176
163
|
count: override.number,
|
|
177
164
|
})
|
|
178
|
-
.then(replacementCount => translateR("{$
|
|
179
|
-
replacement: replacementCount,
|
|
180
|
-
base: baseCount,
|
|
181
|
-
}).then(count => translateR("{$count} from the following list", { count })))
|
|
165
|
+
.then(replacementCount => insteadOfR(replacementCount, baseCount).then(count => translateR("{$count} from the following list", { count })))
|
|
182
166
|
.map(text => `${text}: ${list}`)))
|
|
183
167
|
: renderCantripList(override.options)
|
|
184
168
|
.thenW(list => translateR(".input {$count :number} {{{$count} cantrips}}", {
|
|
@@ -192,10 +176,7 @@ const renderVariantCantripsOption = (baseOptions, variantOptions) => renderVaria
|
|
|
192
176
|
})
|
|
193
177
|
.then(count => translateR("{$count} from the following list", { count }))
|
|
194
178
|
.map(text => `${text}: ${list}`))
|
|
195
|
-
.then(baseText =>
|
|
196
|
-
replacement: replacementText,
|
|
197
|
-
base: baseText,
|
|
198
|
-
}))),
|
|
179
|
+
.then(baseText => insteadOfR(replacementText, baseText))),
|
|
199
180
|
});
|
|
200
181
|
const renderSingleCantripsOption = (option) => renderVariantCantripsOption(undefined, { kind: "Override", Override: option });
|
|
201
182
|
const renderCantripsOption = (professionPackages) => {
|
|
@@ -212,7 +193,7 @@ const renderCantripsOption = (professionPackages) => {
|
|
|
212
193
|
}
|
|
213
194
|
};
|
|
214
195
|
const renderLiturgiesOption = (professionPackages) => mapNullable(getTotalingAPValues(professionPackages, pkg => pkg.content.options?.liturgies), apValue => translateR("Liturgies totaling {$apValue} AP", {
|
|
215
|
-
apValue,
|
|
196
|
+
apValue: fixedNumberOrString(apValue),
|
|
216
197
|
})) ?? Reader.of(undefined);
|
|
217
198
|
const renderVariantSkillSpecializationOption = (baseOptions, variantOptions) => renderVariantOptionPaths(baseOptions, variantOptions, {
|
|
218
199
|
remove: (base) => {
|
|
@@ -260,8 +241,8 @@ const renderVariantCombatTechniquesOption = (baseOptions, variantOptions) => ren
|
|
|
260
241
|
update: (base, override) => renderCombatTechniquesOption(override).then(overrideText => renderCombatTechniquesOption(base).then(baseText => insteadOfR(overrideText, baseText))),
|
|
261
242
|
});
|
|
262
243
|
const renderVariantCursesOption = (baseOptions, variantOptions) => renderVariantOptionPaths(baseOptions, variantOptions, {
|
|
263
|
-
remove: base => translateR("no Curses totaling {$apValue} AP", { apValue: base.ap_value }),
|
|
264
|
-
add: override => translateR("Curses totaling {$apValue} AP", { apValue: override.ap_value }),
|
|
244
|
+
remove: base => translateR("no Curses totaling {$apValue} AP", { apValue: base.ap_value.toFixed() }),
|
|
245
|
+
add: override => translateR("Curses totaling {$apValue} AP", { apValue: override.ap_value.toFixed() }),
|
|
265
246
|
update: (base, override) => insteadOfR(override.ap_value, base.ap_value).then(apValue => translateR("Curses totaling {$apValue} AP", {
|
|
266
247
|
apValue,
|
|
267
248
|
})),
|
|
@@ -273,17 +254,17 @@ const renderVariantSkillsOption = (baseOptions, variantOptions) => renderVariant
|
|
|
273
254
|
skillsOfGroup: nameOfSkillsOfGroup,
|
|
274
255
|
})),
|
|
275
256
|
add: override => nameOfSkillsOfGroupR(override.group).thenW(nameOfSkillsOfGroup => translateR("{$apValue} AP to improve other {$skillsOfGroup}", {
|
|
276
|
-
apValue: override.ap_value,
|
|
257
|
+
apValue: override.ap_value.toFixed(),
|
|
277
258
|
skillsOfGroup: nameOfSkillsOfGroup,
|
|
278
259
|
})),
|
|
279
260
|
update: (base, override) => plainOrInsteadOfR(base, override, b => b.ap_value, equal, b => Reader.of(b)).thenW(apValue => plainOrInsteadOfR(base, override, b => b.group, equal, nameOfSkillsOfGroupR).thenW(nameOfSkillsOfGroup => translateR("{$apValue} AP to improve other {$skillsOfGroup}", {
|
|
280
|
-
apValue,
|
|
281
|
-
skillsOfGroup: nameOfSkillsOfGroup,
|
|
261
|
+
apValue: fixedNumberOrString(apValue),
|
|
262
|
+
skillsOfGroup: fixedNumberOrString(nameOfSkillsOfGroup),
|
|
282
263
|
}))),
|
|
283
264
|
});
|
|
284
265
|
const renderVariantLiturgiesOption = (baseOptions, variantOptions) => renderVariantOptionPaths(baseOptions, variantOptions, {
|
|
285
|
-
remove: base => translateR("no Liturgies totaling {$apValue} AP", { apValue: base.ap_value }),
|
|
286
|
-
add: override => translateR("Liturgies totaling {$apValue} AP", { apValue: override.ap_value }),
|
|
266
|
+
remove: base => translateR("no Liturgies totaling {$apValue} AP", { apValue: base.ap_value.toFixed() }),
|
|
267
|
+
add: override => translateR("Liturgies totaling {$apValue} AP", { apValue: override.ap_value.toFixed() }),
|
|
287
268
|
update: (base, override) => insteadOfR(override.ap_value, base.ap_value).then(apValue => translateR("Liturgies totaling {$apValue} AP", {
|
|
288
269
|
apValue,
|
|
289
270
|
})),
|
|
@@ -416,6 +397,9 @@ const renderCombatTechniques = (professionPackages) => Reader.sequence([
|
|
|
416
397
|
professionPackages.some(pkg => pkg.content.options?.combat_techniques !== undefined)
|
|
417
398
|
? renderSinglePackageValue(professionPackages, pkg => Reader.of(pkg.content.options?.combat_techniques), deepEqual, options => Reader.traverse(options, option => option === undefined ? Reader.of("—") : renderCombatTechniquesOption(option)).map(renderedOptions => renderedOptions.join(" / ")))
|
|
418
399
|
: Reader.of(undefined),
|
|
400
|
+
professionPackages.some(pkg => pkg.content.options?.combatTechniquesForAdventurePoints !== undefined)
|
|
401
|
+
? renderBaseCombatTechniquesForAdventurePointsOption(professionPackages)
|
|
402
|
+
: Reader.of(undefined),
|
|
419
403
|
]).map(list => ensureNonEmpty(list.filter(isNotNullish))?.join(", ") ?? "—");
|
|
420
404
|
const renderSkills = (professionPackages) => Reader.asks(({ getAllInstances }) => getAllInstances("SkillGroup")).thenW(skillGroups => Reader.traverse(skillGroups.toSorted(on(group => group.content.position, compareNumber)), ({ id: groupId, content: group }) => translationR(group).thenW(groupTranslation => Reader.sequence([
|
|
421
405
|
renderNumericListAcrossPackages(professionPackages, pkg => Reader.asks(({ getInstanceById }) => pkg.content.skills
|
|
@@ -444,6 +428,9 @@ const renderSpellworkName = (spellworkIds) => Reader.traverse(spellworkIds, spel
|
|
|
444
428
|
const renderSpellworks = (professionPackages) => Reader.sequence([
|
|
445
429
|
renderCantripsOption(professionPackages),
|
|
446
430
|
renderNumericListAcrossPackages(professionPackages, (pkg) => Reader.of(pkg.content.spells?.map(ct => [ct.id, ct.rating_modifier]) ?? []), deepEqual, renderSpellworkName, undefined),
|
|
431
|
+
professionPackages.some(pkg => pkg.content.options?.spellworks !== undefined)
|
|
432
|
+
? renderBaseNumberOfSpellworksTotalingAdventurePoints(professionPackages)
|
|
433
|
+
: Reader.of(undefined),
|
|
447
434
|
]).map(list => ensureNonEmpty(list.filter(isNotNullish))?.join("; "));
|
|
448
435
|
const retrieveBlessedTraditionIdentifierFromPrerequisiteGroup = (prerequisite) => prerequisite.kind === "Activatable" && prerequisite.Activatable.id.kind === "BlessedTradition"
|
|
449
436
|
? [prerequisite.Activatable.id.BlessedTradition]
|
|
@@ -533,17 +520,9 @@ const renderRatedVariantChanges = (baseList, variantList, renderInstance) => Rea
|
|
|
533
520
|
return renderInstance(id).map(name => `${name} ${rating_modifier.toFixed()}`);
|
|
534
521
|
}
|
|
535
522
|
const baseValue = baseList?.find(item => deepEqual(item.id, id))?.rating_modifier ?? 0;
|
|
536
|
-
return renderInstance(id).thenW(name =>
|
|
537
|
-
replacement: `${name} ${(baseValue + rating_modifier).toFixed()}`,
|
|
538
|
-
base: baseValue,
|
|
539
|
-
}));
|
|
523
|
+
return renderInstance(id).thenW(name => insteadOfR(`${name} ${(baseValue + rating_modifier).toFixed()}`, baseValue));
|
|
540
524
|
}).thenW(localeSortR);
|
|
541
|
-
const
|
|
542
|
-
? Reader.of(undefined)
|
|
543
|
-
: render(base.options?.[key], variant.options[key])).map(text => nullableToArray(text));
|
|
544
|
-
const renderProfessionVariantLabel = (base, variant, translations) => translateR("{$value} AP", {
|
|
545
|
-
value: base.ap_value + (variant.ap_value ?? 0),
|
|
546
|
-
}).thenW(apValueText => localeSortR(translations.map(({ id, content }) => `^[${content.name.default}](entity: "ProfessionVariant", instance: "${id}")`))
|
|
525
|
+
const renderProfessionVariantLabel = (base, variant, translations) => formatAPValue(base.ap_value + (variant.ap_value ?? 0)).thenW(apValueText => localeSortR(translations.map(({ id, content }) => `^[${content.name.default}](entity: "ProfessionVariant", instance: "${id}")`))
|
|
547
526
|
.thenW(list => localeJoinR(list, "conjunction"))
|
|
548
527
|
.map(names => names + parensIf(apValueText)));
|
|
549
528
|
const renderProfessionVariantText = (base, variant, translation) => translation.full_text !== undefined
|
|
@@ -557,9 +536,11 @@ const renderProfessionVariantText = (base, variant, translation) => translation.
|
|
|
557
536
|
renderVariantOption(base, variant, "skill_specialization", renderVariantSkillSpecializationOption),
|
|
558
537
|
renderVariantOption(base, variant, "languages_scripts", renderVariantLanguagesScriptsOption),
|
|
559
538
|
renderVariantOption(base, variant, "combat_techniques", renderVariantCombatTechniquesOption),
|
|
539
|
+
renderVariantOption(base, variant, "combatTechniquesForAdventurePoints", renderVariantCombatTechniquesForAdventurePointsOption),
|
|
560
540
|
renderVariantOption(base, variant, "cantrips", renderVariantCantripsOption),
|
|
561
541
|
renderVariantOption(base, variant, "curses", renderVariantCursesOption),
|
|
562
542
|
renderVariantOption(base, variant, "skills", renderVariantSkillsOption),
|
|
543
|
+
renderVariantOption(base, variant, "spellworks", renderVariantNumberOfSpellworksTotalingAdventurePoints),
|
|
563
544
|
renderVariantOption(base, variant, "liturgies", renderVariantLiturgiesOption),
|
|
564
545
|
variant.special_abilities === undefined
|
|
565
546
|
? Reader.of([])
|
|
@@ -635,10 +616,11 @@ const renderProfessionVariants = (professionPackages) => professionPackages.leng
|
|
|
635
616
|
* Get a JSON representation of the rules text for a profession version.
|
|
636
617
|
*/
|
|
637
618
|
export const getProfessionVersionEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getAllInstances, getChildInstancesForInstanceId, getResolvedSelectOptionById, }, locale, { id, content: entry }) => {
|
|
638
|
-
const { format, translate, translateMap, compare: localeCompare, join: localeJoin } = locale;
|
|
619
|
+
const { format, formatNumber, translate, translateMap, compare: localeCompare, join: localeJoin, } = locale;
|
|
639
620
|
const translation = translateMap(entry.translations);
|
|
640
621
|
const env = {
|
|
641
622
|
format,
|
|
623
|
+
formatNumber,
|
|
642
624
|
translate,
|
|
643
625
|
translateMap,
|
|
644
626
|
localeCompare,
|
package/lib/entities/spell.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare const getCantripEntityDescription: import("../creator.js").Entity
|
|
|
12
12
|
* Get a JSON representation of the rules text for a skill.
|
|
13
13
|
*/
|
|
14
14
|
export declare const getSpellEntityDescription: import("../creator.js").EntityDescriptionCreator<"Spell", {
|
|
15
|
-
getInstanceById: GetInstanceById<"Publication" | "Attribute" | "SkillModificationLevel" | "TargetCategory" | "Property" | "MagicalTradition" | "DerivedCharacteristic" | RatedIdentifier["kind"] | "Enhancement">;
|
|
15
|
+
getInstanceById: GetInstanceById<"Publication" | "Attribute" | "SkillModificationLevel" | "TargetCategory" | "Property" | "MagicalTradition" | "DerivedCharacteristic" | RatedIdentifier["kind"] | "Enhancement" | "FocusRule">;
|
|
16
16
|
getChildInstancesForInstanceId: GetAllChildInstancesForParent<"Enhancement">;
|
|
17
17
|
idMap: IdMap;
|
|
18
18
|
}, import("../index.js").EntityDescription>;
|
|
@@ -20,7 +20,7 @@ export declare const getSpellEntityDescription: import("../creator.js").EntityDe
|
|
|
20
20
|
* Get a JSON representation of the rules text for a ritual.
|
|
21
21
|
*/
|
|
22
22
|
export declare const getRitualEntityDescription: import("../creator.js").EntityDescriptionCreator<"Ritual", {
|
|
23
|
-
getInstanceById: GetInstanceById<"Publication" | "Attribute" | "SkillModificationLevel" | "TargetCategory" | "Property" | "MagicalTradition" | "DerivedCharacteristic" | RatedIdentifier["kind"] | "Enhancement">;
|
|
23
|
+
getInstanceById: GetInstanceById<"Publication" | "Attribute" | "SkillModificationLevel" | "TargetCategory" | "Property" | "MagicalTradition" | "DerivedCharacteristic" | RatedIdentifier["kind"] | "Enhancement" | "FocusRule">;
|
|
24
24
|
getChildInstancesForInstanceId: GetAllChildInstancesForParent<"Enhancement">;
|
|
25
25
|
idMap: IdMap;
|
|
26
26
|
}, import("../index.js").EntityDescription>;
|
package/lib/entities/spell.js
CHANGED
|
@@ -12,7 +12,7 @@ import { createEntityDescriptionCreator } from "../creator.js";
|
|
|
12
12
|
import { renderAnimalTypesSection } from "./partial/animalTypes.js";
|
|
13
13
|
import { renderEnhancements } from "./partial/enhancements.js";
|
|
14
14
|
import { attributedCustomName, attributedName } from "./partial/markdown.js";
|
|
15
|
-
import { printAnimistPowerPrerequisites, printGeodeRitualPrerequisites, } from "./partial/prerequisites/index.js";
|
|
15
|
+
import { getDerivedFocusRuleBadgeFromPrerequisites, printAnimistPowerPrerequisites, printGeodeRitualPrerequisites, } from "./partial/prerequisites/index.js";
|
|
16
16
|
import { renderCastingTime, renderFastSkillNonModifiableCastingTime, renderSlowSkillNonModifiableCastingTime, } from "./partial/rated/activatable/castingTime.js";
|
|
17
17
|
import { renderMagicalActionCost, renderModifiableOneTimeCost, renderNonModifiableOneTimeCost, renderNonModifiableSustainedCost, renderStandaloneCostMap, } from "./partial/rated/activatable/cost.js";
|
|
18
18
|
import { renderExpressionBasedDuration, renderMusicDuration, renderOneTimeDuration, renderSustainedDuration, } from "./partial/rated/activatable/duration.js";
|
|
@@ -162,6 +162,7 @@ export const getSpellEntityDescription = createEntityDescriptionCreator(({ getIn
|
|
|
162
162
|
return {
|
|
163
163
|
title: translation.name,
|
|
164
164
|
className: "spell",
|
|
165
|
+
badge: mapNullable(entry.prerequisites, getDerivedFocusRuleBadgeFromPrerequisites)?.run(env),
|
|
165
166
|
body: [
|
|
166
167
|
{
|
|
167
168
|
type: "definitionList",
|
|
@@ -221,6 +222,7 @@ export const getRitualEntityDescription = createEntityDescriptionCreator(({ getI
|
|
|
221
222
|
return {
|
|
222
223
|
title: translation.name,
|
|
223
224
|
className: "ritual",
|
|
225
|
+
badge: mapNullable(entry.prerequisites, getDerivedFocusRuleBadgeFromPrerequisites)?.run(env),
|
|
224
226
|
body: [
|
|
225
227
|
{
|
|
226
228
|
type: "definitionList",
|