@optolith/entity-descriptions 0.4.14 → 0.4.16
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 +22 -0
- package/lib/entities/activatable.d.ts +1 -1
- package/lib/entities/activatable.js +4 -1
- package/lib/entities/elixir.d.ts +1 -1
- package/lib/entities/partial/adventurePointsValue.js +50 -18
- package/lib/entities/partial/prerequisites/index.d.ts +3 -3
- package/lib/entities/partial/prerequisites/prerequisiteGroups.d.ts +2 -2
- package/lib/entities/partial/prerequisites/prerequisiteGroups.js +3 -0
- package/lib/entities/partial/prerequisites/single/personalityTrait.js +2 -2
- package/lib/entities/partial/prerequisites/single/rated.js +2 -1
- package/lib/entities/partial/rated/activatable/cost.d.ts +5 -4
- package/lib/entities/partial/rated/activatable/cost.js +13 -6
- package/lib/entities/partial/units/timeSpan.d.ts +9 -0
- package/lib/entities/partial/units/timeSpan.js +4 -0
- package/lib/entities/poison.d.ts +1 -1
- package/lib/entities/spell.d.ts +1 -0
- package/lib/entities/spell.js +2 -2
- package/lib/index.d.ts +56 -55
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
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.4.16](https://github.com/Optolith/entity-descriptions/compare/v0.4.15...v0.4.16) (2026-06-08)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* render animist power skill check penalty ([ef7751a](https://github.com/Optolith/entity-descriptions/commit/ef7751ad9f9b995f979d973522c7f27e65ba545c))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* swap personality trait prerequisite texts ([abf4ff6](https://github.com/Optolith/entity-descriptions/commit/abf4ff6cbc8b8b09a0436741947ebf9b15cc9974))
|
|
16
|
+
|
|
17
|
+
## [0.4.15](https://github.com/Optolith/entity-descriptions/compare/v0.4.14...v0.4.15) (2026-06-07)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* add sustained cost map interval ([f7c1b31](https://github.com/Optolith/entity-descriptions/commit/f7c1b31452befa0c898a6f21e4624c8084ea5df5))
|
|
23
|
+
* display full tradition name ([2d07eff](https://github.com/Optolith/entity-descriptions/commit/2d07eff1d4b6a5b72ce705e24969e4a384a1d486))
|
|
24
|
+
* ignore rating in prerequisite when zero ([b375702](https://github.com/Optolith/entity-descriptions/commit/b375702ea644fc21b92bb64b811e204aeda7370c))
|
|
25
|
+
* render ap value from explicit select options ([df2178f](https://github.com/Optolith/entity-descriptions/commit/df2178fe131ed9e9d3427ee092a46b2448b09650))
|
|
26
|
+
|
|
5
27
|
## [0.4.14](https://github.com/Optolith/entity-descriptions/compare/v0.4.13...v0.4.14) (2026-06-07)
|
|
6
28
|
|
|
7
29
|
|
|
@@ -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" | "InstrumentEnchantment" | "KarmaSpecialAbility" | "Krallenkettenzauber" | "Kristallkugelzauber" | "LiturgicalStyleSpecialAbility" | "LycantropicGift" | "MagicalSign" | "MagicalSpecialAbility" | "MagicalTradition" | "MagicStyleSpecialAbility" | "OrbEnchantment" | "PactGift" | "ProtectiveWardingCircleSpecialAbility" | "RingEnchantment" | "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">;
|
|
50
|
+
getInstanceById: GetInstanceById<"Publication" | "Subject" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "TradeSecret" | "Aspect" | "Property" | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Weapon" | "Patron" | "PersonalityTrait">;
|
|
51
51
|
getAllInstances: GetAllInstances<"Script">;
|
|
52
52
|
getResolvedSelectOptionById: GetResolvedSelectOptionById;
|
|
53
53
|
getAllResolvedSelectOptions: GetAllResolvedSelectOptions;
|
|
@@ -705,8 +705,11 @@ export const getActivatableEntityDescription = createEntityDescriptionCreator(({
|
|
|
705
705
|
: entityName === "MagicalTradition"
|
|
706
706
|
? renderAdditionalSpecialRules(translation.name, translation.nameOfSpellcasters, undefined, undefined, undefined, entry.primary).run(env)
|
|
707
707
|
: [];
|
|
708
|
+
const makeTraditionName = entityName === "BlessedTradition" || entityName === "MagicalTradition"
|
|
709
|
+
? name => translate("Tradition ({$tradition})", { tradition: name })
|
|
710
|
+
: name => name;
|
|
708
711
|
return {
|
|
709
|
-
title: (translation.name_in_library ?? translation.name) +
|
|
712
|
+
title: makeTraditionName(translation.name_in_library ?? translation.name) +
|
|
710
713
|
(baseEntry.levels !== undefined ? ` I–${romanize(baseEntry.levels)}` : ""),
|
|
711
714
|
subtitle: mapNullable(baseEntry.usage_type, usageType => {
|
|
712
715
|
switch (usageType.kind) {
|
package/lib/entities/elixir.d.ts
CHANGED
|
@@ -5,6 +5,6 @@ import type { GetResolvedSelectOptionById } from "./partial/prerequisites/single
|
|
|
5
5
|
* Get a JSON representation of the rules text for an elixir.
|
|
6
6
|
*/
|
|
7
7
|
export declare const getElixirEntityDescription: import("../creator.js").EntityDescriptionCreator<"Elixir", {
|
|
8
|
-
getInstanceById: GetInstanceById<"Publication" | "DerivedCharacteristic" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Aspect" | "Property">;
|
|
8
|
+
getInstanceById: GetInstanceById<"Publication" | "DerivedCharacteristic" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Aspect" | "Property" | "PersonalityTrait">;
|
|
9
9
|
getResolvedSelectOptionById: GetResolvedSelectOptionById;
|
|
10
10
|
}, import("../index.js").EntityDescription>;
|
|
@@ -6,6 +6,35 @@ import { romanize } from "@optolith/helpers/roman";
|
|
|
6
6
|
import { assertExhaustive } from "@optolith/helpers/typeSafety";
|
|
7
7
|
import { evaluateMathOperation } from "./mathOperation.js";
|
|
8
8
|
import { MISSING_VALUE } from "./unknown.js";
|
|
9
|
+
const typographicSign = (num) => (num > 0 ? "" : "−") + Math.abs(num).toFixed();
|
|
10
|
+
const renderFixedSelectOptionsAdventurePointsValue = (locale, getAllSelectOptions, getNameForSelectOptionId, getApValueForSelectOption, applyNegative) => {
|
|
11
|
+
const entriesMap = Map.groupBy(getAllSelectOptions().map((item) => [
|
|
12
|
+
getApValueForSelectOption(item, item.id),
|
|
13
|
+
item,
|
|
14
|
+
]), item => item[0])
|
|
15
|
+
.entries()
|
|
16
|
+
.toArray();
|
|
17
|
+
if (entriesMap.every((entry) => typeof entry[0] === "number" && entry[1].length === 1)) {
|
|
18
|
+
const entriesSortedByApValue = entriesMap.toSorted(on(item => item[0], numAsc));
|
|
19
|
+
return entriesSortedByApValue
|
|
20
|
+
.map(entry => locale.translateMap(entry[1][0][1].content.translations)?.name ?? MISSING_VALUE)
|
|
21
|
+
.join("/")
|
|
22
|
+
.concat(`: ${locale.translate("{$value} Adventure Points", { value: entriesSortedByApValue.map(entry => typographicSign(applyNegative(entry[0]))).join("/") })}`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return entriesMap
|
|
26
|
+
.map(([apValue, items]) => [
|
|
27
|
+
apValue,
|
|
28
|
+
locale.join(items
|
|
29
|
+
.map(item => getNameForSelectOptionId(item[1].id))
|
|
30
|
+
.filter(name => name !== undefined)
|
|
31
|
+
.toSorted(locale.compare), "conjunction"),
|
|
32
|
+
])
|
|
33
|
+
.toSorted(on(item => item[1], locale.compare))
|
|
34
|
+
.map(([apValue, itemNames]) => `${itemNames}: ${locale.translate("{$value} Adventure Points", { value: typeof apValue === "number" ? applyNegative(apValue) : apValue })}`)
|
|
35
|
+
.join("; ");
|
|
36
|
+
}
|
|
37
|
+
};
|
|
9
38
|
const renderSelectOptionsAdventurePointsValue = (locale, derivedLabel, getAllSelectOptions, getNameForSelectOptionId, config, applyNegative) => {
|
|
10
39
|
if (config === undefined) {
|
|
11
40
|
return MISSING_VALUE;
|
|
@@ -19,23 +48,8 @@ const renderSelectOptionsAdventurePointsValue = (locale, derivedLabel, getAllSel
|
|
|
19
48
|
})}`;
|
|
20
49
|
}
|
|
21
50
|
case "Fixed":
|
|
22
|
-
return
|
|
23
|
-
config.Fixed.
|
|
24
|
-
config.Fixed.default,
|
|
25
|
-
item,
|
|
26
|
-
]), item => item[0])
|
|
27
|
-
.entries()
|
|
28
|
-
.map(([apValue, items]) => [
|
|
29
|
-
apValue,
|
|
30
|
-
locale.join(items
|
|
31
|
-
.map(item => getNameForSelectOptionId(item[1].id))
|
|
32
|
-
.filter(name => name !== undefined)
|
|
33
|
-
.toSorted(locale.compare), "conjunction"),
|
|
34
|
-
])
|
|
35
|
-
.toArray()
|
|
36
|
-
.toSorted(on(item => item[1], locale.compare))
|
|
37
|
-
.map(([apValue, itemNames]) => `${itemNames}: ${locale.translate("{$value} Adventure Points", { value: applyNegative(apValue) })}`)
|
|
38
|
-
.join("; ");
|
|
51
|
+
return renderFixedSelectOptionsAdventurePointsValue(locale, getAllSelectOptions, getNameForSelectOptionId, item => config.Fixed.map.find(mapItem => deepEqual(mapItem.id, item.id))?.ap_value ??
|
|
52
|
+
config.Fixed.default, applyNegative);
|
|
39
53
|
default:
|
|
40
54
|
return assertExhaustive(config);
|
|
41
55
|
}
|
|
@@ -89,7 +103,25 @@ export const renderAdventurePointsValue = (locale, getNameForId, getNameForSelec
|
|
|
89
103
|
case "DerivedFromSelection": {
|
|
90
104
|
const derivedSelectOptions = entry.select_options?.derived;
|
|
91
105
|
if (derivedSelectOptions === undefined) {
|
|
92
|
-
return
|
|
106
|
+
return renderFixedSelectOptionsAdventurePointsValue(locale, getAllSelectOptions, getNameForSelectOptionId, item => {
|
|
107
|
+
switch (item.content.ap_value?.kind) {
|
|
108
|
+
case "Fixed":
|
|
109
|
+
return item.content.ap_value.Fixed;
|
|
110
|
+
case "DependingOnActiveInstances":
|
|
111
|
+
switch (item.content.ap_value.DependingOnActiveInstances.kind) {
|
|
112
|
+
case "Threshold":
|
|
113
|
+
return item.content.ap_value.DependingOnActiveInstances.Threshold.normal;
|
|
114
|
+
case "Expression":
|
|
115
|
+
return MISSING_VALUE;
|
|
116
|
+
default:
|
|
117
|
+
return assertExhaustive(item.content.ap_value.DependingOnActiveInstances);
|
|
118
|
+
}
|
|
119
|
+
case undefined:
|
|
120
|
+
return MISSING_VALUE;
|
|
121
|
+
default:
|
|
122
|
+
return assertExhaustive(item.content.ap_value);
|
|
123
|
+
}
|
|
124
|
+
}, applyNegative);
|
|
93
125
|
}
|
|
94
126
|
switch (derivedSelectOptions.kind) {
|
|
95
127
|
case "Blessings":
|
|
@@ -13,11 +13,11 @@ export declare const printPublicationPrerequisites: (getInstanceById: GetInstanc
|
|
|
13
13
|
/**
|
|
14
14
|
* Print plain general prerequisites as a string.
|
|
15
15
|
*/
|
|
16
|
-
export declare const printPlainGeneralPrerequisites: (getInstanceById: GetInstanceById<"Race" | "Culture" | "PactCategory" | "PactDomain" | "SocialStatus" | "State" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Property" | "Aspect" | "Enhancement">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, value: PlainGeneralPrerequisites) => string;
|
|
16
|
+
export declare const printPlainGeneralPrerequisites: (getInstanceById: GetInstanceById<"Race" | "Culture" | "PactCategory" | "PactDomain" | "SocialStatus" | "State" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Property" | "Aspect" | "Enhancement" | "PersonalityTrait">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, value: PlainGeneralPrerequisites) => string;
|
|
17
17
|
/**
|
|
18
18
|
* Print general prerequisites as a string.
|
|
19
19
|
*/
|
|
20
|
-
export declare const printGeneralPrerequisites: (getInstanceById: GetInstanceById<"Race" | "Culture" | "PactCategory" | "PactDomain" | "SocialStatus" | "State" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Property" | "Aspect" | "Enhancement">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, value: GeneralPrerequisites, printPreviousLevelPrerequisites?: {
|
|
20
|
+
export declare const printGeneralPrerequisites: (getInstanceById: GetInstanceById<"Race" | "Culture" | "PactCategory" | "PactDomain" | "SocialStatus" | "State" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Property" | "Aspect" | "Enhancement" | "PersonalityTrait">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, value: GeneralPrerequisites, printPreviousLevelPrerequisites?: {
|
|
21
21
|
id: ActivatableIdentifier;
|
|
22
22
|
levels: number;
|
|
23
23
|
}, trailingText?: string) => string;
|
|
@@ -28,7 +28,7 @@ export declare const printProfessionPrerequisites: (getInstanceById: GetInstance
|
|
|
28
28
|
/**
|
|
29
29
|
* Print advantage disadvantage prerequisites as a string.
|
|
30
30
|
*/
|
|
31
|
-
export declare const printAdvantageDisadvantagePrerequisites: (getInstanceById: GetInstanceById<"Race" | "Culture" | "PactCategory" | "PactDomain" | "SocialStatus" | "State" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Property" | "Aspect" | "Enhancement">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, value: AdvantageDisadvantagePrerequisites, name: string, type: "Advantage" | "Disadvantage") => string;
|
|
31
|
+
export declare const printAdvantageDisadvantagePrerequisites: (getInstanceById: GetInstanceById<"Race" | "Culture" | "PactCategory" | "PactDomain" | "SocialStatus" | "State" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Property" | "Aspect" | "Enhancement" | "PersonalityTrait">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, value: AdvantageDisadvantagePrerequisites, name: string, type: "Advantage" | "Disadvantage") => string;
|
|
32
32
|
/**
|
|
33
33
|
* Print arcane tradition prerequisites as a string.
|
|
34
34
|
*/
|
|
@@ -14,7 +14,7 @@ export declare const printPublicationPrerequisiteGroup: (getInstanceById: GetIns
|
|
|
14
14
|
/**
|
|
15
15
|
* Print the translation of a general prerequisite group.
|
|
16
16
|
*/
|
|
17
|
-
export declare const printGeneralPrerequisiteGroup: (getInstanceById: GetInstanceById<"Race" | "Culture" | "PactCategory" | "PactDomain" | "SocialStatus" | "State" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Property" | "Aspect" | "Enhancement">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, prerequisite: GeneralPrerequisiteGroup) => PrerequisitePart | undefined;
|
|
17
|
+
export declare const printGeneralPrerequisiteGroup: (getInstanceById: GetInstanceById<"Race" | "Culture" | "PactCategory" | "PactDomain" | "SocialStatus" | "State" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Property" | "Aspect" | "Enhancement" | "PersonalityTrait">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, prerequisite: GeneralPrerequisiteGroup) => PrerequisitePart | undefined;
|
|
18
18
|
/**
|
|
19
19
|
* Print the translation of a profession prerequisite group.
|
|
20
20
|
*/
|
|
@@ -22,7 +22,7 @@ export declare const printProfessionPrerequisiteGroup: (getInstanceById: GetInst
|
|
|
22
22
|
/**
|
|
23
23
|
* Print the translation of an advantage/disadvantage prerequisite group.
|
|
24
24
|
*/
|
|
25
|
-
export declare const printAdvantageDisadvantagePrerequisiteGroup: (getInstanceById: GetInstanceById<"Race" | "Culture" | "PactCategory" | "PactDomain" | "SocialStatus" | "State" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Property" | "Aspect" | "Enhancement">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, prerequisite: AdvantageDisadvantagePrerequisiteGroup, name: string, type: "Advantage" | "Disadvantage") => PrerequisitePart | undefined;
|
|
25
|
+
export declare const printAdvantageDisadvantagePrerequisiteGroup: (getInstanceById: GetInstanceById<"Race" | "Culture" | "PactCategory" | "PactDomain" | "SocialStatus" | "State" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Property" | "Aspect" | "Enhancement" | "PersonalityTrait">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, prerequisite: AdvantageDisadvantagePrerequisiteGroup, name: string, type: "Advantage" | "Disadvantage") => PrerequisitePart | undefined;
|
|
26
26
|
/**
|
|
27
27
|
* Print the translation of an arcane tradition prerequisite group.
|
|
28
28
|
*/
|
|
@@ -87,6 +87,8 @@ export const printGeneralPrerequisiteGroup = (getInstanceById, getResolvedSelect
|
|
|
87
87
|
return printTextPrerequisite(locale, prerequisite.Text);
|
|
88
88
|
case "SexualCharacteristic":
|
|
89
89
|
return printSexualCharacteristicPrerequisite(locale, prerequisite.SexualCharacteristic);
|
|
90
|
+
case "PersonalityTrait":
|
|
91
|
+
return printPersonalityTraitPrerequisite(getInstanceById, locale, prerequisite.PersonalityTrait);
|
|
90
92
|
default:
|
|
91
93
|
return assertExhaustive(prerequisite);
|
|
92
94
|
}
|
|
@@ -136,6 +138,7 @@ export const printAdvantageDisadvantagePrerequisiteGroup = (getInstanceById, get
|
|
|
136
138
|
case "Enhancement":
|
|
137
139
|
case "Text":
|
|
138
140
|
case "SexualCharacteristic":
|
|
141
|
+
case "PersonalityTrait":
|
|
139
142
|
return printGeneralPrerequisiteGroup(getInstanceById, getResolvedSelectOptionById, locale, prerequisite);
|
|
140
143
|
default:
|
|
141
144
|
return assertExhaustive(prerequisite);
|
|
@@ -17,10 +17,10 @@ export const printPersonalityTraitPrerequisite = (getInstanceById, locale, prere
|
|
|
17
17
|
})})`;
|
|
18
18
|
return {
|
|
19
19
|
value: prerequisite.active
|
|
20
|
-
? locale.translate("
|
|
20
|
+
? locale.translate("must have {$trait}", {
|
|
21
21
|
trait: name,
|
|
22
22
|
})
|
|
23
|
-
: locale.translate("
|
|
23
|
+
: locale.translate("cannot be chosen at the same time as {$trait}", {
|
|
24
24
|
trait: name,
|
|
25
25
|
}),
|
|
26
26
|
sentenceType: undefined,
|
|
@@ -8,8 +8,9 @@ export const printRatedPrerequisite = (getInstanceById, locale, prerequisite) =>
|
|
|
8
8
|
if (prerequisite.display_option !== undefined) {
|
|
9
9
|
return printDisplayOption(locale.translateMap, prerequisite.display_option);
|
|
10
10
|
}
|
|
11
|
+
const name = attributedCustomName(locale.translateMap, getInstanceById, "prerequisite", (t) => t.abbreviation ?? t.name, prerequisite.id) ?? MISSING_VALUE;
|
|
11
12
|
return {
|
|
12
|
-
value:
|
|
13
|
+
value: prerequisite.value > 0 ? `${name} ${prerequisite.value.toFixed()}` : name,
|
|
13
14
|
sentenceType: undefined,
|
|
14
15
|
isMeta: false,
|
|
15
16
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Reader } from "@elyukai/utils/reader";
|
|
2
2
|
import type { CheckResultBasedModifier, DurationUnitValue, ElvenMagicalSongPermanentCost, FirstPersonMagicalMelodyCost, NonModifiableOneTimeCostPerCountable, NonModifiableSustainedCost, OneTimeCost, OneTimeCostMap, ResponsiveText, ResponsiveTextOptional, ResponsiveTextReplace, SkillModificationLevel_ID, SustainedCost } from "@optolith/database-schema/gen";
|
|
3
|
-
import { type LocaleMap } from "../../../../helpers/translate.js";
|
|
3
|
+
import { type LocaleMap, type Translate } from "../../../../helpers/translate.js";
|
|
4
4
|
import { type StdEnv, type StdReader } from "../../reader.js";
|
|
5
|
+
import { type ResponsiveTextSize } from "../../responsiveText.js";
|
|
5
6
|
/**
|
|
6
7
|
* Returns the text for the modifiable one-time cost of an activatable skill.
|
|
7
8
|
*/
|
|
@@ -51,11 +52,11 @@ export declare const renderOneTimeCost: (value: OneTimeCost) => StdReader<string
|
|
|
51
52
|
* Returns the text for the non-modifiable cost of a sustained activatable skill.
|
|
52
53
|
*/
|
|
53
54
|
export declare const renderNonModifiableSustainedCost: (value: NonModifiableSustainedCost) => Reader<{
|
|
54
|
-
translate:
|
|
55
|
+
translate: Translate;
|
|
55
56
|
energyUnit: import("../../units/energy.js").EnergyUnit;
|
|
56
57
|
} & {
|
|
57
|
-
translate:
|
|
58
|
-
responsiveTextSize:
|
|
58
|
+
translate: Translate;
|
|
59
|
+
responsiveTextSize: ResponsiveTextSize;
|
|
59
60
|
} & StdEnv<"t" | "rts" | "tm" | "eu", never, never, never>, string>;
|
|
60
61
|
/**
|
|
61
62
|
* Returns the text for the cost of a sustained activatable skill.
|
|
@@ -2,10 +2,11 @@ import { identity } from "@elyukai/utils/function";
|
|
|
2
2
|
import { Reader } from "@elyukai/utils/reader";
|
|
3
3
|
import { mapNullable } from "@optolith/helpers/nullable";
|
|
4
4
|
import { assertExhaustive } from "@optolith/helpers/typeSafety";
|
|
5
|
+
import { responsiveTranslate, } from "../../../../helpers/translate.js";
|
|
5
6
|
import { renderResponsiveMap } from "../../map.js";
|
|
6
7
|
import { formatEnergyFnR, formatEnergyR, getInstanceByIdFnR, modifiableBySpeedR, responsiveLocaleJoinR, responsiveR, responsiveTextR, responsiveTranslateR, translateMapR, translateR, } from "../../reader.js";
|
|
7
|
-
import { appendNoteIfNeeded, replaceTextIfNeeded } from "../../responsiveText.js";
|
|
8
|
-
import { formatCombinedTimeSpanR } from "../../units/timeSpan.js";
|
|
8
|
+
import { appendNoteIfNeeded, replaceTextIfNeeded, } from "../../responsiveText.js";
|
|
9
|
+
import { formatCombinedTimeSpan, formatCombinedTimeSpanR } from "../../units/timeSpan.js";
|
|
9
10
|
import { MISSING_VALUE } from "../../unknown.js";
|
|
10
11
|
import { appendCheckResultModifier } from "./checkResultBased.js";
|
|
11
12
|
import { wrapIfMinimum } from "./isMinimumMaximum.js";
|
|
@@ -57,12 +58,18 @@ export const renderModifiableOneTimeCost = (value) => deriveModifiableCost(value
|
|
|
57
58
|
}
|
|
58
59
|
return responsiveTextR(translation.additional).map(additional => `${text} + ${additional}`);
|
|
59
60
|
})));
|
|
60
|
-
const
|
|
61
|
+
const appendIntervalToCostR = (interval, baseCost) => interval === undefined
|
|
61
62
|
? Reader.of(baseCost)
|
|
62
63
|
: formatCombinedTimeSpanR(interval, true).then(formattedInterval => responsiveTranslateR("{$cost} per {$interval}", "{$cost}/{$interval}", {
|
|
63
64
|
cost: baseCost,
|
|
64
65
|
interval: formattedInterval,
|
|
65
66
|
}));
|
|
67
|
+
const appendIntervalToCost = (translate, responsiveTextSize, interval, baseCost) => interval === undefined
|
|
68
|
+
? baseCost
|
|
69
|
+
: responsiveTranslate(translate, responsiveTextSize, "{$cost} per {$interval}", "{$cost}/{$interval}", {
|
|
70
|
+
cost: baseCost,
|
|
71
|
+
interval: formatCombinedTimeSpan(translate, responsiveTextSize, interval, true),
|
|
72
|
+
});
|
|
66
73
|
/**
|
|
67
74
|
* Returns the text for a non-modifiable one-time cost of an activatable skill.
|
|
68
75
|
*/
|
|
@@ -70,7 +77,7 @@ export const renderNonModifiableOneTimeCost = (value, shouldAppendNonModifiableS
|
|
|
70
77
|
.thenW(base => appendFamiliarsTrickLPCostIfNeeded(value.lp_value, base))
|
|
71
78
|
.thenW(base => appendPerCountableToCostIfNeeded(value.per, base))
|
|
72
79
|
.then(base => appendPermanentCostIfNeeded(value.permanent_value, base))
|
|
73
|
-
.then(base =>
|
|
80
|
+
.then(base => appendIntervalToCostR(value.interval, base))
|
|
74
81
|
.then(base => appendElvenPermanentCostIfNeeded(value.permanent, base))
|
|
75
82
|
.then(base => wrapIfMinimum(value.is_minimum, base))
|
|
76
83
|
.then(base => appendNoteIfNeeded(value.translations, base))
|
|
@@ -126,7 +133,7 @@ export const renderOneTimeCostMap = (value) => Reader.asks(({ translate }) => tr
|
|
|
126
133
|
: undefined))
|
|
127
134
|
.then(text => appendNonModifiableSuffix(ModifiableParameter.Cost, text)));
|
|
128
135
|
const renderSustainedCostMap = (value) => formatEnergyFnR
|
|
129
|
-
.thenW(formatEnergy => renderResponsiveMap(value, option => option.value, formatEnergy))
|
|
136
|
+
.thenW(formatEnergy => Reader.ask().thenW(({ translate, responsiveTextSize }) => renderResponsiveMap(value, option => option.value, singleValue => appendIntervalToCost(translate, responsiveTextSize, value.interval, formatEnergy(singleValue)))))
|
|
130
137
|
.then(text => appendNonModifiableSuffix(ModifiableParameter.Cost, text));
|
|
131
138
|
/**
|
|
132
139
|
* Returns the text for the cost of a one-time activatable skill.
|
|
@@ -147,7 +154,7 @@ export const renderOneTimeCost = (value) => {
|
|
|
147
154
|
};
|
|
148
155
|
const buildSustainedCost = (activationCost, intervalCost, interval) => {
|
|
149
156
|
const activationCostWithLabel = responsiveR(() => translateR("activation").map(label => `${activationCost} (${label})`), () => Reader.of(activationCost)).thenW(identity);
|
|
150
|
-
const intervalCostWithLabel =
|
|
157
|
+
const intervalCostWithLabel = appendIntervalToCostR(interval, intervalCost);
|
|
151
158
|
return activationCostWithLabel.map2(intervalCostWithLabel, (activationStr, intervalStr) => `${activationStr} + ${intervalStr}`);
|
|
152
159
|
};
|
|
153
160
|
const renderModifiableSustainedCost = (value) => deriveModifiableCost(value.initial_modification_level).thenW(cost => cost === undefined
|
|
@@ -12,6 +12,15 @@ export type TimeSpanUnit = "Seconds" | "Minutes" | "Hours" | "Days" | "Weeks" |
|
|
|
12
12
|
export declare const formatTimeSpan: (translate: Translate, responsiveTextSize: ResponsiveTextSize, unit: {
|
|
13
13
|
kind: TimeSpanUnit;
|
|
14
14
|
} | TimeSpanUnit, value: number | string, interval?: boolean) => string;
|
|
15
|
+
/**
|
|
16
|
+
* Returns the text for a time span unit.
|
|
17
|
+
*/
|
|
18
|
+
export declare const formatCombinedTimeSpan: (translate: Translate, responsiveTextSize: ResponsiveTextSize, object: {
|
|
19
|
+
unit: {
|
|
20
|
+
kind: TimeSpanUnit;
|
|
21
|
+
};
|
|
22
|
+
value: number | string;
|
|
23
|
+
}, interval?: boolean) => string;
|
|
15
24
|
/**
|
|
16
25
|
* Returns the text for a time span unit.
|
|
17
26
|
*/
|
|
@@ -28,6 +28,10 @@ export const formatTimeSpan = (translate, responsiveTextSize, unit, value, inter
|
|
|
28
28
|
style: interval ? "interval" : "default",
|
|
29
29
|
}));
|
|
30
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* Returns the text for a time span unit.
|
|
33
|
+
*/
|
|
34
|
+
export const formatCombinedTimeSpan = (translate, responsiveTextSize, object, interval = false) => formatTimeSpan(translate, responsiveTextSize, object.unit, object.value, interval);
|
|
31
35
|
/**
|
|
32
36
|
* Returns the text for a time span unit.
|
|
33
37
|
*/
|
package/lib/entities/poison.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { GetResolvedSelectOptionById } from "./partial/prerequisites/single
|
|
|
6
6
|
* Get a JSON representation of the rules text for a poison.
|
|
7
7
|
*/
|
|
8
8
|
export declare const getPoisonEntityDescription: import("../creator.js").EntityDescriptionCreator<"Poison", {
|
|
9
|
-
getInstanceById: GetInstanceById<"Publication" | "DerivedCharacteristic" | "Disease" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Aspect" | "Property">;
|
|
9
|
+
getInstanceById: GetInstanceById<"Publication" | "DerivedCharacteristic" | "Disease" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Aspect" | "Property" | "PersonalityTrait">;
|
|
10
10
|
getResolvedSelectOptionById: GetResolvedSelectOptionById;
|
|
11
11
|
idMap: IdMap;
|
|
12
12
|
}, import("../index.js").EntityDescription>;
|
package/lib/entities/spell.d.ts
CHANGED
|
@@ -68,6 +68,7 @@ export declare const getFamiliarsTrickEntityDescription: import("../creator.js")
|
|
|
68
68
|
*/
|
|
69
69
|
export declare const getAnimistPowerEntityDescription: import("../creator.js").EntityDescriptionCreator<"AnimistPower", {
|
|
70
70
|
getInstanceById: GetInstanceById<"Publication" | "Attribute" | "SkillModificationLevel" | "TargetCategory" | "Property" | "MagicalTradition" | "DerivedCharacteristic" | "AnimistPower" | "Tribe">;
|
|
71
|
+
idMap: IdMap;
|
|
71
72
|
}, import("../index.js").EntityDescription>;
|
|
72
73
|
/**
|
|
73
74
|
* Get a JSON representation of the rules text for a Goede ritual.
|
package/lib/entities/spell.js
CHANGED
|
@@ -581,7 +581,7 @@ const renderAnimistPowerImprovementCost = (improvementCost) => {
|
|
|
581
581
|
/**
|
|
582
582
|
* Get a JSON representation of the rules text for a animist power.
|
|
583
583
|
*/
|
|
584
|
-
export const getAnimistPowerEntityDescription = createEntityDescriptionCreator(({ getInstanceById }, locale, { content: entry }) => {
|
|
584
|
+
export const getAnimistPowerEntityDescription = createEntityDescriptionCreator(({ getInstanceById, idMap }, locale, { content: entry }) => {
|
|
585
585
|
const { translate, translateMap } = locale;
|
|
586
586
|
const translation = translateMap(entry.translations);
|
|
587
587
|
if (translation === undefined) {
|
|
@@ -645,7 +645,7 @@ export const getAnimistPowerEntityDescription = createEntityDescriptionCreator((
|
|
|
645
645
|
{
|
|
646
646
|
type: "definitionList",
|
|
647
647
|
items: [
|
|
648
|
-
|
|
648
|
+
renderSkillCheckWithPenalty(entry.check, entry.check_penalty, idMap).run(env),
|
|
649
649
|
renderEffect(mergedEffect).run(env),
|
|
650
650
|
combineGeneratedTextWithStaticTranslation(translate("AE Cost"), cost, translation.cost),
|
|
651
651
|
combineGeneratedTextWithStaticTranslation(translate("Duration"), duration, translation.duration),
|