@optolith/database-schema 0.77.0 → 0.77.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/gen/types.d.ts +243 -0
  3. package/lib/main.js +2 -0
  4. package/lib/types/Attribute.js +1 -3
  5. package/lib/types/DerivedCharacteristic.js +1 -3
  6. package/lib/types/SkillGroup.js +1 -3
  7. package/lib/types/SocialStatus.js +1 -0
  8. package/lib/types/Talisman.js +1 -1
  9. package/lib/types/_Identifier.d.ts +2 -0
  10. package/lib/types/_Identifier.js +4 -0
  11. package/lib/types/equipment/item/BandageOrRemedy.js +1 -1
  12. package/lib/types/equipment/item/CeremonialItem.js +1 -1
  13. package/lib/types/equipment/item/Clothes.js +1 -1
  14. package/lib/types/equipment/item/Container.js +1 -1
  15. package/lib/types/equipment/item/EquipmentCategory.d.ts +121 -0
  16. package/lib/types/equipment/item/EquipmentCategory.js +131 -0
  17. package/lib/types/equipment/item/EquipmentOfBlessedOnes.js +1 -1
  18. package/lib/types/equipment/item/IlluminationLightSource.js +1 -1
  19. package/lib/types/equipment/item/IlluminationRefillOrSupply.js +1 -1
  20. package/lib/types/equipment/item/Item.d.ts +287 -0
  21. package/lib/types/equipment/item/Item.js +167 -0
  22. package/lib/types/equipment/item/Liebesspielzeug.js +1 -1
  23. package/lib/types/equipment/item/LuxuryGood.js +1 -1
  24. package/lib/types/equipment/item/MagicalArtifact.js +1 -1
  25. package/lib/types/equipment/item/MusicalInstrument.js +1 -1
  26. package/lib/types/equipment/item/TravelGearOrTool.js +1 -1
  27. package/lib/types/equipment/item/Weapon.js +1 -1
  28. package/lib/types/equipment/item/WeaponAccessory.js +1 -1
  29. package/lib/types/equipment/item/_Item.js +1 -1
  30. package/lib/types/equipment/item/_Weapon.d.ts +2 -2
  31. package/lib/types/equipment/item/_Weapon.js +7 -4
  32. package/lib/types/equipment/item/sub/Reach.js +1 -3
  33. package/lib/types/index.d.ts +2 -0
  34. package/lib/types/index.js +2 -0
  35. package/package.json +9 -9
