Compare commits

...

26 Commits

Author SHA1 Message Date
Lukas Obermann 75cfe6af36 replace string with locale identifier type in translation dictionaries 2025-09-03 12:11:02 +02:00
Lukas Obermann 93683f5b58 make enum cases camel case instead of pascal case 2025-09-03 12:10:41 +02:00
Lukas Obermann 588c0d6818 refactor!: remove json schema files 2025-09-03 11:59:43 +02:00
Lukas Obermann be5a18725a format all files 2025-07-30 23:01:14 +02:00
Lukas Obermann 6e2a3b300b make folders pascal case 2025-07-30 22:01:17 +02:00
Lukas Obermann ee8d1cef7f compiling without errors 2025-07-30 21:55:46 +02:00
Lukas Obermann 0849f9e993 initial conversion tests 2025-07-27 21:57:38 +02:00
Lukas Obermann 67d649fa31 description should be optional 2025-07-16 17:08:51 +02:00
Lukas Obermann bde9178050 use description for state text 2025-07-14 20:43:46 +02:00
Lukas Obermann a354eaee83 translations for skill modification levels are optional 2025-07-14 18:23:02 +02:00
Lukas Obermann b52f11893b fix service translation name 2025-07-14 13:40:07 +02:00
Lukas Obermann f02c7d436e rename verification to text 2025-07-14 13:18:17 +02:00
Lukas Obermann 3194c79fe3 fix focus rule's errata field having to be optional 2025-07-14 12:45:02 +02:00
Lukas Obermann 1faab3c66b fix optional rule's errata field having to be optional 2025-07-14 12:29:40 +02:00
Lukas Obermann 392286990c fix plain prerequisites 2025-07-12 14:38:09 +02:00
Lukas Obermann 305c13ea0d fix animal shape path reference 2025-07-12 14:23:29 +02:00
Lukas Obermann e5528b7a09 upgrade tsondb 2025-07-12 14:02:08 +02:00
Lukas Obermann a7dd5f1a9f fix wrong displayName configuration 2025-07-12 14:01:21 +02:00
Lukas Obermann ac568e07cb comment isTransient properties to make tsc run smooth 2025-07-11 19:30:27 +02:00
Lukas Obermann e5755edede add prepare script to install directly from github 2025-07-11 19:25:54 +02:00
Lukas Obermann 0218a74dfa fix mistakes setting up tsondb schema 2025-07-11 19:14:35 +02:00
Lukas Obermann c244c11aed use npm module and provide schema export 2025-07-11 19:14:03 +02:00
Lukas Obermann 77fe9c9c21 undo property shortcuts as functions for activatable types 2025-07-10 23:13:04 +02:00
Lukas Obermann 7fdc2a1ae3 fix typescript exceeds stack size 2025-07-10 23:03:56 +02:00
Lukas Obermann 671c9e317b finish everything except profession and isTransient 2025-07-10 23:03:28 +02:00
Lukas Obermann 79fc09fd39 current state of experimenting with tsondb integration
Currently, the ModelContainer is fully local and the data root is set to /data, which is only for testing purposes. The data root should be defined in optolith-data and then ModelContainer somehow needs to be split up to support generating outputs without providing a data root.

