@optolith/entity-descriptions 0.8.0 → 0.9.1
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 +25 -0
- package/lib/entities/activatable.d.ts +3 -2
- package/lib/entities/activatable.js +9 -4
- package/lib/entities/equipmentPackage.js +2 -0
- package/lib/entities/partial/adventurePointsValue.js +5 -1
- package/lib/entities/partial/dice.d.ts +6 -0
- package/lib/entities/partial/dice.js +5 -0
- package/lib/entities/partial/mathOperation.d.ts +5 -0
- package/lib/entities/partial/mathOperation.js +5 -0
- package/lib/entities/poison.js +46 -28
- package/lib/index.d.ts +56 -56
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
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.9.1](https://github.com/Optolith/entity-descriptions/compare/v0.9.0...v0.9.1) (2026-09-11)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
* missing general poison note ([3d0085d](https://github.com/Optolith/entity-descriptions/commit/3d0085dbc1435bad216be21a421f31ee2ab5be69))
|
|
10
|
+
* missing unit in poison time spans ([942425f](https://github.com/Optolith/entity-descriptions/commit/942425f3ba9586671ab19f3be7b7cc2532746cc6))
|
|
11
|
+
## [0.9.0](https://github.com/Optolith/entity-descriptions/compare/v0.8.0...v0.9.0) (2026-09-11)
|
|
12
|
+
|
|
13
|
+
### ⚠ BREAKING CHANGES
|
|
14
|
+
|
|
15
|
+
* **deps:** upgrade to schema 0.58.0
|
|
16
|
+
|
|
17
|
+
### build
|
|
18
|
+
|
|
19
|
+
* **deps:** upgrade to schema 0.58.0 ([fe93cf7](https://github.com/Optolith/entity-descriptions/commit/fe93cf72768cf397a671bd4e883b1bd18288697c))
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* use nameInAPValue for animal shape text generation ([d1c8017](https://github.com/Optolith/entity-descriptions/commit/d1c801791532bdcf1004c67d1e8ae5cb53ae4f07))
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* render brew for cauldron enchantments ([866703a](https://github.com/Optolith/entity-descriptions/commit/866703a4500a9d6e47a59cf78919aa9ebcbca05a))
|
|
28
|
+
* render translation replacement if available ([6f890fd](https://github.com/Optolith/entity-descriptions/commit/6f890fd9885c070934c32db5dc5b745a86b46ac8))
|
|
29
|
+
* time interval display when value is 1 ([ada5cc7](https://github.com/Optolith/entity-descriptions/commit/ada5cc768286ced1a26bacf18a4c16a3d289aa40))
|
|
5
30
|
## [0.8.0](https://github.com/Optolith/entity-descriptions/compare/v0.7.2...v0.8.0) (2026-09-10)
|
|
6
31
|
|
|
7
32
|
### ⚠ BREAKING CHANGES
|
|
@@ -1,4 +1,4 @@
|
|
|
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";
|
|
1
|
+
import type { ActivatableIdentifier, AdvancedSpecialAbility, AdvantageDisadvantagePrerequisites, 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
3
|
import type { GetAllInstances, GetInstanceById } from "../helpers/getTypes.js";
|
|
4
4
|
import type { GetAllResolvedNewSkillApplications, GetAllResolvedSelectOptions, GetAllResolvedSkillUses } from "../index.js";
|
|
@@ -17,6 +17,7 @@ export type BaseActivatable = {
|
|
|
17
17
|
penalty?: Penalty;
|
|
18
18
|
combat_techniques?: ApplicableCombatTechniques;
|
|
19
19
|
volume?: Volume;
|
|
20
|
+
brew?: Brew_ID;
|
|
20
21
|
cost?: EnchantmentCost | DaggerRitualCost | MagicalSignCost | number;
|
|
21
22
|
property?: PropertyDeclaration;
|
|
22
23
|
aspect?: Aspect_ID;
|
|
@@ -47,7 +48,7 @@ export type BaseActivatableTranslation = {
|
|
|
47
48
|
* Get a JSON representation of the rules text for a special ability.
|
|
48
49
|
*/
|
|
49
50
|
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" | "Blessing">;
|
|
51
|
+
getInstanceById: GetInstanceById<"Publication" | "Subject" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "TradeSecret" | "Aspect" | "Property" | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Weapon" | "Patron" | "PersonalityTrait" | "Blessing" | "Brew">;
|
|
51
52
|
getAllInstances: GetAllInstances<"Script">;
|
|
52
53
|
getResolvedSelectOptionById: GetResolvedSelectOptionById;
|
|
53
54
|
getAllResolvedSelectOptions: GetAllResolvedSelectOptions;
|
|
@@ -21,7 +21,7 @@ import { printAdvantageDisadvantagePrerequisites, printGeneralPrerequisites, } f
|
|
|
21
21
|
import { printActivatableName, } from "./partial/prerequisites/single/activatable.js";
|
|
22
22
|
import { renderStandaloneCostMap } from "./partial/rated/activatable/cost.js";
|
|
23
23
|
import { parensIf } from "./partial/rated/activatable/parensIf.js";
|
|
24
|
-
import { attributedNameR, localeSortR, translateR, } from "./partial/reader.js";
|
|
24
|
+
import { attributedNameR, localeSortR, nameR, translateR, } from "./partial/reader.js";
|
|
25
25
|
import { getResponsiveText, getResponsiveTextOptional, ResponsiveTextSize, } from "./partial/responsiveText.js";
|
|
26
26
|
import { formatTimeSpan } from "./partial/units/timeSpan.js";
|
|
27
27
|
import { MISSING_VALUE } from "./partial/unknown.js";
|
|
@@ -305,6 +305,7 @@ const renderVolumeValue = (translate, translateMap, getAllResolvedSelectOptions,
|
|
|
305
305
|
return assertExhaustive(volume);
|
|
306
306
|
}
|
|
307
307
|
};
|
|
308
|
+
const renderBrew = (brew) => nameR("Brew", brew).map(name => name ?? MISSING_VALUE);
|
|
308
309
|
const renderArcaneEnergyCost = (translate, translateMap, format, localeJoin, responsiveTextSize, levels, cost) => {
|
|
309
310
|
switch (cost.kind) {
|
|
310
311
|
case "Fixed": {
|
|
@@ -318,7 +319,7 @@ const renderArcaneEnergyCost = (translate, translateMap, format, localeJoin, res
|
|
|
318
319
|
? str => str
|
|
319
320
|
: str => translate("{$cost} per {$interval}", {
|
|
320
321
|
cost: str,
|
|
321
|
-
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, interval.unit, interval.value),
|
|
322
|
+
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, interval.unit, interval.value, true),
|
|
322
323
|
});
|
|
323
324
|
const wrapInPerLevel = (() => {
|
|
324
325
|
if (cost.Fixed.per_level === undefined) {
|
|
@@ -360,7 +361,7 @@ const renderArcaneEnergyCost = (translate, translateMap, format, localeJoin, res
|
|
|
360
361
|
case "Interval":
|
|
361
362
|
return translate("{$cost} per {$interval}", {
|
|
362
363
|
cost: translate("{$value} AE", { value: cost.Interval.value }),
|
|
363
|
-
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, cost.Interval.interval.unit, cost.Interval.interval.value),
|
|
364
|
+
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, cost.Interval.interval.unit, cost.Interval.interval.value, true),
|
|
364
365
|
});
|
|
365
366
|
case "ActivationAndHalfInterval":
|
|
366
367
|
return additionFormatter(translate("{$value} AE", {
|
|
@@ -369,7 +370,7 @@ const renderArcaneEnergyCost = (translate, translateMap, format, localeJoin, res
|
|
|
369
370
|
cost: translate("{$value} AE", {
|
|
370
371
|
value: Math.round(cost.ActivationAndHalfInterval.value / 2),
|
|
371
372
|
}),
|
|
372
|
-
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, cost.ActivationAndHalfInterval.interval.unit, cost.ActivationAndHalfInterval.interval.value),
|
|
373
|
+
interval: formatTimeSpan(translate, translateMap, format, responsiveTextSize, cost.ActivationAndHalfInterval.interval.unit, cost.ActivationAndHalfInterval.interval.value, true),
|
|
373
374
|
}));
|
|
374
375
|
case "Indefinite":
|
|
375
376
|
return ((mapNullable(translateMap(cost.Indefinite.translations)?.description, description => getResponsiveText(description, responsiveTextSize)) ?? MISSING_VALUE) +
|
|
@@ -846,6 +847,10 @@ export const getActivatableEntityDescription = createEntityDescriptionCreator(({
|
|
|
846
847
|
label: translate("Volume"),
|
|
847
848
|
value: renderVolumeValue(translate, translateMap, () => getAllResolvedSelectOptions(wrappedId), responsiveTextSize, volume),
|
|
848
849
|
})),
|
|
850
|
+
mapNullable(baseEntry.brew, brew => ({
|
|
851
|
+
label: translate("Brew"),
|
|
852
|
+
value: renderBrew(brew).run(env),
|
|
853
|
+
})),
|
|
849
854
|
mapNullable(baseEntry.cost, cost => renderCost(translate, translateMap, format, locale.join, locale.compare, () => getAllResolvedSelectOptions(wrappedId), responsiveTextSize, baseEntry.levels, cost)),
|
|
850
855
|
mapNullable(baseEntry.property, property => ({
|
|
851
856
|
label: translate("Property"),
|
|
@@ -161,6 +161,8 @@ const getAtomicEquipmentCost = (entry) => {
|
|
|
161
161
|
return "Various";
|
|
162
162
|
case "DependingOnPurchaseOrSale":
|
|
163
163
|
return entry.content.cost.DependingOnPurchaseOrSale.purchase;
|
|
164
|
+
case "Range":
|
|
165
|
+
return [entry.content.cost.Range.from, entry.content.cost.Range.to];
|
|
164
166
|
default:
|
|
165
167
|
return assertExhaustive(entry.content.cost);
|
|
166
168
|
}
|
|
@@ -101,6 +101,10 @@ export const renderAdventurePointsValue = (locale, getNameForId, getNameForSelec
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
case "DerivedFromSelection": {
|
|
104
|
+
const derivedTranslation = translateMap(value.DerivedFromSelection.translations);
|
|
105
|
+
if (derivedTranslation?.replacement !== undefined) {
|
|
106
|
+
return derivedTranslation.replacement;
|
|
107
|
+
}
|
|
104
108
|
const derivedSelectOptions = entry.select_options?.derived;
|
|
105
109
|
if (derivedSelectOptions === undefined) {
|
|
106
110
|
return renderFixedSelectOptionsAdventurePointsValue(locale, getAllSelectOptions, getNameForSelectOptionId, item => {
|
|
@@ -144,7 +148,7 @@ export const renderAdventurePointsValue = (locale, getNameForId, getNameForSelec
|
|
|
144
148
|
return translate("{$values} adventure points for a {$sized} animal shape", {
|
|
145
149
|
values: sizes.map(size => applyNegative(size.content.ap_value)).join("/"),
|
|
146
150
|
sized: sizes
|
|
147
|
-
.map(size => translateMap(size.content.translations)?.
|
|
151
|
+
.map(size => translateMap(size.content.translations)?.nameInAPValue ?? MISSING_VALUE)
|
|
148
152
|
.join("/"),
|
|
149
153
|
});
|
|
150
154
|
}
|
|
@@ -4,6 +4,12 @@ import type { Translate } from "../../helpers/translate.js";
|
|
|
4
4
|
* Renders a dice expression like "2D6" into a localized string.
|
|
5
5
|
*/
|
|
6
6
|
export declare const renderDice: (translate: Translate, dice: Dice) => string;
|
|
7
|
+
/**
|
|
8
|
+
* Renders a dice expression like "2D6" into a localized string.
|
|
9
|
+
*/
|
|
10
|
+
export declare const renderDiceR: (dice: Dice) => import("@elyukai/utils/reader").Reader<{
|
|
11
|
+
translate: Translate;
|
|
12
|
+
}, string>;
|
|
7
13
|
/**
|
|
8
14
|
* Renders a dice expression with an additional flat modifier, like "2D6+3" or "2D6-1".
|
|
9
15
|
*/
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { additionFormatter, subtractionFormatter } from "./mathOperation.js";
|
|
2
|
+
import { translateR } from "./reader.js";
|
|
2
3
|
/**
|
|
3
4
|
* Renders a dice expression like "2D6" into a localized string.
|
|
4
5
|
*/
|
|
5
6
|
export const renderDice = (translate, dice) => translate("{$count}D{$sides}", { count: dice.number, sides: dice.sides });
|
|
7
|
+
/**
|
|
8
|
+
* Renders a dice expression like "2D6" into a localized string.
|
|
9
|
+
*/
|
|
10
|
+
export const renderDiceR = (dice) => translateR("{$count}D{$sides}", { count: dice.number, sides: dice.sides });
|
|
6
11
|
/**
|
|
7
12
|
* Renders a dice expression with an additional flat modifier, like "2D6+3" or "2D6-1".
|
|
8
13
|
*/
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Reader } from "@elyukai/utils/reader";
|
|
1
2
|
import type { MathOperation } from "@optolith/database-schema/gen";
|
|
2
3
|
type UnaryFormatter = (value: string | number) => string;
|
|
3
4
|
type BinaryFormatter = (left: string | number, right: string | number) => string;
|
|
@@ -29,6 +30,10 @@ export declare const groupFormatter: UnaryFormatter;
|
|
|
29
30
|
* Render a math operation as a string, using the provided function to render the values.
|
|
30
31
|
*/
|
|
31
32
|
export declare const renderMathOperation: <T, R extends string | number>(operation: MathOperation<T>, renderValue: (value: T) => R, renderDirectValue?: (value: T) => R) => R | string;
|
|
33
|
+
/**
|
|
34
|
+
* Render a math operation as a string, using the provided function to render the values.
|
|
35
|
+
*/
|
|
36
|
+
export declare const renderMathOperationR: <T, R extends string | number, E>(operation: MathOperation<T>, renderValue: (value: T) => Reader<E, R>, renderDirectValue?: (value: T) => Reader<E, R>) => Reader<E, R | string>;
|
|
32
37
|
/**
|
|
33
38
|
* Evaluate a math operation, using the provided function to evaluate the values.
|
|
34
39
|
*/
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Reader } from "@elyukai/utils/reader";
|
|
1
2
|
import { assertExhaustive } from "@optolith/helpers/typeSafety";
|
|
2
3
|
const printOperand = (operand) => typeof operand === "number" ? operand.toFixed() : operand;
|
|
3
4
|
/**
|
|
@@ -72,6 +73,10 @@ export const renderMathOperation = (operation, renderValue, renderDirectValue) =
|
|
|
72
73
|
return assertExhaustive(operation);
|
|
73
74
|
}
|
|
74
75
|
};
|
|
76
|
+
/**
|
|
77
|
+
* Render a math operation as a string, using the provided function to render the values.
|
|
78
|
+
*/
|
|
79
|
+
export const renderMathOperationR = (operation, renderValue, renderDirectValue) => Reader.asks(env => renderMathOperation(operation, value => renderValue(value).run(env), renderDirectValue ? value => renderDirectValue(value).run(env) : undefined));
|
|
75
80
|
/**
|
|
76
81
|
* Evaluate a math operation, using the provided function to evaluate the values.
|
|
77
82
|
*/
|
package/lib/entities/poison.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { ensureNonEmpty } from "@elyukai/utils/array/nonEmpty";
|
|
2
2
|
import { isNotNullish, mapNullable } from "@elyukai/utils/nullable";
|
|
3
|
+
import { Reader } from "@elyukai/utils/reader";
|
|
3
4
|
import { sign } from "@elyukai/utils/string/number";
|
|
4
5
|
import { assertExhaustive } from "@elyukai/utils/typeSafety";
|
|
5
6
|
import { createEntityDescriptionCreator } from "../creator.js";
|
|
6
|
-
import { renderDice } from "./partial/dice.js";
|
|
7
|
+
import { renderDice, renderDiceR } from "./partial/dice.js";
|
|
7
8
|
import { renderAlternativeNames, renderChance, renderLaboratoryLevel, renderResistance, } from "./partial/herbary.js";
|
|
8
|
-
import {
|
|
9
|
+
import { renderMathOperationR } from "./partial/mathOperation.js";
|
|
9
10
|
import { printPlainGeneralPrerequisites } from "./partial/prerequisites/index.js";
|
|
10
11
|
import { parensIf } from "./partial/rated/activatable/parensIf.js";
|
|
12
|
+
import { translateMapR, translateR } from "./partial/reader.js";
|
|
11
13
|
import { ResponsiveTextSize } from "./partial/responsiveText.js";
|
|
12
|
-
import { formatTimeSpan } from "./partial/units/timeSpan.js";
|
|
14
|
+
import { formatTimeSpan, formatTimeSpanR } from "./partial/units/timeSpan.js";
|
|
13
15
|
import { MISSING_VALUE, UNHANDLED_VALUE } from "./partial/unknown.js";
|
|
14
16
|
const renderApplicationType = (translate, localeJoin, localeCompare, applicationType) => translate("{$types} poison", {
|
|
15
17
|
types: localeJoin(applicationType
|
|
@@ -69,7 +71,7 @@ const renderAddiction = (translate, translateMap, format, getInstanceById, addic
|
|
|
69
71
|
default:
|
|
70
72
|
return assertExhaustive(withdrawalPrevention.interval);
|
|
71
73
|
}
|
|
72
|
-
})()),
|
|
74
|
+
})(), true),
|
|
73
75
|
})),
|
|
74
76
|
]
|
|
75
77
|
.filter(isNotNullish)
|
|
@@ -158,48 +160,48 @@ const renderSourceTypeBasedValues = (translate, translateMap, format, getInstanc
|
|
|
158
160
|
return assertExhaustive(sourceType);
|
|
159
161
|
}
|
|
160
162
|
};
|
|
161
|
-
const renderStart = (
|
|
163
|
+
const renderStart = (start) => {
|
|
162
164
|
switch (start.kind) {
|
|
163
165
|
case "Immediate":
|
|
164
|
-
return
|
|
166
|
+
return translateR("immediate");
|
|
165
167
|
case "ExpressionBased":
|
|
166
|
-
return
|
|
168
|
+
return renderMathOperationR(start.ExpressionBased.value, (value) => {
|
|
167
169
|
switch (value.kind) {
|
|
168
170
|
case "Constant":
|
|
169
|
-
return value.Constant
|
|
171
|
+
return Reader.of(value.Constant);
|
|
170
172
|
case "Dice":
|
|
171
|
-
return
|
|
173
|
+
return renderDiceR(value.Dice);
|
|
172
174
|
case "CircleOfDamnation":
|
|
173
|
-
return
|
|
175
|
+
return translateR("CoD");
|
|
174
176
|
default:
|
|
175
177
|
return assertExhaustive(value);
|
|
176
178
|
}
|
|
177
|
-
});
|
|
179
|
+
}).thenW(value => formatTimeSpanR(start.ExpressionBased.unit, value));
|
|
178
180
|
case "Indefinite":
|
|
179
|
-
return
|
|
181
|
+
return translateMapR(start.Indefinite.translations).map(translation => translation?.description ?? UNHANDLED_VALUE);
|
|
180
182
|
default:
|
|
181
183
|
return assertExhaustive(start);
|
|
182
184
|
}
|
|
183
185
|
};
|
|
184
|
-
const renderDuration = (
|
|
186
|
+
const renderDuration = (duration) => {
|
|
185
187
|
switch (duration.kind) {
|
|
186
188
|
case "Instant":
|
|
187
|
-
return
|
|
189
|
+
return translateR("instant");
|
|
188
190
|
case "ExpressionBased":
|
|
189
|
-
return
|
|
191
|
+
return renderMathOperationR(duration.ExpressionBased.value, (value) => {
|
|
190
192
|
switch (value.kind) {
|
|
191
193
|
case "Constant":
|
|
192
|
-
return value.Constant
|
|
194
|
+
return Reader.of(value.Constant);
|
|
193
195
|
case "Dice":
|
|
194
|
-
return
|
|
196
|
+
return renderDiceR(value.Dice);
|
|
195
197
|
case "CircleOfDamnation":
|
|
196
|
-
return
|
|
198
|
+
return translateR("CoD");
|
|
197
199
|
default:
|
|
198
200
|
return assertExhaustive(value);
|
|
199
201
|
}
|
|
200
|
-
});
|
|
202
|
+
}).thenW(value => formatTimeSpanR(duration.ExpressionBased.unit, value));
|
|
201
203
|
case "Indefinite":
|
|
202
|
-
return
|
|
204
|
+
return translateMapR(duration.Indefinite.translations).map(translation => translation?.description ?? UNHANDLED_VALUE);
|
|
203
205
|
default:
|
|
204
206
|
return assertExhaustive(duration);
|
|
205
207
|
}
|
|
@@ -222,6 +224,11 @@ const renderCost = (translate, translateMap, cost) => {
|
|
|
222
224
|
})} (${translate("sale")})`;
|
|
223
225
|
case "Indefinite":
|
|
224
226
|
return translateMap(cost.Indefinite.translations)?.description ?? MISSING_VALUE;
|
|
227
|
+
case "Range":
|
|
228
|
+
return translate(".input {$from :number} .input {$to :number} {{{$from}–{$to} silverthalers}}", {
|
|
229
|
+
from: cost.Range.from,
|
|
230
|
+
to: cost.Range.to,
|
|
231
|
+
});
|
|
225
232
|
default:
|
|
226
233
|
return assertExhaustive(cost);
|
|
227
234
|
}
|
|
@@ -246,6 +253,12 @@ export const getPoisonEntityDescription = createEntityDescriptionCreator(({ getI
|
|
|
246
253
|
if (translation === undefined) {
|
|
247
254
|
return undefined;
|
|
248
255
|
}
|
|
256
|
+
const env = {
|
|
257
|
+
translate,
|
|
258
|
+
translateMap,
|
|
259
|
+
format,
|
|
260
|
+
responsiveTextSize: ResponsiveTextSize.Full,
|
|
261
|
+
};
|
|
249
262
|
const applicationType = renderApplicationType(translate, localeJoin, localeCompare, entry.application_type);
|
|
250
263
|
const { level, sourceType, ingestion, sideEffect, overdose, legality, special, addiction, typicalIngredients, priceOfIngedientsPerLevel, laboratory, brewingDifficulty, prerequisitesBrewingProcess, tradeSecret, note, } = renderSourceTypeBasedValues(translate, translateMap, format, getInstanceById, entry.source_type);
|
|
251
264
|
return {
|
|
@@ -293,14 +306,14 @@ export const getPoisonEntityDescription = createEntityDescriptionCreator(({ getI
|
|
|
293
306
|
},
|
|
294
307
|
{
|
|
295
308
|
label: translate("Start"),
|
|
296
|
-
value: renderStart(
|
|
309
|
+
value: renderStart(entry.start).run(env),
|
|
297
310
|
},
|
|
298
311
|
{
|
|
299
312
|
label: translate("Duration"),
|
|
300
|
-
value: renderDuration(
|
|
313
|
+
value: renderDuration(entry.duration.default).run(env) +
|
|
301
314
|
(entry.duration.reduced === undefined
|
|
302
315
|
? ""
|
|
303
|
-
: ` / ${renderDuration(
|
|
316
|
+
: ` / ${renderDuration(entry.duration.reduced).run(env)}`),
|
|
304
317
|
},
|
|
305
318
|
legality === undefined
|
|
306
319
|
? undefined
|
|
@@ -364,12 +377,17 @@ export const getPoisonEntityDescription = createEntityDescriptionCreator(({ getI
|
|
|
364
377
|
label: translate("Quality Levels"),
|
|
365
378
|
value: translate("The poison levels equals the QL."),
|
|
366
379
|
},
|
|
367
|
-
|
|
368
|
-
?
|
|
369
|
-
: {
|
|
380
|
+
translation.notes !== undefined
|
|
381
|
+
? {
|
|
370
382
|
label: translate("Note"),
|
|
371
|
-
value:
|
|
372
|
-
}
|
|
383
|
+
value: translation.notes,
|
|
384
|
+
}
|
|
385
|
+
: note === undefined
|
|
386
|
+
? undefined
|
|
387
|
+
: {
|
|
388
|
+
label: translate("Note"),
|
|
389
|
+
value: note,
|
|
390
|
+
},
|
|
373
391
|
],
|
|
374
392
|
},
|
|
375
393
|
],
|