@optolith/entity-descriptions 0.11.0 → 0.11.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 +11 -0
- package/lib/entities/activatable.d.ts +2 -1
- package/lib/entities/activatable.js +34 -13
- package/lib/entities/disease.d.ts +1 -1
- package/lib/entities/equipment.d.ts +1 -1
- package/lib/entities/partial/rated/activatable/cost.d.ts +2 -2
- package/lib/entities/partial/rated/activatable/targetCategory.js +2 -5
- package/lib/entities/partial/reader.d.ts +1 -1
- package/lib/entities/partial/responsiveText.d.ts +1 -1
- package/lib/index.d.ts +88 -88
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/lib/entities/partial/prerequisites/single/anyActivatableOfGroup.d.ts +0 -7
- package/lib/entities/partial/prerequisites/single/anyActivatableOfGroup.js +0 -16
- package/lib/entities/partial/prerequisites/single/rated copy.d.ts +0 -8
- package/lib/entities/partial/prerequisites/single/rated copy.js +0 -17
- package/lib/entities/partial/prerequisites/single/tinyActivatable copy.d.ts +0 -7
- package/lib/entities/partial/prerequisites/single/tinyActivatable copy.js +0 -16
- package/lib/helpers/publicationOptions.d.ts +0 -42
- package/lib/helpers/publicationOptions.js +0 -64
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
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.11.1](https://github.com/Optolith/entity-descriptions/compare/v0.11.0...v0.11.1) (2026-09-13)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* attributed target category ([8411c00](https://github.com/Optolith/entity-descriptions/commit/8411c00eb0ac8df5f4335a41db951578cbaffe26))
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* advanced special ability sorting ([fd8ec9c](https://github.com/Optolith/entity-descriptions/commit/fd8ec9cf41625bc67f243850045f2bdf358bae5b)), closes [#50](https://github.com/Optolith/entity-descriptions/issues/50)
|
|
14
|
+
* advanced special ability sorting (other parts) ([75ccc67](https://github.com/Optolith/entity-descriptions/commit/75ccc671ad4a60116067a0b5df143d0b1c1cc3f9))
|
|
15
|
+
* display additional name ([460385e](https://github.com/Optolith/entity-descriptions/commit/460385ee19ea7be58766fb46859256514c75208f))
|
|
5
16
|
## [0.11.0](https://github.com/Optolith/entity-descriptions/compare/v0.10.0...v0.11.0) (2026-09-13)
|
|
6
17
|
|
|
7
18
|
### ⚠ BREAKING CHANGES
|
|
@@ -34,6 +34,7 @@ export type BaseActivatable = {
|
|
|
34
34
|
*/
|
|
35
35
|
export type BaseActivatableTranslation = {
|
|
36
36
|
name: string;
|
|
37
|
+
additionalName?: string;
|
|
37
38
|
name_in_library?: string;
|
|
38
39
|
rules?: string;
|
|
39
40
|
range?: string;
|
|
@@ -48,7 +49,7 @@ export type BaseActivatableTranslation = {
|
|
|
48
49
|
/**
|
|
49
50
|
* Get a JSON representation of the rules text for a special ability.
|
|
50
51
|
*/
|
|
51
|
-
export declare const getActivatableEntityDescription: import("../creator.js").EntityDescriptionCreator<"
|
|
52
|
+
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", {
|
|
52
53
|
getInstanceById: GetInstanceById<"Publication" | "Subject" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "TradeSecret" | "Aspect" | "Property" | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Weapon" | "Patron" | "PersonalityTrait" | "Brew" | "Blessing" | "Cantrip">;
|
|
53
54
|
getAllInstances: GetAllInstances<"Script">;
|
|
54
55
|
getResolvedSelectOptionById: GetResolvedSelectOptionById;
|
|
@@ -4,6 +4,7 @@ import { count } from "@elyukai/utils/array/reductions";
|
|
|
4
4
|
import { deepEqual } from "@elyukai/utils/equality";
|
|
5
5
|
import { constant, on } from "@elyukai/utils/function";
|
|
6
6
|
import { isNotNullish } from "@elyukai/utils/nullable";
|
|
7
|
+
import { reduceCompare } from "@elyukai/utils/ordering";
|
|
7
8
|
import { Reader } from "@elyukai/utils/reader";
|
|
8
9
|
import { numAsc } from "@optolith/helpers/compare";
|
|
9
10
|
import { sign } from "@optolith/helpers/math";
|
|
@@ -546,7 +547,7 @@ const renderAdvancedSpecialAbilityName = (translate, translateMap, getInstanceBy
|
|
|
546
547
|
const normalizedId = normalizeId(entityName, id);
|
|
547
548
|
return `^[${mapNullable(printActivatableName(getInstanceById, translate, normalizedId, option, undefined, getResolvedSelectOptionById, false), name => renderActivatableNameComponents(translateMap, name, false)) ?? MISSING_VALUE}](entity: "${normalizedId.kind}", instance: "${fromUniformCase(normalizedId)}", style: "normal")`;
|
|
548
549
|
};
|
|
549
|
-
const renderAdvancedValue = (translate, translateMap, localeJoin, getInstanceById, getResolvedSelectOptionById, entityName, advanced) => {
|
|
550
|
+
const renderAdvancedValue = (translate, translateMap, localeJoin, localeCompare, getInstanceById, getResolvedSelectOptionById, entityName, advanced) => {
|
|
550
551
|
if (advanced.every(entry => entry.kind === "OneOf") &&
|
|
551
552
|
isNotEmpty(advanced) &&
|
|
552
553
|
advanced.every(entry => entry.OneOf.options.length === 3)) {
|
|
@@ -558,7 +559,9 @@ const renderAdvancedValue = (translate, translateMap, localeJoin, getInstanceByI
|
|
|
558
559
|
if (uniqueOptions.length === advanced.length) {
|
|
559
560
|
const [first, second] = optionsInAllEntries.map(option => renderAdvancedSpecialAbilityName(translate, translateMap, getInstanceById, getResolvedSelectOptionById, entityName, option));
|
|
560
561
|
return [
|
|
561
|
-
...uniqueOptions
|
|
562
|
+
...uniqueOptions
|
|
563
|
+
.map(option => renderAdvancedSpecialAbilityName(translate, translateMap, getInstanceById, getResolvedSelectOptionById, entityName, option))
|
|
564
|
+
.toSorted(localeCompare),
|
|
562
565
|
translate("one or two of these special abilities can alternatively be replaced by advanced special abilities {$first} and/or {$second}", { first, second }),
|
|
563
566
|
].join(", ");
|
|
564
567
|
}
|
|
@@ -568,25 +571,38 @@ const renderAdvancedValue = (translate, translateMap, localeJoin, getInstanceByI
|
|
|
568
571
|
entry.DeriveFromExternalOption.display_option === undefined);
|
|
569
572
|
const anyEntriesToGenerate = count(advanced, entry => entry.kind === "Any");
|
|
570
573
|
const arr = [
|
|
571
|
-
...advanced
|
|
574
|
+
...advanced
|
|
575
|
+
.map((entry) => {
|
|
572
576
|
switch (entry.kind) {
|
|
573
577
|
case "General":
|
|
574
|
-
return
|
|
578
|
+
return [
|
|
579
|
+
"general",
|
|
580
|
+
renderAdvancedSpecialAbilityName(translate, translateMap, getInstanceById, getResolvedSelectOptionById, entityName, entry.General),
|
|
581
|
+
];
|
|
575
582
|
case "RestrictOptions":
|
|
576
|
-
return
|
|
583
|
+
return [
|
|
584
|
+
"general",
|
|
585
|
+
renderAdvancedSpecialAbilityName(translate, translateMap, getInstanceById, getResolvedSelectOptionById, entityName, entry.RestrictOptions.id, entry.RestrictOptions.option),
|
|
586
|
+
];
|
|
577
587
|
case "OneOf": {
|
|
578
588
|
if (entry.OneOf.display_option !== undefined) {
|
|
579
589
|
switch (entry.OneOf.display_option.kind) {
|
|
580
590
|
case "Hide":
|
|
581
591
|
return undefined;
|
|
582
592
|
case "ReplaceWith":
|
|
583
|
-
return
|
|
584
|
-
|
|
593
|
+
return [
|
|
594
|
+
"special",
|
|
595
|
+
translateMap(entry.OneOf.display_option.ReplaceWith.translations)
|
|
596
|
+
?.replacement ?? MISSING_VALUE,
|
|
597
|
+
];
|
|
585
598
|
default:
|
|
586
599
|
return assertExhaustive(entry.OneOf.display_option);
|
|
587
600
|
}
|
|
588
601
|
}
|
|
589
|
-
return
|
|
602
|
+
return [
|
|
603
|
+
"general",
|
|
604
|
+
localeJoin(entry.OneOf.options.map(option => renderAdvancedSpecialAbilityName(translate, translateMap, getInstanceById, getResolvedSelectOptionById, entityName, option)), "disjunction"),
|
|
605
|
+
];
|
|
590
606
|
}
|
|
591
607
|
case "DeriveFromExternalOption":
|
|
592
608
|
if (entry.DeriveFromExternalOption.display_option !== undefined) {
|
|
@@ -594,7 +610,10 @@ const renderAdvancedValue = (translate, translateMap, localeJoin, getInstanceByI
|
|
|
594
610
|
case "Hide":
|
|
595
611
|
return undefined;
|
|
596
612
|
case "ReplaceWith":
|
|
597
|
-
return
|
|
613
|
+
return [
|
|
614
|
+
"special",
|
|
615
|
+
translateMap(entry.DeriveFromExternalOption.display_option.ReplaceWith.translations)?.replacement ?? MISSING_VALUE,
|
|
616
|
+
];
|
|
598
617
|
default:
|
|
599
618
|
return assertExhaustive(entry.DeriveFromExternalOption.display_option);
|
|
600
619
|
}
|
|
@@ -605,7 +624,10 @@ const renderAdvancedValue = (translate, translateMap, localeJoin, getInstanceByI
|
|
|
605
624
|
default:
|
|
606
625
|
return assertExhaustive(entry);
|
|
607
626
|
}
|
|
608
|
-
})
|
|
627
|
+
})
|
|
628
|
+
.filter((item) => isNotNullish(item) && item[1] !== undefined)
|
|
629
|
+
.toSorted(reduceCompare(on(([type]) => type, localeCompare), on(([, value]) => value, localeCompare)))
|
|
630
|
+
.map(value => value[1]),
|
|
609
631
|
derivedFromExternalOptionEntriesToGenerate === 0
|
|
610
632
|
? undefined
|
|
611
633
|
: translate(".input {$count :number} {{{$count} more by primary patron}}", {
|
|
@@ -782,8 +804,7 @@ export const getActivatableEntityDescription = createEntityDescriptionCreator(({
|
|
|
782
804
|
? name => translate("Tradition ({$tradition})", { tradition: name })
|
|
783
805
|
: name => name;
|
|
784
806
|
return {
|
|
785
|
-
title: makeTraditionName(translation.name_in_library ?? translation.name) +
|
|
786
|
-
(baseEntry.levels !== undefined ? ` I–${romanize(baseEntry.levels)}` : ""),
|
|
807
|
+
title: makeTraditionName(translation.name_in_library ?? translation.name + parensIf(translation.additionalName)) + (baseEntry.levels !== undefined ? ` I–${romanize(baseEntry.levels)}` : ""),
|
|
787
808
|
subtitle: mapNullable(baseEntry.subtype, subtype => renderAdvantageDisadvantageSubtype(subtype).run(env)) ??
|
|
788
809
|
mapNullable(baseEntry.usage_type, usageType => renderCombatSpecialAbilityType(usageType).run(env)),
|
|
789
810
|
badge: mapNullable(entityName === "CombatStyleSpecialAbility" || entityName === "AdvancedCombatSpecialAbility"
|
|
@@ -839,7 +860,7 @@ export const getActivatableEntityDescription = createEntityDescriptionCreator(({
|
|
|
839
860
|
mapNullable(baseEntry.advanced, advanced => isStyleSpecialAbilityKind(entityName)
|
|
840
861
|
? {
|
|
841
862
|
label: renderAdvancedLabel(translate, entityName),
|
|
842
|
-
value: renderAdvancedValue(translate, translateMap, locale.join, getInstanceById, getResolvedSelectOptionById, entityName, advanced),
|
|
863
|
+
value: renderAdvancedValue(translate, translateMap, locale.join, locale.compare, getInstanceById, getResolvedSelectOptionById, entityName, advanced),
|
|
843
864
|
}
|
|
844
865
|
: undefined),
|
|
845
866
|
mapNullable(baseEntry.penalty, penalty => ({
|
|
@@ -3,7 +3,7 @@ import type { IdMap } from "../index.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Get a JSON representation of the rules text for an optional rule.
|
|
5
5
|
*/
|
|
6
|
-
export declare const getDiseaseEntityDescription: import("../creator.js").EntityDescriptionCreator<"
|
|
6
|
+
export declare const getDiseaseEntityDescription: import("../creator.js").EntityDescriptionCreator<"Disease" | "AnimalDisease", {
|
|
7
7
|
getInstanceById: GetInstanceById<"Publication" | "AnimalType" | "DerivedCharacteristic">;
|
|
8
8
|
idMap: IdMap;
|
|
9
9
|
}, import("../index.js").EntityDescription>;
|
|
@@ -19,7 +19,7 @@ export declare const renderRangedWeapon: <Damage>(translate: Translate, translat
|
|
|
19
19
|
/**
|
|
20
20
|
* Get a JSON representation of the rules text for equipment.
|
|
21
21
|
*/
|
|
22
|
-
export declare const getEquipmentEntityDescription: import("../creator.js").EntityDescriptionCreator<"Ammunition" | "
|
|
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
23
|
getInstanceById: GetInstanceById<"Publication" | "Attribute" | "Reach" | "SocialStatus" | "CloseCombatTechnique" | "RangedCombatTechnique" | "MagicalTradition" | "BlessedTradition" | "DerivedCharacteristic" | AmmunitionishIdentifier["kind"] | "Race" | "Culture" | "Profession" | "Skill">;
|
|
24
24
|
idMap: IdMap;
|
|
25
25
|
}, import("../index.js").EntityDescription>;
|
|
@@ -42,7 +42,7 @@ export declare const renderIndefiniteCost: (value: IndefiniteCost, shouldAppendN
|
|
|
42
42
|
/**
|
|
43
43
|
* Returns the text for a standalone one-time cost map of an activatable skill.
|
|
44
44
|
*/
|
|
45
|
-
export declare const renderStandaloneCostMap: (value: StandaloneCostMap) => Reader<StdEnv<"
|
|
45
|
+
export declare const renderStandaloneCostMap: (value: StandaloneCostMap) => Reader<StdEnv<"tm" | "t" | "rts"> & {
|
|
46
46
|
translate: import("../../../../helpers/translate.js").Translate;
|
|
47
47
|
energyUnit: import("../../units/energy.js").EnergyUnit;
|
|
48
48
|
}, string>;
|
|
@@ -63,7 +63,7 @@ export declare const renderNonModifiableSustainedCost: (value: NonModifiableSust
|
|
|
63
63
|
responsiveTextSize: import("../../responsiveText.js").ResponsiveTextSize;
|
|
64
64
|
} & {
|
|
65
65
|
translate: import("../../../../helpers/translate.js").Translate;
|
|
66
|
-
} & StdEnv<"f" | "
|
|
66
|
+
} & StdEnv<"f" | "tm" | "t" | "rts"> & StdEnv<"tm" | "t" | "rts" | "eu", never, never, never>, string>;
|
|
67
67
|
/**
|
|
68
68
|
* Returns the text for the cost of a sustained activatable skill.
|
|
69
69
|
*/
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { Reader } from "@elyukai/utils/reader";
|
|
2
|
-
import { mapNullable } from "@optolith/helpers/nullable";
|
|
3
2
|
import { assertExhaustive } from "@optolith/helpers/typeSafety";
|
|
4
|
-
import {
|
|
3
|
+
import { attributedNameR, translateMapR, translateR } from "../../reader.js";
|
|
5
4
|
import { MISSING_VALUE } from "../../unknown.js";
|
|
6
5
|
import { appendInParensIfNotEmpty } from "./parensIf.js";
|
|
7
|
-
const renderPredefined = (targetCategoryId) =>
|
|
8
|
-
.thenW(getInstanceById => mapNullable(getInstanceById("TargetCategory", targetCategoryId), targetCategory => translateMapR(targetCategory.translations).map(translation => translation?.name)) ?? Reader.of(undefined))
|
|
9
|
-
.map(translation => translation ?? MISSING_VALUE);
|
|
6
|
+
const renderPredefined = (targetCategoryId) => attributedNameR("target-category", "TargetCategory", targetCategoryId).map(name => name ?? MISSING_VALUE);
|
|
10
7
|
const getTargetCategoryTranslationByType = (id) => {
|
|
11
8
|
switch (id.kind) {
|
|
12
9
|
case "Self":
|
|
@@ -316,5 +316,5 @@ export declare const modifyBySpeedR: Reader<{
|
|
|
316
316
|
/**
|
|
317
317
|
* Returns the default values wrapped in a reader if the value is nullish, otherwise applies the given function to the value and returns the result.
|
|
318
318
|
*/
|
|
319
|
-
export declare const mapNullableR: <T, U, R>(defaultValue: U, fn: (value: NonNullable<T>) => Reader<U, R>) => (value: T) => Reader<
|
|
319
|
+
export declare const mapNullableR: <T, U, R>(defaultValue: U, fn: (value: NonNullable<T>) => Reader<U, R>) => (value: T) => Reader<U, R> | Reader<unknown, U>;
|
|
320
320
|
export {};
|
|
@@ -40,4 +40,4 @@ export declare const replaceTextIfNeeded: (translations: LocaleMap<{
|
|
|
40
40
|
*/
|
|
41
41
|
export declare const appendNoteIfNeeded: (translations: LocaleMap<{
|
|
42
42
|
note?: ResponsiveTextOptional;
|
|
43
|
-
}> | undefined, valueToAppendTo: string) => Reader<StdEnv<"
|
|
43
|
+
}> | undefined, valueToAppendTo: string) => Reader<StdEnv<"tm" | "rts">, string>;
|