Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9718f7d341 | ||
|
|
0c8f3518ea | ||
|
|
3b3ae6f3a6 | ||
|
|
028e438909 |
+45
-10
@@ -17,7 +17,9 @@ import type {
|
||||
ImprovementCost,
|
||||
Poison,
|
||||
PrerequisiteForLevel,
|
||||
Property_ID,
|
||||
RequirableSelectOptionIdentifier,
|
||||
Ritual_ID,
|
||||
SelectOptionCategory,
|
||||
SelectOptions,
|
||||
SelectOptionsAdventurePointsValue,
|
||||
@@ -28,6 +30,7 @@ import type {
|
||||
SkillSelectOptionCategoryPrerequisite,
|
||||
SpecificFromSkillSelectOptionCategoryCategory,
|
||||
SpecificTargetCategory,
|
||||
Spell_ID,
|
||||
TargetCategory,
|
||||
TradeSecretAdventurePointsValue,
|
||||
} from "../../gen/types.js"
|
||||
@@ -67,15 +70,17 @@ const wrapPlainApValue = (
|
||||
): TradeSecretAdventurePointsValue | undefined =>
|
||||
apValue === undefined ? undefined : Case("Fixed", apValue)
|
||||
|
||||
const matchesSpecificSkillishIdList = (
|
||||
id: string,
|
||||
config: SpecificFromSkillSelectOptionCategoryCategory<string>,
|
||||
const matchesSpecificSkillishIdList = <Ref>(
|
||||
config: SpecificFromSkillSelectOptionCategoryCategory<Ref>,
|
||||
matches: (required: Ref) => boolean,
|
||||
): boolean => {
|
||||
const isInList = config.list.some(matches)
|
||||
|
||||
switch (config.operation.kind) {
|
||||
case "Intersection":
|
||||
return config.list.includes(id)
|
||||
return isInList
|
||||
case "Difference":
|
||||
return !config.list.includes(id)
|
||||
return !isInList
|
||||
default:
|
||||
return assertExhaustive(config.operation)
|
||||
}
|
||||
@@ -233,14 +238,35 @@ const getDefaultSkillishFilter = <E extends SkillishEntityName>(
|
||||
const { specific } = category
|
||||
return specific === undefined
|
||||
? undefined
|
||||
: ({ id }) => matchesSpecificSkillishIdList(id, specific)
|
||||
: ({ id }) => matchesSpecificSkillishIdList(specific, required => required === id)
|
||||
}
|
||||
|
||||
const getDerivedSkillishSelectOptions = <E extends SkillishEntityName>(
|
||||
const getSpellworkFilter = <E extends "Spell" | "Ritual">(
|
||||
category: GenericSkillsSelectOptionCategoryCategory<
|
||||
Case<"Single", Spell_ID | Ritual_ID> | Case<"Property", Property_ID>
|
||||
>,
|
||||
): ((instance: { id: string; content: Entity<TSONDBTypes, E> }) => boolean) | undefined => {
|
||||
const { specific } = category
|
||||
return specific === undefined
|
||||
? undefined
|
||||
: ({ id, content: { property } }) =>
|
||||
matchesSpecificSkillishIdList(specific, required => {
|
||||
switch (required.kind) {
|
||||
case "Single":
|
||||
return required.Single === id
|
||||
case "Property":
|
||||
return property === required.Property
|
||||
default:
|
||||
return assertExhaustive(required)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getDerivedSkillishSelectOptions = <E extends SkillishEntityName, ID>(
|
||||
database: TSONDB<TSONDBTypes>,
|
||||
entryId: ActivatableIdentifier,
|
||||
entity: E,
|
||||
category: GenericSkillsSelectOptionCategoryCategory<string> & {
|
||||
category: GenericSkillsSelectOptionCategoryCategory<ID> & {
|
||||
skill_applications?: SkillApplicationOrUse[] | undefined
|
||||
skill_uses?: SkillApplicationOrUse[] | undefined
|
||||
},
|
||||
@@ -248,7 +274,7 @@ const getDerivedSkillishSelectOptions = <E extends SkillishEntityName>(
|
||||
bindingCost?: SelectOptionsBindingCostValue<SkillishIdentifier | CombatTechniqueIdentifier>
|
||||
ap_value?: SelectOptionsAdventurePointsValue<SkillishIdentifier | CombatTechniqueIdentifier>
|
||||
},
|
||||
filter = getDefaultSkillishFilter<E>(category),
|
||||
filter: ((instance: { id: string; content: Entity<TSONDBTypes, E> }) => boolean) | undefined,
|
||||
) => {
|
||||
const { prerequisites } = category
|
||||
const { bindingCost, ap_value } = options
|
||||
@@ -928,7 +954,10 @@ const getDerivedSelectOptions = (
|
||||
|
||||
const matchesIdRequirement =
|
||||
category.Skills.specific === undefined ||
|
||||
matchesSpecificSkillishIdList(id, category.Skills.specific)
|
||||
matchesSpecificSkillishIdList(
|
||||
category.Skills.specific,
|
||||
required => required === id,
|
||||
)
|
||||
|
||||
return matchesGroupRequirement && matchesIdRequirement
|
||||
},
|
||||
@@ -940,6 +969,7 @@ const getDerivedSelectOptions = (
|
||||
"Spell",
|
||||
category.Spells,
|
||||
selectOptionCategory.Skills,
|
||||
getSpellworkFilter(category.Spells),
|
||||
)
|
||||
case "Rituals":
|
||||
return getDerivedSkillishSelectOptions(
|
||||
@@ -948,6 +978,7 @@ const getDerivedSelectOptions = (
|
||||
"Ritual",
|
||||
category.Rituals,
|
||||
selectOptionCategory.Skills,
|
||||
getSpellworkFilter(category.Rituals),
|
||||
)
|
||||
case "LiturgicalChants":
|
||||
return getDerivedSkillishSelectOptions(
|
||||
@@ -956,6 +987,7 @@ const getDerivedSelectOptions = (
|
||||
"LiturgicalChant",
|
||||
category.LiturgicalChants,
|
||||
selectOptionCategory.Skills,
|
||||
getDefaultSkillishFilter(category.LiturgicalChants),
|
||||
)
|
||||
case "Ceremonies":
|
||||
return getDerivedSkillishSelectOptions(
|
||||
@@ -964,6 +996,7 @@ const getDerivedSelectOptions = (
|
||||
"Ceremony",
|
||||
category.Ceremonies,
|
||||
selectOptionCategory.Skills,
|
||||
getDefaultSkillishFilter(category.Ceremonies),
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(category)
|
||||
@@ -980,6 +1013,7 @@ const getDerivedSelectOptions = (
|
||||
"CloseCombatTechnique",
|
||||
category.CloseCombatTechniques,
|
||||
selectOptionCategory.CombatTechniques,
|
||||
getDefaultSkillishFilter(category.CloseCombatTechniques),
|
||||
)
|
||||
case "RangedCombatTechniques":
|
||||
return getDerivedSkillishSelectOptions(
|
||||
@@ -988,6 +1022,7 @@ const getDerivedSelectOptions = (
|
||||
"RangedCombatTechnique",
|
||||
category.RangedCombatTechniques,
|
||||
selectOptionCategory.CombatTechniques,
|
||||
getDefaultSkillishFilter(category.RangedCombatTechniques),
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(category)
|
||||
|
||||
@@ -1428,6 +1428,7 @@ export const Locale = DB.Entity(import.meta.url, {
|
||||
"Aspect": null,
|
||||
"As chosen": null,
|
||||
"Passive": null,
|
||||
"Active": null,
|
||||
"Basic Maneuver": null,
|
||||
"Special Maneuver": null,
|
||||
"Volume": null,
|
||||
|
||||
@@ -15,6 +15,12 @@ export const name_in_library = DB.Optional({
|
||||
type: DB.String({ minLength: 1 }),
|
||||
})
|
||||
|
||||
export const additionalName = DB.Optional({
|
||||
comment:
|
||||
"A part of the name that is appended in parenthesis. This can be used to specify the group of people that typically uses this entry (e.g. the name of the witch circle for a magic style for witches).\n\nIf `name_in_library` is specified, this will be ignored for places where the `name_in_library` is used.",
|
||||
type: DB.String({ minLength: 1 }),
|
||||
})
|
||||
|
||||
export const levels = DB.Optional({
|
||||
comment: "Number of available levels.",
|
||||
type: DB.Integer({ minimum: 2 }),
|
||||
|
||||
@@ -21,11 +21,25 @@ const CombatSpecialAbilityUsageType = DB.Enum(import.meta.url, {
|
||||
}),
|
||||
})
|
||||
|
||||
export const usage_type = DB.Required({
|
||||
const CombatStyleUsageType = DB.Enum(import.meta.url, {
|
||||
name: "CombatSpecialAbilityTypeUsageType",
|
||||
comment: "The definition of how the combat special ability style can be used in combat.",
|
||||
values: () => ({
|
||||
Passive: DB.EnumCase({ type: null }),
|
||||
Active: DB.EnumCase({ type: null }),
|
||||
}),
|
||||
})
|
||||
|
||||
export const special_ability_usage_type = DB.Required({
|
||||
comment: "The definition of how the combat special ability can be used in combat.",
|
||||
type: DB.IncludeIdentifier(CombatSpecialAbilityUsageType),
|
||||
})
|
||||
|
||||
export const style_usage_type = DB.Required({
|
||||
comment: "The definition of how the combat style can be used in combat.",
|
||||
type: DB.IncludeIdentifier(CombatStyleUsageType),
|
||||
})
|
||||
|
||||
const CombatSpecialAbilityType = DB.Enum(import.meta.url, {
|
||||
name: "CombatSpecialAbilityType",
|
||||
comment:
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
SkillIdentifier,
|
||||
SpellIdentifier,
|
||||
TargetCategoryIdentifier,
|
||||
PropertyIdentifier,
|
||||
} from "./_Identifier.js"
|
||||
import {
|
||||
ActivatableIdentifier,
|
||||
@@ -211,16 +212,34 @@ const SkillsSelectOptionCategory = DB.TypeAlias(import.meta.url, {
|
||||
}),
|
||||
})
|
||||
|
||||
const SpellFilter = DB.Enum(import.meta.url, {
|
||||
name: "SpellFilter",
|
||||
values: () => ({
|
||||
Single: DB.EnumCase({ type: SpellIdentifier() }),
|
||||
Property: DB.EnumCase({ type: PropertyIdentifier() }),
|
||||
}),
|
||||
})
|
||||
|
||||
const RitualFilter = DB.Enum(import.meta.url, {
|
||||
name: "RitualFilter",
|
||||
values: () => ({
|
||||
Single: DB.EnumCase({ type: RitualIdentifier() }),
|
||||
Property: DB.EnumCase({ type: PropertyIdentifier() }),
|
||||
}),
|
||||
})
|
||||
|
||||
const SkillsSelectOptionCategoryCategory = DB.Enum(import.meta.url, {
|
||||
name: "SkillsSelectOptionCategoryCategory",
|
||||
values: () => ({
|
||||
Skills: DB.EnumCase({ type: DB.IncludeIdentifier(SkillSelectOptionCategoryCategory) }),
|
||||
Spells: DB.EnumCase({
|
||||
type: DB.GenIncludeIdentifier(GenericSkillsSelectOptionCategoryCategory, [SpellIdentifier()]),
|
||||
type: DB.GenIncludeIdentifier(GenericSkillsSelectOptionCategoryCategory, [
|
||||
DB.IncludeIdentifierType(SpellFilter),
|
||||
]),
|
||||
}),
|
||||
Rituals: DB.EnumCase({
|
||||
type: DB.GenIncludeIdentifier(GenericSkillsSelectOptionCategoryCategory, [
|
||||
RitualIdentifier(),
|
||||
DB.IncludeIdentifierType(RitualFilter),
|
||||
]),
|
||||
}),
|
||||
LiturgicalChants: DB.EnumCase({
|
||||
|
||||
@@ -238,10 +238,6 @@ export const BannzeichenOption = DB.Entity(import.meta.url, {
|
||||
The surrounding parenthesis will/should not be included, they will/should be generated.`,
|
||||
type: DB.String({ minLength: 1 }),
|
||||
}),
|
||||
native_name: DB.Required({
|
||||
comment: "The native name of the Bannzeichen option.",
|
||||
type: DB.String({ minLength: 1 }),
|
||||
}),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import * as DB from "tsondb/schema/dsl"
|
||||
import { PropertyIdentifier } from "../../_Identifier.js"
|
||||
import { DisplayOption } from "../DisplayOption.js"
|
||||
|
||||
export const PropertyPrerequisite = DB.TypeAlias(import.meta.url, {
|
||||
name: "PropertyPrerequisite",
|
||||
comment: "Requires a specific property or one of a specific set of properties.",
|
||||
type: () =>
|
||||
DB.Object({
|
||||
id: DB.Required({
|
||||
comment: "The property�s identifier.",
|
||||
type: PropertyIdentifier(),
|
||||
}),
|
||||
display_option: DB.Optional({
|
||||
type: DB.IncludeIdentifier(DisplayOption),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as DB from "tsondb/schema/dsl"
|
||||
import { input, levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
|
||||
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
|
||||
import { combat_techniques, penalty, usage_type } from "../_ActivatableCombat.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
|
||||
import { combat_techniques, penalty, special_ability_usage_type } from "../_ActivatableCombat.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.js"
|
||||
import { explicit_select_options, select_options } from "../_ActivatableSelectOptions.js"
|
||||
import { skill_applications, skill_uses } from "../_ActivatableSkillApplicationsAndUses.js"
|
||||
import { GeneralPrerequisites } from "../_Prerequisite.js"
|
||||
@@ -18,7 +18,7 @@ export const AdvancedCombatSpecialAbility = DB.Entity(import.meta.url, {
|
||||
DB.Object({
|
||||
levels,
|
||||
nameBuilderRules,
|
||||
usage_type,
|
||||
usage_type: special_ability_usage_type,
|
||||
select_options,
|
||||
explicit_select_options,
|
||||
skill_applications,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as DB from "tsondb/schema/dsl"
|
||||
import { levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
|
||||
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
|
||||
import { combat_techniques, usage_type } from "../_ActivatableCombat.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
|
||||
import { combat_techniques, special_ability_usage_type } from "../_ActivatableCombat.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.js"
|
||||
import { explicit_select_options, select_options } from "../_ActivatableSelectOptions.js"
|
||||
import { GeneralPrerequisites } from "../_Prerequisite.js"
|
||||
import { NestedTranslationMap } from "../Locale.js"
|
||||
@@ -16,7 +16,7 @@ export const BrawlingSpecialAbility = DB.Entity(import.meta.url, {
|
||||
DB.Object({
|
||||
levels,
|
||||
nameBuilderRules,
|
||||
usage_type,
|
||||
usage_type: special_ability_usage_type,
|
||||
select_options,
|
||||
explicit_select_options,
|
||||
maximum,
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import * as DB from "tsondb/schema/dsl"
|
||||
import { input, levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
|
||||
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
|
||||
import { combat_techniques, penalty, penalty_l10n, usage_type } from "../_ActivatableCombat.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
|
||||
import {
|
||||
combat_techniques,
|
||||
penalty,
|
||||
penalty_l10n,
|
||||
special_ability_usage_type,
|
||||
} from "../_ActivatableCombat.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.js"
|
||||
import { explicit_select_options, select_options } from "../_ActivatableSelectOptions.js"
|
||||
import { skill_applications, skill_uses } from "../_ActivatableSkillApplicationsAndUses.js"
|
||||
import { GeneralPrerequisites } from "../_Prerequisite.js"
|
||||
@@ -17,7 +22,7 @@ export const CombatSpecialAbility = DB.Entity(import.meta.url, {
|
||||
DB.Object({
|
||||
levels,
|
||||
nameBuilderRules,
|
||||
usage_type,
|
||||
usage_type: special_ability_usage_type,
|
||||
select_options,
|
||||
explicit_select_options,
|
||||
skill_applications,
|
||||
|
||||
@@ -2,8 +2,8 @@ import * as DB from "tsondb/schema/dsl"
|
||||
import { levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
|
||||
import { advanced } from "../_ActivatableAdvanced.js"
|
||||
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
|
||||
import { combat_techniques, penalty, type, usage_type } from "../_ActivatableCombat.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
|
||||
import { combat_techniques, penalty, type, style_usage_type } from "../_ActivatableCombat.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.js"
|
||||
import { explicit_select_options, select_options } from "../_ActivatableSelectOptions.js"
|
||||
import { skill_applications, skill_uses } from "../_ActivatableSkillApplicationsAndUses.js"
|
||||
import { AdvancedCombatSpecialAbilityIdentifier } from "../_Identifier.js"
|
||||
@@ -19,7 +19,7 @@ export const CombatStyleSpecialAbility = DB.Entity(import.meta.url, {
|
||||
DB.Object({
|
||||
levels,
|
||||
nameBuilderRules,
|
||||
usage_type,
|
||||
usage_type: style_usage_type,
|
||||
type,
|
||||
select_options,
|
||||
explicit_select_options,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as DB from "tsondb/schema/dsl"
|
||||
import { levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
|
||||
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
|
||||
import { combat_techniques, usage_type } from "../_ActivatableCombat.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
|
||||
import { combat_techniques, special_ability_usage_type } from "../_ActivatableCombat.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.js"
|
||||
import { explicit_select_options, select_options } from "../_ActivatableSelectOptions.js"
|
||||
import { GeneralPrerequisites } from "../_Prerequisite.js"
|
||||
import { NestedTranslationMap } from "../Locale.js"
|
||||
@@ -16,7 +16,7 @@ export const CommandSpecialAbility = DB.Entity(import.meta.url, {
|
||||
DB.Object({
|
||||
levels,
|
||||
nameBuilderRules,
|
||||
usage_type,
|
||||
usage_type: special_ability_usage_type,
|
||||
select_options,
|
||||
explicit_select_options,
|
||||
maximum,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as DB from "tsondb/schema/dsl"
|
||||
import { levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
|
||||
import { additionalName, levels, maximum, name, name_in_library, rules } from "../_Activatable.js"
|
||||
import { advanced } from "../_ActivatableAdvanced.js"
|
||||
import { ap_value, ap_value_append, ap_value_l10n } from "../_ActivatableAdventurePointsValue.js"
|
||||
import { activatableDisplayNameCustomizer, nameBuilderRules } from "../_ActivatableNames.ts"
|
||||
@@ -34,6 +34,7 @@ export const MagicStyleSpecialAbility = DB.Entity(import.meta.url, {
|
||||
"MagicStyleSpecialAbility",
|
||||
DB.Object({
|
||||
name,
|
||||
additionalName,
|
||||
name_in_library,
|
||||
rules,
|
||||
ap_value_append,
|
||||
|
||||
Reference in New Issue
Block a user