@optolith/entity-descriptions 0.4.8 → 0.4.11

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/lib/entities/activatable.js +17 -14
  3. package/lib/entities/curriculum.js +14 -21
  4. package/lib/entities/derivedCharacteristic.d.ts +0 -2
  5. package/lib/entities/derivedCharacteristic.js +10 -17
  6. package/lib/entities/disease.js +5 -1
  7. package/lib/entities/elixir.js +12 -10
  8. package/lib/entities/equipment.d.ts +6 -5
  9. package/lib/entities/equipment.js +19 -6
  10. package/lib/entities/equipmentPackage.js +2 -1
  11. package/lib/entities/liturgicalChant.js +7 -3
  12. package/lib/entities/partial/commonnessRatedAdvantagesAndDisadvantages.js +8 -12
  13. package/lib/entities/partial/herbary.js +5 -8
  14. package/lib/entities/partial/markdown.d.ts +55 -0
  15. package/lib/entities/partial/markdown.js +59 -0
  16. package/lib/entities/partial/prerequisites/index.d.ts +3 -3
  17. package/lib/entities/partial/prerequisites/index.js +3 -3
  18. package/lib/entities/partial/prerequisites/part.js +8 -3
  19. package/lib/entities/partial/prerequisites/prerequisiteGroups.d.ts +1 -1
  20. package/lib/entities/partial/prerequisites/prerequisiteGroups.js +10 -7
  21. package/lib/entities/partial/prerequisites/single/culture.js +2 -1
  22. package/lib/entities/partial/prerequisites/single/personalityTrait.js +2 -1
  23. package/lib/entities/partial/prerequisites/single/profession.js +4 -1
  24. package/lib/entities/partial/prerequisites/single/race.js +2 -1
  25. package/lib/entities/partial/prerequisites/single/rated.js +2 -27
  26. package/lib/entities/partial/prerequisites/single/ratedMinimumNumber.js +2 -1
  27. package/lib/entities/partial/prerequisites/single/ratedSum.js +2 -1
  28. package/lib/entities/partial/prerequisites/single/state.js +2 -1
  29. package/lib/entities/partial/rated/activatable/checkResultBased.js +3 -1
  30. package/lib/entities/partial/reader.d.ts +33 -0
  31. package/lib/entities/partial/reader.js +13 -0
  32. package/lib/entities/personalityTrait.js +9 -2
  33. package/lib/entities/poison.js +20 -9
  34. package/lib/entities/profession.d.ts +2 -2
  35. package/lib/entities/profession.js +133 -38
  36. package/lib/entities/race.d.ts +1 -1
  37. package/lib/entities/race.js +23 -23
  38. package/lib/entities/spell.d.ts +4 -2
  39. package/lib/entities/spell.js +17 -29
  40. package/lib/index.d.ts +64 -64
  41. package/lib/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +5 -5
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Some helpers to create Markdown content.
3
+ */
4
+ import type { EntityMap } from "optolith-database-schema/gen";
5
+ import { type IdArgsVariant } from "tsondb/schema/gen";
6
+ import type { GetInstanceById } from "../../helpers/getTypes.js";
7
+ import type { LocaleMap, TranslateMap } from "../../helpers/translate.js";
8
+ /**
9
+ * Creates an attributed string in Markdown format.
10
+ */
11
+ export declare const attributedString: (text: string, rawAttributes: Partial<Record<string, string>>) => string;
12
+ /**
13
+ * Display an instance of an entity in Markdown format.
14
+ */
15
+ export declare const attributedInstance: (name: string, entity: string, id?: string, other?: Record<string, string>) => string;
16
+ /**
17
+ * Renders the name of an instance in an attributed string.
18
+ */
19
+ export declare const attributedName: <E extends { [K in keyof EntityMap]: EntityMap[K] extends {
20
+ translations: LocaleMap<{
21
+ name: string;
22
+ }>;
23
+ } ? K : never; }[keyof EntityMap]>(translateMap: TranslateMap, getInstanceById: GetInstanceById<E>, context: string, ...args: IdArgsVariant<EntityMap, E>) => string | undefined;
24
+ /**
25
+ * Renders the name of an instance according to a custom function.
26
+ */
27
+ export declare const customName: <E extends { [K in keyof EntityMap]: EntityMap[K] extends {
28
+ translations: LocaleMap<object>;
29
+ } ? K : never; }[keyof EntityMap]>(translateMap: TranslateMap, getInstanceById: GetInstanceById<E>, fn: (translation: EntityMap[E]["translations"][string]) => string, ...args: IdArgsVariant<EntityMap, E>) => string | undefined;
30
+ /**
31
+ * Renders the name of an instance according to a custom function in an attributed string.
32
+ */
33
+ export declare const attributedCustomName: <E extends { [K in keyof EntityMap]: EntityMap[K] extends {
34
+ translations: LocaleMap<object>;
35
+ } ? K : never; }[keyof EntityMap]>(translateMap: TranslateMap, getInstanceById: GetInstanceById<E>, context: string, fn: (translation: EntityMap[E]["translations"][string]) => string, ...args: IdArgsVariant<EntityMap, E>) => string | undefined;
36
+ /**
37
+ * Renders the name of an instance in an attributed string.
38
+ */
39
+ export declare const attributedNameFromInstance: (translateMap: TranslateMap, instance: {
40
+ translations: LocaleMap<{
41
+ name: string;
42
+ }>;
43
+ } | undefined, context: string, ...args: IdArgsVariant<EntityMap, keyof EntityMap>) => string | undefined;
44
+ /**
45
+ * Renders the name of an instance in an attributed string.
46
+ */
47
+ export declare const attributedNameFromTranslation: (translation: {
48
+ name: string;
49
+ } | undefined, context: string, ...args: IdArgsVariant<EntityMap, keyof EntityMap>) => string | undefined;
50
+ /**
51
+ * Renders the name of an instance in an attributed string.
52
+ */
53
+ export declare const attributedNameFromSafeTranslation: (translation: {
54
+ name: string;
55
+ }, context: string, ...args: IdArgsVariant<EntityMap, keyof EntityMap>) => string;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Some helpers to create Markdown content.
3
+ */
4
+ import { mapNullable } from "@elyukai/utils/nullable";
5
+ import { normalizedIdArgs } from "tsondb/schema/gen";
6
+ /**
7
+ * Creates an attributed string in Markdown format.
8
+ */
9
+ export const attributedString = (text, rawAttributes) => `^[${text}](${Object.entries(rawAttributes)
10
+ .filter((pair) => pair[1] !== undefined)
11
+ .map(([key, value]) => `${key}: ${value}`)
12
+ .join(", ")})`;
13
+ /**
14
+ * Display an instance of an entity in Markdown format.
15
+ */
16
+ export const attributedInstance = (name, entity, id, other) => attributedString(name, {
17
+ ...other,
18
+ entity: `"${entity}"`,
19
+ instance: id === undefined ? undefined : `"${id}"`,
20
+ });
21
+ /**
22
+ * Renders the name of an instance in an attributed string.
23
+ */
24
+ export const attributedName = (translateMap, getInstanceById, context, ...args) => {
25
+ const id = normalizedIdArgs(args);
26
+ return mapNullable(translateMap(getInstanceById(...args)?.translations)?.name, name => attributedInstance(name, id.entityName, id.id, { context: `"${context}"` }));
27
+ };
28
+ /**
29
+ * Renders the name of an instance according to a custom function.
30
+ */
31
+ export const customName = (translateMap, getInstanceById, fn, ...args) => mapNullable(translateMap(getInstanceById(...args)?.translations), translation => fn(translation));
32
+ /**
33
+ * Renders the name of an instance according to a custom function in an attributed string.
34
+ */
35
+ export const attributedCustomName = (translateMap, getInstanceById, context, fn, ...args) => {
36
+ const id = normalizedIdArgs(args);
37
+ return mapNullable(translateMap(getInstanceById(...args)?.translations), translation => attributedInstance(fn(translation), id.entityName, id.id, { context: `"${context}"` }));
38
+ };
39
+ /**
40
+ * Renders the name of an instance in an attributed string.
41
+ */
42
+ export const attributedNameFromInstance = (translateMap, instance, context, ...args) => {
43
+ const id = normalizedIdArgs(args);
44
+ return mapNullable(translateMap(instance?.translations)?.name, name => attributedInstance(name, id.entityName, id.id, { context: `"${context}"` }));
45
+ };
46
+ /**
47
+ * Renders the name of an instance in an attributed string.
48
+ */
49
+ export const attributedNameFromTranslation = (translation, context, ...args) => {
50
+ const id = normalizedIdArgs(args);
51
+ return mapNullable(translation?.name, name => attributedInstance(name, id.entityName, id.id, { context: `"${context}"` }));
52
+ };
53
+ /**
54
+ * Renders the name of an instance in an attributed string.
55
+ */
56
+ export const attributedNameFromSafeTranslation = (translation, context, ...args) => {
57
+ const id = normalizedIdArgs(args);
58
+ return attributedInstance(translation.name, id.entityName, id.id, { context: `"${context}"` });
59
+ };
@@ -1,4 +1,4 @@
1
- import type { ActivatableIdentifier, AdvantageDisadvantagePrerequisites, AnimistPowerPrerequisites, ArcaneTraditionPrerequisites, DerivedCharacteristicPrerequisites, EnhancementPrerequisites, GeneralPrerequisites, GeodeRitualPrerequisites, InfluencePrerequisites, LanguagePrerequisites, LiturgyPrerequisites, PersonalityTraitPrerequisites, PlainGeneralPrerequisites, ProfessionPrerequisites, PublicationPrerequisites, RatedIdentifier, SpecialAbilityIdentifier, SpellworkPrerequisites } from "optolith-database-schema/gen";
1
+ import type { ActivatableIdentifier, AdvantageDisadvantagePrerequisites, AnimistPowerPrerequisites, ArcaneTraditionPrerequisites, DerivedCharacteristicPrerequisites, EnhancementPrerequisites, GeneralPrerequisites, GeodeRitualPrerequisites, InfluencePrerequisites, LanguagePrerequisites, LiturgyPrerequisites, PersonalityTraitPrerequisites, PlainGeneralPrerequisites, ProfessionPrerequisites, PublicationPrerequisites, RatedIdentifier, SpellworkPrerequisites } from "optolith-database-schema/gen";
2
2
  import type { GetAllChildInstancesForParent, GetInstanceById } from "../../../helpers/getTypes.js";