@@ -0,0 +1,131 @@
1
+ import * as DB from "tsondb/schema/dsl";
2
+ import { NestedTranslationMap } from "../../Locale.js";
3
+ const ValueRule = DB.Enum(import.meta.url, {
4
+ name: "ValueRule",
5
+ comment: "Defines if an instance MUST/CAN/MUST NOT define a value for this parameter. If multiple rules apply to the same parameter, the order of precedence is Required > Optional > Prohibited.",
6
+ values: () => ({
7
+ Required: DB.EnumCase({
8
+ comment: "The parameter MUST be present in all instances the rule applies to.",
9
+ type: null,
10
+ }),
11
+ Optional: DB.EnumCase({
12
+ comment: "The parameter CAN be present in any instances the rule applies to.",
13
+ type: null,
14
+ }),
15
+ Prohibited: DB.EnumCase({
16
+ comment: "The parameter MUST NOT be present in any instances the rule applies to.",
17
+ type: null,
18
+ }),
19
+ }),
20
+ });
21
+ const AllowedCombatValues = DB.TypeAlias(import.meta.url, {
22
+ name: "AllowedCombatValues",
23
+ comment: "The combat values that are allowed for this category. If any combat value is allowed and used, advantages, disadvantages and known item specifics are also allowed to be defined for the item.",
24
+ type: () => DB.Object({
25
+ isWeaponAllowed: DB.Required({
26
+ comment: "Is the item allowed to be used as a weapon?",
27
+ type: DB.Boolean(),
28
+ }),
29
+ isArmorAllowed: DB.Required({
30
+ comment: "Is the item allowed to be used as an armor?",
31
+ type: DB.Boolean(),
32
+ }),
33
+ }),
34
+ });
35
+ const EquipmentCategoryType = DB.Enum(import.meta.url, {
36
+ name: "EquipmentCategoryType",
37
+ values: () => ({
38
+ Default: DB.EnumCase({
39
+ comment: "Items that can be expressed using the generic Item entity.",
40
+ type: DB.IncludeIdentifier(DefaultEquipmentCategoryTypeRules),
41
+ }),
42
+ Special: DB.EnumCase({
43
+ comment: "Items whose rules and/or values cannot be expressed using the generic Item entity.",
44
+ type: DB.IncludeIdentifier(SpecialEquipmentCategoryEntity),
45
+ }),
46
+ }),
47
+ });
48
+ const DefaultEquipmentCategoryTypeRules = DB.TypeAlias(import.meta.url, {
49
+ name: "DefaultEquipmentCategoryTypeRules",
50
+ type: () => DB.Object({
51
+ combatValues: DB.Required({
52
+ comment: "The combat values that are allowed for this category. If any combat value is allowed and used, advantages, disadvantages and known item specifics are also allowed to be defined for the item.",
53
+ type: DB.IncludeIdentifier(AllowedCombatValues),
54
+ }),
55
+ restrictedTo: DB.Required({
56
+ comment: "Presence of restrictions to certain groups for items in this category.",
57
+ type: DB.IncludeIdentifier(ValueRule),
58
+ }),
59
+ structurePoints: DB.Required({
60
+ comment: "Presence of structure points to certain groups for items in this category.",
61
+ type: DB.IncludeIdentifier(ValueRule),
62
+ }),
63
+ weight: DB.Required({
64
+ comment: "Presence of weight to certain groups for items in this category.",
65
+ type: DB.IncludeIdentifier(ValueRule),
66
+ }),
67
+ complexity: DB.Required({
68
+ comment: "Presence of complexity to certain groups for items in this category.",
69
+ type: DB.IncludeIdentifier(ValueRule),
70
+ }),
71
+ }),
72
+ });
73
+ const SpecialEquipmentCategoryEntity = DB.Enum(import.meta.url, {
74
+ name: "SpecialEquipmentCategoryEntity",
75
+ values: () => ({
76
+ AnimalCare: DB.EnumCase({ type: null }),
77
+ Book: DB.EnumCase({ type: null }),
78
+ Elixir: DB.EnumCase({ type: null }),
79
+ GemOrPreciousStone: DB.EnumCase({ type: null }),
80
+ Newspaper: DB.EnumCase({ type: null }),
81
+ Poison: DB.EnumCase({ type: null }),
82
+ WorkingSupernaturalCreature: DB.EnumCase({ type: null }),
83
+ }),
84
+ });
85
+ export const EquipmentCategory = DB.Entity(import.meta.url, {
86
+ name: "EquipmentCategory",
87
+ namePlural: "EquipmentCategories",
88
+ type: () => DB.Object({
89
+ position: DB.Required({
90
+ comment: "The position of the category in the list. This has to be a unique value.",
91
+ type: DB.Integer({ minimum: 0 }),
92
+ }),
93
+ type: DB.Required({
94
+ comment: "The type of the equipment category.",
95
+ type: DB.IncludeIdentifier(EquipmentCategoryType),
96
+ }),
97
+ translations: NestedTranslationMap(DB.Required, "EquipmentCategory", DB.Object({
98
+ name: DB.Required({
99
+ comment: "The equipment category’s name.",
100
+ type: DB.String({ minLength: 1 }),
101
+ }),
102
+ })),
103
+ }),
104
+ instanceDisplayName: {},
105
+ sortOrder: { keyPath: "position", isIndex: true },
106
+ uniqueConstraints: [
107
+ {
108
+ keyPath: "position",
109
+ },
110
+ {
111
+ entityMapKeyPath: "translations",
112
+ keyPathInEntityMap: "name",
113
+ },
114
+ ],
115
+ });
116
+ export const isEquipmentCategoryOfDefaultType = (category) => category.type.kind === "Default";
117
+ export const mergeValueRules = (categories) => categories.reduce((acc, elem) => acc === "Required" || elem.kind === "Required"
118
+ ? "Required"
119
+ : acc === "Optional" || elem.kind === "Optional"
120
+ ? "Optional"
121
+ : "Prohibited", "Prohibited");
122
+ export const mergeAllValueRules = (categories) => ({
123
+ combatValues: {
124
+ isWeaponAllowed: categories.some(category => category.combatValues.isWeaponAllowed),
125
+ isArmorAllowed: categories.some(category => category.combatValues.isArmorAllowed),
126
+ },
127
+ restrictedTo: { kind: mergeValueRules(categories.map(category => category.restrictedTo)) },
128
+ structurePoints: { kind: mergeValueRules(categories.map(category => category.structurePoints)) },
129
+ weight: { kind: mergeValueRules(categories.map(category => category.weight)) },
130
+ complexity: { kind: mergeValueRules(categories.map(category => category.complexity)) },
131
+ });
@@ -37,7 +37,7 @@ export const EquipmentOfBlessedOnes = DB.Entity(import.meta.url, {
37
37
  return checkWeaponCombatTechniqueIntegrity({
38
38
  ...rest,
39
39
  instanceContent: instanceContent.combat_use.Weapon,
40
- }, { secondary: true });
40
+ });
41
41
  }