Naming inspiration was drawn from SwiftData.
2025-07-08 15:26:49 +02:00
869 changed files with 36754 additions and 87866 deletions
+4
View File
@@ -1,6 +1,10 @@
node_modules
lib
# TSONDB
/data
/gen
# Swift
.DS_Store
/.build
+2 -1
View File
@@ -1,3 +1,4 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
"typescript.tsdk": "node_modules/typescript/lib",
"editor.tabSize": 4
}
+4 -13
View File
@@ -1,22 +1,13 @@
{
"originHash" : "8136f4350c7b746f8a6bfb9ad7b6473b656e39e2c5bf8fed118646234dbac7b0",
"originHash" : "2e7b536a032907c74f365fd46af21e20cf893878a97269b7186860b17a2c9608",
"pins" : [
{
"identity" : "discriminatedenum",
"kind" : "remoteSourceControl",
"location" : "https://github.com/elyukai/DiscriminatedEnum.git",
"state" : {
"branch" : "main",
"revision" : "0043d48d48f9880cb18198e173c479f27040b901"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftlang/swift-syntax.git",
"location" : "https://github.com/swiftlang/swift-syntax",
"state" : {
"revision" : "0687f71944021d616d34d922343dcef086855920",
"version" : "600.0.1"
"revision" : "f99ae8aa18f0cf0d53481901f88a0991dc3bd4a2",
"version" : "601.0.1"
}
}
],
+5 -12
View File
@@ -1,4 +1,4 @@
// swift-tools-version: 6.0
// swift-tools-version: 6.1
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
@@ -7,7 +7,7 @@ import CompilerPluginSupport
let package = Package(
name: "OptolithDatabaseSchema",
platforms: [
.macOS(.v13), .iOS(.v16), .tvOS(.v16), .watchOS(.v9), .macCatalyst(.v16)
.macOS(.v13)
],
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
@@ -16,22 +16,15 @@ let package = Package(
targets: ["OptolithDatabaseSchema"]),
],
dependencies: [
.package(url: "https://github.com/elyukai/DiscriminatedEnum.git", branch: "main"),
.package(url: "https://github.com/swiftlang/swift-syntax.git", from: "600.0.0-latest"),
.package(name: "FileDB", path: "../filedb"),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "OptolithDatabaseSchema",
dependencies: ["DiscriminatedEnum", "OptolithDatabaseSchemaMacros"]),
.macro(
name: "OptolithDatabaseSchemaMacros",
dependencies: [
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
.product(name: "SwiftCompilerPlugin", package: "swift-syntax")
]
),
"FileDB"
]),
]
)
@@ -1,23 +0,0 @@
//
// Entity.swift
// OptolithDatabaseSchema
//
// Created by Lukas Obermann on 15.11.24.
//
/// A type whose data is represented by a single file in the database.
public protocol Entity: Decodable, Hashable, Sendable { }
/// An entity that has associated translations for display purposes.
public protocol LocalizableEntity: Entity {
associatedtype Translation: EntitySubtype
var translations: LocaleMap<Translation> { get }
}
/// A subtype of an entity type that provides conformance to protocols an entity type must conform to. It is used purely for convenience purposes.
public protocol EntitySubtype: Decodable, Hashable, Sendable { }
extension String: EntitySubtype { }
extension Double: EntitySubtype { }
extension Int: EntitySubtype { }
@@ -1,106 +0,0 @@
//
// Advantage.swift
// OptolithDatabaseSchema
//
public struct Advantage: LocalizableEntity {
public let id: Id
public let levels: Levels?
public let selectOptions: SelectOptions?
public let skillApplications: SkillApplications?
public let skillUses: SkillUses?
public let maximum: Maximum?
public let prerequisites: AdvantageDisadvantagePrerequisites?
public let apValue: AdventurePointsValue
/// Does this advantage count towards the maximum of AP to be spent on advantages?
public let hasMaximumSpentInfluence: Bool
/// Does this advantage exclusively applies to arcane spellworks and not to magical actions and magical applications?
public let isExclusiveToArcaneSpellworks: Bool
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<AdvantageTranslation>
public init(id: Id, levels: Levels? = nil, selectOptions: SelectOptions? = nil, skillApplications: SkillApplications? = nil, skillUses: SkillUses? = nil, maximum: Maximum? = nil, prerequisites: AdvantageDisadvantagePrerequisites? = nil, apValue: AdventurePointsValue, hasMaximumSpentInfluence: Bool, isExclusiveToArcaneSpellworks: Bool, src: PublicationRefs, translations: LocaleMap<AdvantageTranslation>) {
self.id = id
self.levels = levels
self.selectOptions = selectOptions
self.skillApplications = skillApplications
self.skillUses = skillUses
self.maximum = maximum
self.prerequisites = prerequisites
self.apValue = apValue
self.hasMaximumSpentInfluence = hasMaximumSpentInfluence
self.isExclusiveToArcaneSpellworks = isExclusiveToArcaneSpellworks
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case levels = "levels"
case selectOptions = "select_options"
case skillApplications = "skill_applications"
case skillUses = "skill_uses"
case maximum = "maximum"
case prerequisites = "prerequisites"
case apValue = "ap_value"
case hasMaximumSpentInfluence = "has_maximum_spent_influence"
case isExclusiveToArcaneSpellworks = "is_exclusive_to_arcane_spellworks"
case src = "src"
case translations = "translations"
}
}
public struct AdvantageTranslation: EntitySubtype {
public let name: Name
public let nameInLibrary: NameInLibrary?
/// A string that is used as a label for an input field.
public let input: Input?
public let rules: Rules
/// The range.
public let range: String?
public let apValue: AdventurePointsValueReplacement?
/// A string that gets appended to the default AP Value text with a preceding space. This always happens if present, even if the generated AP Value text is replaced.
public let apValueAppend: AdventurePointsValueAppend?
public let errata: Errata?
public init(name: Name, nameInLibrary: NameInLibrary? = nil, input: Input? = nil, rules: Rules, range: String? = nil, apValue: AdventurePointsValueReplacement? = nil, apValueAppend: AdventurePointsValueAppend? = nil, errata: Errata? = nil) {
self.name = name
self.nameInLibrary = nameInLibrary
self.input = input
self.rules = rules
self.range = range
self.apValue = apValue
self.apValueAppend = apValueAppend
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case nameInLibrary = "name_in_library"
case input = "input"
case rules = "rules"
case range = "range"
case apValue = "ap_value"
case apValueAppend = "ap_value_append"
case errata = "errata"
}
}
@@ -1,55 +0,0 @@
//
// AnimalDisease.swift
// OptolithDatabaseSchema
//
public struct AnimalDisease: LocalizableEntity {
/// The animal disease's identifier. An unique, increasing integer.
public let id: Int
/// The animal disease's level.
public let level: Int
/// Depending on the disease, apply Spirit or Toughness as a penalty to the disease roll. It may also happen that the lower of both is applied as a penalty.
public let resistance: Resistance
/// What causes the disease? The GM rolls 1D20 to see if a character gets infected. If the infection check succeeds, the GM makes a disease check to determine the severity of the infection.
public let cause: [Cause]
/// The animal types this disease applies to.
///
/// If no animal types are given, the animal disease applies to all animal types.
public let animalTypes: [AnimalTypeReference]
/// If and at which chance the disease can be communicated to intelligent creatures.
///
/// If no causes are given, the disease is not communicable to intelligent creatures.
public let communicabilityToIntelligentCreatures: [Cause]
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DiseaseTranslation>
public init(id: Int, level: Int, resistance: Resistance, cause: [Cause], animalTypes: [AnimalTypeReference], communicabilityToIntelligentCreatures: [Cause], src: PublicationRefs, translations: LocaleMap<DiseaseTranslation>) {
self.id = id
self.level = level
self.resistance = resistance
self.cause = cause
self.animalTypes = animalTypes
self.communicabilityToIntelligentCreatures = communicabilityToIntelligentCreatures
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case level = "level"
case resistance = "resistance"
case cause = "cause"
case animalTypes = "animal_types"
case communicabilityToIntelligentCreatures = "communicability_to_intelligent_creatures"
case src = "src"
case translations = "translations"
}
}
@@ -1,26 +0,0 @@
//
// AnimalType.swift
// OptolithDatabaseSchema
//
public struct AnimalType: LocalizableEntity {
/// The animal type's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<AnimalTypeTranslation>
public init(id: Int, translations: LocaleMap<AnimalTypeTranslation>) {
self.id = id
self.translations = translations
}
}
public struct AnimalTypeTranslation: EntitySubtype {
/// The animal type name.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,6 +0,0 @@
//
// ArcaneBardTradition.swift
// OptolithDatabaseSchema
//
public typealias ArcaneBardTradition = ArcaneTradition
@@ -1,6 +0,0 @@
//
// ArcaneDancerTradition.swift
// OptolithDatabaseSchema
//
public typealias ArcaneDancerTradition = ArcaneTradition
@@ -1,35 +0,0 @@
//
// Aspect.swift
// OptolithDatabaseSchema
//
public struct Aspect: LocalizableEntity {
/// The aspect's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<AspectTranslation>
public init(id: Int, translations: LocaleMap<AspectTranslation>) {
self.id = id
self.translations = translations
}
}
public struct AspectTranslation: EntitySubtype {
/// The aspect name.
public let name: NonEmptyString
/// The aspect's name appended to the simple name (not `name_in_library`) of the special ability *Master of (Aspect)*.
public let masterOfAspectSuffix: NonEmptyString?
public init(name: NonEmptyString, masterOfAspectSuffix: NonEmptyString? = nil) {
self.name = name
self.masterOfAspectSuffix = masterOfAspectSuffix
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case masterOfAspectSuffix = "master_of_aspect_suffix"
}
}
@@ -1,34 +0,0 @@
//
// Attribute.swift
// OptolithDatabaseSchema
//
public struct Attribute: LocalizableEntity {
/// The attribute's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<AttributeTranslation>
public init(id: Int, translations: LocaleMap<AttributeTranslation>) {
self.id = id
self.translations = translations
}
}
public struct AttributeTranslation: EntitySubtype {
/// The attribute's name.
public let name: NonEmptyString
/// The abbreviation of the attribute's name.
public let abbreviation: NonEmptyString
/// The description of the attribute.
public let description: NonEmptyString
public init(name: NonEmptyString, abbreviation: NonEmptyString, description: NonEmptyString) {
self.name = name
self.abbreviation = abbreviation
self.description = description
}
}
@@ -1,180 +0,0 @@
//
// Blessing.swift
// OptolithDatabaseSchema
//
public struct Blessing: LocalizableEntity {
/// The blessing's identifier. An unique, increasing integer.
public let id: Int
/// Measurable parameters of a blessing.
public let parameters: BlessingPerformanceParameters
/// The target category the kind of creature or object the skill affects.
public let `target`: AffectedTargetCategories
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<BlessingTranslation>
public init(id: Int, parameters: BlessingPerformanceParameters, `target`: AffectedTargetCategories, src: PublicationRefs, translations: LocaleMap<BlessingTranslation>) {
self.id = id
self.parameters = parameters
self.`target` = `target`
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case parameters = "parameters"
case `target` = "target"
case src = "src"
case translations = "translations"
}
}
public struct BlessingTranslation: EntitySubtype {
/// The name of the blessing.
public let name: String
/// The effect description.
public let effect: String
@available(*, deprecated)
public let range: String
@available(*, deprecated)
public let duration: String
@available(*, deprecated)
public let `target`: String
public let errata: Errata?
public init(name: String, effect: String, range: String, duration: String, `target`: String, errata: Errata? = nil) {
self.name = name
self.effect = effect
self.range = range
self.duration = duration
self.`target` = `target`
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case effect = "effect"
case range = "range"
case duration = "duration"
case `target` = "target"
case errata = "errata"
}
}
/// Measurable parameters of a blessing.
public struct BlessingPerformanceParameters: EntitySubtype {
public let range: BlessingRange
public let duration: BlessingDuration
public init(range: BlessingRange, duration: BlessingDuration) {
self.range = range
self.duration = duration
}
}
public enum BlessingRange: EntitySubtype {
case `self`
case touch
case fixed(FixedRange)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case `self` = "self"
case touch = "touch"
case fixed = "fixed"
}
private enum Discriminator: String, Decodable {
case `self` = "Self"
case touch = "Touch"
case fixed = "Fixed"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .`self`:
self = .`self`
case .touch:
self = .touch
case .fixed:
self = .fixed(try container.decode(FixedRange.self, forKey: .fixed))
}
}
}
public enum BlessingDuration: EntitySubtype {
case immediate
case fixed(FixedBlessingDuration)
case indefinite(IndefiniteBlessingDuration)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case immediate = "immediate"
case fixed = "fixed"
case indefinite = "indefinite"
}
private enum Discriminator: String, Decodable {
case immediate = "Immediate"
case fixed = "Fixed"
case indefinite = "Indefinite"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .immediate:
self = .immediate
case .fixed:
self = .fixed(try container.decode(FixedBlessingDuration.self, forKey: .fixed))
case .indefinite:
self = .indefinite(try container.decode(IndefiniteBlessingDuration.self, forKey: .indefinite))
}
}
}
public struct FixedBlessingDuration: EntitySubtype {
/// The (unitless) duration.
public let value: Int
/// The duration unit.
public let unit: DurationUnit
public init(value: Int, unit: DurationUnit) {
self.value = value
self.unit = unit
}
}
public struct IndefiniteBlessingDuration: EntitySubtype {
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<IndefiniteBlessingDurationTranslation>
public init(translations: LocaleMap<IndefiniteBlessingDurationTranslation>) {
self.translations = translations
}
}
public struct IndefiniteBlessingDurationTranslation: EntitySubtype {
/// A description of the duration.
public let description: ResponsiveText
public init(description: ResponsiveText) {
self.description = description
}
}
@@ -1,303 +0,0 @@
//
// Cantrip.swift
// OptolithDatabaseSchema
//
public struct Cantrip: LocalizableEntity {
/// The cantrip's identifier. An unique, increasing integer.
public let id: Int
/// Measurable parameters of a cantrip.
public let parameters: CantripPerformanceParameters
/// The target category the kind of creature or object the skill affects.
public let `target`: AffectedTargetCategories
/// The associated property.
public let property: PropertyReference
/// A note specifying the dissemination of the cantrip in different traditions. Sometimes a cantrip is exclusively available to one or more specific traditions, but usually one the academies and traditions are listed the cantrip is most commonly teached in.
public let note: CantripNote?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<CantripTranslation>
public let enhancements: Enhancements?
public init(id: Int, parameters: CantripPerformanceParameters, `target`: AffectedTargetCategories, property: PropertyReference, note: CantripNote? = nil, src: PublicationRefs, translations: LocaleMap<CantripTranslation>, enhancements: Enhancements? = nil) {
self.id = id
self.parameters = parameters
self.`target` = `target`
self.property = property
self.note = note
self.src = src
self.translations = translations
self.enhancements = enhancements
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case parameters = "parameters"
case `target` = "target"
case property = "property"
case note = "note"
case src = "src"
case translations = "translations"
case enhancements = "enhancements"
}
}
public enum CantripNote: EntitySubtype {
case exclusive(ExclusiveCantripNote)
case common(CommonCantripNotes)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case exclusive = "exclusive"
case common = "common"
}
private enum Discriminator: String, Decodable {
case exclusive = "Exclusive"
case common = "Common"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .exclusive:
self = .exclusive(try container.decode(ExclusiveCantripNote.self, forKey: .exclusive))
case .common:
self = .common(try container.decode(CommonCantripNotes.self, forKey: .common))
}
}
}
public struct ExclusiveCantripNote: EntitySubtype {
/// The traditions the cantrip is exclusively available to.
public let traditions: [MagicalTraditionReference]
public init(traditions: [MagicalTraditionReference]) {
self.traditions = traditions
}
}
public struct CommonCantripNotes: EntitySubtype {
/// The academies and traditions the cantrip is commonly teached in.
public let list: [CommonCantripNote]
public init(list: [CommonCantripNote]) {
self.list = list
}
}
public enum CommonCantripNote: EntitySubtype {
case academy(CurriculumReference)
case tradition(CommonCantripTraditionNote)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case academy = "academy"
case tradition = "tradition"
}
private enum Discriminator: String, Decodable {
case academy = "Academy"
case tradition = "Tradition"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .academy:
self = .academy(try container.decode(CurriculumReference.self, forKey: .academy))
case .tradition:
self = .tradition(try container.decode(CommonCantripTraditionNote.self, forKey: .tradition))
}
}
}
public struct CommonCantripTraditionNote: EntitySubtype {
/// The magical tradition's identifier.
public let id: MagicalTraditionIdentifier
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<CommonCantripTraditionNoteTranslation>?
public init(id: MagicalTraditionIdentifier, translations: LocaleMap<CommonCantripTraditionNoteTranslation>? = nil) {
self.id = id
self.translations = translations
}
}
public struct CommonCantripTraditionNoteTranslation: EntitySubtype {
/// A note, appended to the generated string in parenthesis.
public let note: String
public init(note: String) {
self.note = note
}
}
public struct CantripTranslation: EntitySubtype {
/// The name of the spell.
public let name: String
/// The effect description.
public let effect: String
@available(*, deprecated)
public let range: String
@available(*, deprecated)
public let duration: String
@available(*, deprecated)
public let `target`: String
public let errata: Errata?
public init(name: String, effect: String, range: String, duration: String, `target`: String, errata: Errata? = nil) {
self.name = name
self.effect = effect
self.range = range
self.duration = duration
self.`target` = `target`
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case effect = "effect"
case range = "range"
case duration = "duration"
case `target` = "target"
case errata = "errata"
}
}
/// Measurable parameters of a blessing.
public struct CantripPerformanceParameters: EntitySubtype {
public let range: CantripRange
public let duration: CantripDuration
public init(range: CantripRange, duration: CantripDuration) {
self.range = range
self.duration = duration
}
}
public enum CantripRange: EntitySubtype {
case `self`
case touch
case fixed(FixedRange)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case `self` = "self"
case touch = "touch"
case fixed = "fixed"
}
private enum Discriminator: String, Decodable {
case `self` = "Self"
case touch = "Touch"
case fixed = "Fixed"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .`self`:
self = .`self`
case .touch:
self = .touch
case .fixed:
self = .fixed(try container.decode(FixedRange.self, forKey: .fixed))
}
}
}
public enum CantripDuration: EntitySubtype {
case immediate
case fixed(FixedCantripDuration)
case duringLovemaking(CastingTimeDuringLovemaking)
case indefinite(IndefiniteCantripDuration)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case immediate = "immediate"
case fixed = "fixed"
case duringLovemaking = "during_lovemaking"
case indefinite = "indefinite"
}
private enum Discriminator: String, Decodable {
case immediate = "Immediate"
case fixed = "Fixed"
case duringLovemaking = "DuringLovemaking"
case indefinite = "Indefinite"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .immediate:
self = .immediate
case .fixed:
self = .fixed(try container.decode(FixedCantripDuration.self, forKey: .fixed))
case .duringLovemaking:
self = .duringLovemaking(try container.decode(CastingTimeDuringLovemaking.self, forKey: .duringLovemaking))
case .indefinite:
self = .indefinite(try container.decode(IndefiniteCantripDuration.self, forKey: .indefinite))
}
}
}
public struct FixedCantripDuration: EntitySubtype {
/// If `true`, the duration is a maximum duration.
public let isMaximum: Bool?
/// The (unitless) duration.
public let value: Int
/// The duration unit.
public let unit: DurationUnit
public init(isMaximum: Bool? = nil, value: Int, unit: DurationUnit) {
self.isMaximum = isMaximum
self.value = value
self.unit = unit
}
private enum CodingKeys: String, CodingKey {
case isMaximum = "is_maximum"
case value = "value"
case unit = "unit"
}
}
public struct IndefiniteCantripDuration: EntitySubtype {
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<IndefiniteCantripDurationTranslation>
public init(translations: LocaleMap<IndefiniteCantripDurationTranslation>) {
self.translations = translations
}
}
public struct IndefiniteCantripDurationTranslation: EntitySubtype {
/// A description of the duration.
public let description: ResponsiveText
public init(description: ResponsiveText) {
self.description = description
}
}
@@ -1,116 +0,0 @@
//
// Ceremony.swift
// OptolithDatabaseSchema
//
public struct Ceremony: LocalizableEntity {
/// The ceremony's identifier. An unique, increasing integer.
public let id: Int
/// Lists the linked three attributes used to make a skill check.
public let check: SkillCheck
/// In some cases, the target's Spirit or Toughness is applied as a penalty.
public let checkPenalty: SkillCheckPenalty?
/// Measurable parameters of a ceremony.
public let parameters: SlowPerformanceParameters
/// The target category the kind of creature or object the skill affects.
public let `target`: AffectedTargetCategories
/// The tradition(s) the ceremony is available for. Note that general aspects do not have an associated tradition and thus need to be defined in a special way.
public let traditions: [SkillTradition]
/// States which column is used to improve the skill.
public let improvementCost: ImprovementCost
public let prerequisites: LiturgyPrerequisites?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<CeremonyTranslation>
public let enhancements: Enhancements?
public init(id: Int, check: SkillCheck, checkPenalty: SkillCheckPenalty? = nil, parameters: SlowPerformanceParameters, `target`: AffectedTargetCategories, traditions: [SkillTradition], improvementCost: ImprovementCost, prerequisites: LiturgyPrerequisites? = nil, src: PublicationRefs, translations: LocaleMap<CeremonyTranslation>, enhancements: Enhancements? = nil) {
self.id = id
self.check = check
self.checkPenalty = checkPenalty
self.parameters = parameters
self.`target` = `target`
self.traditions = traditions
self.improvementCost = improvementCost
self.prerequisites = prerequisites
self.src = src
self.translations = translations
self.enhancements = enhancements
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case check = "check"
case checkPenalty = "check_penalty"
case parameters = "parameters"
case `target` = "target"
case traditions = "traditions"
case improvementCost = "improvement_cost"
case prerequisites = "prerequisites"
case src = "src"
case translations = "translations"
case enhancements = "enhancements"
}
}
public struct CeremonyTranslation: EntitySubtype {
/// The name of the ceremony.
public let name: NonEmptyString
/// A compressed name of the ceremony for use in small areas (e.g. on character sheet). Should only be defined if the `name` does not fit on character sheet.
public let nameCompressed: NonEmptyString?
/// The effect description may be either a plain text or a text that is divided by a list of effects for each quality level. It may also be a list for each two quality levels.
public let effect: ActivatableSkillEffect
@available(*, deprecated)
public let castingTime: OldParameter
@available(*, deprecated)
public let cost: OldParameter
@available(*, deprecated)
public let range: OldParameter
@available(*, deprecated)
public let duration: OldParameter
@available(*, deprecated)
public let `target`: String
public let errata: Errata?
public init(name: NonEmptyString, nameCompressed: NonEmptyString? = nil, effect: ActivatableSkillEffect, castingTime: OldParameter, cost: OldParameter, range: OldParameter, duration: OldParameter, `target`: String, errata: Errata? = nil) {
self.name = name
self.nameCompressed = nameCompressed
self.effect = effect
self.castingTime = castingTime
self.cost = cost
self.range = range
self.duration = duration
self.`target` = `target`
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case nameCompressed = "name_compressed"
case effect = "effect"
case castingTime = "casting_time"
case cost = "cost"
case range = "range"
case duration = "duration"
case `target` = "target"
case errata = "errata"
}
}
@@ -1,91 +0,0 @@
//
// CombatTechnique_Close.swift
// OptolithDatabaseSchema
//
public struct CloseCombatTechnique: LocalizableEntity {
/// The close combat technique's identifier. An unique, increasing integer.
public let id: Int
/// Special rules for the combat technique that apply to all weapons in this category.
public let special: CloseCombatTechniqueSpecialRules
/// The primary attribute(s).
public let primaryAttribute: [AttributeReference]
/// The *Breaking Point Rating* of the respective combat technique.
public let breakingPointRating: Int
public let improvementCost: ImprovementCost
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<CloseCombatTechniqueTranslation>
public init(id: Int, special: CloseCombatTechniqueSpecialRules, primaryAttribute: [AttributeReference], breakingPointRating: Int, improvementCost: ImprovementCost, src: PublicationRefs, translations: LocaleMap<CloseCombatTechniqueTranslation>) {
self.id = id
self.special = special
self.primaryAttribute = primaryAttribute
self.breakingPointRating = breakingPointRating
self.improvementCost = improvementCost
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case special = "special"
case primaryAttribute = "primary_attribute"
case breakingPointRating = "breaking_point_rating"
case improvementCost = "improvement_cost"
case src = "src"
case translations = "translations"
}
}
/// Special rules for the combat technique that apply to all weapons in this category.
public struct CloseCombatTechniqueSpecialRules: EntitySubtype {
/// Is parrying possible with this combat technique?
public let canParry: Bool
public let hasDamageThreshold: Bool
public let hasReach: Bool
public let hasLength: Bool
public let hasShieldSize: Bool
public init(canParry: Bool, hasDamageThreshold: Bool, hasReach: Bool, hasLength: Bool, hasShieldSize: Bool) {
self.canParry = canParry
self.hasDamageThreshold = hasDamageThreshold
self.hasReach = hasReach
self.hasLength = hasLength
self.hasShieldSize = hasShieldSize
}
private enum CodingKeys: String, CodingKey {
case canParry = "can_parry"
case hasDamageThreshold = "has_damage_threshold"
case hasReach = "has_reach"
case hasLength = "has_length"
case hasShieldSize = "has_shield_size"
}
}
public struct CloseCombatTechniqueTranslation: EntitySubtype {
/// The name of the condition.
public let name: String
/// Additional rules for the condition, if applicable.
public let special: String?
public let errata: Errata?
public init(name: String, special: String? = nil, errata: Errata? = nil) {
self.name = name
self.special = special
self.errata = errata
}
}
@@ -1,74 +0,0 @@
//
// CombatTechnique_Ranged.swift
// OptolithDatabaseSchema
//
public struct RangedCombatTechnique: LocalizableEntity {
/// The ranged combat technique's identifier. An unique, increasing integer.
public let id: Int
/// Special rules for the combat technique that apply to all weapons in this category.
public let special: RangedCombatTechniqueSpecialRules
/// The primary attribute(s).
public let primaryAttribute: [AttributeReference]
/// The *Breaking Point Rating* of the respective combat technique.
public let breakingPointRating: Int
public let improvementCost: ImprovementCost
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<RangedCombatTechniqueTranslation>
public init(id: Int, special: RangedCombatTechniqueSpecialRules, primaryAttribute: [AttributeReference], breakingPointRating: Int, improvementCost: ImprovementCost, src: PublicationRefs, translations: LocaleMap<RangedCombatTechniqueTranslation>) {
self.id = id
self.special = special
self.primaryAttribute = primaryAttribute
self.breakingPointRating = breakingPointRating
self.improvementCost = improvementCost
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case special = "special"
case primaryAttribute = "primary_attribute"
case breakingPointRating = "breaking_point_rating"
case improvementCost = "improvement_cost"
case src = "src"
case translations = "translations"
}
}
/// Special rules for the combat technique that apply to all weapons in this category.
public struct RangedCombatTechniqueSpecialRules: EntitySubtype {
public let hasAmmunition: Bool
public init(hasAmmunition: Bool) {
self.hasAmmunition = hasAmmunition
}
private enum CodingKeys: String, CodingKey {
case hasAmmunition = "has_ammunition"
}
}
public struct RangedCombatTechniqueTranslation: EntitySubtype {
/// The name of the condition.
public let name: String
/// Additional rules for the condition, if applicable.
public let special: String?
public let errata: Errata?
public init(name: String, special: String? = nil, errata: Errata? = nil) {
self.name = name
self.special = special
self.errata = errata
}
}
@@ -1,40 +0,0 @@
//
// Condition.swift
// OptolithDatabaseSchema
//
public struct Condition: LocalizableEntity {
/// The condition's identifier. An unique, increasing integer.
public let id: Int
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ConditionTranslation>
public init(id: Int, src: PublicationRefs, translations: LocaleMap<ConditionTranslation>) {
self.id = id
self.src = src
self.translations = translations
}
}
public struct ConditionTranslation: EntitySubtype {
/// The condition's name.
public let name: NonEmptyString
/// Additional rules for the condition, if applicable.
public let rules: NonEmptyMarkdown?
/// The effects for level 1 to 4.
public let effects: [NonEmptyMarkdown]
public let errata: Errata?
public init(name: NonEmptyString, rules: NonEmptyMarkdown? = nil, effects: [NonEmptyMarkdown], errata: Errata? = nil) {
self.name = name
self.rules = rules
self.effects = effects
self.errata = errata
}
}
@@ -1,27 +0,0 @@
//
// Continent.swift
// OptolithDatabaseSchema
//
/// Continents are mostly referenced to in languages and scripts that occur on a specific continent.
public struct Continent: LocalizableEntity {
/// The continent's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ContinentTranslation>
public init(id: Int, translations: LocaleMap<ContinentTranslation>) {
self.id = id
self.translations = translations
}
}
public struct ContinentTranslation: EntitySubtype {
/// The continent name.
public let name: String
public init(name: String) {
self.name = name
}
}
@@ -1,480 +0,0 @@
//
// Culture.swift
// OptolithDatabaseSchema
//
public struct Culture: LocalizableEntity {
/// An unique, increasing integer.
public let id: Int
/// A list of native languages (usually it is only one).
public let language: [LanguageReference]
/// A list of native scripts (usually it is only one). If the culture does not use any script, leave this field empty.
public let script: [ScriptReference]?
/// If the area knowledge has a fixed value or can be adjusted.
public let areaKnowledge: AreaKnowledge
/// A list of possible social status in the respective culture.
public let socialStatus: [SocialStatusReference]
/// A list of professions that are typical for the culture, as well as professions that are rarely practiced or encountered in the culture. The list is either defined by group (as multiple lists) or plain (as a single list).
public let commonProfessions: CommonProfessions
/// A list of common advantages.
public let commonAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]?
/// A list of common disadvantages.
public let commonDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]?
/// A list of uncommon advantages.
public let uncommonAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]?
/// A list of uncommon disadvantages.
public let uncommonDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]?
/// A list of common skills.
public let commonSkills: [CommonnessRatedSkill]
/// A list of uncommon skills.
public let uncommonSkills: [CommonnessRatedSkill]?
/// The skill points you get for buying the culture package.
public let culturalPackage: [CulturalPackageItem]
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<CultureTranslation>
public init(id: Int, language: [LanguageReference], script: [ScriptReference]? = nil, areaKnowledge: AreaKnowledge, socialStatus: [SocialStatusReference], commonProfessions: CommonProfessions, commonAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]? = nil, commonDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]? = nil, uncommonAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]? = nil, uncommonDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]? = nil, commonSkills: [CommonnessRatedSkill], uncommonSkills: [CommonnessRatedSkill]? = nil, culturalPackage: [CulturalPackageItem], src: PublicationRefs, translations: LocaleMap<CultureTranslation>) {
self.id = id
self.language = language
self.script = script
self.areaKnowledge = areaKnowledge
self.socialStatus = socialStatus
self.commonProfessions = commonProfessions
self.commonAdvantages = commonAdvantages
self.commonDisadvantages = commonDisadvantages
self.uncommonAdvantages = uncommonAdvantages
self.uncommonDisadvantages = uncommonDisadvantages
self.commonSkills = commonSkills
self.uncommonSkills = uncommonSkills
self.culturalPackage = culturalPackage
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case language = "language"
case script = "script"
case areaKnowledge = "area_knowledge"
case socialStatus = "social_status"
case commonProfessions = "common_professions"
case commonAdvantages = "common_advantages"
case commonDisadvantages = "common_disadvantages"
case uncommonAdvantages = "uncommon_advantages"
case uncommonDisadvantages = "uncommon_disadvantages"
case commonSkills = "common_skills"
case uncommonSkills = "uncommon_skills"
case culturalPackage = "cultural_package"
case src = "src"
case translations = "translations"
}
}
/// If the area knowledge has a fixed value or can be adjusted.
public struct AreaKnowledge: EntitySubtype {
/// `true` if the area knowledge has a fixed value, `false` if it can be
/// adjusted.
public let isFixed: Bool
public init(isFixed: Bool) {
self.isFixed = isFixed
}
private enum CodingKeys: String, CodingKey {
case isFixed = "is_fixed"
}
}
/// The "weight" difference compared to other professions or profession variants. Some professions or profession variants are simply more common (Mostly), but sometimes only specific elements are used (Only).
public enum CommonnessWeight: String, EntitySubtype {
case mostly = "Mostly"
case only = "Only"
}
/// Some professions or profession variants are more common than others. There may be cultures where some professions or profession variants are not represented at all.
public struct Weighted<ProfessionOrVariant: EntitySubtype>: EntitySubtype {
/// The list of more common professions or profession variants.
public let elements: [ProfessionOrVariant]
/// The "weight" difference compared to other professions or profession variants. Some professions or profession variants are simply more common
/// (Mostly), but sometimes only specific elements are used (Only).
public let weight: CommonnessWeight
public init(elements: [ProfessionOrVariant], weight: CommonnessWeight) {
self.elements = elements
self.weight = weight
}
}
/// This defines how the list of constraints should be offset against the list of all mundane professions: Either only the professions are kept that intersect with the constraints (include) or only the professions are kept that are different from the constraints (exclude).
public enum CommonProfessionConstraintsOperation: String, EntitySubtype {
case intersection = "Intersection"
case difference = "Difference"
}
/// A list of professions. The filter specifies how the list is applied to all mundane professions.
public struct CommonProfessionConstraints<Constraint: EntitySubtype>: EntitySubtype {
/// The list of constraints.
public let constraints: [Constraint]
/// This defines how the list of constraints should be offset against the list of all mundane professions: Either only the professions are kept that intersect with the constraints (include) or only the professions are kept that are different from the constraints (exclude).
public let operation: CommonProfessionConstraintsOperation
public init(constraints: [Constraint], operation: CommonProfessionConstraintsOperation) {
self.constraints = constraints
self.operation = operation
}
}
/// Some professions may be found in a culture, but are not that common.
public enum Rarity: String, EntitySubtype {
case rare = "Rare"
case veryRare = "VeryRare"
}
public struct ProfessionConstraint: EntitySubtype {
/// The profession's identifier.
public let id: ProfessionIdentifier
/// Some profession variants are more common than others. There may be cultures where some variants are not represented at all.
public let weightedVariants: Weighted<ProfessionVariantReference>?
/// Some professions may be found in a culture, but are not that common.
public let rarity: Rarity?
public init(id: ProfessionIdentifier, weightedVariants: Weighted<ProfessionVariantReference>? = nil, rarity: Rarity? = nil) {
self.id = id
self.weightedVariants = weightedVariants
self.rarity = rarity
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case weightedVariants = "weighted_variants"
case rarity = "rarity"
}
}
/// Some professions may be found in a culture, but are not that common.
public enum MundaneProfessionSubgroupConstraint: String, EntitySubtype {
case profane = "Profane"
case fighter = "Fighter"
case religious = "Religious"
}
public struct MagicalTraditionConstraint: EntitySubtype {
/// The magical tradition's identifier.
public let id: MagicalTraditionIdentifier
/// Some professions are more common than others. There may be cultures where some professions are not represented at all.
public let weightedProfessions: Weighted<ProfessionReference>?
/// Some traditions may be found in a culture, but are not that common.
public let rarity: Rarity?
public init(id: MagicalTraditionIdentifier, weightedProfessions: Weighted<ProfessionReference>? = nil, rarity: Rarity? = nil) {
self.id = id
self.weightedProfessions = weightedProfessions
self.rarity = rarity
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case weightedProfessions = "weighted_professions"
case rarity = "rarity"
}
}
public struct BlessedTraditionConstraint: EntitySubtype {
/// The magical tradition's identifier.
public let id: BlessedTraditionIdentifier
/// Some professions are more common than others. There may be cultures where some professions are not represented at all.
public let weightedProfessions: Weighted<ProfessionReference>?
/// Some traditions may be found in a culture, but are not that common.
public let rarity: Rarity?
public init(id: BlessedTraditionIdentifier, weightedProfessions: Weighted<ProfessionReference>? = nil, rarity: Rarity? = nil) {
self.id = id
self.weightedProfessions = weightedProfessions
self.rarity = rarity
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case weightedProfessions = "weighted_professions"
case rarity = "rarity"
}
}
public enum MundaneCommonProfessionConstraint: EntitySubtype {
case profession(ProfessionConstraint)
case professionSubgroup(MundaneProfessionSubgroupConstraint)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case profession = "profession"
case professionSubgroup = "profession_subgroup"
}
private enum Discriminator: String, Decodable {
case profession = "Profession"
case professionSubgroup = "ProfessionSubgroup"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .profession:
self = .profession(try container.decode(ProfessionConstraint.self, forKey: .profession))
case .professionSubgroup:
self = .professionSubgroup(try container.decode(MundaneProfessionSubgroupConstraint.self, forKey: .professionSubgroup))
}
}
}
public enum MagicCommonProfessionConstraint: EntitySubtype {
case tradition(MagicalTraditionConstraint)
case magicDilettante
case profession(ProfessionConstraint)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case tradition = "tradition"
case magicDilettante = "magic_dilettante"
case profession = "profession"
}
private enum Discriminator: String, Decodable {
case tradition = "Tradition"
case magicDilettante = "MagicDilettante"
case profession = "Profession"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .tradition:
self = .tradition(try container.decode(MagicalTraditionConstraint.self, forKey: .tradition))
case .magicDilettante:
self = .magicDilettante
case .profession:
self = .profession(try container.decode(ProfessionConstraint.self, forKey: .profession))
}
}
}
public struct BlessedCommonProfessionConstraint: EntitySubtype {
public let tag: String
public let tradition: BlessedTraditionConstraint
public init(tag: String, tradition: BlessedTraditionConstraint) {
self.tag = tag
self.tradition = tradition
}
}
public typealias PlainCommonProfessions = CommonProfessionConstraints<ProfessionReference>
/// Lists of professions by group.
public struct GroupedCommonProfessions: EntitySubtype {
public let mundane: CommonProfessionConstraints<MundaneCommonProfessionConstraint>?
public let magic: CommonProfessionConstraints<MagicCommonProfessionConstraint>?
public let blessed: CommonProfessionConstraints<BlessedCommonProfessionConstraint>?
public init(mundane: CommonProfessionConstraints<MundaneCommonProfessionConstraint>? = nil, magic: CommonProfessionConstraints<MagicCommonProfessionConstraint>? = nil, blessed: CommonProfessionConstraints<BlessedCommonProfessionConstraint>? = nil) {
self.mundane = mundane
self.magic = magic
self.blessed = blessed
}
}
/// A list of professions that are typical for the culture, as well as professions that are rarely practiced or encountered in the culture. The list is either defined by group (as multiple lists) or plain (as a single list).
public enum CommonProfessions: EntitySubtype {
case plain(PlainCommonProfessions)
case grouped(GroupedCommonProfessions)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case plain = "plain"
case grouped = "grouped"
}
private enum Discriminator: String, Decodable {
case plain = "Plain"
case grouped = "Grouped"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .plain:
self = .plain(try container.decode(PlainCommonProfessions.self, forKey: .plain))
case .grouped:
self = .grouped(try container.decode(GroupedCommonProfessions.self, forKey: .grouped))
}
}
}
public typealias CommonnessRatedSkill = SkillReference
public struct CulturalPackageItem: EntitySubtype {
/// The skill's identifier.
public let id: SkillIdentifier
/// The skill points for the respective skill you get for buying the cultural package.
public let points: Int
public init(id: SkillIdentifier, points: Int) {
self.id = id
self.points = points
}
}
public struct CultureTranslation: EntitySubtype {
/// The name of the state.
public let name: String
/// The description of the area knowledge.
public let areaKnowledge: AreaKnowledgeTranslation
/// The respective common advantages text from the source book.
public let commonAdvantages: NonEmptyString?
/// The respective common disadvantages text from the source book.
public let commonDisadvantages: NonEmptyString?
/// The respective uncommon advantages text from the source book.
public let uncommonAdvantages: NonEmptyString?
/// The respective uncommon disadvantages text from the source book.
public let uncommonDisadvantages: NonEmptyString?
/// Structured description of common names.
public let commonNames: CommonNames
public let errata: Errata?
public init(name: String, areaKnowledge: AreaKnowledgeTranslation, commonAdvantages: NonEmptyString? = nil, commonDisadvantages: NonEmptyString? = nil, uncommonAdvantages: NonEmptyString? = nil, uncommonDisadvantages: NonEmptyString? = nil, commonNames: CommonNames, errata: Errata? = nil) {
self.name = name
self.areaKnowledge = areaKnowledge
self.commonAdvantages = commonAdvantages
self.commonDisadvantages = commonDisadvantages
self.uncommonAdvantages = uncommonAdvantages
self.uncommonDisadvantages = uncommonDisadvantages
self.commonNames = commonNames
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case areaKnowledge = "area_knowledge"
case commonAdvantages = "common_advantages"
case commonDisadvantages = "common_disadvantages"
case uncommonAdvantages = "uncommon_advantages"
case uncommonDisadvantages = "uncommon_disadvantages"
case commonNames = "common_names"
case errata = "errata"
}
}
/// Description and examples of the area knowledge.
public struct AreaKnowledgeTranslation: EntitySubtype {
/// The full description without examples in parenthesis.
public let description: String
/// A shorter version of the description, used in input fields and other UI elements where the space might be to small to use the full description.
public let abbreviated: String
/// Examples of areas, if applicable.
public let examples: [AreaKnowledgeExample]?
public init(description: String, abbreviated: String, examples: [AreaKnowledgeExample]? = nil) {
self.description = description
self.abbreviated = abbreviated
self.examples = examples
}
}
public struct AreaKnowledgeExample: EntitySubtype {
public let area: String
public init(area: String) {
self.area = area
}
}
/// Structured description of common names.
public struct CommonNames: EntitySubtype {
/// First names can be gender-neutral, but they can also be for a specific binary sex. They are sorted into groups.
public let firstNameGroups: [CommonNameGroup]?
/// Last names can be gender-neutral, like family names, but they can also be for a specific binary sex. They are sorted into groups.
public let lastNameGroups: [CommonNameGroup]?
/// Special naming rules.
public let namingRules: NonEmptyString?
public init(firstNameGroups: [CommonNameGroup]? = nil, lastNameGroups: [CommonNameGroup]? = nil, namingRules: NonEmptyString? = nil) {
self.firstNameGroups = firstNameGroups
self.lastNameGroups = lastNameGroups
self.namingRules = namingRules
}
private enum CodingKeys: String, CodingKey {
case firstNameGroups = "first_name_groups"
case lastNameGroups = "last_name_groups"
case namingRules = "naming_rules"
}
}
public struct CommonNameGroup: EntitySubtype {
/// The group label.
public let label: NonEmptyString
/// The binary sex if the group is only for a certain binary sex.
public let sex: BinarySex?
/// The names from the group.
public let names: [CommonName]
public init(label: NonEmptyString, sex: BinarySex? = nil, names: [CommonName]) {
self.label = label
self.sex = sex
self.names = names
}
}
public struct CommonName: EntitySubtype {
public let name: NonEmptyString
/// Additional information about the name, appended in parenthesis.
public let note: NonEmptyString?
public init(name: NonEmptyString, note: NonEmptyString? = nil) {
self.name = name
self.note = note
}
}
@@ -1,64 +0,0 @@
//
// DerivedCharacteristic.swift
// OptolithDatabaseSchema
//
public struct DerivedCharacteristic: LocalizableEntity {
/// An unique, increasing integer.
public let id: Int
public let prerequisites: DerivedCharacteristicPrerequisites?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DerivedCharacteristicTranslation>
public init(id: Int, prerequisites: DerivedCharacteristicPrerequisites? = nil, src: PublicationRefs, translations: LocaleMap<DerivedCharacteristicTranslation>) {
self.id = id
self.prerequisites = prerequisites
self.src = src
self.translations = translations
}
}
public struct DerivedCharacteristicTranslation: EntitySubtype {
/// The characteristic's name.
public let name: String
/// The characteristic's abbreviation.
public let abbreviation: String
/// Possible calculation strings for the final value.
public let calculation: CalculationTranslation?
public init(name: String, abbreviation: String, calculation: CalculationTranslation? = nil) {
self.name = name
self.abbreviation = abbreviation
self.calculation = calculation
}
}
/// Possible calculation strings for the final value.
public struct CalculationTranslation: EntitySubtype {
/// The default calculation string.
public let `default`: String
/// The calculation string if only half of the primary attribute is used.
public let halfPrimary: String?
/// The calculation string if no primary attribute is used.
public let noPrimary: String?
public init(`default`: String, halfPrimary: String? = nil, noPrimary: String? = nil) {
self.`default` = `default`
self.halfPrimary = halfPrimary
self.noPrimary = noPrimary
}
private enum CodingKeys: String, CodingKey {
case `default` = "default"
case halfPrimary = "half_primary"
case noPrimary = "no_primary"
}
}
@@ -1,94 +0,0 @@
//
// Disadvantage.swift
// OptolithDatabaseSchema
//
public struct Disadvantage: LocalizableEntity {
public let id: Id
public let levels: Levels?
public let selectOptions: SelectOptions?
public let maximum: Maximum?
public let prerequisites: AdvantageDisadvantagePrerequisites?
public let apValue: AdventurePointsValue
/// Does this disadvantage count towards the maximum of AP to be spent on disadvantages?
public let hasMaximumSpentInfluence: Bool
/// Does this disadvantage exclusively applies to arcane spellworks and not to magical actions and magical applications?
public let isExclusiveToArcaneSpellworks: Bool
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DisadvantageTranslation>
public init(id: Id, levels: Levels? = nil, selectOptions: SelectOptions? = nil, maximum: Maximum? = nil, prerequisites: AdvantageDisadvantagePrerequisites? = nil, apValue: AdventurePointsValue, hasMaximumSpentInfluence: Bool, isExclusiveToArcaneSpellworks: Bool, src: PublicationRefs, translations: LocaleMap<DisadvantageTranslation>) {
self.id = id
self.levels = levels
self.selectOptions = selectOptions
self.maximum = maximum
self.prerequisites = prerequisites
self.apValue = apValue
self.hasMaximumSpentInfluence = hasMaximumSpentInfluence
self.isExclusiveToArcaneSpellworks = isExclusiveToArcaneSpellworks
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case levels = "levels"
case selectOptions = "select_options"
case maximum = "maximum"
case prerequisites = "prerequisites"
case apValue = "ap_value"
case hasMaximumSpentInfluence = "has_maximum_spent_influence"
case isExclusiveToArcaneSpellworks = "is_exclusive_to_arcane_spellworks"
case src = "src"
case translations = "translations"
}
}
public struct DisadvantageTranslation: EntitySubtype {
public let name: Name
public let nameInLibrary: NameInLibrary?
/// A string that is used as a label for an input field.
public let input: Input?
public let rules: Rules
/// The range.
public let range: String?
/// A string that gets appended to the default AP Value text with a preceding space. This always happens if present, even if the generated AP Value text is replaced.
public let apValueAppend: AdventurePointsValueAppend?
public let errata: Errata?
public init(name: Name, nameInLibrary: NameInLibrary? = nil, input: Input? = nil, rules: Rules, range: String? = nil, apValueAppend: AdventurePointsValueAppend? = nil, errata: Errata? = nil) {
self.name = name
self.nameInLibrary = nameInLibrary
self.input = input
self.rules = rules
self.range = range
self.apValueAppend = apValueAppend
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case nameInLibrary = "name_in_library"
case input = "input"
case rules = "rules"
case range = "range"
case apValueAppend = "ap_value_append"
case errata = "errata"
}
}
@@ -1,32 +0,0 @@
//
// Disease.swift
// OptolithDatabaseSchema
//
public struct Disease: LocalizableEntity {
/// The disease's identifier. An unique, increasing integer.
public let id: Int
/// The disease's level.
public let level: Int
/// Depending on the disease, apply Spirit or Toughness as a penalty to the disease roll. It may also happen that the lower of both is applied as a penalty.
public let resistance: Resistance
/// What causes the disease? The GM rolls 1D20 to see if a character gets infected. If the infection check succeeds, the GM makes a disease check to determine the severity of the infection.
public let cause: [Cause]
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DiseaseTranslation>
public init(id: Int, level: Int, resistance: Resistance, cause: [Cause], src: PublicationRefs, translations: LocaleMap<DiseaseTranslation>) {
self.id = id
self.level = level
self.resistance = resistance
self.cause = cause
self.src = src
self.translations = translations
}
}
@@ -1,26 +0,0 @@
//
// Element.swift
// OptolithDatabaseSchema
//
public struct Element: LocalizableEntity {
/// The element's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ElementTranslation>
public init(id: Int, translations: LocaleMap<ElementTranslation>) {
self.id = id
self.translations = translations
}
}
public struct ElementTranslation: EntitySubtype {
/// The element's name.
public let name: String
public init(name: String) {
self.name = name
}
}
@@ -1,67 +0,0 @@
//
// ExperienceLevel.swift
// OptolithDatabaseSchema
//
/// Adventure Points and maximum values at hero creation.
public struct ExperienceLevel: LocalizableEntity {
/// An unique, increasing integer.
public let id: Int
/// The AP value you get.
public let adventurePoints: Int
/// The highest possible attribute value.
public let maxAttributeValue: Int
/// The highest possible skill rating.
public let maxSkillRating: Int
/// The highest possible combat technique rating.
public let maxCombatTechniqueRating: Int
/// The limit for the sum of all attribute values.
public let maxAttributeTotal: Int
/// The maximum of spells/chants you can activate.
public let maxNumberOfSpellsLiturgicalChants: Int
/// The maximum of spells of an unfamiliar tradition you can activate.
public let maxNumberOfUnfamiliarSpells: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ExperienceLevelTranslation>
public init(id: Int, adventurePoints: Int, maxAttributeValue: Int, maxSkillRating: Int, maxCombatTechniqueRating: Int, maxAttributeTotal: Int, maxNumberOfSpellsLiturgicalChants: Int, maxNumberOfUnfamiliarSpells: Int, translations: LocaleMap<ExperienceLevelTranslation>) {
self.id = id
self.adventurePoints = adventurePoints
self.maxAttributeValue = maxAttributeValue
self.maxSkillRating = maxSkillRating
self.maxCombatTechniqueRating = maxCombatTechniqueRating
self.maxAttributeTotal = maxAttributeTotal
self.maxNumberOfSpellsLiturgicalChants = maxNumberOfSpellsLiturgicalChants
self.maxNumberOfUnfamiliarSpells = maxNumberOfUnfamiliarSpells
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case adventurePoints = "adventure_points"
case maxAttributeValue = "max_attribute_value"
case maxSkillRating = "max_skill_rating"
case maxCombatTechniqueRating = "max_combat_technique_rating"
case maxAttributeTotal = "max_attribute_total"
case maxNumberOfSpellsLiturgicalChants = "max_number_of_spells_liturgical_chants"
case maxNumberOfUnfamiliarSpells = "max_number_of_unfamiliar_spells"
case translations = "translations"
}
}
public struct ExperienceLevelTranslation: EntitySubtype {
/// The name of the experience level.
public let name: String
public init(name: String) {
self.name = name
}
}
@@ -1,26 +0,0 @@
//
// EyeColor.swift
// OptolithDatabaseSchema
//
public struct EyeColor: LocalizableEntity {
/// The eye color's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<EyeColorTranslation>
public init(id: Int, translations: LocaleMap<EyeColorTranslation>) {
self.id = id
self.translations = translations
}
}
public struct EyeColorTranslation: EntitySubtype {
/// The eye color.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,409 +0,0 @@
//
// FamiliarsTrick.swift
// OptolithDatabaseSchema
//
public struct FamiliarsTrick: LocalizableEntity {
/// The familiar's trick's identifier. An unique, increasing integer.
public let id: Int
/// The animal types this trick is available to. Either it is available to all or only a list of specific animal types.
///
/// If no animal types are given, the animal disease applies to all animal types.
public let animalTypes: [AnimalTypeReference]
/// Measurable parameters of a familiar's trick.
public let parameters: FamiliarsTrickPerformanceParameters
/// The property of the trick.
public let property: FamiliarsTrickProperty
/// The AP value the familiar has to pay for. It may also be that a specific is known by all familiar by default. In the latter case the field is not set.
public let apValue: Int?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<FamiliarsTrickTranslation>
public init(id: Int, animalTypes: [AnimalTypeReference], parameters: FamiliarsTrickPerformanceParameters, property: FamiliarsTrickProperty, apValue: Int? = nil, src: PublicationRefs, translations: LocaleMap<FamiliarsTrickTranslation>) {
self.id = id
self.animalTypes = animalTypes
self.parameters = parameters
self.property = property
self.apValue = apValue
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case animalTypes = "animal_types"
case parameters = "parameters"
case property = "property"
case apValue = "ap_value"
case src = "src"
case translations = "translations"
}
}
public enum FamiliarsTrickProperty: EntitySubtype {
case fixed(PropertyReference)
case indefinite(IndefiniteFamiliarsTrickProperty)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case fixed = "fixed"
case indefinite = "indefinite"
}
private enum Discriminator: String, Decodable {
case fixed = "Fixed"
case indefinite = "Indefinite"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .fixed:
self = .fixed(try container.decode(PropertyReference.self, forKey: .fixed))
case .indefinite:
self = .indefinite(try container.decode(IndefiniteFamiliarsTrickProperty.self, forKey: .indefinite))
}
}
}
public struct IndefiniteFamiliarsTrickProperty: EntitySubtype {
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<IndefiniteFamiliarsTrickPropertyTranslation>
public init(translations: LocaleMap<IndefiniteFamiliarsTrickPropertyTranslation>) {
self.translations = translations
}
}
public struct IndefiniteFamiliarsTrickPropertyTranslation: EntitySubtype {
/// A description of the property.
public let description: ResponsiveText
public init(description: ResponsiveText) {
self.description = description
}
}
public struct FamiliarsTrickTranslation: EntitySubtype {
/// The name of the familiar's trick.
public let name: String
/// The effect description.
public let effect: String
@available(*, deprecated)
public let cost: OldParameter
@available(*, deprecated)
public let duration: OldParameter
public let errata: Errata?
public init(name: String, effect: String, cost: OldParameter, duration: OldParameter, errata: Errata? = nil) {
self.name = name
self.effect = effect
self.cost = cost
self.duration = duration
self.errata = errata
}
}
/// Measurable parameters of a familiar's trick.
public enum FamiliarsTrickPerformanceParameters: EntitySubtype {
case oneTime(FamiliarsTrickOneTimePerformanceParameters)
case oneTimeInterval(FamiliarsTrickOneTimeIntervalPerformanceParameters)
case sustained(FamiliarsTrickSustainedPerformanceParameters)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case oneTime = "one_time"
case oneTimeInterval = "one_time_interval"
case sustained = "sustained"
}
private enum Discriminator: String, Decodable {
case oneTime = "OneTime"
case oneTimeInterval = "OneTimeInterval"
case sustained = "Sustained"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .oneTime:
self = .oneTime(try container.decode(FamiliarsTrickOneTimePerformanceParameters.self, forKey: .oneTime))
case .oneTimeInterval:
self = .oneTimeInterval(try container.decode(FamiliarsTrickOneTimeIntervalPerformanceParameters.self, forKey: .oneTimeInterval))
case .sustained:
self = .sustained(try container.decode(FamiliarsTrickSustainedPerformanceParameters.self, forKey: .sustained))
}
}
}
public struct FamiliarsTrickOneTimePerformanceParameters: EntitySubtype {
public let cost: FamiliarsTrickOneTimeCost
public let duration: FamiliarsTrickOneTimeDuration
public init(cost: FamiliarsTrickOneTimeCost, duration: FamiliarsTrickOneTimeDuration) {
self.cost = cost
self.duration = duration
}
}
public enum FamiliarsTrickOneTimeCost: EntitySubtype {
case fixed(FamiliarsTrickFixedOneTimeCost)
case all(FamiliarsTrickAllOneTimeCost)
case indefinite(FamiliarsTrickIndefiniteOneTimeCost)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case fixed = "fixed"
case all = "all"
case indefinite = "indefinite"
}
private enum Discriminator: String, Decodable {
case fixed = "Fixed"
case all = "All"
case indefinite = "Indefinite"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .fixed:
self = .fixed(try container.decode(FamiliarsTrickFixedOneTimeCost.self, forKey: .fixed))
case .all:
self = .all(try container.decode(FamiliarsTrickAllOneTimeCost.self, forKey: .all))
case .indefinite:
self = .indefinite(try container.decode(FamiliarsTrickIndefiniteOneTimeCost.self, forKey: .indefinite))
}
}
}
public struct FamiliarsTrickFixedOneTimeCost: EntitySubtype {
/// The AE cost value.
public let aeValue: Int
/// The LP cost value.
public let lpValue: Int?
/// The interval in which you have to pay the AE cost again.
public let interval: DurationUnitValue?
/// All translations for the entry, identified by IETF language tag
/// (BCP47).
public let translations: LocaleMap<FamiliarsTrickFixedOneTimeCostTranslation>?
public init(aeValue: Int, lpValue: Int? = nil, interval: DurationUnitValue? = nil, translations: LocaleMap<FamiliarsTrickFixedOneTimeCostTranslation>? = nil) {
self.aeValue = aeValue
self.lpValue = lpValue
self.interval = interval
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case aeValue = "ae_value"
case lpValue = "lp_value"
case interval = "interval"
case translations = "translations"
}
}
public struct FamiliarsTrickFixedOneTimeCostTranslation: EntitySubtype {
/// The cost have to be per a specific countable entity, e.g. `8 KP per person`.
public let per: ResponsiveTextOptional?
public init(per: ResponsiveTextOptional? = nil) {
self.per = per
}
}
public struct FamiliarsTrickAllOneTimeCost: EntitySubtype {
/// The minimum AE the familiar has to have.
public let minimum: Int?
public init(minimum: Int? = nil) {
self.minimum = minimum
}
}
public struct FamiliarsTrickIndefiniteOneTimeCost: EntitySubtype {
/// All translations for the entry, identified by IETF language tag
/// (BCP47).
public let translations: LocaleMap<FamiliarsTrickIndefiniteOneTimeCostTranslation>
public init(translations: LocaleMap<FamiliarsTrickIndefiniteOneTimeCostTranslation>) {
self.translations = translations
}
}
public struct FamiliarsTrickIndefiniteOneTimeCostTranslation: EntitySubtype {
/// A description of the AE cost.
public let description: ResponsiveText
public init(description: ResponsiveText) {
self.description = description
}
}
public enum FamiliarsTrickOneTimeDuration: EntitySubtype {
case immediate
case fixed(FamiliarsTrickFixedOneTimeDuration)
case indefinite(FamiliarsTrickIndefiniteOneTimeDuration)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case immediate = "immediate"
case fixed = "fixed"
case indefinite = "indefinite"
}
private enum Discriminator: String, Decodable {
case immediate = "Immediate"
case fixed = "Fixed"
case indefinite = "Indefinite"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .immediate:
self = .immediate
case .fixed:
self = .fixed(try container.decode(FamiliarsTrickFixedOneTimeDuration.self, forKey: .fixed))
case .indefinite:
self = .indefinite(try container.decode(FamiliarsTrickIndefiniteOneTimeDuration.self, forKey: .indefinite))
}
}
}
public struct FamiliarsTrickFixedOneTimeDuration: EntitySubtype {
/// If the duration is the maximum duration, so it may end earlier.
public let isMaximum: Bool?
/// The (unitless) duration.
public let value: Int
/// The duration unit.
public let unit: DurationUnit
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<FamiliarsTrickFixedOneTimeDurationTranslation>?
public init(isMaximum: Bool? = nil, value: Int, unit: DurationUnit, translations: LocaleMap<FamiliarsTrickFixedOneTimeDurationTranslation>? = nil) {
self.isMaximum = isMaximum
self.value = value
self.unit = unit
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case isMaximum = "is_maximum"
case value = "value"
case unit = "unit"
case translations = "translations"
}
}
public struct FamiliarsTrickFixedOneTimeDurationTranslation: EntitySubtype {
/// A replacement string.
public let replacement: ResponsiveTextReplace?
public init(replacement: ResponsiveTextReplace? = nil) {
self.replacement = replacement
}
}
public struct FamiliarsTrickIndefiniteOneTimeDuration: EntitySubtype {
/// All translations for the entry, identified by IETF language tag
/// (BCP47).
public let translations: LocaleMap<FamiliarsTrickIndefiniteOneTimeDurationTranslation>
public init(translations: LocaleMap<FamiliarsTrickIndefiniteOneTimeDurationTranslation>) {
self.translations = translations
}
}
public struct FamiliarsTrickIndefiniteOneTimeDurationTranslation: EntitySubtype {
/// A description of the duration.
public let description: ResponsiveText
public init(description: ResponsiveText) {
self.description = description
}
}
public struct FamiliarsTrickOneTimeIntervalPerformanceParameters: EntitySubtype {
public let cost: FamiliarsTrickOneTimeIntervalCost
public init(cost: FamiliarsTrickOneTimeIntervalCost) {
self.cost = cost
}
}
public struct FamiliarsTrickOneTimeIntervalCost: EntitySubtype {
/// The AE cost value.
public let aeValue: Int
/// The LP cost value.
public let lpValue: Int?
/// The duration granted/added by paying the given AE cost.
public let interval: DurationUnitValue
public init(aeValue: Int, lpValue: Int? = nil, interval: DurationUnitValue) {
self.aeValue = aeValue
self.lpValue = lpValue
self.interval = interval
}
private enum CodingKeys: String, CodingKey {
case aeValue = "ae_value"
case lpValue = "lp_value"
case interval = "interval"
}
}
public struct FamiliarsTrickSustainedPerformanceParameters: EntitySubtype {
public let cost: FamiliarsTrickSustainedCost
public init(cost: FamiliarsTrickSustainedCost) {
self.cost = cost
}
}
public struct FamiliarsTrickSustainedCost: EntitySubtype {
/// The AE cost value.
public let aeValue: Int
/// The LP cost value.
public let lpValue: Int?
/// The interval in which you have to pay the AE cost again, if any.
public let interval: DurationUnitValue?
public init(aeValue: Int, lpValue: Int? = nil, interval: DurationUnitValue? = nil) {
self.aeValue = aeValue
self.lpValue = lpValue
self.interval = interval
}
private enum CodingKeys: String, CodingKey {
case aeValue = "ae_value"
case lpValue = "lp_value"
case interval = "interval"
}
}
@@ -1,26 +0,0 @@
//
// HairColor.swift
// OptolithDatabaseSchema
//
public struct HairColor: LocalizableEntity {
/// The hair color's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<HairColorTranslation>
public init(id: Int, translations: LocaleMap<HairColorTranslation>) {
self.id = id
self.translations = translations
}
}
public struct HairColorTranslation: EntitySubtype {
/// The hair color.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,6 +0,0 @@
//
// Kirchenpraegung.swift
// OptolithDatabaseSchema
//
public typealias Kirchenpraegung = Influence
@@ -1,324 +0,0 @@
//
// Lessons_Curriculum.swift
// OptolithDatabaseSchema
//
/// This is a curriculum of a specified academy, containing the guideline, elective and restricted spellworks as well as the lesson packages of that academy.
public struct Curriculum: LocalizableEntity {
/// The curriculum's identifier. An unique, increasing integer.
public let id: Int
/// The institution's guideline.
public let guideline: GuidelineReference
/// The academy's elective spellworks package.
public let electiveSpellworks: ElectiveSpellworks?
/// The academy's restricted spellworks package.
public let restrictedSpellworks: RestrictedSpellworks?
/// A list of available lesson packages.
public let lessonPackages: LessonPackages
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<CurriculumTranslation>
public init(id: Int, guideline: GuidelineReference, electiveSpellworks: ElectiveSpellworks? = nil, restrictedSpellworks: RestrictedSpellworks? = nil, lessonPackages: LessonPackages, src: PublicationRefs, translations: LocaleMap<CurriculumTranslation>) {
self.id = id
self.guideline = guideline
self.electiveSpellworks = electiveSpellworks
self.restrictedSpellworks = restrictedSpellworks
self.lessonPackages = lessonPackages
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case guideline = "guideline"
case electiveSpellworks = "elective_spellworks"
case restrictedSpellworks = "restricted_spellworks"
case lessonPackages = "lesson_packages"
case src = "src"
case translations = "translations"
}
}
public struct CurriculumTranslation: EntitySubtype {
/// The name of the academy.
public let name: NonEmptyString
public let errata: Errata?
public init(name: NonEmptyString, errata: Errata? = nil) {
self.name = name
self.errata = errata
}
}
/// The academy's elective spellworks package.
public enum ElectiveSpellworks: EntitySubtype {
case definedByGameMaster
case specific(SpecificElectiveSpellworks)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case definedByGameMaster = "defined_by_game_master"
case specific = "specific"
}
private enum Discriminator: String, Decodable {
case definedByGameMaster = "DefinedByGameMaster"
case specific = "Specific"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .definedByGameMaster:
self = .definedByGameMaster
case .specific:
self = .specific(try container.decode(SpecificElectiveSpellworks.self, forKey: .specific))
}
}
}
public struct SpecificElectiveSpellworks: EntitySubtype {
public let list: [ElectiveSpellwork]
public init(list: [ElectiveSpellwork]) {
self.list = list
}
}
public struct ElectiveSpellwork: EntitySubtype {
public let id: SpellworkIdentifier
/// The elective spellwork may only take effect if a certain condition is met. The condition may be related to professions or profession variants, but it is designed so that it can work without a specific profession, as multiple may belong to an institute, but with referencing other entities instead.
public let restriction: ElectiveSpellworkRestriction?
public init(id: SpellworkIdentifier, restriction: ElectiveSpellworkRestriction? = nil) {
self.id = id
self.restriction = restriction
}
}
/// The elective spellwork may only take effect if a certain condition is met. The condition may be related to professions or profession variants, but it is designed so that it can work without a specific profession, as multiple may belong to an institute, but with referencing other entities instead.
public struct ElectiveSpellworkRestriction: EntitySubtype {
public let tag: String
public let element: ElectiveSpellworkElementRestriction
public init(tag: String, element: ElectiveSpellworkElementRestriction) {
self.tag = tag
self.element = element
}
}
public struct ElectiveSpellworkElementRestriction: EntitySubtype {
public let id: ElementIdentifier
public init(id: ElementIdentifier) {
self.id = id
}
}
/// The academy's restricted spellworks package.
public typealias RestrictedSpellworks = [RestrictedSpellwork]
/// The academy's restricted spellworks package.
public enum RestrictedSpellwork: EntitySubtype {
case property(RestrictedProperty)
case spellwork(SpellworkIdentifier)
case demonSummoning
case borbaradian
case damageIntelligent
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case property = "property"
case spellwork = "spellwork"
case demonSummoning = "demon_summoning"
case borbaradian = "borbaradian"
case damageIntelligent = "damage_intelligent"
}
private enum Discriminator: String, Decodable {
case property = "Property"
case spellwork = "Spellwork"
case demonSummoning = "DemonSummoning"
case borbaradian = "Borbaradian"
case damageIntelligent = "DamageIntelligent"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .property:
self = .property(try container.decode(RestrictedProperty.self, forKey: .property))
case .spellwork:
self = .spellwork(try container.decode(SpellworkIdentifier.self, forKey: .spellwork))
case .demonSummoning:
self = .demonSummoning
case .borbaradian:
self = .borbaradian
case .damageIntelligent:
self = .damageIntelligent
}
}
}
public struct RestrictedProperty: EntitySubtype {
/// The identifier of the property that spellworks are disallowed from.
public let id: PropertyIdentifier
/// Exclude specific spellworks from the restriction.
public let exclude: [SpellworkIdentifier]?
/// Spellworks from this property up to a certain number are allowed. Spellworks excluded from this restriction definition using `exclude` do not contribute to the maximum.
public let maximum: Double?
public init(id: PropertyIdentifier, exclude: [SpellworkIdentifier]? = nil, maximum: Double? = nil) {
self.id = id
self.exclude = exclude
self.maximum = maximum
}
}
/// A list of available lesson packages.
public typealias LessonPackages = [LessonPackage]
public struct LessonPackage: EntitySubtype {
/// The lesson package's identifier. An unique, increasing integer.
public let id: Int
/// The spell values difference of the lesson package. This field reflects the changes (difference) to the field of the same name in the profession package. If a spell gets to SR 0 because of this, it will be removed completely.
public let spellworkChanges: [SpellworkChange]?
public let skills: [AbilityAdjustment]?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<LessonPackageTranslation>
public init(id: Int, spellworkChanges: [SpellworkChange]? = nil, skills: [AbilityAdjustment]? = nil, translations: LocaleMap<LessonPackageTranslation>) {
self.id = id
self.spellworkChanges = spellworkChanges
self.skills = skills
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case spellworkChanges = "spellwork_changes"
case skills = "skills"
case translations = "translations"
}
}
public struct SpellworkChange: EntitySubtype {
public let base: SpellworkAdjustment
public let replacement: SpellworkAdjustment
public init(base: SpellworkAdjustment, replacement: SpellworkAdjustment) {
self.base = base
self.replacement = replacement
}
}
public struct LessonPackageTranslation: EntitySubtype {
/// The name of the lesson package.
public let name: NonEmptyString
/// The spell values difference of the lesson package. Use this field to specify a text that is displayed instead of the generated
/// `spellwork_changes` list. The field is displayed even if no list is
/// present.
public let spellworkChanges: NonEmptyString?
public init(name: NonEmptyString, spellworkChanges: NonEmptyString? = nil) {
self.name = name
self.spellworkChanges = spellworkChanges
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case spellworkChanges = "spellwork_changes"
}
}
public enum AbilityAdjustment: EntitySubtype {
case combatTechnique(CombatTechniqueAdjustment)
case skill(SkillAdjustment)
case spellwork(SpellworkAdjustment)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case combatTechnique = "combat_technique"
case skill = "skill"
case spellwork = "spellwork"
}
private enum Discriminator: String, Decodable {
case combatTechnique = "CombatTechnique"
case skill = "Skill"
case spellwork = "Spellwork"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .combatTechnique:
self = .combatTechnique(try container.decode(CombatTechniqueAdjustment.self, forKey: .combatTechnique))
case .skill:
self = .skill(try container.decode(SkillAdjustment.self, forKey: .skill))
case .spellwork:
self = .spellwork(try container.decode(SpellworkAdjustment.self, forKey: .spellwork))
}
}
}
public struct CombatTechniqueAdjustment: EntitySubtype {
public let id: CombatTechniqueIdentifier
/// The combat technique points that will be added to the current combat technique rating.
public let points: Int
public init(id: CombatTechniqueIdentifier, points: Int) {
self.id = id
self.points = points
}
}
public struct SkillAdjustment: EntitySubtype {
/// The skill's identifier.
public let id: SkillIdentifier
/// The skill points that will be added to the current skill rating.
public let points: Int
public init(id: SkillIdentifier, points: Int) {
self.id = id
self.points = points
}
}
public struct SpellworkAdjustment: EntitySubtype {
public let id: SpellworkIdentifier
/// The skill points that will be added to the current skill rating. If a spell gets to a skill rating of 0 because of this, it will be removed completely.
public let points: Int
/// The target tradition. If the target spell is not from the Guild Mage tradition, specify the tradition identifier here.
public let tradition: MagicalTraditionIdentifier?
public init(id: SpellworkIdentifier, points: Int, tradition: MagicalTraditionIdentifier? = nil) {
self.id = id
self.points = points
self.tradition = tradition
}
}
@@ -1,36 +0,0 @@
//
// Lessons_Guideline.swift
// OptolithDatabaseSchema
//
public struct Guideline: LocalizableEntity {
/// The guideline's identifier. An unique, increasing integer.
public let id: Int
/// Maximum number of spells that can be exchanged.
public let spellworkChangesAllowed: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<GuidelineTranslation>
public init(id: Int, spellworkChangesAllowed: Int, translations: LocaleMap<GuidelineTranslation>) {
self.id = id
self.spellworkChangesAllowed = spellworkChangesAllowed
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case spellworkChangesAllowed = "spellwork_changes_allowed"
case translations = "translations"
}
}
public struct GuidelineTranslation: EntitySubtype {
/// The guideline name.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,116 +0,0 @@
//
// LiturgicalChant.swift
// OptolithDatabaseSchema
//
public struct LiturgicalChant: LocalizableEntity {
/// The liturgical chant's identifier. An unique, increasing integer.
public let id: Int
/// Lists the linked three attributes used to make a skill check.
public let check: SkillCheck
/// In some cases, the target's Spirit or Toughness is applied as a penalty.
public let checkPenalty: SkillCheckPenalty?
/// Measurable parameters of a liturgical chant.
public let parameters: FastPerformanceParameters
/// The target category the kind of creature or object the skill affects.
public let `target`: AffectedTargetCategories
/// The tradition(s) the liturgical chant is available for. Note that general aspects do not have an associated tradition and thus need to be defined in a special way.
public let traditions: [SkillTradition]
/// States which column is used to improve the skill.
public let improvementCost: ImprovementCost
public let prerequisites: LiturgyPrerequisites?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<LiturgicalChantTranslation>
public let enhancements: Enhancements?
public init(id: Int, check: SkillCheck, checkPenalty: SkillCheckPenalty? = nil, parameters: FastPerformanceParameters, `target`: AffectedTargetCategories, traditions: [SkillTradition], improvementCost: ImprovementCost, prerequisites: LiturgyPrerequisites? = nil, src: PublicationRefs, translations: LocaleMap<LiturgicalChantTranslation>, enhancements: Enhancements? = nil) {
self.id = id
self.check = check
self.checkPenalty = checkPenalty
self.parameters = parameters
self.`target` = `target`
self.traditions = traditions
self.improvementCost = improvementCost
self.prerequisites = prerequisites
self.src = src
self.translations = translations
self.enhancements = enhancements
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case check = "check"
case checkPenalty = "check_penalty"
case parameters = "parameters"
case `target` = "target"
case traditions = "traditions"
case improvementCost = "improvement_cost"
case prerequisites = "prerequisites"
case src = "src"
case translations = "translations"
case enhancements = "enhancements"
}
}
public struct LiturgicalChantTranslation: EntitySubtype {
/// The name of the liturgical chant.
public let name: NonEmptyString
/// A compressed name of the liturgical chant for use in small areas (e.g. on character sheet). Should only be defined if the `name` does not fit on character sheet.
public let nameCompressed: NonEmptyString?
/// The effect description may be either a plain text or a text that is divided by a list of effects for each quality level. It may also be a list for each two quality levels.
public let effect: ActivatableSkillEffect
@available(*, deprecated)
public let castingTime: OldParameter
@available(*, deprecated)
public let cost: OldParameter
@available(*, deprecated)
public let range: OldParameter
@available(*, deprecated)
public let duration: OldParameter
@available(*, deprecated)
public let `target`: String
public let errata: Errata?
public init(name: NonEmptyString, nameCompressed: NonEmptyString? = nil, effect: ActivatableSkillEffect, castingTime: OldParameter, cost: OldParameter, range: OldParameter, duration: OldParameter, `target`: String, errata: Errata? = nil) {
self.name = name
self.nameCompressed = nameCompressed
self.effect = effect
self.castingTime = castingTime
self.cost = cost
self.range = range
self.duration = duration
self.`target` = `target`
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case nameCompressed = "name_compressed"
case effect = "effect"
case castingTime = "casting_time"
case cost = "cost"
case range = "range"
case duration = "duration"
case `target` = "target"
case errata = "errata"
}
}
@@ -1,32 +0,0 @@
//
// Locale.swift
// OptolithDatabaseSchema
//
public struct Locale: Entity {
/// The locale's identifier. An IETF language tag (BCP47).
public let id: String
/// Name of the language in it's language.
public let name: String
/// Region in which the language is spoken in it's language.
public let region: String
/// The language is not (fully) implemented and thus needs to be excluded from stable releases.
public let isMissingImplementation: Bool?
public init(id: String, name: String, region: String, isMissingImplementation: Bool? = nil) {
self.id = id
self.name = name
self.region = region
self.isMissingImplementation = isMissingImplementation
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case region = "region"
case isMissingImplementation = "is_missing_implementation"
}
}
@@ -1,41 +0,0 @@
//
// MetaCondition.swift
// OptolithDatabaseSchema
//
/// Meta Conditions are rule elements that work like conditions in the sense that they have four levels with different effects, but which are not explicitly listed as conditions.
public struct MetaCondition: LocalizableEntity {
/// The meta condition's identifier. An unique, increasing integer.
public let id: Int
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<MetaConditionTranslation>
public init(id: Int, src: PublicationRefs, translations: LocaleMap<MetaConditionTranslation>) {
self.id = id
self.src = src
self.translations = translations
}
}
public struct MetaConditionTranslation: EntitySubtype {
/// The meta condition's name.
public let name: NonEmptyString
/// Additional rules for the meta condition, if applicable.
public let rules: NonEmptyMarkdown?
/// The effects for level 1 to 4.
public let effects: [NonEmptyMarkdown]
public let errata: Errata?
public init(name: NonEmptyString, rules: NonEmptyMarkdown? = nil, effects: [NonEmptyMarkdown], errata: Errata? = nil) {
self.name = name
self.rules = rules
self.effects = effects
self.errata = errata
}
}
@@ -1,84 +0,0 @@
//
// PactCategory.swift
// OptolithDatabaseSchema
//
public struct PactCategory: LocalizableEntity {
/// The pact category's identifier. An unique, increasing integer.
public let id: Int
/// Types of creatures in this category.
public let types: [PactType]
/// Domains in this category.
public let domains: [PactDomain]
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<PactCategoryTranslation>
public init(id: Int, types: [PactType], domains: [PactDomain], src: PublicationRefs, translations: LocaleMap<PactCategoryTranslation>) {
self.id = id
self.types = types
self.domains = domains
self.src = src
self.translations = translations
}
}
public struct PactCategoryTranslation: EntitySubtype {
/// The name of the pact category.
public let name: NonEmptyString
public let errata: Errata?
public init(name: NonEmptyString, errata: Errata? = nil) {
self.name = name
self.errata = errata
}
}
public struct PactType: EntitySubtype {
/// The type's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<PactTypeTranslation>
public init(id: Int, translations: LocaleMap<PactTypeTranslation>) {
self.id = id
self.translations = translations
}
}
public struct PactTypeTranslation: EntitySubtype {
/// The name of the type.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
public struct PactDomain: EntitySubtype {
/// The domain's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<PactDomainTranslation>
public init(id: Int, translations: LocaleMap<PactDomainTranslation>) {
self.id = id
self.translations = translations
}
}
public struct PactDomainTranslation: EntitySubtype {
/// The name of the domain.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,245 +0,0 @@
//
// Patron.swift
// OptolithDatabaseSchema
//
public struct Patron: LocalizableEntity {
/// The patron's identifier. An unique, increasing integer.
public let id: Int
/// The patron's category.
public let category: PatronCategoryReference
/// The patron-specific skills.
public let skills: [SkillReference]
/// The patron is only available to a certain set of cultures. It may be available to all, it may be available to only specific ones (intersection) and it may be available to all except specific ones to the listed cultures
/// (difference).
public let culture: PatronCulture
/// The list of cultures where patrons from this category can be the primary patron of.
public let primaryPatronCultures: [CultureReference]?
/// The patron-specific powers. Used by animist power Animal Powers IIII and should only be present on animal patrons.
public let powers: AnimalPowers?
/// The patron-specific AE cost. Used by several animist forces for animal patrons.
public let aeCost: Int?
/// The patron-specific improvement cost. Used by several animist forces for animal patrons.
public let improvementCost: ImprovementCost?
/// The patron may grant common advantages that are taken into account during character creation.
///
/// *Source:* Geisterwald & Knochenklippen, p. 6-7
public let commonAdvantages: [AdvantageReference]?
/// The patron may grant common disadvantages that are taken into account during character creation.
///
/// *Source:* Geisterwald & Knochenklippen, p. 6-7
public let commonDisadvantages: [DisadvantageReference]?
/// The animist may learn spellworks common for this patron.
///
/// *Source:* Geisterwald & Knochenklippen, p. 6-7
public let commonSpellworks: [SpellworkReference]?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<PatronTranslation>
public init(id: Int, category: PatronCategoryReference, skills: [SkillReference], culture: PatronCulture, primaryPatronCultures: [CultureReference]? = nil, powers: AnimalPowers? = nil, aeCost: Int? = nil, improvementCost: ImprovementCost? = nil, commonAdvantages: [AdvantageReference]? = nil, commonDisadvantages: [DisadvantageReference]? = nil, commonSpellworks: [SpellworkReference]? = nil, translations: LocaleMap<PatronTranslation>) {
self.id = id
self.category = category
self.skills = skills
self.culture = culture
self.primaryPatronCultures = primaryPatronCultures
self.powers = powers
self.aeCost = aeCost
self.improvementCost = improvementCost
self.commonAdvantages = commonAdvantages
self.commonDisadvantages = commonDisadvantages
self.commonSpellworks = commonSpellworks
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case category = "category"
case skills = "skills"
case culture = "culture"
case primaryPatronCultures = "primary_patron_cultures"
case powers = "powers"
case aeCost = "ae_cost"
case improvementCost = "improvement_cost"
case commonAdvantages = "common_advantages"
case commonDisadvantages = "common_disadvantages"
case commonSpellworks = "common_spellworks"
case translations = "translations"
}
}
public struct PatronTranslation: EntitySubtype {
/// The name of the patron.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
/// The patron cultures the patron is or is not part of. If the patron is part of all patron cultures, the set should be empty and the operation should be difference.
public struct PatronCulture: EntitySubtype {
public let `set`: [CultureReference]
public let operation: PatronCultureOperation
public init(`set`: [CultureReference], operation: PatronCultureOperation) {
self.`set` = `set`
self.operation = operation
}
private enum CodingKeys: String, CodingKey {
case `set` = "set"
case operation = "operation"
}
}
/// The set operation to combine the set of all patron cultures with the specified set of patron cultures: If they should intersect, the patron is only part of the given cultures. If they should differ, the patron is only part of the cultures that are not given.
public enum PatronCultureOperation: String, EntitySubtype {
case intersection = "Intersection"
case difference = "Difference"
}
public struct AnimalPowers: EntitySubtype {
public let level1: AnimalPowersLevel1
public let level2: AnimalPowersLevel2
public let level3: AnimalPowersLevel3
public init(level1: AnimalPowersLevel1, level2: AnimalPowersLevel2, level3: AnimalPowersLevel3) {
self.level1 = level1
self.level2 = level2
self.level3 = level3
}
}
public struct AdvantageAnimalPower: EntitySubtype {
/// The advantage's identifier.
public let id: AdvantageIdentifier
/// It grants a higher level of the advantage.
public let level: Int?
/// It grants a specific general option of the advantage.
public let option: Int?
public init(id: AdvantageIdentifier, level: Int? = nil, option: Int? = nil) {
self.id = id
self.level = level
self.option = option
}
}
public struct SkillAnimalPower: EntitySubtype {
/// The skill's identifier.
public let id: SkillIdentifier
/// The points that gets added to the skill's rating.
public let points: Int
public init(id: SkillIdentifier, points: Int) {
self.id = id
self.points = points
}
}
public enum AnimalPowerLevel1: EntitySubtype {
case advantage(AdvantageAnimalPower)
case skill(SkillAnimalPower)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case advantage = "advantage"
case skill = "skill"
}
private enum Discriminator: String, Decodable {
case advantage = "Advantage"
case skill = "Skill"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .advantage:
self = .advantage(try container.decode(AdvantageAnimalPower.self, forKey: .advantage))
case .skill:
self = .skill(try container.decode(SkillAnimalPower.self, forKey: .skill))
}
}
}
public typealias AnimalPowersLevel1 = [AnimalPowerLevel1]
public struct CombatAnimalPower: EntitySubtype {
/// The combat value.
public let id: CombatAnimalPowerType
/// The value that gets added to the combat value.
public let value: Int
public init(id: CombatAnimalPowerType, value: Int) {
self.id = id
self.value = value
}
}
public enum CombatAnimalPowerType: String, EntitySubtype {
case attack = "Attack"
case parry = "Parry"
case rangedCombat = "RangedCombat"
case dodge = "Dodge"
case damagePoints = "DamagePoints"
case protection = "Protection"
}
public struct AnimalPowerLevel2: EntitySubtype {
public let tag: String
public let combat: CombatAnimalPower
public init(tag: String, combat: CombatAnimalPower) {
self.tag = tag
self.combat = combat
}
}
public typealias AnimalPowersLevel2 = [AnimalPowerLevel2]
public struct AttributeAnimalPower: EntitySubtype {
/// The attribute's identifier.
public let id: AttributeIdentifier
/// The value that gets added to the attribute.
public let value: Int
public init(id: AttributeIdentifier, value: Int) {
self.id = id
self.value = value
}
}
public struct AnimalPowerLevel3: EntitySubtype {
public let tag: String
public let attribute: AttributeAnimalPower
public init(tag: String, attribute: AttributeAnimalPower) {
self.tag = tag
self.attribute = attribute
}
}
public typealias AnimalPowersLevel3 = [AnimalPowerLevel3]
@@ -1,36 +0,0 @@
//
// PatronCategory.swift
// OptolithDatabaseSchema
//
public struct PatronCategory: LocalizableEntity {
/// The patron category's identifier. An unique, increasing integer.
public let id: Int
/// The list of cultures where patrons from this category can be the primary patron of.
public let primaryPatronCultures: [CultureReference]
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<PatronCategoryTranslation>
public init(id: Int, primaryPatronCultures: [CultureReference], translations: LocaleMap<PatronCategoryTranslation>) {
self.id = id
self.primaryPatronCultures = primaryPatronCultures
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case primaryPatronCultures = "primary_patron_cultures"
case translations = "translations"
}
}
public struct PatronCategoryTranslation: EntitySubtype {
/// The name of the patron category.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,70 +0,0 @@
//
// PersonalityTrait.swift
// OptolithDatabaseSchema
//
/// A personality trait describes character aspects of a person from a certain region. Higher trait levels only cover a part of the region covered by lower-level traits.
public struct PersonalityTrait: LocalizableEntity {
/// The personality trait's identifier. An unique, increasing integer.
public let id: Int
/// The personality trait's level.
public let level: Int
public let prerequisites: PersonalityTraitPrerequisites?
/// The lower-level personality trait(s) this trait can be combined with.
public let combinationOptions: [PersonalityTraitReference]?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<PersonalityTraitTranslation>
public init(id: Int, level: Int, prerequisites: PersonalityTraitPrerequisites? = nil, combinationOptions: [PersonalityTraitReference]? = nil, src: PublicationRefs, translations: LocaleMap<PersonalityTraitTranslation>) {
self.id = id
self.level = level
self.prerequisites = prerequisites
self.combinationOptions = combinationOptions
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case level = "level"
case prerequisites = "prerequisites"
case combinationOptions = "combination_options"
case src = "src"
case translations = "translations"
}
}
public struct PersonalityTraitTranslation: EntitySubtype {
/// The name of the personality trait.
public let name: NonEmptyString
/// The effects of the personality trait. They should be sorted like they are in the book.
public let effects: [PersonalityTraitEffect]
public let errata: Errata?
public init(name: NonEmptyString, effects: [PersonalityTraitEffect], errata: Errata? = nil) {
self.name = name
self.effects = effects
self.errata = errata
}
}
public struct PersonalityTraitEffect: EntitySubtype {
/// A label that is displayed and placed before the actual text.
public let label: NonEmptyString?
/// The effect text.
public let text: NonEmptyString
public init(label: NonEmptyString? = nil, text: NonEmptyString) {
self.label = label
self.text = text
}
}
@@ -1,902 +0,0 @@
//
// Profession.swift
// OptolithDatabaseSchema
//
public struct Profession: Entity {
/// The profession's identifier. An unique, increasing integer.
public let id: Int
/// The profession group.
public let group: ProfessionGroup
/// A list of professions representing the same profession but with (slightly) different stats. For example, there may be a profession in a regional sourcebook or in the core rules and a profession in an extension rulebook like Magic of Aventuria, where the profession is basically called the same and almost has the same values, but the version from Magic of Aventuria features a spell style special ability that does not exist in the core rules or regional sourcebook.
///
/// The profession representation may feature different values for different explicitly mentioned experience levels. In most cases, there is only one stats package, which targets the experience level *Experienced*.
public let versions: [ProfessionVersion]
public init(id: Int, group: ProfessionGroup, versions: [ProfessionVersion]) {
self.id = id
self.group = group
self.versions = versions
}
}
public enum ProfessionGroup: EntitySubtype {
case mundane(MundaneProfessionGroup)
case magical(MagicalProfessionGroup)
case blessed
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case mundane = "mundane"
case magical = "magical"
case blessed = "blessed"
}
private enum Discriminator: String, Decodable {
case mundane = "Mundane"
case magical = "Magical"
case blessed = "Blessed"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .mundane:
self = .mundane(try container.decode(MundaneProfessionGroup.self, forKey: .mundane))
case .magical:
self = .magical(try container.decode(MagicalProfessionGroup.self, forKey: .magical))
case .blessed:
self = .blessed
}
}
}
public enum MundaneProfessionGroup: String, EntitySubtype {
case profane = "Profane"
case fighter = "Fighter"
case religious = "Religious"
}
public struct MagicalProfessionGroup: EntitySubtype {
/// The curriculum/academy associated with this magical profession, if any.
public let curriculum: CurriculumReference?
public init(curriculum: CurriculumReference? = nil) {
self.curriculum = curriculum
}
}
public enum ProfessionVersion: EntitySubtype {
case experienced(ExperiencedProfessionPackage)
case byExperienceLevel(ProfessionPackagesForDifferentExperienceLevels)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case experienced = "experienced"
case byExperienceLevel = "by_experience_level"
}
private enum Discriminator: String, Decodable {
case experienced = "Experienced"
case byExperienceLevel = "ByExperienceLevel"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .experienced:
self = .experienced(try container.decode(ExperiencedProfessionPackage.self, forKey: .experienced))
case .byExperienceLevel:
self = .byExperienceLevel(try container.decode(ProfessionPackagesForDifferentExperienceLevels.self, forKey: .byExperienceLevel))
}
}
}
public struct ExperiencedProfessionPackage: EntitySubtype {
/// The profession representation variant's identifier. An unique, increasing integer.
public let id: Int
public let `package`: ProfessionPackage
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ProfessionTranslation>
public init(id: Int, `package`: ProfessionPackage, src: PublicationRefs, translations: LocaleMap<ProfessionTranslation>) {
self.id = id
self.`package` = `package`
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case `package` = "package"
case src = "src"
case translations = "translations"
}
}
public struct ProfessionPackagesForDifferentExperienceLevels: EntitySubtype {
/// The profession representation variant's identifier. An unique, increasing integer.
public let id: Int
public let packagesMap: [ExperienceLevelDynamicProfessionPackage]
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ProfessionTranslation>
public init(id: Int, packagesMap: [ExperienceLevelDynamicProfessionPackage], src: PublicationRefs, translations: LocaleMap<ProfessionTranslation>) {
self.id = id
self.packagesMap = packagesMap
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case packagesMap = "packages_map"
case src = "src"
case translations = "translations"
}
}
public struct ExperienceLevelDynamicProfessionPackage: EntitySubtype {
/// The experience level this profession targets. The experience level must be unique for this representation.
public let experienceLevelId: Int
public let `package`: ProfessionPackage
public init(experienceLevelId: Int, `package`: ProfessionPackage) {
self.experienceLevelId = experienceLevelId
self.`package` = `package`
}
private enum CodingKeys: String, CodingKey {
case experienceLevelId = "experience_level_id"
case `package` = "package"
}
}
public struct ProfessionPackage: EntitySubtype {
/// What does the professional package cost in adventure points?
public let apValue: Int
/// Which prerequisites must be met to buy the stat block? For example, a character might need the advantage Spellcaster or Blessed. Note: the AP cost for a profession package does not include these prerequisites.
public let prerequisites: ProfessionPrerequisites?
/// In some areas, the profession package grants a loose set of stats where the player must choose between different options for the profession package.
public let options: ProfessionPackageOptions?
/// Any special abilities the profession receives from the package.
public let specialAbilities: [ProfessionSpecialAbility]?
/// Provides ratings for the combat techniques that the hero receives from the package.
public let combatTechniques: [CombatTechniqueRating]?
/// The skill ratings the package grants to the hero.
public let skills: [SkillRating]?
/// The skill ratings a magical profession receives for spells; these spells are considered activated. Spells from an unfamiliar Tradition, if any, are identified as such.
public let spells: [SpellRating]?
/// Clerical professions receive these liturgical chants at the listed skill ratings. These liturgical chants are considered activated.
public let liturgicalChants: [LiturgicalChantRating]?
/// Typical advantages for the profession.
public let suggestedAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]?
/// Typical disadvantages for the profession.
public let suggestedDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]?
/// These advantages do not fit well with this profession; to be checked with the GM before taking any of them.
public let unsuitableAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]?
/// These disadvantages do not fit well with this profession; to be checked with the GM before taking any of them.
public let unsuitableDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]?
/// Provides examples of variants for the profession, which may include changes to AP values and additional or modified skill ratings, special abilities, or combat techniques, as compared to the basic profession. Usually picking a variant is optional, but there are some rare exceptions where picking a variant is required.
public let variants: ProfessionVariants?
public init(apValue: Int, prerequisites: ProfessionPrerequisites? = nil, options: ProfessionPackageOptions? = nil, specialAbilities: [ProfessionSpecialAbility]? = nil, combatTechniques: [CombatTechniqueRating]? = nil, skills: [SkillRating]? = nil, spells: [SpellRating]? = nil, liturgicalChants: [LiturgicalChantRating]? = nil, suggestedAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]? = nil, suggestedDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]? = nil, unsuitableAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]? = nil, unsuitableDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]? = nil, variants: ProfessionVariants? = nil) {
self.apValue = apValue
self.prerequisites = prerequisites
self.options = options
self.specialAbilities = specialAbilities
self.combatTechniques = combatTechniques
self.skills = skills
self.spells = spells
self.liturgicalChants = liturgicalChants
self.suggestedAdvantages = suggestedAdvantages
self.suggestedDisadvantages = suggestedDisadvantages
self.unsuitableAdvantages = unsuitableAdvantages
self.unsuitableDisadvantages = unsuitableDisadvantages
self.variants = variants
}
private enum CodingKeys: String, CodingKey {
case apValue = "ap_value"
case prerequisites = "prerequisites"
case options = "options"
case specialAbilities = "special_abilities"
case combatTechniques = "combat_techniques"
case skills = "skills"
case spells = "spells"
case liturgicalChants = "liturgical_chants"
case suggestedAdvantages = "suggested_advantages"
case suggestedDisadvantages = "suggested_disadvantages"
case unsuitableAdvantages = "unsuitable_advantages"
case unsuitableDisadvantages = "unsuitable_disadvantages"
case variants = "variants"
}
}
public struct ProfessionTranslation: EntitySubtype {
/// Name of the basic profession.
public let name: ProfessionName
/// A name addition of the profession. This will contain texts like name of the academy or the witch circle. It is enclosed in parenthesis, but the database entry must not contain parenthesis.
public let specification: ProfessionName?
/// Typical advantages for the profession.
public let suggestedAdvantages: NonEmptyString?
/// Typical disadvantages for the profession.
public let suggestedDisadvantages: NonEmptyString?
/// These advantages do not fit well with this profession; to be checked with the GM before taking any of them.
public let unsuitableAdvantages: NonEmptyString?
/// These disadvantages do not fit well with this profession; to be checked with the GM before taking any of them.
public let unsuitableDisadvantages: NonEmptyString?
public let errata: Errata?
public init(name: ProfessionName, specification: ProfessionName? = nil, suggestedAdvantages: NonEmptyString? = nil, suggestedDisadvantages: NonEmptyString? = nil, unsuitableAdvantages: NonEmptyString? = nil, unsuitableDisadvantages: NonEmptyString? = nil, errata: Errata? = nil) {
self.name = name
self.specification = specification
self.suggestedAdvantages = suggestedAdvantages
self.suggestedDisadvantages = suggestedDisadvantages
self.unsuitableAdvantages = unsuitableAdvantages
self.unsuitableDisadvantages = unsuitableDisadvantages
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case specification = "specification"
case suggestedAdvantages = "suggested_advantages"
case suggestedDisadvantages = "suggested_disadvantages"
case unsuitableAdvantages = "unsuitable_advantages"
case unsuitableDisadvantages = "unsuitable_disadvantages"
case errata = "errata"
}
}
/// Provides examples of variants for the profession, which may include changes to AP values and additional or modified skill ratings, special abilities, or combat techniques, as compared to the basic profession. Usually picking a variant is optional, but there are some rare exceptions where picking a variant is required.
public struct ProfessionVariants: EntitySubtype {
/// If the selection of a profession variant is required.
public let isSelectionRequired: Bool
/// The list of profession variants.
public let list: [ProfessionVariant]
public init(isSelectionRequired: Bool, list: [ProfessionVariant]) {
self.isSelectionRequired = isSelectionRequired
self.list = list
}
private enum CodingKeys: String, CodingKey {
case isSelectionRequired = "is_selection_required"
case list = "list"
}
}
public struct ProfessionVariant: EntitySubtype {
/// The profession variant's identifier. An unique, increasing integer.
public let id: Int
/// The AP value you have to pay for the package variant.
public let apValue: Int
/// Which prerequisites must be met to buy the stat block? For example, a character might need the advantage Spellcaster or Blessed. Note: the AP cost for a profession package does not include these prerequisites.
public let prerequisites: ProfessionPrerequisites?
public let options: ProfessionVariantPackageOptions?
/// Any special abilities the profession receives from the package variant.
public let specialAbilities: [VariantSpecialAbility]?
/// Provides ratings for the combat techniques that the hero receives from the package variant.
public let combatTechniques: [CombatTechniqueRating]?
/// The skill ratings the package variant grants to the hero.
public let skills: [SkillRating]?
/// The skill ratings a magical profession variant receives for spells; these spells are considered activated. Spells from an unfamiliar Tradition, if any, are identified as such.
public let spells: [SpellRating]?
/// Clerical professions receive these liturgical chants at the listed skill ratings. These liturgical chants are considered activated.
public let liturgicalChants: [LiturgicalChantRating]?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ProfessionVariantTranslation>
public init(id: Int, apValue: Int, prerequisites: ProfessionPrerequisites? = nil, options: ProfessionVariantPackageOptions? = nil, specialAbilities: [VariantSpecialAbility]? = nil, combatTechniques: [CombatTechniqueRating]? = nil, skills: [SkillRating]? = nil, spells: [SpellRating]? = nil, liturgicalChants: [LiturgicalChantRating]? = nil, translations: LocaleMap<ProfessionVariantTranslation>) {
self.id = id
self.apValue = apValue
self.prerequisites = prerequisites
self.options = options
self.specialAbilities = specialAbilities
self.combatTechniques = combatTechniques
self.skills = skills
self.spells = spells
self.liturgicalChants = liturgicalChants
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case apValue = "ap_value"
case prerequisites = "prerequisites"
case options = "options"
case specialAbilities = "special_abilities"
case combatTechniques = "combat_techniques"
case skills = "skills"
case spells = "spells"
case liturgicalChants = "liturgical_chants"
case translations = "translations"
}
}
public struct ProfessionVariantTranslation: EntitySubtype {
/// Name of the profession variant.
public let name: ProfessionName
/// A text that replaces the generated text for the profession variant.
public let fullText: NonEmptyString?
/// A text that is appended to the generated text for the profession variant.
///
/// Has no effect when `full_text` is set.
public let concludingText: NonEmptyString?
public init(name: ProfessionName, fullText: NonEmptyString? = nil, concludingText: NonEmptyString? = nil) {
self.name = name
self.fullText = fullText
self.concludingText = concludingText
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case fullText = "full_text"
case concludingText = "concluding_text"
}
}
public enum ProfessionSpecialAbility: EntitySubtype {
case fixed(FixedSpecialAbility)
case selection(SpecialAbilitySelection)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case fixed = "fixed"
case selection = "selection"
}
private enum Discriminator: String, Decodable {
case fixed = "Fixed"
case selection = "Selection"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .fixed:
self = .fixed(try container.decode(FixedSpecialAbility.self, forKey: .fixed))
case .selection:
self = .selection(try container.decode(SpecialAbilitySelection.self, forKey: .selection))
}
}
}
public typealias FixedSpecialAbility = SpecialAbilityDefinition
public struct SpecialAbilitySelection: EntitySubtype {
public let options: [SpecialAbilityDefinition]
public init(options: [SpecialAbilityDefinition]) {
self.options = options
}
}
public struct SpecialAbilityDefinition: EntitySubtype {
/// The identifier of the combat technique to provide the rating for.
public let id: SpecialAbilityIdentifier
/// The level of the received special ability.
public let level: Int?
/// Received select options. Order is important. Typically, you only need the first array index, though.
public let options: [RequirableSelectOptionIdentifier]?
public init(id: SpecialAbilityIdentifier, level: Int? = nil, options: [RequirableSelectOptionIdentifier]? = nil) {
self.id = id
self.level = level
self.options = options
}
}
public enum VariantSpecialAbility: EntitySubtype {
case fixed(FixedVariantSpecialAbility)
case selection(VariantSpecialAbilitySelection)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case fixed = "fixed"
case selection = "selection"
}
private enum Discriminator: String, Decodable {
case fixed = "Fixed"
case selection = "Selection"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .fixed:
self = .fixed(try container.decode(FixedVariantSpecialAbility.self, forKey: .fixed))
case .selection:
self = .selection(try container.decode(VariantSpecialAbilitySelection.self, forKey: .selection))
}
}
}
public struct FixedVariantSpecialAbility: EntitySubtype {
/// The identifier of the combat technique to provide the rating for.
public let id: SpecialAbilityIdentifier
/// if set to `false`, if the selection is granted by the basic package, it is removed.
public let active: Bool?
/// The level of the received special ability.
public let level: Int?
/// Received select options. Order is important. Typically, you only need the first array index, though.
public let options: [RequirableSelectOptionIdentifier]?
public init(id: SpecialAbilityIdentifier, active: Bool? = nil, level: Int? = nil, options: [RequirableSelectOptionIdentifier]? = nil) {
self.id = id
self.active = active
self.level = level
self.options = options
}
}
public struct VariantSpecialAbilitySelection: EntitySubtype {
/// if set to `false`, if the selection is granted by the basic package, it is removed.
public let active: Bool?
public let options: [SpecialAbilityDefinition]
public init(active: Bool? = nil, options: [SpecialAbilityDefinition]) {
self.active = active
self.options = options
}
}
public struct CombatTechniqueRating: EntitySubtype {
/// The identifier of the combat technique to provide the rating for.
public let id: CombatTechniqueIdentifier
/// The rating bonus provided for the combat technique. If used in a profession variant, it can also be used to lower the bonus of the base profession.
///
/// **Note:** This is a rating *bonus*, so it will be *added* to the default
/// value of 6.
public let rating: Int
public init(id: CombatTechniqueIdentifier, rating: Int) {
self.id = id
self.rating = rating
}
}
public struct SkillRating: EntitySubtype {
/// The identifier of the skill to provide the rating for.
public let id: SkillIdentifier
/// The rating bonus provided for the skill. If used in a profession variant, it can also be used to lower the bonus of the base profession
public let rating: Int
public init(id: SkillIdentifier, rating: Int) {
self.id = id
self.rating = rating
}
}
public struct SpellRating: EntitySubtype {
/// The identifier(s) of the spell(s) to choose from to provide the rating for. If multiple spells are provided, they must all have the same improvement cost.
public let id: [ProfessionSpellIdentifier]
/// The rating bonus provided for the (selected) spell. If used in a profession variant, it can also be used to lower the bonus of the base profession.
public let rating: Int
public init(id: [ProfessionSpellIdentifier], rating: Int) {
self.id = id
self.rating = rating
}
}
public enum ProfessionSpellIdentifier: EntitySubtype {
case spellwork(ProfessionSpellworkIdentifier)
case magicalAction(ProfessionMagicalActionIdentifier)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case spellwork = "spellwork"
case magicalAction = "magical_action"
}
private enum Discriminator: String, Decodable {
case spellwork = "Spellwork"
case magicalAction = "MagicalAction"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .spellwork:
self = .spellwork(try container.decode(ProfessionSpellworkIdentifier.self, forKey: .spellwork))
case .magicalAction:
self = .magicalAction(try container.decode(ProfessionMagicalActionIdentifier.self, forKey: .magicalAction))
}
}
}
public struct ProfessionSpellworkIdentifier: EntitySubtype {
/// The identifier of the spell to provide the rating for.
public let id: SpellworkIdentifier
/// If the spell is not part of the magical tradition required by the package, this references the magical tradition it is part of. It can also be used to define the target magical tradition of a spell if multiple magical traditions are required and the spell is available to multiple of them.
public let tradition: MagicalTraditionReference?
public init(id: SpellworkIdentifier, tradition: MagicalTraditionReference? = nil) {
self.id = id
self.tradition = tradition
}
}
public struct ProfessionMagicalActionIdentifier: EntitySubtype {
/// The identifier of the magical action to provide the rating for.
public let id: MagicalActionIdentifier
public init(id: MagicalActionIdentifier) {
self.id = id
}
}
public struct LiturgicalChantRating: EntitySubtype {
/// The identifier(s) of the liturgical chant(s) to choose from to provide the rating for. If multiple liturgical chants are provided, they must all have the same improvement cost.
public let id: [LiturgyIdentifier]
/// The rating bonus provided for the selected liturgical chant. If used in a profession variant, it can also be used to lower the bonus of the base profession.
public let rating: Int
public init(id: [LiturgyIdentifier], rating: Int) {
self.id = id
self.rating = rating
}
}
/// In some areas, the profession package grants a loose set of stats where the player must choose between different options for the profession package.
public struct ProfessionPackageOptions: EntitySubtype {
public let skillSpecialization: SkillSpecializationOptions?
public let languagesScripts: LanguagesScriptsOptions?
public let combatTechniques: CombatTechniquesOptions?
public let cantrips: CantripsOptions?
public let curses: CursesOptions?
public let terrainKnowledge: TerrainKnowledgeOptions?
public let skills: SkillsOptions?
public init(skillSpecialization: SkillSpecializationOptions? = nil, languagesScripts: LanguagesScriptsOptions? = nil, combatTechniques: CombatTechniquesOptions? = nil, cantrips: CantripsOptions? = nil, curses: CursesOptions? = nil, terrainKnowledge: TerrainKnowledgeOptions? = nil, skills: SkillsOptions? = nil) {
self.skillSpecialization = skillSpecialization
self.languagesScripts = languagesScripts
self.combatTechniques = combatTechniques
self.cantrips = cantrips
self.curses = curses
self.terrainKnowledge = terrainKnowledge
self.skills = skills
}
private enum CodingKeys: String, CodingKey {
case skillSpecialization = "skill_specialization"
case languagesScripts = "languages_scripts"
case combatTechniques = "combat_techniques"
case cantrips = "cantrips"
case curses = "curses"
case terrainKnowledge = "terrain_knowledge"
case skills = "skills"
}
}
/// In some areas, the profession package grants a loose set of stats where the player must choose between different options for the profession package. The variant may override or remove those options.
public struct ProfessionVariantPackageOptions: EntitySubtype {
public let skillSpecialization: VariantOptionAction<SkillSpecializationOptions>?
public let languagesScripts: VariantOptionAction<LanguagesScriptsOptions>?
public let combatTechniques: VariantOptionAction<CombatTechniquesOptions>?
public let cantrips: VariantOptionAction<CantripsOptions>?
public let curses: VariantOptionAction<CursesOptions>?
public let terrainKnowledge: VariantOptionAction<TerrainKnowledgeOptions>?
public let skills: VariantOptionAction<SkillsOptions>?
public init(skillSpecialization: VariantOptionAction<SkillSpecializationOptions>? = nil, languagesScripts: VariantOptionAction<LanguagesScriptsOptions>? = nil, combatTechniques: VariantOptionAction<CombatTechniquesOptions>? = nil, cantrips: VariantOptionAction<CantripsOptions>? = nil, curses: VariantOptionAction<CursesOptions>? = nil, terrainKnowledge: VariantOptionAction<TerrainKnowledgeOptions>? = nil, skills: VariantOptionAction<SkillsOptions>? = nil) {
self.skillSpecialization = skillSpecialization
self.languagesScripts = languagesScripts
self.combatTechniques = combatTechniques
self.cantrips = cantrips
self.curses = curses
self.terrainKnowledge = terrainKnowledge
self.skills = skills
}
private enum CodingKeys: String, CodingKey {
case skillSpecialization = "skill_specialization"
case languagesScripts = "languages_scripts"
case combatTechniques = "combat_techniques"
case cantrips = "cantrips"
case curses = "curses"
case terrainKnowledge = "terrain_knowledge"
case skills = "skills"
}
}
public enum VariantOptionAction<T: EntitySubtype>: EntitySubtype {
case remove
case `override`(T)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case remove = "remove"
case `override` = "override"
}
private enum Discriminator: String, Decodable {
case remove = "Remove"
case `override` = "Override"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .remove:
self = .remove
case .`override`:
self = .`override`(try container.decode(T.self, forKey: .`override`))
}
}
}
/// Select an application from a skill or from one of a list of skills where you get a skill specialization for. You can also specify a skill groups from which you can choose a skill.
public enum SkillSpecializationOptions: EntitySubtype {
case single(SingleSkillSpecializationOption)
case group(SkillGroupSkillSpecializationOption)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case single = "single"
case group = "group"
}
private enum Discriminator: String, Decodable {
case single = "Single"
case group = "Group"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .single:
self = .single(try container.decode(SingleSkillSpecializationOption.self, forKey: .single))
case .group:
self = .group(try container.decode(SkillGroupSkillSpecializationOption.self, forKey: .group))
}
}
}
public struct SingleSkillSpecializationOption: EntitySubtype {
/// Possible skills to get a skill specialization for.
public let options: [SkillReference]
public init(options: [SkillReference]) {
self.options = options
}
}
public typealias SkillGroupSkillSpecializationOption = SkillGroupReference
/// Buy languages and scripts for a specific amount of AP.
public struct LanguagesScriptsOptions: EntitySubtype {
/// The AP value you can buy languages and scripts for.
public let apValue: Int
public init(apValue: Int) {
self.apValue = apValue
}
private enum CodingKeys: String, CodingKey {
case apValue = "ap_value"
}
}
/// Select one or more combat techniques you get a CtR bonus for.
public struct CombatTechniquesOptions: EntitySubtype {
/// Specify the number of combat techniques that can be selected so that they get increased to a specific CtR. There can be multiple selections with different CtRs.
public let fixed: [RatingForCombatTechniquesNumber]
/// Define if after the fixed selections the remaining unselected combat techniques will receive a certain rating bonus as well.
public let restRating: Int?
/// The list of combat techniques to choose from.
public let options: [CombatTechniqueReference]
public init(fixed: [RatingForCombatTechniquesNumber], restRating: Int? = nil, options: [CombatTechniqueReference]) {
self.fixed = fixed
self.restRating = restRating
self.options = options
}
private enum CodingKeys: String, CodingKey {
case fixed = "fixed"
case restRating = "rest_rating"
case options = "options"
}
}
public struct RatingForCombatTechniquesNumber: EntitySubtype {
/// The number of selectable combat techniques.
public let number: Int
/// The rating bonus provided for the selected combat technique(s).
///
/// **Note:** This is a rating *bonus*, so it will be *added* to the default
/// value of 6.
public let rating: Int
public init(number: Int, rating: Int) {
self.number = number
self.rating = rating
}
}
/// Select one or more cantrips you receive.
public struct CantripsOptions: EntitySubtype {
/// The number of selectable cantrips.
public let number: Int
/// The list of cantrips to choose from.
public let options: [CantripReference]
public init(number: Int, options: [CantripReference]) {
self.number = number
self.options = options
}
}
/// Buy curses for a specific amount of AP.
public struct CursesOptions: EntitySubtype {
/// The AP value you can buy curses for.
public let apValue: Int
public init(apValue: Int) {
self.apValue = apValue
}
private enum CodingKeys: String, CodingKey {
case apValue = "ap_value"
}
}
/// Select one of a list of possible terrain knowledges
public struct TerrainKnowledgeOptions: EntitySubtype {
/// The list of possible terrain knowledges.
public let options: [TerrainKnowledgeOptionReference]
public init(options: [TerrainKnowledgeOptionReference]) {
self.options = options
}
}
public struct TerrainKnowledgeOptionReference: EntitySubtype {
/// The terrain knowledge option's identifier.
public let id: Int
public init(id: Int) {
self.id = id
}
}
/// Buy skills for a specific amount of AP.
public struct SkillsOptions: EntitySubtype {
/// If specified, you may only choose from skills of the specified group.
public let group: SkillGroupReference?
/// The AP value you can buy skills for.
public let apValue: Int
public init(group: SkillGroupReference? = nil, apValue: Int) {
self.group = group
self.apValue = apValue
}
private enum CodingKeys: String, CodingKey {
case group = "group"
case apValue = "ap_value"
}
}
/// The name of the profession that may have sex-specific names.
public enum ProfessionName: EntitySubtype {
case simpleProfessionName(SimpleProfessionName)
case professionNameBySex(ProfessionNameBySex)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let simpleProfessionName = try? container.decode(SimpleProfessionName.self) {
self = .simpleProfessionName(simpleProfessionName)
} else if let professionNameBySex = try? container.decode(ProfessionNameBySex.self) {
self = .professionNameBySex(professionNameBySex)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No ProfessionName type found")
}
}
}
public typealias SimpleProfessionName = NonEmptyString
public struct ProfessionNameBySex: EntitySubtype {
/// The name from the source publication.
public let `default`: NonEmptyString
/// The male name.
public let male: NonEmptyString
/// The female name.
public let female: NonEmptyString
public init(`default`: NonEmptyString, male: NonEmptyString, female: NonEmptyString) {
self.`default` = `default`
self.male = male
self.female = female
}
private enum CodingKeys: String, CodingKey {
case `default` = "default"
case male = "male"
case female = "female"
}
}
@@ -1,30 +0,0 @@
//
// Property.swift
// OptolithDatabaseSchema
//
public struct Property: LocalizableEntity {
/// The property's identifier. An unique, increasing integer.
public let id: Int
/// The property check's attributes. Only the properties from the Core Rules have defined property checks.
public let check: SkillCheck?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<PropertyTranslation>
public init(id: Int, check: SkillCheck? = nil, translations: LocaleMap<PropertyTranslation>) {
self.id = id
self.check = check
self.translations = translations
}
}
public struct PropertyTranslation: EntitySubtype {
/// The property's name.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,354 +0,0 @@
//
// Race.swift
// OptolithDatabaseSchema
//
/// A playable race with stats and skills.
public struct Race: LocalizableEntity {
/// The race's identifier. An unique, increasing integer.
public let id: Int
/// How many Adventure Points does the race cost during character creation?
public let apValue: Int
/// The races base values.
public let baseValues: BaseValues
/// Describes how to raise or lower maximum attribute values during character creation.
public let attributeAdjustments: AttributeAdjustments
/// A list of automatically applied advantages. This does only work for advantages with no further configuration such as level or special selection.
public let automaticAdvantages: [AdvantageReference]?
/// A list of strongly recommended advantages.
public let stronglyRecommendedAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]?
/// A list of strongly recommended disadvantages.
public let stronglyRecommendedDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]?
/// Configuration for random weight generation.
public let weight: RandomWeightGeneration
/// Defines the starting ages for the race. It depends on the selected experience level.
public let startingAge: [StartingAgeConfigForExperienceLevel]
/// A list of available race variants where one has to be selected. If no variants are to be selected, a single variant with no name has to be provided which will be used as the missing values for the base race.
public let variants: RaceVariants
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<RaceTranslation>
public init(id: Int, apValue: Int, baseValues: BaseValues, attributeAdjustments: AttributeAdjustments, automaticAdvantages: [AdvantageReference]? = nil, stronglyRecommendedAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]? = nil, stronglyRecommendedDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]? = nil, weight: RandomWeightGeneration, startingAge: [StartingAgeConfigForExperienceLevel], variants: RaceVariants, src: PublicationRefs, translations: LocaleMap<RaceTranslation>) {
self.id = id
self.apValue = apValue
self.baseValues = baseValues
self.attributeAdjustments = attributeAdjustments
self.automaticAdvantages = automaticAdvantages
self.stronglyRecommendedAdvantages = stronglyRecommendedAdvantages
self.stronglyRecommendedDisadvantages = stronglyRecommendedDisadvantages
self.weight = weight
self.startingAge = startingAge
self.variants = variants
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case apValue = "ap_value"
case baseValues = "base_values"
case attributeAdjustments = "attribute_adjustments"
case automaticAdvantages = "automatic_advantages"
case stronglyRecommendedAdvantages = "strongly_recommended_advantages"
case stronglyRecommendedDisadvantages = "strongly_recommended_disadvantages"
case weight = "weight"
case startingAge = "starting_age"
case variants = "variants"
case src = "src"
case translations = "translations"
}
}
/// The races base values.
public struct BaseValues: EntitySubtype {
/// The races life point base value.
public let lifePoints: Int
/// The races Spirit base value.
public let spirit: Int
/// The races Toughness base value.
public let toughness: Int
/// The races tactical movement rate.
public let movement: Int
public init(lifePoints: Int, spirit: Int, toughness: Int, movement: Int) {
self.lifePoints = lifePoints
self.spirit = spirit
self.toughness = toughness
self.movement = movement
}
private enum CodingKeys: String, CodingKey {
case lifePoints = "life_points"
case spirit = "spirit"
case toughness = "toughness"
case movement = "movement"
}
}
/// Describes how to raise or lower maximum attribute values during character creation.
public struct AttributeAdjustments: EntitySubtype {
/// The values by which the maximum of the respective attribute is modified.
public let fixed: [FixedAttributeAdjustment]?
/// An array of attribute maximum modifiers, where the attribute they apply to is selected from a list of options.
///
/// The array only permits a single entry because no race specified more than one selectable attribute adjustment so far. But the schema allows for multiple entries to be future-proof.
public let selectable: [SelectableAttributeAdjustment]?
public init(fixed: [FixedAttributeAdjustment]? = nil, selectable: [SelectableAttributeAdjustment]? = nil) {
self.fixed = fixed
self.selectable = selectable
}
}
/// A value by which the maximum of the respective attribute is modified.
public struct FixedAttributeAdjustment: EntitySubtype {
/// The attribute the modifier applies to.
public let id: AttributeIdentifier
/// The value by which the specified attribute's maximum is modified
/// (negative values will lower the maximum).
public let value: Int
public init(id: AttributeIdentifier, value: Int) {
self.id = id
self.value = value
}
}
/// A value that will be added to the current maximum of the selected attribute that has been chosen from the listed attributes (negative values will lower the maximum).
public struct SelectableAttributeAdjustment: EntitySubtype {
/// A list of attributes the player has to choose from.
public let list: [AttributeReference]
/// The value by which the selected attribute's maximum is modified
/// (negative values will lower the maximum).
public let value: Int
public init(list: [AttributeReference], value: Int) {
self.list = list
self.value = value
}
}
/// Configuration for random weight generation.
public struct RandomWeightGeneration: EntitySubtype {
/// The base value used for random weight. The height subtrahend; in case of
/// `Height - 110 + 2D6` it is `110`.
public let base: Int
/// The dice used for random weight.
public let random: [WeightDice]
public init(base: Int, random: [WeightDice]) {
self.base = base
self.random = random
}
}
public struct WeightDice: EntitySubtype {
/// Number of dice of the same type. Example: 2 in 2D6.
public let number: Int
/// Number of sides on every die. Example: 6 in 2D6.
public let sides: DieType
/// The strategy how to offset the randomly generated values against the base value. Either they are all added or subtracted or even results are added and odd results are subtracted.
public let offsetStrategy: WeightDiceOffsetStrategy
public init(number: Int, sides: DieType, offsetStrategy: WeightDiceOffsetStrategy) {
self.number = number
self.sides = sides
self.offsetStrategy = offsetStrategy
}
private enum CodingKeys: String, CodingKey {
case number = "number"
case sides = "sides"
case offsetStrategy = "offset_strategy"
}
}
/// The strategy how to offset the randomly generated values against the base value. Either they are all added or subtracted or even results are added and odd results are subtracted.
public enum WeightDiceOffsetStrategy: String, EntitySubtype {
case add = "Add"
case subtract = "Subtract"
case addEvenSubtractOdd = "AddEvenSubtractOdd"
}
public struct StartingAgeConfigForExperienceLevel: EntitySubtype {
/// The selected experience level's identifier.
public let id: ExperienceLevelIdentifier
/// The base value for the selected experience level.
public let base: Int
/// The random value for the selected experience level. It is going to be added to the base value.
public let random: Dice
public init(id: ExperienceLevelIdentifier, base: Int, random: Dice) {
self.id = id
self.base = base
self.random = random
}
}
/// A list of available race variants where one has to be selected. If no variants are to be selected, a single variant with no name has to be provided which will be used as the missing values for the base race.
public typealias RaceVariants = [RaceVariant]
public struct RaceVariant: EntitySubtype {
/// An unique, increasing integer.
public let id: Int
/// The list of common cultures.
public let commonCultures: [CultureReference]
/// A list of common advantages.
public let commonAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]?
/// A list of common disadvantages.
public let commonDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]?
/// A list of uncommon advantages.
public let uncommonAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]?
/// A list of uncommon disadvantages.
public let uncommonDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]?
/// An array containing 20 (numeric) hair color identifiers. The array also represents the 20-sided die for a random hair color.
public let hairColor: [HairColorReference]
/// An array containing 20 (numeric) eye color identifiers. The array also represents the 20-sided die for a random eye color.
public let eyeColor: [EyeColorReference]
/// Configuration for random height generation.
public let height: Height
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<RaceVariantTranslation>
public init(id: Int, commonCultures: [CultureReference], commonAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]? = nil, commonDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]? = nil, uncommonAdvantages: [CommonnessRatedAdvantageDisadvantage<AdvantageIdentifier>]? = nil, uncommonDisadvantages: [CommonnessRatedAdvantageDisadvantage<DisadvantageIdentifier>]? = nil, hairColor: [HairColorReference], eyeColor: [EyeColorReference], height: Height, translations: LocaleMap<RaceVariantTranslation>) {
self.id = id
self.commonCultures = commonCultures
self.commonAdvantages = commonAdvantages
self.commonDisadvantages = commonDisadvantages
self.uncommonAdvantages = uncommonAdvantages
self.uncommonDisadvantages = uncommonDisadvantages
self.hairColor = hairColor
self.eyeColor = eyeColor
self.height = height
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case commonCultures = "common_cultures"
case commonAdvantages = "common_advantages"
case commonDisadvantages = "common_disadvantages"
case uncommonAdvantages = "uncommon_advantages"
case uncommonDisadvantages = "uncommon_disadvantages"
case hairColor = "hair_color"
case eyeColor = "eye_color"
case height = "height"
case translations = "translations"
}
}
/// Configuration for random height generation.
public struct Height: EntitySubtype {
/// The base value used for random height.
public let base: Int
/// The dice used for random height.
public let random: [Dice]
public init(base: Int, random: [Dice]) {
self.base = base
self.random = random
}
}
public struct RaceVariantTranslation: EntitySubtype {
/// The race variant's name. If left empty, it defaults to the base race name. This can be used if the race has no (visible) variants so that a single variant has to be provided.
public let name: NonEmptyString?
/// The respective common advantages text from the source book.
public let commonAdvantages: NonEmptyString?
/// The respective common disadvantages text from the source book.
public let commonDisadvantages: NonEmptyString?
/// The respective uncommon advantages text from the source book.
public let uncommonAdvantages: NonEmptyString?
/// The respective uncommon disadvantages text from the source book.
public let uncommonDisadvantages: NonEmptyString?
public init(name: NonEmptyString? = nil, commonAdvantages: NonEmptyString? = nil, commonDisadvantages: NonEmptyString? = nil, uncommonAdvantages: NonEmptyString? = nil, uncommonDisadvantages: NonEmptyString? = nil) {
self.name = name
self.commonAdvantages = commonAdvantages
self.commonDisadvantages = commonDisadvantages
self.uncommonAdvantages = uncommonAdvantages
self.uncommonDisadvantages = uncommonDisadvantages
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case commonAdvantages = "common_advantages"
case commonDisadvantages = "common_disadvantages"
case uncommonAdvantages = "uncommon_advantages"
case uncommonDisadvantages = "uncommon_disadvantages"
}
}
public struct RaceTranslation: EntitySubtype {
/// The race's name.
public let name: NonEmptyString
/// The respective attribute adjustments text from the source book.
public let attributeAdjustments: NonEmptyString
/// The respective automatic advantages text from the source book.
public let automaticAdvantages: NonEmptyString?
/// The respective strongly recommended advantages text from the source book.
public let stronglyRecommendedAdvantages: NonEmptyString?
/// The respective strongly recommended disadvantages text from the source book.
public let stronglyRecommendedDisadvantages: NonEmptyString?
public let errata: Errata?
public init(name: NonEmptyString, attributeAdjustments: NonEmptyString, automaticAdvantages: NonEmptyString? = nil, stronglyRecommendedAdvantages: NonEmptyString? = nil, stronglyRecommendedDisadvantages: NonEmptyString? = nil, errata: Errata? = nil) {
self.name = name
self.attributeAdjustments = attributeAdjustments
self.automaticAdvantages = automaticAdvantages
self.stronglyRecommendedAdvantages = stronglyRecommendedAdvantages
self.stronglyRecommendedDisadvantages = stronglyRecommendedDisadvantages
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case attributeAdjustments = "attribute_adjustments"
case automaticAdvantages = "automatic_advantages"
case stronglyRecommendedAdvantages = "strongly_recommended_advantages"
case stronglyRecommendedDisadvantages = "strongly_recommended_disadvantages"
case errata = "errata"
}
}
@@ -1,26 +0,0 @@
//
// Region.swift
// OptolithDatabaseSchema
//
public struct Region: LocalizableEntity {
/// The region's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<RegionTranslation>
public init(id: Int, translations: LocaleMap<RegionTranslation>) {
self.id = id
self.translations = translations
}
}
public struct RegionTranslation: EntitySubtype {
/// The region name.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,116 +0,0 @@
//
// Ritual.swift
// OptolithDatabaseSchema
//
public struct Ritual: LocalizableEntity {
/// The ritual's identifier. An unique, increasing integer.
public let id: Int
/// Lists the linked three attributes used to make a skill check.
public let check: SkillCheck
/// In some cases, the target's Spirit or Toughness is applied as a penalty.
public let checkPenalty: SkillCheckPenalty?
/// Measurable parameters of a ritual.
public let parameters: SlowPerformanceParameters
/// The target category the kind of creature or object the skill affects.
public let `target`: AffectedTargetCategories
/// The associated property.
public let property: PropertyReference
/// The tradition(s) the ritual is available for. It may be *generally* available to all traditions or it may be only familiar in specific traditions.
public let traditions: Traditions
/// States which column is used to improve the skill.
public let improvementCost: ImprovementCost
public let prerequisites: SpellworkPrerequisites?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<RitualTranslation>
public let enhancements: Enhancements?
public init(id: Int, check: SkillCheck, checkPenalty: SkillCheckPenalty? = nil, parameters: SlowPerformanceParameters, `target`: AffectedTargetCategories, property: PropertyReference, traditions: Traditions, improvementCost: ImprovementCost, prerequisites: SpellworkPrerequisites? = nil, src: PublicationRefs, translations: LocaleMap<RitualTranslation>, enhancements: Enhancements? = nil) {
self.id = id
self.check = check
self.checkPenalty = checkPenalty
self.parameters = parameters
self.`target` = `target`
self.property = property
self.traditions = traditions
self.improvementCost = improvementCost
self.prerequisites = prerequisites
self.src = src
self.translations = translations
self.enhancements = enhancements
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case check = "check"
case checkPenalty = "check_penalty"
case parameters = "parameters"
case `target` = "target"
case property = "property"
case traditions = "traditions"
case improvementCost = "improvement_cost"
case prerequisites = "prerequisites"
case src = "src"
case translations = "translations"
case enhancements = "enhancements"
}
}
public struct RitualTranslation: EntitySubtype {
/// The name of the ritual.
public let name: String
/// The effect description may be either a plain text or a text that is divided by a list of effects for each quality level. It may also be a list for each two quality levels.
public let effect: ActivatableSkillEffect
@available(*, deprecated)
public let castingTime: OldParameter
@available(*, deprecated)
public let cost: OldParameter
@available(*, deprecated)
public let range: OldParameter
@available(*, deprecated)
public let duration: OldParameter
@available(*, deprecated)
public let `target`: String
public let errata: Errata?
public init(name: String, effect: ActivatableSkillEffect, castingTime: OldParameter, cost: OldParameter, range: OldParameter, duration: OldParameter, `target`: String, errata: Errata? = nil) {
self.name = name
self.effect = effect
self.castingTime = castingTime
self.cost = cost
self.range = range
self.duration = duration
self.`target` = `target`
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case effect = "effect"
case castingTime = "casting_time"
case cost = "cost"
case range = "range"
case duration = "duration"
case `target` = "target"
case errata = "errata"
}
}
@@ -1,52 +0,0 @@
//
// Service.swift
// OptolithDatabaseSchema
//
public struct Service: LocalizableEntity {
/// The service's identifier. An unique, increasing integer.
public let id: Int
/// Defines for which creature type(s) the service is available.
public let `availability`: [ServiceAvailability]
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ServiceTranslation>
public init(id: Int, `availability`: [ServiceAvailability], src: PublicationRefs, translations: LocaleMap<ServiceTranslation>) {
self.id = id
self.`availability` = `availability`
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case `availability` = "availability"
case src = "src"
case translations = "translations"
}
}
public enum ServiceAvailability: String, EntitySubtype {
case summonedCreatures = "SummonedCreatures"
case monstrosities = "Monstrosities"
}
public struct ServiceTranslation: EntitySubtype {
/// The name of the service.
public let name: NonEmptyString
/// The description of the service.
public let description: NonEmptyMarkdown
public let errata: Errata?
public init(name: NonEmptyString, description: NonEmptyMarkdown, errata: Errata? = nil) {
self.name = name
self.description = description
self.errata = errata
}
}
@@ -1,45 +0,0 @@
//
// SexPractice.swift
// OptolithDatabaseSchema
//
public struct SexPractice: LocalizableEntity {
/// The sex practice's identifier. An unique, increasing integer.
public let id: Int
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<SexPracticeTranslation>
public init(id: Int, src: PublicationRefs, translations: LocaleMap<SexPracticeTranslation>) {
self.id = id
self.src = src
self.translations = translations
}
}
public struct SexPracticeTranslation: EntitySubtype {
/// The sex practice's name.
public let name: NonEmptyString
/// The rules of the sex practice.
public let rules: NonEmptyString
/// How long a round of this sex practice takes.
public let duration: NonEmptyString
/// Prerequisites of participants and environment. Do not specify if the sex practice has no prerequisites.
public let prerequisites: NonEmptyString?
/// Effects of a failed *Seduction* check.
public let failed: NonEmptyString
public init(name: NonEmptyString, rules: NonEmptyString, duration: NonEmptyString, prerequisites: NonEmptyString? = nil, failed: NonEmptyString) {
self.name = name
self.rules = rules
self.duration = duration
self.prerequisites = prerequisites
self.failed = failed
}
}
@@ -1,171 +0,0 @@
//
// Skill.swift
// OptolithDatabaseSchema
//
public struct Skill: LocalizableEntity {
/// The skill's identifier. An unique, increasing integer.
public let id: Int
/// Lists the linked three attributes used to make a skill check.
public let check: SkillCheck
/// Lists applications for the skill, if any. This does not necessarily include all possible applications. There may also be new applications that could be purchased via certain advantages or special abilities.
public let applications: Applications
/// Indicates whether encumbrance gives a penalty for checks with the skill.
public let encumbrance: EncumbranceInfluence
/// States which column is used to improve the skill.
public let improvementCost: ImprovementCost
/// The skill group this skill belongs to.
public let group: SkillGroupReference
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<SkillTranslation>
public init(id: Int, check: SkillCheck, applications: Applications, encumbrance: EncumbranceInfluence, improvementCost: ImprovementCost, group: SkillGroupReference, src: PublicationRefs, translations: LocaleMap<SkillTranslation>) {
self.id = id
self.check = check
self.applications = applications
self.encumbrance = encumbrance
self.improvementCost = improvementCost
self.group = group
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case check = "check"
case applications = "applications"
case encumbrance = "encumbrance"
case improvementCost = "improvement_cost"
case group = "group"
case src = "src"
case translations = "translations"
}
}
public struct SkillTranslation: EntitySubtype {
/// The name of the skill.
public let name: NonEmptyString
/// If there are options available that can not be put into a selection list (like different cults), provide the label text for the input element here. Otherwise leave empty.
public let applicationsInputLabel: NonEmptyString?
/// The text listing the certain circumstances in which the encumbrance may count. This text must be used if `encumbrance` is set to `"Maybe"`, otherwise it is ignored if defined.
public let encumbranceDescription: NonEmptyString?
/// Mentions any tools from the equipment list that are necessary to employ the skill.
public let tools: NonEmptyMarkdown?
/// Gives examples of the effects that various QL might provide.
public let quality: NonEmptyMarkdown
/// Lists examples of results for a failed check.
public let failed: NonEmptyMarkdown
/// Lists examples of results for a critical success.
public let critical: NonEmptyMarkdown
/// Lists examples of results for botches.
public let botch: NonEmptyMarkdown
public let errata: Errata?
public init(name: NonEmptyString, applicationsInputLabel: NonEmptyString? = nil, encumbranceDescription: NonEmptyString? = nil, tools: NonEmptyMarkdown? = nil, quality: NonEmptyMarkdown, failed: NonEmptyMarkdown, critical: NonEmptyMarkdown, botch: NonEmptyMarkdown, errata: Errata? = nil) {
self.name = name
self.applicationsInputLabel = applicationsInputLabel
self.encumbranceDescription = encumbranceDescription
self.tools = tools
self.quality = quality
self.failed = failed
self.critical = critical
self.botch = botch
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case applicationsInputLabel = "applications_input_label"
case encumbranceDescription = "encumbrance_description"
case tools = "tools"
case quality = "quality"
case failed = "failed"
case critical = "critical"
case botch = "botch"
case errata = "errata"
}
}
/// A category. All available entries from the specified category will be included as separate applications.
public enum ApplicationCategory: String, EntitySubtype {
case blessedTraditions = "BlessedTraditions"
case diseases = "Diseases"
case regions = "Regions"
}
/// The skill's applications.
public enum Applications: EntitySubtype {
case derived(ApplicationCategory)
case explicit(SpecificApplications)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case derived = "derived"
case explicit = "explicit"
}
private enum Discriminator: String, Decodable {
case derived = "Derived"
case explicit = "Explicit"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .derived:
self = .derived(try container.decode(ApplicationCategory.self, forKey: .derived))
case .explicit:
self = .explicit(try container.decode(SpecificApplications.self, forKey: .explicit))
}
}
}
/// A list of explicit applications.
public typealias SpecificApplications = [Application]
/// An explicit skill application.
public struct Application: EntitySubtype {
/// The skill application's identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ApplicationTranslation>
public init(id: Int, translations: LocaleMap<ApplicationTranslation>) {
self.id = id
self.translations = translations
}
}
public struct ApplicationTranslation: EntitySubtype {
/// The skill application's name.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
/// Indicates whether encumbrance gives a penalty for checks with the skill.
public enum EncumbranceInfluence: String, EntitySubtype {
case `true` = "True"
case `false` = "False"
case maybe = "Maybe"
}
@@ -1,39 +0,0 @@
//
// SkillGroup.swift
// OptolithDatabaseSchema
//
public struct SkillGroup: LocalizableEntity {
/// The skill group's identifier. An unique, increasing integer.
public let id: Int
/// The skill group check's attributes.
public let check: SkillCheck
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<SkillGroupTranslation>
public init(id: Int, check: SkillCheck, translations: LocaleMap<SkillGroupTranslation>) {
self.id = id
self.check = check
self.translations = translations
}
}
public struct SkillGroupTranslation: EntitySubtype {
/// The skill group's name.
public let name: NonEmptyString
/// The skill group's long name.
public let longName: NonEmptyString
public init(name: NonEmptyString, longName: NonEmptyString) {
self.name = name
self.longName = longName
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case longName = "long_name"
}
}
@@ -1,111 +0,0 @@
//
// SkillModificationLevel.swift
// OptolithDatabaseSchema
//
public struct SkillModificationLevel: Entity {
/// The skill modification level's identifier.
public let id: Int
/// Configuration for this level for fast skills (spells, liturgical chants).
public let fast: FastSkillModificationLevelConfig
/// Configuration for this level for slow skills (rituals, ceremonies).
public let slow: SlowSkillModificationLevelConfig
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<SkillModificationLevelTranslation>?
public init(id: Int, fast: FastSkillModificationLevelConfig, slow: SlowSkillModificationLevelConfig, translations: LocaleMap<SkillModificationLevelTranslation>? = nil) {
self.id = id
self.fast = fast
self.slow = slow
self.translations = translations
}
}
public struct FastSkillModificationLevelConfig: EntitySubtype {
/// The casting time in actions.
public let castingTime: Int
/// The range in meters.
public let range: Int
/// The cost in AE/KP.
public let cost: Int
public init(castingTime: Int, range: Int, cost: Int) {
self.castingTime = castingTime
self.range = range
self.cost = cost
}
private enum CodingKeys: String, CodingKey {
case castingTime = "casting_time"
case range = "range"
case cost = "cost"
}
}
public struct SlowSkillModificationLevelConfig: EntitySubtype {
/// The casting time.
public let castingTime: SlowSkillCastingTime
/// The range in meters.
public let range: Int
/// The cost in AE/KP.
public let cost: Int
public init(castingTime: SlowSkillCastingTime, range: Int, cost: Int) {
self.castingTime = castingTime
self.range = range
self.cost = cost
}
private enum CodingKeys: String, CodingKey {
case castingTime = "casting_time"
case range = "range"
case cost = "cost"
}
}
public struct SlowSkillCastingTime: EntitySubtype {
/// The (unitless) casting time.
public let value: Int
/// The unit for the `value`.
public let unit: SlowSkillCastingTimeUnit
public init(value: Int, unit: SlowSkillCastingTimeUnit) {
self.value = value
self.unit = unit
}
}
public enum SlowSkillCastingTimeUnit: String, EntitySubtype {
case minutes = "Minutes"
case hours = "Hours"
}
public struct SkillModificationLevelTranslation: EntitySubtype {
/// Configuration for this level for fast skills (spells, liturgical chants). Values set here override the default generated text.
public let fast: LevelTypeConfigTranslation?
/// Configuration for this level for slow skills (rituals, ceremonies). Values set here override the default generated text.
public let slow: LevelTypeConfigTranslation?
public init(fast: LevelTypeConfigTranslation? = nil, slow: LevelTypeConfigTranslation? = nil) {
self.fast = fast
self.slow = slow
}
}
/// Configuration translation of a type for a level. Values set here override the default generated text.
public struct LevelTypeConfigTranslation: EntitySubtype {
public let range: NonEmptyString
public init(range: NonEmptyString) {
self.range = range
}
}
@@ -1,26 +0,0 @@
//
// SocialStatus.swift
// OptolithDatabaseSchema
//
public struct SocialStatus: LocalizableEntity {
/// The social status' identifier. An unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<SocialStatusTranslation>
public init(id: Int, translations: LocaleMap<SocialStatusTranslation>) {
self.id = id
self.translations = translations
}
}
public struct SocialStatusTranslation: EntitySubtype {
/// The social status name.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,116 +0,0 @@
//
// Spell.swift
// OptolithDatabaseSchema
//
public struct Spell: LocalizableEntity {
/// The spell's identifier. An unique, increasing integer.
public let id: Int
/// Lists the linked three attributes used to make a skill check.
public let check: SkillCheck
/// In some cases, the target's Spirit or Toughness is applied as a penalty.
public let checkPenalty: SkillCheckPenalty?
/// Measurable parameters of a spell.
public let parameters: FastPerformanceParameters
/// The target category the kind of creature or object the skill affects.
public let `target`: AffectedTargetCategories
/// The associated property.
public let property: PropertyReference
/// The tradition(s) the spell is available for. It may be *generally* available to all traditions or it may be only familiar in specific traditions.
public let traditions: Traditions
/// States which column is used to improve the skill.
public let improvementCost: ImprovementCost
public let prerequisites: SpellworkPrerequisites?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<SpellTranslation>
public let enhancements: Enhancements?
public init(id: Int, check: SkillCheck, checkPenalty: SkillCheckPenalty? = nil, parameters: FastPerformanceParameters, `target`: AffectedTargetCategories, property: PropertyReference, traditions: Traditions, improvementCost: ImprovementCost, prerequisites: SpellworkPrerequisites? = nil, src: PublicationRefs, translations: LocaleMap<SpellTranslation>, enhancements: Enhancements? = nil) {
self.id = id
self.check = check
self.checkPenalty = checkPenalty
self.parameters = parameters
self.`target` = `target`
self.property = property
self.traditions = traditions
self.improvementCost = improvementCost
self.prerequisites = prerequisites
self.src = src
self.translations = translations
self.enhancements = enhancements
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case check = "check"
case checkPenalty = "check_penalty"
case parameters = "parameters"
case `target` = "target"
case property = "property"
case traditions = "traditions"
case improvementCost = "improvement_cost"
case prerequisites = "prerequisites"
case src = "src"
case translations = "translations"
case enhancements = "enhancements"
}
}
public struct SpellTranslation: EntitySubtype {
/// The name of the spell.
public let name: NonEmptyString
/// The effect description may be either a plain text or a text that is divided by a list of effects for each quality level. It may also be a list for each two quality levels.
public let effect: ActivatableSkillEffect
@available(*, deprecated)
public let castingTime: OldParameter
@available(*, deprecated)
public let cost: OldParameter
@available(*, deprecated)
public let range: OldParameter
@available(*, deprecated)
public let duration: OldParameter
@available(*, deprecated)
public let `target`: String
public let errata: Errata?
public init(name: NonEmptyString, effect: ActivatableSkillEffect, castingTime: OldParameter, cost: OldParameter, range: OldParameter, duration: OldParameter, `target`: String, errata: Errata? = nil) {
self.name = name
self.effect = effect
self.castingTime = castingTime
self.cost = cost
self.range = range
self.duration = duration
self.`target` = `target`
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case effect = "effect"
case castingTime = "casting_time"
case cost = "cost"
case range = "range"
case duration = "duration"
case `target` = "target"
case errata = "errata"
}
}
@@ -1,36 +0,0 @@
//
// State.swift
// OptolithDatabaseSchema
//
public struct State: LocalizableEntity {
/// The state's identifier. An unique, increasing integer.
public let id: Int
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<StateTranslation>
public init(id: Int, src: PublicationRefs, translations: LocaleMap<StateTranslation>) {
self.id = id
self.src = src
self.translations = translations
}
}
public struct StateTranslation: EntitySubtype {
/// The name of the state.
public let name: NonEmptyString
/// The description of the state.
public let description: NonEmptyMarkdown
public let errata: Errata?
public init(name: NonEmptyString, description: NonEmptyMarkdown, errata: Errata? = nil) {
self.name = name
self.description = description
self.errata = errata
}
}
@@ -1,82 +0,0 @@
//
// Talisman.swift
// OptolithDatabaseSchema
//
public struct Talisman: LocalizableEntity {
/// The talisman's identifier. An unique, increasing integer.
public let id: Int
/// The tradition(s) the talisman belongs to.
public let tradition: [BlessedTraditionReference]
/// The talisman type, if any.
public let type: TalismanType?
/// The AP value for the required trade secret, if possible.
public let apValue: Int?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<TalismanTranslation>
public init(id: Int, tradition: [BlessedTraditionReference], type: TalismanType? = nil, apValue: Int? = nil, src: PublicationRefs, translations: LocaleMap<TalismanTranslation>) {
self.id = id
self.tradition = tradition
self.type = type
self.apValue = apValue
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case tradition = "tradition"
case type = "type"
case apValue = "ap_value"
case src = "src"
case translations = "translations"
}
}
public enum TalismanType: String, EntitySubtype {
case mainTalisman = "MainTalisman"
case talisman = "Talisman"
case minorTalisman = "MinorTalisman"
case regalia = "Regalia"
case powerfulTalisman = "PowerfulTalisman"
}
public struct TalismanTranslation: EntitySubtype {
/// The name of the talisman.
public let name: NonEmptyString
/// The effect description.
public let effect: NonEmptyMarkdown
/// The activation parameters.
public let activation: TalismanActivationTranslation?
public let errata: Errata?
public init(name: NonEmptyString, effect: NonEmptyMarkdown, activation: TalismanActivationTranslation? = nil, errata: Errata? = nil) {
self.name = name
self.effect = effect
self.activation = activation
self.errata = errata
}
}
public struct TalismanActivationTranslation: EntitySubtype {
/// The KP cost.
public let cost: Int
/// The duration.
public let duration: NonEmptyString
public init(cost: Int, duration: NonEmptyString) {
self.cost = cost
self.duration = duration
}
}
@@ -1,40 +0,0 @@
//
// TargetCategory.swift
// OptolithDatabaseSchema
//
public struct TargetCategory: LocalizableEntity {
/// The target category's identifier. An unique, increasing integer.
public let id: Int
/// A superordinate target category, if present.
public let parent: TargetCategoryParent?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<TargetCategoryTranslation>
public init(id: Int, parent: TargetCategoryParent? = nil, translations: LocaleMap<TargetCategoryTranslation>) {
self.id = id
self.parent = parent
self.translations = translations
}
}
/// A superordinate target category, if present.
public struct TargetCategoryParent: EntitySubtype {
/// The identifier of the superordinate target category.
public let id: TargetCategoryIdentifier
public init(id: TargetCategoryIdentifier) {
self.id = id
}
}
public struct TargetCategoryTranslation: EntitySubtype {
/// The target category name.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
File diff suppressed because it is too large Load Diff
@@ -1,594 +0,0 @@
//
// _ActivatableSelectOptionCategory.swift
// OptolithDatabaseSchema
//
public enum SelectOptionCategory: EntitySubtype {
case blessings
case cantrips
case tradeSecrets
case scripts
case animalShapes
case arcaneBardTraditions
case arcaneDancerTraditions
case sexPractices
case races
case cultures
case racesAndCultures
case blessedTraditions(BlessedTraditionsSelectOptionCategory)
case elements(ElementsSelectOptionCategory)
case properties(PropertiesSelectOptionCategory)
case aspects(AspectSelectOptionCategory)
case diseases(DiseasesPoisonsSelectOptionCategory)
case poisons(DiseasesPoisonsSelectOptionCategory)
case languages(LanguagesSelectOptionCategory)
case skills(SkillsSelectOptionCategory)
case combatTechniques(CombatTechniquesSelectOptionCategory)
case targetCategories(TargetCategoriesSelectOptionCategory)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case blessings = "blessings"
case cantrips = "cantrips"
case tradeSecrets = "trade_secrets"
case scripts = "scripts"
case animalShapes = "animal_shapes"
case arcaneBardTraditions = "arcane_bard_traditions"
case arcaneDancerTraditions = "arcane_dancer_traditions"
case sexPractices = "sex_practices"
case races = "races"
case cultures = "cultures"
case racesAndCultures = "races_and_cultures"
case blessedTraditions = "blessed_traditions"
case elements = "elements"
case properties = "properties"
case aspects = "aspects"
case diseases = "diseases"
case poisons = "poisons"
case languages = "languages"
case skills = "skills"
case combatTechniques = "combat_techniques"
case targetCategories = "target_categories"
}
private enum Discriminator: String, Decodable {
case blessings = "Blessings"
case cantrips = "Cantrips"
case tradeSecrets = "TradeSecrets"
case scripts = "Scripts"
case animalShapes = "AnimalShapes"
case arcaneBardTraditions = "ArcaneBardTraditions"
case arcaneDancerTraditions = "ArcaneDancerTraditions"
case sexPractices = "SexPractices"
case races = "Races"
case cultures = "Cultures"
case racesAndCultures = "RacesAndCultures"
case blessedTraditions = "BlessedTraditions"
case elements = "Elements"
case properties = "Properties"
case aspects = "Aspects"
case diseases = "Diseases"
case poisons = "Poisons"
case languages = "Languages"
case skills = "Skills"
case combatTechniques = "CombatTechniques"
case targetCategories = "TargetCategories"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .blessings:
self = .blessings
case .cantrips:
self = .cantrips
case .tradeSecrets:
self = .tradeSecrets
case .scripts:
self = .scripts
case .animalShapes:
self = .animalShapes
case .arcaneBardTraditions:
self = .arcaneBardTraditions
case .arcaneDancerTraditions:
self = .arcaneDancerTraditions
case .sexPractices:
self = .sexPractices
case .races:
self = .races
case .cultures:
self = .cultures
case .racesAndCultures:
self = .racesAndCultures
case .blessedTraditions:
self = .blessedTraditions(try container.decode(BlessedTraditionsSelectOptionCategory.self, forKey: .blessedTraditions))
case .elements:
self = .elements(try container.decode(ElementsSelectOptionCategory.self, forKey: .elements))
case .properties:
self = .properties(try container.decode(PropertiesSelectOptionCategory.self, forKey: .properties))
case .aspects:
self = .aspects(try container.decode(AspectSelectOptionCategory.self, forKey: .aspects))
case .diseases:
self = .diseases(try container.decode(DiseasesPoisonsSelectOptionCategory.self, forKey: .diseases))
case .poisons:
self = .poisons(try container.decode(DiseasesPoisonsSelectOptionCategory.self, forKey: .poisons))
case .languages:
self = .languages(try container.decode(LanguagesSelectOptionCategory.self, forKey: .languages))
case .skills:
self = .skills(try container.decode(SkillsSelectOptionCategory.self, forKey: .skills))
case .combatTechniques:
self = .combatTechniques(try container.decode(CombatTechniquesSelectOptionCategory.self, forKey: .combatTechniques))
case .targetCategories:
self = .targetCategories(try container.decode(TargetCategoriesSelectOptionCategory.self, forKey: .targetCategories))
}
}
}
public struct BlessedTraditionsSelectOptionCategory: EntitySubtype {
/// Should the principles (code) of the tradition be required to select the respective tradition?
public let requirePrinciples: Bool?
public init(requirePrinciples: Bool? = nil) {
self.requirePrinciples = requirePrinciples
}
private enum CodingKeys: String, CodingKey {
case requirePrinciples = "require_principles"
}
}
public struct ElementsSelectOptionCategory: EntitySubtype {
/// Only include entries with the listed identifiers.
public let specific: [ElementReference]?
public init(specific: [ElementReference]? = nil) {
self.specific = specific
}
}
public struct PropertiesSelectOptionCategory: EntitySubtype {
/// Does each property require it's corresponding property knowledge?
public let requireKnowledge: Bool?
/// Require a minimum number of spellworks of the respective property to be on a minimum skill rating.
public let requireMinimumSpellworksOn: RequiredMinimumSkillsToBeOnSkillRating?
public init(requireKnowledge: Bool? = nil, requireMinimumSpellworksOn: RequiredMinimumSkillsToBeOnSkillRating? = nil) {
self.requireKnowledge = requireKnowledge
self.requireMinimumSpellworksOn = requireMinimumSpellworksOn
}
private enum CodingKeys: String, CodingKey {
case requireKnowledge = "require_knowledge"
case requireMinimumSpellworksOn = "require_minimum_spellworks_on"
}
}
public struct AspectSelectOptionCategory: EntitySubtype {
/// Does each aspect require it's corresponding aspect knowledge?
public let requireKnowledge: Bool?
/// The generated name should be the *Master of (Aspect)* suffix for this aspect instead of the aspect's name. If an aspect does not provide a suffix (such as the General aspect), it is automatically excluded from the list.
public let useMasterOfSuffixAsName: Bool?
/// Require a minimum number of liturgies of the respective aspect to be on a minimum skill rating.
public let requireMinimumLiturgiesOn: RequiredMinimumSkillsToBeOnSkillRating?
public init(requireKnowledge: Bool? = nil, useMasterOfSuffixAsName: Bool? = nil, requireMinimumLiturgiesOn: RequiredMinimumSkillsToBeOnSkillRating? = nil) {
self.requireKnowledge = requireKnowledge
self.useMasterOfSuffixAsName = useMasterOfSuffixAsName
self.requireMinimumLiturgiesOn = requireMinimumLiturgiesOn
}
private enum CodingKeys: String, CodingKey {
case requireKnowledge = "require_knowledge"
case useMasterOfSuffixAsName = "use_master_of_suffix_as_name"
case requireMinimumLiturgiesOn = "require_minimum_liturgies_on"
}
}
/// Require a minimum number of spellworks/liturgies of the respective property/aspect to be on a minimum skill rating.
public struct RequiredMinimumSkillsToBeOnSkillRating: EntitySubtype {
/// The minimum number of liturgies that need to be on the defined minimum skill rating.
public let number: Int
/// The minimum skill rating the defined minimum number of liturgies need to be on.
public let rating: Int
public init(number: Int, rating: Int) {
self.number = number
self.rating = rating
}
}
public struct DiseasesPoisonsSelectOptionCategory: EntitySubtype {
/// Only convert half the disease/poison level into the AP value.
public let useHalfLevelAsApValue: Bool?
public init(useHalfLevelAsApValue: Bool? = nil) {
self.useHalfLevelAsApValue = useHalfLevelAsApValue
}
private enum CodingKeys: String, CodingKey {
case useHalfLevelAsApValue = "use_half_level_as_ap_value"
}
}
public struct LanguagesSelectOptionCategory: EntitySubtype {
/// Generate prerequisites for each entry of the category.
public let prerequisites: [LanguagesSelectOptionCategoryPrerequisite]?
public init(prerequisites: [LanguagesSelectOptionCategoryPrerequisite]? = nil) {
self.prerequisites = prerequisites
}
}
public struct LanguagesSelectOptionCategoryPrerequisite: EntitySubtype {
public let tag: String
public let selectOption: OptionPrerequisite
public init(tag: String, selectOption: OptionPrerequisite) {
self.tag = tag
self.selectOption = selectOption
}
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case selectOption = "select_option"
}
}
public struct SkillsSelectOptionCategory: EntitySubtype {
/// A list of skill categories.
public let categories: [SkillsSelectOptionCategoryCategory]
/// Generate AP values for each entry.
public let apValue: SelectOptionsAdventurePointsValue<SkillishIdentifier>?
public init(categories: [SkillsSelectOptionCategoryCategory], apValue: SelectOptionsAdventurePointsValue<SkillishIdentifier>? = nil) {
self.categories = categories
self.apValue = apValue
}
private enum CodingKeys: String, CodingKey {
case categories = "categories"
case apValue = "ap_value"
}
}
public enum SkillsSelectOptionCategoryCategory: EntitySubtype {
case skills(SkillSelectOptionCategoryCategory)
case spells(GenericSkillsSelectOptionCategoryCategory<SpellReference>)
case rituals(GenericSkillsSelectOptionCategoryCategory<RitualReference>)
case liturgicalChants(GenericSkillsSelectOptionCategoryCategory<LiturgicalChantReference>)
case ceremonies(GenericSkillsSelectOptionCategoryCategory<CeremonyReference>)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case skills = "skills"
case spells = "spells"
case rituals = "rituals"
case liturgicalChants = "liturgical_chants"
case ceremonies = "ceremonies"
}
private enum Discriminator: String, Decodable {
case skills = "Skills"
case spells = "Spells"
case rituals = "Rituals"
case liturgicalChants = "LiturgicalChants"
case ceremonies = "Ceremonies"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .skills:
self = .skills(try container.decode(SkillSelectOptionCategoryCategory.self, forKey: .skills))
case .spells:
self = .spells(try container.decode(GenericSkillsSelectOptionCategoryCategory<SpellReference>.self, forKey: .spells))
case .rituals:
self = .rituals(try container.decode(GenericSkillsSelectOptionCategoryCategory<RitualReference>.self, forKey: .rituals))
case .liturgicalChants:
self = .liturgicalChants(try container.decode(GenericSkillsSelectOptionCategoryCategory<LiturgicalChantReference>.self, forKey: .liturgicalChants))
case .ceremonies:
self = .ceremonies(try container.decode(GenericSkillsSelectOptionCategoryCategory<CeremonyReference>.self, forKey: .ceremonies))
}
}
}
public struct SkillSelectOptionCategoryCategory: EntitySubtype {
/// Only include entries of the specified groups.
public let groups: [SkillGroupReference]?
/// Only include (`Intersection`) or exclude (`Difference`) specific skills.
public let specific: SpecificFromSkillSelectOptionCategoryCategory<SkillReference>?
/// Registers new applications, which get enabled once this entry is activated with its respective select option. It specifies an entry-unique identifier, the skill it belongs to is derived from the select option automatically. A translation can be left out if its name equals the name of the origin entry.
public let skillApplications: [SkillApplicationOrUse]?
/// Registers uses, which get enabled once this entry is activated with its respective select option. It specifies an entry-unique identifier, the skill it belongs to is derived from the select option automatically. A translation can be left out if its name equals the name of the origin entry.
public let skillUses: [SkillApplicationOrUse]?
/// Generate prerequisites for each entry of the category.
public let prerequisites: [SkillSelectOptionCategoryPrerequisite]?
/// Generate AP values for each entry.
public let apValue: SelectOptionsAdventurePointsValue<SkillIdentifier>?
public init(groups: [SkillGroupReference]? = nil, specific: SpecificFromSkillSelectOptionCategoryCategory<SkillReference>? = nil, skillApplications: [SkillApplicationOrUse]? = nil, skillUses: [SkillApplicationOrUse]? = nil, prerequisites: [SkillSelectOptionCategoryPrerequisite]? = nil, apValue: SelectOptionsAdventurePointsValue<SkillIdentifier>? = nil) {
self.groups = groups
self.specific = specific
self.skillApplications = skillApplications
self.skillUses = skillUses
self.prerequisites = prerequisites
self.apValue = apValue
}
private enum CodingKeys: String, CodingKey {
case groups = "groups"
case specific = "specific"
case skillApplications = "skill_applications"
case skillUses = "skill_uses"
case prerequisites = "prerequisites"
case apValue = "ap_value"
}
}
public struct CombatTechniquesSelectOptionCategory: EntitySubtype {
/// A list of combat technique categories.
public let categories: [CombatTechniquesSelectOptionCategoryCategory]
/// Generate AP values for each entry.
public let apValue: SelectOptionsAdventurePointsValue<CombatTechniqueIdentifier>?
public init(categories: [CombatTechniquesSelectOptionCategoryCategory], apValue: SelectOptionsAdventurePointsValue<CombatTechniqueIdentifier>? = nil) {
self.categories = categories
self.apValue = apValue
}
private enum CodingKeys: String, CodingKey {
case categories = "categories"
case apValue = "ap_value"
}
}
public enum CombatTechniquesSelectOptionCategoryCategory: EntitySubtype {
case closeCombatTechniques(GenericSkillsSelectOptionCategoryCategory<CloseCombatTechniqueReference>)
case rangedCombatTechniques(GenericSkillsSelectOptionCategoryCategory<RangedCombatTechniqueReference>)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case closeCombatTechniques = "close_combat_techniques"
case rangedCombatTechniques = "ranged_combat_techniques"
}
private enum Discriminator: String, Decodable {
case closeCombatTechniques = "CloseCombatTechniques"
case rangedCombatTechniques = "RangedCombatTechniques"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .closeCombatTechniques:
self = .closeCombatTechniques(try container.decode(GenericSkillsSelectOptionCategoryCategory<CloseCombatTechniqueReference>.self, forKey: .closeCombatTechniques))
case .rangedCombatTechniques:
self = .rangedCombatTechniques(try container.decode(GenericSkillsSelectOptionCategoryCategory<RangedCombatTechniqueReference>.self, forKey: .rangedCombatTechniques))
}
}
}
public struct SkillApplicationOrUse: EntitySubtype {
/// The application's or use's identifier. An entry-unique, increasing integer.
public let id: Int
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<SkillApplicationOrUseTranslation>?
public init(id: Int, translations: LocaleMap<SkillApplicationOrUseTranslation>? = nil) {
self.id = id
self.translations = translations
}
}
public struct SkillApplicationOrUseTranslation: EntitySubtype {
/// The name of the application or use if different from the activatable entry's name.
public let name: String
public init(name: String) {
self.name = name
}
}
public struct GenericSkillsSelectOptionCategoryCategory<Ref: EntitySubtype>: EntitySubtype {
/// Only include (`Intersection`) or exclude (`Difference`) specific entries.
public let specific: SpecificFromSkillSelectOptionCategoryCategory<Ref>?
/// Generate prerequisites for each entry of the category.
public let prerequisites: [SkillSelectOptionCategoryPrerequisite]?
public init(specific: SpecificFromSkillSelectOptionCategoryCategory<Ref>? = nil, prerequisites: [SkillSelectOptionCategoryPrerequisite]? = nil) {
self.specific = specific
self.prerequisites = prerequisites
}
}
public struct SpecificFromSkillSelectOptionCategoryCategory<Ref: EntitySubtype>: EntitySubtype {
public let operation: SpecificFromSkillSelectOptionCategoryCategoryOperation
/// The list of specific entries.
public let list: [Ref]
public init(operation: SpecificFromSkillSelectOptionCategoryCategoryOperation, list: [Ref]) {
self.operation = operation
self.list = list
}
}
/// Only include (`Intersection`) or exclude (`Difference`) specific entries.
public enum SpecificFromSkillSelectOptionCategoryCategoryOperation: String, EntitySubtype {
case intersection = "Intersection"
case difference = "Difference"
}
public enum SkillSelectOptionCategoryPrerequisite: EntitySubtype {
case `self`(SelfPrerequisite)
case selectOption(OptionPrerequisite)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case `self` = "self"
case selectOption = "select_option"
}
private enum Discriminator: String, Decodable {
case `self` = "Self"
case selectOption = "SelectOption"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .`self`:
self = .`self`(try container.decode(SelfPrerequisite.self, forKey: .`self`))
case .selectOption:
self = .selectOption(try container.decode(OptionPrerequisite.self, forKey: .selectOption))
}
}
}
public struct SelfPrerequisite: EntitySubtype {
/// The entry requires itself on a certain Skill Rating.
public let value: Int
public init(value: Int) {
self.value = value
}
}
/// The entry requires or prohibits itself as a select option of another entry.
public struct OptionPrerequisite: EntitySubtype {
/// The target entry's identifier.
public let id: ActivatableIdentifier
/// Is the select option required (`true`) or prohibited (`false`)?
public let active: Bool
/// The required level, if any.
public let level: Int?
public init(id: ActivatableIdentifier, active: Bool, level: Int? = nil) {
self.id = id
self.active = active
self.level = level
}
}
/// Generate AP values for each entry.
public enum SelectOptionsAdventurePointsValue<Identifier: EntitySubtype>: EntitySubtype {
case derivedFromImprovementCost(SelectOptionsDeriveAdventurePointsValueFromImprovementCost)
case fixed(SelectOptionsFixedAdventurePointsValue<Identifier>)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case derivedFromImprovementCost = "derived_from_improvement_cost"
case fixed = "fixed"
}
private enum Discriminator: String, Decodable {
case derivedFromImprovementCost = "DerivedFromImprovementCost"
case fixed = "Fixed"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .derivedFromImprovementCost:
self = .derivedFromImprovementCost(try container.decode(SelectOptionsDeriveAdventurePointsValueFromImprovementCost.self, forKey: .derivedFromImprovementCost))
case .fixed:
self = .fixed(try container.decode(SelectOptionsFixedAdventurePointsValue<Identifier>.self, forKey: .fixed))
}
}
}
/// Derive the cost from the improvement cost of each entry.
///
/// **Calculation:** AP Value = Improvement Cost × `multiplier` + `offset`
public struct SelectOptionsDeriveAdventurePointsValueFromImprovementCost: EntitySubtype {
/// This number is multiplied with the improvement cost of the entry
/// (A = 1 to D = 4).
public let multiplier: Int?
/// This number is added to the multiplied improvement cost of the entry.
public let offset: Int?
public init(multiplier: Int? = nil, offset: Int? = nil) {
self.multiplier = multiplier
self.offset = offset
}
}
public struct SelectOptionsFixedAdventurePointsValue<Identifier: EntitySubtype>: EntitySubtype {
/// A mapping of skill identifiers to their specific AP values.
public let map: [SelectOptionsFixedAdventurePointsValueMapping<Identifier>]
/// The default value of an entry. Used as a fallback if no value is found in `list`.
public let `default`: Int
public init(map: [SelectOptionsFixedAdventurePointsValueMapping<Identifier>], `default`: Int) {
self.map = map
self.`default` = `default`
}
private enum CodingKeys: String, CodingKey {
case map = "map"
case `default` = "default"
}
}
public struct SelectOptionsFixedAdventurePointsValueMapping<Identifier: EntitySubtype>: EntitySubtype {
/// The entry's identifier.
public let id: Identifier
/// The AP value for the specified entry.
public let apValue: Int
public init(id: Identifier, apValue: Int) {
self.id = id
self.apValue = apValue
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case apValue = "ap_value"
}
}
public struct TargetCategoriesSelectOptionCategory: EntitySubtype {
/// A list of combat technique categories.
public let list: [SpecificTargetCategory]
public init(list: [SpecificTargetCategory]) {
self.list = list
}
}
public struct SpecificTargetCategory: EntitySubtype {
/// The target categorys identifier.
public let id: TargetCategoryIdentifier
/// The volume for this specific selection.
public let volume: Int?
public init(id: TargetCategoryIdentifier, volume: Int? = nil) {
self.id = id
self.volume = volume
}
}
@@ -1,125 +0,0 @@
//
// _ActivatableSkill.swift
// OptolithDatabaseSchema
//
public struct OneTimePerformanceParameters<CastingTime: EntitySubtype>: EntitySubtype {
public let castingTime: CastingTime
public let cost: OneTimeCost
public let range: Range
public let duration: DurationForOneTime
public init(castingTime: CastingTime, cost: OneTimeCost, range: Range, duration: DurationForOneTime) {
self.castingTime = castingTime
self.cost = cost
self.range = range
self.duration = duration
}
private enum CodingKeys: String, CodingKey {
case castingTime = "casting_time"
case cost = "cost"
case range = "range"
case duration = "duration"
}
}
public struct SustainedPerformanceParameters<CastingTime: EntitySubtype>: EntitySubtype {
public let castingTime: CastingTime
public let cost: SustainedCost
public let range: Range
public let duration: DurationForSustained?
public init(castingTime: CastingTime, cost: SustainedCost, range: Range, duration: DurationForSustained? = nil) {
self.castingTime = castingTime
self.cost = cost
self.range = range
self.duration = duration
}
private enum CodingKeys: String, CodingKey {
case castingTime = "casting_time"
case cost = "cost"
case range = "range"
case duration = "duration"
}
}
public enum FastPerformanceParameters: EntitySubtype {
case oneTime(FastOneTimePerformanceParameters)
case sustained(FastSustainedPerformanceParameters)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case oneTime = "one_time"
case sustained = "sustained"
}
private enum Discriminator: String, Decodable {
case oneTime = "OneTime"
case sustained = "Sustained"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .oneTime:
self = .oneTime(try container.decode(FastOneTimePerformanceParameters.self, forKey: .oneTime))
case .sustained:
self = .sustained(try container.decode(FastSustainedPerformanceParameters.self, forKey: .sustained))
}
}
}
public typealias FastOneTimePerformanceParameters = OneTimePerformanceParameters<FastCastingTime>
public typealias FastSustainedPerformanceParameters = SustainedPerformanceParameters<FastCastingTime>
public enum SlowPerformanceParameters: EntitySubtype {
case oneTime(SlowOneTimePerformanceParameters)
case sustained(SlowSustainedPerformanceParameters)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case oneTime = "one_time"
case sustained = "sustained"
}
private enum Discriminator: String, Decodable {
case oneTime = "OneTime"
case sustained = "Sustained"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .oneTime:
self = .oneTime(try container.decode(SlowOneTimePerformanceParameters.self, forKey: .oneTime))
case .sustained:
self = .sustained(try container.decode(SlowSustainedPerformanceParameters.self, forKey: .sustained))
}
}
}
public typealias SlowOneTimePerformanceParameters = OneTimePerformanceParameters<SlowCastingTime>
public typealias SlowSustainedPerformanceParameters = SustainedPerformanceParameters<SlowCastingTime>
public struct OldParameter: EntitySubtype {
public let full: String
public let abbr: String
public init(full: String, abbr: String) {
self.full = full
self.abbr = abbr
}
}
@@ -1,109 +0,0 @@
//
// _ActivatableSkillCastingTime.swift
// OptolithDatabaseSchema
//
public enum CastingTime<NonModifiable: EntitySubtype>: EntitySubtype {
case modifiable(ModifiableCastingTime)
case nonModifiable(NonModifiable)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case modifiable = "modifiable"
case nonModifiable = "non_modifiable"
}
private enum Discriminator: String, Decodable {
case modifiable = "Modifiable"
case nonModifiable = "NonModifiable"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .modifiable:
self = .modifiable(try container.decode(ModifiableCastingTime.self, forKey: .modifiable))
case .nonModifiable:
self = .nonModifiable(try container.decode(NonModifiable.self, forKey: .nonModifiable))
}
}
}
public struct ModifiableCastingTime: EntitySubtype {
/// The initial skill modification identifier/level.
public let initialModificationLevel: Int
public init(initialModificationLevel: Int) {
self.initialModificationLevel = initialModificationLevel
}
private enum CodingKeys: String, CodingKey {
case initialModificationLevel = "initial_modification_level"
}
}
/// The casting time may have two different values: One for use in normal time, i. e. actions, combat rounds and others, and one for use during lovemaking, which is a rule set from Aventurian Intimacy.
///
/// There must always be at least one casting time value.
public struct CastingTimeIncludingLovemaking<NonModifiable: EntitySubtype>: EntitySubtype {
/// The default casting time definition.
public let `default`: CastingTime<NonModifiable>?
/// The casting time during lovemaking. In Aventurian Intimacy, you may only use an activatable skill during lovemaking if it has a casting time used during lovemaking.
public let duringLovemaking: CastingTimeDuringLovemaking?
public init(`default`: CastingTime<NonModifiable>? = nil, duringLovemaking: CastingTimeDuringLovemaking? = nil) {
self.`default` = `default`
self.duringLovemaking = duringLovemaking
}
private enum CodingKeys: String, CodingKey {
case `default` = "default"
case duringLovemaking = "during_lovemaking"
}
}
/// The casting time during lovemaking. In Aventurian Intimacy, you may only use an activatable skill during lovemaking if it has a casting time used during lovemaking.
public struct CastingTimeDuringLovemaking: EntitySubtype {
/// The (unitless) casting time value.
public let value: Int
/// The unit of the `value`.
public let unit: CastingTimeDuringLovemakingUnit
public init(value: Int, unit: CastingTimeDuringLovemakingUnit) {
self.value = value
self.unit = unit
}
}
public enum CastingTimeDuringLovemakingUnit: String, EntitySubtype {
case seductionActions = "SeductionActions"
case rounds = "Rounds"
}
public struct FastSkillNonModifiableCastingTime: EntitySubtype {
/// The casting time value in actions.
public let actions: Int
public init(actions: Int) {
self.actions = actions
}
}
public struct SlowSkillNonModifiableCastingTime: EntitySubtype {
/// The (unitless) casting time value.
public let value: Int
public let unit: SlowSkillCastingTimeUnit
public init(value: Int, unit: SlowSkillCastingTimeUnit) {
self.value = value
self.unit = unit
}
}
public typealias FastCastingTime = CastingTimeIncludingLovemaking<FastSkillNonModifiableCastingTime>
public typealias SlowCastingTime = CastingTimeIncludingLovemaking<SlowSkillNonModifiableCastingTime>
@@ -1,43 +0,0 @@
//
// _ActivatableSkillCheckResultBased.swift
// OptolithDatabaseSchema
//
/// Defines the derived (unitless) value.
public enum CheckResultValue: String, EntitySubtype {
case qualityLevels = "QualityLevels"
case skillPoints = "SkillPoints"
}
/// Defines how the the `value` is set off against the check result.
public enum CheckResultArithmetic: String, EntitySubtype {
case multiply = "Multiply"
case divide = "Divide"
}
public struct CheckResultBasedModifier: EntitySubtype {
/// The arithmetic how to apply the `value` to the `base`.
public let arithmetic: CheckResultArithmetic
/// The value that is applied to the `base` using the defined `arithmetic`.
public let value: Int
public init(arithmetic: CheckResultArithmetic, value: Int) {
self.arithmetic = arithmetic
self.value = value
}
}
/// Defines a parameter being based on a check result.
public struct CheckResultBased: EntitySubtype {
/// The base value that is derived from the check result.
public let base: CheckResultValue
/// If defined, it modifies the base value.
public let modifier: CheckResultBasedModifier?
public init(base: CheckResultValue, modifier: CheckResultBasedModifier? = nil) {
self.base = base
self.modifier = modifier
}
}
@@ -1,389 +0,0 @@
//
// _ActivatableSkillCost.swift
// OptolithDatabaseSchema
//
public enum OneTimeCost: EntitySubtype {
case single(SingleOneTimeCost)
case conjunction(MultipleOneTimeCosts)
case disjunction(MultipleOneTimeCosts)
case map(CostMap)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case single = "single"
case conjunction = "conjunction"
case disjunction = "disjunction"
case map = "map"
}
private enum Discriminator: String, Decodable {
case single = "Single"
case conjunction = "Conjunction"
case disjunction = "Disjunction"
case map = "Map"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .single:
self = .single(try container.decode(SingleOneTimeCost.self, forKey: .single))
case .conjunction:
self = .conjunction(try container.decode(MultipleOneTimeCosts.self, forKey: .conjunction))
case .disjunction:
self = .disjunction(try container.decode(MultipleOneTimeCosts.self, forKey: .disjunction))
case .map:
self = .map(try container.decode(CostMap.self, forKey: .map))
}
}
}
public enum SingleOneTimeCost: EntitySubtype {
case modifiable(ModifiableOneTimeCost)
case nonModifiable(NonModifiableOneTimeCost)
case indefinite(IndefiniteOneTimeCost)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case modifiable = "modifiable"
case nonModifiable = "non_modifiable"
case indefinite = "indefinite"
}
private enum Discriminator: String, Decodable {
case modifiable = "Modifiable"
case nonModifiable = "NonModifiable"
case indefinite = "Indefinite"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .modifiable:
self = .modifiable(try container.decode(ModifiableOneTimeCost.self, forKey: .modifiable))
case .nonModifiable:
self = .nonModifiable(try container.decode(NonModifiableOneTimeCost.self, forKey: .nonModifiable))
case .indefinite:
self = .indefinite(try container.decode(IndefiniteOneTimeCost.self, forKey: .indefinite))
}
}
}
public typealias MultipleOneTimeCosts = [SingleOneTimeCost]
public struct ModifiableOneTimeCost: EntitySubtype {
/// The initial skill modification identifier/level.
public let initialModificationLevel: Int
/// The part of the cost value that has to be spent permanently.
public let permanentValue: Int?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ModifiableOneTimeCostTranslation>?
public init(initialModificationLevel: Int, permanentValue: Int? = nil, translations: LocaleMap<ModifiableOneTimeCostTranslation>? = nil) {
self.initialModificationLevel = initialModificationLevel
self.permanentValue = permanentValue
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case initialModificationLevel = "initial_modification_level"
case permanentValue = "permanent_value"
case translations = "translations"
}
}
public struct ModifiableOneTimeCostTranslation: EntitySubtype {
/// A replacement string.
public let replacement: ResponsiveTextReplace
public init(replacement: ResponsiveTextReplace) {
self.replacement = replacement
}
}
public struct NonModifiableOneTimeCost: EntitySubtype {
/// If `true`, the non-modifiable value is a minimum value.
public let isMinimum: Bool?
/// The AE cost value.
public let value: Int
/// The part of the cost value that has to be spent permanently.
public let permanentValue: Int?
/// The cost have to be per a specific countable entity, e.g. `8 KP per person`.
public let per: NonModifiableOneTimeCostPerCountable?
/// All translations for the entry, identified by IETF language tag
/// (BCP47).
public let translations: LocaleMap<NonModifiableOneTimeCostTranslation>?
public init(isMinimum: Bool? = nil, value: Int, permanentValue: Int? = nil, per: NonModifiableOneTimeCostPerCountable? = nil, translations: LocaleMap<NonModifiableOneTimeCostTranslation>? = nil) {
self.isMinimum = isMinimum
self.value = value
self.permanentValue = permanentValue
self.per = per
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case isMinimum = "is_minimum"
case value = "value"
case permanentValue = "permanent_value"
case per = "per"
case translations = "translations"
}
}
public struct NonModifiableOneTimeCostPerCountable: EntitySubtype {
/// If defined, the minimum total AE that have to be spent casting the skill.
public let minimumTotal: Double?
/// All translations for the entry, identified by IETF language tag
/// (BCP47).
public let translations: LocaleMap<NonModifiableOneTimeCostPerCountableTranslation>
public init(minimumTotal: Double? = nil, translations: LocaleMap<NonModifiableOneTimeCostPerCountableTranslation>) {
self.minimumTotal = minimumTotal
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case minimumTotal = "minimum_total"
case translations = "translations"
}
}
public struct NonModifiableOneTimeCostPerCountableTranslation: EntitySubtype {
/// The countable entity name.
public let countable: ResponsiveText
public init(countable: ResponsiveText) {
self.countable = countable
}
}
public struct NonModifiableOneTimeCostTranslation: EntitySubtype {
/// A note, appended to the generated string in parenthesis.
public let note: ResponsiveTextOptional
public init(note: ResponsiveTextOptional) {
self.note = note
}
}
public struct IndefiniteOneTimeCost: EntitySubtype {
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<IndefiniteOneTimeCostTranslation>
public init(translations: LocaleMap<IndefiniteOneTimeCostTranslation>) {
self.translations = translations
}
}
public struct IndefiniteOneTimeCostTranslation: EntitySubtype {
/// A description of where the cost come from.
public let description: ResponsiveText
public init(description: ResponsiveText) {
self.description = description
}
}
/// A content that is `2/4/8/16 AE for an item the size of a cup/chest/door/castle gate` may be respresented as the following map:
///
/// ```yaml
/// options:
/// - value: 2
/// label: "cup"
/// - value: 4
/// label: "chest"
/// - value: 8
/// label: "door"
/// - value: 16
/// label: "castle gate"
/// for_append: "an item the size of a"
/// ```
///
/// This will generate the exact same string as seen above given it is set for a spellwork and thus `AE` is used.
public struct CostMap: EntitySubtype {
/// The possible costs and associated labels.
public let options: [CostMapOption]
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<CostMapTranslation>?
public init(options: [CostMapOption], translations: LocaleMap<CostMapTranslation>? = nil) {
self.options = options
self.translations = translations
}
}
public struct CostMapOption: EntitySubtype {
/// The full cost value for this option.
public let value: Int
/// The part of the `value` that has to be paid permanently.
public let permanentValue: Int?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<CostMapOptionTranslation>?
public init(value: Int, permanentValue: Int? = nil, translations: LocaleMap<CostMapOptionTranslation>? = nil) {
self.value = value
self.permanentValue = permanentValue
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case value = "value"
case permanentValue = "permanent_value"
case translations = "translations"
}
}
public struct CostMapOptionTranslation: EntitySubtype {
/// The description of the option for cost string generation.
public let label: NonEmptyString
/// The description of the option if used standalone. Only used if different from `label`.
public let labelStandalone: NonEmptyString?
public init(label: NonEmptyString, labelStandalone: NonEmptyString? = nil) {
self.label = label
self.labelStandalone = labelStandalone
}
private enum CodingKeys: String, CodingKey {
case label = "label"
case labelStandalone = "label_standalone"
}
}
public struct CostMapTranslation: EntitySubtype {
/// Place a string between the `for` and the grouped map option labels.
public let listPrepend: NonEmptyString?
/// Place a string after the grouped map option labels.
public let listAppend: NonEmptyString?
/// If the string from the book cannot be generated using the default generation technique, use this string. All options still need to be inserted propertly, since it may be used by in-game tools to provide a selection to players.
public let replacement: NonEmptyString?
public init(listPrepend: NonEmptyString? = nil, listAppend: NonEmptyString? = nil, replacement: NonEmptyString? = nil) {
self.listPrepend = listPrepend
self.listAppend = listAppend
self.replacement = replacement
}
private enum CodingKeys: String, CodingKey {
case listPrepend = "list_prepend"
case listAppend = "list_append"
case replacement = "replacement"
}
}
public enum SustainedCost: EntitySubtype {
case modifiable(ModifiableSustainedCost)
case nonModifiable(NonModifiableSustainedCost)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case modifiable = "modifiable"
case nonModifiable = "non_modifiable"
}
private enum Discriminator: String, Decodable {
case modifiable = "Modifiable"
case nonModifiable = "NonModifiable"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .modifiable:
self = .modifiable(try container.decode(ModifiableSustainedCost.self, forKey: .modifiable))
case .nonModifiable:
self = .nonModifiable(try container.decode(NonModifiableSustainedCost.self, forKey: .nonModifiable))
}
}
}
public struct ModifiableSustainedCost: EntitySubtype {
/// The initial skill modification identifier/level.
public let initialModificationLevel: Int
/// The sustain interval.
public let interval: DurationUnitValue
public init(initialModificationLevel: Int, interval: DurationUnitValue) {
self.initialModificationLevel = initialModificationLevel
self.interval = interval
}
private enum CodingKeys: String, CodingKey {
case initialModificationLevel = "initial_modification_level"
case interval = "interval"
}
}
public struct NonModifiableSustainedCost: EntitySubtype {
/// If `true`, the non-modifiable value is a minimum value.
public let isMinimum: Bool?
/// The AE cost value.
public let value: Int
/// The cost have to be per a specific countable entity, e.g. `8 KP per person per 5 minutes`.
public let per: NonModifiableSustainedCostPerCountable?
/// The sustain interval.
public let interval: DurationUnitValue
public init(isMinimum: Bool? = nil, value: Int, per: NonModifiableSustainedCostPerCountable? = nil, interval: DurationUnitValue) {
self.isMinimum = isMinimum
self.value = value
self.per = per
self.interval = interval
}
private enum CodingKeys: String, CodingKey {
case isMinimum = "is_minimum"
case value = "value"
case per = "per"
case interval = "interval"
}
}
public struct NonModifiableSustainedCostPerCountable: EntitySubtype {
/// If defined, the minimum total AE that have to be spent casting the skill.
public let minimumTotal: Double?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<NonModifiableSustainedCostPerCountableTranslation>
public init(minimumTotal: Double? = nil, translations: LocaleMap<NonModifiableSustainedCostPerCountableTranslation>) {
self.minimumTotal = minimumTotal
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case minimumTotal = "minimum_total"
case translations = "translations"
}
}
public struct NonModifiableSustainedCostPerCountableTranslation: EntitySubtype {
/// The countable entity name.
public let countable: ResponsiveText
public init(countable: ResponsiveText) {
self.countable = countable
}
}
@@ -1,219 +0,0 @@
//
// _ActivatableSkillDuration.swift
// OptolithDatabaseSchema
//
public enum DurationForOneTime: EntitySubtype {
case immediate(Immediate)
case permanent(PermanentDuration)
case fixed(FixedDuration)
case checkResultBased(CheckResultBasedDuration)
case indefinite(IndefiniteDuration)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case immediate = "immediate"
case permanent = "permanent"
case fixed = "fixed"
case checkResultBased = "check_result_based"
case indefinite = "indefinite"
}
private enum Discriminator: String, Decodable {
case immediate = "Immediate"
case permanent = "Permanent"
case fixed = "Fixed"
case checkResultBased = "CheckResultBased"
case indefinite = "Indefinite"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .immediate:
self = .immediate(try container.decode(Immediate.self, forKey: .immediate))
case .permanent:
self = .permanent(try container.decode(PermanentDuration.self, forKey: .permanent))
case .fixed:
self = .fixed(try container.decode(FixedDuration.self, forKey: .fixed))
case .checkResultBased:
self = .checkResultBased(try container.decode(CheckResultBasedDuration.self, forKey: .checkResultBased))
case .indefinite:
self = .indefinite(try container.decode(IndefiniteDuration.self, forKey: .indefinite))
}
}
}
public struct Immediate: EntitySubtype {
/// Specified if the duration has a maximum time span.
public let maximum: DurationUnitValue?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ImmediateTranslation>?
public init(maximum: DurationUnitValue? = nil, translations: LocaleMap<ImmediateTranslation>? = nil) {
self.maximum = maximum
self.translations = translations
}
}
public struct ImmediateTranslation: EntitySubtype {
/// A replacement string.
public let replacement: ResponsiveTextReplace
public init(replacement: ResponsiveTextReplace) {
self.replacement = replacement
}
}
public struct PermanentDuration: EntitySubtype {
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<PermanentDurationTranslation>?
public init(translations: LocaleMap<PermanentDurationTranslation>? = nil) {
self.translations = translations
}
}
public struct PermanentDurationTranslation: EntitySubtype {
/// A replacement string.
public let replacement: ResponsiveTextReplace
public init(replacement: ResponsiveTextReplace) {
self.replacement = replacement
}
}
public struct FixedDuration: EntitySubtype {
/// If the duration is the maximum duration, so it may end earlier.
public let isMaximum: Bool?
/// The (unitless) duration.
public let value: Int
/// The duration unit.
public let unit: DurationUnit
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<FixedDurationTranslation>?
public init(isMaximum: Bool? = nil, value: Int, unit: DurationUnit, translations: LocaleMap<FixedDurationTranslation>? = nil) {
self.isMaximum = isMaximum
self.value = value
self.unit = unit
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case isMaximum = "is_maximum"
case value = "value"
case unit = "unit"
case translations = "translations"
}
}
public struct FixedDurationTranslation: EntitySubtype {
/// A replacement string.
public let replacement: ResponsiveTextReplace
public init(replacement: ResponsiveTextReplace) {
self.replacement = replacement
}
}
/// Defines the duration being based on a check result.
public struct CheckResultBasedDuration: EntitySubtype {
/// If the duration is the maximum duration, so it may end earlier.
public let isMaximum: Bool?
/// The base value that is derived from the check result.
public let base: CheckResultValue
/// If defined, it modifies the base value.
public let modifier: CheckResultBasedModifier?
/// The duration unit.
public let unit: DurationUnit
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<CheckResultBasedDurationTranslation>?
public init(isMaximum: Bool? = nil, base: CheckResultValue, modifier: CheckResultBasedModifier? = nil, unit: DurationUnit, translations: LocaleMap<CheckResultBasedDurationTranslation>? = nil) {
self.isMaximum = isMaximum
self.base = base
self.modifier = modifier
self.unit = unit
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case isMaximum = "is_maximum"
case base = "base"
case modifier = "modifier"
case unit = "unit"
case translations = "translations"
}
}
public struct CheckResultBasedDurationTranslation: EntitySubtype {
/// A replacement string.
public let replacement: ResponsiveTextReplace
public init(replacement: ResponsiveTextReplace) {
self.replacement = replacement
}
}
public struct IndefiniteDuration: EntitySubtype {
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<IndefiniteDurationTranslation>
public init(translations: LocaleMap<IndefiniteDurationTranslation>) {
self.translations = translations
}
}
public struct IndefiniteDurationTranslation: EntitySubtype {
/// A description of the duration.
public let description: ResponsiveText
public init(description: ResponsiveText) {
self.description = description
}
}
public struct DurationForSustained: EntitySubtype {
/// The sustained skill can be active a maximum amount of time.
public let maximum: DurationUnitValue
public init(maximum: DurationUnitValue) {
self.maximum = maximum
}
}
public enum DurationUnit: String, EntitySubtype {
case seconds = "Seconds"
case minutes = "Minutes"
case hours = "Hours"
case days = "Days"
case weeks = "Weeks"
case months = "Months"
case years = "Years"
case centuries = "Centuries"
case actions = "Actions"
case combatRounds = "CombatRounds"
}
public struct DurationUnitValue: EntitySubtype {
/// The (unitless) duration value.
public let value: Int
/// The unit of the `value`.
public let unit: DurationUnit
public init(value: Int, unit: DurationUnit) {
self.value = value
self.unit = unit
}
}
@@ -1,92 +0,0 @@
//
// _ActivatableSkillEffect.swift
// OptolithDatabaseSchema
//
/// The effect description may be either a plain text or a text that is divided by a list of effects for each quality level. It may also be a list for each two quality levels.
public enum ActivatableSkillEffect: EntitySubtype {
case plain(ActivatableSkillPlainEffect)
case forEachQualityLevel(ActivatableSkillEffectForEachQualityLevel)
case forEachTwoQualityLevels(ActivatableSkillEffectForEachTwoQualityLevels)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case plain = "plain"
case forEachQualityLevel = "for_each_quality_level"
case forEachTwoQualityLevels = "for_each_two_quality_levels"
}
private enum Discriminator: String, Decodable {
case plain = "Plain"
case forEachQualityLevel = "ForEachQualityLevel"
case forEachTwoQualityLevels = "ForEachTwoQualityLevels"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .plain:
self = .plain(try container.decode(ActivatableSkillPlainEffect.self, forKey: .plain))
case .forEachQualityLevel:
self = .forEachQualityLevel(try container.decode(ActivatableSkillEffectForEachQualityLevel.self, forKey: .forEachQualityLevel))
case .forEachTwoQualityLevels:
self = .forEachTwoQualityLevels(try container.decode(ActivatableSkillEffectForEachTwoQualityLevels.self, forKey: .forEachTwoQualityLevels))
}
}
}
public struct ActivatableSkillPlainEffect: EntitySubtype {
/// The effect description.
public let text: NonEmptyMarkdown
public init(text: NonEmptyMarkdown) {
self.text = text
}
}
public struct ActivatableSkillEffectForEachQualityLevel: EntitySubtype {
/// The effect description before the list of effects for each quality level.
public let textBefore: NonEmptyMarkdown
/// The list of effects for each quality level. The first element represents QL 1, the second element QL 2, and so on.
public let qualityLevels: [NonEmptyMarkdown]
/// The effect description after the list of effects for each quality level.
public let textAfter: NonEmptyMarkdown?
public init(textBefore: NonEmptyMarkdown, qualityLevels: [NonEmptyMarkdown], textAfter: NonEmptyMarkdown? = nil) {
self.textBefore = textBefore
self.qualityLevels = qualityLevels
self.textAfter = textAfter
}
private enum CodingKeys: String, CodingKey {
case textBefore = "text_before"
case qualityLevels = "quality_levels"
case textAfter = "text_after"
}
}
public struct ActivatableSkillEffectForEachTwoQualityLevels: EntitySubtype {
/// The effect description before the list of effects for each quality level.
public let textBefore: NonEmptyMarkdown
/// The list of effects for each two quality levels. The first element represents QL 12, the second element QL 34 and the third element QL 56.
public let qualityLevels: [NonEmptyMarkdown]
/// The effect description after the list of effects for each quality level.
public let textAfter: NonEmptyMarkdown?
public init(textBefore: NonEmptyMarkdown, qualityLevels: [NonEmptyMarkdown], textAfter: NonEmptyMarkdown? = nil) {
self.textBefore = textBefore
self.qualityLevels = qualityLevels
self.textAfter = textAfter
}
private enum CodingKeys: String, CodingKey {
case textBefore = "text_before"
case qualityLevels = "quality_levels"
case textAfter = "text_after"
}
}
@@ -1,171 +0,0 @@
//
// _ActivatableSkillRange.swift
// OptolithDatabaseSchema
//
public struct Range: EntitySubtype {
public let value: RangeValue
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<RangeTranslation>?
public init(value: RangeValue, translations: LocaleMap<RangeTranslation>? = nil) {
self.value = value
self.translations = translations
}
}
public enum RangeValue: EntitySubtype {
case modifiable(ModifiableRange)
case sight
case `self`
case global
case touch
case fixed(FixedRange)
case checkResultBased(CheckResultBasedRange)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case modifiable = "modifiable"
case sight = "sight"
case `self` = "self"
case global = "global"
case touch = "touch"
case fixed = "fixed"
case checkResultBased = "check_result_based"
}
private enum Discriminator: String, Decodable {
case modifiable = "Modifiable"
case sight = "Sight"
case `self` = "Self"
case global = "Global"
case touch = "Touch"
case fixed = "Fixed"
case checkResultBased = "CheckResultBased"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .modifiable:
self = .modifiable(try container.decode(ModifiableRange.self, forKey: .modifiable))
case .sight:
self = .sight
case .`self`:
self = .`self`
case .global:
self = .global
case .touch:
self = .touch
case .fixed:
self = .fixed(try container.decode(FixedRange.self, forKey: .fixed))
case .checkResultBased:
self = .checkResultBased(try container.decode(CheckResultBasedRange.self, forKey: .checkResultBased))
}
}
}
public struct ModifiableRange: EntitySubtype {
/// If `true`, the range is a maximum range.
public let isMaximum: Bool?
/// The initial skill modification identifier/level.
public let initialModificationLevel: Int
/// If `true`, the range is a radius.
public let isRadius: Bool?
public init(isMaximum: Bool? = nil, initialModificationLevel: Int, isRadius: Bool? = nil) {
self.isMaximum = isMaximum
self.initialModificationLevel = initialModificationLevel
self.isRadius = isRadius
}
private enum CodingKeys: String, CodingKey {
case isMaximum = "is_maximum"
case initialModificationLevel = "initial_modification_level"
case isRadius = "is_radius"
}
}
public struct FixedRange: EntitySubtype {
/// If `true`, the range is a maximum range.
public let isMaximum: Bool?
/// The (unitless) range value.
public let value: Int
/// The unit of the `value`.
public let unit: RangeUnit
/// If `true`, the range is a radius.
public let isRadius: Bool?
public init(isMaximum: Bool? = nil, value: Int, unit: RangeUnit, isRadius: Bool? = nil) {
self.isMaximum = isMaximum
self.value = value
self.unit = unit
self.isRadius = isRadius
}
private enum CodingKeys: String, CodingKey {
case isMaximum = "is_maximum"
case value = "value"
case unit = "unit"
case isRadius = "is_radius"
}
}
/// Defines the range being based on a check result.
public struct CheckResultBasedRange: EntitySubtype {
/// If the range is the maximum range.
public let isMaximum: Bool?
/// The base value that is derived from the check result.
public let base: CheckResultValue
/// If defined, it modifies the base value.
public let modifier: CheckResultBasedModifier?
/// The duration unit.
public let unit: RangeUnit
/// If `true`, the range is a radius.
public let isRadius: Bool?
public init(isMaximum: Bool? = nil, base: CheckResultValue, modifier: CheckResultBasedModifier? = nil, unit: RangeUnit, isRadius: Bool? = nil) {
self.isMaximum = isMaximum
self.base = base
self.modifier = modifier
self.unit = unit
self.isRadius = isRadius
}
private enum CodingKeys: String, CodingKey {
case isMaximum = "is_maximum"
case base = "base"
case modifier = "modifier"
case unit = "unit"
case isRadius = "is_radius"
}
}
public struct RangeTranslation: EntitySubtype {
/// A note, appended to the generated string in parenthesis. If the generated is modified using `replacement`, the note is appended to the modifier string.
public let note: ResponsiveTextOptional?
/// A replacement string. If `note` is provided, it is appended to the replaced string.
public let replacement: ResponsiveTextReplace?
public init(note: ResponsiveTextOptional? = nil, replacement: ResponsiveTextReplace? = nil) {
self.note = note
self.replacement = replacement
}
}
public enum RangeUnit: String, EntitySubtype {
case steps = "Steps"
case miles = "Miles"
}
@@ -1,72 +0,0 @@
//
// _ActivatableSkillTargetCategory.swift
// OptolithDatabaseSchema
//
/// The target category the kind of creature or object the skill affects.
///
/// If no target categories are given, the skill applies to all target categories.
public typealias AffectedTargetCategories = [SpecificAffectedTargetCategory]
public struct SpecificAffectedTargetCategory: EntitySubtype {
public let id: SpecificAffectedTargetCategoryIdentifier
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<SpecificAffectedTargetCategoryTranslation>?
public init(id: SpecificAffectedTargetCategoryIdentifier, translations: LocaleMap<SpecificAffectedTargetCategoryTranslation>? = nil) {
self.id = id
self.translations = translations
}
}
public struct SpecificAffectedTargetCategoryTranslation: EntitySubtype {
/// A note, appended to the generated string in parenthesis.
public let note: NonEmptyString
public init(note: NonEmptyString) {
self.note = note
}
}
public enum SpecificAffectedTargetCategoryIdentifier: EntitySubtype {
case `self`
case zone
case liturgicalChantsAndCeremonies
case cantrips
case predefined(TargetCategoryReference)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case `self` = "self"
case zone = "zone"
case liturgicalChantsAndCeremonies = "liturgical_chants_and_ceremonies"
case cantrips = "cantrips"
case predefined = "predefined"
}
private enum Discriminator: String, Decodable {
case `self` = "Self"
case zone = "Zone"
case liturgicalChantsAndCeremonies = "LiturgicalChantsAndCeremonies"
case cantrips = "Cantrips"
case predefined = "Predefined"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .`self`:
self = .`self`
case .zone:
self = .zone
case .liturgicalChantsAndCeremonies:
self = .liturgicalChantsAndCeremonies
case .cantrips:
self = .cantrips
case .predefined:
self = .predefined(try container.decode(TargetCategoryReference.self, forKey: .predefined))
}
}
}
@@ -1,17 +0,0 @@
//
// _AlternativeNames.swift
// OptolithDatabaseSchema
//
public struct AlternativeName: EntitySubtype {
/// An alternative name of the disease.
public let name: NonEmptyString
/// The region where this alternative name is used.
public let region: NonEmptyString?
public init(name: NonEmptyString, region: NonEmptyString? = nil) {
self.name = name
self.region = region
}
}
@@ -1,29 +0,0 @@
//
// _ArcaneTradition.swift
// OptolithDatabaseSchema
//
public struct ArcaneTradition: LocalizableEntity {
/// The arcane tradition's identifier. An unique, increasing integer.
public let id: Int
public let prerequisites: ArcaneTraditionPrerequisites
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ArcaneTraditionTranslation>
public init(id: Int, prerequisites: ArcaneTraditionPrerequisites, translations: LocaleMap<ArcaneTraditionTranslation>) {
self.id = id
self.prerequisites = prerequisites
self.translations = translations
}
}
public struct ArcaneTraditionTranslation: EntitySubtype {
/// The arcane tradition's name.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,44 +0,0 @@
//
// _Blessed.swift
// OptolithDatabaseSchema
//
public enum SkillTradition: EntitySubtype {
case generalAspect(AspectReference)
case tradition(SkillTraditionWithAspects)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case generalAspect = "general_aspect"
case tradition = "tradition"
}
private enum Discriminator: String, Decodable {
case generalAspect = "GeneralAspect"
case tradition = "Tradition"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .generalAspect:
self = .generalAspect(try container.decode(AspectReference.self, forKey: .generalAspect))
case .tradition:
self = .tradition(try container.decode(SkillTraditionWithAspects.self, forKey: .tradition))
}
}
}
public struct SkillTraditionWithAspects: EntitySubtype {
/// The blessed tradition.
public let tradition: BlessedTraditionReference
/// The aspect(s) from the tradition the ceremony belongs to. Note that not all traditions have aspects. Traditions with aspects must have at least one aspect specified.
public let aspects: [AspectReference]?
public init(tradition: BlessedTraditionReference, aspects: [AspectReference]? = nil) {
self.tradition = tradition
self.aspects = aspects
}
}
@@ -1,14 +0,0 @@
//
// _CommonnessRatedAdvantageDisadvantage.swift
// OptolithDatabaseSchema
//
/// Reference to a commonness-rated advantage or disadvantage. Commonness-rating terms used in the source books are strongly recommended, common, uncommon, suggested and unsuitable.
public struct CommonnessRatedAdvantageDisadvantage<Identifier: EntitySubtype>: EntitySubtype {
/// The advantage's or disadvantage's identifier.
public let id: Identifier
public init(id: Identifier) {
self.id = id
}
}
@@ -1,24 +0,0 @@
//
// _Dice.swift
// OptolithDatabaseSchema
//
public struct Dice: EntitySubtype {
/// Number of dice of the same type. Example: 2 in 2D6.
public let number: Int
/// Number of sides on every die. Example: 6 in 2D6.
public let sides: DieType
public init(number: Int, sides: DieType) {
self.number = number
self.sides = sides
}
}
/// Number of sides on every dice. Example: 6 in 2D6.
public enum DieType: Int, EntitySubtype {
case _3 = 3
case _6 = 6
case _20 = 20
}
@@ -1,120 +0,0 @@
//
// _DiseasePoison.swift
// OptolithDatabaseSchema
//
/// Depending on the disease, apply Spirit or Toughness as a penalty to the disease roll. It may also happen that the lower of both is applied as a penalty.
public enum Resistance: String, EntitySubtype {
case spirit = "Spirit"
case toughness = "Toughness"
case lowerOfSpiritAndToughness = "LowerOfSpiritAndToughness"
}
/// What causes the disease? The GM rolls 1D20 to see if a character gets infected. If the infection check succeeds, the GM makes a disease check to determine the severity of the infection.
public struct Cause: EntitySubtype {
/// The chance to get infected by this cause, in percent.
public let chance: Int?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<CauseTranslation>
public init(chance: Int? = nil, translations: LocaleMap<CauseTranslation>) {
self.chance = chance
self.translations = translations
}
}
public struct CauseTranslation: EntitySubtype {
/// The name of the cause.
public let name: String
/// The chance to get infected by this cause. If present for this language, this overrides the universal `chance` field; they cannot be used at the same time.
public let chance: NonEmptyString?
/// An additional note about this cause.
public let note: NonEmptyString?
public init(name: String, chance: NonEmptyString? = nil, note: NonEmptyString? = nil) {
self.name = name
self.chance = chance
self.note = note
}
}
public struct DiseaseTranslation: EntitySubtype {
/// The name of the disease.
public let name: NonEmptyString
/// A list of alternative names.
public let alternativeNames: [AlternativeName]?
/// The diseases progress, in detail.
public let progress: NonEmptyMarkdown
/// After infection, how much time passes before symptoms appear?
public let incubationTime: NonEmptyString
/// The damage caused by the disease. If the disease check fails, apply the lessened effects.
public let damage: Reduceable<NonEmptyMarkdown>
/// The duration of the disease. If the disease check fails, use the lessened duration.
public let duration: Reduceable<NonEmptyMarkdown>
/// Special information about the disease.
public let special: NonEmptyMarkdown?
/// Methods known to lessen the diseases progress or relieve symptoms.
public let treatment: NonEmptyMarkdown
/// Known remedies for the disease.
public let cure: NonEmptyMarkdown
public let errata: Errata?
public init(name: NonEmptyString, alternativeNames: [AlternativeName]? = nil, progress: NonEmptyMarkdown, incubationTime: NonEmptyString, damage: Reduceable<NonEmptyMarkdown>, duration: Reduceable<NonEmptyMarkdown>, special: NonEmptyMarkdown? = nil, treatment: NonEmptyMarkdown, cure: NonEmptyMarkdown, errata: Errata? = nil) {
self.name = name
self.alternativeNames = alternativeNames
self.progress = progress
self.incubationTime = incubationTime
self.damage = damage
self.duration = duration
self.special = special
self.treatment = treatment
self.cure = cure
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case alternativeNames = "alternative_names"
case progress = "progress"
case incubationTime = "incubation_time"
case damage = "damage"
case duration = "duration"
case special = "special"
case treatment = "treatment"
case cure = "cure"
case errata = "errata"
}
}
/// An effect or other parameter that may be reduced by a failed disease check for lessening or a degraded poison.
///
/// This streamlines the wording for diseases and poison by using a unified wording for *lessened* (disease) and *degraded* (poison).
public struct Reduceable<Content: EntitySubtype>: EntitySubtype {
/// The default value. In the source, it's the text before the slash.
public let `default`: Content
/// The reduced value. In the source, it's the text after the slash. Some entries may not have a reduced value.
public let reduced: Content?
public init(`default`: Content, reduced: Content? = nil) {
self.`default` = `default`
self.reduced = reduced
}
private enum CodingKeys: String, CodingKey {
case `default` = "default"
case reduced = "reduced"
}
}
@@ -1,60 +0,0 @@
//
// _Enhancements.swift
// OptolithDatabaseSchema
//
/// A list of enhancements.
public typealias Enhancements = [Enhancement]
public struct Enhancement: EntitySubtype {
/// The enhancement's identifier. An unique, increasing integer.
public let id: Int
/// The skill rating required to learn this enhancement.
public let skillRating: Int
/// The value to multiply with the numeric representation of the associated skill's improvement cost to form the final AP cost of this enhancement.
public let adventurePointsModifier: Int
public let prerequisites: EnhancementPrerequisites?
/// Only defined if different than the associated skill.
public let src: PublicationRefs?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<EnhancementTranslation>
public init(id: Int, skillRating: Int, adventurePointsModifier: Int, prerequisites: EnhancementPrerequisites? = nil, src: PublicationRefs? = nil, translations: LocaleMap<EnhancementTranslation>) {
self.id = id
self.skillRating = skillRating
self.adventurePointsModifier = adventurePointsModifier
self.prerequisites = prerequisites
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case skillRating = "skill_rating"
case adventurePointsModifier = "adventure_points_modifier"
case prerequisites = "prerequisites"
case src = "src"
case translations = "translations"
}
}
public struct EnhancementTranslation: EntitySubtype {
/// The name of the enhancement.
public let name: String
/// The effect description.
public let effect: String
public let errata: Errata?
public init(name: String, effect: String, errata: Errata? = nil) {
self.name = name
self.effect = effect
self.errata = errata
}
}
@@ -1,855 +0,0 @@
//
// _IdentifierGroup.swift
// OptolithDatabaseSchema
//
public enum ActivatableIdentifier: EntitySubtype {
case advantageIdentifier(AdvantageIdentifier)
case disadvantageIdentifier(DisadvantageIdentifier)
case advancedCombatSpecialAbilityIdentifier(AdvancedCombatSpecialAbilityIdentifier)
case advancedKarmaSpecialAbilityIdentifier(AdvancedKarmaSpecialAbilityIdentifier)
case advancedMagicalSpecialAbilityIdentifier(AdvancedMagicalSpecialAbilityIdentifier)
case advancedSkillSpecialAbilityIdentifier(AdvancedSkillSpecialAbilityIdentifier)
case ancestorGlyphIdentifier(AncestorGlyphIdentifier)
case arcaneOrbEnchantmentIdentifier(ArcaneOrbEnchantmentIdentifier)
case attireEnchantmentIdentifier(AttireEnchantmentIdentifier)
case blessedTraditionIdentifier(BlessedTraditionIdentifier)
case bowlEnchantmentIdentifier(BowlEnchantmentIdentifier)
case brawlingSpecialAbilityIdentifier(BrawlingSpecialAbilityIdentifier)
case cauldronEnchantmentIdentifier(CauldronEnchantmentIdentifier)
case ceremonialItemSpecialAbilityIdentifier(CeremonialItemSpecialAbilityIdentifier)
case chronicleEnchantmentIdentifier(ChronicleEnchantmentIdentifier)
case combatSpecialAbilityIdentifier(CombatSpecialAbilityIdentifier)
case combatStyleSpecialAbilityIdentifier(CombatStyleSpecialAbilityIdentifier)
case commandSpecialAbilityIdentifier(CommandSpecialAbilityIdentifier)
case daggerRitualIdentifier(DaggerRitualIdentifier)
case familiarSpecialAbilityIdentifier(FamiliarSpecialAbilityIdentifier)
case fatePointSexSpecialAbilityIdentifier(FatePointSexSpecialAbilityIdentifier)
case fatePointSpecialAbilityIdentifier(FatePointSpecialAbilityIdentifier)
case foolsHatEnchantmentIdentifier(FoolsHatEnchantmentIdentifier)
case generalSpecialAbilityIdentifier(GeneralSpecialAbilityIdentifier)
case instrumentEnchantmentIdentifier(InstrumentEnchantmentIdentifier)
case karmaSpecialAbilityIdentifier(KarmaSpecialAbilityIdentifier)
case krallenkettenzauberIdentifier(KrallenkettenzauberIdentifier)
case liturgicalStyleSpecialAbilityIdentifier(LiturgicalStyleSpecialAbilityIdentifier)
case lycantropicGiftIdentifier(LycantropicGiftIdentifier)
case magicalSignIdentifier(MagicalSignIdentifier)
case magicalSpecialAbilityIdentifier(MagicalSpecialAbilityIdentifier)
case magicalTraditionIdentifier(MagicalTraditionIdentifier)
case magicStyleSpecialAbilityIdentifier(MagicStyleSpecialAbilityIdentifier)
case orbEnchantmentIdentifier(OrbEnchantmentIdentifier)
case pactGiftIdentifier(PactGiftIdentifier)
case protectiveWardingCircleSpecialAbilityIdentifier(ProtectiveWardingCircleSpecialAbilityIdentifier)
case ringEnchantmentIdentifier(RingEnchantmentIdentifier)
case sermonIdentifier(SermonIdentifier)
case sexSpecialAbilityIdentifier(SexSpecialAbilityIdentifier)
case sickleRitualIdentifier(SickleRitualIdentifier)
case sikaryanDrainSpecialAbilityIdentifier(SikaryanDrainSpecialAbilityIdentifier)
case skillStyleSpecialAbilityIdentifier(SkillStyleSpecialAbilityIdentifier)
case spellSwordEnchantmentIdentifier(SpellSwordEnchantmentIdentifier)
case staffEnchantmentIdentifier(StaffEnchantmentIdentifier)
case toyEnchantmentIdentifier(ToyEnchantmentIdentifier)
case trinkhornzauberIdentifier(TrinkhornzauberIdentifier)
case vampiricGiftIdentifier(VampiricGiftIdentifier)
case visionIdentifier(VisionIdentifier)
case wandEnchantmentIdentifier(WandEnchantmentIdentifier)
case weaponEnchantmentIdentifier(WeaponEnchantmentIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let advantageIdentifier = try? container.decode(AdvantageIdentifier.self) {
self = .advantageIdentifier(advantageIdentifier)
} else if let disadvantageIdentifier = try? container.decode(DisadvantageIdentifier.self) {
self = .disadvantageIdentifier(disadvantageIdentifier)
} else if let advancedCombatSpecialAbilityIdentifier = try? container.decode(AdvancedCombatSpecialAbilityIdentifier.self) {
self = .advancedCombatSpecialAbilityIdentifier(advancedCombatSpecialAbilityIdentifier)
} else if let advancedKarmaSpecialAbilityIdentifier = try? container.decode(AdvancedKarmaSpecialAbilityIdentifier.self) {
self = .advancedKarmaSpecialAbilityIdentifier(advancedKarmaSpecialAbilityIdentifier)
} else if let advancedMagicalSpecialAbilityIdentifier = try? container.decode(AdvancedMagicalSpecialAbilityIdentifier.self) {
self = .advancedMagicalSpecialAbilityIdentifier(advancedMagicalSpecialAbilityIdentifier)
} else if let advancedSkillSpecialAbilityIdentifier = try? container.decode(AdvancedSkillSpecialAbilityIdentifier.self) {
self = .advancedSkillSpecialAbilityIdentifier(advancedSkillSpecialAbilityIdentifier)
} else if let ancestorGlyphIdentifier = try? container.decode(AncestorGlyphIdentifier.self) {
self = .ancestorGlyphIdentifier(ancestorGlyphIdentifier)
} else if let arcaneOrbEnchantmentIdentifier = try? container.decode(ArcaneOrbEnchantmentIdentifier.self) {
self = .arcaneOrbEnchantmentIdentifier(arcaneOrbEnchantmentIdentifier)
} else if let attireEnchantmentIdentifier = try? container.decode(AttireEnchantmentIdentifier.self) {
self = .attireEnchantmentIdentifier(attireEnchantmentIdentifier)
} else if let blessedTraditionIdentifier = try? container.decode(BlessedTraditionIdentifier.self) {
self = .blessedTraditionIdentifier(blessedTraditionIdentifier)
} else if let bowlEnchantmentIdentifier = try? container.decode(BowlEnchantmentIdentifier.self) {
self = .bowlEnchantmentIdentifier(bowlEnchantmentIdentifier)
} else if let brawlingSpecialAbilityIdentifier = try? container.decode(BrawlingSpecialAbilityIdentifier.self) {
self = .brawlingSpecialAbilityIdentifier(brawlingSpecialAbilityIdentifier)
} else if let cauldronEnchantmentIdentifier = try? container.decode(CauldronEnchantmentIdentifier.self) {
self = .cauldronEnchantmentIdentifier(cauldronEnchantmentIdentifier)
} else if let ceremonialItemSpecialAbilityIdentifier = try? container.decode(CeremonialItemSpecialAbilityIdentifier.self) {
self = .ceremonialItemSpecialAbilityIdentifier(ceremonialItemSpecialAbilityIdentifier)
} else if let chronicleEnchantmentIdentifier = try? container.decode(ChronicleEnchantmentIdentifier.self) {
self = .chronicleEnchantmentIdentifier(chronicleEnchantmentIdentifier)
} else if let combatSpecialAbilityIdentifier = try? container.decode(CombatSpecialAbilityIdentifier.self) {
self = .combatSpecialAbilityIdentifier(combatSpecialAbilityIdentifier)
} else if let combatStyleSpecialAbilityIdentifier = try? container.decode(CombatStyleSpecialAbilityIdentifier.self) {
self = .combatStyleSpecialAbilityIdentifier(combatStyleSpecialAbilityIdentifier)
} else if let commandSpecialAbilityIdentifier = try? container.decode(CommandSpecialAbilityIdentifier.self) {
self = .commandSpecialAbilityIdentifier(commandSpecialAbilityIdentifier)
} else if let daggerRitualIdentifier = try? container.decode(DaggerRitualIdentifier.self) {
self = .daggerRitualIdentifier(daggerRitualIdentifier)
} else if let familiarSpecialAbilityIdentifier = try? container.decode(FamiliarSpecialAbilityIdentifier.self) {
self = .familiarSpecialAbilityIdentifier(familiarSpecialAbilityIdentifier)
} else if let fatePointSexSpecialAbilityIdentifier = try? container.decode(FatePointSexSpecialAbilityIdentifier.self) {
self = .fatePointSexSpecialAbilityIdentifier(fatePointSexSpecialAbilityIdentifier)
} else if let fatePointSpecialAbilityIdentifier = try? container.decode(FatePointSpecialAbilityIdentifier.self) {
self = .fatePointSpecialAbilityIdentifier(fatePointSpecialAbilityIdentifier)
} else if let foolsHatEnchantmentIdentifier = try? container.decode(FoolsHatEnchantmentIdentifier.self) {
self = .foolsHatEnchantmentIdentifier(foolsHatEnchantmentIdentifier)
} else if let generalSpecialAbilityIdentifier = try? container.decode(GeneralSpecialAbilityIdentifier.self) {
self = .generalSpecialAbilityIdentifier(generalSpecialAbilityIdentifier)
} else if let instrumentEnchantmentIdentifier = try? container.decode(InstrumentEnchantmentIdentifier.self) {
self = .instrumentEnchantmentIdentifier(instrumentEnchantmentIdentifier)
} else if let karmaSpecialAbilityIdentifier = try? container.decode(KarmaSpecialAbilityIdentifier.self) {
self = .karmaSpecialAbilityIdentifier(karmaSpecialAbilityIdentifier)
} else if let krallenkettenzauberIdentifier = try? container.decode(KrallenkettenzauberIdentifier.self) {
self = .krallenkettenzauberIdentifier(krallenkettenzauberIdentifier)
} else if let liturgicalStyleSpecialAbilityIdentifier = try? container.decode(LiturgicalStyleSpecialAbilityIdentifier.self) {
self = .liturgicalStyleSpecialAbilityIdentifier(liturgicalStyleSpecialAbilityIdentifier)
} else if let lycantropicGiftIdentifier = try? container.decode(LycantropicGiftIdentifier.self) {
self = .lycantropicGiftIdentifier(lycantropicGiftIdentifier)
} else if let magicalSignIdentifier = try? container.decode(MagicalSignIdentifier.self) {
self = .magicalSignIdentifier(magicalSignIdentifier)
} else if let magicalSpecialAbilityIdentifier = try? container.decode(MagicalSpecialAbilityIdentifier.self) {
self = .magicalSpecialAbilityIdentifier(magicalSpecialAbilityIdentifier)
} else if let magicalTraditionIdentifier = try? container.decode(MagicalTraditionIdentifier.self) {
self = .magicalTraditionIdentifier(magicalTraditionIdentifier)
} else if let magicStyleSpecialAbilityIdentifier = try? container.decode(MagicStyleSpecialAbilityIdentifier.self) {
self = .magicStyleSpecialAbilityIdentifier(magicStyleSpecialAbilityIdentifier)
} else if let orbEnchantmentIdentifier = try? container.decode(OrbEnchantmentIdentifier.self) {
self = .orbEnchantmentIdentifier(orbEnchantmentIdentifier)
} else if let pactGiftIdentifier = try? container.decode(PactGiftIdentifier.self) {
self = .pactGiftIdentifier(pactGiftIdentifier)
} else if let protectiveWardingCircleSpecialAbilityIdentifier = try? container.decode(ProtectiveWardingCircleSpecialAbilityIdentifier.self) {
self = .protectiveWardingCircleSpecialAbilityIdentifier(protectiveWardingCircleSpecialAbilityIdentifier)
} else if let ringEnchantmentIdentifier = try? container.decode(RingEnchantmentIdentifier.self) {
self = .ringEnchantmentIdentifier(ringEnchantmentIdentifier)
} else if let sermonIdentifier = try? container.decode(SermonIdentifier.self) {
self = .sermonIdentifier(sermonIdentifier)
} else if let sexSpecialAbilityIdentifier = try? container.decode(SexSpecialAbilityIdentifier.self) {
self = .sexSpecialAbilityIdentifier(sexSpecialAbilityIdentifier)
} else if let sickleRitualIdentifier = try? container.decode(SickleRitualIdentifier.self) {
self = .sickleRitualIdentifier(sickleRitualIdentifier)
} else if let sikaryanDrainSpecialAbilityIdentifier = try? container.decode(SikaryanDrainSpecialAbilityIdentifier.self) {
self = .sikaryanDrainSpecialAbilityIdentifier(sikaryanDrainSpecialAbilityIdentifier)
} else if let skillStyleSpecialAbilityIdentifier = try? container.decode(SkillStyleSpecialAbilityIdentifier.self) {
self = .skillStyleSpecialAbilityIdentifier(skillStyleSpecialAbilityIdentifier)
} else if let spellSwordEnchantmentIdentifier = try? container.decode(SpellSwordEnchantmentIdentifier.self) {
self = .spellSwordEnchantmentIdentifier(spellSwordEnchantmentIdentifier)
} else if let staffEnchantmentIdentifier = try? container.decode(StaffEnchantmentIdentifier.self) {
self = .staffEnchantmentIdentifier(staffEnchantmentIdentifier)
} else if let toyEnchantmentIdentifier = try? container.decode(ToyEnchantmentIdentifier.self) {
self = .toyEnchantmentIdentifier(toyEnchantmentIdentifier)
} else if let trinkhornzauberIdentifier = try? container.decode(TrinkhornzauberIdentifier.self) {
self = .trinkhornzauberIdentifier(trinkhornzauberIdentifier)
} else if let vampiricGiftIdentifier = try? container.decode(VampiricGiftIdentifier.self) {
self = .vampiricGiftIdentifier(vampiricGiftIdentifier)
} else if let visionIdentifier = try? container.decode(VisionIdentifier.self) {
self = .visionIdentifier(visionIdentifier)
} else if let wandEnchantmentIdentifier = try? container.decode(WandEnchantmentIdentifier.self) {
self = .wandEnchantmentIdentifier(wandEnchantmentIdentifier)
} else if let weaponEnchantmentIdentifier = try? container.decode(WeaponEnchantmentIdentifier.self) {
self = .weaponEnchantmentIdentifier(weaponEnchantmentIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No ActivatableIdentifier type found")
}
}
}
public enum SpecialAbilityIdentifier: EntitySubtype {
case advancedCombatSpecialAbilityIdentifier(AdvancedCombatSpecialAbilityIdentifier)
case advancedKarmaSpecialAbilityIdentifier(AdvancedKarmaSpecialAbilityIdentifier)
case advancedMagicalSpecialAbilityIdentifier(AdvancedMagicalSpecialAbilityIdentifier)
case advancedSkillSpecialAbilityIdentifier(AdvancedSkillSpecialAbilityIdentifier)
case ancestorGlyphIdentifier(AncestorGlyphIdentifier)
case arcaneOrbEnchantmentIdentifier(ArcaneOrbEnchantmentIdentifier)
case attireEnchantmentIdentifier(AttireEnchantmentIdentifier)
case blessedTraditionIdentifier(BlessedTraditionIdentifier)
case bowlEnchantmentIdentifier(BowlEnchantmentIdentifier)
case brawlingSpecialAbilityIdentifier(BrawlingSpecialAbilityIdentifier)
case cauldronEnchantmentIdentifier(CauldronEnchantmentIdentifier)
case ceremonialItemSpecialAbilityIdentifier(CeremonialItemSpecialAbilityIdentifier)
case chronicleEnchantmentIdentifier(ChronicleEnchantmentIdentifier)
case combatSpecialAbilityIdentifier(CombatSpecialAbilityIdentifier)
case combatStyleSpecialAbilityIdentifier(CombatStyleSpecialAbilityIdentifier)
case commandSpecialAbilityIdentifier(CommandSpecialAbilityIdentifier)
case daggerRitualIdentifier(DaggerRitualIdentifier)
case familiarSpecialAbilityIdentifier(FamiliarSpecialAbilityIdentifier)
case fatePointSexSpecialAbilityIdentifier(FatePointSexSpecialAbilityIdentifier)
case fatePointSpecialAbilityIdentifier(FatePointSpecialAbilityIdentifier)
case foolsHatEnchantmentIdentifier(FoolsHatEnchantmentIdentifier)
case generalSpecialAbilityIdentifier(GeneralSpecialAbilityIdentifier)
case instrumentEnchantmentIdentifier(InstrumentEnchantmentIdentifier)
case karmaSpecialAbilityIdentifier(KarmaSpecialAbilityIdentifier)
case krallenkettenzauberIdentifier(KrallenkettenzauberIdentifier)
case liturgicalStyleSpecialAbilityIdentifier(LiturgicalStyleSpecialAbilityIdentifier)
case lycantropicGiftIdentifier(LycantropicGiftIdentifier)
case magicalSignIdentifier(MagicalSignIdentifier)
case magicalSpecialAbilityIdentifier(MagicalSpecialAbilityIdentifier)
case magicalTraditionIdentifier(MagicalTraditionIdentifier)
case magicStyleSpecialAbilityIdentifier(MagicStyleSpecialAbilityIdentifier)
case orbEnchantmentIdentifier(OrbEnchantmentIdentifier)
case pactGiftIdentifier(PactGiftIdentifier)
case protectiveWardingCircleSpecialAbilityIdentifier(ProtectiveWardingCircleSpecialAbilityIdentifier)
case ringEnchantmentIdentifier(RingEnchantmentIdentifier)
case sermonIdentifier(SermonIdentifier)
case sexSpecialAbilityIdentifier(SexSpecialAbilityIdentifier)
case sickleRitualIdentifier(SickleRitualIdentifier)
case sikaryanDrainSpecialAbilityIdentifier(SikaryanDrainSpecialAbilityIdentifier)
case skillStyleSpecialAbilityIdentifier(SkillStyleSpecialAbilityIdentifier)
case spellSwordEnchantmentIdentifier(SpellSwordEnchantmentIdentifier)
case staffEnchantmentIdentifier(StaffEnchantmentIdentifier)
case toyEnchantmentIdentifier(ToyEnchantmentIdentifier)
case trinkhornzauberIdentifier(TrinkhornzauberIdentifier)
case vampiricGiftIdentifier(VampiricGiftIdentifier)
case visionIdentifier(VisionIdentifier)
case wandEnchantmentIdentifier(WandEnchantmentIdentifier)
case weaponEnchantmentIdentifier(WeaponEnchantmentIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let advancedCombatSpecialAbilityIdentifier = try? container.decode(AdvancedCombatSpecialAbilityIdentifier.self) {
self = .advancedCombatSpecialAbilityIdentifier(advancedCombatSpecialAbilityIdentifier)
} else if let advancedKarmaSpecialAbilityIdentifier = try? container.decode(AdvancedKarmaSpecialAbilityIdentifier.self) {
self = .advancedKarmaSpecialAbilityIdentifier(advancedKarmaSpecialAbilityIdentifier)
} else if let advancedMagicalSpecialAbilityIdentifier = try? container.decode(AdvancedMagicalSpecialAbilityIdentifier.self) {
self = .advancedMagicalSpecialAbilityIdentifier(advancedMagicalSpecialAbilityIdentifier)
} else if let advancedSkillSpecialAbilityIdentifier = try? container.decode(AdvancedSkillSpecialAbilityIdentifier.self) {
self = .advancedSkillSpecialAbilityIdentifier(advancedSkillSpecialAbilityIdentifier)
} else if let ancestorGlyphIdentifier = try? container.decode(AncestorGlyphIdentifier.self) {
self = .ancestorGlyphIdentifier(ancestorGlyphIdentifier)
} else if let arcaneOrbEnchantmentIdentifier = try? container.decode(ArcaneOrbEnchantmentIdentifier.self) {
self = .arcaneOrbEnchantmentIdentifier(arcaneOrbEnchantmentIdentifier)
} else if let attireEnchantmentIdentifier = try? container.decode(AttireEnchantmentIdentifier.self) {
self = .attireEnchantmentIdentifier(attireEnchantmentIdentifier)
} else if let blessedTraditionIdentifier = try? container.decode(BlessedTraditionIdentifier.self) {
self = .blessedTraditionIdentifier(blessedTraditionIdentifier)
} else if let bowlEnchantmentIdentifier = try? container.decode(BowlEnchantmentIdentifier.self) {
self = .bowlEnchantmentIdentifier(bowlEnchantmentIdentifier)
} else if let brawlingSpecialAbilityIdentifier = try? container.decode(BrawlingSpecialAbilityIdentifier.self) {
self = .brawlingSpecialAbilityIdentifier(brawlingSpecialAbilityIdentifier)
} else if let cauldronEnchantmentIdentifier = try? container.decode(CauldronEnchantmentIdentifier.self) {
self = .cauldronEnchantmentIdentifier(cauldronEnchantmentIdentifier)
} else if let ceremonialItemSpecialAbilityIdentifier = try? container.decode(CeremonialItemSpecialAbilityIdentifier.self) {
self = .ceremonialItemSpecialAbilityIdentifier(ceremonialItemSpecialAbilityIdentifier)
} else if let chronicleEnchantmentIdentifier = try? container.decode(ChronicleEnchantmentIdentifier.self) {
self = .chronicleEnchantmentIdentifier(chronicleEnchantmentIdentifier)
} else if let combatSpecialAbilityIdentifier = try? container.decode(CombatSpecialAbilityIdentifier.self) {
self = .combatSpecialAbilityIdentifier(combatSpecialAbilityIdentifier)
} else if let combatStyleSpecialAbilityIdentifier = try? container.decode(CombatStyleSpecialAbilityIdentifier.self) {
self = .combatStyleSpecialAbilityIdentifier(combatStyleSpecialAbilityIdentifier)
} else if let commandSpecialAbilityIdentifier = try? container.decode(CommandSpecialAbilityIdentifier.self) {
self = .commandSpecialAbilityIdentifier(commandSpecialAbilityIdentifier)
} else if let daggerRitualIdentifier = try? container.decode(DaggerRitualIdentifier.self) {
self = .daggerRitualIdentifier(daggerRitualIdentifier)
} else if let familiarSpecialAbilityIdentifier = try? container.decode(FamiliarSpecialAbilityIdentifier.self) {
self = .familiarSpecialAbilityIdentifier(familiarSpecialAbilityIdentifier)
} else if let fatePointSexSpecialAbilityIdentifier = try? container.decode(FatePointSexSpecialAbilityIdentifier.self) {
self = .fatePointSexSpecialAbilityIdentifier(fatePointSexSpecialAbilityIdentifier)
} else if let fatePointSpecialAbilityIdentifier = try? container.decode(FatePointSpecialAbilityIdentifier.self) {
self = .fatePointSpecialAbilityIdentifier(fatePointSpecialAbilityIdentifier)
} else if let foolsHatEnchantmentIdentifier = try? container.decode(FoolsHatEnchantmentIdentifier.self) {
self = .foolsHatEnchantmentIdentifier(foolsHatEnchantmentIdentifier)
} else if let generalSpecialAbilityIdentifier = try? container.decode(GeneralSpecialAbilityIdentifier.self) {
self = .generalSpecialAbilityIdentifier(generalSpecialAbilityIdentifier)
} else if let instrumentEnchantmentIdentifier = try? container.decode(InstrumentEnchantmentIdentifier.self) {
self = .instrumentEnchantmentIdentifier(instrumentEnchantmentIdentifier)
} else if let karmaSpecialAbilityIdentifier = try? container.decode(KarmaSpecialAbilityIdentifier.self) {
self = .karmaSpecialAbilityIdentifier(karmaSpecialAbilityIdentifier)
} else if let krallenkettenzauberIdentifier = try? container.decode(KrallenkettenzauberIdentifier.self) {
self = .krallenkettenzauberIdentifier(krallenkettenzauberIdentifier)
} else if let liturgicalStyleSpecialAbilityIdentifier = try? container.decode(LiturgicalStyleSpecialAbilityIdentifier.self) {
self = .liturgicalStyleSpecialAbilityIdentifier(liturgicalStyleSpecialAbilityIdentifier)
} else if let lycantropicGiftIdentifier = try? container.decode(LycantropicGiftIdentifier.self) {
self = .lycantropicGiftIdentifier(lycantropicGiftIdentifier)
} else if let magicalSignIdentifier = try? container.decode(MagicalSignIdentifier.self) {
self = .magicalSignIdentifier(magicalSignIdentifier)
} else if let magicalSpecialAbilityIdentifier = try? container.decode(MagicalSpecialAbilityIdentifier.self) {
self = .magicalSpecialAbilityIdentifier(magicalSpecialAbilityIdentifier)
} else if let magicalTraditionIdentifier = try? container.decode(MagicalTraditionIdentifier.self) {
self = .magicalTraditionIdentifier(magicalTraditionIdentifier)
} else if let magicStyleSpecialAbilityIdentifier = try? container.decode(MagicStyleSpecialAbilityIdentifier.self) {
self = .magicStyleSpecialAbilityIdentifier(magicStyleSpecialAbilityIdentifier)
} else if let orbEnchantmentIdentifier = try? container.decode(OrbEnchantmentIdentifier.self) {
self = .orbEnchantmentIdentifier(orbEnchantmentIdentifier)
} else if let pactGiftIdentifier = try? container.decode(PactGiftIdentifier.self) {
self = .pactGiftIdentifier(pactGiftIdentifier)
} else if let protectiveWardingCircleSpecialAbilityIdentifier = try? container.decode(ProtectiveWardingCircleSpecialAbilityIdentifier.self) {
self = .protectiveWardingCircleSpecialAbilityIdentifier(protectiveWardingCircleSpecialAbilityIdentifier)
} else if let ringEnchantmentIdentifier = try? container.decode(RingEnchantmentIdentifier.self) {
self = .ringEnchantmentIdentifier(ringEnchantmentIdentifier)
} else if let sermonIdentifier = try? container.decode(SermonIdentifier.self) {
self = .sermonIdentifier(sermonIdentifier)
} else if let sexSpecialAbilityIdentifier = try? container.decode(SexSpecialAbilityIdentifier.self) {
self = .sexSpecialAbilityIdentifier(sexSpecialAbilityIdentifier)
} else if let sickleRitualIdentifier = try? container.decode(SickleRitualIdentifier.self) {
self = .sickleRitualIdentifier(sickleRitualIdentifier)
} else if let sikaryanDrainSpecialAbilityIdentifier = try? container.decode(SikaryanDrainSpecialAbilityIdentifier.self) {
self = .sikaryanDrainSpecialAbilityIdentifier(sikaryanDrainSpecialAbilityIdentifier)
} else if let skillStyleSpecialAbilityIdentifier = try? container.decode(SkillStyleSpecialAbilityIdentifier.self) {
self = .skillStyleSpecialAbilityIdentifier(skillStyleSpecialAbilityIdentifier)
} else if let spellSwordEnchantmentIdentifier = try? container.decode(SpellSwordEnchantmentIdentifier.self) {
self = .spellSwordEnchantmentIdentifier(spellSwordEnchantmentIdentifier)
} else if let staffEnchantmentIdentifier = try? container.decode(StaffEnchantmentIdentifier.self) {
self = .staffEnchantmentIdentifier(staffEnchantmentIdentifier)
} else if let toyEnchantmentIdentifier = try? container.decode(ToyEnchantmentIdentifier.self) {
self = .toyEnchantmentIdentifier(toyEnchantmentIdentifier)
} else if let trinkhornzauberIdentifier = try? container.decode(TrinkhornzauberIdentifier.self) {
self = .trinkhornzauberIdentifier(trinkhornzauberIdentifier)
} else if let vampiricGiftIdentifier = try? container.decode(VampiricGiftIdentifier.self) {
self = .vampiricGiftIdentifier(vampiricGiftIdentifier)
} else if let visionIdentifier = try? container.decode(VisionIdentifier.self) {
self = .visionIdentifier(visionIdentifier)
} else if let wandEnchantmentIdentifier = try? container.decode(WandEnchantmentIdentifier.self) {
self = .wandEnchantmentIdentifier(wandEnchantmentIdentifier)
} else if let weaponEnchantmentIdentifier = try? container.decode(WeaponEnchantmentIdentifier.self) {
self = .weaponEnchantmentIdentifier(weaponEnchantmentIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No SpecialAbilityIdentifier type found")
}
}
}
public enum CombatRelatedSpecialAbilityIdentifier: EntitySubtype {
case combatSpecialAbilityIdentifier(CombatSpecialAbilityIdentifier)
case combatStyleSpecialAbilityIdentifier(CombatStyleSpecialAbilityIdentifier)
case advancedCombatSpecialAbilityIdentifier(AdvancedCombatSpecialAbilityIdentifier)
case commandSpecialAbilityIdentifier(CommandSpecialAbilityIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let combatSpecialAbilityIdentifier = try? container.decode(CombatSpecialAbilityIdentifier.self) {
self = .combatSpecialAbilityIdentifier(combatSpecialAbilityIdentifier)
} else if let combatStyleSpecialAbilityIdentifier = try? container.decode(CombatStyleSpecialAbilityIdentifier.self) {
self = .combatStyleSpecialAbilityIdentifier(combatStyleSpecialAbilityIdentifier)
} else if let advancedCombatSpecialAbilityIdentifier = try? container.decode(AdvancedCombatSpecialAbilityIdentifier.self) {
self = .advancedCombatSpecialAbilityIdentifier(advancedCombatSpecialAbilityIdentifier)
} else if let commandSpecialAbilityIdentifier = try? container.decode(CommandSpecialAbilityIdentifier.self) {
self = .commandSpecialAbilityIdentifier(commandSpecialAbilityIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No CombatRelatedSpecialAbilityIdentifier type found")
}
}
}
public enum TraditionIdentifier: EntitySubtype {
case magicalTraditionIdentifier(MagicalTraditionIdentifier)
case blessedTraditionIdentifier(BlessedTraditionIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let magicalTraditionIdentifier = try? container.decode(MagicalTraditionIdentifier.self) {
self = .magicalTraditionIdentifier(magicalTraditionIdentifier)
} else if let blessedTraditionIdentifier = try? container.decode(BlessedTraditionIdentifier.self) {
self = .blessedTraditionIdentifier(blessedTraditionIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No TraditionIdentifier type found")
}
}
}
public enum RatedIdentifier: EntitySubtype {
case attributeIdentifier(AttributeIdentifier)
case skillIdentifier(SkillIdentifier)
case closeCombatTechniqueIdentifier(CloseCombatTechniqueIdentifier)
case rangedCombatTechniqueIdentifier(RangedCombatTechniqueIdentifier)
case spellIdentifier(SpellIdentifier)
case ritualIdentifier(RitualIdentifier)
case liturgicalChantIdentifier(LiturgicalChantIdentifier)
case ceremonyIdentifier(CeremonyIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let attributeIdentifier = try? container.decode(AttributeIdentifier.self) {
self = .attributeIdentifier(attributeIdentifier)
} else if let skillIdentifier = try? container.decode(SkillIdentifier.self) {
self = .skillIdentifier(skillIdentifier)
} else if let closeCombatTechniqueIdentifier = try? container.decode(CloseCombatTechniqueIdentifier.self) {
self = .closeCombatTechniqueIdentifier(closeCombatTechniqueIdentifier)
} else if let rangedCombatTechniqueIdentifier = try? container.decode(RangedCombatTechniqueIdentifier.self) {
self = .rangedCombatTechniqueIdentifier(rangedCombatTechniqueIdentifier)
} else if let spellIdentifier = try? container.decode(SpellIdentifier.self) {
self = .spellIdentifier(spellIdentifier)
} else if let ritualIdentifier = try? container.decode(RitualIdentifier.self) {
self = .ritualIdentifier(ritualIdentifier)
} else if let liturgicalChantIdentifier = try? container.decode(LiturgicalChantIdentifier.self) {
self = .liturgicalChantIdentifier(liturgicalChantIdentifier)
} else if let ceremonyIdentifier = try? container.decode(CeremonyIdentifier.self) {
self = .ceremonyIdentifier(ceremonyIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No RatedIdentifier type found")
}
}
}
public enum SkillishIdentifier: EntitySubtype {
case skillIdentifier(SkillIdentifier)
case spellIdentifier(SpellIdentifier)
case ritualIdentifier(RitualIdentifier)
case liturgicalChantIdentifier(LiturgicalChantIdentifier)
case ceremonyIdentifier(CeremonyIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let skillIdentifier = try? container.decode(SkillIdentifier.self) {
self = .skillIdentifier(skillIdentifier)
} else if let spellIdentifier = try? container.decode(SpellIdentifier.self) {
self = .spellIdentifier(spellIdentifier)
} else if let ritualIdentifier = try? container.decode(RitualIdentifier.self) {
self = .ritualIdentifier(ritualIdentifier)
} else if let liturgicalChantIdentifier = try? container.decode(LiturgicalChantIdentifier.self) {
self = .liturgicalChantIdentifier(liturgicalChantIdentifier)
} else if let ceremonyIdentifier = try? container.decode(CeremonyIdentifier.self) {
self = .ceremonyIdentifier(ceremonyIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No SkillishIdentifier type found")
}
}
}
public enum AdvancedSpecialAbilityRestrictedOptionIdentifier: EntitySubtype {
case generalIdentifier(GeneralIdentifier)
case skillIdentifier(SkillIdentifier)
case elementIdentifier(ElementIdentifier)
case aspectIdentifier(AspectIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let generalIdentifier = try? container.decode(GeneralIdentifier.self) {
self = .generalIdentifier(generalIdentifier)
} else if let skillIdentifier = try? container.decode(SkillIdentifier.self) {
self = .skillIdentifier(skillIdentifier)
} else if let elementIdentifier = try? container.decode(ElementIdentifier.self) {
self = .elementIdentifier(elementIdentifier)
} else if let aspectIdentifier = try? container.decode(AspectIdentifier.self) {
self = .aspectIdentifier(aspectIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No AdvancedSpecialAbilityRestrictedOptionIdentifier type found")
}
}
}
public enum VolumePointsOptionReferenceIdentifier: EntitySubtype {
case generalIdentifier(GeneralIdentifier)
case animalShapeSizeIdentifier(AnimalShapeSizeIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let generalIdentifier = try? container.decode(GeneralIdentifier.self) {
self = .generalIdentifier(generalIdentifier)
} else if let animalShapeSizeIdentifier = try? container.decode(AnimalShapeSizeIdentifier.self) {
self = .animalShapeSizeIdentifier(animalShapeSizeIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No VolumePointsOptionReferenceIdentifier type found")
}
}
}
public enum CombatTechniqueIdentifier: EntitySubtype {
case closeCombatTechniqueIdentifier(CloseCombatTechniqueIdentifier)
case rangedCombatTechniqueIdentifier(RangedCombatTechniqueIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let closeCombatTechniqueIdentifier = try? container.decode(CloseCombatTechniqueIdentifier.self) {
self = .closeCombatTechniqueIdentifier(closeCombatTechniqueIdentifier)
} else if let rangedCombatTechniqueIdentifier = try? container.decode(RangedCombatTechniqueIdentifier.self) {
self = .rangedCombatTechniqueIdentifier(rangedCombatTechniqueIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No CombatTechniqueIdentifier type found")
}
}
}
public enum ExtensionRuleIdentifier: EntitySubtype {
case focusRuleIdentifier(FocusRuleIdentifier)
case optionalRuleIdentifier(OptionalRuleIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let focusRuleIdentifier = try? container.decode(FocusRuleIdentifier.self) {
self = .focusRuleIdentifier(focusRuleIdentifier)
} else if let optionalRuleIdentifier = try? container.decode(OptionalRuleIdentifier.self) {
self = .optionalRuleIdentifier(optionalRuleIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No ExtensionRuleIdentifier type found")
}
}
}
public enum SkillWithEnhancementsIdentifier: EntitySubtype {
case spellIdentifier(SpellIdentifier)
case ritualIdentifier(RitualIdentifier)
case liturgicalChantIdentifier(LiturgicalChantIdentifier)
case ceremonyIdentifier(CeremonyIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let spellIdentifier = try? container.decode(SpellIdentifier.self) {
self = .spellIdentifier(spellIdentifier)
} else if let ritualIdentifier = try? container.decode(RitualIdentifier.self) {
self = .ritualIdentifier(ritualIdentifier)
} else if let liturgicalChantIdentifier = try? container.decode(LiturgicalChantIdentifier.self) {
self = .liturgicalChantIdentifier(liturgicalChantIdentifier)
} else if let ceremonyIdentifier = try? container.decode(CeremonyIdentifier.self) {
self = .ceremonyIdentifier(ceremonyIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No SkillWithEnhancementsIdentifier type found")
}
}
}
public enum SpellworkIdentifier: EntitySubtype {
case spellIdentifier(SpellIdentifier)
case ritualIdentifier(RitualIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let spellIdentifier = try? container.decode(SpellIdentifier.self) {
self = .spellIdentifier(spellIdentifier)
} else if let ritualIdentifier = try? container.decode(RitualIdentifier.self) {
self = .ritualIdentifier(ritualIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No SpellworkIdentifier type found")
}
}
}
public enum LiturgyIdentifier: EntitySubtype {
case liturgicalChantIdentifier(LiturgicalChantIdentifier)
case ceremonyIdentifier(CeremonyIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let liturgicalChantIdentifier = try? container.decode(LiturgicalChantIdentifier.self) {
self = .liturgicalChantIdentifier(liturgicalChantIdentifier)
} else if let ceremonyIdentifier = try? container.decode(CeremonyIdentifier.self) {
self = .ceremonyIdentifier(ceremonyIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No LiturgyIdentifier type found")
}
}
}
public enum MagicalActionIdentifier: EntitySubtype {
case curseIdentifier(CurseIdentifier)
case elvenMagicalSongIdentifier(ElvenMagicalSongIdentifier)
case dominationRitualIdentifier(DominationRitualIdentifier)
case magicalMelodyIdentifier(MagicalMelodyIdentifier)
case magicalDanceIdentifier(MagicalDanceIdentifier)
case jesterTrickIdentifier(JesterTrickIdentifier)
case animistPowerIdentifier(AnimistPowerIdentifier)
case geodeRitualIdentifier(GeodeRitualIdentifier)
case zibiljaRitualIdentifier(ZibiljaRitualIdentifier)
case magicalRuneIdentifier(MagicalRuneIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let curseIdentifier = try? container.decode(CurseIdentifier.self) {
self = .curseIdentifier(curseIdentifier)
} else if let elvenMagicalSongIdentifier = try? container.decode(ElvenMagicalSongIdentifier.self) {
self = .elvenMagicalSongIdentifier(elvenMagicalSongIdentifier)
} else if let dominationRitualIdentifier = try? container.decode(DominationRitualIdentifier.self) {
self = .dominationRitualIdentifier(dominationRitualIdentifier)
} else if let magicalMelodyIdentifier = try? container.decode(MagicalMelodyIdentifier.self) {
self = .magicalMelodyIdentifier(magicalMelodyIdentifier)
} else if let magicalDanceIdentifier = try? container.decode(MagicalDanceIdentifier.self) {
self = .magicalDanceIdentifier(magicalDanceIdentifier)
} else if let jesterTrickIdentifier = try? container.decode(JesterTrickIdentifier.self) {
self = .jesterTrickIdentifier(jesterTrickIdentifier)
} else if let animistPowerIdentifier = try? container.decode(AnimistPowerIdentifier.self) {
self = .animistPowerIdentifier(animistPowerIdentifier)
} else if let geodeRitualIdentifier = try? container.decode(GeodeRitualIdentifier.self) {
self = .geodeRitualIdentifier(geodeRitualIdentifier)
} else if let zibiljaRitualIdentifier = try? container.decode(ZibiljaRitualIdentifier.self) {
self = .zibiljaRitualIdentifier(zibiljaRitualIdentifier)
} else if let magicalRuneIdentifier = try? container.decode(MagicalRuneIdentifier.self) {
self = .magicalRuneIdentifier(magicalRuneIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No MagicalActionIdentifier type found")
}
}
}
public enum SelectOptionIdentifier: EntitySubtype {
case generalIdentifier(GeneralIdentifier)
case blessingIdentifier(BlessingIdentifier)
case cantripIdentifier(CantripIdentifier)
case tradeSecretIdentifier(TradeSecretIdentifier)
case scriptIdentifier(ScriptIdentifier)
case animalShapeIdentifier(AnimalShapeIdentifier)
case arcaneBardTraditionIdentifier(ArcaneBardTraditionIdentifier)
case arcaneDancerTraditionIdentifier(ArcaneDancerTraditionIdentifier)
case sexPracticeIdentifier(SexPracticeIdentifier)
case raceIdentifier(RaceIdentifier)
case cultureIdentifier(CultureIdentifier)
case blessedTraditionIdentifier(BlessedTraditionIdentifier)
case elementIdentifier(ElementIdentifier)
case propertyIdentifier(PropertyIdentifier)
case aspectIdentifier(AspectIdentifier)
case diseaseIdentifier(DiseaseIdentifier)
case poisonIdentifier(PoisonIdentifier)
case languageIdentifier(LanguageIdentifier)
case skillIdentifier(SkillIdentifier)
case closeCombatTechniqueIdentifier(CloseCombatTechniqueIdentifier)
case rangedCombatTechniqueIdentifier(RangedCombatTechniqueIdentifier)
case liturgicalChantIdentifier(LiturgicalChantIdentifier)
case ceremonyIdentifier(CeremonyIdentifier)
case spellIdentifier(SpellIdentifier)
case ritualIdentifier(RitualIdentifier)
case targetCategoryIdentifier(TargetCategoryIdentifier)
case patronIdentifier(PatronIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let generalIdentifier = try? container.decode(GeneralIdentifier.self) {
self = .generalIdentifier(generalIdentifier)
} else if let blessingIdentifier = try? container.decode(BlessingIdentifier.self) {
self = .blessingIdentifier(blessingIdentifier)
} else if let cantripIdentifier = try? container.decode(CantripIdentifier.self) {
self = .cantripIdentifier(cantripIdentifier)
} else if let tradeSecretIdentifier = try? container.decode(TradeSecretIdentifier.self) {
self = .tradeSecretIdentifier(tradeSecretIdentifier)
} else if let scriptIdentifier = try? container.decode(ScriptIdentifier.self) {
self = .scriptIdentifier(scriptIdentifier)
} else if let animalShapeIdentifier = try? container.decode(AnimalShapeIdentifier.self) {
self = .animalShapeIdentifier(animalShapeIdentifier)
} else if let arcaneBardTraditionIdentifier = try? container.decode(ArcaneBardTraditionIdentifier.self) {
self = .arcaneBardTraditionIdentifier(arcaneBardTraditionIdentifier)
} else if let arcaneDancerTraditionIdentifier = try? container.decode(ArcaneDancerTraditionIdentifier.self) {
self = .arcaneDancerTraditionIdentifier(arcaneDancerTraditionIdentifier)
} else if let sexPracticeIdentifier = try? container.decode(SexPracticeIdentifier.self) {
self = .sexPracticeIdentifier(sexPracticeIdentifier)
} else if let raceIdentifier = try? container.decode(RaceIdentifier.self) {
self = .raceIdentifier(raceIdentifier)
} else if let cultureIdentifier = try? container.decode(CultureIdentifier.self) {
self = .cultureIdentifier(cultureIdentifier)
} else if let blessedTraditionIdentifier = try? container.decode(BlessedTraditionIdentifier.self) {
self = .blessedTraditionIdentifier(blessedTraditionIdentifier)
} else if let elementIdentifier = try? container.decode(ElementIdentifier.self) {
self = .elementIdentifier(elementIdentifier)
} else if let propertyIdentifier = try? container.decode(PropertyIdentifier.self) {
self = .propertyIdentifier(propertyIdentifier)
} else if let aspectIdentifier = try? container.decode(AspectIdentifier.self) {
self = .aspectIdentifier(aspectIdentifier)
} else if let diseaseIdentifier = try? container.decode(DiseaseIdentifier.self) {
self = .diseaseIdentifier(diseaseIdentifier)
} else if let poisonIdentifier = try? container.decode(PoisonIdentifier.self) {
self = .poisonIdentifier(poisonIdentifier)
} else if let languageIdentifier = try? container.decode(LanguageIdentifier.self) {
self = .languageIdentifier(languageIdentifier)
} else if let skillIdentifier = try? container.decode(SkillIdentifier.self) {
self = .skillIdentifier(skillIdentifier)
} else if let closeCombatTechniqueIdentifier = try? container.decode(CloseCombatTechniqueIdentifier.self) {
self = .closeCombatTechniqueIdentifier(closeCombatTechniqueIdentifier)
} else if let rangedCombatTechniqueIdentifier = try? container.decode(RangedCombatTechniqueIdentifier.self) {
self = .rangedCombatTechniqueIdentifier(rangedCombatTechniqueIdentifier)
} else if let liturgicalChantIdentifier = try? container.decode(LiturgicalChantIdentifier.self) {
self = .liturgicalChantIdentifier(liturgicalChantIdentifier)
} else if let ceremonyIdentifier = try? container.decode(CeremonyIdentifier.self) {
self = .ceremonyIdentifier(ceremonyIdentifier)
} else if let spellIdentifier = try? container.decode(SpellIdentifier.self) {
self = .spellIdentifier(spellIdentifier)
} else if let ritualIdentifier = try? container.decode(RitualIdentifier.self) {
self = .ritualIdentifier(ritualIdentifier)
} else if let targetCategoryIdentifier = try? container.decode(TargetCategoryIdentifier.self) {
self = .targetCategoryIdentifier(targetCategoryIdentifier)
} else if let patronIdentifier = try? container.decode(PatronIdentifier.self) {
self = .patronIdentifier(patronIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No SelectOptionIdentifier type found")
}
}
}
public enum RequirableSelectOptionIdentifier: EntitySubtype {
case generalIdentifier(GeneralIdentifier)
case skillIdentifier(SkillIdentifier)
case closeCombatTechniqueIdentifier(CloseCombatTechniqueIdentifier)
case rangedCombatTechniqueIdentifier(RangedCombatTechniqueIdentifier)
case propertyIdentifier(PropertyIdentifier)
case aspectIdentifier(AspectIdentifier)
case languageIdentifier(LanguageIdentifier)
case animalShapeIdentifier(AnimalShapeIdentifier)
case liturgicalChantIdentifier(LiturgicalChantIdentifier)
case ceremonyIdentifier(CeremonyIdentifier)
case spellIdentifier(SpellIdentifier)
case ritualIdentifier(RitualIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let generalIdentifier = try? container.decode(GeneralIdentifier.self) {
self = .generalIdentifier(generalIdentifier)
} else if let skillIdentifier = try? container.decode(SkillIdentifier.self) {
self = .skillIdentifier(skillIdentifier)
} else if let closeCombatTechniqueIdentifier = try? container.decode(CloseCombatTechniqueIdentifier.self) {
self = .closeCombatTechniqueIdentifier(closeCombatTechniqueIdentifier)
} else if let rangedCombatTechniqueIdentifier = try? container.decode(RangedCombatTechniqueIdentifier.self) {
self = .rangedCombatTechniqueIdentifier(rangedCombatTechniqueIdentifier)
} else if let propertyIdentifier = try? container.decode(PropertyIdentifier.self) {
self = .propertyIdentifier(propertyIdentifier)
} else if let aspectIdentifier = try? container.decode(AspectIdentifier.self) {
self = .aspectIdentifier(aspectIdentifier)
} else if let languageIdentifier = try? container.decode(LanguageIdentifier.self) {
self = .languageIdentifier(languageIdentifier)
} else if let animalShapeIdentifier = try? container.decode(AnimalShapeIdentifier.self) {
self = .animalShapeIdentifier(animalShapeIdentifier)
} else if let liturgicalChantIdentifier = try? container.decode(LiturgicalChantIdentifier.self) {
self = .liturgicalChantIdentifier(liturgicalChantIdentifier)
} else if let ceremonyIdentifier = try? container.decode(CeremonyIdentifier.self) {
self = .ceremonyIdentifier(ceremonyIdentifier)
} else if let spellIdentifier = try? container.decode(SpellIdentifier.self) {
self = .spellIdentifier(spellIdentifier)
} else if let ritualIdentifier = try? container.decode(RitualIdentifier.self) {
self = .ritualIdentifier(ritualIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No RequirableSelectOptionIdentifier type found")
}
}
}
public enum CoreRuleDerivableContentIdentifier: EntitySubtype {
case magicalTraditionIdentifier(MagicalTraditionIdentifier)
case familiarSpecialAbilityIdentifier(FamiliarSpecialAbilityIdentifier)
case magicalSpecialAbilityIdentifier(MagicalSpecialAbilityIdentifier)
case blessedTraditionIdentifier(BlessedTraditionIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let magicalTraditionIdentifier = try? container.decode(MagicalTraditionIdentifier.self) {
self = .magicalTraditionIdentifier(magicalTraditionIdentifier)
} else if let familiarSpecialAbilityIdentifier = try? container.decode(FamiliarSpecialAbilityIdentifier.self) {
self = .familiarSpecialAbilityIdentifier(familiarSpecialAbilityIdentifier)
} else if let magicalSpecialAbilityIdentifier = try? container.decode(MagicalSpecialAbilityIdentifier.self) {
self = .magicalSpecialAbilityIdentifier(magicalSpecialAbilityIdentifier)
} else if let blessedTraditionIdentifier = try? container.decode(BlessedTraditionIdentifier.self) {
self = .blessedTraditionIdentifier(blessedTraditionIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No CoreRuleDerivableContentIdentifier type found")
}
}
}
public enum EquipmentIdentifier: EntitySubtype {
case ammunitionIdentifier(AmmunitionIdentifier)
case animalIdentifier(AnimalIdentifier)
case animalCareIdentifier(AnimalCareIdentifier)
case armorIdentifier(ArmorIdentifier)
case bandageOrRemedyIdentifier(BandageOrRemedyIdentifier)
case bookIdentifier(BookIdentifier)
case ceremonialItemIdentifier(CeremonialItemIdentifier)
case clothesIdentifier(ClothesIdentifier)
case containerIdentifier(ContainerIdentifier)
case elixirIdentifier(ElixirIdentifier)
case equipmentOfBlessedOnesIdentifier(EquipmentOfBlessedOnesIdentifier)
case gemOrPreciousStoneIdentifier(GemOrPreciousStoneIdentifier)
case illuminationLightSourceIdentifier(IlluminationLightSourceIdentifier)
case illuminationRefillsOrSuppliesIdentifier(IlluminationRefillsOrSuppliesIdentifier)
case jewelryIdentifier(JewelryIdentifier)
case liebesspielzeugIdentifier(LiebesspielzeugIdentifier)
case luxuryGoodIdentifier(LuxuryGoodIdentifier)
case magicalArtifactIdentifier(MagicalArtifactIdentifier)
case musicalInstrumentIdentifier(MusicalInstrumentIdentifier)
case orienteeringAidIdentifier(OrienteeringAidIdentifier)
case poisonIdentifier(PoisonIdentifier)
case ropeOrChainIdentifier(RopeOrChainIdentifier)
case stationaryIdentifier(StationaryIdentifier)
case thievesToolIdentifier(ThievesToolIdentifier)
case toolOfTheTradeIdentifier(ToolOfTheTradeIdentifier)
case travelGearOrToolIdentifier(TravelGearOrToolIdentifier)
case vehicleIdentifier(VehicleIdentifier)
case weaponIdentifier(WeaponIdentifier)
case weaponAccessoryIdentifier(WeaponAccessoryIdentifier)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let ammunitionIdentifier = try? container.decode(AmmunitionIdentifier.self) {
self = .ammunitionIdentifier(ammunitionIdentifier)
} else if let animalIdentifier = try? container.decode(AnimalIdentifier.self) {
self = .animalIdentifier(animalIdentifier)
} else if let animalCareIdentifier = try? container.decode(AnimalCareIdentifier.self) {
self = .animalCareIdentifier(animalCareIdentifier)
} else if let armorIdentifier = try? container.decode(ArmorIdentifier.self) {
self = .armorIdentifier(armorIdentifier)
} else if let bandageOrRemedyIdentifier = try? container.decode(BandageOrRemedyIdentifier.self) {
self = .bandageOrRemedyIdentifier(bandageOrRemedyIdentifier)
} else if let bookIdentifier = try? container.decode(BookIdentifier.self) {
self = .bookIdentifier(bookIdentifier)
} else if let ceremonialItemIdentifier = try? container.decode(CeremonialItemIdentifier.self) {
self = .ceremonialItemIdentifier(ceremonialItemIdentifier)
} else if let clothesIdentifier = try? container.decode(ClothesIdentifier.self) {
self = .clothesIdentifier(clothesIdentifier)
} else if let containerIdentifier = try? container.decode(ContainerIdentifier.self) {
self = .containerIdentifier(containerIdentifier)
} else if let elixirIdentifier = try? container.decode(ElixirIdentifier.self) {
self = .elixirIdentifier(elixirIdentifier)
} else if let equipmentOfBlessedOnesIdentifier = try? container.decode(EquipmentOfBlessedOnesIdentifier.self) {
self = .equipmentOfBlessedOnesIdentifier(equipmentOfBlessedOnesIdentifier)
} else if let gemOrPreciousStoneIdentifier = try? container.decode(GemOrPreciousStoneIdentifier.self) {
self = .gemOrPreciousStoneIdentifier(gemOrPreciousStoneIdentifier)
} else if let illuminationLightSourceIdentifier = try? container.decode(IlluminationLightSourceIdentifier.self) {
self = .illuminationLightSourceIdentifier(illuminationLightSourceIdentifier)
} else if let illuminationRefillsOrSuppliesIdentifier = try? container.decode(IlluminationRefillsOrSuppliesIdentifier.self) {
self = .illuminationRefillsOrSuppliesIdentifier(illuminationRefillsOrSuppliesIdentifier)
} else if let jewelryIdentifier = try? container.decode(JewelryIdentifier.self) {
self = .jewelryIdentifier(jewelryIdentifier)
} else if let liebesspielzeugIdentifier = try? container.decode(LiebesspielzeugIdentifier.self) {
self = .liebesspielzeugIdentifier(liebesspielzeugIdentifier)
} else if let luxuryGoodIdentifier = try? container.decode(LuxuryGoodIdentifier.self) {
self = .luxuryGoodIdentifier(luxuryGoodIdentifier)
} else if let magicalArtifactIdentifier = try? container.decode(MagicalArtifactIdentifier.self) {
self = .magicalArtifactIdentifier(magicalArtifactIdentifier)
} else if let musicalInstrumentIdentifier = try? container.decode(MusicalInstrumentIdentifier.self) {
self = .musicalInstrumentIdentifier(musicalInstrumentIdentifier)
} else if let orienteeringAidIdentifier = try? container.decode(OrienteeringAidIdentifier.self) {
self = .orienteeringAidIdentifier(orienteeringAidIdentifier)
} else if let poisonIdentifier = try? container.decode(PoisonIdentifier.self) {
self = .poisonIdentifier(poisonIdentifier)
} else if let ropeOrChainIdentifier = try? container.decode(RopeOrChainIdentifier.self) {
self = .ropeOrChainIdentifier(ropeOrChainIdentifier)
} else if let stationaryIdentifier = try? container.decode(StationaryIdentifier.self) {
self = .stationaryIdentifier(stationaryIdentifier)
} else if let thievesToolIdentifier = try? container.decode(ThievesToolIdentifier.self) {
self = .thievesToolIdentifier(thievesToolIdentifier)
} else if let toolOfTheTradeIdentifier = try? container.decode(ToolOfTheTradeIdentifier.self) {
self = .toolOfTheTradeIdentifier(toolOfTheTradeIdentifier)
} else if let travelGearOrToolIdentifier = try? container.decode(TravelGearOrToolIdentifier.self) {
self = .travelGearOrToolIdentifier(travelGearOrToolIdentifier)
} else if let vehicleIdentifier = try? container.decode(VehicleIdentifier.self) {
self = .vehicleIdentifier(vehicleIdentifier)
} else if let weaponIdentifier = try? container.decode(WeaponIdentifier.self) {
self = .weaponIdentifier(weaponIdentifier)
} else if let weaponAccessoryIdentifier = try? container.decode(WeaponAccessoryIdentifier.self) {
self = .weaponAccessoryIdentifier(weaponAccessoryIdentifier)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No EquipmentIdentifier type found")
}
}
}
public enum OneOrManyNumericIdentifiers: EntitySubtype {
case oneNumericIdentifier(OneNumericIdentifier)
case manyNumericIdentifiers(ManyNumericIdentifiers)
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if let oneNumericIdentifier = try? container.decode(OneNumericIdentifier.self) {
self = .oneNumericIdentifier(oneNumericIdentifier)
} else if let manyNumericIdentifiers = try? container.decode(ManyNumericIdentifiers.self) {
self = .manyNumericIdentifiers(manyNumericIdentifiers)
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "No OneOrManyNumericIdentifiers type found")
}
}
}
public typealias OneNumericIdentifier = Double
public typealias ManyNumericIdentifiers = [OneNumericIdentifier]
@@ -1,11 +0,0 @@
//
// _ImprovementCost.swift
// OptolithDatabaseSchema
//
public enum ImprovementCost: String, EntitySubtype {
case a = "A"
case b = "B"
case c = "C"
case d = "D"
}
@@ -1,52 +0,0 @@
//
// _Influence.swift
// OptolithDatabaseSchema
//
public struct Influence: LocalizableEntity {
/// The influence's identifier. An unique, increasing integer.
public let id: Int
public let prerequisites: InfluencePrerequisites
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<InfluenceTranslation>
public init(id: Int, prerequisites: InfluencePrerequisites, src: PublicationRefs, translations: LocaleMap<InfluenceTranslation>) {
self.id = id
self.prerequisites = prerequisites
self.src = src
self.translations = translations
}
}
public struct InfluenceTranslation: EntitySubtype {
/// The influence name.
public let name: NonEmptyString
/// The effects of the influence. They should be sorted like they are in the book.
public let effects: [InfluenceEffect]
public let errata: Errata?
public init(name: NonEmptyString, effects: [InfluenceEffect], errata: Errata? = nil) {
self.name = name
self.effects = effects
self.errata = errata
}
}
public struct InfluenceEffect: EntitySubtype {
/// An optional label that is displayed and placed before the actual text.
public let label: NonEmptyString?
/// The effect text.
public let text: NonEmptyString
public init(label: NonEmptyString? = nil, text: NonEmptyString) {
self.label = label
self.text = text
}
}
@@ -1,8 +0,0 @@
//
// _NonEmptyString.swift
// OptolithDatabaseSchema
//
public typealias NonEmptyString = String
public typealias NonEmptyMarkdown = String
@@ -1,110 +0,0 @@
//
// _Prerequisite.swift
// OptolithDatabaseSchema
//
/// A prerequisite group has no influence on validation logic. It serves as a single unit for displaying purposes, where the source uses a prerequisites item that cannot be represented as a single prerequisite.
public struct PrerequisiteGroup<T: EntitySubtype>: EntitySubtype {
public let list: [T]
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<NonEmptyString>
public init(list: [T], translations: LocaleMap<NonEmptyString>) {
self.list = list
self.translations = translations
}
}
public struct PrerequisitesDisjunction<T: EntitySubtype>: EntitySubtype {
public let list: [T]
public let displayOption: DisplayOption?
public init(list: [T], displayOption: DisplayOption? = nil) {
self.list = list
self.displayOption = displayOption
}
private enum CodingKeys: String, CodingKey {
case list = "list"
case displayOption = "display_option"
}
}
public enum PrerequisitesElement<T: EntitySubtype>: EntitySubtype {
case single(T)
case disjunction(PrerequisitesDisjunction<T>)
case group(PrerequisiteGroup<T>)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case single = "single"
case disjunction = "disjunction"
case group = "group"
}
private enum Discriminator: String, Decodable {
case single = "Single"
case disjunction = "Disjunction"
case group = "Group"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .single:
self = .single(try container.decode(T.self, forKey: .single))
case .disjunction:
self = .disjunction(try container.decode(PrerequisitesDisjunction<T>.self, forKey: .disjunction))
case .group:
self = .group(try container.decode(PrerequisiteGroup<T>.self, forKey: .group))
}
}
}
public typealias PlainPrerequisites<T: EntitySubtype> = [PrerequisitesElement<T>]
public struct PrerequisiteForLevel<T: EntitySubtype>: EntitySubtype {
public let level: Int
public let prerequisite: PrerequisitesElement<T>
public init(level: Int, prerequisite: PrerequisitesElement<T>) {
self.level = level
self.prerequisite = prerequisite
}
}
public typealias PrerequisitesForLevels<T: EntitySubtype> = [PrerequisiteForLevel<T>]
public typealias DerivedCharacteristicPrerequisites = PlainPrerequisites<DerivedCharacteristicPrerequisiteGroup>
public typealias PublicationPrerequisites = PlainPrerequisites<PublicationPrerequisiteGroup>
public typealias PlainGeneralPrerequisites = PlainPrerequisites<GeneralPrerequisiteGroup>
public typealias GeneralPrerequisites = PrerequisitesForLevels<GeneralPrerequisiteGroup>
public typealias ProfessionPrerequisites = PlainPrerequisites<ProfessionPrerequisiteGroup>
public typealias AdvantageDisadvantagePrerequisites = PrerequisitesForLevels<AdvantageDisadvantagePrerequisiteGroup>
public typealias ArcaneTraditionPrerequisites = PlainPrerequisites<ArcaneTraditionPrerequisiteGroup>
public typealias PersonalityTraitPrerequisites = PlainPrerequisites<PersonalityTraitPrerequisiteGroup>
public typealias SpellworkPrerequisites = PlainPrerequisites<SpellworkPrerequisiteGroup>
public typealias LiturgyPrerequisites = PlainPrerequisites<LiturgyPrerequisiteGroup>
public typealias InfluencePrerequisites = PlainPrerequisites<InfluencePrerequisiteGroup>
public typealias LanguagePrerequisites = PrerequisitesForLevels<LanguagePrerequisiteGroup>
public typealias AnimistPowerPrerequisites = PlainPrerequisites<AnimistPowerPrerequisiteGroup>
public typealias GeodeRitualPrerequisites = PlainPrerequisites<GeodeRitualPrerequisiteGroup>
public typealias EnhancementPrerequisites = PlainPrerequisites<EnhancementPrerequisiteGroup>
@@ -1,9 +0,0 @@
//
// _Sex.swift
// OptolithDatabaseSchema
//
public enum BinarySex: String, Entity {
case male = "Male"
case female = "Female"
}
@@ -1,356 +0,0 @@
//
// _SimpleReferences.swift
// OptolithDatabaseSchema
//
public struct FocusRuleSubjectReference: EntitySubtype {
public let id: SubjectIdentifier
public init(id: SubjectIdentifier) {
self.id = id
}
}
public struct RaceReference: EntitySubtype {
public let id: RaceIdentifier
public init(id: RaceIdentifier) {
self.id = id
}
}
public struct CultureReference: EntitySubtype {
public let id: CultureIdentifier
public init(id: CultureIdentifier) {
self.id = id
}
}
public struct ProfessionReference: EntitySubtype {
public let id: ProfessionIdentifier
public init(id: ProfessionIdentifier) {
self.id = id
}
}
public struct ProfessionVariantReference: EntitySubtype {
public let id: ProfessionVariantIdentifier
public init(id: ProfessionVariantIdentifier) {
self.id = id
}
}
public struct AttributeReference: EntitySubtype {
public let id: AttributeIdentifier
public init(id: AttributeIdentifier) {
self.id = id
}
}
public struct SkillReference: EntitySubtype {
public let id: SkillIdentifier
public init(id: SkillIdentifier) {
self.id = id
}
}
public struct SkillGroupReference: EntitySubtype {
public let id: SkillGroupIdentifier
public init(id: SkillGroupIdentifier) {
self.id = id
}
}
public struct CombatTechniqueReference: EntitySubtype {
public let id: CombatTechniqueIdentifier
public init(id: CombatTechniqueIdentifier) {
self.id = id
}
}
public struct CloseCombatTechniqueReference: EntitySubtype {
public let id: CloseCombatTechniqueIdentifier
public init(id: CloseCombatTechniqueIdentifier) {
self.id = id
}
}
public struct RangedCombatTechniqueReference: EntitySubtype {
public let id: RangedCombatTechniqueIdentifier
public init(id: RangedCombatTechniqueIdentifier) {
self.id = id
}
}
public struct MagicalTraditionReference: EntitySubtype {
public let id: MagicalTraditionIdentifier
public init(id: MagicalTraditionIdentifier) {
self.id = id
}
}
public struct CantripReference: EntitySubtype {
public let id: CantripIdentifier
public init(id: CantripIdentifier) {
self.id = id
}
}
public struct SpellReference: EntitySubtype {
public let id: SpellIdentifier
public init(id: SpellIdentifier) {
self.id = id
}
}
public struct RitualReference: EntitySubtype {
public let id: RitualIdentifier
public init(id: RitualIdentifier) {
self.id = id
}
}
public struct SpellworkReference: EntitySubtype {
public let id: SpellworkIdentifier
public init(id: SpellworkIdentifier) {
self.id = id
}
}
public struct PropertyReference: EntitySubtype {
public let id: PropertyIdentifier
public init(id: PropertyIdentifier) {
self.id = id
}
}
public struct BlessedTraditionReference: EntitySubtype {
public let id: BlessedTraditionIdentifier
public init(id: BlessedTraditionIdentifier) {
self.id = id
}
}
public struct BlessingReference: EntitySubtype {
public let id: BlessingIdentifier
public init(id: BlessingIdentifier) {
self.id = id
}
}
public struct LiturgicalChantReference: EntitySubtype {
public let id: LiturgicalChantIdentifier
public init(id: LiturgicalChantIdentifier) {
self.id = id
}
}
public struct CeremonyReference: EntitySubtype {
public let id: CeremonyIdentifier
public init(id: CeremonyIdentifier) {
self.id = id
}
}
public struct AspectReference: EntitySubtype {
public let id: AspectIdentifier
public init(id: AspectIdentifier) {
self.id = id
}
}
public struct AdvantageReference: EntitySubtype {
public let id: AdvantageIdentifier
public init(id: AdvantageIdentifier) {
self.id = id
}
}
public struct DisadvantageReference: EntitySubtype {
public let id: DisadvantageIdentifier
public init(id: DisadvantageIdentifier) {
self.id = id
}
}
public struct AdvancedSpecialAbilityReference<Identifier: EntitySubtype>: EntitySubtype {
public let id: Identifier
public init(id: Identifier) {
self.id = id
}
}
public struct LanguageReference: EntitySubtype {
public let id: LanguageIdentifier
public init(id: LanguageIdentifier) {
self.id = id
}
}
public struct ScriptReference: EntitySubtype {
public let id: ScriptIdentifier
public init(id: ScriptIdentifier) {
self.id = id
}
}
public struct SocialStatusReference: EntitySubtype {
public let id: SocialStatusIdentifier
public init(id: SocialStatusIdentifier) {
self.id = id
}
}
public struct CurriculumReference: EntitySubtype {
public let id: CurriculumIdentifier
public init(id: CurriculumIdentifier) {
self.id = id
}
}
public struct GuidelineReference: EntitySubtype {
public let id: GuidelineIdentifier
public init(id: GuidelineIdentifier) {
self.id = id
}
}
public struct AnimalTypeReference: EntitySubtype {
public let id: AnimalTypeIdentifier
public init(id: AnimalTypeIdentifier) {
self.id = id
}
}
public struct TargetCategoryReference: EntitySubtype {
public let id: TargetCategoryIdentifier
public init(id: TargetCategoryIdentifier) {
self.id = id
}
}
public struct PatronCategoryReference: EntitySubtype {
public let id: PatronCategoryIdentifier
public init(id: PatronCategoryIdentifier) {
self.id = id
}
}
public struct PersonalityTraitReference: EntitySubtype {
public let id: PersonalityTraitIdentifier
public init(id: PersonalityTraitIdentifier) {
self.id = id
}
}
public struct HairColorReference: EntitySubtype {
public let id: HairColorIdentifier
public init(id: HairColorIdentifier) {
self.id = id
}
}
public struct EyeColorReference: EntitySubtype {
public let id: EyeColorIdentifier
public init(id: EyeColorIdentifier) {
self.id = id
}
}
public struct PactCategoryReference: EntitySubtype {
public let id: PactCategoryIdentifier
public init(id: PactCategoryIdentifier) {
self.id = id
}
}
public struct PactDomainReference: EntitySubtype {
public let id: PactDomainIdentifier
public init(id: PactDomainIdentifier) {
self.id = id
}
}
public struct PatronReference: EntitySubtype {
public let id: PatronIdentifier
public init(id: PatronIdentifier) {
self.id = id
}
}
public struct AnimistTribeReference: EntitySubtype {
public let id: AnimistTribeIdentifier
public init(id: AnimistTribeIdentifier) {
self.id = id
}
}
public struct ElementReference: EntitySubtype {
public let id: ElementIdentifier
public init(id: ElementIdentifier) {
self.id = id
}
}
public struct WeaponReference: EntitySubtype {
public let id: WeaponIdentifier
public init(id: WeaponIdentifier) {
self.id = id
}
}
public struct ArmorReference: EntitySubtype {
public let id: ArmorIdentifier
public init(id: ArmorIdentifier) {
self.id = id
}
}
public struct TraditionReference: EntitySubtype {
public let id: TraditionIdentifier
public init(id: TraditionIdentifier) {
self.id = id
}
}
@@ -1,17 +0,0 @@
//
// _SkillCheck.swift
// OptolithDatabaseSchema
//
/// The attributes' identifiers of the skill check.
public typealias SkillCheck = [AttributeReference]
/// A specific value that represents a penalty for the associated skill check.
public enum SkillCheckPenalty: String, EntitySubtype {
case spirit = "Spirit"
case halfOfSpirit = "HalfOfSpirit"
case toughness = "Toughness"
case higherOfSpiritAndToughness = "HigherOfSpiritAndToughness"
case summoningDifficulty = "SummoningDifficulty"
case creationDifficulty = "CreationDifficulty"
}
@@ -1,35 +0,0 @@
//
// _Spellwork.swift
// OptolithDatabaseSchema
//
/// The tradition(s) the ritual is available for. It may be *generally* available to all traditions or it may be only familiar in specific traditions.
public enum Traditions: EntitySubtype {
case general
case specific(SpecificTraditions)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case general = "general"
case specific = "specific"
}
private enum Discriminator: String, Decodable {
case general = "General"
case specific = "Specific"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .general:
self = .general
case .specific:
self = .specific(try container.decode(SpecificTraditions.self, forKey: .specific))
}
}
}
/// A list of specific traditions.
public typealias SpecificTraditions = [MagicalTraditionIdentifier]
@@ -1,46 +0,0 @@
//
// EquipmentPackage.swift
// OptolithDatabaseSchema
//
public struct EquipmentPackage: LocalizableEntity {
/// The equipment package's identifier. An unique, increasing integer.
public let id: Int
/// All items in the package. You have to provide the item (template) identifier and you can optionally provide the number of how often an item is included in the package.
public let items: [EquipmentPackageItem]
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<EquipmentPackageTranslation>
public init(id: Int, items: [EquipmentPackageItem], src: PublicationRefs, translations: LocaleMap<EquipmentPackageTranslation>) {
self.id = id
self.items = items
self.src = src
self.translations = translations
}
}
public struct EquipmentPackageItem: EntitySubtype {
/// The item's identifier.
public let id: EquipmentIdentifier
/// The number of how often the item is included in the package.
public let number: Int?
public init(id: EquipmentIdentifier, number: Int? = nil) {
self.id = id
self.number = number
}
}
public struct EquipmentPackageTranslation: EntitySubtype {
/// The name of the equipment package.
public let name: NonEmptyString
public init(name: NonEmptyString) {
self.name = name
}
}
@@ -1,42 +0,0 @@
//
// Ammunition.swift
// OptolithDatabaseSchema
//
public struct Ammunition: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<AmmunitionTranslation>
public init(cost: Cost, src: PublicationRefs, translations: LocaleMap<AmmunitionTranslation>) {
self.cost = cost
self.src = src
self.translations = translations
}
}
public struct AmmunitionTranslation: EntitySubtype {
/// The name of the item.
public let name: NonEmptyString
/// An auxiliary name or label of the item, if available.
public let secondaryName: NonEmptyString?
public let errata: Errata?
public init(name: NonEmptyString, secondaryName: NonEmptyString? = nil, errata: Errata? = nil) {
self.name = name
self.secondaryName = secondaryName
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case secondaryName = "secondary_name"
case errata = "errata"
}
}
@@ -1,20 +0,0 @@
//
// Animal.swift
// OptolithDatabaseSchema
//
public struct Animal: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DefaultItemTranslation>
public init(cost: Cost, src: PublicationRefs, translations: LocaleMap<DefaultItemTranslation>) {
self.cost = cost
self.src = src
self.translations = translations
}
}
@@ -1,92 +0,0 @@
//
// AnimalCare.swift
// OptolithDatabaseSchema
//
public struct AnimalCare: LocalizableEntity {
/// Values depending on whether the animal care is feed.
public let type: AnimalCareType
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DefaultItemTranslation>
public init(type: AnimalCareType, src: PublicationRefs, translations: LocaleMap<DefaultItemTranslation>) {
self.type = type
self.src = src
self.translations = translations
}
}
/// Values depending on whether the animal care is feed.
public enum AnimalCareType: EntitySubtype {
case general(GeneralAnimalCare)
case feed(AnimalFeed)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case general = "general"
case feed = "feed"
}
private enum Discriminator: String, Decodable {
case general = "General"
case feed = "Feed"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .general:
self = .general(try container.decode(GeneralAnimalCare.self, forKey: .general))
case .feed:
self = .feed(try container.decode(AnimalFeed.self, forKey: .feed))
}
}
}
public struct GeneralAnimalCare: EntitySubtype {
/// The cost in silverthalers.
public let cost: Cost
/// The weight in kg.
public let weight: Weight
public init(cost: Cost, weight: Weight) {
self.cost = cost
self.weight = weight
}
}
public struct AnimalFeed: EntitySubtype {
/// The cost in silverthalers.
public let cost: AnimalFeedCost
public init(cost: AnimalFeedCost) {
self.cost = cost
}
}
public enum AnimalFeedCost: EntitySubtype {
case perWeek(FixedCost)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case perWeek = "per_week"
}
private enum Discriminator: String, Decodable {
case perWeek = "PerWeek"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .perWeek:
self = .perWeek(try container.decode(FixedCost.self, forKey: .perWeek))
}
}
}
@@ -1,237 +0,0 @@
//
// Armor.swift
// OptolithDatabaseSchema
//
public struct Armor: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
/// The weight in kg.
public let weight: Weight
/// The complexity of crafting the item.
public let complexity: Complexity
/// The PRO value.
public let protection: Protection
/// The ENC value.
public let encumbrance: Encumbrance
/// Does the armor have additional penalties (MOV -1, INI -1)?
public let hasAdditionalPenalties: HasAdditionalPenalties
/// The armor type.
public let armorType: ArmorTypeReference
/// Specify if armor is only available for a specific hit zone.
public let hitZone: HitZone?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ArmorTranslation>
public init(cost: Cost, weight: Weight, complexity: Complexity, protection: Protection, encumbrance: Encumbrance, hasAdditionalPenalties: HasAdditionalPenalties, armorType: ArmorTypeReference, hitZone: HitZone? = nil, src: PublicationRefs, translations: LocaleMap<ArmorTranslation>) {
self.cost = cost
self.weight = weight
self.complexity = complexity
self.protection = protection
self.encumbrance = encumbrance
self.hasAdditionalPenalties = hasAdditionalPenalties
self.armorType = armorType
self.hitZone = hitZone
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case cost = "cost"
case weight = "weight"
case complexity = "complexity"
case protection = "protection"
case encumbrance = "encumbrance"
case hasAdditionalPenalties = "has_additional_penalties"
case armorType = "armor_type"
case hitZone = "hit_zone"
case src = "src"
case translations = "translations"
}
}
public struct ArmorTranslation: EntitySubtype {
/// The name of the item.
public let name: NonEmptyString
/// An auxiliary name or label of the item, if available.
public let secondaryName: NonEmptyString?
/// Note text.
public let note: NonEmptyMarkdown?
/// Special rules text.
public let rules: NonEmptyMarkdown?
/// The armor advantage text.
public let advantage: NonEmptyMarkdown?
/// The armor disadvantage text.
public let disadvantage: NonEmptyMarkdown?
public let errata: Errata?
public init(name: NonEmptyString, secondaryName: NonEmptyString? = nil, note: NonEmptyMarkdown? = nil, rules: NonEmptyMarkdown? = nil, advantage: NonEmptyMarkdown? = nil, disadvantage: NonEmptyMarkdown? = nil, errata: Errata? = nil) {
self.name = name
self.secondaryName = secondaryName
self.note = note
self.rules = rules
self.advantage = advantage
self.disadvantage = disadvantage
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case secondaryName = "secondary_name"
case note = "note"
case rules = "rules"
case advantage = "advantage"
case disadvantage = "disadvantage"
case errata = "errata"
}
}
public struct SecondaryArmor: EntitySubtype {
/// The PRO value.
public let protection: Protection
/// The ENC value.
public let encumbrance: Encumbrance
/// Does the armor have additional penalties (MOV -1, INI -1)?
public let hasAdditionalPenalties: HasAdditionalPenalties
/// The armor type.
public let armorType: ArmorTypeReference
/// Specify if armor is only available for a specific hit zone.
public let hitZone: HitZone?
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<SecondaryArmorTranslation>?
public init(protection: Protection, encumbrance: Encumbrance, hasAdditionalPenalties: HasAdditionalPenalties, armorType: ArmorTypeReference, hitZone: HitZone? = nil, translations: LocaleMap<SecondaryArmorTranslation>? = nil) {
self.protection = protection
self.encumbrance = encumbrance
self.hasAdditionalPenalties = hasAdditionalPenalties
self.armorType = armorType
self.hitZone = hitZone
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case protection = "protection"
case encumbrance = "encumbrance"
case hasAdditionalPenalties = "has_additional_penalties"
case armorType = "armor_type"
case hitZone = "hit_zone"
case translations = "translations"
}
}
public struct SecondaryArmorTranslation: EntitySubtype {
/// The armor advantage text.
public let advantage: NonEmptyMarkdown?
/// The armor disadvantage text.
public let disadvantage: NonEmptyMarkdown?
public init(advantage: NonEmptyMarkdown? = nil, disadvantage: NonEmptyMarkdown? = nil) {
self.advantage = advantage
self.disadvantage = disadvantage
}
}
/// The PRO value.
public typealias Protection = Int
/// The ENC value.
public typealias Encumbrance = Int
/// Does the armor have additional penalties (MOV -1, INI -1)?
public typealias HasAdditionalPenalties = Bool
/// The armor type.
public struct ArmorTypeReference: EntitySubtype {
/// The armor type's identifier.
public let id: Int
public init(id: Int) {
self.id = id
}
}
/// Specify if armor is only available for a specific hit zone.
public enum HitZone: EntitySubtype {
case head(HeadHitZone)
case torso
case arms
case legs
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case head = "head"
case torso = "torso"
case arms = "arms"
case legs = "legs"
}
private enum Discriminator: String, Decodable {
case head = "Head"
case torso = "Torso"
case arms = "Arms"
case legs = "Legs"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .head:
self = .head(try container.decode(HeadHitZone.self, forKey: .head))
case .torso:
self = .torso
case .arms:
self = .arms
case .legs:
self = .legs
}
}
}
public struct HeadHitZone: EntitySubtype {
/// In some cases, multiple armors for the same hit zone can be combined. They're listed at the item that can be combined with others.
public let combinationPossibilities: HeadHitZoneCombinationPossibilities?
public init(combinationPossibilities: HeadHitZoneCombinationPossibilities? = nil) {
self.combinationPossibilities = combinationPossibilities
}
private enum CodingKeys: String, CodingKey {
case combinationPossibilities = "combination_possibilities"
}
}
public struct HeadHitZoneCombinationPossibilities: EntitySubtype {
/// A list of armors that can be combined with this armor.
public let armors: [ArmorReference]
/// The PRO value that is added to the PRO value of the other armor instead of adding the normale PRO value.
public let protection: Int?
public init(armors: [ArmorReference], protection: Int? = nil) {
self.armors = armors
self.protection = protection
}
}
@@ -1,46 +0,0 @@
//
// BandageOrRemedy.swift
// OptolithDatabaseSchema
//
public struct BandageOrRemedy: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
/// The weight in kg.
public let weight: Weight
/// The complexity of crafting the item.
public let complexity: Complexity?
/// The structure points of the item. Use an array if the item consists of multiple components that have individual structure points.
public let structurePoints: StructurePoints?
/// The item can also be used either as an improvised weapon or as an armor, although this is not the primary use case of the item.
public let combatUse: CombatUse?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DefaultItemTranslation>
public init(cost: Cost, weight: Weight, complexity: Complexity? = nil, structurePoints: StructurePoints? = nil, combatUse: CombatUse? = nil, src: PublicationRefs, translations: LocaleMap<DefaultItemTranslation>) {
self.cost = cost
self.weight = weight
self.complexity = complexity
self.structurePoints = structurePoints
self.combatUse = combatUse
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case cost = "cost"
case weight = "weight"
case complexity = "complexity"
case structurePoints = "structure_points"
case combatUse = "combat_use"
case src = "src"
case translations = "translations"
}
}
@@ -1,83 +0,0 @@
//
// Book.swift
// OptolithDatabaseSchema
//
public struct Book: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
/// The weight in kg.
public let weight: Weight
/// The complexity of crafting the item.
public let complexity: Complexity
/// The structure points of the item. Use an array if the item consists of multiple components that have individual structure points.
public let structurePoints: StructurePoints
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<BookTranslation>
public init(cost: Cost, weight: Weight, complexity: Complexity, structurePoints: StructurePoints, src: PublicationRefs, translations: LocaleMap<BookTranslation>) {
self.cost = cost
self.weight = weight
self.complexity = complexity
self.structurePoints = structurePoints
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case cost = "cost"
case weight = "weight"
case complexity = "complexity"
case structurePoints = "structure_points"
case src = "src"
case translations = "translations"
}
}
public struct BookTranslation: EntitySubtype {
/// The name of the item.
public let name: NonEmptyString
/// An auxiliary name or label of the item, if available.
public let secondaryName: NonEmptyString?
/// The language the book is written in.
public let language: NonEmptyString
/// The script that was used for the book.
public let script: NonEmptyString
/// Note text.
public let note: NonEmptyMarkdown?
/// Special rules text.
public let rules: NonEmptyMarkdown?
public let errata: Errata?
public init(name: NonEmptyString, secondaryName: NonEmptyString? = nil, language: NonEmptyString, script: NonEmptyString, note: NonEmptyMarkdown? = nil, rules: NonEmptyMarkdown? = nil, errata: Errata? = nil) {
self.name = name
self.secondaryName = secondaryName
self.language = language
self.script = script
self.note = note
self.rules = rules
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case secondaryName = "secondary_name"
case language = "language"
case script = "script"
case note = "note"
case rules = "rules"
case errata = "errata"
}
}
@@ -1,51 +0,0 @@
//
// CeremonialItem.swift
// OptolithDatabaseSchema
//
public struct CeremonialItem: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
/// The weight in kg.
public let weight: Weight
/// The complexity of crafting the item.
public let complexity: Complexity?
/// The structure points of the item. Use an array if the item consists of multiple components that have individual structure points.
public let structurePoints: StructurePoints
/// The deity associated with the equipment item.
public let associatedTradition: BlessedTraditionReference
/// The item can also be used either as an improvised weapon or as an armor, although this is not the primary use case of the item.
public let combatUse: CombatUse?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DefaultItemTranslation>
public init(cost: Cost, weight: Weight, complexity: Complexity? = nil, structurePoints: StructurePoints, associatedTradition: BlessedTraditionReference, combatUse: CombatUse? = nil, src: PublicationRefs, translations: LocaleMap<DefaultItemTranslation>) {
self.cost = cost
self.weight = weight
self.complexity = complexity
self.structurePoints = structurePoints
self.associatedTradition = associatedTradition
self.combatUse = combatUse
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case cost = "cost"
case weight = "weight"
case complexity = "complexity"
case structurePoints = "structure_points"
case associatedTradition = "associated_tradition"
case combatUse = "combat_use"
case src = "src"
case translations = "translations"
}
}
@@ -1,6 +0,0 @@
//
// Clothes.swift
// OptolithDatabaseSchema
//
public typealias Clothes = DefaultItem
@@ -1,6 +0,0 @@
//
// Container.swift
// OptolithDatabaseSchema
//
public typealias Container = DefaultItem
@@ -1,83 +0,0 @@
//
// Elixir.swift
// OptolithDatabaseSchema
//
public struct Elixir: LocalizableEntity {
/// The elixir's identifier. An unique, increasing integer.
public let id: Int
/// The cost per ingredient level in silverthalers.
public let costPerIngredientLevel: Double
/// The laboratory level needed to brew the elixir.
public let laboratory: LaboratoryLevel
/// The brewing difficulty, which represents the challenge of creating an elixir.
public let brewingDifficulty: Int
/// AP value and prerequisites of the elixir recipes trade secret.
public let tradeSecret: RecipeTradeSecret
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<ElixirTranslation>
public init(id: Int, costPerIngredientLevel: Double, laboratory: LaboratoryLevel, brewingDifficulty: Int, tradeSecret: RecipeTradeSecret, src: PublicationRefs, translations: LocaleMap<ElixirTranslation>) {
self.id = id
self.costPerIngredientLevel = costPerIngredientLevel
self.laboratory = laboratory
self.brewingDifficulty = brewingDifficulty
self.tradeSecret = tradeSecret
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case id = "id"
case costPerIngredientLevel = "cost_per_ingredient_level"
case laboratory = "laboratory"
case brewingDifficulty = "brewing_difficulty"
case tradeSecret = "trade_secret"
case src = "src"
case translations = "translations"
}
}
public struct ElixirTranslation: EntitySubtype {
/// The name of the elixir.
public let name: NonEmptyString
/// A list of alternative names.
public let alternativeNames: [AlternativeName]?
/// A list of typical ingredients.
public let typicalIngredients: [NonEmptyString]
/// Prerequsites for the brewing process, if any.
public let brewingProcessPrerequisites: NonEmptyMarkdown?
/// The list of effects for each quality level. The first element represents QL 1, the second element QL 2, and so on.
public let qualityLevels: [NonEmptyMarkdown]
public let errata: Errata?
public init(name: NonEmptyString, alternativeNames: [AlternativeName]? = nil, typicalIngredients: [NonEmptyString], brewingProcessPrerequisites: NonEmptyMarkdown? = nil, qualityLevels: [NonEmptyMarkdown], errata: Errata? = nil) {
self.name = name
self.alternativeNames = alternativeNames
self.typicalIngredients = typicalIngredients
self.brewingProcessPrerequisites = brewingProcessPrerequisites
self.qualityLevels = qualityLevels
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case alternativeNames = "alternative_names"
case typicalIngredients = "typical_ingredients"
case brewingProcessPrerequisites = "brewing_process_prerequisites"
case qualityLevels = "quality_levels"
case errata = "errata"
}
}
@@ -1,36 +0,0 @@
//
// EquipmentOfBlessedOnes.swift
// OptolithDatabaseSchema
//
public struct EquipmentOfBlessedOnes: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
/// The structure points of the item. Use an array if the item consists of multiple components that have individual structure points.
public let structurePoints: StructurePoints
/// The deity associated with the equipment item.
public let associatedTradition: [BlessedTraditionReference]
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DefaultItemTranslation>
public init(cost: Cost, structurePoints: StructurePoints, associatedTradition: [BlessedTraditionReference], src: PublicationRefs, translations: LocaleMap<DefaultItemTranslation>) {
self.cost = cost
self.structurePoints = structurePoints
self.associatedTradition = associatedTradition
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case cost = "cost"
case structurePoints = "structure_points"
case associatedTradition = "associated_tradition"
case src = "src"
case translations = "translations"
}
}
@@ -1,57 +0,0 @@
//
// GemOrPreciousStone.swift
// OptolithDatabaseSchema
//
public struct GemOrPreciousStone: LocalizableEntity {
/// The cost in silverthalers per 10 karat.
public let cost: Cost
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<GemOrPreciousStoneTranslation>
public init(cost: Cost, src: PublicationRefs, translations: LocaleMap<GemOrPreciousStoneTranslation>) {
self.cost = cost
self.src = src
self.translations = translations
}
}
public struct GemOrPreciousStoneTranslation: EntitySubtype {
/// The name of the item.
public let name: NonEmptyString
/// An auxiliary name or label of the item, if available.
public let secondaryName: NonEmptyString?
/// The color of the gem or stone.
public let color: NonEmptyString
/// Note text.
public let note: NonEmptyMarkdown?
/// Special rules text.
public let rules: NonEmptyMarkdown?
public let errata: Errata?
public init(name: NonEmptyString, secondaryName: NonEmptyString? = nil, color: NonEmptyString, note: NonEmptyMarkdown? = nil, rules: NonEmptyMarkdown? = nil, errata: Errata? = nil) {
self.name = name
self.secondaryName = secondaryName
self.color = color
self.note = note
self.rules = rules
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case secondaryName = "secondary_name"
case color = "color"
case note = "note"
case rules = "rules"
case errata = "errata"
}
}
@@ -1,95 +0,0 @@
//
// IlluminationLightSource.swift
// OptolithDatabaseSchema
//
public struct IlluminationLightSource: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
/// The weight in kg.
public let weight: Weight
/// The complexity of crafting the item.
public let complexity: Complexity?
/// The structure points of the item. Use an array if the item consists of multiple components that have individual structure points.
public let structurePoints: StructurePoints
/// The burning time is the time how long the light source can be lit. After that time you have to use a new light source.
public let burningTime: BurningTime
/// The item can also be used either as an improvised weapon or as an armor, although this is not the primary use case of the item.
public let combatUse: CombatUse?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DefaultItemTranslation>
public init(cost: Cost, weight: Weight, complexity: Complexity? = nil, structurePoints: StructurePoints, burningTime: BurningTime, combatUse: CombatUse? = nil, src: PublicationRefs, translations: LocaleMap<DefaultItemTranslation>) {
self.cost = cost
self.weight = weight
self.complexity = complexity
self.structurePoints = structurePoints
self.burningTime = burningTime
self.combatUse = combatUse
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case cost = "cost"
case weight = "weight"
case complexity = "complexity"
case structurePoints = "structure_points"
case burningTime = "burning_time"
case combatUse = "combat_use"
case src = "src"
case translations = "translations"
}
}
public enum BurningTime: EntitySubtype {
case unlimited
case limited(LimitedBurningTime)
private enum CodingKeys: String, CodingKey {
case tag = "tag"
case unlimited = "unlimited"
case limited = "limited"
}
private enum Discriminator: String, Decodable {
case unlimited = "Unlimited"
case limited = "Limited"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let tag = try container.decode(Discriminator.self, forKey: .tag)
switch tag {
case .unlimited:
self = .unlimited
case .limited:
self = .limited(try container.decode(LimitedBurningTime.self, forKey: .limited))
}
}
}
public struct LimitedBurningTime: EntitySubtype {
/// The (unitless) time value.
public let value: Double
/// The time unit.
public let unit: LimitedBurningTimeUnit
public init(value: Double, unit: LimitedBurningTimeUnit) {
self.value = value
self.unit = unit
}
}
public enum LimitedBurningTimeUnit: String, EntitySubtype {
case hours = "Hours"
}
@@ -1,6 +0,0 @@
//
// IlluminationRefillsOrSupplies.swift
// OptolithDatabaseSchema
//
public typealias IlluminationRefillsOrSupplies = DefaultItem
@@ -1,88 +0,0 @@
//
// Jewelry.swift
// OptolithDatabaseSchema
//
public struct Jewelry: LocalizableEntity {
/// The cost in silverthalers.
public let cost: JewelryMaterialDifference<Cost>
/// The weight in kg.
public let weight: JewelryMaterialDifference<Weight>
/// The complexity of crafting the item.
public let complexity: Complexity
/// The structure points of the item. Use an array if the item consists of multiple components that have individual structure points.
public let structurePoints: StructurePoints
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<JewelryTranslation>
public init(cost: JewelryMaterialDifference<Cost>, weight: JewelryMaterialDifference<Weight>, complexity: Complexity, structurePoints: StructurePoints, src: PublicationRefs, translations: LocaleMap<JewelryTranslation>) {
self.cost = cost
self.weight = weight
self.complexity = complexity
self.structurePoints = structurePoints
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case cost = "cost"
case weight = "weight"
case complexity = "complexity"
case structurePoints = "structure_points"
case src = "src"
case translations = "translations"
}
}
/// Jewelry has different cost based on the material.
public struct JewelryMaterialDifference<T: EntitySubtype>: EntitySubtype {
public let bronze: T
public let silver: T
public let gold: T
public init(bronze: T, silver: T, gold: T) {
self.bronze = bronze
self.silver = silver
self.gold = gold
}
}
public struct JewelryTranslation: EntitySubtype {
/// The name of the item.
public let name: NonEmptyString
/// An auxiliary name or label of the item, if available.
public let secondaryName: NonEmptyString?
/// Note text.
public let note: NonEmptyMarkdown?
/// Special rules text.
public let rules: NonEmptyMarkdown?
public let errata: Errata?
public init(name: NonEmptyString, secondaryName: NonEmptyString? = nil, note: NonEmptyMarkdown? = nil, rules: NonEmptyMarkdown? = nil, errata: Errata? = nil) {
self.name = name
self.secondaryName = secondaryName
self.note = note
self.rules = rules
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case secondaryName = "secondary_name"
case note = "note"
case rules = "rules"
case errata = "errata"
}
}
@@ -1,6 +0,0 @@
//
// Liebesspielzeug.swift
// OptolithDatabaseSchema
//
public typealias Liebesspielzeug = DefaultItem
@@ -1,46 +0,0 @@
//
// LuxuryGood.swift
// OptolithDatabaseSchema
//
public struct LuxuryGood: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
/// The weight in kg.
public let weight: Weight
/// The complexity of crafting the item.
public let complexity: Complexity?
/// The structure points of the item. Use an array if the item consists of multiple components that have individual structure points.
public let structurePoints: StructurePoints?
/// The item can also be used either as an improvised weapon or as an armor, although this is not the primary use case of the item.
public let combatUse: CombatUse?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DefaultItemTranslation>
public init(cost: Cost, weight: Weight, complexity: Complexity? = nil, structurePoints: StructurePoints? = nil, combatUse: CombatUse? = nil, src: PublicationRefs, translations: LocaleMap<DefaultItemTranslation>) {
self.cost = cost
self.weight = weight
self.complexity = complexity
self.structurePoints = structurePoints
self.combatUse = combatUse
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case cost = "cost"
case weight = "weight"
case complexity = "complexity"
case structurePoints = "structure_points"
case combatUse = "combat_use"
case src = "src"
case translations = "translations"
}
}
@@ -1,52 +0,0 @@
//
// MagicalArtifact.swift
// OptolithDatabaseSchema
//
public struct MagicalArtifact: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<MagicalArtifactTranslation>
public init(cost: Cost, src: PublicationRefs, translations: LocaleMap<MagicalArtifactTranslation>) {
self.cost = cost
self.src = src
self.translations = translations
}
}
public struct MagicalArtifactTranslation: EntitySubtype {
/// The name of the item.
public let name: NonEmptyString
/// An auxiliary name or label of the item, if available.
public let secondaryName: NonEmptyString?
/// Note text.
public let note: NonEmptyMarkdown?
/// Special rules text.
public let rules: NonEmptyMarkdown?
public let errata: Errata?
public init(name: NonEmptyString, secondaryName: NonEmptyString? = nil, note: NonEmptyMarkdown? = nil, rules: NonEmptyMarkdown? = nil, errata: Errata? = nil) {
self.name = name
self.secondaryName = secondaryName
self.note = note
self.rules = rules
self.errata = errata
}
private enum CodingKeys: String, CodingKey {
case name = "name"
case secondaryName = "secondary_name"
case note = "note"
case rules = "rules"
case errata = "errata"
}
}
@@ -1,41 +0,0 @@
//
// MusicalInstrument.swift
// OptolithDatabaseSchema
//
public struct MusicalInstrument: LocalizableEntity {
/// The cost in silverthalers.
public let cost: Cost
/// The weight in kg.
public let weight: Weight
/// The complexity of crafting the item.
public let complexity: Complexity?
/// The item can also be used either as an improvised weapon or as an armor, although this is not the primary use case of the item.
public let combatUse: CombatUse?
public let src: PublicationRefs
/// All translations for the entry, identified by IETF language tag (BCP47).
public let translations: LocaleMap<DefaultItemTranslation>
public init(cost: Cost, weight: Weight, complexity: Complexity? = nil, combatUse: CombatUse? = nil, src: PublicationRefs, translations: LocaleMap<DefaultItemTranslation>) {
self.cost = cost
self.weight = weight
self.complexity = complexity
self.combatUse = combatUse
self.src = src
self.translations = translations
}
private enum CodingKeys: String, CodingKey {
case cost = "cost"
case weight = "weight"
case complexity = "complexity"
case combatUse = "combat_use"
case src = "src"
case translations = "translations"
}
}
@@ -1,6 +0,0 @@
//
// OrienteeringAid.swift
// OptolithDatabaseSchema
//
public typealias OrienteeringAid = DefaultItem

Some files were not shown because too many files have changed in this diff Show More