3
3
  import type { LocaleEnvironment } from "../../../helpers/locale.js";
4
4
  import type { GetResolvedSelectOptionById } from "./single/activatable.js";
@@ -18,7 +18,7 @@ export declare const printPlainGeneralPrerequisites: (getInstanceById: GetInstan
18
18
  * Print general prerequisites as a string.
19
19
  */
20
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?: {
21
- id: SpecialAbilityIdentifier;
21
+ id: ActivatableIdentifier;
22
22
  levels: number;
23
23
  }, trailingText?: string) => string;
24
24
  /**
@@ -60,7 +60,7 @@ export declare const printAnimistPowerPrerequisites: (getInstanceById: GetInstan
60
60
  /**
61
61
  * Print geode ritual prerequisites as a string.
62
62
  */
63
- export declare const printGeodeRitualPrerequisites: (getInstanceById: GetInstanceById<"Influence">, locale: LocaleEnvironment, value: GeodeRitualPrerequisites) => string;
63
+ export declare const printGeodeRitualPrerequisites: (getInstanceById: GetInstanceById<"Influence" | ActivatableIdentifier["kind"] | "Aspect">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, value: GeodeRitualPrerequisites) => string;
64
64
  /**
65
65
  * Print enhancement prerequisites as a string.
66
66
  */
