optolith-database-schema 0.16.3 → 0.16.5

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 CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.16.5](https://github.com/elyukai/optolith-database-schema/compare/v0.16.4...v0.16.5) (2024-02-29)
6
+
7
+
8
+ ### Features
9
+
10
+ * add missing activatable and rated identifiers ([a34676b](https://github.com/elyukai/optolith-database-schema/commit/a34676b3c3a7d91621d285447eb913d6888e2c8e))
11
+ * convert many used keys to their english fallback and add some new keys ([ae07fd2](https://github.com/elyukai/optolith-database-schema/commit/ae07fd2b6def34c4a5269202a9ac3a3b8e735b37))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * add missing identifier handling to magical and blessed advantages and disadvantages cache ([eba871a](https://github.com/elyukai/optolith-database-schema/commit/eba871a0e7ea803775a30c01e2d2c278bd60856f))
17
+ * applications and uses for select options ([c21b851](https://github.com/elyukai/optolith-database-schema/commit/c21b8512817204129a9213b330abc811b64dad13))
18
+
19
+ ### [0.16.4](https://github.com/elyukai/optolith-database-schema/compare/v0.16.3...v0.16.4) (2024-01-21)
20
+
21
+
22
+ ### Features
23
+
24
+ * magical and blessed advantages and disadvantages identifier cache ([4dc6e3d](https://github.com/elyukai/optolith-database-schema/commit/4dc6e3dec721019af728db6b68138498da4b1775))
25
+
5
26
  ### [0.16.3](https://github.com/elyukai/optolith-database-schema/compare/v0.16.2...v0.16.3) (2024-01-18)
6
27
 
7
28
 
@@ -104,6 +104,11 @@ const getApValueForSkillish = (config, id, ic) => {
104
104
  return assertExhaustive(config);
105
105
  }
106
106
  };
107
+ const convertSkillApplicationOrUse = (id, applicationOrUse) => ({
108
+ id: applicationOrUse.id,
109
+ skill: { tag: "Single", single: { id } },
110
+ translations: applicationOrUse.translations,
111
+ });
107
112
  const getDerivedSelectOptions = (selectOptionCategory, entryId, database) => {
108
113
  switch (selectOptionCategory.tag) {
109
114
  case "Blessings":
@@ -529,16 +534,8 @@ const getDerivedSelectOptions = (selectOptionCategory, entryId, database) => {
529
534
  const id = { tag: "Skill", skill: skill.id };
530
535
  return {
531
536
  id,
532
- skill_uses: category.skills.skill_uses?.map(use => ({
533
- id: use.id,
534
- skill: { tag: "Single", single: { id } },
535
- translations: use.translations,
536
- })),
537
- skill_applications: category.skills.skill_applications?.map(use => ({
538
- id: use.id,
539
- skill: { tag: "Single", single: { id } },
540
- translations: use.translations,
541
- })),
537
+ skill_uses: category.skills.skill_uses?.map(use => convertSkillApplicationOrUse(id, use)),
538
+ skill_applications: category.skills.skill_applications?.map(use => convertSkillApplicationOrUse(id, use)),
542
539
  prerequisites: getSkillishPrerequisites(category.skills.prerequisites, id),
543
540
  ap_value: getApValueForSkillish(category.skills.ap_value ?? apValueGen, id, skill.improvement_cost),
544
541
  src: skill.src,
@@ -691,22 +688,36 @@ const getDerivedSelectOptions = (selectOptionCategory, entryId, database) => {
691
688
  return assertExhaustive(selectOptionCategory);
692
689
  }
693
690
  };
691
+ const joinLocaleMaps = (a, b, join) => {
692
+ const combinedLocaleMap = {};
693
+ for (const key of new Set([...Object.keys(a), ...Object.keys(b)])) {
694
+ const newValue = join(a[key], b[key]);
695
+ if (newValue != null) {
696
+ combinedLocaleMap[key] = newValue;
697
+ }
698
+ }
699
+ return combinedLocaleMap;
700
+ };
694
701
  const getExplicitSelectOptions = (explicitSelectOptions, database) => explicitSelectOptions
695
702
  .map((explicitSelectOption) => {
696
703
  switch (explicitSelectOption.tag) {
697
704
  case "General":
698
705
  return {
706
+ ...explicitSelectOption.general,
699
707
  id: { tag: "General", general: explicitSelectOption.general.id },
700
- translations: explicitSelectOption.general.translations,
701
708
  };
702
709
  case "Skill": {
703
710
  const skill = database.skills.find(p => p[0] === explicitSelectOption.skill.id.skill)?.[1];
704
711
  if (skill === undefined) {
705
712
  return undefined;
706
713
  }
714
+ const id = { tag: "Skill", skill: explicitSelectOption.skill.id.skill };
707
715
  return {
708
- id: { tag: "Skill", skill: explicitSelectOption.skill.id.skill },
709
- translations: mapObject(skill.translations, t10n => ({ name: t10n.name })),
716
+ ...explicitSelectOption.skill,
717
+ id,
718
+ skill_applications: explicitSelectOption.skill.skill_applications?.map(use => convertSkillApplicationOrUse(id, use)),
719
+ skill_uses: explicitSelectOption.skill.skill_uses?.map(use => convertSkillApplicationOrUse(id, use)),
720
+ translations: joinLocaleMaps(explicitSelectOption.skill.translations ?? {}, skill.translations, (explicit, base) => base === undefined ? undefined : { ...explicit, name: base.name }),
710
721
  };
711
722
  }
712
723
  case "CombatTechnique":
@@ -718,10 +729,9 @@ const getExplicitSelectOptions = (explicitSelectOptions, database) => explicitSe
718
729
  return undefined;
719
730
  }
720
731
  return {
732
+ ...explicitSelectOption.combat_technique,
721
733
  id: { tag: "CloseCombatTechnique", close_combat_technique: id },
722
- translations: mapObject(closeCombatTechnique.translations, t10n => ({
723
- name: t10n.name,
724
- })),
734
+ translations: joinLocaleMaps(explicitSelectOption.combat_technique.translations ?? {}, closeCombatTechnique.translations, (explicit, base) => base === undefined ? undefined : { ...explicit, name: base.name }),
725
735
  };
726
736
  }
727
737
  case "RangedCombatTechnique": {
@@ -731,10 +741,9 @@ const getExplicitSelectOptions = (explicitSelectOptions, database) => explicitSe
731
741
  return undefined;
732
742
  }
733
743
  return {
744
+ ...explicitSelectOption.combat_technique,
734
745
  id: { tag: "RangedCombatTechnique", ranged_combat_technique: id },
735
- translations: mapObject(rangedCombatTechnique.translations, t10n => ({
736
- name: t10n.name,
737
- })),
746
+ translations: joinLocaleMaps(explicitSelectOption.combat_technique.translations ?? {}, rangedCombatTechnique.translations, (explicit, base) => base === undefined ? undefined : { ...explicit, name: base.name }),
738
747
  };
739
748
  }
740
749
  default:
@@ -857,6 +866,8 @@ const getSelectOptionsForResults = (database, idTag, results) => results.reduce(
857
866
  return { tag: "Krallenkettenzauber", krallenkettenzauber: id };
858
867
  case "Trinkhornzauber":
859
868
  return { tag: "Trinkhornzauber", trinkhornzauber: id };
869
+ case "MagicalSign":
870
+ return { tag: "MagicalSign", magical_sign: id };
860
871
  default:
861
872
  return assertExhaustive(idTag);
862
873
  }
@@ -0,0 +1,20 @@
1
+ import type { CacheConfig } from "../cacheConfig.js";
2
+ export type MagicalAndBlessedAdvantagesAndDisadvantagesCache = {
3
+ advantages: {
4
+ magical: {
5
+ ids: number[];
6
+ };
7
+ blessed: {
8
+ ids: number[];
9
+ };
10
+ };
11
+ disadvantages: {
12
+ magical: {
13
+ ids: number[];
14
+ };
15
+ blessed: {
16
+ ids: number[];
17
+ };
18
+ };
19
+ };
20
+ export declare const config: CacheConfig<MagicalAndBlessedAdvantagesAndDisadvantagesCache>;
@@ -0,0 +1,164 @@
1
+ import { assertExhaustive } from "../helpers/typeSafety.js";
2
+ const BLESSED_ID = 12;
3
+ const SPELLCASTER_ID = 47;
4
+ const getAdvantageId = (type) => {
5
+ switch (type) {
6
+ case "Magical":
7
+ return SPELLCASTER_ID;
8
+ case "Blessed":
9
+ return BLESSED_ID;
10
+ default:
11
+ return assertExhaustive(type);
12
+ }
13
+ };
14
+ const isRatedFor = (type, ratedId) => {
15
+ switch (ratedId.tag) {
16
+ case "Spell":
17
+ case "Ritual":
18
+ return type === "Magical";
19
+ case "LiturgicalChant":
20
+ case "Ceremony":
21
+ return type === "Blessed";
22
+ case "Attribute":
23
+ case "Skill":
24
+ case "CloseCombatTechnique":
25
+ case "RangedCombatTechnique":
26
+ return false;
27
+ default:
28
+ return assertExhaustive(ratedId);
29
+ }
30
+ };
31
+ const isPrerequisiteFor = (type, prerequisite, getById, traversedIds) => {
32
+ switch (prerequisite.tag) {
33
+ case "Activatable": {
34
+ if (prerequisite.activatable.id.tag === "Advantage" &&
35
+ prerequisite.activatable.id.advantage === getAdvantageId(type) &&
36
+ prerequisite.activatable.active) {
37
+ return true;
38
+ }
39
+ const entry = getById(prerequisite.activatable.id);
40
+ return entry !== undefined && is(type, entry, getById, traversedIds);
41
+ }
42
+ case "Rated":
43
+ return isRatedFor(type, prerequisite.rated.id);
44
+ case "CommonSuggestedByRCP":
45
+ case "Sex":
46
+ case "Race":
47
+ case "Culture":
48
+ case "Pact":
49
+ case "SocialStatus":
50
+ case "State":
51
+ case "Rule":
52
+ case "PrimaryAttribute":
53
+ case "BlessedTradition":
54
+ case "MagicalTradition":
55
+ case "RatedMinimumNumber":
56
+ case "RatedSum":
57
+ case "ExternalEnhancement":
58
+ case "Text":
59
+ case "NoOtherAncestorBloodAdvantage":
60
+ case "SexualCharacteristic":
61
+ return false;
62
+ default:
63
+ return assertExhaustive(prerequisite);
64
+ }
65
+ };
66
+ const is = (type, entry, getById, traversedIds) => {
67
+ if (!entry.prerequisites || traversedIds.includes(entry.id)) {
68
+ return false;
69
+ }
70
+ const newTraversedIds = [...traversedIds, entry.id];
71
+ return (entry.prerequisites !== undefined &&
72
+ entry.prerequisites.some(prerequisite => {
73
+ switch (prerequisite.prerequisite.tag) {
74
+ case "Single":
75
+ return isPrerequisiteFor(type, prerequisite.prerequisite.single, getById, newTraversedIds);
76
+ case "Disjunction":
77
+ return prerequisite.prerequisite.disjunction.list.some(p => isPrerequisiteFor(type, p, getById, newTraversedIds));
78
+ case "Group":
79
+ return prerequisite.prerequisite.group.list.some(p => isPrerequisiteFor(type, p, getById, newTraversedIds));
80
+ default:
81
+ return assertExhaustive(prerequisite.prerequisite);
82
+ }
83
+ }));
84
+ };
85
+ export const config = {
86
+ builder(database) {
87
+ const getActivatableById = (id) => {
88
+ // prettier-ignore
89
+ switch (id.tag) {
90
+ case "AdvancedCombatSpecialAbility": return database.advancedCombatSpecialAbilities.find(([entryId]) => entryId === id.advanced_combat_special_ability)?.[1];
91
+ case "AdvancedKarmaSpecialAbility": return database.advancedKarmaSpecialAbilities.find(([entryId]) => entryId === id.advanced_karma_special_ability)?.[1];
92
+ case "AdvancedMagicalSpecialAbility": return database.advancedMagicalSpecialAbilities.find(([entryId]) => entryId === id.advanced_magical_special_ability)?.[1];
93
+ case "AdvancedSkillSpecialAbility": return database.advancedSkillSpecialAbilities.find(([entryId]) => entryId === id.advanced_skill_special_ability)?.[1];
94
+ case "Advantage": return database.advantages.find(([entryId]) => entryId === id.advantage)?.[1];
95
+ case "AncestorGlyph": return database.ancestorGlyphs.find(([entryId]) => entryId === id.ancestor_glyph)?.[1];
96
+ case "ArcaneOrbEnchantment": return database.arcaneOrbEnchantments.find(([entryId]) => entryId === id.arcane_orb_enchantment)?.[1];
97
+ case "AttireEnchantment": return database.attireEnchantments.find(([entryId]) => entryId === id.attire_enchantment)?.[1];
98
+ case "BlessedTradition": return database.blessedTraditions.find(([entryId]) => entryId === id.blessed_tradition)?.[1];
99
+ case "BowlEnchantment": return database.bowlEnchantments.find(([entryId]) => entryId === id.bowl_enchantment)?.[1];
100
+ case "BrawlingSpecialAbility": return database.brawlingSpecialAbilities.find(([entryId]) => entryId === id.brawling_special_ability)?.[1];
101
+ case "CauldronEnchantment": return database.cauldronEnchantments.find(([entryId]) => entryId === id.cauldron_enchantment)?.[1];
102
+ case "CeremonialItemSpecialAbility": return database.ceremonialItemSpecialAbilities.find(([entryId]) => entryId === id.ceremonial_item_special_ability)?.[1];
103
+ case "ChronicleEnchantment": return database.chronicleEnchantments.find(([entryId]) => entryId === id.chronicle_enchantment)?.[1];
104
+ case "CombatSpecialAbility": return database.combatSpecialAbilities.find(([entryId]) => entryId === id.combat_special_ability)?.[1];
105
+ case "CombatStyleSpecialAbility": return database.combatStyleSpecialAbilities.find(([entryId]) => entryId === id.combat_style_special_ability)?.[1];
106
+ case "CommandSpecialAbility": return database.commandSpecialAbilities.find(([entryId]) => entryId === id.command_special_ability)?.[1];
107
+ case "DaggerRitual": return database.daggerRituals.find(([entryId]) => entryId === id.dagger_ritual)?.[1];
108
+ case "Disadvantage": return database.disadvantages.find(([entryId]) => entryId === id.disadvantage)?.[1];
109
+ case "FamiliarSpecialAbility": return database.familiarSpecialAbilities.find(([entryId]) => entryId === id.familiar_special_ability)?.[1];
110
+ case "FatePointSexSpecialAbility": return database.fatePointSexSpecialAbilities.find(([entryId]) => entryId === id.fate_point_sex_special_ability)?.[1];
111
+ case "FatePointSpecialAbility": return database.fatePointSpecialAbilities.find(([entryId]) => entryId === id.fate_point_special_ability)?.[1];
112
+ case "FoolsHatEnchantment": return database.foolsHatEnchantments.find(([entryId]) => entryId === id.fools_hat_enchantment)?.[1];
113
+ case "GeneralSpecialAbility": return database.generalSpecialAbilities.find(([entryId]) => entryId === id.general_special_ability)?.[1];
114
+ case "InstrumentEnchantment": return database.instrumentEnchantments.find(([entryId]) => entryId === id.instrument_enchantment)?.[1];
115
+ case "KarmaSpecialAbility": return database.karmaSpecialAbilities.find(([entryId]) => entryId === id.karma_special_ability)?.[1];
116
+ case "Krallenkettenzauber": return database.krallenkettenzauber.find(([entryId]) => entryId === id.krallenkettenzauber)?.[1];
117
+ case "LiturgicalStyleSpecialAbility": return database.liturgicalStyleSpecialAbilities.find(([entryId]) => entryId === id.liturgical_style_special_ability)?.[1];
118
+ case "LycantropicGift": return database.lycantropicGifts.find(([entryId]) => entryId === id.lycantropic_gift)?.[1];
119
+ case "MagicalSign": return database.magicalSigns.find(([entryId]) => entryId === id.magical_sign)?.[1];
120
+ case "MagicalSpecialAbility": return database.magicalSpecialAbilities.find(([entryId]) => entryId === id.magical_special_ability)?.[1];
121
+ case "MagicalTradition": return database.magicalTraditions.find(([entryId]) => entryId === id.magical_tradition)?.[1];
122
+ case "MagicStyleSpecialAbility": return database.magicStyleSpecialAbilities.find(([entryId]) => entryId === id.magic_style_special_ability)?.[1];
123
+ case "OrbEnchantment": return database.orbEnchantments.find(([entryId]) => entryId === id.orb_enchantment)?.[1];
124
+ case "PactGift": return database.pactGifts.find(([entryId]) => entryId === id.pact_gift)?.[1];
125
+ case "ProtectiveWardingCircleSpecialAbility": return database.protectiveWardingCircleSpecialAbilities.find(([entryId]) => entryId === id.protective_warding_circle_special_ability)?.[1];
126
+ case "RingEnchantment": return database.ringEnchantments.find(([entryId]) => entryId === id.ring_enchantment)?.[1];
127
+ case "Sermon": return database.sermons.find(([entryId]) => entryId === id.sermon)?.[1];
128
+ case "SexSpecialAbility": return database.sexSpecialAbilities.find(([entryId]) => entryId === id.sex_special_ability)?.[1];
129
+ case "SickleRitual": return database.sickleRituals.find(([entryId]) => entryId === id.sickle_ritual)?.[1];
130
+ case "SikaryanDrainSpecialAbility": return database.sikaryanDrainSpecialAbilities.find(([entryId]) => entryId === id.sikaryan_drain_special_ability)?.[1];
131
+ case "SkillStyleSpecialAbility": return database.skillStyleSpecialAbilities.find(([entryId]) => entryId === id.skill_style_special_ability)?.[1];
132
+ case "SpellSwordEnchantment": return database.spellSwordEnchantments.find(([entryId]) => entryId === id.spell_sword_enchantment)?.[1];
133
+ case "StaffEnchantment": return database.staffEnchantments.find(([entryId]) => entryId === id.staff_enchantment)?.[1];
134
+ case "ToyEnchantment": return database.toyEnchantments.find(([entryId]) => entryId === id.toy_enchantment)?.[1];
135
+ case "Trinkhornzauber": return database.trinkhornzauber.find(([entryId]) => entryId === id.trinkhornzauber)?.[1];
136
+ case "VampiricGift": return database.vampiricGifts.find(([entryId]) => entryId === id.vampiric_gift)?.[1];
137
+ case "Vision": return database.visions.find(([entryId]) => entryId === id.vision)?.[1];
138
+ case "WandEnchantment": return database.wandEnchantments.find(([entryId]) => entryId === id.wand_enchantment)?.[1];
139
+ case "WeaponEnchantment": return database.weaponEnchantments.find(([entryId]) => entryId === id.weapon_enchantment)?.[1];
140
+ default:
141
+ return assertExhaustive(id);
142
+ }
143
+ };
144
+ // prettier-ignore
145
+ return {
146
+ advantages: {
147
+ magical: {
148
+ ids: database.advantages.filter(([_, entry]) => is("Magical", entry, getActivatableById, [])).map(([id]) => id),
149
+ },
150
+ blessed: {
151
+ ids: database.advantages.filter(([_, entry]) => is("Blessed", entry, getActivatableById, [])).map(([id]) => id),
152
+ },
153
+ },
154
+ disadvantages: {
155
+ magical: {
156
+ ids: database.disadvantages.filter(([_, entry]) => is("Magical", entry, getActivatableById, [])).map(([id]) => id),
157
+ },
158
+ blessed: {
159
+ ids: database.disadvantages.filter(([_, entry]) => is("Blessed", entry, getActivatableById, [])).map(([id]) => id),
160
+ },
161
+ },
162
+ };
163
+ },
164
+ };
@@ -1,13 +1,16 @@
1
1
  import * as ActivatableSelectOptions from "../cache/activatableSelectOptions.js";
2
2
  import * as AncestorBloodAdvantages from "../cache/ancestorBloodAdvantages.js";
3
+ import * as MagicalAndBlessedAdvantagesAndDisadvantages from "../cache/magicalAndBlessedAdvantagesAndDisadvantages.js";
3
4
  import * as NewApplicationsAndUses from "../cache/newApplicationsAndUses.js";
4
5
  export type CacheMap = {
5
6
  activatableSelectOptions: ActivatableSelectOptions.ActivatableSelectOptionsCache;
6
7
  ancestorBloodAdvantages: AncestorBloodAdvantages.AncestorBloodAdvantagesCache;
8
+ magicalAndBlessedAdvantagesAndDisadvantages: MagicalAndBlessedAdvantagesAndDisadvantages.MagicalAndBlessedAdvantagesAndDisadvantagesCache;
7
9
  newApplicationsAndUses: NewApplicationsAndUses.NewApplicationsAndUsesCache;
8
10
  };
9
11
  export declare const cacheMap: {
10
12
  activatableSelectOptions: import("../cacheConfig.js").CacheConfig<ActivatableSelectOptions.ActivatableSelectOptionsCache>;
11
13
  ancestorBloodAdvantages: import("../cacheConfig.js").CacheConfig<AncestorBloodAdvantages.AncestorBloodAdvantagesCache>;
14
+ magicalAndBlessedAdvantagesAndDisadvantages: import("../cacheConfig.js").CacheConfig<MagicalAndBlessedAdvantagesAndDisadvantages.MagicalAndBlessedAdvantagesAndDisadvantagesCache>;
12
15
  newApplicationsAndUses: import("../cacheConfig.js").CacheConfig<NewApplicationsAndUses.NewApplicationsAndUsesCache, [generatedSelectOptions: ActivatableSelectOptions.ActivatableSelectOptionsCache]>;
13
16
  };
@@ -1,8 +1,10 @@
1
1
  import * as ActivatableSelectOptions from "../cache/activatableSelectOptions.js";
2
2
  import * as AncestorBloodAdvantages from "../cache/ancestorBloodAdvantages.js";
3
+ import * as MagicalAndBlessedAdvantagesAndDisadvantages from "../cache/magicalAndBlessedAdvantagesAndDisadvantages.js";
3
4
  import * as NewApplicationsAndUses from "../cache/newApplicationsAndUses.js";
4
5
  export const cacheMap = {
5
6
  activatableSelectOptions: ActivatableSelectOptions.config,
6
7
  ancestorBloodAdvantages: AncestorBloodAdvantages.config,
8
+ magicalAndBlessedAdvantagesAndDisadvantages: MagicalAndBlessedAdvantagesAndDisadvantages.config,
7
9
  newApplicationsAndUses: NewApplicationsAndUses.config,
8
10
  };
package/lib/main.js CHANGED
@@ -78,10 +78,12 @@ export const buildCache = async (cachePaths, validResults, options = {}) => {
78
78
  const { pretty = false } = options;
79
79
  const activatableSelectOptionsCache = cacheMap.activatableSelectOptions.builder(validResults);
80
80
  const ancestorBloodAdvantagesCache = cacheMap.ancestorBloodAdvantages.builder(validResults);
81
+ const magicalAndBlessedAdvantagesAndDisadvantagesCache = cacheMap.magicalAndBlessedAdvantagesAndDisadvantages.builder(validResults);
81
82
  const newApplicationsAndUsesCache = cacheMap.newApplicationsAndUses.builder(validResults, activatableSelectOptionsCache);
82
83
  const cacheData = {
83
84
  activatableSelectOptions: activatableSelectOptionsCache,
84
85
  ancestorBloodAdvantages: ancestorBloodAdvantagesCache,
86
+ magicalAndBlessedAdvantagesAndDisadvantages: magicalAndBlessedAdvantagesAndDisadvantagesCache,
85
87
  newApplicationsAndUses: newApplicationsAndUsesCache,
86
88
  };
87
89
  for (const [cacheName, cachePath] of Object.entries(cachePaths)) {
package/lib/types/UI.d.ts CHANGED
@@ -60,7 +60,6 @@ export type UI = {
60
60
  "Install Later": NonEmptyString;
61
61
  "No update available": NonEmptyString;
62
62
  "You're running the latest version available.": NonEmptyString;
63
- "initialization.loadtableserror": NonEmptyString;
64
63
  "Characters": NonEmptyString;
65
64
  "Groups": NonEmptyString;
66
65
  "Library": NonEmptyString;
@@ -211,6 +210,9 @@ export type UI = {
211
210
  * - `0`: Length in cm
212
211
  */
213
212
  "general.lengthvalue": NonEmptyString;
213
+ /**
214
+ * As in *2D6*.
215
+ */
214
216
  "D": NonEmptyString;
215
217
  "general.none": NonEmptyString;
216
218
  "general.or": NonEmptyString;
@@ -220,11 +222,6 @@ export type UI = {
220
222
  "general.emptylistplaceholder": NonEmptyString;
221
223
  "general.emptylistnoresultsplaceholder": NonEmptyString;
222
224
  "No Results": NonEmptyString;
223
- /**
224
- * - `0`: Name of element
225
- * - `1`: AP value
226
- */
227
- "general.withapvalue": NonEmptyString;
228
225
  "Search": NonEmptyString;
229
226
  "Sort By": NonEmptyString;
230
227
  "Name": NonEmptyString;
@@ -235,38 +232,26 @@ export type UI = {
235
232
  "general.filters.sort.bycost": NonEmptyString;
236
233
  "general.filters.sort.byweight": NonEmptyString;
237
234
  "general.filters.showactivatedentries": NonEmptyString;
238
- "general.dialogs.savebtn": NonEmptyString;
239
235
  "Done": NonEmptyString;
240
- "general.dialogs.deletebtn": NonEmptyString;
241
- "general.dialogs.yesbtn": NonEmptyString;
242
- "general.dialogs.nobtn": NonEmptyString;
243
- "general.dialogs.okbtn": NonEmptyString;
236
+ "OK": NonEmptyString;
244
237
  "Cancel": NonEmptyString;
245
- "general.dialogs.copybtn": NonEmptyString;
246
- "general.dialogs.createbtn": NonEmptyString;
247
- "general.dialogs.applybtn": NonEmptyString;
238
+ "Create": NonEmptyString;
239
+ "Apply": NonEmptyString;
248
240
  "Add": NonEmptyString;
249
- "general.dialogs.notenoughap.title": NonEmptyString;
250
- /**
251
- * - `0`: Missing AP
252
- */
253
- "general.dialogs.notenoughap.message": NonEmptyString;
254
- /**
255
- * - `0`: Category in which the limit is reached
256
- */
257
- "general.dialogs.reachedaplimit.title": NonEmptyString;
258
- /**
259
- * - `0`: Missing AP
260
- * - `1`: Maximum possible AP spent on category
261
- * - `2`: Category in which the limit is reached
262
- */
263
- "general.dialogs.reachedaplimit.message": NonEmptyString;
264
- "general.dialogs.reachedaplimit.advantages": NonEmptyString;
265
- "general.dialogs.reachedaplimit.magicaladvantages": NonEmptyString;
266
- "general.dialogs.reachedaplimit.blessedadvantages": NonEmptyString;
267
- "general.dialogs.reachedaplimit.disadvantages": NonEmptyString;
268
- "general.dialogs.reachedaplimit.magicaldisadvantages": NonEmptyString;
269
- "general.dialogs.reachedaplimit.blesseddisadvantages": NonEmptyString;
241
+ "Not enough AP": NonEmptyString;
242
+ "You are missing {0} Adventure Points to do this.": PluralizationCategories;
243
+ "Exceeding Adventure Points limit for advantages": NonEmptyString;
244
+ "You cannot spend more than {0} AP on advantages. You would exceed this limit by {1} AP.": NonEmptyString;
245
+ "Exceeding Adventure Points limit for magical advantages": NonEmptyString;
246
+ "You cannot spend more than {0} AP on magical advantages. You would exceed this limit by {1} AP.": NonEmptyString;
247
+ "Exceeding Adventure Points limit for blessed advantages": NonEmptyString;
248
+ "You cannot spend more than {0} AP on blessed advantages. You would exceed this limit by {1} AP.": NonEmptyString;
249
+ "Exceeding Adventure Points limit for disadvantages": NonEmptyString;
250
+ "You cannot receive more than {0} AP from disadvantages. You would exceed this limit by {1} AP.": NonEmptyString;
251
+ "Exceeding Adventure Points limit for magical disadvantages": NonEmptyString;
252
+ "You cannot receive more than {0} AP from magical disadvantages. You would exceed this limit by {1} AP.": NonEmptyString;
253
+ "Exceeding Adventure Points limit for blessed disadvantages": NonEmptyString;
254
+ "You cannot receive more than {0} AP from blessed disadvantages. You would exceed this limit by {1} AP.": NonEmptyString;
270
255
  "heroes.filters.origin.allheroes": NonEmptyString;
271
256
  "heroes.filters.origin.ownheroes": NonEmptyString;
272
257
  "heroes.filters.origin.sharedheroes": NonEmptyString;
@@ -320,7 +305,6 @@ export type UI = {
320
305
  "wiki.filters.specialabilities.all": NonEmptyString;
321
306
  "wiki.filters.itemtemplates": NonEmptyString;
322
307
  "wiki.filters.itemtemplates.all": NonEmptyString;
323
- "imprint.title": NonEmptyString;
324
308
  "Edit Name": NonEmptyString;
325
309
  "Change Name": NonEmptyString;
326
310
  "Edit Profession Name": NonEmptyString;
@@ -356,6 +340,7 @@ export type UI = {
356
340
  "Reroll Size": NonEmptyString;
357
341
  "Reroll Weight": NonEmptyString;
358
342
  "personaldata.cultureareaknowledge": NonEmptyString;
343
+ "You can save up no more than 10 AP to use later during the game, and you cannot begin the game with a negative AP balance.": NonEmptyString;
359
344
  "sheets.printtopdfbtn": NonEmptyString;
360
345
  "sheets.dialogs.pdfexportsavelocation.title": NonEmptyString;
361
346
  "sheets.dialogs.pdfsaved": NonEmptyString;
@@ -769,55 +754,14 @@ export type UI = {
769
754
  "How many points do you want to remove?": NonEmptyString;
770
755
  "Remove": NonEmptyString;
771
756
  "Permanently Spent": NonEmptyString;
772
- "advantages.filters.commonadvantages": NonEmptyString;
773
- "disadvantages.filters.commondisadvantages": NonEmptyString;
774
- "advantagesdisadvantages.addbtn": NonEmptyString;
775
- "advantagesdisadvantages.afraidof": NonEmptyString;
776
- "advantagesdisadvantages.immunityto": NonEmptyString;
777
- "advantagesdisadvantages.hatredfor": NonEmptyString;
778
- "advantagesdisadvantages.header.name": NonEmptyString;
779
- "advantagesdisadvantages.header.adventurepoints": NonEmptyString;
780
- "advantagesdisadvantages.header.adventurepoints.tooltip": NonEmptyString;
781
- /**
782
- * - `0`: Current AP spent on advantages
783
- * - `1`: Maximum possible AP spent on advantages
784
- */
785
- "advantagesdisadvantages.apspent.spentonadvantages": NonEmptyString;
786
- /**
787
- * - `0`: Current AP spent on magic advantages
788
- * - `1`: Maximum possible AP spent on magic advantages
789
- */
790
- "advantagesdisadvantages.apspent.spentonmagicadvantages": NonEmptyString;
791
- /**
792
- * - `0`: Current AP spent on blessed advantages
793
- * - `1`: Maximum possible AP spent on blessed advantages
794
- */
795
- "advantagesdisadvantages.apspent.spentonblessedadvantages": NonEmptyString;
796
- /**
797
- * - `0`: Current AP spent on disadvantages
798
- * - `1`: Maximum possible AP spent on disadvantages
799
- */
800
- "advantagesdisadvantages.apspent.spentondisadvantages": NonEmptyString;
801
- /**
802
- * - `0`: Current AP spent on magic disadvantages
803
- * - `1`: Maximum possible AP spent on magic disadvantages
804
- */
805
- "advantagesdisadvantages.apspent.spentonmagicdisadvantages": NonEmptyString;
806
- /**
807
- * - `0`: Current AP spent on blessed disadvantages
808
- * - `1`: Maximum possible AP spent on blessed disadvantages
809
- */
810
- "advantagesdisadvantages.apspent.spentonblesseddisadvantages": NonEmptyString;
811
- "advantagesdisadvantages.dialogs.customcost.title": NonEmptyString;
757
+ "Common Advantages": NonEmptyString;
758
+ "Common Disadvantages": NonEmptyString;
759
+ "Custom AP Cost": NonEmptyString;
812
760
  /**
813
761
  * - `0`: Entry name
814
762
  */
815
- "advantagesdisadvantages.dialogs.customcost.for": NonEmptyString;
816
- "specialabilities.addbtn": NonEmptyString;
817
- "specialabilities.header.name": NonEmptyString;
818
- "specialabilities.header.group": NonEmptyString;
819
- "specialabilities.header.adventurepoints": NonEmptyString;
820
- "specialabilities.header.adventurepoints.tooltip": NonEmptyString;
763
+ "AP Cost for {0}": NonEmptyString;
764
+ "Custom option": NonEmptyString;
821
765
  "specialabilities.nativetonguelevel": NonEmptyString;
822
766
  "inlinewiki.rule": NonEmptyString;
823
767
  "inlinewiki.effect": NonEmptyString;
@@ -860,32 +804,24 @@ export type UI = {
860
804
  * - `0`: Minimum social status
861
805
  */
862
806
  "inlinewiki.socialstatusxorhigher": NonEmptyString;
863
- "skills.commonskills": NonEmptyString;
864
- "skills.header.name": NonEmptyString;
865
- "skills.header.skillrating": NonEmptyString;
866
- "skills.header.skillrating.tooltip": NonEmptyString;
867
- "skills.header.group": NonEmptyString;
868
- "skills.header.check": NonEmptyString;
869
- "skills.header.improvementcost": NonEmptyString;
870
- "skills.header.improvementcost.tooltip": NonEmptyString;
807
+ "Common Skills": NonEmptyString;
808
+ "SR": NonEmptyString;
809
+ "Skill Rating": NonEmptyString;
810
+ "IC": NonEmptyString;
871
811
  "New Applications": NonEmptyString;
872
812
  "Uses": NonEmptyString;
873
- "showfrequency.stronglyrecommended": NonEmptyString;
874
- "showfrequency.common": NonEmptyString;
875
- "showfrequency.uncommon": NonEmptyString;
876
- "showfrequency.unfamiliarspells": NonEmptyString;
877
- "combattechniques.header.name": NonEmptyString;
878
- "combattechniques.header.group": NonEmptyString;
879
- "combattechniques.header.combattechniquerating": NonEmptyString;
880
- "combattechniques.header.combattechniquerating.tooltip": NonEmptyString;
881
- "combattechniques.header.improvementcost": NonEmptyString;
882
- "combattechniques.header.improvementcost.tooltip": NonEmptyString;
883
- "combattechniques.header.primaryattribute": NonEmptyString;
884
- "combattechniques.header.primaryattribute.tooltip": NonEmptyString;
885
- "combattechniques.header.attack": NonEmptyString;
886
- "combattechniques.header.attack.tooltip": NonEmptyString;
887
- "combattechniques.header.parry": NonEmptyString;
888
- "combattechniques.header.parry.tooltip": NonEmptyString;
813
+ "Strongly Recommended": NonEmptyString;
814
+ "Common": NonEmptyString;
815
+ "Uncommon": NonEmptyString;
816
+ "Unfamiliar Spells": NonEmptyString;
817
+ "CTR": NonEmptyString;
818
+ "Combat Technique Rating": NonEmptyString;
819
+ "P": NonEmptyString;
820
+ "Primary Attribute(s)": NonEmptyString;
821
+ "AT": NonEmptyString;
822
+ "Attack": NonEmptyString;
823
+ "PA": NonEmptyString;
824
+ "Parry": NonEmptyString;
889
825
  "Close Combat": NonEmptyString;
890
826
  "Ranged Combat": NonEmptyString;
891
827
  "inlinewiki.special": NonEmptyString;
@@ -901,18 +837,8 @@ export type UI = {
901
837
  "Animist Powers": NonEmptyString;
902
838
  "Geode Rituals": NonEmptyString;
903
839
  "Zibilja Rituals": NonEmptyString;
904
- "spells.addbtn": NonEmptyString;
905
- "spells.header.name": NonEmptyString;
906
- "spells.header.property": NonEmptyString;
907
- "spells.header.group": NonEmptyString;
908
- "spells.header.skillrating": NonEmptyString;
909
- "spells.header.skillrating.tooltip": NonEmptyString;
910
- "spells.header.check": NonEmptyString;
911
- "spells.header.checkmodifier": NonEmptyString;
912
- "spells.header.checkmodifier.tooltip": NonEmptyString;
913
- "spells.header.improvementcost": NonEmptyString;
914
- "spells.header.improvementcost.tooltip": NonEmptyString;
915
- "spells.groups.cantrip": NonEmptyString;
840
+ "Mod": NonEmptyString;
841
+ "Check Modifier": NonEmptyString;
916
842
  "spells.traditions.general": NonEmptyString;
917
843
  "magicalactions.animistforces.tribes.general": NonEmptyString;
918
844
  "inlinewiki.castingtime": NonEmptyString;
@@ -547,6 +547,24 @@ export type TrinkhornzauberIdentifier = {
547
547
  */
548
548
  trinkhornzauber: number;
549
549
  };
550
+ export type MagicalRuneIdentifier = {
551
+ tag: "MagicalRune";
552
+ /**
553
+ * The magical rune’s identifier.
554
+ * @integer
555
+ * @minimum 1
556
+ */
557
+ magical_rune: number;
558
+ };
559
+ export type MagicalSignIdentifier = {
560
+ tag: "MagicalSign";
561
+ /**
562
+ * The magical sign’s identifier.
563
+ * @integer
564
+ * @minimum 1
565
+ */
566
+ magical_sign: number;
567
+ };
550
568
  export type LanguageIdentifier = {
551
569
  tag: "Language";
552
570
  /**