diff --git a/src/main.ts b/src/main.ts index dc7c9e53..2ad7b2a3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -51,6 +51,7 @@ export const schema = new Schema( Types.BlessedTradition, Types.Blessing, Types.Book, + Types.BotanicRegion, Types.BowlEnchantment, Types.BrawlingSpecialAbility, Types.Brew, @@ -99,6 +100,7 @@ export const schema = new Schema( Types.HairColor, Types.Haubenzauber, Types.HerbalAid, + Types.HerbalPreservation, Types.HomunculusType, Types.IlluminationLightSource, Types.IlluminationRefillOrSupply, @@ -165,6 +167,7 @@ export const schema = new Schema( Types.StaffEnchantment, Types.State, Types.Stationery, + Types.SubBiome, Types.Subject, Types.Talisman, Types.TargetCategory, diff --git a/src/types/Locale.ts b/src/types/Locale.ts index 2f0dab86..a9904cfd 100644 --- a/src/types/Locale.ts +++ b/src/types/Locale.ts @@ -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, diff --git a/src/types/_ActivatableSkillDuration.ts b/src/types/_ActivatableSkillDuration.ts index 66fbd988..ad14dd21 100644 --- a/src/types/_ActivatableSkillDuration.ts +++ b/src/types/_ActivatableSkillDuration.ts @@ -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 }), diff --git a/src/types/_Identifier.ts b/src/types/_Identifier.ts index db15652d..573809e9 100644 --- a/src/types/_Identifier.ts +++ b/src/types/_Identifier.ts @@ -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" @@ -243,6 +246,7 @@ export const GuidelineIdentifier: () => R = () => R(Guideline) export const HairColorIdentifier: () => R = () => R(HairColor) export const HaubenzauberIdentifier: () => R = () => R(Haubenzauber) 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) @@ -297,6 +301,7 @@ 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) @@ -319,6 +324,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) diff --git a/src/types/equipment/item/HerbalPreservation.ts b/src/types/equipment/item/HerbalPreservation.ts new file mode 100644 index 00000000..9dbf1817 --- /dev/null +++ b/src/types/equipment/item/HerbalPreservation.ts @@ -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), + }), + }), +}) diff --git a/src/types/equipment/item/Plant.ts b/src/types/equipment/item/Plant.ts index 33a0439d..9e069ce9 100644 --- a/src/types/equipment/item/Plant.ts +++ b/src/types/equipment/item/Plant.ts @@ -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" }), + }), + }), + ), + }), +}) diff --git a/src/types/equipment/item/sub/Biome.ts b/src/types/equipment/item/sub/Biome.ts index 23b228af..ccc1c6a4 100644 --- a/src/types/equipment/item/sub/Biome.ts +++ b/src/types/equipment/item/sub/Biome.ts @@ -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: [ diff --git a/src/types/equipment/item/sub/BotanicRegion.ts b/src/types/equipment/item/sub/BotanicRegion.ts new file mode 100644 index 00000000..b21aad09 --- /dev/null +++ b/src/types/equipment/item/sub/BotanicRegion.ts @@ -0,0 +1,33 @@ +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", + }, + ], +}) diff --git a/src/types/equipment/item/sub/SubBiome.ts b/src/types/equipment/item/sub/SubBiome.ts new file mode 100644 index 00000000..32fa860d --- /dev/null +++ b/src/types/equipment/item/sub/SubBiome.ts @@ -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", + }, + ], +}) diff --git a/src/types/index.ts b/src/types/index.ts index 1e735191..d988faf3 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -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"