@@ -85,7 +85,7 @@ const printPrerequisitesForLevels = (printPrerequisite, locale, value, printPrev
85
85
  level: i + 2,
86
86
  prerequisite: {
87
87
  kind: "Single",
88
- Single: printPreviousLevelPrerequisites.createPreerequisite(i + 2),
88
+ Single: printPreviousLevelPrerequisites.createPrerequisite(i + 1),
89
89
  },
90
90
  }));
91
91
  const groupedByLevel = Map.groupBy([...value, ...previousLevelPrerequisites], prerequisite => prerequisite.level);
@@ -153,7 +153,7 @@ export const printGeneralPrerequisites = (getInstanceById, getResolvedSelectOpti
153
153
  ? undefined
154
154
  : {
155
155
  levels: printPreviousLevelPrerequisites.levels,
156
- createPreerequisite: (level) => ({
156
+ createPrerequisite: (level) => ({
157
157
  kind: "Activatable",
158
158
  Activatable: {
159
159
  id: printPreviousLevelPrerequisites.id,
@@ -201,7 +201,7 @@ export const printAnimistPowerPrerequisites = (getInstanceById, locale, value) =
201
201
  /**
202
202
  * Print geode ritual prerequisites as a string.
203
203
  */
204
- export const printGeodeRitualPrerequisites = (getInstanceById, locale, value) => printPlainPrerequisites(prerequisite => printGeodeRitualPrerequisiteGroup(getInstanceById, locale, prerequisite), locale, value);
204
+ export const printGeodeRitualPrerequisites = (getInstanceById, getResolvedSelectOptionById, locale, value) => printPlainPrerequisites(prerequisite => printGeodeRitualPrerequisiteGroup(getInstanceById, getResolvedSelectOptionById, locale, prerequisite), locale, value);
205
205
  /**
206
206
  * Print enhancement prerequisites as a string.
207
207
  */
@@ -5,6 +5,7 @@ import { compareNumber, reduceCompare } from "@elyukai/utils/ordering";
5
5
  import { assertExhaustive } from "@optolith/helpers/typeSafety";
6
6
  import { fromUniformCase } from "tsondb/schema/gen";
7
7
  import { renderActivatableNameComponents, renderActivatableNameComponentsCombinedIfPossible, } from "../activatableNameChunks.js";
8
+ import { attributedInstance } from "../markdown.js";
8
9
  /**
9
10
  * Type guard for prerequisite parts with a value object.
10
11
  */
@@ -18,15 +19,19 @@ const countFurtherToCombined = (part, remainingParts) => {
18
19
  remainingParts.length
19
20
  : indexHasDifferentBaseValues;
20
21
  };
22
+ const wrapActivatableInAttributedString = (text, id) => attributedInstance(text, id.kind, fromUniformCase(id), { context: '"prerequisite"' });
21
23
  const joinAdjacentParts = (translateMap, localeCompare, part, remainingParts) => {
22
24
  const valuesWithSameBase = remainingParts.slice(0, countFurtherToCombined(part, remainingParts));
23
25
  if (valuesWithSameBase.length > 0) {
24
26
  return [
25
- renderActivatableNameComponentsCombinedIfPossible(translateMap, [part.value, ...valuesWithSameBase.map(p => p.value)], true, list => list.toSorted(localeCompare).join(", ")),
27
+ wrapActivatableInAttributedString(renderActivatableNameComponentsCombinedIfPossible(translateMap, [part.value, ...valuesWithSameBase.map(p => p.value)], true, list => list.toSorted(localeCompare).join(", ")), part.value.id),
26
28
  valuesWithSameBase.length,
27
29
  ];
28
30
  }
29
- return [renderActivatableNameComponents(translateMap, part.value, true), 0];
31
+ return [
32
+ wrapActivatableInAttributedString(renderActivatableNameComponents(translateMap, part.value, true), part.value.id),
33
+ 0,
34
+ ];
30
35
  };
31
36
  const appendBySentenceType = (previouslyRendered, currentRendered, sentenceType, isLast) => {
32
37
  switch (sentenceType?.kind) {
@@ -76,7 +81,7 @@ const appendPrerequisitePartGroup = (previous, translateMap, localeCompare, part
76
81
  return parts.reduce((acc, current, i, arr) => appendBySentenceType(acc, (current.label ?? "") +
77
82
  (typeof current.value === "string"
78
83
  ? current.value
79
- : renderActivatableNameComponents(translateMap, current.value, true)), current.sentenceType, isLast && i === arr.length - 1), previous);
84
+ : wrapActivatableInAttributedString(renderActivatableNameComponents(translateMap, current.value, true), current.value.id)), current.sentenceType, isLast && i === arr.length - 1), previous);
80
85
  }
81
86
  };
82
87
  /**
@@ -54,7 +54,7 @@ export declare const printAnimistPowerPrerequisiteGroup: (getInstanceById: GetIn
54
54
  /**
55
55
  * Print the translation of a geode ritual prerequisite group.
56
56
  */
57
- export declare const printGeodeRitualPrerequisiteGroup: (getInstanceById: GetInstanceById<"Influence">, locale: LocaleEnvironment, prerequisite: GeodeRitualPrerequisiteGroup) => PrerequisitePart | undefined;
57
+ export declare const printGeodeRitualPrerequisiteGroup: (getInstanceById: GetInstanceById<"Influence" | ActivatableIdentifier["kind"] | "Aspect">, getResolvedSelectOptionById: GetResolvedSelectOptionById, locale: LocaleEnvironment, prerequisite: GeodeRitualPrerequisiteGroup) => PrerequisitePart | undefined;
58
58
  /**
59
59
  * Print the translation of an enhancement prerequisite group.
60
60
  */
@@ -241,13 +241,16 @@ printAnimistPowerPrerequisite(getInstanceById, locale, prerequisite.AnimistPower
241
241
  /**
242
242
  * Print the translation of a geode ritual prerequisite group.
243
243
  */
244
- export const printGeodeRitualPrerequisiteGroup = (getInstanceById, locale, prerequisite) =>
245
- // switch (prerequisite.tag) {
246
- // case "Influence":
247
- // default:
248
- // return assertExhaustive(prerequisite)
249
- // }
250
- printInfluencePrerequisite(getInstanceById, locale, prerequisite.Influence);
244
+ export const printGeodeRitualPrerequisiteGroup = (getInstanceById, getResolvedSelectOptionById, locale, prerequisite) => {
245
+ switch (prerequisite.kind) {
246
+ case "Activatable":
247
+ return printActivatablePrerequisite(getInstanceById, getResolvedSelectOptionById, locale, prerequisite.Activatable, false);
248
+ case "Influence":
249
+ return printInfluencePrerequisite(getInstanceById, locale, prerequisite.Influence);
250
+ default:
251
+ return assertExhaustive(prerequisite);
252
+ }
253
+ };
251
254
  /**
252
255
  * Print the translation of an enhancement prerequisite group.
253
256
  */
@@ -1,3 +1,4 @@
1
+ import { attributedNameFromSafeTranslation } from "../../markdown.js";
1
2
  import { printDisplayOption } from "../displayOption.js";
2
3
  /**
3
4
  * Get the translation of a culture prerequisite.
@@ -13,7 +14,7 @@ export const printCulturePrerequisite = (getInstanceById, locale, prerequisite)
13
14
  }
14
15
  return {
15
16
  label: `${locale.translate("Culture")} `,
16
- value: cultureTranslation.name,
17
+ value: attributedNameFromSafeTranslation(cultureTranslation, "prerequisite", "Culture", prerequisite.id),
17
18
  sentenceType: undefined,
18
19
  isMeta: false,
19
20
  };
@@ -1,3 +1,4 @@
1
+ import { attributedNameFromSafeTranslation } from "../../markdown.js";
1
2
  import { printDisplayOption } from "../displayOption.js";
2
3
  /**
3
4
  * Get the translation of a personality trait prerequisite.
@@ -11,7 +12,7 @@ export const printPersonalityTraitPrerequisite = (getInstanceById, locale, prere
11
12
  if (personalityTrait === undefined || personalityTraitTranslation === undefined) {
12
13
  return undefined;
13
14
  }
14
- const name = `${personalityTraitTranslation.name} (${locale.translate("Level {$level}", {
15
+ const name = `${attributedNameFromSafeTranslation(personalityTraitTranslation, "prerequisite", "PersonalityTrait", prerequisite.id)} (${locale.translate("Level {$level}", {
15
16
  level: personalityTrait.level,
16
17
  })})`;
17
18
  return {
@@ -1,3 +1,4 @@
1
+ import { attributedInstance } from "../../markdown.js";
1
2
  import { getProfessionName } from "../../professions.js";
2
3
  import { printDisplayOption } from "../displayOption.js";
3
4
  /**
@@ -12,7 +13,9 @@ export const printProfessionPrerequisite = (getChildInstancesForInstanceId, loca
12
13
  return undefined;
13
14
  }
14
15
  return {
15
- value: professionName,
16
+ value: attributedInstance(professionName, "Profession", prerequisite.id, {
17
+ context: '"prerequisite"',
18
+ }),
16
19
  sentenceType: undefined,
17
20
  isMeta: false,
18
21
  };
@@ -1,3 +1,4 @@
1
+ import { attributedNameFromSafeTranslation } from "../../markdown.js";
1
2
  import { printDisplayOption } from "../displayOption.js";
2
3
  /**
3
4
  * Get the translation of a race prerequisite.
@@ -13,7 +14,7 @@ export const printRacePrerequisite = (getInstanceById, locale, prerequisite) =>
13
14
  }
14
15
  return {
15
16
  label: `${locale.translate("Race")} `,
16
- value: raceTranslation.name,
17
+ value: attributedNameFromSafeTranslation(raceTranslation, "prerequisite", "Race", prerequisite.id),
17
18
  sentenceType: undefined,
18
19
  isMeta: false,
19
20
  };
@@ -1,31 +1,6 @@
1
- import { assertExhaustive } from "@optolith/helpers/typeSafety";
1
+ import { attributedCustomName } from "../../markdown.js";
2
2
  import { MISSING_VALUE } from "../../unknown.js";
3
3
  import { printDisplayOption } from "../displayOption.js";
4
- const printRatedName = (getInstanceById, translateMap, id) => {
5
- switch (id.kind) {
6
- case "Attribute":
7
- return (translateMap(getInstanceById("Attribute", id.Attribute)?.translations)?.abbreviation ??
8
- MISSING_VALUE);
9
- case "Skill":
10
- return translateMap(getInstanceById("Skill", id.Skill)?.translations)?.name ?? MISSING_VALUE;
11
- case "CloseCombatTechnique":
12
- return (translateMap(getInstanceById("CloseCombatTechnique", id.CloseCombatTechnique)?.translations)
13
- ?.name ?? MISSING_VALUE);
14
- case "RangedCombatTechnique":
15
- return (translateMap(getInstanceById("RangedCombatTechnique", id.RangedCombatTechnique)?.translations)?.name ?? MISSING_VALUE);
16
- case "Spell":
17
- return translateMap(getInstanceById("Spell", id.Spell)?.translations)?.name ?? MISSING_VALUE;
18
- case "Ritual":
19
- return translateMap(getInstanceById("Ritual", id.Ritual)?.translations)?.name ?? MISSING_VALUE;
20
- case "LiturgicalChant":
21
- return (translateMap(getInstanceById("LiturgicalChant", id.LiturgicalChant)?.translations)?.name ??
22
- MISSING_VALUE);
23
- case "Ceremony":
24
- return (translateMap(getInstanceById("Ceremony", id.Ceremony)?.translations)?.name ?? MISSING_VALUE);
25
- default:
26
- return assertExhaustive(id);
27
- }
28
- };
29
4
  /**
30
5
  * Get the translation of a blessed tradition prerequisite.
31
6
  */
@@ -34,7 +9,7 @@ export const printRatedPrerequisite = (getInstanceById, locale, prerequisite) =>
34
9
  return printDisplayOption(locale.translateMap, prerequisite.display_option);
35
10
  }
36
11
  return {
37
- value: `${printRatedName(getInstanceById, locale.translateMap, prerequisite.id)} ${prerequisite.value.toFixed()}`,
12
+ value: `${attributedCustomName(locale.translateMap, getInstanceById, "prerequisite", (t) => t.abbreviation ?? t.name, prerequisite.id) ?? MISSING_VALUE} ${prerequisite.value.toFixed()}`,
38
13
  sentenceType: undefined,
39
14
  isMeta: false,
40
15
  };
@@ -1,5 +1,6 @@
1
1
  import { isNotNullish } from "@optolith/helpers/nullable";
2
2
  import { assertExhaustive } from "@optolith/helpers/typeSafety";
3
+ import { attributedName } from "../../markdown.js";
3
4
  import { MISSING_VALUE } from "../../unknown.js";
4
5
  import { printDisplayOption } from "../displayOption.js";
5
6
  const printNumberOfTheFollowingSkills = (locale, number) => locale.translate(".input {$count :number} {{{$count} of the following skills}}", {
@@ -36,7 +37,7 @@ export const printRatedMinimumNumberPrerequisite = (getInstanceById, locale, pre
36
37
  switch (prerequisite.targets.kind) {
37
38
  case "Skills": {
38
39
  const skills = prerequisite.targets.Skills.targets
39
- .map(id => locale.translateMap(getInstanceById("Skill", id)?.translations)?.name)
40
+ .map(id => attributedName(locale.translateMap, getInstanceById, "prerequisite", "Skill", id))
40
41
  .filter(isNotNullish);
41
42
  return {
42
43
  value: locale.translate(".input {$minRating :number} {{{$count} on at least SR {$minRating}: {$list}}}", // zwei der folgenden Talente mindestens FW 10:
@@ -1,4 +1,5 @@
1
1
  import { isNotNullish } from "@optolith/helpers/nullable";
2
+ import { attributedName } from "../../markdown.js";
2
3
  import { printDisplayOption } from "../displayOption.js";
3
4
  /**
4
5
  * Get the translation of a rated sum prerequisite.
@@ -8,7 +9,7 @@ export const printRatedSumPrerequisite = (getInstanceById, locale, prerequisite)
8
9
  return printDisplayOption(locale.translateMap, prerequisite.display_option);
9
10
  }
10
11
  const skills = prerequisite.targets
11
- .map(skillId => locale.translateMap(getInstanceById("Skill", skillId)?.translations)?.name)
12
+ .map(skillId => attributedName(locale.translateMap, getInstanceById, "prerequisite", "Skill", skillId))
12
13
  .filter(isNotNullish);
13
14
  return {
14
15
  value: locale.translate("the SR for {$skill} combined must add up to at least {$minRating}", {
@@ -1,3 +1,4 @@
1
+ import { attributedNameFromSafeTranslation } from "../../markdown.js";
1
2
  import { printDisplayOption } from "../displayOption.js";
2
3
  /**
3
4
  * Get the translation of a state prerequisite.
@@ -13,7 +14,7 @@ export const printStatePrerequisite = (getInstanceById, locale, prerequisite) =>
13
14
  }
14
15
  return {
15
16
  label: `${locale.translate("State")} `,
16
- value: `*${stateTranslation.name}*`,
17
+ value: attributedNameFromSafeTranslation(stateTranslation, "prerequisite", "State", prerequisite.id),
17
18
  sentenceType: undefined,
18
19
  isMeta: false,
19
20
  };
@@ -1,6 +1,6 @@
1
1
  import { mapNullableDefault } from "@optolith/helpers/nullable";
2
2
  import { assertExhaustive } from "@optolith/helpers/typeSafety";
3
- import { divisionFormatter, multiplicationFormatter, } from "../../mathOperation.js";
3
+ import { divisionFormatter, multiplicationFormatter } from "../../mathOperation.js";
4
4
  import { translateR } from "../../reader.js";
5
5
  const renderCheckResultBaseValue = (baseValue) => {
6
6
  switch (baseValue.kind) {
@@ -8,6 +8,8 @@ const renderCheckResultBaseValue = (baseValue) => {
8
8
  return translateR("QL");
9
9
  case "SkillPoints":
10
10
  return translateR("SP");
11
+ case "SkillRating":
12
+ return translateR("SR");
11
13
  default:
12
14
  return assertExhaustive(baseValue);
13
15
  }
@@ -133,6 +133,39 @@ export declare const strictNameR: <E extends { [K in keyof EntityMap]: EntityMap
133
133
  translateMap: TranslateMap;
134
134
  getInstanceById: GetInstanceById<E>;
135
135
  }, string>;
136
+ /**
137
+ * Retrieves the `name` property of the specified entry in an attributed string.
138
+ */
139
+ export declare const attributedNameR: <E extends { [K in keyof EntityMap]: EntityMap[K] extends {
140
+ translations: LocaleMap<{
141
+ name: string;
142
+ }>;
143
+ } ? K : never; }[keyof EntityMap]>(context: string, ...args: IdArgsVariant<EntityMap, E>) => Reader<{
144
+ translateMap: TranslateMap;
145
+ getInstanceById: GetInstanceById<E>;
146
+ }, string | undefined>;
147
+ /**
148
+ * Applies a function to the translation of the specified entry and renders it in an attributed string.
149
+ */
150
+ export declare const attributedCustomNameR: <E extends { [K in keyof EntityMap]: EntityMap[K] extends {
151
+ translations: LocaleMap<{
152
+ name: string;
153
+ }>;
154
+ } ? K : never; }[keyof EntityMap]>(context: string, fn: (translation: EntityMap[E]["translations"][string]) => string, ...args: IdArgsVariant<EntityMap, E>) => Reader<{
155
+ translateMap: TranslateMap;
156
+ getInstanceById: GetInstanceById<E>;
157
+ }, string | undefined>;
158
+ /**
159
+ * Applies a function to the translation of the specified entry.
160
+ */
161
+ export declare const customNameR: <E extends { [K in keyof EntityMap]: EntityMap[K] extends {
162
+ translations: LocaleMap<{
163
+ name: string;
164
+ }>;
165
+ } ? K : never; }[keyof EntityMap]>(fn: (translation: EntityMap[E]["translations"][string]) => string, ...args: IdArgsVariant<EntityMap, E>) => Reader<{
166
+ translateMap: TranslateMap;
167
+ getInstanceById: GetInstanceById<E>;
168
+ }, string | undefined>;
136
169
  /**
137
170
  * Joins a list of strings according to the locale’s rules for the given type.
138
171
  */
@@ -1,6 +1,7 @@
1
1
  import { isNotNullish } from "@elyukai/utils/nullable";
2
2
  import { Reader } from "@elyukai/utils/reader";
3
3
  import { assertExhaustive } from "@elyukai/utils/typeSafety";
4
+ import { attributedCustomName, attributedName, customName } from "./markdown.js";
4
5
  import { Speed } from "./rated/activatable/speed.js";
5
6
  import { responsive, ResponsiveTextSize } from "./responsiveText.js";
6
7
  import { formatEnergy } from "./units/energy.js";
@@ -50,6 +51,18 @@ export const nameR = (...args) => Reader.asks(env => env.translateMap(env.getIns
50
51
  * Returns {@link MISSING_VALUE} if there is no name for the entry in the locale. This can happen if the entry itself does not exist, or it does not have a translation for the current locale.
51
52
  */
52
53
  export const strictNameR = (...args) => nameR(...args).map(name => name ?? MISSING_VALUE);
54
+ /**
55
+ * Retrieves the `name` property of the specified entry in an attributed string.
56
+ */
57
+ export const attributedNameR = (context, ...args) => Reader.asks(env => attributedName(env.translateMap, env.getInstanceById, context, ...args));
58
+ /**
59
+ * Applies a function to the translation of the specified entry and renders it in an attributed string.
60
+ */
61
+ export const attributedCustomNameR = (context, fn, ...args) => Reader.asks(env => attributedCustomName(env.translateMap, env.getInstanceById, context, fn, ...args));
62
+ /**
63
+ * Applies a function to the translation of the specified entry.
64
+ */
65
+ export const customNameR = (fn, ...args) => Reader.asks(env => customName(env.translateMap, env.getInstanceById, fn, ...args));
53
66
  /**
54
67
  * Joins a list of strings according to the locale’s rules for the given type.
55
68
  */
@@ -1,8 +1,10 @@
1
1
  import { on } from "@elyukai/utils/function";
2
+ import { mapNullable } from "@elyukai/utils/nullable";
2
3
  import { compareNullish } from "@elyukai/utils/ordering";
3
4
  import { romanize } from "@elyukai/utils/roman";
4
5
  import { numAsc } from "@optolith/helpers/compare";
5
6
  import { createEntityDescriptionCreator } from "../creator.js";
7
+ import { attributedNameFromInstance } from "./partial/markdown.js";
6
8
  import { printPersonalityTraitPrerequisites } from "./partial/prerequisites/index.js";
7
9
  import { MISSING_VALUE } from "./partial/unknown.js";
8
10
  /**
@@ -31,13 +33,18 @@ export const getPersonalityTraitEntityDescription = createEntityDescriptionCreat
31
33
  ? undefined
32
34
  : {
33
35
  label: translate("Can be combined with"),
34
- value: Map.groupBy(entry.combination_options.map(optionId => getInstanceById("PersonalityTrait", optionId)), option => option?.level ?? null)
36
+ value: Map.groupBy(entry.combination_options.map(optionId => mapNullable(getInstanceById("PersonalityTrait", optionId), pt => ({
37
+ id: optionId,
38
+ content: pt,
39
+ }))), option => option?.content.level ?? null)
35
40
  .entries()
36
41
  .toArray()
37
42
  .toSorted(on(group => group[0], compareNullish(numAsc)))
38
43
  .map(([level, options]) => level === null
39
44
  ? MISSING_VALUE
40
- : `${translate("Level {$level}", { level: romanize(level) })} ${localeJoin(options.map(option => translateMap(option?.translations)?.name ?? MISSING_VALUE), "disjunction")}`)
45
+ : `${translate("Level {$level}", { level: romanize(level) })} ${localeJoin(options.map(option => (option &&
46
+ attributedNameFromInstance(translateMap, option.content, "prerequisite", "PersonalityTrait", option.id)) ??
47
+ MISSING_VALUE), "disjunction")}`)
41
48
  .join(", "),
42
49
  },
43
50
  entry.prerequisites === undefined
@@ -3,7 +3,7 @@ import { isNotNullish, mapNullable } from "@elyukai/utils/nullable";
3
3
  import { sign } from "@elyukai/utils/string/number";
4
4
  import { assertExhaustive } from "@elyukai/utils/typeSafety";
5
5
  import { createEntityDescriptionCreator } from "../creator.js";
6
- import { renderDice, renderDiceAndFlat } from "./partial/dice.js";
6
+ import { renderDice } from "./partial/dice.js";
7
7
  import { renderAlternativeNames, renderChance, renderLaboratoryLevel, renderResistance, } from "./partial/herbary.js";
8
8
  import { renderMathOperation } from "./partial/mathOperation.js";
9
9
  import { printPlainGeneralPrerequisites } from "./partial/prerequisites/index.js";
@@ -93,6 +93,12 @@ const renderSourceTypeBasedValues = (translate, translateMap, getInstanceById, s
93
93
  return {
94
94
  level: renderLevel(translate, translateMap, sourceType.AnimalVenom.level),
95
95
  sourceType: translate("animal venom"),
96
+ tradeSecret: mapNullable(sourceType.AnimalVenom.complexity, complexity => complexity.kind === "Complex"
97
+ ? {
98
+ apValue: complexity.Complex.ap_value,
99
+ prerequisites: complexity.Complex.prerequisites,
100
+ }
101
+ : undefined),
96
102
  };
97
103
  case "AlchemicalPoison": {
98
104
  const translation = translateMap(sourceType.AlchemicalPoison.translations);
@@ -156,10 +162,19 @@ const renderStart = (translate, translateMap, start) => {
156
162
  switch (start.kind) {
157
163
  case "Immediate":
158
164
  return translate("immediate");
159
- case "Constant":
160
- return formatTimeSpan(translate, ResponsiveTextSize.Full, start.Constant.unit, start.Constant.value);
161
- case "DiceBased":
162
- return formatTimeSpan(translate, ResponsiveTextSize.Full, start.DiceBased.unit, renderDiceAndFlat(translate, start.DiceBased.dice, start.DiceBased.flat));
165
+ case "ExpressionBased":
166
+ return renderMathOperation(start.ExpressionBased.value, value => {
167
+ switch (value.kind) {
168
+ case "Constant":
169
+ return value.Constant.toFixed();
170
+ case "Dice":
171
+ return renderDice(translate, value.Dice);
172
+ case "CircleOfDamnation":
173
+ return translate("CoD");
174
+ default:
175
+ return assertExhaustive(value);
176
+ }
177
+ });
163
178
  case "Indefinite":
164
179
  return translateMap(start.Indefinite.translations)?.description ?? MISSING_VALUE;
165
180
  default:
@@ -170,10 +185,6 @@ const renderDuration = (translate, translateMap, duration) => {
170
185
  switch (duration.kind) {
171
186
  case "Instant":
172
187
  return translate("instant");
173
- case "Constant":
174
- return formatTimeSpan(translate, ResponsiveTextSize.Full, duration.Constant.unit, duration.Constant.value);
175
- case "DiceBased":
176
- return formatTimeSpan(translate, ResponsiveTextSize.Full, duration.DiceBased.unit, renderDiceAndFlat(translate, duration.DiceBased.dice, duration.DiceBased.flat));
177
188
  case "ExpressionBased":
178
189
  return renderMathOperation(duration.ExpressionBased.value, value => {
179
190
  switch (value.kind) {
@@ -1,11 +1,11 @@
1
- import type { MagicalActionIdentifier, RatedIdentifier, SpecialAbilityIdentifier } from "optolith-database-schema/gen";
1
+ import type { MagicalActionIdentifier, ProfessionSpecialAbilityIdentifier, RatedIdentifier } from "optolith-database-schema/gen";
2
2
  import type { GetAllChildInstancesForParent, GetAllInstances, GetInstanceById } from "../helpers/getTypes.js";
3
3
  import { type GetResolvedSelectOptionById } from "./partial/prerequisites/single/activatable.js";
4
4
  /**
5
5
  * Get a JSON representation of the rules text for a profession version.
6
6
  */
7
7
  export declare const getProfessionVersionEntityDescription: import("../creator.js").EntityDescriptionCreator<"ProfessionVersion", {
8
- getInstanceById: GetInstanceById<"Publication" | "ExperienceLevel" | "Advantage" | "Disadvantage" | SpecialAbilityIdentifier["kind"] | "Aspect" | RatedIdentifier["kind"] | "Race" | "Culture" | MagicalActionIdentifier["kind"] | "SkillGroup" | "Cantrip" | "Blessing">;
8
+ getInstanceById: GetInstanceById<"Publication" | "ExperienceLevel" | "Advantage" | "Disadvantage" | ProfessionSpecialAbilityIdentifier["kind"] | "Aspect" | RatedIdentifier["kind"] | "Race" | "Culture" | MagicalActionIdentifier["kind"] | "SkillGroup" | "Cantrip" | "Blessing">;
9
9
  getAllInstances: GetAllInstances<"SkillGroup">;
10
10
  getChildInstancesForInstanceId: GetAllChildInstancesForParent<"ProfessionPackage" | "ProfessionVariant">;
11
11
  getResolvedSelectOptionById: GetResolvedSelectOptionById;