@optolith/entity-descriptions 0.13.2 → 0.15.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 +23 -0
- package/lib/creator.d.ts +4 -11
- package/lib/creator.js +58 -2
- package/lib/entities/activatable.d.ts +5 -2
- package/lib/entities/activatable.js +29 -15
- package/lib/entities/alternativeRule.d.ts +1 -1
- package/lib/entities/attribute.d.ts +1 -3
- package/lib/entities/combatTechnique.d.ts +2 -2
- package/lib/entities/condition.d.ts +2 -6
- package/lib/entities/culture.d.ts +2 -1
- package/lib/entities/culture.js +3 -3
- package/lib/entities/curriculum.d.ts +1 -1
- package/lib/entities/curriculum.js +1 -1
- package/lib/entities/derivedCharacteristic.d.ts +1 -1
- package/lib/entities/disease.d.ts +1 -1
- package/lib/entities/elixir.d.ts +1 -1
- package/lib/entities/elixir.js +1 -1
- package/lib/entities/equipment.d.ts +4 -6
- package/lib/entities/equipment.js +517 -213
- package/lib/entities/equipmentPackage.d.ts +1 -1
- package/lib/entities/experienceLevel.d.ts +1 -3
- package/lib/entities/focusRule.d.ts +1 -1
- package/lib/entities/influence.d.ts +1 -1
- package/lib/entities/liturgicalChant.d.ts +3 -3
- package/lib/entities/optionalRule.d.ts +1 -3
- 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/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/simple.d.ts +55 -0
- package/lib/entities/partial/units/simple.js +56 -0
- 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/personalityTrait.d.ts +1 -1
- package/lib/entities/poison.d.ts +1 -1
- package/lib/entities/poison.js +1 -1
- package/lib/entities/profession.d.ts +2 -1
- package/lib/entities/profession.js +44 -62
- package/lib/entities/race.d.ts +2 -2
- package/lib/entities/sexPractice.d.ts +1 -3
- package/lib/entities/skill.d.ts +1 -1
- package/lib/entities/spell.d.ts +17 -16
- package/lib/entities/state.d.ts +1 -3
- package/lib/entities/tradeSecret.d.ts +4 -0
- package/lib/entities/tradeSecret.js +77 -0
- package/lib/env.d.ts +9 -2
- package/lib/helpers/locale.d.ts +4 -0
- package/lib/index.d.ts +320 -293
- package/lib/index.js +9 -1
- package/lib/references/index.d.ts +2 -3
- package/lib/references/index.js +11 -16
- package/lib/references/page.d.ts +4 -2
- package/lib/references/page.js +6 -4
- package/lib/references/pageRange.d.ts +3 -3
- package/lib/references/pageRange.js +6 -4
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
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.15.0](https://github.com/Optolith/entity-descriptions/compare/v0.14.0...v0.15.0) (2026-09-26)
|
|
6
|
+
|
|
7
|
+
### ⚠ BREAKING CHANGES
|
|
8
|
+
|
|
9
|
+
* tabular descriptions for most equipment
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add trade secret entity description ([6379f7d](https://github.com/Optolith/entity-descriptions/commit/6379f7d5fb111ad5960db15b16a17e9d3600bf71))
|
|
14
|
+
* tabular descriptions for most equipment ([3c53e81](https://github.com/Optolith/entity-descriptions/commit/3c53e81d8ca55b47c16ebd4727aa34531f42f965))
|
|
15
|
+
## [0.14.0](https://github.com/Optolith/entity-descriptions/compare/v0.13.2...v0.14.0) (2026-09-24)
|
|
16
|
+
|
|
17
|
+
### ⚠ BREAKING CHANGES
|
|
18
|
+
|
|
19
|
+
* **deps:** upgrade to schema 0.65.0
|
|
20
|
+
|
|
21
|
+
### build
|
|
22
|
+
|
|
23
|
+
* **deps:** upgrade to schema 0.65.0 ([cb94c96](https://github.com/Optolith/entity-descriptions/commit/cb94c96df8dc3f1d4f5476db729df2ed85ce6b1d))
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* missing adventure points label for AP value by level ([9aabd43](https://github.com/Optolith/entity-descriptions/commit/9aabd437d587e7b559c18a730249ea3c66bb8387))
|
|
5
28
|
## [0.13.2](https://github.com/Optolith/entity-descriptions/compare/v0.13.1...v0.13.2) (2026-09-16)
|
|
6
29
|
|
|
7
30
|
### Features
|
package/lib/creator.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type AnyNonNullish } from "@elyukai/utils/nullable";
|
|
1
2
|
import type { EntityMap } from "@optolith/database-schema/gen";
|
|
2
|
-
import type {
|
|
3
|
+
import type { StdEnv } from "./env.js";
|
|
3
4
|
import type { LocaleEnvironment } from "./helpers/locale.js";
|
|
4
5
|
import type { EntityDescription, RawEntityDescription } from "./index.js";
|
|
5
6
|
import { type PublicationOptions } from "./references/publicationOptions.js";
|
|
@@ -17,19 +18,11 @@ export type TaggedEntity<ES extends keyof EntityMap> = {
|
|
|
17
18
|
* Creates a function that creates the JSON representation of the rules text for
|
|
18
19
|
* a library entry.
|
|
19
20
|
*/
|
|
20
|
-
export declare const createEntityDescriptionCreator: <ES extends keyof EntityMap, A extends
|
|
21
|
-
getInstanceById: GetInstanceById<"Publication">;
|
|
22
|
-
} = {
|
|
23
|
-
getInstanceById: GetInstanceById<"Publication">;
|
|
24
|
-
}>(fn: EntityDescriptionCreator<ES, A, RawEntityDescription>) => EntityDescriptionCreator<ES, A>;
|
|
21
|
+
export declare const createEntityDescriptionCreator: <ES extends keyof EntityMap, A = AnyNonNullish, Cols extends string = never>(fn: EntityDescriptionCreator<ES, A, RawEntityDescription<Cols, A>>) => EntityDescriptionCreator<ES, A & StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">>;
|
|
25
22
|
/**
|
|
26
23
|
* A function that creates the JSON representation of the rules text for a
|
|
27
24
|
* library entry.
|
|
28
25
|
*/
|
|
29
|
-
export type EntityDescriptionCreator<ES extends keyof EntityMap = keyof EntityMap, A
|
|
30
|
-
getInstanceById: GetInstanceById<"Publication">;
|
|
31
|
-
} = {
|
|
32
|
-
getInstanceById: GetInstanceById<"Publication">;
|
|
33
|
-
}, R = EntityDescription> = (databaseAccessors: A, locale: LocaleEnvironment, entry: TaggedEntity<ES>, options: {
|
|
26
|
+
export type EntityDescriptionCreator<ES extends keyof EntityMap = keyof EntityMap, A = AnyNonNullish, R = EntityDescription<string>> = (databaseAccessors: A, locale: LocaleEnvironment, entry: TaggedEntity<ES>, options: {
|
|
34
27
|
publications: PublicationOptions;
|
|
35
28
|
}) => R | undefined;
|
package/lib/creator.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ensureNonEmpty } from "@elyukai/utils/array/nonEmpty";
|
|
1
2
|
import { isNotNullish } from "@elyukai/utils/nullable";
|
|
2
3
|
import { assertExhaustive } from "@elyukai/utils/typeSafety";
|
|
3
4
|
import { getReferencesTranslation } from "./references/index.js";
|
|
@@ -50,25 +51,80 @@ const mapRawSection = (section) => {
|
|
|
50
51
|
return assertExhaustive(section);
|
|
51
52
|
}
|
|
52
53
|
};
|
|
54
|
+
const mapRawTabular = (raw, env, options) => ({
|
|
55
|
+
...raw,
|
|
56
|
+
category: raw.category === undefined
|
|
57
|
+
? undefined
|
|
58
|
+
: {
|
|
59
|
+
label: raw.category.label.run(env),
|
|
60
|
+
value: raw.category.value.run(env),
|
|
61
|
+
},
|
|
62
|
+
labels: Object.fromEntries(Object.entries(raw.labels).map(([col, label]) => [col, label.run(env)])),
|
|
63
|
+
values: Object.fromEntries(Object.entries(raw.values).map(([col, value]) => [col, value.run(env)])),
|
|
64
|
+
additionalInformation: raw.additionalInformation === undefined
|
|
65
|
+
? undefined
|
|
66
|
+
: raw.additionalInformation
|
|
67
|
+
.map(info => {
|
|
68
|
+
if (info === undefined) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
const { label: labelR, id, value: valueR } = info;
|
|
72
|
+
const value = valueR.run(env);
|
|
73
|
+
if (value === undefined) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
label: labelR.run(env),
|
|
78
|
+
id,
|
|
79
|
+
value,
|
|
80
|
+
};
|
|
81
|
+
})
|
|
82
|
+
.filter(isNotNullish),
|
|
83
|
+
errata: raw.errata?.map(({ date, description }) => ({
|
|
84
|
+
date: env.formatDate(new Date(date)),
|
|
85
|
+
description: description.trim(),
|
|
86
|
+
})),
|
|
87
|
+
references: raw.references === undefined
|
|
88
|
+
? undefined
|
|
89
|
+
: getReferencesTranslation(options.publications, raw.references).run(env),
|
|
90
|
+
});
|
|
53
91
|
/**
|
|
54
92
|
* Creates a function that creates the JSON representation of the rules text for
|
|
55
93
|
* a library entry.
|
|
56
94
|
*/
|
|
57
95
|
export const createEntityDescriptionCreator = (fn) => (databaseAccessors, locale, entry, options) => {
|
|
58
96
|
const rawEntry = fn(databaseAccessors, locale, entry, options);
|
|
97
|
+
if (Array.isArray(rawEntry)) {
|
|
98
|
+
const results = rawEntry
|
|
99
|
+
.filter(e => isEntryFromIncludedPublication({ src: e.references }, databaseAccessors.getInstanceById, locale.translateMap, options.publications))
|
|
100
|
+
.map(e => mapRawTabular(e, databaseAccessors, options));
|
|
101
|
+
return ensureNonEmpty(results);
|
|
102
|
+
}
|
|
59
103
|
if (rawEntry === undefined ||
|
|
60
104
|
!isEntryFromIncludedPublication({ src: rawEntry.references }, databaseAccessors.getInstanceById, locale.translateMap, options.publications)) {
|
|
61
105
|
return undefined;
|
|
62
106
|
}
|
|
107
|
+
if (rawEntry.type === "tabular") {
|
|
108
|
+
return mapRawTabular(rawEntry, databaseAccessors, options);
|
|
109
|
+
}
|
|
63
110
|
return {
|
|
64
111
|
...rawEntry,
|
|
112
|
+
category: rawEntry.category === undefined
|
|
113
|
+
? undefined
|
|
114
|
+
: {
|
|
115
|
+
label: rawEntry.category.label.run(databaseAccessors),
|
|
116
|
+
value: rawEntry.category.value.run(databaseAccessors),
|
|
117
|
+
},
|
|
65
118
|
body: rawEntry.body.filter(isNotNullish).map(mapRawSection),
|
|
66
119
|
errata: rawEntry.errata?.map(({ date, description }) => ({
|
|
67
|
-
date: locale.formatDate(date),
|
|
120
|
+
date: locale.formatDate(new Date(date)),
|
|
68
121
|
description: description.trim(),
|
|
69
122
|
})),
|
|
70
123
|
references: rawEntry.references === undefined
|
|
71
124
|
? undefined
|
|
72
|
-
: getReferencesTranslation(
|
|
125
|
+
: getReferencesTranslation(options.publications, rawEntry.references).run({
|
|
126
|
+
...databaseAccessors,
|
|
127
|
+
...locale,
|
|
128
|
+
}),
|
|
73
129
|
};
|
|
74
130
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ActivatableIdentifier, ActivatableNameBuilderRules, AdvancedSpecialAbility, AdvantageDisadvantagePrerequisites, AdvantageDisadvantageSubtype, AdventurePointsValue, ApplicableCombatTechniques, Aspect_ID, Brew_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
|
+
import type { StdEnv } from "../env.js";
|
|
3
4
|
import type { GetAllInstances, GetInstanceById } from "../helpers/getTypes.js";
|
|
5
|
+
import type { TranslateMap } from "../helpers/translate.js";
|
|
4
6
|
import type { GetAllResolvedNewSkillApplications, GetAllResolvedSelectOptions, GetAllResolvedSkillUses } from "../index.js";
|
|
5
7
|
import { type GetResolvedSelectOptionById } from "./partial/prerequisites/single/activatable.js";
|
|
6
8
|
type AdvancedSpecialAbilityKind = "AdvancedSkillSpecialAbility" | "AdvancedCombatSpecialAbility" | "AdvancedMagicalSpecialAbility" | "AdvancedKarmaSpecialAbility";
|
|
@@ -51,11 +53,12 @@ export type BaseActivatableTranslation = {
|
|
|
51
53
|
* Get a JSON representation of the rules text for a special ability.
|
|
52
54
|
*/
|
|
53
55
|
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", {
|
|
54
|
-
getInstanceById: GetInstanceById<"Publication" | "Subject" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "TradeSecret" | "Aspect" | "Property" | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Weapon" | "Patron" | "PersonalityTrait" | "Brew" | "Blessing" | "Cantrip" | "FocusRule">;
|
|
56
|
+
getInstanceById: GetInstanceById<"Publication" | "Subject" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "TradeSecret" | "Aspect" | "Property" | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Weapon" | "Patron" | "PersonalityTrait" | "Brew" | "Blessing" | "Cantrip" | "FocusRule" | "CeremonialItemSpecialAbilityGroup">;
|
|
55
57
|
getAllInstances: GetAllInstances<"Script">;
|
|
56
58
|
getResolvedSelectOptionById: GetResolvedSelectOptionById;
|
|
57
59
|
getAllResolvedSelectOptions: GetAllResolvedSelectOptions;
|
|
58
60
|
getAllResolvedNewSkillApplications: GetAllResolvedNewSkillApplications;
|
|
59
61
|
getAllResolvedSkillUses: GetAllResolvedSkillUses;
|
|
60
|
-
|
|
62
|
+
translateMap: TranslateMap;
|
|
63
|
+
} & StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
|
61
64
|
export {};
|
|
@@ -22,7 +22,7 @@ import { getDerivedFocusRuleBadgeFromPrerequisites, printAdvantageDisadvantagePr
|
|
|
22
22
|
import { printActivatableName, } from "./partial/prerequisites/single/activatable.js";
|
|
23
23
|
import { renderStandaloneCostMap } from "./partial/rated/activatable/cost.js";
|
|
24
24
|
import { parensIf } from "./partial/rated/activatable/parensIf.js";
|
|
25
|
-
import { attributedNameR, localeSortR, nameR, translateR } from "./partial/reader.js";
|
|
25
|
+
import { attributedNameR, customNameR, localeSortR, nameR, translateR } from "./partial/reader.js";
|
|
26
26
|
import { getResponsiveText, getResponsiveTextOptional, ResponsiveTextSize, } from "./partial/responsiveText.js";
|
|
27
27
|
import { formatTimeSpan } from "./partial/units/timeSpan.js";
|
|
28
28
|
import { MISSING_VALUE } from "./partial/unknown.js";
|
|
@@ -44,6 +44,10 @@ const renderAdvantageDisadvantageSubtype = (subtype) => {
|
|
|
44
44
|
return translateR("Magical Rank");
|
|
45
45
|
case "MagicalTitle":
|
|
46
46
|
return translateR("Magical Title");
|
|
47
|
+
case "BlessedRank":
|
|
48
|
+
return translateR("Blessed Title");
|
|
49
|
+
case "BlessedTitle":
|
|
50
|
+
return translateR("Blessed Title");
|
|
47
51
|
default:
|
|
48
52
|
return assertExhaustive(subtype);
|
|
49
53
|
}
|
|
@@ -311,7 +315,9 @@ const renderVolumeValue = (translate, translateMap, getAllResolvedSelectOptions,
|
|
|
311
315
|
levels: volume.ByLevel.list.map((_, index) => romanize(index + 1)).join("/"),
|
|
312
316
|
});
|
|
313
317
|
case "Map":
|
|
314
|
-
return renderParameterMap(volume.Map, option => Reader.of(option.points), values => translateR("{$points} points", {
|
|
318
|
+
return renderParameterMap(volume.Map, option => Reader.of(option.points), values => translateR("{$points} points", {
|
|
319
|
+
points: typeof values === "number" ? values.toFixed() : values,
|
|
320
|
+
})).run({
|
|
315
321
|
translate,
|
|
316
322
|
translateMap,
|
|
317
323
|
responsiveTextSize,
|
|
@@ -342,7 +348,7 @@ const renderArcaneEnergyCost = (translate, translateMap, format, localeJoin, res
|
|
|
342
348
|
? value => translate(".input {$value :number} {{{$value} permanent AE}}", {
|
|
343
349
|
value,
|
|
344
350
|
})
|
|
345
|
-
: value => translate("{$value} AE", { value });
|
|
351
|
+
: value => translate("{$value} AE", { value: value.toFixed() });
|
|
346
352
|
const { interval } = cost.Fixed;
|
|
347
353
|
const wrapInInterval = interval === undefined
|
|
348
354
|
? str => str
|
|
@@ -370,40 +376,40 @@ const renderArcaneEnergyCost = (translate, translateMap, format, localeJoin, res
|
|
|
370
376
|
return wrapInPerLevel(value => wrapInInterval(translationWrapper(value))) + noteInParens;
|
|
371
377
|
}
|
|
372
378
|
case "Constant":
|
|
373
|
-
return (translate("{$value} AE", { value: cost.Constant.value }) +
|
|
379
|
+
return (translate("{$value} AE", { value: cost.Constant.value.toFixed() }) +
|
|
374
380
|
(cost.Constant.permanent_value === undefined
|
|
375
381
|
? ""
|
|
376
382
|
: translate(", {$value} of which are permanent", {
|
|
377
|
-
value: cost.Constant.permanent_value,
|
|
383
|
+
value: cost.Constant.permanent_value.toFixed(),
|
|
378
384
|
})));
|
|
379
385
|
case "PerCountable": {
|
|
380
386
|
const translation = translateMap(cost.PerCountable.translations);
|
|
381
387
|
return ((cost.PerCountable.base_value === undefined
|
|
382
388
|
? ""
|
|
383
|
-
: `${translate("{$value} AE", { value: cost.PerCountable.base_value })} + `) +
|
|
389
|
+
: `${translate("{$value} AE", { value: cost.PerCountable.base_value.toFixed() })} + `) +
|
|
384
390
|
translate("{$cost} per {$countable}", {
|
|
385
|
-
cost: translate("{$value} AE", { value: cost.PerCountable.value }),
|
|
391
|
+
cost: translate("{$value} AE", { value: cost.PerCountable.value.toFixed() }),
|
|
386
392
|
countable: getResponsiveText(translation?.per, responsiveTextSize),
|
|
387
393
|
}) +
|
|
388
394
|
parensIf(mapNullable(translation?.note, note => getResponsiveTextOptional(note, responsiveTextSize))));
|
|
389
395
|
}
|
|
390
396
|
case "Interval":
|
|
391
397
|
return translate("{$cost} per {$interval}", {
|
|
392
|
-
cost: translate("{$value} AE", { value: cost.Interval.value }),
|
|
398
|
+
cost: translate("{$value} AE", { value: cost.Interval.value.toFixed() }),
|
|
393
399
|
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, cost.Interval.interval.unit, cost.Interval.interval.value, true),
|
|
394
400
|
});
|
|
395
401
|
case "ActivationAndHalfInterval":
|
|
396
402
|
return additionFormatter(translate("{$value} AE", {
|
|
397
|
-
value: cost.ActivationAndHalfInterval.value,
|
|
403
|
+
value: cost.ActivationAndHalfInterval.value.toFixed(),
|
|
398
404
|
}) + parensIf(translate("activation")), translate("{$cost} per {$interval}", {
|
|
399
405
|
cost: translate("{$value} AE", {
|
|
400
|
-
value: Math.round(cost.ActivationAndHalfInterval.value / 2),
|
|
406
|
+
value: Math.round(cost.ActivationAndHalfInterval.value / 2).toFixed(),
|
|
401
407
|
}),
|
|
402
408
|
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, cost.ActivationAndHalfInterval.interval.unit, cost.ActivationAndHalfInterval.interval.value, true),
|
|
403
409
|
}));
|
|
404
410
|
case "Indefinite":
|
|
405
411
|
return ((mapNullable(translateMap(cost.Indefinite.translations)?.description, description => getResponsiveText(description, responsiveTextSize)) ?? MISSING_VALUE) +
|
|
406
|
-
mapNullableDefault(cost.Indefinite.modifier, modifier => ` + ${translate("{$value} AE", { value: modifier.value })}`, ""));
|
|
412
|
+
mapNullableDefault(cost.Indefinite.modifier, modifier => ` + ${translate("{$value} AE", { value: modifier.value.toFixed() })}`, ""));
|
|
407
413
|
case "Disjunction":
|
|
408
414
|
return translate("{$value} AE", {
|
|
409
415
|
value: localeJoin(cost.Disjunction.options.map(option => option.value.toFixed() +
|
|
@@ -430,7 +436,7 @@ const renderArcaneEnergyCost = (translate, translateMap, format, localeJoin, res
|
|
|
430
436
|
case "Verbose":
|
|
431
437
|
return cost.ByLevel.levels
|
|
432
438
|
.map((level, index) => translate("{$cost} for level {$level}", {
|
|
433
|
-
cost: translate("{$value} AE", { value: level.value }),
|
|
439
|
+
cost: translate("{$value} AE", { value: level.value.toFixed() }),
|
|
434
440
|
level: romanize(index + 1),
|
|
435
441
|
}))
|
|
436
442
|
.join("; ");
|
|
@@ -454,7 +460,9 @@ const renderBindingCost = (translate, translateMap, localeCompare, getAllResolve
|
|
|
454
460
|
}),
|
|
455
461
|
});
|
|
456
462
|
case "Map":
|
|
457
|
-
return renderParameterMap(cost.Map, option => Reader.of(option.permanentValue), values => translateR("{$value} permanent AE", {
|
|
463
|
+
return renderParameterMap(cost.Map, option => Reader.of(option.permanentValue), values => translateR("{$value} permanent AE", {
|
|
464
|
+
value: typeof values === "number" ? values.toFixed() : values,
|
|
465
|
+
})).run({
|
|
458
466
|
translate,
|
|
459
467
|
translateMap,
|
|
460
468
|
responsiveTextSize,
|
|
@@ -481,12 +489,12 @@ const renderBindingCost = (translate, translateMap, localeCompare, getAllResolve
|
|
|
481
489
|
const renderLifePointsCost = (translate, cost) => cost === undefined
|
|
482
490
|
? ""
|
|
483
491
|
: // eslint-disable-next-line no-irregular-whitespace
|
|
484
|
-
` (+ ${translate("{$value} LP", { value: cost.Fixed.value })})`;
|
|
492
|
+
` (+ ${translate("{$value} LP", { value: cost.Fixed.value.toFixed() })})`;
|
|
485
493
|
const renderCost = (translate, translateMap, format, localeJoin, localeCompare, getAllResolvedSelectOptions, responsiveTextSize, levels, cost) => {
|
|
486
494
|
if (typeof cost === "number") {
|
|
487
495
|
return {
|
|
488
496
|
label: translate("AE Cost"),
|
|
489
|
-
value: translate("{$value} AE", { value: cost }),
|
|
497
|
+
value: translate("{$value} AE", { value: cost.toFixed() }),
|
|
490
498
|
};
|
|
491
499
|
}
|
|
492
500
|
switch (cost.kind) {
|
|
@@ -823,6 +831,12 @@ export const getActivatableEntityDescription = createEntityDescriptionCreator(({
|
|
|
823
831
|
}
|
|
824
832
|
: name => `${name} I–${romanize(levels)}`;
|
|
825
833
|
return {
|
|
834
|
+
category: entityName === "CeremonialItemSpecialAbility" && entry.associatedItem !== undefined
|
|
835
|
+
? {
|
|
836
|
+
label: attributedNameR("category", "CeremonialItemSpecialAbilityGroup", entry.associatedItem).map(name => name ?? MISSING_VALUE),
|
|
837
|
+
value: customNameR(t => t.nameForSorting, "CeremonialItemSpecialAbilityGroup", entry.associatedItem).map(name => name ?? MISSING_VALUE),
|
|
838
|
+
}
|
|
839
|
+
: undefined,
|
|
826
840
|
title: addLevels(makeTraditionName(translation.name_in_library ?? translation.name + parensIf(translation.additionalName))),
|
|
827
841
|
subtitle: mapNullable(baseEntry.subtype, subtype => renderAdvantageDisadvantageSubtype(subtype).run(env)) ??
|
|
828
842
|
mapNullable(baseEntry.usage_type, usageType => renderCombatSpecialAbilityType(usageType).run(env)),
|
|
@@ -4,4 +4,4 @@ import type { GetInstanceById } from "../helpers/getTypes.js";
|
|
|
4
4
|
*/
|
|
5
5
|
export declare const getAlternativeRuleEntityDescription: import("../creator.js").EntityDescriptionCreator<"AlternativeRule", {
|
|
6
6
|
getInstanceById: GetInstanceById<"Publication" | "PlayerType">;
|
|
7
|
-
}, import("../index.js").EntityDescription
|
|
7
|
+
} & import("../env.js").StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Get a JSON representation of the rules text for an attribute.
|
|
3
3
|
*/
|
|
4
|
-
export declare const getAttributeEntityDescription: import("../creator.js").EntityDescriptionCreator<"Attribute",
|
|
5
|
-
getInstanceById: import("../helpers/getTypes.js").GetInstanceById<"Publication">;
|
|
6
|
-
}, import("../index.js").EntityDescription>;
|
|
4
|
+
export declare const getAttributeEntityDescription: import("../creator.js").EntityDescriptionCreator<"Attribute", import("@elyukai/utils/nullable").AnyNonNullish & import("../env.js").StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
|
@@ -4,10 +4,10 @@ import type { GetInstanceById } from "../helpers/getTypes.js";
|
|
|
4
4
|
*/
|
|
5
5
|
export declare const getCloseCombatTechniqueEntityDescription: import("../creator.js").EntityDescriptionCreator<"CloseCombatTechnique", {
|
|
6
6
|
getInstanceById: GetInstanceById<"Publication" | "Attribute">;
|
|
7
|
-
}, import("../index.js").EntityDescription
|
|
7
|
+
} & import("../env.js").StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
|
8
8
|
/**
|
|
9
9
|
* Get a JSON representation of the rules text for a ranged combat technique.
|
|
10
10
|
*/
|
|
11
11
|
export declare const getRangedCombatTechniqueEntityDescription: import("../creator.js").EntityDescriptionCreator<"RangedCombatTechnique", {
|
|
12
12
|
getInstanceById: GetInstanceById<"Publication" | "Attribute">;
|
|
13
|
-
}, import("../index.js").EntityDescription
|
|
13
|
+
} & import("../env.js").StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Get a JSON representation of the rules text for a condition.
|
|
3
3
|
*/
|
|
4
|
-
export declare const getConditionEntityDescription: import("../creator.js").EntityDescriptionCreator<"Condition",
|
|
5
|
-
getInstanceById: import("../helpers/getTypes.js").GetInstanceById<"Publication">;
|
|
6
|
-
}, import("../index.js").EntityDescription>;
|
|
4
|
+
export declare const getConditionEntityDescription: import("../creator.js").EntityDescriptionCreator<"Condition", import("@elyukai/utils/nullable").AnyNonNullish & import("../env.js").StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
|
7
5
|
/**
|
|
8
6
|
* Get a JSON representation of the rules text for a meta condition.
|
|
9
7
|
*/
|
|
10
|
-
export declare const getMetaConditionEntityDescription: import("../creator.js").EntityDescriptionCreator<"MetaCondition",
|
|
11
|
-
getInstanceById: import("../helpers/getTypes.js").GetInstanceById<"Publication">;
|
|
12
|
-
}, import("../index.js").EntityDescription>;
|
|
8
|
+
export declare const getMetaConditionEntityDescription: import("../creator.js").EntityDescriptionCreator<"MetaCondition", import("@elyukai/utils/nullable").AnyNonNullish & import("../env.js").StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StdEnv } from "../env.js";
|
|
1
2
|
import type { GetAllChildInstancesForParent, GetInstanceById } from "../helpers/getTypes.js";
|
|
2
3
|
import type { GetResolvedSelectOptionById } from "./partial/prerequisites/single/activatable.js";
|
|
3
4
|
/**
|
|
@@ -7,4 +8,4 @@ export declare const getCultureEntityDescription: import("../creator.js").Entity
|
|
|
7
8
|
getInstanceById: GetInstanceById<"Publication" | "Advantage" | "Disadvantage" | "Skill" | "Language" | "LanguageSpecialization" | "Script" | "SocialStatus" | "ProfessionVariant" | "MagicalTradition" | "BlessedTradition">;
|
|
8
9
|
getChildInstancesForInstanceId: GetAllChildInstancesForParent<"ProfessionVersion">;
|
|
9
10
|
getResolvedSelectOptionById: GetResolvedSelectOptionById;
|
|
10
|
-
}, import("../index.js").EntityDescription
|
|
11
|
+
} & StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
package/lib/entities/culture.js
CHANGED
|
@@ -248,14 +248,14 @@ export const getCultureEntityDescription = createEntityDescriptionCreator(({ get
|
|
|
248
248
|
if (allSame(processedScripts, on(([, apValue]) => apValue, equal))) {
|
|
249
249
|
return (localeJoin(processedScripts.map(([name]) => name).toSorted(localeCompare), "disjunction") +
|
|
250
250
|
parensIf(translate("{$value} AP", {
|
|
251
|
-
value: processedScripts[0][1],
|
|
251
|
+
value: processedScripts[0][1].toFixed(),
|
|
252
252
|
})));
|
|
253
253
|
}
|
|
254
254
|
else {
|
|
255
255
|
return localeJoin(processedScripts
|
|
256
256
|
.map(([name, apValue]) => name +
|
|
257
257
|
parensIf(translate("{$value} AP", {
|
|
258
|
-
value: apValue,
|
|
258
|
+
value: apValue.toFixed(),
|
|
259
259
|
})))
|
|
260
260
|
.toSorted(localeCompare), "disjunction");
|
|
261
261
|
}
|
|
@@ -306,7 +306,7 @@ export const getCultureEntityDescription = createEntityDescriptionCreator(({ get
|
|
|
306
306
|
type: "labeled",
|
|
307
307
|
label: translate("Cultural Package {$cultureName}", {
|
|
308
308
|
cultureName: translation.name,
|
|
309
|
-
}) + parensIf(translate("{$value} AP", { value: culturalPackageApValue })),
|
|
309
|
+
}) + parensIf(translate("{$value} AP", { value: culturalPackageApValue.toFixed() })),
|
|
310
310
|
value: {
|
|
311
311
|
type: "plain",
|
|
312
312
|
text: culturePackageText,
|
|
@@ -8,4 +8,4 @@ export declare const getCurriculumEntityDescription: import("../creator.js").Ent
|
|
|
8
8
|
getAllInstances: GetAllInstances<"Profession">;
|
|
9
9
|
getChildInstancesForInstanceId: GetAllChildInstancesForParent<"LessonPackage" | "ProfessionVersion" | "ProfessionPackage">;
|
|
10
10
|
idMap: IdMap;
|
|
11
|
-
}, import("../index.js").EntityDescription
|
|
11
|
+
} & import("../env.js").StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
|
@@ -183,7 +183,7 @@ const renderAbilityAdjustment = (translate, translateMap, getInstanceById, baseP
|
|
|
183
183
|
const printedBaseValue = mapNullable(renderPrintedAbilityAdjustmentBaseValue(abilityAdjustment), value => value + defaultValue);
|
|
184
184
|
return translate("{$replacement} instead of {$base}", {
|
|
185
185
|
base: printedBaseValue === basePoints
|
|
186
|
-
? basePoints
|
|
186
|
+
? basePoints.toFixed()
|
|
187
187
|
: `<ins>${basePoints.toFixed()}</ins><del>${printedBaseValue?.toFixed() ?? "n/a"}</del>`,
|
|
188
188
|
replacement: `${renderAbilityAdjustmentName(translateMap, getInstanceById, abilityAdjustment)} ${(basePoints + renderAbilityAdjustmentModifierValue(abilityAdjustment)).toFixed()}`,
|
|
189
189
|
});
|
|
@@ -4,4 +4,4 @@ import type { GetInstanceById } from "../helpers/getTypes.js";
|
|
|
4
4
|
*/
|
|
5
5
|
export declare const getDerivedCharacteristicEntityDescription: import("../creator.js").EntityDescriptionCreator<"DerivedCharacteristic", {
|
|
6
6
|
getInstanceById: GetInstanceById<"Publication" | "Attribute" | "DerivedCharacteristic">;
|
|
7
|
-
}, import("../index.js").EntityDescription
|
|
7
|
+
} & import("../env.js").StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
|
@@ -6,4 +6,4 @@ import type { IdMap } from "../index.js";
|
|
|
6
6
|
export declare const getDiseaseEntityDescription: import("../creator.js").EntityDescriptionCreator<"Disease" | "AnimalDisease", {
|
|
7
7
|
getInstanceById: GetInstanceById<"Publication" | "AnimalType" | "DerivedCharacteristic">;
|
|
8
8
|
idMap: IdMap;
|
|
9
|
-
}, import("../index.js").EntityDescription
|
|
9
|
+
} & import("../env.js").StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
package/lib/entities/elixir.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ import type { GetResolvedSelectOptionById } from "./partial/prerequisites/single
|
|
|
7
7
|
export declare const getElixirEntityDescription: import("../creator.js").EntityDescriptionCreator<"Elixir", {
|
|
8
8
|
getInstanceById: GetInstanceById<"Publication" | "DerivedCharacteristic" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Aspect" | "Property" | "PersonalityTrait" | "Blessing" | "Cantrip">;
|
|
9
9
|
getResolvedSelectOptionById: GetResolvedSelectOptionById;
|
|
10
|
-
}, import("../index.js").EntityDescription
|
|
10
|
+
} & import("../env.js").StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|
package/lib/entities/elixir.js
CHANGED
|
@@ -54,7 +54,7 @@ export const getElixirEntityDescription = createEntityDescriptionCreator(({ getI
|
|
|
54
54
|
{
|
|
55
55
|
label: `${translate("AP Value")} (${translate("Trade Secret")})`,
|
|
56
56
|
value: translate("{$value} AP", {
|
|
57
|
-
value: entry.trade_secret.ap_value,
|
|
57
|
+
value: entry.trade_secret.ap_value.toFixed(),
|
|
58
58
|
}) +
|
|
59
59
|
parensIf(mapNullable(entry.trade_secret.prerequisites, prerequisites => `${translate("Prerequisites")}: ${printPlainGeneralPrerequisites(prerequisites).run(env)}`)),
|
|
60
60
|
},
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { AmmunitionishIdentifier, EquipmentIdentifier, GenMeleeWeapon, GenRangedWeapon, LocaleMeasurementAdjustments } from "@optolith/database-schema/gen";
|
|
2
2
|
import { type TaggedEntity } from "../creator.js";
|
|
3
|
+
import type { StdEnv } from "../env.js";
|
|
3
4
|
import type { GetInstanceById } from "../helpers/getTypes.js";
|
|
4
5
|
import type { LocaleJoin } from "../helpers/locale.js";
|
|
5
|
-
import type
|
|
6
|
-
import
|
|
6
|
+
import { type Format, type Translate, type TranslateMap } from "../helpers/translate.js";
|
|
7
|
+
import { type LabeledEntityDescriptionSection, type RawEntityDescriptionSectionContent } from "../index.js";
|
|
7
8
|
/**
|
|
8
9
|
* Get the name of an equipment item.
|
|
9
10
|
*/
|
|
@@ -19,7 +20,4 @@ export declare const renderRangedWeapon: <Damage>(translate: Translate, translat
|
|
|
19
20
|
/**
|
|
20
21
|
* Get a JSON representation of the rules text for equipment.
|
|
21
22
|
*/
|
|
22
|
-
export declare const getEquipmentEntityDescription: import("../creator.js").EntityDescriptionCreator<"Weapon" | "Ammunition" | "Armor" | "Animal" | "AnimalCare" | "BandageOrRemedy" | "Book" | "CeremonialItem" | "Clothes" | "ClothingPackage" | "Container" | "EquipmentOfBlessedOnes" | "GemOrPreciousStone" | "IlluminationLightSource" | "IlluminationRefillOrSupply" | "Jewelry" | "Laboratory" | "Liebesspielzeug" | "LuxuryGood" | "MagicalArtifact" | "MusicalInstrument" | "Newspaper" | "OrienteeringAid" | "RopeOrChain" | "Stationery" | "ThievesTool" | "ToolOfTheTrade" | "TravelGearOrTool" | "Vehicle" | "WeaponAccessory" | "WorkingSupernaturalCreature",
|
|
23
|
-
getInstanceById: GetInstanceById<"Publication" | "Attribute" | "Reach" | "SocialStatus" | "CloseCombatTechnique" | "RangedCombatTechnique" | "MagicalTradition" | "BlessedTradition" | "DerivedCharacteristic" | AmmunitionishIdentifier["kind"] | "Race" | "Culture" | "Profession" | "Skill">;
|
|
24
|
-
idMap: IdMap;
|
|
25
|
-
}, import("../index.js").EntityDescription>;
|
|
23
|
+
export declare const getEquipmentEntityDescription: import("../creator.js").EntityDescriptionCreator<"Weapon" | "Ammunition" | "Armor" | "Animal" | "AnimalCare" | "BandageOrRemedy" | "Book" | "CeremonialItem" | "Clothes" | "ClothingPackage" | "Container" | "EquipmentOfBlessedOnes" | "GemOrPreciousStone" | "IlluminationLightSource" | "IlluminationRefillOrSupply" | "Jewelry" | "Laboratory" | "Liebesspielzeug" | "LuxuryGood" | "MagicalArtifact" | "MusicalInstrument" | "Newspaper" | "OrienteeringAid" | "RopeOrChain" | "Stationery" | "ThievesTool" | "ToolOfTheTrade" | "TravelGearOrTool" | "Vehicle" | "WeaponAccessory" | "WorkingSupernaturalCreature", StdEnv<"f" | "fn" | "t" | "tm" | "lj" | "lc" | "rts" | "ibi" | "ma" | "idm", "BlessedTradition" | "MagicalTradition" | "Publication" | "Race" | "Culture" | "SocialStatus" | "Attribute" | "Skill" | "CloseCombatTechnique" | "RangedCombatTechnique" | "Weapon" | "Profession" | "Ammunition" | "DerivedCharacteristic" | "Reach"> & StdEnv<"fd" | "t" | "tm" | "ibi", "Publication">, import("../index.js").EntityDescription<string>>;
|