42
42
  return [];
43
43
  },
@@ -45,7 +45,7 @@ export const IlluminationLightSource = DB.Entity(import.meta.url, {
45
45
  return checkWeaponCombatTechniqueIntegrity({
46
46
  ...rest,
47
47
  instanceContent: instanceContent.combat_use.Weapon,
48
- }, { secondary: true });
48
+ });
49
49
  }
50
50
  return [];
51
51
  },
@@ -41,7 +41,7 @@ export const IlluminationRefillOrSupply = DB.Entity(import.meta.url, {
41
41
  return checkWeaponCombatTechniqueIntegrity({
42
42
  ...rest,
43
43
  instanceContent: instanceContent.combat_use.Weapon,
44
- }, { secondary: true });
44
+ });
45
45
  }
46
46
  return [];
47
47
  },
@@ -0,0 +1,287 @@
1
+ import * as DB from "tsondb/schema/dsl";
2
+ export declare const Item: DB.Entity<"Item", {
3
+ categories: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, true>;
4
+ cost: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"Cost", {
5
+ Free: DB.EnumCase<null>;
6
+ Various: DB.EnumCase<null>;
7
+ Invaluable: DB.EnumCase<null>;
8
+ Fixed: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"FixedCost", DB.Object<{
9
+ value: DB.MemberDecl<DB.Float, true>;
10
+ translations: DB.MemberDecl<DB.NestedEntityMap<"FixedCostTranslation", {
11
+ wrap_in_text: DB.MemberDecl<DB.String, true>;
12
+ }>, false>;
13
+ }>, []>>>;
14
+ Range: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"CostRange", DB.Object<{
15
+ from: DB.MemberDecl<DB.Float, true>;
16
+ to: DB.MemberDecl<DB.Float, false>;
17
+ translations: DB.MemberDecl<DB.NestedEntityMap<"CostRangeTranslation", {
18
+ wrap_in_text: DB.MemberDecl<DB.String, true>;
19
+ }>, false>;
20
+ }>, []>>>;
21
+ }, []>>, true>;
22
+ weight: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"Weight", DB.Float, []>>, true>;
23
+ complexity: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"Complexity", {
24
+ Primitive: DB.EnumCase<null>;
25
+ Simple: DB.EnumCase<null>;
26
+ Complex: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"ComplexComplexity", DB.Object<{
27
+ ap_value: DB.MemberDecl<DB.Integer, true>;
28
+ src: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"PublicationRefs", DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"PublicationRef", DB.Object<{
29
+ id: DB.MemberDecl<DB.ReferenceIdentifier, true>;
30
+ occurrences: DB.MemberDecl<DB.NestedEntityMap<string, {
31
+ initial: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"InitialOccurrence", DB.Object<{
32
+ printing: DB.MemberDecl<DB.Integer, false>;
33
+ pages: DB.MemberDecl<DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"PageRange", DB.Object<{
34
+ first_page: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"Page", {
35
+ InsideCoverFront: DB.EnumCase<null>;
36
+ InsideCoverBack: DB.EnumCase<null>;
37
+ Numbered: DB.EnumCase<DB.Integer>;
38
+ }, []>>, true>;
39
+ last_page: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"Page", {
40
+ InsideCoverFront: DB.EnumCase<null>;
41
+ InsideCoverBack: DB.EnumCase<null>;
42
+ Numbered: DB.EnumCase<DB.Integer>;
43
+ }, []>>, false>;
44
+ }>, []>>>, true>;
45
+ isRemoved: DB.MemberDecl<DB.Boolean, false>;
46
+ }>, []>>, true>;
47
+ revisions: DB.MemberDecl<DB.Array<DB.IncludeIdentifier<[], DB.Enum<"Revision", {
48
+ Since: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"Since", DB.Object<{
49
+ printing: DB.MemberDecl<DB.Integer, true>;
50
+ pages: DB.MemberDecl<DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"PageRange", DB.Object<{
51
+ first_page: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"Page", {
52
+ InsideCoverFront: DB.EnumCase<null>;
53
+ InsideCoverBack: DB.EnumCase<null>;
54
+ Numbered: DB.EnumCase<DB.Integer>;
55
+ }, []>>, true>;
56
+ last_page: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"Page", {
57
+ InsideCoverFront: DB.EnumCase<null>;
58
+ InsideCoverBack: DB.EnumCase<null>;
59
+ Numbered: DB.EnumCase<DB.Integer>;
60
+ }, []>>, false>;
61
+ }>, []>>>, true>;
62
+ }>, []>>>;
63
+ Deprecated: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"Deprecation", DB.Object<{
64
+ printing: DB.MemberDecl<DB.Integer, true>;
65
+ }>, []>>>;
66
+ }, []>>>, false>;
67
+ }>, true>;
68
+ }>, []>>>, []>>, false>;
69
+ }>, []>>>;
70
+ }, []>>, false>;
71
+ structurePoints: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"StructurePoints", DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"StructurePointsComponent", DB.Object<{
72
+ points: DB.MemberDecl<DB.Integer, true>;
73
+ }>, []>>>, []>>, true>;
74
+ meleeUses: DB.MemberDecl<DB.NestedEntityMap<string, {
75
+ damage: DB.MemberDecl<DB.TypeArgument<DB.Param<"Damage", DB.Type>>, true>;
76
+ damage_threshold: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"PrimaryAttributeDamageThreshold", {
77
+ Default: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"DefaultPrimaryAttributeDamageThreshold", DB.Object<{
78
+ threshold: DB.MemberDecl<DB.Integer, true>;
79
+ }>, []>>>;
80
+ List: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"PrimaryAttributeDamageThresholdList", DB.Object<{
81
+ list: DB.MemberDecl<DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"SinglePrimaryAttributeDamageThreshold", DB.Object<{
82
+ attribute: DB.MemberDecl<DB.ReferenceIdentifier, true>;
83
+ threshold: DB.MemberDecl<DB.Integer, true>;
84
+ }>, []>>>, true>;
85
+ }>, []>>>;
86
+ }, []>>, false>;
87
+ attackModifier: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"AttackModifier", DB.Integer, []>>, false>;
88
+ parryModifier: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"ParryModifier", DB.Integer, []>>, false>;
89
+ reach: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, false>;
90
+ length: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"Length", DB.Integer, []>>, false>;
91
+ size: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"ShieldSize", {
92
+ Small: DB.EnumCase<null>;
93
+ Medium: DB.EnumCase<null>;
94
+ Large: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"LargeShieldSize", DB.Object<{
95
+ attack_penalty: DB.MemberDecl<DB.Integer, false>;
96
+ }>, []>>>;
97
+ }, []>>, false>;
98
+ is_parrying_weapon: DB.MemberDecl<DB.Boolean, true>;
99
+ is_two_handed_weapon: DB.MemberDecl<DB.Boolean, true>;
100
+ is_improvised_weapon: DB.MemberDecl<DB.Boolean, true>;
101
+ }>, false>;
102
+ rangedUses: DB.MemberDecl<DB.NestedEntityMap<string, {
103
+ damage: DB.MemberDecl<DB.TypeArgument<DB.Param<"Damage", DB.Type>>, true>;
104
+ reload_time: DB.MemberDecl<DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"ReloadTime", DB.Object<{
105
+ value: DB.MemberDecl<DB.Integer, true>;
106
+ }>, []>>>, true>;
107
+ range: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RangeBrackets", DB.Object<{
108
+ close: DB.MemberDecl<DB.Integer, true>;
109
+ medium: DB.MemberDecl<DB.Integer, true>;
110
+ far: DB.MemberDecl<DB.Integer, true>;
111
+ }>, []>>, true>;
112
+ ammunition: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"AmmunitionishIdentifier", {
113
+ Ammunition: DB.EnumCase<DB.ReferenceIdentifier>;
114
+ Weapon: DB.EnumCase<DB.ReferenceIdentifier>;
115
+ }, []>>, false>;
116
+ length: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"Length", DB.Integer, []>>, false>;
117
+ is_improvised_weapon: DB.MemberDecl<DB.Boolean, true>;
118
+ }>, false>;
119
+ armorUse: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"SecondaryArmor", DB.Object<{
120
+ protection: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"Protection", DB.Integer, []>>, true>;
121
+ encumbrance: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"Encumbrance", DB.Integer, []>>, true>;
122
+ has_additional_penalties: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"HasAdditionalPenalties", DB.Boolean, []>>, true>;
123
+ variantOf: DB.MemberDecl<DB.ReferenceIdentifier, true>;
124
+ hit_zone: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"HitZone", {
125
+ Head: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"HeadHitZone", DB.Object<{
126
+ combination_possibilities: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"HeadHitZoneCombinationPossibilities", DB.Object<{
127
+ armors: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, true>;
128
+ protection: DB.MemberDecl<DB.Integer, false>;
129
+ }>, []>>, false>;
130
+ }>, []>>>;
131
+ Torso: DB.EnumCase<null>;
132
+ Arms: DB.EnumCase<null>;
133
+ Legs: DB.EnumCase<null>;
134
+ }, []>>, false>;
135
+ restrictedTo: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedTo", DB.Object<{
136
+ races: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedToRaces", DB.Object<{
137
+ scope: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, true>;
138
+ }>, []>>, false>;
139
+ cultures: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedToCultures", DB.Object<{
140
+ scope: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, true>;
141
+ }>, []>>, false>;
142
+ professions: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedToProfessions", DB.Object<{
143
+ scope: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, true>;
144
+ }>, []>>, false>;
145
+ magicalTraditions: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedToMagicalTraditions", DB.Object<{
146
+ scope: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, true>;
147
+ }>, []>>, false>;
148
+ blessedTraditions: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedToBlessedTraditions", DB.Object<{
149
+ scope: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"RestrictedToBlessedTraditionsScope", {
150
+ Specific: DB.EnumCase<DB.Array<DB.ReferenceIdentifier>>;
151
+ Church: DB.EnumCase<null>;
152
+ Shamanistic: DB.EnumCase<null>;
153
+ }, []>>, true>;
154
+ isSanctifiedBy: DB.MemberDecl<DB.Boolean, true>;
155
+ }>, []>>, false>;
156
+ }>, []>>, false>;
157
+ translations: DB.MemberDecl<DB.NestedEntityMap<"SecondaryArmorTranslation", {
158
+ advantage: DB.MemberDecl<DB.String, false>;
159
+ disadvantage: DB.MemberDecl<DB.String, false>;
160
+ }>, false>;
161
+ }>, []>>, false>;
162
+ restrictedTo: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedTo", DB.Object<{
163
+ races: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedToRaces", DB.Object<{
164
+ scope: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, true>;
165
+ }>, []>>, false>;
166
+ cultures: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedToCultures", DB.Object<{
167
+ scope: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, true>;
168
+ }>, []>>, false>;
169
+ professions: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedToProfessions", DB.Object<{
170
+ scope: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, true>;
171
+ }>, []>>, false>;
172
+ magicalTraditions: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedToMagicalTraditions", DB.Object<{
173
+ scope: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, true>;
174
+ }>, []>>, false>;
175
+ blessedTraditions: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"RestrictedToBlessedTraditions", DB.Object<{
176
+ scope: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"RestrictedToBlessedTraditionsScope", {
177
+ Specific: DB.EnumCase<DB.Array<DB.ReferenceIdentifier>>;
178
+ Church: DB.EnumCase<null>;
179
+ Shamanistic: DB.EnumCase<null>;
180
+ }, []>>, true>;
181
+ isSanctifiedBy: DB.MemberDecl<DB.Boolean, true>;
182
+ }>, []>>, false>;
183
+ }>, []>>, false>;
184
+ knownItemSpecifics: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"KnownItemSpecifics", DB.Object<{
185
+ age: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"KnownItemAge", {
186
+ Antique: DB.EnumCase<null>;
187
+ Old: DB.EnumCase<null>;
188
+ }, []>>, false>;
189
+ condition: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"KnownItemCondition", {
190
+ Broken: DB.EnumCase<null>;
191
+ Poor: DB.EnumCase<null>;
192
+ Good: DB.EnumCase<null>;
193
+ VeryGood: DB.EnumCase<null>;
194
+ AsNew: DB.EnumCase<null>;
195
+ }, []>>, false>;
196
+ stabilityRating: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"KnownItemStabilityRating", {
197
+ Constant: DB.EnumCase<DB.Integer>;
198
+ Unbreakable: DB.EnumCase<null>;
199
+ }, []>>, false>;
200
+ damageLevel: DB.MemberDecl<DB.Integer, false>;
201
+ collectorsValue: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"CollectorsValue", {
202
+ Constant: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"ConstantCollectorsValue", DB.Object<{
203
+ value: DB.MemberDecl<DB.Float, true>;
204
+ translations: DB.MemberDecl<DB.NestedEntityMap<"ConstantCollectorsValueTranslation", {
205
+ note: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"ResponsiveTextOptional", DB.Object<{
206
+ full: DB.MemberDecl<DB.String, true>;
207
+ compressed: DB.MemberDecl<DB.String, false>;
208
+ }>, []>>, false>;
209
+ replacement: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"ResponsiveTextReplace", DB.Object<{
210
+ full: DB.MemberDecl<DB.String, true>;
211
+ compressed: DB.MemberDecl<DB.String, true>;
212
+ }>, []>>, false>;
213
+ }>, false>;
214
+ }>, []>>>;
215
+ Minimum: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"MinimumCollectorsValue", DB.Object<{
216
+ value: DB.MemberDecl<DB.Float, true>;
217
+ translations: DB.MemberDecl<DB.NestedEntityMap<"MinimumCollectorsValueTranslation", {
218
+ note: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"ResponsiveTextOptional", DB.Object<{
219
+ full: DB.MemberDecl<DB.String, true>;
220
+ compressed: DB.MemberDecl<DB.String, false>;
221
+ }>, []>>, false>;
222
+ replacement: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"ResponsiveTextReplace", DB.Object<{
223
+ full: DB.MemberDecl<DB.String, true>;
224
+ compressed: DB.MemberDecl<DB.String, true>;
225
+ }>, []>>, false>;
226
+ }>, false>;
227
+ }>, []>>>;
228
+ Invaluable: DB.EnumCase<null>;
229
+ }, []>>, true>;
230
+ }>, []>>, false>;
231
+ src: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"PublicationRefs", DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"PublicationRef", DB.Object<{
232
+ id: DB.MemberDecl<DB.ReferenceIdentifier, true>;
233
+ occurrences: DB.MemberDecl<DB.NestedEntityMap<string, {
234
+ initial: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"InitialOccurrence", DB.Object<{
235
+ printing: DB.MemberDecl<DB.Integer, false>;
236
+ pages: DB.MemberDecl<DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"PageRange", DB.Object<{
237
+ first_page: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"Page", {
238
+ InsideCoverFront: DB.EnumCase<null>;
239
+ InsideCoverBack: DB.EnumCase<null>;
240
+ Numbered: DB.EnumCase<DB.Integer>;
241
+ }, []>>, true>;
242
+ last_page: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"Page", {
243
+ InsideCoverFront: DB.EnumCase<null>;
244
+ InsideCoverBack: DB.EnumCase<null>;
245
+ Numbered: DB.EnumCase<DB.Integer>;
246
+ }, []>>, false>;
247
+ }>, []>>>, true>;
248
+ isRemoved: DB.MemberDecl<DB.Boolean, false>;
249
+ }>, []>>, true>;
250
+ revisions: DB.MemberDecl<DB.Array<DB.IncludeIdentifier<[], DB.Enum<"Revision", {
251
+ Since: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"Since", DB.Object<{
252
+ printing: DB.MemberDecl<DB.Integer, true>;
253
+ pages: DB.MemberDecl<DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"PageRange", DB.Object<{
254
+ first_page: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"Page", {
255
+ InsideCoverFront: DB.EnumCase<null>;
256
+ InsideCoverBack: DB.EnumCase<null>;
257
+ Numbered: DB.EnumCase<DB.Integer>;
258
+ }, []>>, true>;
259
+ last_page: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"Page", {
260
+ InsideCoverFront: DB.EnumCase<null>;
261
+ InsideCoverBack: DB.EnumCase<null>;
262
+ Numbered: DB.EnumCase<DB.Integer>;
263
+ }, []>>, false>;
264
+ }>, []>>>, true>;
265
+ }>, []>>>;
266
+ Deprecated: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"Deprecation", DB.Object<{
267
+ printing: DB.MemberDecl<DB.Integer, true>;
268
+ }>, []>>>;
269
+ }, []>>>, false>;
270
+ }>, true>;
271
+ }>, []>>>, []>>, true>;
272
+ translations: DB.MemberDecl<DB.NestedEntityMap<"ItemTranslation", {
273
+ name: DB.MemberDecl<DB.String, true>;
274
+ secondaryName: DB.MemberDecl<DB.String, false>;
275
+ note: DB.MemberDecl<DB.String, false>;
276
+ rules: DB.MemberDecl<DB.String, false>;
277
+ advantage: DB.MemberDecl<DB.String, false>;
278
+ disadvantage: DB.MemberDecl<DB.String, false>;
279
+ knownItemSpecifics: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"KnownItemSpecificsTranslation", DB.Object<{
280
+ condition: DB.MemberDecl<DB.String, true>;
281
+ }>, []>>, false>;
282
+ errata: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"Errata", DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"Erratum", DB.Object<{
283
+ date: DB.MemberDecl<DB.Date, true>;
284
+ description: DB.MemberDecl<DB.String, true>;
285
+ }>, []>>>, []>>, false>;
286
+ }>, true>;
287
+ }, undefined>;
@@ -0,0 +1,167 @@
1
+ import { isNotEmpty } from "@elyukai/utils/array/nonEmpty";
2
+ import { isNotNullish } from "@elyukai/utils/nullable";
3
+ import * as DB from "tsondb/schema/dsl";
4
+ import { EquipmentCategoryIdentifier } from "../../_Identifier.js";
5
+ import { CloseCombatTechnique, RangedCombatTechnique } from "../../CombatTechnique.js";
6
+ import { NestedTranslationMap } from "../../Locale.js";
7
+ import { Errata } from "../../source/_Erratum.js";
8
+ import { src } from "../../source/_PublicationRef.js";
9
+ import { Complexity, Cost, KnownItemSpecifics, KnownItemSpecificsTranslation, RestrictedTo, StructurePoints, Weight, } from "./_Item.js";
10
+ import { MeleeWeapon } from "./_MeleeWeapon.js";
11
+ import { RangedWeapon } from "./_RangedWeapon.js";
12
+ import { checkWeaponCombatTechniqueIntegrity } from "./_Weapon.js";
13
+ import { SecondaryArmor } from "./Armor.js";
14
+ import { isEquipmentCategoryOfDefaultType, mergeAllValueRules } from "./EquipmentCategory.js";
15
+ export const Item = DB.Entity(import.meta.url, {
16
+ name: "Item",
17
+ namePlural: "Items",
18
+ type: () => DB.Object({
19
+ categories: DB.Required({
20
+ comment: "The categories this item belongs to.",
21
+ type: DB.Array(EquipmentCategoryIdentifier(), { minItems: 1, uniqueItems: true }),
22
+ }),
23
+ cost: DB.Required({
24
+ comment: "The cost in silverthalers.",
25
+ type: DB.IncludeIdentifier(Cost),
26
+ }),
27
+ weight: DB.Required({
28
+ comment: "The weight in kg.",
29
+ type: DB.IncludeIdentifier(Weight),
30
+ }),
31
+ complexity: DB.Optional({
32
+ comment: "The complexity of crafting the item.",
33
+ type: DB.IncludeIdentifier(Complexity),
34
+ }),
35
+ structurePoints: DB.Required({
36
+ comment: "The structure points of the item. Use an array if the item consists of multiple components that have individual structure points.",
37
+ type: DB.IncludeIdentifier(StructurePoints),
38
+ }),
39
+ meleeUses: DB.Optional({
40
+ comment: "A list of stat blocks for each close combat technique this weapon can be used with.",
41
+ type: DB.NestedEntityMap({
42
+ name: "MeleeWeaponUse2",
43
+ namePlural: "MeleeWeaponUses2",
44
+ secondaryEntity: CloseCombatTechnique,
45
+ type: DB.IncludeIdentifier(MeleeWeapon),
46
+ minProperties: 1,
47
+ }),
48
+ }),
49
+ rangedUses: DB.Optional({
50
+ comment: "A list of stat blocks for each ranged combat technique this weapon can be used with.",
51
+ type: DB.NestedEntityMap({
52
+ name: "RangedWeaponUse2",
53
+ namePlural: "RangedWeaponUses2",
54
+ secondaryEntity: RangedCombatTechnique,
55
+ type: DB.IncludeIdentifier(RangedWeapon),
56
+ minProperties: 1,
57
+ }),
58
+ }),
59
+ armorUse: DB.Optional({
60
+ comment: "Stats for this item being used as an armor.",
61
+ type: DB.IncludeIdentifier(SecondaryArmor),
62
+ }),
63
+ restrictedTo: DB.Optional({
64
+ comment: "Define if during character creation this weapon can only be bought by a specific subset of characters.",
65
+ type: DB.IncludeIdentifier(RestrictedTo),
66
+ }),
67
+ knownItemSpecifics: DB.Optional({
68
+ comment: "The weapon is a known item, which implies some additional values.",
69
+ type: DB.IncludeIdentifier(KnownItemSpecifics),
70
+ }),
71
+ src,
72
+ translations: NestedTranslationMap(DB.Required, "Item", DB.Object({
73
+ name: DB.Required({
74
+ comment: "The item’s name.",
75
+ type: DB.String({ minLength: 1 }),
76
+ }),
77
+ secondaryName: DB.Optional({
78
+ comment: "An auxiliary name or label of the item, if available.",
79
+ type: DB.String({ minLength: 1 }),
80
+ }),
81
+ note: DB.Optional({
82
+ comment: "Note text.",
83
+ type: DB.String({ minLength: 1, markdown: "block" }),
84
+ }),
85
+ rules: DB.Optional({
86
+ comment: "Special rules text.",
87
+ type: DB.String({ minLength: 1, markdown: "block" }),
88
+ }),
89
+ advantage: DB.Optional({
90
+ comment: "The weapon advantage text.",
91
+ type: DB.String({ minLength: 1, markdown: "block" }),
92
+ }),
93
+ disadvantage: DB.Optional({
94
+ comment: "The weapon disadvantage text.",
95
+ type: DB.String({ minLength: 1, markdown: "block" }),
96
+ }),
97
+ knownItemSpecifics: DB.Optional({
98
+ comment: "The weapon is a known item, which implies some additional values.",
99
+ type: DB.IncludeIdentifier(KnownItemSpecificsTranslation),
100
+ }),
101
+ errata: DB.Optional({
102
+ type: DB.IncludeIdentifier(Errata),
103
+ }),
104
+ })),
105
+ }),
106
+ instanceDisplayName: {},
107
+ uniqueConstraints: [
108
+ {
109
+ entityMapKeyPath: "translations",
110
+ keyPathInEntityMap: "name",
111
+ },
112
+ ],
113
+ customConstraints: ({ instanceContent, ...rest }) => checkWeaponCombatTechniqueIntegrity({
114
+ ...rest,
115
+ instanceContent,
116
+ }).concat(checkEquipmentCategoryConstraintsWithItem(instanceContent, rest.getInstanceById)),
117
+ });
118
+ const checkEquipmentCategoryConstraintsWithItem = (item, getInstanceById) => {
119
+ const categories = item.categories.map(categoryId => getInstanceById("EquipmentCategory", categoryId));
120
+ if (isNotEmpty(categories)) {
121
+ if (categories.every(isNotNullish)) {
122
+ if (categories.every(isEquipmentCategoryOfDefaultType)) {
123
+ const mergedRules = mergeAllValueRules(categories.map(c => c.type.Default));
124
+ const errors = [];
125
+ if (mergedRules.combatValues.isWeaponAllowed &&
126
+ item.meleeUses === undefined &&
127
+ item.rangedUses === undefined) {
128
+ errors.push("A weapon must defined at least one melee use or ranged use.");
129
+ }
130
+ if (mergedRules.combatValues.isArmorAllowed && item.armorUse === undefined) {
131
+ errors.push("An armor must defined an armor use.");
132
+ }
133
+ if (!mergedRules.combatValues.isWeaponAllowed &&
134
+ !mergedRules.combatValues.isArmorAllowed &&
135
+ Object.values(item.translations).some(t => t.advantage !== undefined ||
136
+ t.disadvantage !== undefined ||
137
+ t.knownItemSpecifics !== undefined)) {
138
+ errors.push("Advantages, disadvantages and known item specifics may only be specified for weapons and armor.");
139
+ }
140
+ const applyValueRule = (rule, value, valueName) => {
141
+ if (rule.kind === "Required" && value === undefined) {
142
+ errors.push(`${valueName} required for this item.`);
143
+ }
144
+ else if (rule.kind === "Prohibited" && value !== undefined) {
145
+ errors.push(`${valueName} prohibited for this item.`);
146
+ }
147
+ };
148
+ applyValueRule(mergedRules.complexity, item.complexity, "A complexity is");
149
+ applyValueRule(mergedRules.restrictedTo, item.restrictedTo, "Restriction are");
150
+ applyValueRule(mergedRules.structurePoints, item.structurePoints, "Structure points are");
151
+ applyValueRule(mergedRules.weight, item.weight, "A weight is");
152
+ return errors;
153
+ }
154
+ else {
155
+ return [
156
+ "One or more categories of this item are not of the default type, which cannot be chosen items of this entity.",
157
+ ];
158
+ }
159
+ }
160
+ else {
161
+ return ["One or more categories of this item could not be found."];
162
+ }
163
+ }
164
+ else {
165
+ return ["At least one category must be chosen for an item."];
166
+ }
167
+ };
@@ -41,7 +41,7 @@ export const Liebesspielzeug = DB.Entity(import.meta.url, {
41
41
  return checkWeaponCombatTechniqueIntegrity({
42
42
  ...rest,
43
43
  instanceContent: instanceContent.combat_use.Weapon,
44
- }, { secondary: true });
44
+ });
45
45
  }
46
46
  return [];
47
47
  },
@@ -41,7 +41,7 @@ export const LuxuryGood = DB.Entity(import.meta.url, {
41
41
  return checkWeaponCombatTechniqueIntegrity({
42
42
  ...rest,
43
43
  instanceContent: instanceContent.combat_use.Weapon,
44
- }, { secondary: true });
44
+ });
45
45
  }
46
46
  return [];
47
47
  },
@@ -75,7 +75,7 @@ export const MagicalArtifact = DB.Entity(import.meta.url, {
75
75
  return checkWeaponCombatTechniqueIntegrity({
76
76
  ...rest,
77
77
  instanceContent: instanceContent.combat_use.Weapon,
78
- }, { secondary: true });
78
+ });
79
79
  }
80
80
  return [];
81
81
  },
@@ -41,7 +41,7 @@ export const MusicalInstrument = DB.Entity(import.meta.url, {
41
41
  return checkWeaponCombatTechniqueIntegrity({
42
42
  ...rest,
43
43
  instanceContent: instanceContent.combat_use.Weapon,
44
- }, { secondary: true });
44
+ });
45
45
  }
46
46
  return [];
47
47
  },