Compare commits

...
17 Commits
Author SHA1 Message Date
Lector 9718f7d341 feat!: derived select options based on property
Refs: #175
Closes #174
2026-06-27 14:55:52 +02:00
Lector 0c8f3518ea feat!: active usage type for combat styles
Refs: #171
Closes #170
Reviewed-by: Lukas Obermann <lukas.obermann@icloud.com>
2026-06-27 14:06:46 +02:00
Lukas Obermann 3b3ae6f3a6 feat: optional additional name for magic styles 2026-06-24 22:19:55 +02:00
Lukas Obermann 028e438909 fix!: remove bannzeichen option native name 2026-06-21 22:53:25 +02:00
Lukas Obermann 04f2a32a5e build(release): 0.53.0
Signed-off-by: Lukas Obermann <lukas.obermann@icloud.com>
2026-06-21 21:46:25 +02:00
Lukas Obermann 0e25dbf4a7 feat!: add bannzeichen cost map 2026-06-21 21:46:15 +02:00
Lukas Obermann 7e977925b5 feat: separate tradition artifact enhancement identifiers
Still includes them in SpecialAbilityIdentifier group, but now have
their own group as well.
2026-06-21 21:28:44 +02:00
Lukas Obermann 11cadd76ba build(release): 0.52.2
Signed-off-by: Lukas Obermann <lukas.obermann@icloud.com>
2026-06-21 14:28:11 +02:00
Lukas Obermann 249af59f6a fix: combined unique constraint for botanic regions 2026-06-21 14:28:05 +02:00
Lukas Obermann bb7d59e8b7 build(release): 0.52.1
Signed-off-by: Lukas Obermann <lukas.obermann@icloud.com>
2026-06-20 08:54:41 +02:00
Lector 1e30f55407 feat: optional translation for combat technique restrictions
Refs: #169
Closes #168
Reviewed-by: Lukas Obermann <lukas.obermann@icloud.com>
2026-06-20 08:54:20 +02:00
Lukas Obermann b70343ba6e build(release): 0.52.0
Signed-off-by: Lukas Obermann <lukas.obermann@icloud.com>
2026-06-19 16:49:38 +02:00
Lector 3b522aa9d7 feat: botanic region uniqueness per parent
Refs: #166
Closes #165
Reviewed-by: Lukas Obermann <lukas.obermann@icloud.com>
2026-06-19 16:43:50 +02:00
Lector 894fe21536 feat!: enchantment cost map
Refs: #167
Closes #164
2026-06-19 16:40:55 +02:00
Lukas Obermann e89c4390be build(release): 0.51.0
Signed-off-by: Lukas Obermann <lukas.obermann@icloud.com>
2026-06-18 20:44:19 +02:00
Lector da1d2459db feat: add schemas for goblin tradition artifact enchantments
Refs: #163
Closes #162
Reviewed-by: Lukas Obermann <lukas.obermann@icloud.com>
2026-06-18 20:43:41 +02:00
Lector 6c62616285 feat!: rework plants schema
Refs: #161
Closes #160
2026-06-18 14:52:54 +02:00
30 changed files with 656 additions and 82 deletions
+50
View File
@@ -2,6 +2,56 @@
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
## [0.53.0](https://github.com/Optolith/database-schema/compare/v0.52.2...v0.53.0) (2026-06-21)
### ⚠ BREAKING CHANGES
* add bannzeichen cost map
### Features
* add bannzeichen cost map ([0e25dbf](https://github.com/Optolith/database-schema/commit/0e25dbf4a70275b9ba87f1d6b50f8e0c5ac806c1))
* separate tradition artifact enhancement identifiers ([7e97792](https://github.com/Optolith/database-schema/commit/7e977925b52135859dc4335dcf4238c1271c1a02))
## [0.52.2](https://github.com/Optolith/database-schema/compare/v0.52.1...v0.52.2) (2026-06-21)
### Bug Fixes
* combined unique constraint for botanic regions ([249af59](https://github.com/Optolith/database-schema/commit/249af59f6ac7549fa91ad756f8f12d4802593a3a))
## [0.52.1](https://github.com/Optolith/database-schema/compare/v0.52.0...v0.52.1) (2026-06-20)
### Features
* optional translation for combat technique restrictions ([1e30f55](https://github.com/Optolith/database-schema/commit/1e30f55407cae829aae2d1a1097c30eff4c68f3a)), closes [#169](https://github.com/Optolith/database-schema/issues/169) [#168](https://github.com/Optolith/database-schema/issues/168)
## [0.52.0](https://github.com/Optolith/database-schema/compare/v0.51.0...v0.52.0) (2026-06-19)
### ⚠ BREAKING CHANGES
* enchantment cost map
### Features
* botanic region uniqueness per parent ([3b522aa](https://github.com/Optolith/database-schema/commit/3b522aa9d7a76b1d8dafa3a89b1712ecba4b0c85)), closes [#166](https://github.com/Optolith/database-schema/issues/166) [#165](https://github.com/Optolith/database-schema/issues/165)
* enchantment cost map ([894fe21](https://github.com/Optolith/database-schema/commit/894fe21536d21c2bbc618ec77279da96f5303f06)), closes [#167](https://github.com/Optolith/database-schema/issues/167) [#164](https://github.com/Optolith/database-schema/issues/164)
## [0.51.0](https://github.com/Optolith/database-schema/compare/v0.50.1...v0.51.0) (2026-06-18)
### ⚠ BREAKING CHANGES
* rework plants schema
### Features
* add schemas for goblin tradition artifact enchantments ([da1d245](https://github.com/Optolith/database-schema/commit/da1d2459db003a624cce4d84c2695b927d7476f0)), closes [#163](https://github.com/Optolith/database-schema/issues/163) [#162](https://github.com/Optolith/database-schema/issues/162)
* rework plants schema ([6c62616](https://github.com/Optolith/database-schema/commit/6c6261628583cda5a27d34c194e5aae69c38a079)), closes [#161](https://github.com/Optolith/database-schema/issues/161) [#160](https://github.com/Optolith/database-schema/issues/160)
## [0.50.1](https://github.com/Optolith/database-schema/compare/v0.50.0...v0.50.1) (2026-06-14)
+6 -6
View File
@@ -1,15 +1,15 @@
{
"name": "@optolith/database-schema",
"version": "0.50.1",
"version": "0.53.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@optolith/database-schema",
"version": "0.50.1",
"version": "0.53.0",
"license": "MPL-2.0",
"dependencies": {
"@elyukai/utils": "^0.3.4",
"@elyukai/utils": "^0.3.6",
"tsondb": "^0.20.3",
"yaml": "^2.9.0"
},
@@ -60,9 +60,9 @@
}
},
"node_modules/@elyukai/utils": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@elyukai/utils/-/utils-0.3.4.tgz",
"integrity": "sha512-zqBF3Nz7Pd5e35E2mZuImeAvCSRlAneIWb/gZKtaa9yX1oPTW/4uVKrK5k7QE9pR7xMPo7FTUs2jZ5ZDaZ75PA==",
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@elyukai/utils/-/utils-0.3.6.tgz",
"integrity": "sha512-SFij3T0baqFu+G5NGjlHPVpLtKEeVRKg59jiMr7wQwAYM7LLpgoArBLeM/UL98FM0ntmvaRDDEBCfyMcCnsxdA==",
"license": "MPL-2.0"
},
"node_modules/@eslint-community/eslint-utils": {
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@optolith/database-schema",
"version": "0.50.1",
"version": "0.53.0",
"description": "Definitions and utilities for the flat-file database of Optolith, a character creation tool for the Pen and Paper RPG “The Dark Eye 5”, and its external integrations into other software.",
"keywords": [
"tde",
@@ -38,7 +38,7 @@
"author": "Lukas Obermann",
"license": "MPL-2.0",
"dependencies": {
"@elyukai/utils": "^0.3.4",
"@elyukai/utils": "^0.3.6",
"tsondb": "^0.20.3",
"yaml": "^2.9.0"
},
+48 -10
View File
@@ -17,7 +17,9 @@ import type {
ImprovementCost,
Poison,
PrerequisiteForLevel,
Property_ID,
RequirableSelectOptionIdentifier,
Ritual_ID,
SelectOptionCategory,
SelectOptions,
SelectOptionsAdventurePointsValue,
@@ -28,6 +30,7 @@ import type {
SkillSelectOptionCategoryPrerequisite,
SpecificFromSkillSelectOptionCategoryCategory,
SpecificTargetCategory,
Spell_ID,
TargetCategory,
TradeSecretAdventurePointsValue,
} from "../../gen/types.js"
@@ -67,15 +70,17 @@ const wrapPlainApValue = (
): TradeSecretAdventurePointsValue | undefined =>
apValue === undefined ? undefined : Case("Fixed", apValue)
const matchesSpecificSkillishIdList = (
id: string,
config: SpecificFromSkillSelectOptionCategoryCategory<string>,
const matchesSpecificSkillishIdList = <Ref>(
config: SpecificFromSkillSelectOptionCategoryCategory<Ref>,
matches: (required: Ref) => boolean,
): boolean => {
const isInList = config.list.some(matches)
switch (config.operation.kind) {
case "Intersection":
return config.list.includes(id)
return isInList
case "Difference":
return !config.list.includes(id)
return !isInList
default:
return assertExhaustive(config.operation)
}
@@ -233,14 +238,35 @@ const getDefaultSkillishFilter = <E extends SkillishEntityName>(
const { specific } = category
return specific === undefined
? undefined
: ({ id }) => matchesSpecificSkillishIdList(id, specific)
: ({ id }) => matchesSpecificSkillishIdList(specific, required => required === id)
}
const getDerivedSkillishSelectOptions = <E extends SkillishEntityName>(
const getSpellworkFilter = <E extends "Spell" | "Ritual">(
category: GenericSkillsSelectOptionCategoryCategory<
Case<"Single", Spell_ID | Ritual_ID> | Case<"Property", Property_ID>
>,
): ((instance: { id: string; content: Entity<TSONDBTypes, E> }) => boolean) | undefined => {
const { specific } = category
return specific === undefined
? undefined
: ({ id, content: { property } }) =>
matchesSpecificSkillishIdList(specific, required => {
switch (required.kind) {
case "Single":
return required.Single === id
case "Property":
return property === required.Property
default:
return assertExhaustive(required)
}
})
}
const getDerivedSkillishSelectOptions = <E extends SkillishEntityName, ID>(
database: TSONDB<TSONDBTypes>,
entryId: ActivatableIdentifier,
entity: E,
category: GenericSkillsSelectOptionCategoryCategory<string> & {
category: GenericSkillsSelectOptionCategoryCategory<ID> & {
skill_applications?: SkillApplicationOrUse[] | undefined
skill_uses?: SkillApplicationOrUse[] | undefined
},
@@ -248,7 +274,7 @@ const getDerivedSkillishSelectOptions = <E extends SkillishEntityName>(
bindingCost?: SelectOptionsBindingCostValue<SkillishIdentifier | CombatTechniqueIdentifier>
ap_value?: SelectOptionsAdventurePointsValue<SkillishIdentifier | CombatTechniqueIdentifier>
},
filter = getDefaultSkillishFilter<E>(category),
filter: ((instance: { id: string; content: Entity<TSONDBTypes, E> }) => boolean) | undefined,
) => {
const { prerequisites } = category
const { bindingCost, ap_value } = options
@@ -928,7 +954,10 @@ const getDerivedSelectOptions = (
const matchesIdRequirement =
category.Skills.specific === undefined ||
matchesSpecificSkillishIdList(id, category.Skills.specific)
matchesSpecificSkillishIdList(
category.Skills.specific,
required => required === id,
)
return matchesGroupRequirement && matchesIdRequirement
},
@@ -940,6 +969,7 @@ const getDerivedSelectOptions = (
"Spell",
category.Spells,
selectOptionCategory.Skills,
getSpellworkFilter(category.Spells),
)
case "Rituals":
return getDerivedSkillishSelectOptions(
@@ -948,6 +978,7 @@ const getDerivedSelectOptions = (
"Ritual",
category.Rituals,
selectOptionCategory.Skills,
getSpellworkFilter(category.Rituals),
)
case "LiturgicalChants":
return getDerivedSkillishSelectOptions(
@@ -956,6 +987,7 @@ const getDerivedSelectOptions = (
"LiturgicalChant",
category.LiturgicalChants,
selectOptionCategory.Skills,
getDefaultSkillishFilter(category.LiturgicalChants),
)
case "Ceremonies":
return getDerivedSkillishSelectOptions(
@@ -964,6 +996,7 @@ const getDerivedSelectOptions = (
"Ceremony",
category.Ceremonies,
selectOptionCategory.Skills,
getDefaultSkillishFilter(category.Ceremonies),
)
default:
return assertExhaustive(category)
@@ -980,6 +1013,7 @@ const getDerivedSelectOptions = (
"CloseCombatTechnique",
category.CloseCombatTechniques,
selectOptionCategory.CombatTechniques,
getDefaultSkillishFilter(category.CloseCombatTechniques),
)
case "RangedCombatTechniques":
return getDerivedSkillishSelectOptions(
@@ -988,6 +1022,7 @@ const getDerivedSelectOptions = (
"RangedCombatTechnique",
category.RangedCombatTechniques,
selectOptionCategory.CombatTechniques,
getDefaultSkillishFilter(category.RangedCombatTechniques),
)
default:
return assertExhaustive(category)
@@ -1118,8 +1153,10 @@ const cacheKeyBase: Record<ActivatableIdentifier["kind"], null> = {
FoolsHatEnchantment: null,
GeneralSpecialAbility: null,
Haubenzauber: null,
Hauerkettenzauber: null,
InstrumentEnchantment: null,
KarmaSpecialAbility: null,
Keulenzauber: null,
Krallenkettenzauber: null,
Kristallkugelzauber: null,
LiturgicalStyleSpecialAbility: null,
@@ -1132,6 +1169,7 @@ const cacheKeyBase: Record<ActivatableIdentifier["kind"], null> = {
PactGift: null,
ProtectiveWardingCircleSpecialAbility: null,
RingEnchantment: null,
Schweinetrommelzauber: null,
Sermon: null,
SexSpecialAbility: null,
SickleRitual: null,
+6
View File
@@ -51,6 +51,7 @@ export const schema = new Schema<TSONDBTypes>(
Types.BlessedTradition,
Types.Blessing,
Types.Book,
Types.BotanicRegion,
Types.BowlEnchantment,
Types.BrawlingSpecialAbility,
Types.Brew,
@@ -97,8 +98,10 @@ export const schema = new Schema<TSONDBTypes>(
Types.GoblinRitual,
Types.Guideline,
Types.HairColor,
Types.Hauerkettenzauber,
Types.Haubenzauber,
Types.HerbalAid,
Types.HerbalPreservation,
Types.HomunculusType,
Types.IlluminationLightSource,
Types.IlluminationRefillOrSupply,
@@ -106,6 +109,7 @@ export const schema = new Schema<TSONDBTypes>(
Types.JesterTrick,
Types.Jewelry,
Types.KarmaSpecialAbility,
Types.Keulenzauber,
Types.Krallenkettenzauber,
Types.Kristallkugelzauber,
Types.Laboratory,
@@ -148,6 +152,7 @@ export const schema = new Schema<TSONDBTypes>(
Types.RingEnchantment,
Types.Ritual,
Types.RopeOrChain,
Types.Schweinetrommelzauber,
Types.Script,
Types.Sermon,
Types.Service,
@@ -165,6 +170,7 @@ export const schema = new Schema<TSONDBTypes>(
Types.StaffEnchantment,
Types.State,
Types.Stationery,
Types.SubBiome,
Types.Subject,
Types.Talisman,
Types.TargetCategory,
+7
View File
@@ -1042,6 +1042,12 @@ export const Locale = DB.Entity(import.meta.url, {
".input {$value :number} .input {$style :string} {{{$value} years}}": null,
"{$value} years": null,
"years": null,
".input {$value :number} .input {$style :string} {{{$value} dcs.}}": null,
"{$value} dcs.": null,
"dcs.": null,
".input {$value :number} .input {$style :string} {{{$value} decades}}": null,
"{$value} decades": null,
"decades": null,
".input {$value :number} .input {$style :string} {{{$value} cent.}}": null,
"{$value} cent.": null,
"cent.": null,
@@ -1422,6 +1428,7 @@ export const Locale = DB.Entity(import.meta.url, {
"Aspect": null,
"As chosen": null,
"Passive": null,
"Active": null,
"Basic Maneuver": null,
"Special Maneuver": null,
"Volume": null,
+6
View File
@@ -15,6 +15,12 @@ export const name_in_library = DB.Optional({
type: DB.String({ minLength: 1 }),
})
export const additionalName = DB.Optional({
comment:
"A part of the name that is appended in parenthesis. This can be used to specify the group of people that typically uses this entry (e.g. the name of the witch circle for a magic style for witches).\n\nIf `name_in_library` is specified, this will be ignored for places where the `name_in_library` is used.",
type: DB.String({ minLength: 1 }),
})
export const levels = DB.Optional({
comment: "Number of available levels.",
type: DB.Integer({ minimum: 2 }),
+26 -1
View File
@@ -9,6 +9,7 @@ import {
CombatRelatedSpecialAbilityIdentifier,
CombatTechniqueIdentifier,
} from "./_IdentifierGroup.js"
import { NestedTranslationMap } from "./Locale.js"
const CombatSpecialAbilityUsageType = DB.Enum(import.meta.url, {
name: "CombatSpecialAbilityUsageType",
@@ -20,11 +21,25 @@ const CombatSpecialAbilityUsageType = DB.Enum(import.meta.url, {
}),
})
export const usage_type = DB.Required({
const CombatStyleUsageType = DB.Enum(import.meta.url, {
name: "CombatSpecialAbilityTypeUsageType",
comment: "The definition of how the combat special ability style can be used in combat.",
values: () => ({
Passive: DB.EnumCase({ type: null }),
Active: DB.EnumCase({ type: null }),
}),
})
export const special_ability_usage_type = DB.Required({
comment: "The definition of how the combat special ability can be used in combat.",
type: DB.IncludeIdentifier(CombatSpecialAbilityUsageType),
})
export const style_usage_type = DB.Required({
comment: "The definition of how the combat style can be used in combat.",
type: DB.IncludeIdentifier(CombatStyleUsageType),
})
const CombatSpecialAbilityType = DB.Enum(import.meta.url, {
name: "CombatSpecialAbilityType",
comment:
@@ -323,6 +338,16 @@ const SpecificApplicableCombatTechnique = DB.TypeAlias(import.meta.url, {
restriction: DB.Optional({
type: DB.IncludeIdentifier(ApplicableSpecificCombatTechniquesRestriction),
}),
translation: NestedTranslationMap(
DB.Optional,
"SpecificApplicableCombatTechnique",
DB.Object({
restriction: DB.Required({
comment: "The additional restriction of the combat technique.",
type: DB.String({ minLength: 1, markdown: "inline" }),
}),
}),
),
weapons: DB.Optional({
comment: "The specific weapons this combat special ability is only applicable to.",
type: DB.Array(WeaponIdentifier(), { minItems: 1 }),
+2
View File
@@ -4,6 +4,7 @@ import { DurationUnitValue } from "./_ActivatableSkillDuration.js"
import { AspectIdentifier, PropertyIdentifier } from "./_Identifier.js"
import { VolumePointsOptionReferenceIdentifier } from "./_IdentifierGroup.js"
import { ResponsiveText, ResponsiveTextOptional } from "./_ResponsiveText.js"
import { OneTimeCostMap } from "./_ActivatableSkillCost.js"
const EnchantmentCost = DB.Enum(import.meta.url, {
name: "EnchantmentCost",
@@ -37,6 +38,7 @@ export const ArcaneEnergyCost = DB.Enum(import.meta.url, {
Disjunction: DB.EnumCase({ type: DB.IncludeIdentifier(ArcaneEnergyCostDisjunction) }),
Variable: DB.EnumCase({ type: null }),
ByLevel: DB.EnumCase({ type: DB.IncludeIdentifier(ArcaneEnergyCostByLevel) }),
Map: DB.EnumCase({ type: DB.IncludeIdentifier(OneTimeCostMap) }),
}),
})
+21 -2
View File
@@ -11,6 +11,7 @@ import {
SkillIdentifier,
SpellIdentifier,
TargetCategoryIdentifier,
PropertyIdentifier,
} from "./_Identifier.js"
import {
ActivatableIdentifier,
@@ -211,16 +212,34 @@ const SkillsSelectOptionCategory = DB.TypeAlias(import.meta.url, {
}),
})
const SpellFilter = DB.Enum(import.meta.url, {
name: "SpellFilter",
values: () => ({
Single: DB.EnumCase({ type: SpellIdentifier() }),
Property: DB.EnumCase({ type: PropertyIdentifier() }),
}),
})
const RitualFilter = DB.Enum(import.meta.url, {
name: "RitualFilter",
values: () => ({
Single: DB.EnumCase({ type: RitualIdentifier() }),
Property: DB.EnumCase({ type: PropertyIdentifier() }),
}),
})
const SkillsSelectOptionCategoryCategory = DB.Enum(import.meta.url, {
name: "SkillsSelectOptionCategoryCategory",
values: () => ({
Skills: DB.EnumCase({ type: DB.IncludeIdentifier(SkillSelectOptionCategoryCategory) }),
Spells: DB.EnumCase({
type: DB.GenIncludeIdentifier(GenericSkillsSelectOptionCategoryCategory, [SpellIdentifier()]),
type: DB.GenIncludeIdentifier(GenericSkillsSelectOptionCategoryCategory, [
DB.IncludeIdentifierType(SpellFilter),
]),
}),
Rituals: DB.EnumCase({
type: DB.GenIncludeIdentifier(GenericSkillsSelectOptionCategoryCategory, [
RitualIdentifier(),
DB.IncludeIdentifierType(RitualFilter),
]),
}),
LiturgicalChants: DB.EnumCase({
+1
View File
@@ -150,6 +150,7 @@ export const DurationUnit = DB.Enum(import.meta.url, {
Weeks: DB.EnumCase({ type: null }),
Months: DB.EnumCase({ type: null }),
Years: DB.EnumCase({ type: null }),
Decades: DB.EnumCase({ type: null }),
Centuries: DB.EnumCase({ type: null }),
Actions: DB.EnumCase({ type: null }),
CombatRounds: DB.EnumCase({ type: null }),
+12
View File
@@ -33,6 +33,7 @@ import { Elixir } from "./equipment/item/Elixir.js"
import { EquipmentOfBlessedOnes } from "./equipment/item/EquipmentOfBlessedOnes.js"
import { GemOrPreciousStone } from "./equipment/item/GemOrPreciousStone.js"
import { HerbalAid } from "./equipment/item/HerbalAid.js"
import { HerbalPreservation } from "./equipment/item/HerbalPreservation.js"
import { IlluminationLightSource } from "./equipment/item/IlluminationLightSource.js"
import { IlluminationRefillOrSupply } from "./equipment/item/IlluminationRefillOrSupply.js"
import { Jewelry } from "./equipment/item/Jewelry.js"
@@ -49,7 +50,9 @@ import { RopeOrChain } from "./equipment/item/RopeOrChain.js"
import { Stationery } from "./equipment/item/Stationery.js"
import { ArmorType } from "./equipment/item/sub/ArmorType.js"
import { Biome } from "./equipment/item/sub/Biome.js"
import { SubBiome } from "./equipment/item/sub/SubBiome.js"
import { Reach } from "./equipment/item/sub/Reach.js"
import { BotanicRegion } from "./equipment/item/sub/BotanicRegion.js"
import { ThievesTool } from "./equipment/item/ThievesTool.js"
import { ToolOfTheTrade } from "./equipment/item/ToolOfTheTrade.js"
import { TravelGearOrTool } from "./equipment/item/TravelGearOrTool.js"
@@ -145,12 +148,15 @@ import { CauldronEnchantment } from "./traditionArtifacts/CauldronEnchantment.js
import { ChronicleEnchantment } from "./traditionArtifacts/ChronicleEnchantment.js"
import { DaggerRitual } from "./traditionArtifacts/DaggerRitual.js"
import { FoolsHatEnchantment } from "./traditionArtifacts/FoolsHatEnchantment.js"
import { Hauerkettenzauber } from "./traditionArtifacts/Hauerkettenzauber.js"
import { Haubenzauber } from "./traditionArtifacts/Haubenzauber.js"
import { InstrumentEnchantment } from "./traditionArtifacts/InstrumentEnchantment.js"
import { Keulenzauber } from "./traditionArtifacts/Keulenzauber.js"
import { Krallenkettenzauber } from "./traditionArtifacts/Krallenkettenzauber.js"
import { Kristallkugelzauber } from "./traditionArtifacts/Kristallkugelzauber.js"
import { OrbEnchantment } from "./traditionArtifacts/OrbEnchantment.js"
import { RingEnchantment } from "./traditionArtifacts/RingEnchantment.js"
import { Schweinetrommelzauber } from "./traditionArtifacts/Schweinetrommelzauber.js"
import { SickleRitual } from "./traditionArtifacts/SickleRitual.js"
import { SpellSwordEnchantment } from "./traditionArtifacts/SpellSwordEnchantment.js"
import { StaffEnchantment } from "./traditionArtifacts/StaffEnchantment.js"
@@ -242,7 +248,9 @@ export const GoblinRitualIdentifier: () => R = () => R(GoblinRitual)
export const GuidelineIdentifier: () => R = () => R(Guideline)
export const HairColorIdentifier: () => R = () => R(HairColor)
export const HaubenzauberIdentifier: () => R = () => R(Haubenzauber)
export const HauerkettenZauberIdentifier: () => R = () => R(Hauerkettenzauber)
export const HerbalAidIdentifier: () => R = () => R(HerbalAid)
export const HerbalPreservationIdentifier: () => R = () => R(HerbalPreservation)
export const IlluminationLightSourceIdentifier: () => R = () => R(IlluminationLightSource)
export const IlluminationRefillOrSupplyIdentifier: () => R = () => R(IlluminationRefillOrSupply)
export const InfluenceIdentifier: () => R = () => R(Influence)
@@ -250,6 +258,7 @@ export const InstrumentEnchantmentIdentifier: () => R = () => R(InstrumentEnchan
export const JesterTrickIdentifier: () => R = () => R(JesterTrick)
export const JewelryIdentifier: () => R = () => R(Jewelry)
export const KarmaSpecialAbilityIdentifier: () => R = () => R(KarmaSpecialAbility)
export const KeulenzauberIdentifier: () => R = () => R(Keulenzauber)
export const KrallenkettenzauberIdentifier: () => R = () => R(Krallenkettenzauber)
export const KristallkugelzauberIdentifier: () => R = () => R(Kristallkugelzauber)
export const LaboratoryIdentifier: () => R = () => R(Laboratory)
@@ -297,9 +306,11 @@ export const RaceIdentifier: () => R = () => R(Race)
export const RaceVariantIdentifier: () => R = () => R(RaceVariant)
export const RangedCombatTechniqueIdentifier: () => R = () => R(RangedCombatTechnique)
export const ReachIdentifier: () => R = () => R(Reach)
export const BotanicRegionIdentifier: () => R = () => R(BotanicRegion)
export const RingEnchantmentIdentifier: () => R = () => R(RingEnchantment)
export const RitualIdentifier: () => R = () => R(Ritual)
export const RopeOrChainIdentifier: () => R = () => R(RopeOrChain)
export const SchweinetrommelzauberIdentifier: () => R = () => R(Schweinetrommelzauber)
export const ScriptIdentifier: () => R = () => R(Script)
export const SermonIdentifier: () => R = () => R(Sermon)
export const SexPracticeIdentifier: () => R = () => R(SexPractice)
@@ -319,6 +330,7 @@ export const SpellSwordEnchantmentIdentifier: () => R = () => R(SpellSwordEnchan
export const StaffEnchantmentIdentifier: () => R = () => R(StaffEnchantment)
export const StateIdentifier: () => R = () => R(State)
export const StationeryIdentifier: () => R = () => R(Stationery)
export const SubBiomeIdentifier: () => R = () => R(SubBiome)
export const SubjectIdentifier: () => R = () => R(Subject)
export const TargetCategoryIdentifier: () => R = () => R(TargetCategory)
export const ThievesToolIdentifier: () => R = () => R(ThievesTool)
+54 -35
View File
@@ -1,3 +1,4 @@
import { sortObjectKeys } from "@elyukai/utils/object"
import * as DB from "tsondb/schema/dsl"
import {
AdvancedCombatSpecialAbilityIdentifier,
@@ -62,12 +63,14 @@ import {
GeodeRitualIdentifier,
GoblinRitualIdentifier,
HaubenzauberIdentifier,
HauerkettenZauberIdentifier,
IlluminationLightSourceIdentifier,
IlluminationRefillOrSupplyIdentifier,
InstrumentEnchantmentIdentifier,
JesterTrickIdentifier,
JewelryIdentifier,
KarmaSpecialAbilityIdentifier,
KeulenzauberIdentifier,
KrallenkettenzauberIdentifier,
KristallkugelzauberIdentifier,
LaboratoryIdentifier,
@@ -100,6 +103,7 @@ import {
RingEnchantmentIdentifier,
RitualIdentifier,
RopeOrChainIdentifier,
SchweinetrommelzauberIdentifier,
ScriptIdentifier,
SermonIdentifier,
SexPracticeIdentifier,
@@ -164,65 +168,80 @@ export const NewSkillApplicationOrUseParentIdentifier = DB.Enum(import.meta.url,
}),
})
export const SpecialAbilityIdentifier = DB.Enum(import.meta.url, {
name: "SpecialAbilityIdentifier",
export const TraditionArtifactEnchantmentIdentifier = DB.Enum(import.meta.url, {
name: "TraditionArtifactEnchantmentIdentifier",
values: () => ({
AdvancedCombatSpecialAbility: DB.EnumCase({ type: AdvancedCombatSpecialAbilityIdentifier() }),
AdvancedKarmaSpecialAbility: DB.EnumCase({ type: AdvancedKarmaSpecialAbilityIdentifier() }),
AdvancedMagicalSpecialAbility: DB.EnumCase({ type: AdvancedMagicalSpecialAbilityIdentifier() }),
AdvancedSkillSpecialAbility: DB.EnumCase({ type: AdvancedSkillSpecialAbilityIdentifier() }),
AncestorGlyph: DB.EnumCase({ type: AncestorGlyphIdentifier() }),
ArcaneOrbEnchantment: DB.EnumCase({ type: ArcaneOrbEnchantmentIdentifier() }),
AttireEnchantment: DB.EnumCase({ type: AttireEnchantmentIdentifier() }),
Beutelzauber: DB.EnumCase({ type: BeutelzauberIdentifier() }),
BlessedTradition: DB.EnumCase({ type: BlessedTraditionIdentifier() }),
BowlEnchantment: DB.EnumCase({ type: BowlEnchantmentIdentifier() }),
BrawlingSpecialAbility: DB.EnumCase({ type: BrawlingSpecialAbilityIdentifier() }),
CauldronEnchantment: DB.EnumCase({ type: CauldronEnchantmentIdentifier() }),
CeremonialItemSpecialAbility: DB.EnumCase({ type: CeremonialItemSpecialAbilityIdentifier() }),
ChronicleEnchantment: DB.EnumCase({ type: ChronicleEnchantmentIdentifier() }),
CombatSpecialAbility: DB.EnumCase({ type: CombatSpecialAbilityIdentifier() }),
CombatStyleSpecialAbility: DB.EnumCase({ type: CombatStyleSpecialAbilityIdentifier() }),
CommandSpecialAbility: DB.EnumCase({ type: CommandSpecialAbilityIdentifier() }),
DaggerRitual: DB.EnumCase({ type: DaggerRitualIdentifier() }),
FamiliarSpecialAbility: DB.EnumCase({ type: FamiliarSpecialAbilityIdentifier() }),
FatePointSexSpecialAbility: DB.EnumCase({ type: FatePointSexSpecialAbilityIdentifier() }),
FatePointSpecialAbility: DB.EnumCase({ type: FatePointSpecialAbilityIdentifier() }),
FoolsHatEnchantment: DB.EnumCase({ type: FoolsHatEnchantmentIdentifier() }),
GeneralSpecialAbility: DB.EnumCase({ type: GeneralSpecialAbilityIdentifier() }),
Haubenzauber: DB.EnumCase({ type: HaubenzauberIdentifier() }),
Hauerkettenzauber: DB.EnumCase({ type: HauerkettenZauberIdentifier() }),
InstrumentEnchantment: DB.EnumCase({ type: InstrumentEnchantmentIdentifier() }),
KarmaSpecialAbility: DB.EnumCase({ type: KarmaSpecialAbilityIdentifier() }),
Keulenzauber: DB.EnumCase({ type: KeulenzauberIdentifier() }),
Krallenkettenzauber: DB.EnumCase({ type: KrallenkettenzauberIdentifier() }),
Kristallkugelzauber: DB.EnumCase({ type: KristallkugelzauberIdentifier() }),
LiturgicalStyleSpecialAbility: DB.EnumCase({ type: LiturgicalStyleSpecialAbilityIdentifier() }),
LycantropicGift: DB.EnumCase({ type: LycantropicGiftIdentifier() }),
MagicalSign: DB.EnumCase({ type: MagicalSignIdentifier() }),
MagicalSpecialAbility: DB.EnumCase({ type: MagicalSpecialAbilityIdentifier() }),
MagicalTradition: DB.EnumCase({ type: MagicalTraditionIdentifier() }),
MagicStyleSpecialAbility: DB.EnumCase({ type: MagicStyleSpecialAbilityIdentifier() }),
OrbEnchantment: DB.EnumCase({ type: OrbEnchantmentIdentifier() }),
PactGift: DB.EnumCase({ type: PactGiftIdentifier() }),
ProtectiveWardingCircleSpecialAbility: DB.EnumCase({
type: ProtectiveWardingCircleSpecialAbilityIdentifier(),
}),
RingEnchantment: DB.EnumCase({ type: RingEnchantmentIdentifier() }),
Sermon: DB.EnumCase({ type: SermonIdentifier() }),
SexSpecialAbility: DB.EnumCase({ type: SexSpecialAbilityIdentifier() }),
Schweinetrommelzauber: DB.EnumCase({ type: SchweinetrommelzauberIdentifier() }),
SickleRitual: DB.EnumCase({ type: SickleRitualIdentifier() }),
SikaryanDrainSpecialAbility: DB.EnumCase({ type: SikaryanDrainSpecialAbilityIdentifier() }),
SkillStyleSpecialAbility: DB.EnumCase({ type: SkillStyleSpecialAbilityIdentifier() }),
SpellSwordEnchantment: DB.EnumCase({ type: SpellSwordEnchantmentIdentifier() }),
StaffEnchantment: DB.EnumCase({ type: StaffEnchantmentIdentifier() }),
ToyEnchantment: DB.EnumCase({ type: ToyEnchantmentIdentifier() }),
Trinkhornzauber: DB.EnumCase({ type: TrinkhornzauberIdentifier() }),
VampiricGift: DB.EnumCase({ type: VampiricGiftIdentifier() }),
Vision: DB.EnumCase({ type: VisionIdentifier() }),
WandEnchantment: DB.EnumCase({ type: WandEnchantmentIdentifier() }),
WeaponEnchantment: DB.EnumCase({ type: WeaponEnchantmentIdentifier() }),
}),
})
export const SpecialAbilityIdentifier = DB.Enum(import.meta.url, {
name: "SpecialAbilityIdentifier",
values: () =>
sortObjectKeys({
AdvancedCombatSpecialAbility: DB.EnumCase({ type: AdvancedCombatSpecialAbilityIdentifier() }),
AdvancedKarmaSpecialAbility: DB.EnumCase({ type: AdvancedKarmaSpecialAbilityIdentifier() }),
AdvancedMagicalSpecialAbility: DB.EnumCase({
type: AdvancedMagicalSpecialAbilityIdentifier(),
}),
AdvancedSkillSpecialAbility: DB.EnumCase({ type: AdvancedSkillSpecialAbilityIdentifier() }),
AncestorGlyph: DB.EnumCase({ type: AncestorGlyphIdentifier() }),
BlessedTradition: DB.EnumCase({ type: BlessedTraditionIdentifier() }),
BrawlingSpecialAbility: DB.EnumCase({ type: BrawlingSpecialAbilityIdentifier() }),
CeremonialItemSpecialAbility: DB.EnumCase({ type: CeremonialItemSpecialAbilityIdentifier() }),
ChronicleEnchantment: DB.EnumCase({ type: ChronicleEnchantmentIdentifier() }),
CombatSpecialAbility: DB.EnumCase({ type: CombatSpecialAbilityIdentifier() }),
CombatStyleSpecialAbility: DB.EnumCase({ type: CombatStyleSpecialAbilityIdentifier() }),
CommandSpecialAbility: DB.EnumCase({ type: CommandSpecialAbilityIdentifier() }),
FamiliarSpecialAbility: DB.EnumCase({ type: FamiliarSpecialAbilityIdentifier() }),
FatePointSexSpecialAbility: DB.EnumCase({ type: FatePointSexSpecialAbilityIdentifier() }),
FatePointSpecialAbility: DB.EnumCase({ type: FatePointSpecialAbilityIdentifier() }),
GeneralSpecialAbility: DB.EnumCase({ type: GeneralSpecialAbilityIdentifier() }),
KarmaSpecialAbility: DB.EnumCase({ type: KarmaSpecialAbilityIdentifier() }),
LiturgicalStyleSpecialAbility: DB.EnumCase({
type: LiturgicalStyleSpecialAbilityIdentifier(),
}),
LycantropicGift: DB.EnumCase({ type: LycantropicGiftIdentifier() }),
MagicalSign: DB.EnumCase({ type: MagicalSignIdentifier() }),
MagicalSpecialAbility: DB.EnumCase({ type: MagicalSpecialAbilityIdentifier() }),
MagicalTradition: DB.EnumCase({ type: MagicalTraditionIdentifier() }),
MagicStyleSpecialAbility: DB.EnumCase({ type: MagicStyleSpecialAbilityIdentifier() }),
PactGift: DB.EnumCase({ type: PactGiftIdentifier() }),
ProtectiveWardingCircleSpecialAbility: DB.EnumCase({
type: ProtectiveWardingCircleSpecialAbilityIdentifier(),
}),
Sermon: DB.EnumCase({ type: SermonIdentifier() }),
SexSpecialAbility: DB.EnumCase({ type: SexSpecialAbilityIdentifier() }),
SikaryanDrainSpecialAbility: DB.EnumCase({ type: SikaryanDrainSpecialAbilityIdentifier() }),
SkillStyleSpecialAbility: DB.EnumCase({ type: SkillStyleSpecialAbilityIdentifier() }),
VampiricGift: DB.EnumCase({ type: VampiricGiftIdentifier() }),
Vision: DB.EnumCase({ type: VisionIdentifier() }),
...TraditionArtifactEnchantmentIdentifier.type.value.values,
}),
})
export const CombatRelatedSpecialAbilityIdentifier = DB.Enum(import.meta.url, {
name: "CombatRelatedSpecialAbilityIdentifier",
values: () => ({
@@ -0,0 +1,93 @@
import * as DB from "tsondb/schema/dsl"
import { NestedTranslationMap } from "../../Locale.js"
import { DurationUnit } from "../../_ActivatableSkillDuration.js"
import { ResponsiveTextReplace } from "../../_ResponsiveText.js"
import { Dice } from "../../_Dice.js"
import { MathOperation } from "../../_MathExpression.js"
import { EffectType } from "./_Herbary.js"
import { src } from "../../source/_PublicationRef.js"
export const HerbalPreservation = DB.Entity(import.meta.url, {
name: "HerbalPreservation",
namePlural: "HerbalPreservations",
type: () =>
DB.Object({
types: DB.Required({
comment: "The types of this preservation.",
type: DB.Array(DB.IncludeIdentifier(EffectType), { minItems: 1, uniqueItems: true }),
}),
longevity: DB.Required({
comment: "How long this preservation lasts.",
type: DB.IncludeIdentifier(HerbalPreservationLongevity),
}),
src,
translations: NestedTranslationMap(
DB.Required,
"HerbalPreservation",
DB.Object({
name: DB.Required({
comment: "The herbal preservation's name.",
type: DB.String({ minLength: 1 }),
}),
preparation: DB.Required({
comment: "How to prepare this preservation.",
type: DB.String({ minLength: 1, markdown: "inline" }),
}),
alternative_effect: DB.Required({
comment: "The herbal preservation's alternative effect.",
type: DB.String({ minLength: 1, markdown: "block" }),
}),
}),
),
}),
instanceDisplayName: {},
uniqueConstraints: [
{
entityMapKeyPath: "translations",
keyPathInEntityMap: "name",
},
],
})
export const HerbalPreservationLongevity = DB.TypeAlias(import.meta.url, {
name: "HerbalPreservationLongevity",
type: () =>
DB.Object({
value: DB.Required({
comment: "An expression that evaluates to the duration.",
type: DB.IncludeIdentifier(HerbalPreservationLongevityExpression),
}),
unit: DB.Required({
comment: "The duration unit.",
type: DB.IncludeIdentifier(DurationUnit),
}),
translations: NestedTranslationMap(
DB.Optional,
"HerbalPreservationLongevity",
DB.Object({
replacement: DB.Required({
comment: "A replacement string.",
type: DB.IncludeIdentifier(ResponsiveTextReplace),
}),
}),
),
}),
})
export const HerbalPreservationLongevityExpression = DB.TypeAlias(import.meta.url, {
name: "HerbalPreservationLongevityExpression",
type: () =>
DB.GenIncludeIdentifier(MathOperation, [
DB.IncludeIdentifier(HerbalPreservationLongevityValue),
]),
})
export const HerbalPreservationLongevityValue = DB.Enum(import.meta.url, {
name: "HerbalPreservationLongevityValue",
values: () => ({
Constant: DB.EnumCase({ type: DB.Integer({ minimum: 1 }) }),
Dice: DB.EnumCase({
type: DB.IncludeIdentifier(Dice),
}),
}),
})
+86 -6
View File
@@ -4,7 +4,10 @@ import { NestedTranslationMap } from "../../Locale.js"
import { AlternativeName } from "../../_AlternativeNames.js"
import {
BiomeIdentifier,
SubBiomeIdentifier,
BotanicRegionIdentifier,
HerbalAidIdentifier,
HerbalPreservationIdentifier,
ElixirIdentifier,
PoisonIdentifier,
} from "../../_Identifier.js"
@@ -26,15 +29,15 @@ export const Plant = DB.Entity(import.meta.url, {
}),
search_difficulty: DB.Required({
comment: "The search difficulty for this plant.",
type: DB.Integer(),
type: DB.IncludeIdentifier(PlantDifficulty),
}),
identification_difficulty: DB.Required({
comment: "The identification difficulty for this plant.",
type: DB.Integer(),
type: DB.IncludeIdentifier(PlantDifficulty),
}),
applications: DB.Required({
comment: "The applications of this plant per quality level.",
type: DB.Array(DB.Integer(), { minItems: 6, maxItems: 6 }),
type: DB.IncludeIdentifier(PlantApplications),
}),
touch: DB.Optional({
comment: "The plant's touch effect.",
@@ -56,6 +59,10 @@ export const Plant = DB.Entity(import.meta.url, {
comment: "The herbal aids and elixirs that can be crafted with this plant.",
type: DB.Array(DB.IncludeIdentifier(PlantRecipe), { minItems: 1 }),
}),
longevity: DB.Optional({
comment: "The longevity of the plant.",
type: DB.IncludeIdentifier(PlantLongevity),
}),
src,
translations: NestedTranslationMap(
DB.Required,
@@ -123,9 +130,9 @@ const PlantOccurrence = DB.TypeAlias(import.meta.url, {
name: "PlantOccurrence",
type: () =>
DB.Object({
biome: DB.Required({
comment: "The biome this plant occurs in.",
type: BiomeIdentifier(),
regions: DB.Required({
comment: "Where this plant occurs in.",
type: DB.IncludeIdentifier(PlantOccurrenceTier),
}),
rarity: DB.Required({
comment: "The rarity of this plant in the biome.",
@@ -144,6 +151,54 @@ const PlantOccurrence = DB.TypeAlias(import.meta.url, {
}),
})
const PlantOccurrenceTier = DB.Enum(import.meta.url, {
name: "PlantOccurrenceTier",
values: () => ({
Biomes: DB.EnumCase({
type: DB.Array(BiomeIdentifier(), { minItems: 1 }),
}),
SubBiomes: DB.EnumCase({
type: DB.Array(SubBiomeIdentifier(), { minItems: 1 }),
}),
BotanicRegions: DB.EnumCase({
type: DB.Array(BotanicRegionIdentifier(), { minItems: 1 }),
}),
}),
})
const PlantDifficulty = DB.Enum(import.meta.url, {
name: "PlantDifficulty",
values: () => ({
Constant: DB.EnumCase({ type: DB.Integer() }),
Indefinite: DB.EnumCase({ type: DB.IncludeIdentifier(IndefinitePlantDescription) }),
}),
})
const IndefinitePlantDescription = DB.TypeAlias(import.meta.url, {
name: "IndefinitePlantDescription",
type: () =>
DB.Object({
translations: NestedTranslationMap(
DB.Required,
"IndefinitePlantDescription",
DB.Object({
description: DB.Required({
comment: "A description of whatever is indefinite of this plant.",
type: DB.String({ minLength: 1, markdown: "block" }),
}),
}),
),
}),
})
const PlantApplications = DB.Enum(import.meta.url, {
name: "PlantApplications",
values: () => ({
Constant: DB.EnumCase({ type: DB.Array(DB.Integer(), { minItems: 6, maxItems: 6 }) }),
Indefinite: DB.EnumCase({ type: DB.IncludeIdentifier(IndefinitePlantDescription) }),
}),
})
const PlantEffect = DB.TypeAlias(import.meta.url, {
name: "PlantEffect",
type: () =>
@@ -279,3 +334,28 @@ const IndefiniteRecipe = DB.TypeAlias(import.meta.url, {
),
}),
})
const PlantLongevity = DB.TypeAlias(import.meta.url, {
name: "PlantLongevity",
type: () =>
DB.Object({
preservations: DB.Optional({
comment: "The preservations with alternative effect of this preserved plant",
type: DB.Array(HerbalPreservationIdentifier(), { minItems: 1, uniqueItems: true }),
}),
translations: NestedTranslationMap(
DB.Required,
"PlantLongevity",
DB.Object({
raw: DB.Required({
comment: "The longevity of the raw plant",
type: DB.String({ minLength: 1, markdown: "block" }),
}),
preserved: DB.Optional({
comment: "The longevity of the preserved plant",
type: DB.String({ minLength: 1, markdown: "block" }),
}),
}),
),
}),
})
+4
View File
@@ -1,5 +1,6 @@
import * as DB from "tsondb/schema/dsl"
import { NestedTranslationMap } from "../../../Locale.js"
import { SubBiome } from "./SubBiome.js"
export const Biome = DB.Entity(import.meta.url, {
name: "Biome",
@@ -16,6 +17,9 @@ export const Biome = DB.Entity(import.meta.url, {
}),
}),
),
sub_biomes: DB.Required({
type: DB.ChildEntitiesType(SubBiome),
}),
}),
instanceDisplayName: {},
uniqueConstraints: [
@@ -0,0 +1,38 @@
import * as DB from "tsondb/schema/dsl"
import { NestedTranslationMap } from "../../../Locale.js"
import { SubBiomeIdentifier } from "../../../_Identifier.js"
export const BotanicRegion = DB.Entity(import.meta.url, {
name: "BotanicRegion",
namePlural: "BotanicRegions",
type: () =>
DB.Object({
parent: DB.Required({
comment: "The subbiome this region belongs to.",
type: SubBiomeIdentifier(),
}),
translations: NestedTranslationMap(
DB.Required,
"BotanicRegion",
DB.Object({
name: DB.Required({
comment: "The region's name.",
type: DB.String({ minLength: 1 }),
}),
}),
),
}),
parentReferenceKey: "parent",
instanceDisplayName: {},
uniqueConstraints: [
[
{
entityMapKeyPath: "translations",
keyPathInEntityMap: "name",
},
{
keyPath: "parent",
},
],
],
})
+37
View File
@@ -0,0 +1,37 @@
import * as DB from "tsondb/schema/dsl"
import { NestedTranslationMap } from "../../../Locale.js"
import { BiomeIdentifier } from "../../../_Identifier.js"
import { BotanicRegion } from "./BotanicRegion.js"
export const SubBiome = DB.Entity(import.meta.url, {
name: "SubBiome",
namePlural: "SubBiomes",
type: () =>
DB.Object({
parent: DB.Required({
comment: "The biome this sub-biome belongs to.",
type: BiomeIdentifier(),
}),
translations: NestedTranslationMap(
DB.Required,
"SubBiome",
DB.Object({
name: DB.Required({
comment: "The subbiome's name.",
type: DB.String({ minLength: 1 }),
}),
}),
),
regions: DB.Required({
type: DB.ChildEntities(BotanicRegion),
}),
}),
parentReferenceKey: "parent",
instanceDisplayName: {},
uniqueConstraints: [
{
entityMapKeyPath: "translations",
keyPathInEntityMap: "name",
},
],
})
+6
View File
@@ -31,6 +31,7 @@ export { Elixir } from "./equipment/item/Elixir.js"
export { EquipmentOfBlessedOnes } from "./equipment/item/EquipmentOfBlessedOnes.js"
export { GemOrPreciousStone } from "./equipment/item/GemOrPreciousStone.js"
export { HerbalAid } from "./equipment/item/HerbalAid.js"
export { HerbalPreservation } from "./equipment/item/HerbalPreservation.js"
export { IlluminationLightSource } from "./equipment/item/IlluminationLightSource.js"
export { IlluminationRefillOrSupply } from "./equipment/item/IlluminationRefillOrSupply.js"
export { Jewelry } from "./equipment/item/Jewelry.js"
@@ -47,7 +48,9 @@ export { RopeOrChain } from "./equipment/item/RopeOrChain.js"
export { Stationery } from "./equipment/item/Stationery.js"
export { ArmorType } from "./equipment/item/sub/ArmorType.js"
export { Biome } from "./equipment/item/sub/Biome.js"
export { SubBiome } from "./equipment/item/sub/SubBiome.js"
export { Reach } from "./equipment/item/sub/Reach.js"
export { BotanicRegion } from "./equipment/item/sub/BotanicRegion.js"
export { ThievesTool } from "./equipment/item/ThievesTool.js"
export { ToolOfTheTrade } from "./equipment/item/ToolOfTheTrade.js"
export { TravelGearOrTool } from "./equipment/item/TravelGearOrTool.js"
@@ -145,11 +148,14 @@ export { ChronicleEnchantment } from "./traditionArtifacts/ChronicleEnchantment.
export { DaggerRitual } from "./traditionArtifacts/DaggerRitual.js"
export { FoolsHatEnchantment } from "./traditionArtifacts/FoolsHatEnchantment.js"
export { Haubenzauber } from "./traditionArtifacts/Haubenzauber.js"
export { Hauerkettenzauber } from "./traditionArtifacts/Hauerkettenzauber.js"
export { InstrumentEnchantment } from "./traditionArtifacts/InstrumentEnchantment.js"
export { Keulenzauber } from "./traditionArtifacts/Keulenzauber.js"
export { Krallenkettenzauber } from "./traditionArtifacts/Krallenkettenzauber.js"
export { Kristallkugelzauber } from "./traditionArtifacts/Kristallkugelzauber.js"
export { OrbEnchantment } from "./traditionArtifacts/OrbEnchantment.js"
export { RingEnchantment } from "./traditionArtifacts/RingEnchantment.js"
export { Schweinetrommelzauber } from "./traditionArtifacts/Schweinetrommelzauber.js"
export { SickleRitual } from "./traditionArtifacts/SickleRitual.js"
export { SpellSwordEnchantment } from "./traditionArtifacts/SpellSwordEnchantment.js"
export { StaffEnchantment } from "./traditionArtifacts/StaffEnchantment.js"
+2 -4
View File
@@ -1,5 +1,6 @@
import * as DB from "tsondb/schema/dsl"
import { name_in_library } from "../_Activatable.js"
import { OneTimeCostMap } from "../_ActivatableSkillCost.ts"
import { ExpressionBasedDuration } from "../_ActivatableSkillDuration.js"
import { ActivatableSkillEffect } from "../_ActivatableSkillEffect.js"
import { BannzeichenIdentifier, PropertyIdentifier } from "../_Identifier.js"
@@ -111,6 +112,7 @@ const BannzeichenCost = DB.Enum(import.meta.url, {
values: () => ({
Single: DB.EnumCase({ type: DB.IncludeIdentifier(SingleBannzeichenCost) }),
Disjunction: DB.EnumCase({ type: DB.IncludeIdentifier(BannzeichenCostDisjunction) }),
Map: DB.EnumCase({ type: DB.IncludeIdentifier(OneTimeCostMap) }),
DerivedFromOption: DB.EnumCase({ type: null }),
}),
})
@@ -236,10 +238,6 @@ export const BannzeichenOption = DB.Entity(import.meta.url, {
The surrounding parenthesis will/should not be included, they will/should be generated.`,
type: DB.String({ minLength: 1 }),
}),
native_name: DB.Required({
comment: "The native name of the Bannzeichen option.",
type: DB.String({ minLength: 1 }),
}),
}),
),
}),
@@ -0,0 +1,18 @@
import * as DB from "tsondb/schema/dsl"
import { PropertyIdentifier } from "../../_Identifier.js"
import { DisplayOption } from "../DisplayOption.js"
export const PropertyPrerequisite = DB.TypeAlias(import.meta.url, {
name: "PropertyPrerequisite",
comment: "Requires a specific property or one of a specific set of properties.",
type: () =>
DB.Object({
id: DB.Required({
comment: "The propertys identifier.",
type: PropertyIdentifier(),
}),
display_option: DB.Optional({
type: DB.IncludeIdentifier(DisplayOption),
}),
}),
})
@@ -1,8 +1,8 @@
import * as DB from "tsondb/schema/dsl"
import { input, levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
import { combat_techniques, penalty, usage_type } from "../_ActivatableCombat.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
import { combat_techniques, penalty, special_ability_usage_type } from "../_ActivatableCombat.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.js"
import { explicit_select_options, select_options } from "../_ActivatableSelectOptions.js"
import { skill_applications, skill_uses } from "../_ActivatableSkillApplicationsAndUses.js"
import { GeneralPrerequisites } from "../_Prerequisite.js"
@@ -18,7 +18,7 @@ export const AdvancedCombatSpecialAbility = DB.Entity(import.meta.url, {
DB.Object({
levels,
nameBuilderRules,
usage_type,
usage_type: special_ability_usage_type,
select_options,
explicit_select_options,
skill_applications,
@@ -1,8 +1,8 @@
import * as DB from "tsondb/schema/dsl"
import { levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
import { combat_techniques, usage_type } from "../_ActivatableCombat.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
import { combat_techniques, special_ability_usage_type } from "../_ActivatableCombat.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.js"
import { explicit_select_options, select_options } from "../_ActivatableSelectOptions.js"
import { GeneralPrerequisites } from "../_Prerequisite.js"
import { NestedTranslationMap } from "../Locale.js"
@@ -16,7 +16,7 @@ export const BrawlingSpecialAbility = DB.Entity(import.meta.url, {
DB.Object({
levels,
nameBuilderRules,
usage_type,
usage_type: special_ability_usage_type,
select_options,
explicit_select_options,
maximum,
@@ -1,8 +1,13 @@
import * as DB from "tsondb/schema/dsl"
import { input, levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
import { combat_techniques, penalty, penalty_l10n, usage_type } from "../_ActivatableCombat.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
import {
combat_techniques,
penalty,
penalty_l10n,
special_ability_usage_type,
} from "../_ActivatableCombat.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.js"
import { explicit_select_options, select_options } from "../_ActivatableSelectOptions.js"
import { skill_applications, skill_uses } from "../_ActivatableSkillApplicationsAndUses.js"
import { GeneralPrerequisites } from "../_Prerequisite.js"
@@ -17,7 +22,7 @@ export const CombatSpecialAbility = DB.Entity(import.meta.url, {
DB.Object({
levels,
nameBuilderRules,
usage_type,
usage_type: special_ability_usage_type,
select_options,
explicit_select_options,
skill_applications,
@@ -2,8 +2,8 @@ import * as DB from "tsondb/schema/dsl"
import { levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
import { advanced } from "../_ActivatableAdvanced.js"
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
import { combat_techniques, penalty, type, usage_type } from "../_ActivatableCombat.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
import { combat_techniques, penalty, type, style_usage_type } from "../_ActivatableCombat.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.js"
import { explicit_select_options, select_options } from "../_ActivatableSelectOptions.js"
import { skill_applications, skill_uses } from "../_ActivatableSkillApplicationsAndUses.js"
import { AdvancedCombatSpecialAbilityIdentifier } from "../_Identifier.js"
@@ -19,7 +19,7 @@ export const CombatStyleSpecialAbility = DB.Entity(import.meta.url, {
DB.Object({
levels,
nameBuilderRules,
usage_type,
usage_type: style_usage_type,
type,
select_options,
explicit_select_options,
@@ -1,8 +1,8 @@
import * as DB from "tsondb/schema/dsl"
import { levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
import { combat_techniques, usage_type } from "../_ActivatableCombat.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
import { combat_techniques, special_ability_usage_type } from "../_ActivatableCombat.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.js"
import { explicit_select_options, select_options } from "../_ActivatableSelectOptions.js"
import { GeneralPrerequisites } from "../_Prerequisite.js"
import { NestedTranslationMap } from "../Locale.js"
@@ -16,7 +16,7 @@ export const CommandSpecialAbility = DB.Entity(import.meta.url, {
DB.Object({
levels,
nameBuilderRules,
usage_type,
usage_type: special_ability_usage_type,
select_options,
explicit_select_options,
maximum,
@@ -1,5 +1,5 @@
import * as DB from "tsondb/schema/dsl"
import { levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
import { additionalName, levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
import { advanced } from "../_ActivatableAdvanced.js"
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
@@ -34,6 +34,7 @@ export const MagicStyleSpecialAbility = DB.Entity(import.meta.url, {
"MagicStyleSpecialAbility",
DB.Object({
name,
additionalName,
name_in_library,
rules,
ap_value_append,
@@ -0,0 +1,36 @@
import * as DB from "tsondb/schema/dsl"
import { levels, maximum } from "../_Activatable.js"
import { ap_value } from "../_ActivatableAdventurePointsValue.js"
import { nameBuilderRules } from "../_ActivatableNames.js"
import { cost, property, volume } from "../_ActivatableNonMundane.js"
import { GeneralPrerequisites } from "../_Prerequisite.js"
import { src } from "../source/_PublicationRef.js"
import { translations } from "./_shared.js"
export const Hauerkettenzauber = DB.Entity(import.meta.url, {
name: "Hauerkettenzauber",
namePlural: "Hauerkettenzauber",
type: () =>
DB.Object({
levels,
nameBuilderRules,
maximum,
prerequisites: DB.Optional({
type: DB.IncludeIdentifier(GeneralPrerequisites),
}),
volume,
cost,
property: property(),
ap_value,
src,
translations: translations("Hauerkettenzauber"),
}),
instanceDisplayName: {},
uniqueConstraints: [
{
entityMapKeyPath: "translations",
keyPathInEntityMap: "name_in_library",
keyPathInEntityMapFallback: "name",
},
],
})
@@ -0,0 +1,37 @@
import * as DB from "tsondb/schema/dsl"
import { levels, maximum } from "../_Activatable.js"
import { ap_value } from "../_ActivatableAdventurePointsValue.js"
import { nameBuilderRules } from "../_ActivatableNames.js"
import { cost, property, volume } from "../_ActivatableNonMundane.js"
import { GeneralPrerequisites } from "../_Prerequisite.js"
import { src } from "../source/_PublicationRef.js"
import { translations } from "./_shared.js"
//Keulenzauber für Goblinzauberinnen
export const Keulenzauber = DB.Entity(import.meta.url, {
name: "Keulenzauber",
namePlural: "Keulenzauber",
type: () =>
DB.Object({
levels,
nameBuilderRules,
maximum,
prerequisites: DB.Optional({
type: DB.IncludeIdentifier(GeneralPrerequisites),
}),
volume,
cost,
property: property(),
ap_value,
src,
translations: translations("Keulenzauber"),
}),
instanceDisplayName: {},
uniqueConstraints: [
{
entityMapKeyPath: "translations",
keyPathInEntityMap: "name_in_library",
keyPathInEntityMapFallback: "name",
},
],
})
@@ -0,0 +1,36 @@
import * as DB from "tsondb/schema/dsl"
import { levels, maximum } from "../_Activatable.js"
import { ap_value } from "../_ActivatableAdventurePointsValue.js"
import { nameBuilderRules } from "../_ActivatableNames.js"
import { cost, property, volume } from "../_ActivatableNonMundane.js"
import { GeneralPrerequisites } from "../_Prerequisite.js"
import { src } from "../source/_PublicationRef.js"
import { translations } from "./_shared.js"
export const Schweinetrommelzauber = DB.Entity(import.meta.url, {
name: "Schweinetrommelzauber",
namePlural: "Schweinetrommelzauber",
type: () =>
DB.Object({
levels,
nameBuilderRules,
maximum,
prerequisites: DB.Optional({
type: DB.IncludeIdentifier(GeneralPrerequisites),
}),
volume,
cost,
property: property(),
ap_value,
src,
translations: translations("Schweinetrommelzauber"),
}),
instanceDisplayName: {},
uniqueConstraints: [
{
entityMapKeyPath: "translations",
keyPathInEntityMap: "name_in_library",
keyPathInEntityMapFallback: "name",
},
],
})