@optolith/entity-descriptions 0.4.26 → 0.6.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 +33 -0
- package/lib/entities/activatable.d.ts +3 -3
- package/lib/entities/activatable.js +60 -29
- package/lib/entities/equipment.d.ts +2 -2
- package/lib/entities/equipment.js +7 -7
- package/lib/entities/liturgicalChant.js +19 -12
- package/lib/entities/partial/enhancements.js +2 -2
- package/lib/entities/partial/map.d.ts +25 -36
- package/lib/entities/partial/map.js +16 -15
- package/lib/entities/partial/prerequisites/prerequisiteGroups.js +9 -2
- package/lib/entities/partial/prerequisites/single/enhancement.d.ts +7 -3
- package/lib/entities/partial/prerequisites/single/enhancement.js +19 -25
- package/lib/entities/partial/rated/activatable/castingTime.d.ts +5 -5
- package/lib/entities/partial/rated/activatable/castingTime.js +6 -3
- package/lib/entities/partial/rated/activatable/cost.d.ts +20 -14
- package/lib/entities/partial/rated/activatable/cost.js +62 -27
- package/lib/entities/partial/rated/activatable/duration.d.ts +3 -3
- package/lib/entities/partial/rated/activatable/index.d.ts +6 -6
- package/lib/entities/partial/rated/activatable/index.js +4 -4
- package/lib/entities/partial/reader.d.ts +10 -0
- package/lib/entities/partial/reader.js +5 -1
- package/lib/entities/partial/units/timeSpan.d.ts +23 -15
- package/lib/entities/partial/units/timeSpan.js +17 -3
- package/lib/entities/poison.js +9 -9
- package/lib/entities/profession.js +17 -15
- package/lib/entities/spell.js +34 -18
- package/lib/helpers/enums.d.ts +2 -1
- package/lib/helpers/enums.js +1 -3
- package/lib/index.d.ts +56 -56
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -10
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [0.6.0](https://github.com/Optolith/entity-descriptions/compare/v0.5.1...v0.6.0) (2026-09-08)
|
|
6
|
+
|
|
7
|
+
### ⚠ BREAKING CHANGES
|
|
8
|
+
|
|
9
|
+
* **deps:** upgrade to schema 0.55.0
|
|
10
|
+
|
|
11
|
+
### build
|
|
12
|
+
|
|
13
|
+
* **deps:** upgrade to schema 0.55.0 ([0dff095](https://github.com/Optolith/entity-descriptions/commit/0dff0950d939beec0e688e792c58d6d0a2ce44d7))
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* restricted blessings for traditions ([ca26c4c](https://github.com/Optolith/entity-descriptions/commit/ca26c4cadc77198b164967074735707ac6ec8593)), closes [#42](https://github.com/Optolith/entity-descriptions/issues/42)
|
|
18
|
+
## [0.5.1](https://github.com/Optolith/entity-descriptions/compare/v0.5.0...v0.5.1) (2026-09-08)
|
|
19
|
+
## [0.5.0](https://github.com/Optolith/entity-descriptions/compare/v0.4.26...v0.5.0) (2026-09-08)
|
|
20
|
+
|
|
21
|
+
### ⚠ BREAKING CHANGES
|
|
22
|
+
|
|
23
|
+
* **deps:** upgrade to schema 0.54.0 and other newer dependencies
|
|
24
|
+
|
|
25
|
+
### build
|
|
26
|
+
|
|
27
|
+
* **deps:** upgrade to schema 0.54.0 and other newer dependencies ([5ebe2df](https://github.com/Optolith/entity-descriptions/commit/5ebe2df9e468da66f792dd6e40e414037f395579))
|
|
28
|
+
|
|
29
|
+
### Features
|
|
30
|
+
|
|
31
|
+
* attributed names for enhancement prerequisites ([0e8600a](https://github.com/Optolith/entity-descriptions/commit/0e8600ac4999c4c7f83b6c719d8955dcc7f87512))
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
* do not display enchantment parent in parent description ([7e3d5da](https://github.com/Optolith/entity-descriptions/commit/7e3d5daf565eb1729b6f6a31229cd7bfa826bf0d)), closes [#26](https://github.com/Optolith/entity-descriptions/issues/26)
|
|
36
|
+
* indentation for multi-paragraph enhancements ([206f13c](https://github.com/Optolith/entity-descriptions/commit/206f13cc5730148e98c5263cc891a53c10391e3f))
|
|
37
|
+
* sort liturgical chant traditions alphabetically ([2255cd4](https://github.com/Optolith/entity-descriptions/commit/2255cd44f8df474ce4b17b253ead84c4f2c10217)), closes [#35](https://github.com/Optolith/entity-descriptions/issues/35)
|
|
5
38
|
## [0.4.26](https://github.com/Optolith/entity-descriptions/compare/v0.4.25...v0.4.26) (2026-06-21)
|
|
6
39
|
|
|
7
40
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ActivatableIdentifier, AdvancedSpecialAbility, AdvantageDisadvantagePrerequisites, AdventurePointsValue, ApplicableCombatTechniques, Aspect_ID,
|
|
1
|
+
import type { ActivatableIdentifier, AdvancedSpecialAbility, AdvantageDisadvantagePrerequisites, AdventurePointsValue, ApplicableCombatTechniques, Aspect_ID, DaggerRitualCost, EnchantmentCost, Errata, GeneralPrerequisites, MagicalSignCost, Penalty, PropertyDeclaration, PublicationRefs, RatedIdentifier, SelectOptions, SpecialRule, Volume } from "@optolith/database-schema/gen";
|
|
2
2
|
import { Case } from "tsondb/schema/gen";
|
|
3
3
|
import type { GetAllInstances, GetInstanceById } from "../helpers/getTypes.js";
|
|
4
4
|
import type { GetAllResolvedNewSkillApplications, GetAllResolvedSelectOptions, GetAllResolvedSkillUses } from "../index.js";
|
|
@@ -12,7 +12,7 @@ export type BaseActivatable = {
|
|
|
12
12
|
levels?: number;
|
|
13
13
|
maximum?: number;
|
|
14
14
|
select_options?: SelectOptions;
|
|
15
|
-
usage_type?:
|
|
15
|
+
usage_type?: Case<"Passive" | "Active" | "BasicManeuver" | "SpecialManeuver">;
|
|
16
16
|
advanced?: AdvancedSpecialAbility<AdvancedIdentifierSpecialAbility>[];
|
|
17
17
|
penalty?: Penalty;
|
|
18
18
|
combat_techniques?: ApplicableCombatTechniques;
|
|
@@ -47,7 +47,7 @@ export type BaseActivatableTranslation = {
|
|
|
47
47
|
* Get a JSON representation of the rules text for a special ability.
|
|
48
48
|
*/
|
|
49
49
|
export declare const getActivatableEntityDescription: import("../creator.js").EntityDescriptionCreator<"Advantage" | "Disadvantage" | "AdvancedCombatSpecialAbility" | "AdvancedKarmaSpecialAbility" | "AdvancedMagicalSpecialAbility" | "AdvancedSkillSpecialAbility" | "AncestorGlyph" | "ArcaneOrbEnchantment" | "AttireEnchantment" | "Beutelzauber" | "BlessedTradition" | "BowlEnchantment" | "BrawlingSpecialAbility" | "CauldronEnchantment" | "CeremonialItemSpecialAbility" | "ChronicleEnchantment" | "CombatSpecialAbility" | "CombatStyleSpecialAbility" | "CommandSpecialAbility" | "DaggerRitual" | "FamiliarSpecialAbility" | "FatePointSexSpecialAbility" | "FatePointSpecialAbility" | "FoolsHatEnchantment" | "GeneralSpecialAbility" | "Haubenzauber" | "Hauerkettenzauber" | "InstrumentEnchantment" | "KarmaSpecialAbility" | "Keulenzauber" | "Krallenkettenzauber" | "Kristallkugelzauber" | "LiturgicalStyleSpecialAbility" | "LycantropicGift" | "MagicalSign" | "MagicalSpecialAbility" | "MagicalTradition" | "MagicStyleSpecialAbility" | "OrbEnchantment" | "PactGift" | "ProtectiveWardingCircleSpecialAbility" | "RingEnchantment" | "Schweinetrommelzauber" | "Sermon" | "SexSpecialAbility" | "SickleRitual" | "SikaryanDrainSpecialAbility" | "SkillStyleSpecialAbility" | "SpellSwordEnchantment" | "StaffEnchantment" | "ToyEnchantment" | "Trinkhornzauber" | "VampiricGift" | "Vision" | "WandEnchantment" | "WeaponEnchantment", {
|
|
50
|
-
getInstanceById: GetInstanceById<"Publication" | "Subject" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "TradeSecret" | "Aspect" | "Property" | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Weapon" | "Patron" | "PersonalityTrait">;
|
|
50
|
+
getInstanceById: GetInstanceById<"Publication" | "Subject" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "TradeSecret" | "Aspect" | "Property" | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Weapon" | "Patron" | "PersonalityTrait" | "Blessing">;
|
|
51
51
|
getAllInstances: GetAllInstances<"Script">;
|
|
52
52
|
getResolvedSelectOptionById: GetResolvedSelectOptionById;
|
|
53
53
|
getAllResolvedSelectOptions: GetAllResolvedSelectOptions;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isNotEmpty } from "@elyukai/utils/array/nonEmpty";
|
|
2
2
|
import { count } from "@elyukai/utils/array/reductions";
|
|
3
3
|
import { deepEqual } from "@elyukai/utils/equality";
|
|
4
|
-
import { on } from "@elyukai/utils/function";
|
|
4
|
+
import { constant, on } from "@elyukai/utils/function";
|
|
5
5
|
import { isNotNullish } from "@elyukai/utils/nullable";
|
|
6
6
|
import { Reader } from "@elyukai/utils/reader";
|
|
7
7
|
import { numAsc } from "@optolith/helpers/compare";
|
|
@@ -18,6 +18,7 @@ import { attributedName } from "./partial/markdown.js";
|
|
|
18
18
|
import { additionFormatter } from "./partial/mathOperation.js";
|
|
19
19
|
import { printAdvantageDisadvantagePrerequisites, printGeneralPrerequisites, } from "./partial/prerequisites/index.js";
|
|
20
20
|
import { printActivatableName, } from "./partial/prerequisites/single/activatable.js";
|
|
21
|
+
import { renderStandaloneCostMap } from "./partial/rated/activatable/cost.js";
|
|
21
22
|
import { parensIf } from "./partial/rated/activatable/parensIf.js";
|
|
22
23
|
import { attributedNameR, localeSortR, translateR, } from "./partial/reader.js";
|
|
23
24
|
import { getResponsiveText, getResponsiveTextOptional, ResponsiveTextSize, } from "./partial/responsiveText.js";
|
|
@@ -274,7 +275,7 @@ const renderVolumeValue = (translate, translateMap, getAllResolvedSelectOptions,
|
|
|
274
275
|
levels: volume.ByLevel.list.map((_, index) => romanize(index + 1)).join("/"),
|
|
275
276
|
});
|
|
276
277
|
case "Map":
|
|
277
|
-
return renderResponsiveMap(volume.Map, option => option.points, values =>
|
|
278
|
+
return renderResponsiveMap(volume.Map, option => Reader.of(option.points), values => translateR("{$points} points", { points: values })).run({
|
|
278
279
|
translate,
|
|
279
280
|
translateMap,
|
|
280
281
|
responsiveTextSize,
|
|
@@ -297,7 +298,7 @@ const renderVolumeValue = (translate, translateMap, getAllResolvedSelectOptions,
|
|
|
297
298
|
return assertExhaustive(volume);
|
|
298
299
|
}
|
|
299
300
|
};
|
|
300
|
-
const renderArcaneEnergyCost = (translate, translateMap, localeJoin, responsiveTextSize, levels, cost) => {
|
|
301
|
+
const renderArcaneEnergyCost = (translate, translateMap, format, localeJoin, responsiveTextSize, levels, cost) => {
|
|
301
302
|
switch (cost.kind) {
|
|
302
303
|
case "Fixed": {
|
|
303
304
|
const translationWrapper = cost.Fixed.is_permanent === true
|
|
@@ -310,7 +311,7 @@ const renderArcaneEnergyCost = (translate, translateMap, localeJoin, responsiveT
|
|
|
310
311
|
? str => str
|
|
311
312
|
: str => translate("{$cost} per {$interval}", {
|
|
312
313
|
cost: str,
|
|
313
|
-
interval: formatTimeSpan(translate, responsiveTextSize, interval.unit, interval.value),
|
|
314
|
+
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, interval.unit, interval.value),
|
|
314
315
|
});
|
|
315
316
|
const wrapInPerLevel = (() => {
|
|
316
317
|
if (cost.Fixed.per_level === undefined) {
|
|
@@ -352,7 +353,7 @@ const renderArcaneEnergyCost = (translate, translateMap, localeJoin, responsiveT
|
|
|
352
353
|
case "Interval":
|
|
353
354
|
return translate("{$cost} per {$interval}", {
|
|
354
355
|
cost: translate("{$value} AE", { value: cost.Interval.value }),
|
|
355
|
-
interval: formatTimeSpan(translate, responsiveTextSize, cost.Interval.interval.unit, cost.Interval.interval.value),
|
|
356
|
+
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, cost.Interval.interval.unit, cost.Interval.interval.value),
|
|
356
357
|
});
|
|
357
358
|
case "ActivationAndHalfInterval":
|
|
358
359
|
return additionFormatter(translate("{$value} AE", {
|
|
@@ -361,7 +362,7 @@ const renderArcaneEnergyCost = (translate, translateMap, localeJoin, responsiveT
|
|
|
361
362
|
cost: translate("{$value} AE", {
|
|
362
363
|
value: Math.round(cost.ActivationAndHalfInterval.value / 2),
|
|
363
364
|
}),
|
|
364
|
-
interval: formatTimeSpan(translate, responsiveTextSize, cost.ActivationAndHalfInterval.interval.unit, cost.ActivationAndHalfInterval.interval.value),
|
|
365
|
+
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, cost.ActivationAndHalfInterval.interval.unit, cost.ActivationAndHalfInterval.interval.value),
|
|
365
366
|
}));
|
|
366
367
|
case "Indefinite":
|
|
367
368
|
return ((mapNullable(translateMap(cost.Indefinite.translations)?.description, description => getResponsiveText(description, responsiveTextSize)) ?? MISSING_VALUE) +
|
|
@@ -372,18 +373,11 @@ const renderArcaneEnergyCost = (translate, translateMap, localeJoin, responsiveT
|
|
|
372
373
|
mapNullableDefault(translateMap(option.translations)?.note, note => parensIf(getResponsiveTextOptional(note, responsiveTextSize)), "")), "disjunction"),
|
|
373
374
|
});
|
|
374
375
|
case "Map":
|
|
375
|
-
return
|
|
376
|
-
? {
|
|
377
|
-
surround: values => translate(", {$value} of which are permanent", {
|
|
378
|
-
value: values,
|
|
379
|
-
}),
|
|
380
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- is checked beforehand
|
|
381
|
-
getAdditionalValue: option => option.permanent_value,
|
|
382
|
-
}
|
|
383
|
-
: undefined).run({
|
|
376
|
+
return renderStandaloneCostMap(cost.Map).run({
|
|
384
377
|
translate,
|
|
385
378
|
translateMap,
|
|
386
379
|
responsiveTextSize,
|
|
380
|
+
energyUnit: "ArcaneEnergy",
|
|
387
381
|
});
|
|
388
382
|
case "Variable":
|
|
389
383
|
return translate("Variable");
|
|
@@ -423,7 +417,7 @@ const renderBindingCost = (translate, translateMap, localeCompare, getAllResolve
|
|
|
423
417
|
}),
|
|
424
418
|
});
|
|
425
419
|
case "Map":
|
|
426
|
-
return renderResponsiveMap(cost.Map, option => option.
|
|
420
|
+
return renderResponsiveMap(cost.Map, option => Reader.of(option.permanentValue), values => translateR("{$value} permanent AE", { value: values })).run({
|
|
427
421
|
translate,
|
|
428
422
|
translateMap,
|
|
429
423
|
responsiveTextSize,
|
|
@@ -451,7 +445,7 @@ const renderLifePointsCost = (translate, cost) => cost === undefined
|
|
|
451
445
|
? ""
|
|
452
446
|
: // eslint-disable-next-line no-irregular-whitespace
|
|
453
447
|
` (+ ${translate("{$value} LP", { value: cost.Fixed.value })})`;
|
|
454
|
-
const renderCost = (translate, translateMap, localeJoin, localeCompare, getAllResolvedSelectOptions, responsiveTextSize, levels, cost) => {
|
|
448
|
+
const renderCost = (translate, translateMap, format, localeJoin, localeCompare, getAllResolvedSelectOptions, responsiveTextSize, levels, cost) => {
|
|
455
449
|
if (typeof cost === "number") {
|
|
456
450
|
return {
|
|
457
451
|
label: translate("AE Cost"),
|
|
@@ -466,9 +460,9 @@ const renderCost = (translate, translateMap, localeJoin, localeCompare, getAllRe
|
|
|
466
460
|
label: translate("AE Cost"),
|
|
467
461
|
value: cost.kind === "ArcaneEnergyCost"
|
|
468
462
|
? "ae_cost" in cost.ArcaneEnergyCost
|
|
469
|
-
? renderArcaneEnergyCost(translate, translateMap, localeJoin, responsiveTextSize, levels, cost.ArcaneEnergyCost.ae_cost) + renderLifePointsCost(translate, cost.ArcaneEnergyCost.lp_cost)
|
|
470
|
-
: renderArcaneEnergyCost(translate, translateMap, localeJoin, responsiveTextSize, levels, cost.ArcaneEnergyCost)
|
|
471
|
-
: renderArcaneEnergyCost(translate, translateMap, localeJoin, responsiveTextSize, levels, cost),
|
|
463
|
+
? renderArcaneEnergyCost(translate, translateMap, format, localeJoin, responsiveTextSize, levels, cost.ArcaneEnergyCost.ae_cost) + renderLifePointsCost(translate, cost.ArcaneEnergyCost.lp_cost)
|
|
464
|
+
: renderArcaneEnergyCost(translate, translateMap, format, localeJoin, responsiveTextSize, levels, cost.ArcaneEnergyCost)
|
|
465
|
+
: renderArcaneEnergyCost(translate, translateMap, format, localeJoin, responsiveTextSize, levels, cost),
|
|
472
466
|
};
|
|
473
467
|
case "BindingCost":
|
|
474
468
|
return {
|
|
@@ -657,6 +651,37 @@ const renderFavoredSkillsSelection = (baseList, favoredSkillsSelection) => favor
|
|
|
657
651
|
baseList,
|
|
658
652
|
selection: names.join(", "),
|
|
659
653
|
}));
|
|
654
|
+
const getRestrictedBlessingsSpecialRuleLabelKey = (restrictedBlessings) => {
|
|
655
|
+
if (restrictedBlessings === "All") {
|
|
656
|
+
return "No Blessings";
|
|
657
|
+
}
|
|
658
|
+
switch (restrictedBlessings.kind) {
|
|
659
|
+
case "Three":
|
|
660
|
+
return "Restricted Blessings";
|
|
661
|
+
case "Six":
|
|
662
|
+
return "Strongly Restricted Blessings";
|
|
663
|
+
default:
|
|
664
|
+
return assertExhaustive(restrictedBlessings);
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
const renderRestrictedBlessingsSpecialRule = (restrictedBlessings, nameOfPeopleWithThisTradition) => translateR(getRestrictedBlessingsSpecialRuleLabelKey(restrictedBlessings)).thenW(label => restrictedBlessings === "All"
|
|
668
|
+
? translateR("{$nameOfBlessedOnes} cannot use blessings.", {
|
|
669
|
+
nameOfBlessedOnes: nameOfPeopleWithThisTradition,
|
|
670
|
+
}).map(text => ({
|
|
671
|
+
label,
|
|
672
|
+
text,
|
|
673
|
+
}))
|
|
674
|
+
: Reader.traverse(restrictedBlessings.kind === "Three"
|
|
675
|
+
? restrictedBlessings.Three
|
|
676
|
+
: restrictedBlessings.Six, id => attributedNameR("restricted-blessings", "Blessing", id).map(name => name ?? MISSING_VALUE))
|
|
677
|
+
.thenW(localeSortR)
|
|
678
|
+
.thenW(list => translateR("{$nameOfBlessedOnes} cannot use {$blessings :list type=disjunction}.", {
|
|
679
|
+
nameOfBlessedOnes: nameOfPeopleWithThisTradition,
|
|
680
|
+
blessings: list,
|
|
681
|
+
}).map(text => ({
|
|
682
|
+
label,
|
|
683
|
+
text,
|
|
684
|
+
}))));
|
|
660
685
|
const renderFavoredSkillsSpecialRule = (favoredCombatTechniques, favoredSkills, favoredSkillsSelection) => translateR("Favored Skills").thenW(label => renderFavoredCombatTechniques(favoredCombatTechniques)
|
|
661
686
|
.thenW(favoredCombatTechniquesText => renderFavoredSkillsBaseList(favoredCombatTechniquesText, favoredSkills))
|
|
662
687
|
.thenW(list => renderFavoredSkillsSelection(list, favoredSkillsSelection))
|
|
@@ -676,7 +701,11 @@ const renderPrimaryAttributeSpecialRule = (traditionName, nameOfPeopleWithThisTr
|
|
|
676
701
|
}))).map(description => ({
|
|
677
702
|
text: description,
|
|
678
703
|
}));
|
|
679
|
-
const renderAdditionalSpecialRules = (traditionName, nameOfPeopleWithThisTradition, favoredCombatTechniques, favoredSkills, favoredSkillsSelection, primaryAttribute) => Reader.sequence([
|
|
704
|
+
const renderAdditionalSpecialRules = (fixedSpecialRules, traditionName, nameOfPeopleWithThisTradition, restrictedBlessings, favoredCombatTechniques, favoredSkills, favoredSkillsSelection, primaryAttribute) => Reader.sequence([
|
|
705
|
+
restrictedBlessings === undefined
|
|
706
|
+
? Reader.of(undefined)
|
|
707
|
+
: renderRestrictedBlessingsSpecialRule(restrictedBlessings, nameOfPeopleWithThisTradition),
|
|
708
|
+
...fixedSpecialRules.map(rule => Reader.of(rule)),
|
|
680
709
|
favoredSkills === undefined
|
|
681
710
|
? Reader.of(undefined)
|
|
682
711
|
: renderFavoredSkillsSpecialRule(favoredCombatTechniques, favoredSkills, favoredSkillsSelection),
|
|
@@ -686,7 +715,7 @@ const renderAdditionalSpecialRules = (traditionName, nameOfPeopleWithThisTraditi
|
|
|
686
715
|
* Get a JSON representation of the rules text for a special ability.
|
|
687
716
|
*/
|
|
688
717
|
export const getActivatableEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getAllInstances, getResolvedSelectOptionById, getAllResolvedSelectOptions }, locale, { entity: entityName, content: entry, id }) => {
|
|
689
|
-
const { translate, translateMap } = locale;
|
|
718
|
+
const { translate, translateMap, format } = locale;
|
|
690
719
|
const translation = translateMap(entry.translations);
|
|
691
720
|
const responsiveTextSize = ResponsiveTextSize.Full;
|
|
692
721
|
if (translation === undefined) {
|
|
@@ -697,14 +726,15 @@ export const getActivatableEntityDescription = createEntityDescriptionCreator(({
|
|
|
697
726
|
translateMap,
|
|
698
727
|
getInstanceById,
|
|
699
728
|
localeCompare: locale.compare,
|
|
729
|
+
localeJoin: locale.join,
|
|
700
730
|
};
|
|
701
731
|
const baseEntry = entry;
|
|
702
732
|
const wrappedId = Case(entityName, id);
|
|
703
|
-
const
|
|
704
|
-
? renderAdditionalSpecialRules(translation.name, translation.nameOfBlessedOnes, entry.favored_combat_techniques, entry.favored_skills, entry.favored_skills_selection, entry.primary).run(env)
|
|
733
|
+
const addAdditionalSpecialRules = entityName === "BlessedTradition"
|
|
734
|
+
? (baseList) => renderAdditionalSpecialRules(baseList, translation.name, translation.nameOfBlessedOnes, entry.type.kind === "Church" ? entry.type.Church.restrictedBlessings : "All", entry.favored_combat_techniques, entry.favored_skills, entry.favored_skills_selection, entry.primary).run(env)
|
|
705
735
|
: entityName === "MagicalTradition"
|
|
706
|
-
? renderAdditionalSpecialRules(translation.name, translation.nameOfSpellcasters, undefined, undefined, undefined, entry.primary).run(env)
|
|
707
|
-
: [];
|
|
736
|
+
? (baseList) => renderAdditionalSpecialRules(baseList, translation.name, translation.nameOfSpellcasters, undefined, undefined, undefined, undefined, entry.primary).run(env)
|
|
737
|
+
: constant([]);
|
|
708
738
|
const makeTraditionName = entityName === "BlessedTradition" || entityName === "MagicalTradition"
|
|
709
739
|
? name => translate("Tradition ({$tradition})", { tradition: name })
|
|
710
740
|
: name => name;
|
|
@@ -713,6 +743,8 @@ export const getActivatableEntityDescription = createEntityDescriptionCreator(({
|
|
|
713
743
|
(baseEntry.levels !== undefined ? ` I–${romanize(baseEntry.levels)}` : ""),
|
|
714
744
|
subtitle: mapNullable(baseEntry.usage_type, usageType => {
|
|
715
745
|
switch (usageType.kind) {
|
|
746
|
+
case "Active":
|
|
747
|
+
return translate("Active");
|
|
716
748
|
case "Passive":
|
|
717
749
|
return translate("Passive");
|
|
718
750
|
case "BasicManeuver":
|
|
@@ -727,8 +759,7 @@ export const getActivatableEntityDescription = createEntityDescriptionCreator(({
|
|
|
727
759
|
body: [
|
|
728
760
|
mapNullable(translation.special_rules, specialRules => ({
|
|
729
761
|
type: "plain",
|
|
730
|
-
text: specialRules
|
|
731
|
-
.concat(additionalSpecialRules)
|
|
762
|
+
text: addAdditionalSpecialRules(specialRules)
|
|
732
763
|
.map(specialRule => specialRule.label === undefined
|
|
733
764
|
? `- ${specialRule.text}`
|
|
734
765
|
: `- *${specialRule.label}*: ${specialRule.text}`)
|
|
@@ -789,7 +820,7 @@ export const getActivatableEntityDescription = createEntityDescriptionCreator(({
|
|
|
789
820
|
label: translate("Volume"),
|
|
790
821
|
value: renderVolumeValue(translate, translateMap, () => getAllResolvedSelectOptions(wrappedId), responsiveTextSize, volume),
|
|
791
822
|
})),
|
|
792
|
-
mapNullable(baseEntry.cost, cost => renderCost(translate, translateMap, locale.join, locale.compare, () => getAllResolvedSelectOptions(wrappedId), responsiveTextSize, baseEntry.levels, cost)),
|
|
823
|
+
mapNullable(baseEntry.cost, cost => renderCost(translate, translateMap, format, locale.join, locale.compare, () => getAllResolvedSelectOptions(wrappedId), responsiveTextSize, baseEntry.levels, cost)),
|
|
793
824
|
mapNullable(baseEntry.property, property => ({
|
|
794
825
|
label: translate("Property"),
|
|
795
826
|
value: renderPropertyValue(getInstanceById, translate, translateMap, property),
|
|
@@ -2,7 +2,7 @@ import type { AmmunitionishIdentifier, EquipmentIdentifier, GenMeleeWeapon, GenR
|
|
|
2
2
|
import { type TaggedEntity } from "../creator.js";
|
|
3
3
|
import type { GetInstanceById } from "../helpers/getTypes.js";
|
|
4
4
|
import type { LocaleJoin } from "../helpers/locale.js";
|
|
5
|
-
import type { Translate, TranslateMap } from "../helpers/translate.js";
|
|
5
|
+
import type { Format, Translate, TranslateMap } from "../helpers/translate.js";
|
|
6
6
|
import type { IdMap, LabeledEntityDescriptionSection, RawEntityDescriptionSectionContent } from "../index.js";
|
|
7
7
|
/**
|
|
8
8
|
* Get the name of an equipment item.
|
|
@@ -15,7 +15,7 @@ export declare const renderMeleeWeapon: <Damage>(translate: Translate, translate
|
|
|
15
15
|
/**
|
|
16
16
|
* Render combat values of a ranged weapon.
|
|
17
17
|
*/
|
|
18
|
-
export declare const renderRangedWeapon: <Damage>(translate: Translate, translateMap: TranslateMap, getInstanceById: GetInstanceById<"RangedCombatTechnique" | AmmunitionishIdentifier["kind"]>, measurements: Required<LocaleMeasurementAdjustments>, renderDamage: (damage: Damage) => string, rangedCombatTechniqueId: string, use: GenRangedWeapon<Damage>) => LabeledEntityDescriptionSection<RawEntityDescriptionSectionContent>;
|
|
18
|
+
export declare const renderRangedWeapon: <Damage>(translate: Translate, translateMap: TranslateMap, format: Format, getInstanceById: GetInstanceById<"RangedCombatTechnique" | AmmunitionishIdentifier["kind"]>, measurements: Required<LocaleMeasurementAdjustments>, renderDamage: (damage: Damage) => string, rangedCombatTechniqueId: string, use: GenRangedWeapon<Damage>) => LabeledEntityDescriptionSection<RawEntityDescriptionSectionContent>;
|
|
19
19
|
/**
|
|
20
20
|
* Get a JSON representation of the rules text for equipment.
|
|
21
21
|
*/
|
|
@@ -162,12 +162,12 @@ export const renderMeleeWeapon = (translate, translateMap, localeJoin, getInstan
|
|
|
162
162
|
},
|
|
163
163
|
};
|
|
164
164
|
};
|
|
165
|
-
const renderReloadTime = (translate, reloadTime) => isNotEmpty(reloadTime)
|
|
165
|
+
const renderReloadTime = (translate, translateMap, format, reloadTime) => isNotEmpty(reloadTime)
|
|
166
166
|
? reloadTime.length > 1
|
|
167
167
|
? translate("{$value} actions", {
|
|
168
168
|
value: reloadTime.map(time => time.value).join("/"),
|
|
169
169
|
})
|
|
170
|
-
: formatTimeSpan(translate, ResponsiveTextSize.Full, "Actions", reloadTime[0].value)
|
|
170
|
+
: formatTimeSpan(translate, translateMap, format, ResponsiveTextSize.Full, "Actions", reloadTime[0].value)
|
|
171
171
|
: MISSING_VALUE;
|
|
172
172
|
const renderRangeBrackets = (rangeBrackets) => `${rangeBrackets.close.toFixed()}/${rangeBrackets.medium.toFixed()}/${rangeBrackets.far.toFixed()}`;
|
|
173
173
|
const renderAmmunition = (translateMap, getInstanceById, ammunition) => ammunition === undefined
|
|
@@ -177,7 +177,7 @@ const renderMeleeDamage = (translate) => (damage) => renderDiceAndFlat(translate
|
|
|
177
177
|
/**
|
|
178
178
|
* Render combat values of a ranged weapon.
|
|
179
179
|
*/
|
|
180
|
-
export const renderRangedWeapon = (translate, translateMap, getInstanceById, measurements, renderDamage, rangedCombatTechniqueId, use) => {
|
|
180
|
+
export const renderRangedWeapon = (translate, translateMap, format, getInstanceById, measurements, renderDamage, rangedCombatTechniqueId, use) => {
|
|
181
181
|
const combatTechnique = getInstanceById("RangedCombatTechnique", rangedCombatTechniqueId);
|
|
182
182
|
return {
|
|
183
183
|
type: "labeled",
|
|
@@ -193,7 +193,7 @@ export const renderRangedWeapon = (translate, translateMap, getInstanceById, mea
|
|
|
193
193
|
},
|
|
194
194
|
{
|
|
195
195
|
label: translate("Reload Time"),
|
|
196
|
-
value: renderReloadTime(translate, use.reload_time),
|
|
196
|
+
value: renderReloadTime(translate, translateMap, format, use.reload_time),
|
|
197
197
|
},
|
|
198
198
|
{
|
|
199
199
|
label: translate("Range Brackets"),
|
|
@@ -624,7 +624,7 @@ const renderBookRules = (translate, rules) => {
|
|
|
624
624
|
* Get a JSON representation of the rules text for equipment.
|
|
625
625
|
*/
|
|
626
626
|
export const getEquipmentEntityDescription = createEntityDescriptionCreator(({ getInstanceById, idMap }, locale, entry) => {
|
|
627
|
-
const { translate, translateMap } = locale;
|
|
627
|
+
const { translate, translateMap, format } = locale;
|
|
628
628
|
if (entry.entity === "Book") {
|
|
629
629
|
const translation = translateMap(entry.content.translations);
|
|
630
630
|
if (translation === undefined) {
|
|
@@ -729,7 +729,7 @@ export const getEquipmentEntityDescription = createEntityDescriptionCreator(({ g
|
|
|
729
729
|
? Object.entries(combatValues.values.melee_uses ?? {}).map(([combatTechniqueId, use]) => renderMeleeWeapon(translate, translateMap, locale.join, getInstanceById, locale.measurementAdjustments, renderMeleeDamage(translate), combatTechniqueId, use))
|
|
730
730
|
: []),
|
|
731
731
|
...(combatValues?.type === "Weapon"
|
|
732
|
-
? Object.entries(combatValues.values.ranged_uses ?? {}).map(([combatTechniqueId, use]) => renderRangedWeapon(translate, translateMap, getInstanceById, locale.measurementAdjustments, renderRangedDamage(translate), combatTechniqueId, use))
|
|
732
|
+
? Object.entries(combatValues.values.ranged_uses ?? {}).map(([combatTechniqueId, use]) => renderRangedWeapon(translate, translateMap, format, getInstanceById, locale.measurementAdjustments, renderRangedDamage(translate), combatTechniqueId, use))
|
|
733
733
|
: []),
|
|
734
734
|
{
|
|
735
735
|
type: "definitionList",
|
|
@@ -742,7 +742,7 @@ export const getEquipmentEntityDescription = createEntityDescriptionCreator(({ g
|
|
|
742
742
|
label: translate("Burning Time"),
|
|
743
743
|
value: burningTime.kind === "Unlimited"
|
|
744
744
|
? translate("unlimited")
|
|
745
|
-
: formatTimeSpan(translate, ResponsiveTextSize.Full, burningTime.Limited.unit, burningTime.Limited.value),
|
|
745
|
+
: formatTimeSpan(translate, translateMap, format, ResponsiveTextSize.Full, burningTime.Limited.unit, burningTime.Limited.value),
|
|
746
746
|
})),
|
|
747
747
|
mapNullable(baseItemTranslation?.color, color => ({
|
|
748
748
|
label: translate("Color"),
|
|
@@ -17,16 +17,19 @@ const getTextForBlessingTraditions = (deps, id) => {
|
|
|
17
17
|
const blessedTraditions = deps.getAllInstances("BlessedTradition");
|
|
18
18
|
const primaryTradition = blessedTraditions.find(trad => trad.content.primaryBlessing === id);
|
|
19
19
|
const secondaryTraditions = blessedTraditions.filter(trad => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
if (trad.content.type.kind === "Church") {
|
|
21
|
+
switch (trad.content.type.Church.restrictedBlessings?.kind) {
|
|
22
|
+
case "Six":
|
|
23
|
+
return !trad.content.type.Church.restrictedBlessings.Six.includes(id);
|
|
24
|
+
case "Three":
|
|
25
|
+
return !trad.content.type.Church.restrictedBlessings.Three.includes(id);
|
|
26
|
+
case undefined:
|
|
27
|
+
return false;
|
|
28
|
+
default:
|
|
29
|
+
return assertExhaustive(trad.content.type.Church.restrictedBlessings);
|
|
30
|
+
}
|
|
29
31
|
}
|
|
32
|
+
return false;
|
|
30
33
|
});
|
|
31
34
|
const translateTradition = (trad) => {
|
|
32
35
|
const traditionTranslation = deps.translateMap(trad.content.translations);
|
|
@@ -84,6 +87,7 @@ const getTextForTraditions = (deps, values) => {
|
|
|
84
87
|
}
|
|
85
88
|
})
|
|
86
89
|
.filter(isNotNullish)
|
|
90
|
+
.sort(deps.localeCompare)
|
|
87
91
|
.join(", ");
|
|
88
92
|
return {
|
|
89
93
|
label: deps.translate("Traditions"),
|
|
@@ -94,7 +98,7 @@ const getTextForTraditions = (deps, values) => {
|
|
|
94
98
|
* Get a JSON representation of the rules text for a blessing.
|
|
95
99
|
*/
|
|
96
100
|
export const getBlessingEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getAllInstances }, locale, { id, content: entry }) => {
|
|
97
|
-
const { translate, translateMap } = locale;
|
|
101
|
+
const { translate, translateMap, format } = locale;
|
|
98
102
|
const translation = translateMap(entry.translations);
|
|
99
103
|
if (translation === undefined) {
|
|
100
104
|
return undefined;
|
|
@@ -102,6 +106,7 @@ export const getBlessingEntityDescription = createEntityDescriptionCreator(({ ge
|
|
|
102
106
|
const env = {
|
|
103
107
|
translate,
|
|
104
108
|
translateMap,
|
|
109
|
+
format,
|
|
105
110
|
localeCompare: locale.compare,
|
|
106
111
|
getInstanceById,
|
|
107
112
|
getAllInstances,
|
|
@@ -135,7 +140,7 @@ export const getBlessingEntityDescription = createEntityDescriptionCreator(({ ge
|
|
|
135
140
|
* Get a JSON representation of the rules text for a liturgical chant.
|
|
136
141
|
*/
|
|
137
142
|
export const getLiturgicalChantEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getChildInstancesForInstanceId, idMap }, locale, { content: entry, entity, id }, options) => {
|
|
138
|
-
const { translate, translateMap, compare: localeCompare, join: localeJoin } = locale;
|
|
143
|
+
const { translate, translateMap, format, compare: localeCompare, join: localeJoin } = locale;
|
|
139
144
|
const translation = translateMap(entry.translations);
|
|
140
145
|
if (translation === undefined) {
|
|
141
146
|
return undefined;
|
|
@@ -143,6 +148,7 @@ export const getLiturgicalChantEntityDescription = createEntityDescriptionCreato
|
|
|
143
148
|
const env = {
|
|
144
149
|
translate,
|
|
145
150
|
translateMap,
|
|
151
|
+
format,
|
|
146
152
|
getInstanceById,
|
|
147
153
|
getChildInstancesForInstanceId,
|
|
148
154
|
localeJoin: locale.join,
|
|
@@ -198,7 +204,7 @@ export const getLiturgicalChantEntityDescription = createEntityDescriptionCreato
|
|
|
198
204
|
* Get a JSON representation of the rules text for a ceremony.
|
|
199
205
|
*/
|
|
200
206
|
export const getCeremonyEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getChildInstancesForInstanceId, idMap }, locale, { content: entry, entity, id }, options) => {
|
|
201
|
-
const { translate, translateMap, compare: localeCompare, join: localeJoin } = locale;
|
|
207
|
+
const { translate, translateMap, format, compare: localeCompare, join: localeJoin } = locale;
|
|
202
208
|
const translation = translateMap(entry.translations);
|
|
203
209
|
if (translation === undefined) {
|
|
204
210
|
return undefined;
|
|
@@ -206,6 +212,7 @@ export const getCeremonyEntityDescription = createEntityDescriptionCreator(({ ge
|
|
|
206
212
|
const env = {
|
|
207
213
|
translate,
|
|
208
214
|
translateMap,
|
|
215
|
+
format,
|
|
209
216
|
getInstanceById,
|
|
210
217
|
getChildInstancesForInstanceId,
|
|
211
218
|
localeJoin: locale.join,
|
|
@@ -20,7 +20,7 @@ const getEnhancementAPValue = (adventurePoints, parentImprovementCost) => {
|
|
|
20
20
|
};
|
|
21
21
|
const renderEnhancement = (enhancement, parentImprovementCost) => translateMapR(enhancement.content.translations).thenW(translation => Reader.ask().map(env => translation === undefined
|
|
22
22
|
? undefined
|
|
23
|
-
: `- ^[${translation.name}](entity: "Enhancement") (${env.translate("SR {$value}", { value: enhancement.content.skill_rating })}, ${env.translate("{$value} AP", { value: getEnhancementAPValue(enhancement.content.adventurePoints, parentImprovementCost) })}): ${translation.effect}${enhancement.content.prerequisites === undefined ? "" : ` ${env.translate(".input {$hiddenCount :number} {{Prerequisites}}", { hiddenCount: enhancement.content.prerequisites.length })}: ${printEnhancementPrerequisites(env.getInstanceById, { translate: env.translate, translateMap: env.translateMap, compare: env.localeCompare, join: env.localeJoin }, enhancement.content.prerequisites)}`}`));
|
|
23
|
+
: `- ^[${translation.name}](entity: "Enhancement") (${env.translate("SR {$value}", { value: enhancement.content.skill_rating })}, ${env.translate("{$value} AP", { value: getEnhancementAPValue(enhancement.content.adventurePoints, parentImprovementCost) })}): ${translation.effect.split("\n").join("\n ")}${enhancement.content.prerequisites === undefined ? "" : ` ${env.translate(".input {$hiddenCount :number} {{Prerequisites}}", { hiddenCount: enhancement.content.prerequisites.length })}: ${printEnhancementPrerequisites(env.getInstanceById, { translate: env.translate, translateMap: env.translateMap, compare: env.localeCompare, join: env.localeJoin }, enhancement.content.prerequisites)}`}`));
|
|
24
24
|
/**
|
|
25
25
|
* Render the enhancements section for an entity description, if applicable.
|
|
26
26
|
*/
|
|
@@ -33,7 +33,7 @@ export const renderEnhancements = (parentId, parentImprovementCost) => getChildI
|
|
|
33
33
|
}
|
|
34
34
|
return translateR("Enhancements").map((label) => ({
|
|
35
35
|
type: "labeled",
|
|
36
|
-
label
|
|
36
|
+
label: `${label}:`,
|
|
37
37
|
value: {
|
|
38
38
|
type: "plain",
|
|
39
39
|
text: nonNullishDescriptions.join("\n"),
|
|
@@ -1,51 +1,40 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
1
|
+
import { Reader } from "@elyukai/utils/reader";
|
|
2
|
+
import type { ParameterMapStyle, ResponsiveTextOptional } from "@optolith/database-schema/gen";
|
|
3
|
+
import type { LocaleMap } from "../../helpers/translate.js";
|
|
4
|
+
import { type StdEnv, type StdReader } from "./reader.js";
|
|
4
5
|
/**
|
|
5
6
|
* Renders a map of options to a string.
|
|
6
7
|
*/
|
|
7
|
-
export declare const renderMap: <
|
|
8
|
-
options: MO[];
|
|
9
|
-
style?: MapStyle;
|
|
10
|
-
translations?: LocaleMap<MT>;
|
|
11
|
-
}, MOT = M extends {
|
|
8
|
+
export declare const renderMap: <V, T, OT, VEnv, SVEnv>(map: {
|
|
12
9
|
options: {
|
|
13
|
-
|
|
10
|
+
value: V;
|
|
11
|
+
translations?: LocaleMap<OT>;
|
|
14
12
|
}[];
|
|
15
|
-
|
|
16
|
-
translations?: LocaleMap<
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
translations?: LocaleMap<MOT>;
|
|
22
|
-
})[];
|
|
23
|
-
} ? MO_ : never>(translate: Translate, translateMap: TranslateMap, map: M, getValue: (option: MO) => string | number, surroundValues: ((values: string) => string) | undefined, getLabel: (optionTranslation: MOT) => string, getListPrefix: (translation: MT) => string | undefined, getListSuffix: (translation: MT) => string | undefined, getReplacement: (translation: MT) => string | undefined, ...moreToAppend: ({
|
|
24
|
-
surround: (values: string) => string;
|
|
25
|
-
getAdditionalValue: (option: MO, optionTranslation: MOT) => string | number;
|
|
26
|
-
} | undefined)[]) => string;
|
|
13
|
+
style: ParameterMapStyle;
|
|
14
|
+
translations?: LocaleMap<T>;
|
|
15
|
+
}, getValue: (option: V) => Reader<VEnv, string | number>, surroundValues: ((values: string) => Reader<SVEnv, string>) | undefined, getLabel: (optionTranslation: OT) => string, getListPrefix: (translation: T) => string | undefined, getListSuffix: (translation: T) => string | undefined, getReplacement: (translation: T) => string | undefined, ...moreToAppend: ({
|
|
16
|
+
surround: (values: string) => StdReader<string, "t">;
|
|
17
|
+
getAdditionalValue: (option: V, optionTranslation: OT) => string | number;
|
|
18
|
+
} | undefined)[]) => Reader<StdEnv<"t" | "tm"> & VEnv & SVEnv, string>;
|
|
27
19
|
/**
|
|
28
20
|
* Renders a map of options to a string.
|
|
29
21
|
*/
|
|
30
|
-
export declare const renderResponsiveMap: <
|
|
31
|
-
options:
|
|
32
|
-
|
|
22
|
+
export declare const renderResponsiveMap: <T, VEnv, SVEnv>(map: {
|
|
23
|
+
options: {
|
|
24
|
+
value: T;
|
|
25
|
+
translations?: LocaleMap<{
|
|
26
|
+
label: ResponsiveTextOptional;
|
|
27
|
+
}>;
|
|
28
|
+
}[];
|
|
29
|
+
style: ParameterMapStyle;
|
|
33
30
|
translations?: LocaleMap<{
|
|
34
|
-
list_prepend?: ResponsiveTextOptional;
|
|
35
31
|
listPrefix?: ResponsiveTextOptional;
|
|
36
|
-
list_append?: ResponsiveTextOptional;
|
|
37
32
|
listSuffix?: ResponsiveTextOptional;
|
|
38
33
|
replacement?: ResponsiveTextOptional;
|
|
39
34
|
}>;
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}>;
|
|
44
|
-
} = M extends {
|
|
45
|
-
options: (infer MO_)[];
|
|
46
|
-
} ? MO_ : never>(map: M, getValue: (option: MO) => string | number, surroundValues: ((values: string) => string) | undefined, ...moreToAppend: ({
|
|
47
|
-
surround: (values: string) => string;
|
|
48
|
-
getAdditionalValue: (option: MO, optionTranslation: {
|
|
35
|
+
}, getValue: (option: T) => Reader<VEnv, string | number>, surroundValues: ((values: string) => Reader<SVEnv, string>) | undefined, ...moreToAppend: ({
|
|
36
|
+
surround: (values: string) => StdReader<string, "t">;
|
|
37
|
+
getAdditionalValue: (option: T, optionTranslation: {
|
|
49
38
|
label: ResponsiveTextOptional;
|
|
50
39
|
}) => string | number;
|
|
51
|
-
} | undefined)[]) =>
|
|
40
|
+
} | undefined)[]) => Reader<StdEnv<"t" | "tm" | "rts"> & VEnv & SVEnv, string>;
|
|
@@ -6,32 +6,32 @@ import { MISSING_VALUE } from "./unknown.js";
|
|
|
6
6
|
/**
|
|
7
7
|
* Renders a map of options to a string.
|
|
8
8
|
*/
|
|
9
|
-
export const renderMap = (
|
|
10
|
-
const translation = translateMap(map.translations);
|
|
9
|
+
export const renderMap = (map, getValue, surroundValues = values => Reader.of(values), getLabel, getListPrefix, getListSuffix, getReplacement, ...moreToAppend) => Reader.asks(env => {
|
|
10
|
+
const translation = env.translateMap(map.translations);
|
|
11
11
|
const replacement = mapNullable(translation, t => getReplacement(t));
|
|
12
12
|
if (isNotNullish(replacement)) {
|
|
13
13
|
return replacement;
|
|
14
14
|
}
|
|
15
|
-
if (map.style
|
|
15
|
+
if (map.style.kind === "Verbose") {
|
|
16
16
|
return map.options
|
|
17
17
|
.map(option => {
|
|
18
|
-
const value = getValue(option);
|
|
19
|
-
const optionTranslation = translateMap(option.translations);
|
|
20
|
-
return `${surroundValues(typeof value === "number" ? value.toFixed() : value)} ${translate("for")} ${mapNullableDefault(mapNullable(translation, getListPrefix), listPrefix => `${listPrefix} `, "")}${optionTranslation === undefined ? MISSING_VALUE : getLabel(optionTranslation)}${mapNullableDefault(mapNullable(translation, getListSuffix), listSuffix => ` ${listSuffix}`, "")}${moreToAppend
|
|
18
|
+
const value = getValue(option.value).run(env);
|
|
19
|
+
const optionTranslation = env.translateMap(option.translations);
|
|
20
|
+
return `${surroundValues(typeof value === "number" ? value.toFixed() : value).run(env)} ${env.translate("for")} ${mapNullableDefault(mapNullable(translation, getListPrefix), listPrefix => `${listPrefix} `, "")}${optionTranslation === undefined ? MISSING_VALUE : getLabel(optionTranslation)}${mapNullableDefault(mapNullable(translation, getListSuffix), listSuffix => ` ${listSuffix}`, "")}${moreToAppend
|
|
21
21
|
.filter(isNotNullish)
|
|
22
22
|
.map(({ surround, getAdditionalValue }) => {
|
|
23
23
|
const additionalValue = optionTranslation === undefined
|
|
24
24
|
? MISSING_VALUE
|
|
25
|
-
: getAdditionalValue(option, optionTranslation);
|
|
26
|
-
return surround(typeof additionalValue === "number" ? additionalValue.toFixed() : additionalValue);
|
|
25
|
+
: getAdditionalValue(option.value, optionTranslation);
|
|
26
|
+
return surround(typeof additionalValue === "number" ? additionalValue.toFixed() : additionalValue).run(env);
|
|
27
27
|
})
|
|
28
28
|
.join("")}`;
|
|
29
29
|
})
|
|
30
30
|
.join(", ");
|
|
31
31
|
}
|
|
32
|
-
return `${surroundValues(map.options.map(option => getValue(option)).join("/"))} ${translate("for")} ${mapNullableDefault(mapNullable(translation, getListPrefix), listPrefix => `${listPrefix} `, "")}${map.options
|
|
32
|
+
return `${surroundValues(map.options.map(option => getValue(option.value).run(env)).join("/")).run(env)} ${env.translate("for")} ${mapNullableDefault(mapNullable(translation, getListPrefix), listPrefix => `${listPrefix} `, "")}${map.options
|
|
33
33
|
.map(option => {
|
|
34
|
-
const optionTranslation = translateMap(option.translations);
|
|
34
|
+
const optionTranslation = env.translateMap(option.translations);
|
|
35
35
|
if (optionTranslation === undefined) {
|
|
36
36
|
return MISSING_VALUE;
|
|
37
37
|
}
|
|
@@ -41,16 +41,17 @@ export const renderMap = (translate, translateMap, map, getValue, surroundValues
|
|
|
41
41
|
.filter(isNotNullish)
|
|
42
42
|
.map(({ surround, getAdditionalValue }) => surround(map.options
|
|
43
43
|
.map(option => {
|
|
44
|
-
const optionTranslation = translateMap(option.translations);
|
|
44
|
+
const optionTranslation = env.translateMap(option.translations);
|
|
45
45
|
if (optionTranslation === undefined) {
|
|
46
46
|
return MISSING_VALUE;
|
|
47
47
|
}
|
|
48
|
-
return getAdditionalValue(option, optionTranslation);
|
|
48
|
+
return getAdditionalValue(option.value, optionTranslation);
|
|
49
49
|
})
|
|
50
|
-
.join("/")))
|
|
50
|
+
.join("/")).run(env))
|
|
51
51
|
.join("")}`;
|
|
52
|
-
};
|
|
52
|
+
});
|
|
53
53
|
/**
|
|
54
54
|
* Renders a map of options to a string.
|
|
55
55
|
*/
|
|
56
|
-
export const renderResponsiveMap = (map, getValue, surroundValues, ...moreToAppend) => Reader.asks(
|
|
56
|
+
export const renderResponsiveMap = (map, getValue, surroundValues, ...moreToAppend) => Reader.asks(env => renderMap(map, getValue, surroundValues, translation => getResponsiveTextOptional(translation.label, env.responsiveTextSize) ??
|
|
57
|
+
translation.label.full, translation => mapNullable(translation.listPrefix, text => getResponsiveTextOptional(text, env.responsiveTextSize)), translation => mapNullable(translation.listSuffix, text => getResponsiveTextOptional(text, env.responsiveTextSize)), translation => mapNullable(translation.replacement, text => getResponsiveTextOptional(text, env.responsiveTextSize)), ...moreToAppend).run(env));
|