feat: print prerequisites
This commit is contained in:
@@ -0,0 +1,506 @@
|
||||
import { mapObject } from "@optolith/helpers/object"
|
||||
import { romanize } from "@optolith/helpers/roman"
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { ResolvedSelectOption } from "optolith-database-schema/cache/activatableSelectOptions"
|
||||
import {
|
||||
ActivatableIdentifier,
|
||||
SelectOptionIdentifier,
|
||||
} from "optolith-database-schema/types/_IdentifierGroup"
|
||||
import { LocaleMap } from "optolith-database-schema/types/_LocaleMap"
|
||||
import { GetById } from "../../helpers/getTypes.js"
|
||||
import {
|
||||
AdvantageIdentifier,
|
||||
DisadvantageIdentifier,
|
||||
KarmaSpecialAbilityIdentifier,
|
||||
} from "../../helpers/identifiers.js"
|
||||
import { LocaleEnvironment } from "../../helpers/locale.js"
|
||||
import { MISSING_VALUE } from "./unknown.js"
|
||||
|
||||
/**
|
||||
* Returns the full name of the activatable entry as well as its components.
|
||||
*/
|
||||
export type ActivatableNameComponents = {
|
||||
full: ActivatableNameChunk
|
||||
fullWithoutLevel:
|
||||
| ActivatableNameChunk
|
||||
| [ActivatableNameChunk, ActivatableNameChunk]
|
||||
base: ActivatableNameChunk
|
||||
options: (
|
||||
| ActivatableNameChunk
|
||||
| [ActivatableNameChunk, ActivatableNameChunk]
|
||||
)[]
|
||||
}
|
||||
|
||||
/**
|
||||
* A part of the name, which can be a locale map, a string for all locales or a
|
||||
* function returning a string.
|
||||
*/
|
||||
export type ActivatableNameChunk =
|
||||
| LocaleMap<string>
|
||||
| string
|
||||
| ((locale: LocaleEnvironment) => string)
|
||||
|
||||
const combineChunks = (
|
||||
a: ActivatableNameChunk,
|
||||
b: ActivatableNameChunk,
|
||||
join: (a: string, b: string) => string,
|
||||
): ActivatableNameChunk => {
|
||||
if (typeof a === "string") {
|
||||
if (typeof b === "string") {
|
||||
return join(a, b)
|
||||
} else if (typeof b === "function") {
|
||||
return fs => join(a, b(fs))
|
||||
} else if (typeof b === "object") {
|
||||
return mapObject(b, bValue => join(a, bValue))
|
||||
}
|
||||
return b
|
||||
} else if (typeof a === "function") {
|
||||
if (typeof b === "string") {
|
||||
return fs => join(a(fs), b)
|
||||
} else if (typeof b === "function") {
|
||||
return fs => join(a(fs), b(fs))
|
||||
} else if (typeof b === "object") {
|
||||
return fs => join(a(fs), fs.translateMap(b) ?? MISSING_VALUE)
|
||||
}
|
||||
return b
|
||||
} else if (typeof a === "object") {
|
||||
if (typeof b === "string") {
|
||||
return mapObject(a, aValue => join(aValue, b))
|
||||
} else if (typeof b === "function") {
|
||||
return fs => join(fs.translateMap(a) ?? MISSING_VALUE, b(fs))
|
||||
} else if (typeof b === "object") {
|
||||
const ret: LocaleMap<string> = {}
|
||||
for (const key of new Set([...Object.keys(a), ...Object.keys(b)])) {
|
||||
ret[key] = join(a[key] ?? MISSING_VALUE, b[key] ?? MISSING_VALUE)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
const mapChunk = (
|
||||
chunk: ActivatableNameChunk,
|
||||
map: (str: string) => string,
|
||||
): ActivatableNameChunk => {
|
||||
if (typeof chunk === "string") {
|
||||
return map(chunk)
|
||||
} else if (typeof chunk === "function") {
|
||||
return fs => map(chunk(fs))
|
||||
} else if (typeof chunk === "object") {
|
||||
return mapObject(chunk, chunkValue => map(chunkValue))
|
||||
}
|
||||
return chunk
|
||||
}
|
||||
|
||||
const zipChunks = (
|
||||
chunks: (
|
||||
| ActivatableNameChunk
|
||||
| [ActivatableNameChunk, ActivatableNameChunk]
|
||||
)[],
|
||||
): ActivatableNameChunk => {
|
||||
const withNormalizedPairs = chunks.map(chunk => {
|
||||
if (Array.isArray(chunk)) {
|
||||
return combineChunks(chunk[0], chunk[1], (a, b) => `${a}: ${b}`)
|
||||
}
|
||||
|
||||
return chunk
|
||||
})
|
||||
|
||||
return withNormalizedPairs.reduce(
|
||||
(acc, chunk) =>
|
||||
acc === "" ? chunk : combineChunks(acc, chunk, (a, b) => `${a}, ${b}`),
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
const combineBaseName = (
|
||||
base: ActivatableNameChunk,
|
||||
level: number | undefined,
|
||||
options: ActivatableNameComponents["options"],
|
||||
config: {
|
||||
levelPlacement?: "before" | "after"
|
||||
useParenthesis?: boolean
|
||||
} = {},
|
||||
): Pick<ActivatableNameComponents, "full" | "fullWithoutLevel"> => {
|
||||
const { levelPlacement = "after", useParenthesis = true } = config
|
||||
const appendLevel: (str: string) => string =
|
||||
level === undefined ? x => x : x => `${x} ${romanize(level)}`
|
||||
|
||||
const wrapParens = (str: string) => `(${str})`
|
||||
|
||||
const appendOptions = useParenthesis
|
||||
? (baseStr: string, optionsStr: string) =>
|
||||
optionsStr === "" ? baseStr : `${baseStr} ${wrapParens(optionsStr)}`
|
||||
: (baseStr: string, optionsStr: string) =>
|
||||
optionsStr === "" ? baseStr : `${baseStr} ${optionsStr}`
|
||||
|
||||
const full = combineChunks(
|
||||
base,
|
||||
zipChunks(options),
|
||||
(() => {
|
||||
switch (levelPlacement) {
|
||||
case "before":
|
||||
return (a, b) => appendOptions(appendLevel(a), b)
|
||||
case "after":
|
||||
return (a, b) => appendLevel(appendOptions(a, b))
|
||||
default:
|
||||
return assertExhaustive(levelPlacement)
|
||||
}
|
||||
})(),
|
||||
)
|
||||
|
||||
switch (levelPlacement) {
|
||||
case "before":
|
||||
return {
|
||||
full,
|
||||
fullWithoutLevel: [base, mapChunk(zipChunks(options), wrapParens)],
|
||||
}
|
||||
case "after":
|
||||
return {
|
||||
full,
|
||||
fullWithoutLevel: combineChunks(
|
||||
base,
|
||||
zipChunks(options),
|
||||
appendOptions,
|
||||
),
|
||||
}
|
||||
default:
|
||||
return assertExhaustive(levelPlacement)
|
||||
}
|
||||
}
|
||||
|
||||
const getEntrySpecificFullName = (
|
||||
getAspectById: GetById.Static.Aspect,
|
||||
locale: LocaleEnvironment,
|
||||
id: ActivatableIdentifier,
|
||||
base: ActivatableNameChunk,
|
||||
level: number | undefined,
|
||||
options: SelectOptionIdentifier[] | undefined,
|
||||
printedOptions: ActivatableNameComponents["options"],
|
||||
): Pick<ActivatableNameComponents, "full" | "fullWithoutLevel"> | undefined => {
|
||||
switch (id.tag) {
|
||||
case "Advantage":
|
||||
switch (id.advantage) {
|
||||
case AdvantageIdentifier.HatredOf: {
|
||||
const [firstOption, ...rest] = printedOptions
|
||||
|
||||
if (firstOption === undefined || Array.isArray(firstOption)) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return combineBaseName(
|
||||
combineChunks(base, firstOption, (a, b) => `${a} ${b}`),
|
||||
level,
|
||||
rest,
|
||||
)
|
||||
}
|
||||
case AdvantageIdentifier.ImmunityToPoison:
|
||||
case AdvantageIdentifier.ImmunityToDisease:
|
||||
return combineBaseName(base, level, printedOptions, {
|
||||
useParenthesis: false,
|
||||
})
|
||||
default:
|
||||
return undefined
|
||||
}
|
||||
case "Disadvantage":
|
||||
switch (id.disadvantage) {
|
||||
case DisadvantageIdentifier.PersonalityFlaw: {
|
||||
const [selection, optionalText, ...rest] = printedOptions
|
||||
|
||||
if (
|
||||
selection === undefined ||
|
||||
Array.isArray(selection) ||
|
||||
Array.isArray(optionalText)
|
||||
) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return combineBaseName(base, level, [
|
||||
optionalText === undefined ? selection : [selection, optionalText],
|
||||
...rest,
|
||||
])
|
||||
}
|
||||
case DisadvantageIdentifier.AfraidOf:
|
||||
return combineBaseName(base, level, printedOptions, {
|
||||
useParenthesis: false,
|
||||
})
|
||||
case DisadvantageIdentifier.Principles:
|
||||
case DisadvantageIdentifier.Obligations:
|
||||
return combineBaseName(base, level, printedOptions, {
|
||||
levelPlacement: "before",
|
||||
})
|
||||
default:
|
||||
return undefined
|
||||
}
|
||||
case "AdvancedCombatSpecialAbility":
|
||||
case "AdvancedKarmaSpecialAbility":
|
||||
case "AdvancedMagicalSpecialAbility":
|
||||
return undefined
|
||||
case "AdvancedSkillSpecialAbility":
|
||||
switch (id.advanced_skill_special_ability) {
|
||||
// case AdvancedSkillSpecialAbilityIdentifier.Fachwissen: {
|
||||
// const [skillId, firstApplicationId, secondApplicationId] = options ?? []
|
||||
// const aspect =
|
||||
// aspectId?.tag === "Aspect"
|
||||
// ? getAspectById(aspectId.aspect)
|
||||
// : undefined
|
||||
// const aspectTranslations = locale.translateMap(aspect?.translations)
|
||||
|
||||
// if (aspectTranslations === undefined) {
|
||||
// return undefined
|
||||
// }
|
||||
|
||||
// return combineBaseName(
|
||||
// combineChunks(
|
||||
// base,
|
||||
// aspectTranslations.master_of_aspect_suffix ??
|
||||
// aspectTranslations.name,
|
||||
// (a, b) => `${a} ${b}`,
|
||||
// ),
|
||||
// level,
|
||||
// [],
|
||||
// )
|
||||
// const getApp = (
|
||||
// getSid: (r: Record<ActiveObjectWithId>) => Maybe<string | number>,
|
||||
// ) =>
|
||||
// pipe(
|
||||
// SA.applications,
|
||||
// filter(pipe(AA.prerequisite, isNothing)),
|
||||
// find(pipe(AA.id, elemF(getSid(hero_entry)))),
|
||||
// fmap(AA.name),
|
||||
// )
|
||||
// return pipe_(
|
||||
// hero_entry,
|
||||
// AOWIA.sid,
|
||||
// misStringM,
|
||||
// bindF(lookupF(SDA.skills(staticData))),
|
||||
// bindF(skill =>
|
||||
// pipe_(
|
||||
// List(getApp(AOWIA.sid2)(skill), getApp(AOWIA.sid3)(skill)),
|
||||
// catMaybes,
|
||||
// ensure(xs => flength(xs) === 2),
|
||||
// fmap(
|
||||
// pipe(
|
||||
// sortStrings(staticData),
|
||||
// formatList("conjunction")(staticData),
|
||||
// apps => `${SA.name(skill)}: ${apps}`,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// )
|
||||
// }
|
||||
|
||||
default:
|
||||
return undefined
|
||||
}
|
||||
case "AncestorGlyph":
|
||||
case "ArcaneOrbEnchantment":
|
||||
case "AttireEnchantment":
|
||||
case "BlessedTradition":
|
||||
case "BowlEnchantment":
|
||||
case "BrawlingSpecialAbility":
|
||||
case "CauldronEnchantment":
|
||||
case "CeremonialItemSpecialAbility":
|
||||
case "ChronicleEnchantment":
|
||||
case "CombatSpecialAbility":
|
||||
case "CombatStyleSpecialAbility":
|
||||
case "CommandSpecialAbility":
|
||||
case "DaggerRitual":
|
||||
case "FamiliarSpecialAbility":
|
||||
case "FatePointSexSpecialAbility":
|
||||
case "FatePointSpecialAbility":
|
||||
case "FoolsHatEnchantment":
|
||||
return undefined
|
||||
case "GeneralSpecialAbility":
|
||||
switch (id.general_special_ability) {
|
||||
// case GeneralSpecialAbilityIdentifier.LanguageSpecialization: {
|
||||
// const [languageId, specializationId] = options ?? []
|
||||
|
||||
// const language =
|
||||
// languageId?.tag === "Language"
|
||||
// ? getLanguageById(languageId.language)
|
||||
// : undefined
|
||||
|
||||
// const specializations =
|
||||
// language?.specializations?.tag === "Specific"
|
||||
// ? language.specializations.specific.list
|
||||
// : []
|
||||
|
||||
// const specialization =
|
||||
// specializationId?.tag === "General"
|
||||
// ? specializations.find(
|
||||
// spec => spec.id === specializationId.general,
|
||||
// )
|
||||
// : undefined
|
||||
|
||||
// if (aspectTranslations === undefined) {
|
||||
// return undefined
|
||||
// }
|
||||
|
||||
// return combineBaseName(
|
||||
// combineChunks(
|
||||
// base,
|
||||
// aspectTranslations.master_of_aspect_suffix ??
|
||||
// aspectTranslations.name,
|
||||
// (a, b) => `${a} ${b}`,
|
||||
// ),
|
||||
// level,
|
||||
// [],
|
||||
// )
|
||||
|
||||
// return pipe(
|
||||
// SDA.specialAbilities,
|
||||
// lookup<string>(SpecialAbilityId.Language),
|
||||
// bindF(pipe(findSelectOption, thrush(AOWIA.sid(hero_entry)))),
|
||||
// bindF(lang =>
|
||||
// pipe(
|
||||
// AOWIA.sid2,
|
||||
// bindF(
|
||||
// ifElse<string | number, string>(isString)<Maybe<string>>(
|
||||
// Just,
|
||||
// )(spec_id =>
|
||||
// bind(SOA.specializations(lang))(subscriptF(spec_id - 1)),
|
||||
// ),
|
||||
// ),
|
||||
// fmap(spec => `${SOA.name(lang)}: ${spec}`),
|
||||
// )(hero_entry),
|
||||
// ),
|
||||
// )(staticData)
|
||||
// }
|
||||
|
||||
default:
|
||||
return undefined
|
||||
}
|
||||
case "InstrumentEnchantment":
|
||||
return undefined
|
||||
case "KarmaSpecialAbility":
|
||||
switch (id.karma_special_ability) {
|
||||
case KarmaSpecialAbilityIdentifier.MasterOfAspect: {
|
||||
const [aspectId] = options ?? []
|
||||
const aspect =
|
||||
aspectId?.tag === "Aspect"
|
||||
? getAspectById(aspectId.aspect)
|
||||
: undefined
|
||||
const aspectTranslations = locale.translateMap(aspect?.translations)
|
||||
|
||||
if (aspectTranslations === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return combineBaseName(
|
||||
combineChunks(
|
||||
base,
|
||||
aspectTranslations.master_of_aspect_suffix ??
|
||||
aspectTranslations.name,
|
||||
(a, b) => `${a} ${b}`,
|
||||
),
|
||||
level,
|
||||
[],
|
||||
)
|
||||
}
|
||||
|
||||
default:
|
||||
return undefined
|
||||
}
|
||||
case "Krallenkettenzauber":
|
||||
case "LiturgicalStyleSpecialAbility":
|
||||
case "LycantropicGift":
|
||||
case "MagicalSign":
|
||||
case "MagicalSpecialAbility":
|
||||
case "MagicalTradition":
|
||||
case "MagicStyleSpecialAbility":
|
||||
case "OrbEnchantment":
|
||||
case "PactGift":
|
||||
case "ProtectiveWardingCircleSpecialAbility":
|
||||
case "RingEnchantment":
|
||||
case "Sermon":
|
||||
case "SexSpecialAbility":
|
||||
case "SickleRitual":
|
||||
case "SikaryanDrainSpecialAbility":
|
||||
case "SkillStyleSpecialAbility":
|
||||
case "SpellSwordEnchantment":
|
||||
case "StaffEnchantment":
|
||||
case "ToyEnchantment":
|
||||
case "Trinkhornzauber":
|
||||
case "VampiricGift":
|
||||
case "Vision":
|
||||
case "WandEnchantment":
|
||||
case "WeaponEnchantment":
|
||||
return undefined
|
||||
default:
|
||||
return assertExhaustive(id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name components for an activatable entry.
|
||||
*/
|
||||
export const getNameComponents = <T>(
|
||||
getAspectById: GetById.Static.Aspect,
|
||||
locale: LocaleEnvironment,
|
||||
id: ActivatableIdentifier,
|
||||
options: SelectOptionIdentifier[] | undefined,
|
||||
level: number | undefined,
|
||||
translations: LocaleMap<T>,
|
||||
getBaseName: (translation: T) => string,
|
||||
getSelectOptionById: (
|
||||
id: SelectOptionIdentifier,
|
||||
) => ResolvedSelectOption | undefined,
|
||||
displayedInProfession: boolean,
|
||||
): ActivatableNameComponents => {
|
||||
const base = mapObject(translations, getBaseName)
|
||||
const nameOptions: ActivatableNameComponents["options"] = (() => {
|
||||
const arr =
|
||||
options?.map(optionId => {
|
||||
const optTranslations = getSelectOptionById(optionId)?.translations
|
||||
return optTranslations === undefined
|
||||
? MISSING_VALUE
|
||||
: mapObject(optTranslations, t10n =>
|
||||
displayedInProfession
|
||||
? t10n.name_in_profession ?? t10n.name
|
||||
: t10n.name,
|
||||
)
|
||||
}) ?? []
|
||||
|
||||
if (arr.length > 1) {
|
||||
const [first, ...rest] = arr
|
||||
return [[first!, zipChunks(rest)]]
|
||||
}
|
||||
|
||||
return arr
|
||||
})()
|
||||
|
||||
return {
|
||||
...(getEntrySpecificFullName(
|
||||
getAspectById,
|
||||
locale,
|
||||
id,
|
||||
base,
|
||||
level,
|
||||
options,
|
||||
nameOptions,
|
||||
) ?? combineBaseName(base, level, nameOptions)),
|
||||
base,
|
||||
options: nameOptions,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a name chunk to a displayable string.
|
||||
*/
|
||||
export const printActivatableNameChunk = (
|
||||
locale: LocaleEnvironment,
|
||||
chunk: ActivatableNameChunk,
|
||||
): string => {
|
||||
if (typeof chunk === "string") {
|
||||
return chunk
|
||||
} else if (typeof chunk === "function") {
|
||||
return chunk(locale)
|
||||
} else if (typeof chunk === "object") {
|
||||
return locale.translateMap(chunk) ?? MISSING_VALUE
|
||||
}
|
||||
return chunk
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { DisplayOption } from "optolith-database-schema/types/prerequisites/DisplayOption"
|
||||
import { LocaleEnvironment } from "../../../helpers/locale.js"
|
||||
import { MISSING_VALUE } from "../unknown.js"
|
||||
import { PrerequisitePart } from "./part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a display option.
|
||||
*/
|
||||
export const printDisplayOption = (
|
||||
locale: LocaleEnvironment,
|
||||
displayOption: DisplayOption,
|
||||
): PrerequisitePart | undefined => {
|
||||
switch (displayOption.tag) {
|
||||
case "Hide":
|
||||
return undefined
|
||||
case "ReplaceWith":
|
||||
return {
|
||||
value:
|
||||
locale.translateMap(displayOption.replace_with.translations) ??
|
||||
MISSING_VALUE,
|
||||
sentenceType: displayOption.replace_with.sentence_type,
|
||||
isMeta: false,
|
||||
}
|
||||
default:
|
||||
return assertExhaustive(displayOption)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { SentenceType } from "optolith-database-schema/types/prerequisites/single/TextPrerequisite"
|
||||
import { LocaleEnvironment } from "../../../helpers/locale.js"
|
||||
|
||||
/**
|
||||
* A part of the total list of prerequisites.
|
||||
*/
|
||||
export type PrerequisitePart = {
|
||||
label?: string
|
||||
value: string
|
||||
sentenceType: SentenceType | undefined
|
||||
isMeta: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Join prerequisite parts using their configuration.
|
||||
*/
|
||||
export const joinPrerequisiteParts = (
|
||||
locale: LocaleEnvironment,
|
||||
parts: PrerequisitePart[],
|
||||
): string =>
|
||||
parts.reduce(
|
||||
(acc, part, i, arr) => {
|
||||
const text =
|
||||
part.label === undefined ? part.value : part.label + part.value
|
||||
|
||||
if (acc === "") {
|
||||
return text
|
||||
}
|
||||
|
||||
switch (part.sentenceType) {
|
||||
case "Standalone":
|
||||
return `${
|
||||
/[.;]$/u.test(acc) ? `${acc.slice(0, -1)}. ` : `${acc}. `
|
||||
}${text}${text.endsWith(".") ? "" : "."}`
|
||||
case "Connected":
|
||||
return `${/[.;]$/u.test(acc) ? `${acc} ` : `${acc}; `}${text}${
|
||||
i < arr.length - 1 ? ";" : ""
|
||||
}`
|
||||
case undefined:
|
||||
return `${acc}${/[.;]$/u.test(acc) ? " " : ", "}${text}`
|
||||
default:
|
||||
return assertExhaustive(part.sentenceType)
|
||||
}
|
||||
},
|
||||
parts.every(part => part.isMeta) ? locale.translate("none") : "",
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,467 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { ResolvedSelectOption } from "optolith-database-schema/cache/activatableSelectOptions"
|
||||
import {
|
||||
ActivatableIdentifier,
|
||||
SelectOptionIdentifier,
|
||||
} from "optolith-database-schema/types/_IdentifierGroup"
|
||||
import { LocaleMap } from "optolith-database-schema/types/_LocaleMap"
|
||||
import { ActivatablePrerequisite } from "optolith-database-schema/types/prerequisites/single/ActivatablePrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import {
|
||||
getNameComponents,
|
||||
printActivatableNameChunk,
|
||||
} from "../../activatableNameChunks.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
const getTranslationsForActivatable = (
|
||||
getAdvantageById: GetById.Static.Advantage,
|
||||
getDisadvantageById: GetById.Static.Disadvantage,
|
||||
getAdvancedCombatSpecialAbilityById: GetById.Static.AdvancedCombatSpecialAbility,
|
||||
getAdvancedKarmaSpecialAbilityById: GetById.Static.AdvancedKarmaSpecialAbility,
|
||||
getAdvancedMagicalSpecialAbilityById: GetById.Static.AdvancedMagicalSpecialAbility,
|
||||
getAdvancedSkillSpecialAbilityById: GetById.Static.AdvancedSkillSpecialAbility,
|
||||
getAncestorGlyphById: GetById.Static.AncestorGlyph,
|
||||
getArcaneOrbEnchantmentById: GetById.Static.ArcaneOrbEnchantment,
|
||||
getAttireEnchantmentById: GetById.Static.AttireEnchantment,
|
||||
getBlessedTraditionById: GetById.Static.BlessedTradition,
|
||||
getBowlEnchantmentById: GetById.Static.BowlEnchantment,
|
||||
getBrawlingSpecialAbilityById: GetById.Static.BrawlingSpecialAbility,
|
||||
getCauldronEnchantmentById: GetById.Static.CauldronEnchantment,
|
||||
getCeremonialItemSpecialAbilityById: GetById.Static.CeremonialItemSpecialAbility,
|
||||
getChronicleEnchantmentById: GetById.Static.ChronicleEnchantment,
|
||||
getCombatSpecialAbilityById: GetById.Static.CombatSpecialAbility,
|
||||
getCombatStyleSpecialAbilityById: GetById.Static.CombatStyleSpecialAbility,
|
||||
getCommandSpecialAbilityById: GetById.Static.CommandSpecialAbility,
|
||||
getDaggerRitualById: GetById.Static.DaggerRitual,
|
||||
getFamiliarSpecialAbilityById: GetById.Static.FamiliarSpecialAbility,
|
||||
getFatePointSexSpecialAbilityById: GetById.Static.FatePointSexSpecialAbility,
|
||||
getFatePointSpecialAbilityById: GetById.Static.FatePointSpecialAbility,
|
||||
getFoolsHatEnchantmentById: GetById.Static.FoolsHatEnchantment,
|
||||
getGeneralSpecialAbilityById: GetById.Static.GeneralSpecialAbility,
|
||||
getInstrumentEnchantmentById: GetById.Static.InstrumentEnchantment,
|
||||
getKarmaSpecialAbilityById: GetById.Static.KarmaSpecialAbility,
|
||||
getKrallenkettenzauberById: GetById.Static.Krallenkettenzauber,
|
||||
getLiturgicalStyleSpecialAbilityById: GetById.Static.LiturgicalStyleSpecialAbility,
|
||||
getLycantropicGiftById: GetById.Static.LycantropicGift,
|
||||
getMagicalSignById: GetById.Static.MagicalSign,
|
||||
getMagicalSpecialAbilityById: GetById.Static.MagicalSpecialAbility,
|
||||
getMagicalTraditionById: GetById.Static.MagicalTradition,
|
||||
getMagicStyleSpecialAbilityById: GetById.Static.MagicStyleSpecialAbility,
|
||||
getOrbEnchantmentById: GetById.Static.OrbEnchantment,
|
||||
getPactGiftById: GetById.Static.PactGift,
|
||||
getProtectiveWardingCircleSpecialAbilityById: GetById.Static.ProtectiveWardingCircleSpecialAbility,
|
||||
getRingEnchantmentById: GetById.Static.RingEnchantment,
|
||||
getSermonById: GetById.Static.Sermon,
|
||||
getSexSpecialAbilityById: GetById.Static.SexSpecialAbility,
|
||||
getSickleRitualById: GetById.Static.SickleRitual,
|
||||
getSikaryanDrainSpecialAbilityById: GetById.Static.SikaryanDrainSpecialAbility,
|
||||
getSkillStyleSpecialAbilityById: GetById.Static.SkillStyleSpecialAbility,
|
||||
getSpellSwordEnchantmentById: GetById.Static.SpellSwordEnchantment,
|
||||
getStaffEnchantmentById: GetById.Static.StaffEnchantment,
|
||||
getToyEnchantmentById: GetById.Static.ToyEnchantment,
|
||||
getTrinkhornzauberById: GetById.Static.Trinkhornzauber,
|
||||
getVampiricGiftById: GetById.Static.VampiricGift,
|
||||
getVisionById: GetById.Static.Vision,
|
||||
getWandEnchantmentById: GetById.Static.WandEnchantment,
|
||||
getWeaponEnchantmentById: GetById.Static.WeaponEnchantment,
|
||||
id: ActivatableIdentifier,
|
||||
): { translations: LocaleMap<{ name: string }> } | undefined => {
|
||||
switch (id.tag) {
|
||||
case "Advantage":
|
||||
return getAdvantageById(id.advantage)
|
||||
case "Disadvantage":
|
||||
return getDisadvantageById(id.disadvantage)
|
||||
case "AdvancedCombatSpecialAbility":
|
||||
return getAdvancedCombatSpecialAbilityById(
|
||||
id.advanced_combat_special_ability,
|
||||
)
|
||||
case "AdvancedKarmaSpecialAbility":
|
||||
return getAdvancedKarmaSpecialAbilityById(
|
||||
id.advanced_karma_special_ability,
|
||||
)
|
||||
case "AdvancedMagicalSpecialAbility":
|
||||
return getAdvancedMagicalSpecialAbilityById(
|
||||
id.advanced_magical_special_ability,
|
||||
)
|
||||
case "AdvancedSkillSpecialAbility":
|
||||
return getAdvancedSkillSpecialAbilityById(
|
||||
id.advanced_skill_special_ability,
|
||||
)
|
||||
case "AncestorGlyph":
|
||||
return getAncestorGlyphById(id.ancestor_glyph)
|
||||
case "ArcaneOrbEnchantment":
|
||||
return getArcaneOrbEnchantmentById(id.arcane_orb_enchantment)
|
||||
case "AttireEnchantment":
|
||||
return getAttireEnchantmentById(id.attire_enchantment)
|
||||
case "BlessedTradition":
|
||||
return getBlessedTraditionById(id.blessed_tradition)
|
||||
case "BowlEnchantment":
|
||||
return getBowlEnchantmentById(id.bowl_enchantment)
|
||||
case "BrawlingSpecialAbility":
|
||||
return getBrawlingSpecialAbilityById(id.brawling_special_ability)
|
||||
case "CauldronEnchantment":
|
||||
return getCauldronEnchantmentById(id.cauldron_enchantment)
|
||||
case "CeremonialItemSpecialAbility":
|
||||
return getCeremonialItemSpecialAbilityById(
|
||||
id.ceremonial_item_special_ability,
|
||||
)
|
||||
case "ChronicleEnchantment":
|
||||
return getChronicleEnchantmentById(id.chronicle_enchantment)
|
||||
case "CombatSpecialAbility":
|
||||
return getCombatSpecialAbilityById(id.combat_special_ability)
|
||||
case "CombatStyleSpecialAbility":
|
||||
return getCombatStyleSpecialAbilityById(id.combat_style_special_ability)
|
||||
case "CommandSpecialAbility":
|
||||
return getCommandSpecialAbilityById(id.command_special_ability)
|
||||
case "DaggerRitual":
|
||||
return getDaggerRitualById(id.dagger_ritual)
|
||||
case "FamiliarSpecialAbility":
|
||||
return getFamiliarSpecialAbilityById(id.familiar_special_ability)
|
||||
case "FatePointSexSpecialAbility":
|
||||
return getFatePointSexSpecialAbilityById(
|
||||
id.fate_point_sex_special_ability,
|
||||
)
|
||||
case "FatePointSpecialAbility":
|
||||
return getFatePointSpecialAbilityById(id.fate_point_special_ability)
|
||||
case "FoolsHatEnchantment":
|
||||
return getFoolsHatEnchantmentById(id.fools_hat_enchantment)
|
||||
case "GeneralSpecialAbility":
|
||||
return getGeneralSpecialAbilityById(id.general_special_ability)
|
||||
case "InstrumentEnchantment":
|
||||
return getInstrumentEnchantmentById(id.instrument_enchantment)
|
||||
case "KarmaSpecialAbility":
|
||||
return getKarmaSpecialAbilityById(id.karma_special_ability)
|
||||
case "Krallenkettenzauber":
|
||||
return getKrallenkettenzauberById(id.krallenkettenzauber)
|
||||
case "LiturgicalStyleSpecialAbility":
|
||||
return getLiturgicalStyleSpecialAbilityById(
|
||||
id.liturgical_style_special_ability,
|
||||
)
|
||||
case "LycantropicGift":
|
||||
return getLycantropicGiftById(id.lycantropic_gift)
|
||||
case "MagicalSign":
|
||||
return getMagicalSignById(id.magical_sign)
|
||||
case "MagicalSpecialAbility":
|
||||
return getMagicalSpecialAbilityById(id.magical_special_ability)
|
||||
case "MagicalTradition":
|
||||
return getMagicalTraditionById(id.magical_tradition)
|
||||
case "MagicStyleSpecialAbility":
|
||||
return getMagicStyleSpecialAbilityById(id.magic_style_special_ability)
|
||||
case "OrbEnchantment":
|
||||
return getOrbEnchantmentById(id.orb_enchantment)
|
||||
case "PactGift":
|
||||
return getPactGiftById(id.pact_gift)
|
||||
case "ProtectiveWardingCircleSpecialAbility":
|
||||
return getProtectiveWardingCircleSpecialAbilityById(
|
||||
id.protective_warding_circle_special_ability,
|
||||
)
|
||||
case "RingEnchantment":
|
||||
return getRingEnchantmentById(id.ring_enchantment)
|
||||
case "Sermon":
|
||||
return getSermonById(id.sermon)
|
||||
case "SexSpecialAbility":
|
||||
return getSexSpecialAbilityById(id.sex_special_ability)
|
||||
case "SickleRitual":
|
||||
return getSickleRitualById(id.sickle_ritual)
|
||||
case "SikaryanDrainSpecialAbility":
|
||||
return getSikaryanDrainSpecialAbilityById(
|
||||
id.sikaryan_drain_special_ability,
|
||||
)
|
||||
case "SkillStyleSpecialAbility":
|
||||
return getSkillStyleSpecialAbilityById(id.skill_style_special_ability)
|
||||
case "SpellSwordEnchantment":
|
||||
return getSpellSwordEnchantmentById(id.spell_sword_enchantment)
|
||||
case "StaffEnchantment":
|
||||
return getStaffEnchantmentById(id.staff_enchantment)
|
||||
case "ToyEnchantment":
|
||||
return getToyEnchantmentById(id.toy_enchantment)
|
||||
case "Trinkhornzauber":
|
||||
return getTrinkhornzauberById(id.trinkhornzauber)
|
||||
case "VampiricGift":
|
||||
return getVampiricGiftById(id.vampiric_gift)
|
||||
case "Vision":
|
||||
return getVisionById(id.vision)
|
||||
case "WandEnchantment":
|
||||
return getWandEnchantmentById(id.wand_enchantment)
|
||||
case "WeaponEnchantment":
|
||||
return getWeaponEnchantmentById(id.weapon_enchantment)
|
||||
default:
|
||||
return assertExhaustive(id)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Gets a resolved select option by its identifier.
|
||||
*/
|
||||
export type GetResolvedSelectOptionById = (
|
||||
id: ActivatableIdentifier,
|
||||
selectOptionId: SelectOptionIdentifier,
|
||||
) => ResolvedSelectOption | undefined
|
||||
|
||||
const printActivatableName = (
|
||||
getAdvantageById: GetById.Static.Advantage,
|
||||
getDisadvantageById: GetById.Static.Disadvantage,
|
||||
getAdvancedCombatSpecialAbilityById: GetById.Static.AdvancedCombatSpecialAbility,
|
||||
getAdvancedKarmaSpecialAbilityById: GetById.Static.AdvancedKarmaSpecialAbility,
|
||||
getAdvancedMagicalSpecialAbilityById: GetById.Static.AdvancedMagicalSpecialAbility,
|
||||
getAdvancedSkillSpecialAbilityById: GetById.Static.AdvancedSkillSpecialAbility,
|
||||
getAncestorGlyphById: GetById.Static.AncestorGlyph,
|
||||
getArcaneOrbEnchantmentById: GetById.Static.ArcaneOrbEnchantment,
|
||||
getAttireEnchantmentById: GetById.Static.AttireEnchantment,
|
||||
getBlessedTraditionById: GetById.Static.BlessedTradition,
|
||||
getBowlEnchantmentById: GetById.Static.BowlEnchantment,
|
||||
getBrawlingSpecialAbilityById: GetById.Static.BrawlingSpecialAbility,
|
||||
getCauldronEnchantmentById: GetById.Static.CauldronEnchantment,
|
||||
getCeremonialItemSpecialAbilityById: GetById.Static.CeremonialItemSpecialAbility,
|
||||
getChronicleEnchantmentById: GetById.Static.ChronicleEnchantment,
|
||||
getCombatSpecialAbilityById: GetById.Static.CombatSpecialAbility,
|
||||
getCombatStyleSpecialAbilityById: GetById.Static.CombatStyleSpecialAbility,
|
||||
getCommandSpecialAbilityById: GetById.Static.CommandSpecialAbility,
|
||||
getDaggerRitualById: GetById.Static.DaggerRitual,
|
||||
getFamiliarSpecialAbilityById: GetById.Static.FamiliarSpecialAbility,
|
||||
getFatePointSexSpecialAbilityById: GetById.Static.FatePointSexSpecialAbility,
|
||||
getFatePointSpecialAbilityById: GetById.Static.FatePointSpecialAbility,
|
||||
getFoolsHatEnchantmentById: GetById.Static.FoolsHatEnchantment,
|
||||
getGeneralSpecialAbilityById: GetById.Static.GeneralSpecialAbility,
|
||||
getInstrumentEnchantmentById: GetById.Static.InstrumentEnchantment,
|
||||
getKarmaSpecialAbilityById: GetById.Static.KarmaSpecialAbility,
|
||||
getKrallenkettenzauberById: GetById.Static.Krallenkettenzauber,
|
||||
getLiturgicalStyleSpecialAbilityById: GetById.Static.LiturgicalStyleSpecialAbility,
|
||||
getLycantropicGiftById: GetById.Static.LycantropicGift,
|
||||
getMagicalSignById: GetById.Static.MagicalSign,
|
||||
getMagicalSpecialAbilityById: GetById.Static.MagicalSpecialAbility,
|
||||
getMagicalTraditionById: GetById.Static.MagicalTradition,
|
||||
getMagicStyleSpecialAbilityById: GetById.Static.MagicStyleSpecialAbility,
|
||||
getOrbEnchantmentById: GetById.Static.OrbEnchantment,
|
||||
getPactGiftById: GetById.Static.PactGift,
|
||||
getProtectiveWardingCircleSpecialAbilityById: GetById.Static.ProtectiveWardingCircleSpecialAbility,
|
||||
getRingEnchantmentById: GetById.Static.RingEnchantment,
|
||||
getSermonById: GetById.Static.Sermon,
|
||||
getSexSpecialAbilityById: GetById.Static.SexSpecialAbility,
|
||||
getSickleRitualById: GetById.Static.SickleRitual,
|
||||
getSikaryanDrainSpecialAbilityById: GetById.Static.SikaryanDrainSpecialAbility,
|
||||
getSkillStyleSpecialAbilityById: GetById.Static.SkillStyleSpecialAbility,
|
||||
getSpellSwordEnchantmentById: GetById.Static.SpellSwordEnchantment,
|
||||
getStaffEnchantmentById: GetById.Static.StaffEnchantment,
|
||||
getToyEnchantmentById: GetById.Static.ToyEnchantment,
|
||||
getTrinkhornzauberById: GetById.Static.Trinkhornzauber,
|
||||
getVampiricGiftById: GetById.Static.VampiricGift,
|
||||
getVisionById: GetById.Static.Vision,
|
||||
getWandEnchantmentById: GetById.Static.WandEnchantment,
|
||||
getWeaponEnchantmentById: GetById.Static.WeaponEnchantment,
|
||||
getAspectById: GetById.Static.Aspect,
|
||||
locale: LocaleEnvironment,
|
||||
id: ActivatableIdentifier,
|
||||
options: SelectOptionIdentifier[] | undefined,
|
||||
level: number | undefined,
|
||||
getResolvedSelectOptionById: GetResolvedSelectOptionById,
|
||||
) => {
|
||||
const entry = getTranslationsForActivatable(
|
||||
getAdvantageById,
|
||||
getDisadvantageById,
|
||||
getAdvancedCombatSpecialAbilityById,
|
||||
getAdvancedKarmaSpecialAbilityById,
|
||||
getAdvancedMagicalSpecialAbilityById,
|
||||
getAdvancedSkillSpecialAbilityById,
|
||||
getAncestorGlyphById,
|
||||
getArcaneOrbEnchantmentById,
|
||||
getAttireEnchantmentById,
|
||||
getBlessedTraditionById,
|
||||
getBowlEnchantmentById,
|
||||
getBrawlingSpecialAbilityById,
|
||||
getCauldronEnchantmentById,
|
||||
getCeremonialItemSpecialAbilityById,
|
||||
getChronicleEnchantmentById,
|
||||
getCombatSpecialAbilityById,
|
||||
getCombatStyleSpecialAbilityById,
|
||||
getCommandSpecialAbilityById,
|
||||
getDaggerRitualById,
|
||||
getFamiliarSpecialAbilityById,
|
||||
getFatePointSexSpecialAbilityById,
|
||||
getFatePointSpecialAbilityById,
|
||||
getFoolsHatEnchantmentById,
|
||||
getGeneralSpecialAbilityById,
|
||||
getInstrumentEnchantmentById,
|
||||
getKarmaSpecialAbilityById,
|
||||
getKrallenkettenzauberById,
|
||||
getLiturgicalStyleSpecialAbilityById,
|
||||
getLycantropicGiftById,
|
||||
getMagicalSignById,
|
||||
getMagicalSpecialAbilityById,
|
||||
getMagicalTraditionById,
|
||||
getMagicStyleSpecialAbilityById,
|
||||
getOrbEnchantmentById,
|
||||
getPactGiftById,
|
||||
getProtectiveWardingCircleSpecialAbilityById,
|
||||
getRingEnchantmentById,
|
||||
getSermonById,
|
||||
getSexSpecialAbilityById,
|
||||
getSickleRitualById,
|
||||
getSikaryanDrainSpecialAbilityById,
|
||||
getSkillStyleSpecialAbilityById,
|
||||
getSpellSwordEnchantmentById,
|
||||
getStaffEnchantmentById,
|
||||
getToyEnchantmentById,
|
||||
getTrinkhornzauberById,
|
||||
getVampiricGiftById,
|
||||
getVisionById,
|
||||
getWandEnchantmentById,
|
||||
getWeaponEnchantmentById,
|
||||
id,
|
||||
)
|
||||
|
||||
if (entry === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return getNameComponents(
|
||||
getAspectById,
|
||||
locale,
|
||||
id,
|
||||
options,
|
||||
level,
|
||||
entry.translations,
|
||||
t => t.name,
|
||||
selectOptionId => getResolvedSelectOptionById(id, selectOptionId),
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of a blessed tradition prerequisite.
|
||||
*/
|
||||
export const printActivatablePrerequisite = (
|
||||
getAdvantageById: GetById.Static.Advantage,
|
||||
getDisadvantageById: GetById.Static.Disadvantage,
|
||||
getAdvancedCombatSpecialAbilityById: GetById.Static.AdvancedCombatSpecialAbility,
|
||||
getAdvancedKarmaSpecialAbilityById: GetById.Static.AdvancedKarmaSpecialAbility,
|
||||
getAdvancedMagicalSpecialAbilityById: GetById.Static.AdvancedMagicalSpecialAbility,
|
||||
getAdvancedSkillSpecialAbilityById: GetById.Static.AdvancedSkillSpecialAbility,
|
||||
getAncestorGlyphById: GetById.Static.AncestorGlyph,
|
||||
getArcaneOrbEnchantmentById: GetById.Static.ArcaneOrbEnchantment,
|
||||
getAttireEnchantmentById: GetById.Static.AttireEnchantment,
|
||||
getBlessedTraditionById: GetById.Static.BlessedTradition,
|
||||
getBowlEnchantmentById: GetById.Static.BowlEnchantment,
|
||||
getBrawlingSpecialAbilityById: GetById.Static.BrawlingSpecialAbility,
|
||||
getCauldronEnchantmentById: GetById.Static.CauldronEnchantment,
|
||||
getCeremonialItemSpecialAbilityById: GetById.Static.CeremonialItemSpecialAbility,
|
||||
getChronicleEnchantmentById: GetById.Static.ChronicleEnchantment,
|
||||
getCombatSpecialAbilityById: GetById.Static.CombatSpecialAbility,
|
||||
getCombatStyleSpecialAbilityById: GetById.Static.CombatStyleSpecialAbility,
|
||||
getCommandSpecialAbilityById: GetById.Static.CommandSpecialAbility,
|
||||
getDaggerRitualById: GetById.Static.DaggerRitual,
|
||||
getFamiliarSpecialAbilityById: GetById.Static.FamiliarSpecialAbility,
|
||||
getFatePointSexSpecialAbilityById: GetById.Static.FatePointSexSpecialAbility,
|
||||
getFatePointSpecialAbilityById: GetById.Static.FatePointSpecialAbility,
|
||||
getFoolsHatEnchantmentById: GetById.Static.FoolsHatEnchantment,
|
||||
getGeneralSpecialAbilityById: GetById.Static.GeneralSpecialAbility,
|
||||
getInstrumentEnchantmentById: GetById.Static.InstrumentEnchantment,
|
||||
getKarmaSpecialAbilityById: GetById.Static.KarmaSpecialAbility,
|
||||
getKrallenkettenzauberById: GetById.Static.Krallenkettenzauber,
|
||||
getLiturgicalStyleSpecialAbilityById: GetById.Static.LiturgicalStyleSpecialAbility,
|
||||
getLycantropicGiftById: GetById.Static.LycantropicGift,
|
||||
getMagicalSignById: GetById.Static.MagicalSign,
|
||||
getMagicalSpecialAbilityById: GetById.Static.MagicalSpecialAbility,
|
||||
getMagicalTraditionById: GetById.Static.MagicalTradition,
|
||||
getMagicStyleSpecialAbilityById: GetById.Static.MagicStyleSpecialAbility,
|
||||
getOrbEnchantmentById: GetById.Static.OrbEnchantment,
|
||||
getPactGiftById: GetById.Static.PactGift,
|
||||
getProtectiveWardingCircleSpecialAbilityById: GetById.Static.ProtectiveWardingCircleSpecialAbility,
|
||||
getRingEnchantmentById: GetById.Static.RingEnchantment,
|
||||
getSermonById: GetById.Static.Sermon,
|
||||
getSexSpecialAbilityById: GetById.Static.SexSpecialAbility,
|
||||
getSickleRitualById: GetById.Static.SickleRitual,
|
||||
getSikaryanDrainSpecialAbilityById: GetById.Static.SikaryanDrainSpecialAbility,
|
||||
getSkillStyleSpecialAbilityById: GetById.Static.SkillStyleSpecialAbility,
|
||||
getSpellSwordEnchantmentById: GetById.Static.SpellSwordEnchantment,
|
||||
getStaffEnchantmentById: GetById.Static.StaffEnchantment,
|
||||
getToyEnchantmentById: GetById.Static.ToyEnchantment,
|
||||
getTrinkhornzauberById: GetById.Static.Trinkhornzauber,
|
||||
getVampiricGiftById: GetById.Static.VampiricGift,
|
||||
getVisionById: GetById.Static.Vision,
|
||||
getWandEnchantmentById: GetById.Static.WandEnchantment,
|
||||
getWeaponEnchantmentById: GetById.Static.WeaponEnchantment,
|
||||
getAspectById: GetById.Static.Aspect,
|
||||
getResolvedSelectOptionById: GetResolvedSelectOptionById,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: ActivatablePrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
const nameComponents = printActivatableName(
|
||||
getAdvantageById,
|
||||
getDisadvantageById,
|
||||
getAdvancedCombatSpecialAbilityById,
|
||||
getAdvancedKarmaSpecialAbilityById,
|
||||
getAdvancedMagicalSpecialAbilityById,
|
||||
getAdvancedSkillSpecialAbilityById,
|
||||
getAncestorGlyphById,
|
||||
getArcaneOrbEnchantmentById,
|
||||
getAttireEnchantmentById,
|
||||
getBlessedTraditionById,
|
||||
getBowlEnchantmentById,
|
||||
getBrawlingSpecialAbilityById,
|
||||
getCauldronEnchantmentById,
|
||||
getCeremonialItemSpecialAbilityById,
|
||||
getChronicleEnchantmentById,
|
||||
getCombatSpecialAbilityById,
|
||||
getCombatStyleSpecialAbilityById,
|
||||
getCommandSpecialAbilityById,
|
||||
getDaggerRitualById,
|
||||
getFamiliarSpecialAbilityById,
|
||||
getFatePointSexSpecialAbilityById,
|
||||
getFatePointSpecialAbilityById,
|
||||
getFoolsHatEnchantmentById,
|
||||
getGeneralSpecialAbilityById,
|
||||
getInstrumentEnchantmentById,
|
||||
getKarmaSpecialAbilityById,
|
||||
getKrallenkettenzauberById,
|
||||
getLiturgicalStyleSpecialAbilityById,
|
||||
getLycantropicGiftById,
|
||||
getMagicalSignById,
|
||||
getMagicalSpecialAbilityById,
|
||||
getMagicalTraditionById,
|
||||
getMagicStyleSpecialAbilityById,
|
||||
getOrbEnchantmentById,
|
||||
getPactGiftById,
|
||||
getProtectiveWardingCircleSpecialAbilityById,
|
||||
getRingEnchantmentById,
|
||||
getSermonById,
|
||||
getSexSpecialAbilityById,
|
||||
getSickleRitualById,
|
||||
getSikaryanDrainSpecialAbilityById,
|
||||
getSkillStyleSpecialAbilityById,
|
||||
getSpellSwordEnchantmentById,
|
||||
getStaffEnchantmentById,
|
||||
getToyEnchantmentById,
|
||||
getTrinkhornzauberById,
|
||||
getVampiricGiftById,
|
||||
getVisionById,
|
||||
getWandEnchantmentById,
|
||||
getWeaponEnchantmentById,
|
||||
getAspectById,
|
||||
locale,
|
||||
prerequisite.id,
|
||||
prerequisite.options,
|
||||
prerequisite.level,
|
||||
getResolvedSelectOptionById,
|
||||
)
|
||||
|
||||
if (nameComponents === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
label: `${
|
||||
prerequisite.active
|
||||
? locale.translate("special ability")
|
||||
: locale.translate("no special ability")
|
||||
} `,
|
||||
value: printActivatableNameChunk(locale, nameComponents.full),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { isNotNullish } from "@optolith/helpers/nullable"
|
||||
import { romanize } from "@optolith/helpers/roman"
|
||||
import { AnimistPowerPrerequisite } from "optolith-database-schema/types/prerequisites/single/AnimistPowerPrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a culture prerequisite.
|
||||
*/
|
||||
export const printAnimistPowerPrerequisite = (
|
||||
getAnimistPowerById: GetById.Static.AnimistPower,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: AnimistPowerPrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
const animistPower = getAnimistPowerById(prerequisite.id.animist_power)
|
||||
|
||||
return {
|
||||
value: [
|
||||
locale.translateMap(animistPower?.translations)?.name ?? "MISSING_VALUE",
|
||||
prerequisite.level === undefined
|
||||
? undefined
|
||||
: romanize(prerequisite.level),
|
||||
prerequisite.value.toString(),
|
||||
]
|
||||
.filter(isNotNullish)
|
||||
.join(" "),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import {
|
||||
BlessedTraditionPrerequisite,
|
||||
BlessedTraditionPrerequisiteRestriction,
|
||||
} from "optolith-database-schema/types/prerequisites/single/TraditionPrerequisite"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
const printValue = (
|
||||
locale: LocaleEnvironment,
|
||||
restriction: BlessedTraditionPrerequisiteRestriction | undefined,
|
||||
) => {
|
||||
switch (restriction) {
|
||||
case "Church":
|
||||
return locale.translate("Tradition ({0})", locale.translate("Church"))
|
||||
case "Shamanistic":
|
||||
return locale.translate("Tradition ({0})", locale.translate("Shaman"))
|
||||
case undefined:
|
||||
return locale.translate("Tradition")
|
||||
default:
|
||||
return assertExhaustive(restriction)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of a blessed tradition prerequisite.
|
||||
*/
|
||||
export const printBlessedTraditionPrerequisite = (
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: BlessedTraditionPrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
return {
|
||||
label: `${locale.translate("special ability")} `,
|
||||
value: printValue(locale, prerequisite.restriction),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
const printType = (
|
||||
locale: LocaleEnvironment,
|
||||
type: "advantage" | "disadvantage",
|
||||
): string => {
|
||||
switch (type) {
|
||||
case "advantage":
|
||||
return locale.translate("advantage")
|
||||
case "disadvantage":
|
||||
return locale.translate("disadvantage")
|
||||
default:
|
||||
return assertExhaustive(type)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of a culture prerequisite.
|
||||
*/
|
||||
export const printCommonSuggestedByRCPPrerequisite = (
|
||||
locale: LocaleEnvironment,
|
||||
_prerequisite: Record<string, never>,
|
||||
name: string,
|
||||
type: "advantage" | "disadvantage",
|
||||
): PrerequisitePart | undefined => ({
|
||||
value: locale.translate(
|
||||
"Race, culture, or profession must have {0} as an automatic or suggested {1}",
|
||||
name,
|
||||
printType(locale, type),
|
||||
),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
import { CulturePrerequisite } from "optolith-database-schema/types/prerequisites/single/CulturePrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a culture prerequisite.
|
||||
*/
|
||||
export const printCulturePrerequisite = (
|
||||
getCultureById: GetById.Static.Culture,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: CulturePrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
const culture = getCultureById(prerequisite.id.culture)
|
||||
const cultureTranslation = locale.translateMap(culture?.translations)
|
||||
|
||||
if (cultureTranslation === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
label: `${locale.translate("Culture")} `,
|
||||
value: cultureTranslation.name,
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { Enhancements } from "optolith-database-schema/types/_Enhancements"
|
||||
import { SkillWithEnhancementsIdentifier } from "optolith-database-schema/types/_IdentifierGroup"
|
||||
import { LocaleMap } from "optolith-database-schema/types/_LocaleMap"
|
||||
import {
|
||||
ExternalEnhancementPrerequisite,
|
||||
InternalEnhancementPrerequisite,
|
||||
} from "optolith-database-schema/types/prerequisites/single/EnhancementPrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
const printLabel = (
|
||||
locale: LocaleEnvironment,
|
||||
skillId: SkillWithEnhancementsIdentifier,
|
||||
): string => {
|
||||
switch (skillId.tag) {
|
||||
case "Spell":
|
||||
case "Ritual":
|
||||
return locale.translate("spell enhancement")
|
||||
case "LiturgicalChant":
|
||||
case "Ceremony":
|
||||
return locale.translate("liturgical enhancement")
|
||||
default:
|
||||
return assertExhaustive(skillId)
|
||||
}
|
||||
}
|
||||
|
||||
const getSkill = (
|
||||
getSpellById: GetById.Static.Spell,
|
||||
getRitualById: GetById.Static.Ritual,
|
||||
getLiturgicalChantById: GetById.Static.LiturgicalChant,
|
||||
getCeremonyById: GetById.Static.Ceremony,
|
||||
parentId: SkillWithEnhancementsIdentifier,
|
||||
):
|
||||
| { translations: LocaleMap<{ name: string }>; enhancements?: Enhancements }
|
||||
| undefined => {
|
||||
switch (parentId.tag) {
|
||||
case "Spell":
|
||||
return getSpellById(parentId.spell)
|
||||
case "Ritual":
|
||||
return getRitualById(parentId.ritual)
|
||||
case "LiturgicalChant":
|
||||
return getLiturgicalChantById(parentId.liturgical_chant)
|
||||
case "Ceremony":
|
||||
return getCeremonyById(parentId.ceremony)
|
||||
default:
|
||||
return assertExhaustive(parentId)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of an external enhancement prerequisite.
|
||||
*/
|
||||
export const printExternalEnhancementPrerequisite = (
|
||||
getSpellById: GetById.Static.Spell,
|
||||
getRitualById: GetById.Static.Ritual,
|
||||
getLiturgicalChantById: GetById.Static.LiturgicalChant,
|
||||
getCeremonyById: GetById.Static.Ceremony,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: ExternalEnhancementPrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
const skill = getSkill(
|
||||
getSpellById,
|
||||
getRitualById,
|
||||
getLiturgicalChantById,
|
||||
getCeremonyById,
|
||||
prerequisite.skill.id,
|
||||
)
|
||||
|
||||
const enhancement = skill?.enhancements?.find(
|
||||
e => e.id === prerequisite.enhancement.id,
|
||||
)
|
||||
|
||||
return {
|
||||
label: `${printLabel(locale, prerequisite.skill.id)} `,
|
||||
value: `*${
|
||||
locale.translateMap(enhancement?.translations)?.name
|
||||
}* ${locale.translate("for")} ${
|
||||
locale.translateMap(skill?.translations)?.name
|
||||
}`,
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of an internal enhancement prerequisite.
|
||||
*/
|
||||
export const printInternalEnhancementPrerequisite = (
|
||||
getSpellById: GetById.Static.Spell,
|
||||
getRitualById: GetById.Static.Ritual,
|
||||
getLiturgicalChantById: GetById.Static.LiturgicalChant,
|
||||
getCeremonyById: GetById.Static.Ceremony,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: InternalEnhancementPrerequisite,
|
||||
parentId: SkillWithEnhancementsIdentifier,
|
||||
): PrerequisitePart | undefined => {
|
||||
const skill = getSkill(
|
||||
getSpellById,
|
||||
getRitualById,
|
||||
getLiturgicalChantById,
|
||||
getCeremonyById,
|
||||
parentId,
|
||||
)
|
||||
|
||||
const enhancement = skill?.enhancements?.find(e => e.id === prerequisite.id)
|
||||
|
||||
return {
|
||||
label: `${printLabel(locale, parentId)} `,
|
||||
value: `*${locale.translateMap(enhancement?.translations)?.name}*`,
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { InfluencePrerequisite } from "optolith-database-schema/types/prerequisites/single/InfluencePrerequisite"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { MISSING_VALUE } from "../../unknown.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a culture prerequisite.
|
||||
*/
|
||||
export const printInfluencePrerequisite = (
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: InfluencePrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return {
|
||||
value: MISSING_VALUE,
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import {
|
||||
MagicalTraditionPrerequisite,
|
||||
MagicalTraditionPrerequisiteRestriction,
|
||||
} from "optolith-database-schema/types/prerequisites/single/TraditionPrerequisite"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
const printValue = (
|
||||
locale: LocaleEnvironment,
|
||||
restriction: MagicalTraditionPrerequisiteRestriction | undefined,
|
||||
) => {
|
||||
switch (restriction) {
|
||||
case "CanLearnRituals":
|
||||
return locale.translate(
|
||||
"Tradition must be able to use rituals",
|
||||
locale.translate("Church"),
|
||||
)
|
||||
case "CanBindFamiliars":
|
||||
return locale.translate(
|
||||
"Tradition must be able to bind familiars",
|
||||
locale.translate("Shaman"),
|
||||
)
|
||||
case undefined:
|
||||
return locale.translate("Tradition")
|
||||
default:
|
||||
return assertExhaustive(restriction)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of a magical tradition prerequisite.
|
||||
*/
|
||||
export const printMagicalTraditionPrerequisite = (
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: MagicalTraditionPrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
return {
|
||||
value: printValue(locale, prerequisite.restriction),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a culture prerequisite.
|
||||
*/
|
||||
export const printNoOtherAncestorBloodAdvantagePrerequisite = (
|
||||
locale: LocaleEnvironment,
|
||||
_prerequisite: Record<string, never>,
|
||||
): PrerequisitePart | undefined => ({
|
||||
value: locale.translate("no other ancestor blood advantage"),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
})
|
||||
@@ -0,0 +1,54 @@
|
||||
import { isNotNullish } from "@optolith/helpers/nullable"
|
||||
import { romanize } from "@optolith/helpers/roman"
|
||||
import { PactPrerequisite } from "optolith-database-schema/types/prerequisites/single/PactPrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { MISSING_VALUE } from "../../unknown.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a culture prerequisite.
|
||||
*/
|
||||
export const printPactPrerequisite = (
|
||||
getPactCategoryById: GetById.Static.PactCategory,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: PactPrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
const pactCategory = getPactCategoryById(
|
||||
prerequisite.category.id.pact_category,
|
||||
)
|
||||
|
||||
const parts = [
|
||||
prerequisite.domain_id === undefined
|
||||
? undefined
|
||||
: locale.translate(
|
||||
"domain {0}",
|
||||
locale.joinDisjunctionList(
|
||||
prerequisite.domain_id.map(
|
||||
ref =>
|
||||
locale.translateMap(
|
||||
pactCategory?.domains.find(
|
||||
domain => domain.id === ref.id.pact_domain,
|
||||
)?.translations,
|
||||
)?.name ?? MISSING_VALUE,
|
||||
),
|
||||
),
|
||||
),
|
||||
locale.translate(
|
||||
"{0} level {1}",
|
||||
locale.translateMap(pactCategory?.translations)?.name ?? MISSING_VALUE,
|
||||
romanize(prerequisite.level ?? 1),
|
||||
),
|
||||
].filter(isNotNullish)
|
||||
|
||||
return {
|
||||
value: parts.join(", "),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { PrimaryAttributePrerequisite } from "optolith-database-schema/types/prerequisites/single/PrimaryAttributePrerequisite"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a state prerequisite.
|
||||
*/
|
||||
export const printPrimaryAttributePrerequisite = (
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: PrimaryAttributePrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
return {
|
||||
label: `${locale.translate("Primary Attribute")} `,
|
||||
value: prerequisite.value.toString(),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { PublicationPrerequisite } from "optolith-database-schema/types/prerequisites/single/PublicationPrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a state prerequisite.
|
||||
*/
|
||||
export const printPublicationPrerequisite = (
|
||||
getPublicationById: GetById.Static.Publication,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: PublicationPrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
const publication = getPublicationById(prerequisite.id.publication)
|
||||
const publicationTranslation = locale.translateMap(publication?.translations)
|
||||
|
||||
if (publicationTranslation === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
value: publicationTranslation.name,
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { RacePrerequisite } from "optolith-database-schema/types/prerequisites/single/RacePrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a race prerequisite.
|
||||
*/
|
||||
export const printRacePrerequisite = (
|
||||
getRaceById: GetById.Static.Race,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: RacePrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
const race = getRaceById(prerequisite.id.race)
|
||||
const raceTranslation = locale.translateMap(race?.translations)
|
||||
|
||||
if (raceTranslation === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
label: `${locale.translate("Race")} `,
|
||||
value: raceTranslation.name,
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { RatedIdentifier } from "optolith-database-schema/types/_IdentifierGroup"
|
||||
import { RatedPrerequisite } from "optolith-database-schema/types/prerequisites/single/RatedPrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { MISSING_VALUE } from "../../unknown.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
const printRatedName = (
|
||||
getAttributeById: GetById.Static.Attribute,
|
||||
getSkillById: GetById.Static.Skill,
|
||||
getCloseCombatTechniqueById: GetById.Static.CloseCombatTechnique,
|
||||
getRangedCombatTechniqueById: GetById.Static.RangedCombatTechnique,
|
||||
getSpellById: GetById.Static.Spell,
|
||||
getRitualById: GetById.Static.Ritual,
|
||||
getLiturgicalChantById: GetById.Static.LiturgicalChant,
|
||||
getCeremonyById: GetById.Static.Ceremony,
|
||||
locale: LocaleEnvironment,
|
||||
id: RatedIdentifier,
|
||||
) => {
|
||||
switch (id.tag) {
|
||||
case "Attribute":
|
||||
return (
|
||||
locale.translateMap(getAttributeById(id.attribute)?.translations)
|
||||
?.name ?? MISSING_VALUE
|
||||
)
|
||||
case "Skill":
|
||||
return (
|
||||
locale.translateMap(getSkillById(id.skill)?.translations)?.name ??
|
||||
MISSING_VALUE
|
||||
)
|
||||
case "CloseCombatTechnique":
|
||||
return (
|
||||
locale.translateMap(
|
||||
getCloseCombatTechniqueById(id.close_combat_technique)?.translations,
|
||||
)?.name ?? MISSING_VALUE
|
||||
)
|
||||
case "RangedCombatTechnique":
|
||||
return (
|
||||
locale.translateMap(
|
||||
getRangedCombatTechniqueById(id.ranged_combat_technique)
|
||||
?.translations,
|
||||
)?.name ?? MISSING_VALUE
|
||||
)
|
||||
case "Spell":
|
||||
return (
|
||||
locale.translateMap(getSpellById(id.spell)?.translations)?.name ??
|
||||
MISSING_VALUE
|
||||
)
|
||||
case "Ritual":
|
||||
return (
|
||||
locale.translateMap(getRitualById(id.ritual)?.translations)?.name ??
|
||||
MISSING_VALUE
|
||||
)
|
||||
case "LiturgicalChant":
|
||||
return (
|
||||
locale.translateMap(
|
||||
getLiturgicalChantById(id.liturgical_chant)?.translations,
|
||||
)?.name ?? MISSING_VALUE
|
||||
)
|
||||
case "Ceremony":
|
||||
return (
|
||||
locale.translateMap(getCeremonyById(id.ceremony)?.translations)?.name ??
|
||||
MISSING_VALUE
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of a blessed tradition prerequisite.
|
||||
*/
|
||||
export const printRatedPrerequisite = (
|
||||
getAttributeById: GetById.Static.Attribute,
|
||||
getSkillById: GetById.Static.Skill,
|
||||
getCloseCombatTechniqueById: GetById.Static.CloseCombatTechnique,
|
||||
getRangedCombatTechniqueById: GetById.Static.RangedCombatTechnique,
|
||||
getSpellById: GetById.Static.Spell,
|
||||
getRitualById: GetById.Static.Ritual,
|
||||
getLiturgicalChantById: GetById.Static.LiturgicalChant,
|
||||
getCeremonyById: GetById.Static.Ceremony,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: RatedPrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
return {
|
||||
value: `${printRatedName(
|
||||
getAttributeById,
|
||||
getSkillById,
|
||||
getCloseCombatTechniqueById,
|
||||
getRangedCombatTechniqueById,
|
||||
getSpellById,
|
||||
getRitualById,
|
||||
getLiturgicalChantById,
|
||||
getCeremonyById,
|
||||
locale,
|
||||
prerequisite.id,
|
||||
)} ${prerequisite.value}`,
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
import { isNotNullish } from "@optolith/helpers/nullable"
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import {
|
||||
CombatTechniquesTargetGroup,
|
||||
RatedMinimumNumberPrerequisite,
|
||||
} from "optolith-database-schema/types/prerequisites/single/RatedMinimumNumberPrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { MISSING_VALUE } from "../../unknown.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
const printNumberOfTheFollowingSkills = (
|
||||
locale: LocaleEnvironment,
|
||||
number: number,
|
||||
): string => {
|
||||
switch (number) {
|
||||
case 1:
|
||||
return locale.translate("one of the following skills")
|
||||
case 2:
|
||||
return locale.translate("two of the following skills")
|
||||
case 3:
|
||||
return locale.translate("three of the following skills")
|
||||
case 4:
|
||||
return locale.translate("four of the following skills")
|
||||
case 5:
|
||||
return locale.translate("five of the following skills")
|
||||
case 6:
|
||||
return locale.translate("six of the following skills")
|
||||
case 7:
|
||||
return locale.translate("seven of the following skills")
|
||||
case 8:
|
||||
return locale.translate("eight of the following skills")
|
||||
case 9:
|
||||
return locale.translate("nine of the following skills")
|
||||
default:
|
||||
return locale.translate("{0} of the following skills")
|
||||
}
|
||||
}
|
||||
|
||||
const printNumberOfAllCombatTechniques = (
|
||||
locale: LocaleEnvironment,
|
||||
number: number,
|
||||
): string => {
|
||||
switch (number) {
|
||||
case 1:
|
||||
return locale.translate("one combat technique")
|
||||
case 2:
|
||||
return locale.translate("two combat techniques")
|
||||
case 3:
|
||||
return locale.translate("three combat techniques")
|
||||
case 4:
|
||||
return locale.translate("four combat techniques")
|
||||
case 5:
|
||||
return locale.translate("five combat techniques")
|
||||
case 6:
|
||||
return locale.translate("six combat techniques")
|
||||
case 7:
|
||||
return locale.translate("seven combat techniques")
|
||||
case 8:
|
||||
return locale.translate("eight combat techniques")
|
||||
case 9:
|
||||
return locale.translate("nine combat techniques")
|
||||
default:
|
||||
return locale.translate("{0} combat techniques")
|
||||
}
|
||||
}
|
||||
|
||||
const printNumberOfCloseCombatTechniques = (
|
||||
locale: LocaleEnvironment,
|
||||
number: number,
|
||||
): string => {
|
||||
switch (number) {
|
||||
case 1:
|
||||
return locale.translate("one close combat technique")
|
||||
case 2:
|
||||
return locale.translate("two close combat techniques")
|
||||
case 3:
|
||||
return locale.translate("three close combat techniques")
|
||||
case 4:
|
||||
return locale.translate("four close combat techniques")
|
||||
case 5:
|
||||
return locale.translate("five close combat techniques")
|
||||
case 6:
|
||||
return locale.translate("six close combat techniques")
|
||||
case 7:
|
||||
return locale.translate("seven close combat techniques")
|
||||
case 8:
|
||||
return locale.translate("eight close combat techniques")
|
||||
case 9:
|
||||
return locale.translate("nine close combat techniques")
|
||||
default:
|
||||
return locale.translate("{0} close combat techniques")
|
||||
}
|
||||
}
|
||||
|
||||
const printNumberOfRangedCombatTechniques = (
|
||||
locale: LocaleEnvironment,
|
||||
number: number,
|
||||
): string => {
|
||||
switch (number) {
|
||||
case 1:
|
||||
return locale.translate("one ranged combat technique")
|
||||
case 2:
|
||||
return locale.translate("two ranged combat techniques")
|
||||
case 3:
|
||||
return locale.translate("three ranged combat techniques")
|
||||
case 4:
|
||||
return locale.translate("four ranged combat techniques")
|
||||
case 5:
|
||||
return locale.translate("five ranged combat techniques")
|
||||
case 6:
|
||||
return locale.translate("six ranged combat techniques")
|
||||
case 7:
|
||||
return locale.translate("seven ranged combat techniques")
|
||||
case 8:
|
||||
return locale.translate("eight ranged combat techniques")
|
||||
case 9:
|
||||
return locale.translate("nine ranged combat techniques")
|
||||
default:
|
||||
return locale.translate("{0} ranged combat techniques")
|
||||
}
|
||||
}
|
||||
|
||||
const printNumberOfCombatTechniques = (
|
||||
locale: LocaleEnvironment,
|
||||
category: CombatTechniquesTargetGroup,
|
||||
number: number,
|
||||
): string => {
|
||||
switch (category) {
|
||||
case "All":
|
||||
return printNumberOfAllCombatTechniques(locale, number)
|
||||
case "Close":
|
||||
return printNumberOfCloseCombatTechniques(locale, number)
|
||||
case "Ranged":
|
||||
return printNumberOfRangedCombatTechniques(locale, number)
|
||||
default:
|
||||
return assertExhaustive(category)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of a rated minimum number prerequisite.
|
||||
*/
|
||||
export const printRatedMinimumNumberPrerequisite = (
|
||||
getSkillById: GetById.Static.Skill,
|
||||
getPropertyById: GetById.Static.Property,
|
||||
getAspectById: GetById.Static.Aspect,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: RatedMinimumNumberPrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
switch (prerequisite.targets.tag) {
|
||||
case "Skills": {
|
||||
const skills = prerequisite.targets.skills.list
|
||||
.map(
|
||||
ref =>
|
||||
locale.translateMap(getSkillById(ref.id.skill)?.translations)?.name,
|
||||
)
|
||||
.filter(isNotNullish)
|
||||
|
||||
return {
|
||||
value: locale.translate(
|
||||
"{0} on at least SR {1}: {2}", // zwei der folgenden Talente mindestens FW 10:
|
||||
printNumberOfTheFollowingSkills(locale, prerequisite.number),
|
||||
prerequisite.value,
|
||||
locale.joinConjunctionList(skills),
|
||||
),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
|
||||
case "CombatTechniques": {
|
||||
// de-DE: "Fernkampfwert 10"
|
||||
// en-US: "Ranged Combat 10"
|
||||
// nl-BE: "Schiet/werpwaarde 10"
|
||||
// fr-FR: "Ranged Combat 10"
|
||||
// it-IT: "Una tecnica di combattimento a distanza 10"
|
||||
|
||||
return {
|
||||
value: `${printNumberOfCombatTechniques(
|
||||
locale,
|
||||
prerequisite.targets.combat_techniques.group,
|
||||
prerequisite.number,
|
||||
)} ${prerequisite.value}`,
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
|
||||
case "Spellworks": {
|
||||
return {
|
||||
value: locale.translate(
|
||||
"{0} arcane works with the property {1} at SR {2} or higher",
|
||||
prerequisite.number,
|
||||
locale.translateMap(
|
||||
getPropertyById(prerequisite.targets.spellworks.id.property)
|
||||
?.translations,
|
||||
)?.name ?? MISSING_VALUE,
|
||||
prerequisite.value,
|
||||
),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
|
||||
case "Liturgies": {
|
||||
return {
|
||||
value: locale.translate(
|
||||
"{0} liturgical chants and ceremonies with the aspect {1} at SR {2} or higher",
|
||||
prerequisite.number,
|
||||
locale.translateMap(
|
||||
getAspectById(prerequisite.targets.liturgies.id.aspect)
|
||||
?.translations,
|
||||
)?.name ?? MISSING_VALUE,
|
||||
prerequisite.value,
|
||||
),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return assertExhaustive(prerequisite.targets)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { isNotNullish } from "@optolith/helpers/nullable"
|
||||
import { RatedSumPrerequisite } from "optolith-database-schema/types/prerequisites/single/RatedSumPrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a rated sum prerequisite.
|
||||
*/
|
||||
export const printRatedSumPrerequisite = (
|
||||
getSkillById: GetById.Static.Skill,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: RatedSumPrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
const skills = prerequisite.targets
|
||||
.map(
|
||||
target =>
|
||||
locale.translateMap(getSkillById(target.skill)?.translations)?.name,
|
||||
)
|
||||
.filter(isNotNullish)
|
||||
|
||||
return {
|
||||
value: locale.translate(
|
||||
"the SR for {0} combined must add up to at least {1}",
|
||||
locale.joinConjunctionList(skills),
|
||||
prerequisite.sum,
|
||||
),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { RulePrerequisite } from "optolith-database-schema/types/prerequisites/single/RulePrerequisite"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a rule prerequisite.
|
||||
*/
|
||||
export const printRulePrerequisite = (
|
||||
_locale: LocaleEnvironment,
|
||||
_prerequisite: RulePrerequisite,
|
||||
): PrerequisitePart | undefined => undefined
|
||||
@@ -0,0 +1,28 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { BinarySex } from "optolith-database-schema/types/_Sex"
|
||||
import { SexPrerequisite } from "optolith-database-schema/types/prerequisites/single/SexPrerequisite"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
const printId = (locale: LocaleEnvironment, id: BinarySex): string => {
|
||||
switch (id) {
|
||||
case "Male":
|
||||
return locale.translate("Male")
|
||||
case "Female":
|
||||
return locale.translate("Female")
|
||||
default:
|
||||
return assertExhaustive(id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of a (binary) sex prerequisite.
|
||||
*/
|
||||
export const printBinarySexPrerequisite = (
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: SexPrerequisite,
|
||||
): PrerequisitePart | undefined => ({
|
||||
value: printId(locale, prerequisite.id),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
})
|
||||
@@ -0,0 +1,33 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import {
|
||||
SexualCharacteristic,
|
||||
SexualCharacteristicPrerequisite,
|
||||
} from "optolith-database-schema/types/prerequisites/single/SexualCharacteristicPrerequisite"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
const printId = (
|
||||
locale: LocaleEnvironment,
|
||||
id: SexualCharacteristic,
|
||||
): string => {
|
||||
switch (id) {
|
||||
case "Penis":
|
||||
return locale.translate("Penis")
|
||||
case "Vagina":
|
||||
return locale.translate("Vagina")
|
||||
default:
|
||||
return assertExhaustive(id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of a sexual characteristic prerequisite.
|
||||
*/
|
||||
export const printSexualCharacteristicPrerequisite = (
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: SexualCharacteristicPrerequisite,
|
||||
): PrerequisitePart | undefined => ({
|
||||
value: locale.translate("Person with {0}", printId(locale, prerequisite.id)),
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
})
|
||||
@@ -0,0 +1,34 @@
|
||||
import { SocialStatusPrerequisite } from "optolith-database-schema/types/prerequisites/single/SocialStatusPrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a social status prerequisite.
|
||||
*/
|
||||
export const printSocialStatusPrerequisite = (
|
||||
getSocialStatusById: GetById.Static.SocialStatus,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: SocialStatusPrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
const socialStatus = getSocialStatusById(prerequisite.id.social_status)
|
||||
const socialStatusTranslation = locale.translateMap(
|
||||
socialStatus?.translations,
|
||||
)
|
||||
|
||||
if (socialStatusTranslation === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
label: `${locale.translate("Social Status {0} or higher")} `,
|
||||
value: `*${socialStatusTranslation.name}*`,
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { StatePrerequisite } from "optolith-database-schema/types/prerequisites/single/StatePrerequisite"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { printDisplayOption } from "../displayOption.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a state prerequisite.
|
||||
*/
|
||||
export const printStatePrerequisite = (
|
||||
getStateById: GetById.Static.State,
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: StatePrerequisite,
|
||||
): PrerequisitePart | undefined => {
|
||||
if (prerequisite.display_option !== undefined) {
|
||||
return printDisplayOption(locale, prerequisite.display_option)
|
||||
}
|
||||
|
||||
const state = getStateById(prerequisite.id.state)
|
||||
const stateTranslation = locale.translateMap(state?.translations)
|
||||
|
||||
if (stateTranslation === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
label: `${locale.translate("State")} `,
|
||||
value: `*${stateTranslation.name}*`,
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TextPrerequisite } from "optolith-database-schema/types/prerequisites/single/TextPrerequisite"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { MISSING_VALUE } from "../../unknown.js"
|
||||
import { PrerequisitePart } from "../part.js"
|
||||
|
||||
/**
|
||||
* Get the translation of a text prerequisite.
|
||||
*/
|
||||
export const printTextPrerequisite = (
|
||||
locale: LocaleEnvironment,
|
||||
prerequisite: TextPrerequisite,
|
||||
): PrerequisitePart => ({
|
||||
value: locale.translateMap(prerequisite.translations) ?? MISSING_VALUE,
|
||||
sentenceType: prerequisite.sentence_type,
|
||||
isMeta: prerequisite.is_meta ?? false,
|
||||
})
|
||||
@@ -1,7 +1,7 @@
|
||||
import { filterNonNullable } from "@optolith/helpers/array"
|
||||
import { mapNullable } from "@optolith/helpers/nullable"
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { Effect } from "optolith-database-schema/types/_ActivatableSkillEffect"
|
||||
import { ActivatableSkillEffect } from "optolith-database-schema/types/_ActivatableSkillEffect"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { EntityDescriptionSection } from "../../../../index.js"
|
||||
|
||||
@@ -34,7 +34,7 @@ const getContentPartsForQualityLevels = (
|
||||
*/
|
||||
export const getTextForEffect = (
|
||||
locale: LocaleEnvironment,
|
||||
effect: Effect,
|
||||
effect: ActivatableSkillEffect,
|
||||
): EntityDescriptionSection[] => {
|
||||
switch (effect.tag) {
|
||||
case "Plain":
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { mapNullable } from "@optolith/helpers/nullable"
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import {
|
||||
TargetCategory,
|
||||
TargetCategoryIdentifier,
|
||||
AffectedTargetCategories,
|
||||
SpecificAffectedTargetCategoryIdentifier,
|
||||
} from "optolith-database-schema/types/_ActivatableSkillTargetCategory"
|
||||
import { TargetCategoryReference } from "optolith-database-schema/types/_SimpleReferences"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
@@ -43,7 +43,7 @@ const getPredefinedTranslation = (
|
||||
const getTargetCategoryTranslationByType = (
|
||||
getTargetCategoryById: GetById.Static.TargetCategory,
|
||||
locale: LocaleEnvironment,
|
||||
id: TargetCategoryIdentifier,
|
||||
id: SpecificAffectedTargetCategoryIdentifier,
|
||||
) => {
|
||||
switch (id.tag) {
|
||||
case "Self":
|
||||
@@ -71,7 +71,7 @@ const getTargetCategoryTranslationByType = (
|
||||
export const getTargetCategoryTranslation = (
|
||||
getTargetCategoryById: GetById.Static.TargetCategory,
|
||||
locale: LocaleEnvironment,
|
||||
values: TargetCategory,
|
||||
values: AffectedTargetCategories,
|
||||
): EntityDescriptionSection => ({
|
||||
label: locale.translate("Target Category"),
|
||||
value:
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
// TODO: Update for new identifier mappings
|
||||
|
||||
/**
|
||||
* Used identifiers of optional rules.
|
||||
*/
|
||||
export enum OptionalRuleIdentifier {
|
||||
MaximumAttributeScores = 8,
|
||||
HigherDefenseStats = 17,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of races.
|
||||
*/
|
||||
export enum RaceIdentifier {
|
||||
Humans = 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of professions.
|
||||
*/
|
||||
export enum ProfessionIdentifier {
|
||||
OwnProfession = 0,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of eye colors.
|
||||
*/
|
||||
export enum EyeColorIdentifier {
|
||||
Red = 19,
|
||||
Purple = 20,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of hair colors.
|
||||
*/
|
||||
export enum HairColorIdentifier {
|
||||
White = 24,
|
||||
Green = 25,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of attributes.
|
||||
*/
|
||||
export enum AttributeIdentifier {
|
||||
Courage = 1,
|
||||
Sagacity = 2,
|
||||
Intuition = 3,
|
||||
Charisma = 4,
|
||||
Dexterity = 5,
|
||||
Agility = 6,
|
||||
Constitution = 7,
|
||||
Strength = 8,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of derived characteristics.
|
||||
*/
|
||||
export enum DerivedCharacteristicIdentifier {
|
||||
LifePoints = 1,
|
||||
ArcaneEnergy = 2,
|
||||
KarmaPoints = 3,
|
||||
Spirit = 4,
|
||||
Toughness = 5,
|
||||
Dodge = 6,
|
||||
Initiative = 7,
|
||||
Movement = 8,
|
||||
FatePoints = 9,
|
||||
WoundThreshold = 10,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of energies.
|
||||
*/
|
||||
export type EnergyIdentifier =
|
||||
| DerivedCharacteristicIdentifier.LifePoints
|
||||
| DerivedCharacteristicIdentifier.ArcaneEnergy
|
||||
| DerivedCharacteristicIdentifier.KarmaPoints
|
||||
|
||||
/**
|
||||
* Used identifiers of skill.
|
||||
*/
|
||||
export enum SkillIdentifier {
|
||||
Flying = 1,
|
||||
Gaukelei = 2,
|
||||
Climbing = 3,
|
||||
BodyControl = 4,
|
||||
FeatOfStrength = 5,
|
||||
Riding = 6,
|
||||
Swimming = 7,
|
||||
SelfControl = 8,
|
||||
Singing = 9,
|
||||
Perception = 10,
|
||||
Dancing = 11,
|
||||
Pickpocket = 12,
|
||||
Stealth = 13,
|
||||
Carousing = 14,
|
||||
Persuasion = 15,
|
||||
Seduction = 16,
|
||||
Intimidation = 17,
|
||||
Etiquette = 18,
|
||||
Streetwise = 19,
|
||||
Empathy = 20,
|
||||
FastTalk = 21,
|
||||
Disguise = 22,
|
||||
Willpower = 23,
|
||||
Tracking = 24,
|
||||
Ropes = 25,
|
||||
Fishing = 26,
|
||||
Orienting = 27,
|
||||
PlantLore = 28,
|
||||
AnimalLore = 29,
|
||||
Survival = 30,
|
||||
Gambling = 31,
|
||||
Geography = 32,
|
||||
History = 33,
|
||||
Religions = 34,
|
||||
Warfare = 35,
|
||||
MagicalLore = 36,
|
||||
Mechanics = 37,
|
||||
Math = 38,
|
||||
Law = 39,
|
||||
MythsAndLegends = 40,
|
||||
SphereLore = 41,
|
||||
Astronomy = 42,
|
||||
Alchemy = 43,
|
||||
Sailing = 44,
|
||||
Driving = 45,
|
||||
Commerce = 46,
|
||||
TreatPoison = 47,
|
||||
TreatDisease = 48,
|
||||
TreatSoul = 49,
|
||||
TreatWounds = 50,
|
||||
Woodworking = 51,
|
||||
PrepareFood = 52,
|
||||
Leatherworking = 53,
|
||||
ArtisticAbility = 54,
|
||||
Metalworking = 55,
|
||||
Music = 56,
|
||||
PickLocks = 57,
|
||||
Earthencraft = 58,
|
||||
Clothworking = 59,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of skill groups.
|
||||
*/
|
||||
export enum SkillGroupIdentifier {
|
||||
Physical = 1,
|
||||
Social = 2,
|
||||
Nature = 3,
|
||||
Knowledge = 4,
|
||||
Craft = 5,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of advantages.
|
||||
*/
|
||||
export enum AdvantageIdentifier {
|
||||
CustomAdvantage = 0,
|
||||
Aptitude = 4, // Begabung
|
||||
Nimble = 9, // Flink
|
||||
Blessed = 12,
|
||||
Luck = 14,
|
||||
ExceptionalSkill = 16,
|
||||
ExceptionalCombatTechnique = 17,
|
||||
IncreasedAstralPower = 20,
|
||||
IncreasedKarmaPoints = 21,
|
||||
IncreasedLifePoints = 22,
|
||||
IncreasedSpirit = 23,
|
||||
IncreasedToughness = 24,
|
||||
ImmunityToPoison = 25,
|
||||
ImmunityToDisease = 26,
|
||||
MagicalAttunement = 29,
|
||||
Rich = 33,
|
||||
SociallyAdaptable = 37,
|
||||
InspireConfidence = 43,
|
||||
WeaponAptitude = 44,
|
||||
Spellcaster = 47,
|
||||
Unyielding = 51, // Eisern
|
||||
HatredOf = 55,
|
||||
LargeSpellSelection = 66,
|
||||
LeichterGang = 85,
|
||||
Preacher = 91,
|
||||
Visionary = 92,
|
||||
ManySermons = 93,
|
||||
ManyVisions = 94,
|
||||
Einkommen = 129,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of disadvantages.
|
||||
*/
|
||||
export enum DisadvantageIdentifier {
|
||||
CustomDisadvantage = 0,
|
||||
AfraidOf = 1,
|
||||
Poor = 2,
|
||||
Slow = 4,
|
||||
NoFlyingBalm = 14,
|
||||
NoFamiliar = 15,
|
||||
MagicalRestriction = 21,
|
||||
DecreasedArcanePower = 23,
|
||||
DecreasedKarmaPoints = 24,
|
||||
DecreasedLifePoints = 25,
|
||||
DecreasedSpirit = 26,
|
||||
DecreasedToughness = 27,
|
||||
BadLuck = 28,
|
||||
PersonalityFlaw = 30,
|
||||
Principles = 31,
|
||||
BadHabit = 33,
|
||||
NegativeTrait = 34, // Schlechte Eigenschaft
|
||||
Stigma = 42,
|
||||
Deaf = 44, // Taub
|
||||
Incompetent = 45,
|
||||
Obligations = 47, // Verpflichtungen
|
||||
Maimed = 48, // Verstümmelt
|
||||
BrittleBones = 56, // Gläsern
|
||||
SmallSpellSelection = 64,
|
||||
FewerSermons = 70,
|
||||
FewerVisions = 71,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of ranged combat techniques.
|
||||
*/
|
||||
export enum RangedCombatTechniqueIdentifier {
|
||||
SpittingFire = 4,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of advanced skill special abilities.
|
||||
*/
|
||||
export enum AdvancedSkillSpecialAbilityIdentifier {
|
||||
Fachwissen = 2,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of combat special abilities.
|
||||
*/
|
||||
export enum CombatSpecialAbilityIdentifier {
|
||||
CombatReflexes = 12,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of general special abilities.
|
||||
*/
|
||||
export enum GeneralSpecialAbilityIdentifier {
|
||||
SkillSpecialization = 9,
|
||||
CraftInstruments = 17,
|
||||
Hunter = 18,
|
||||
Literacy = 27,
|
||||
Language = 29,
|
||||
LanguageSpecialization = 30,
|
||||
FireEater = 53,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of magical special abilities.
|
||||
*/
|
||||
export enum MagicalSpecialAbilityIdentifier {
|
||||
PropertyKnowledge = 3,
|
||||
GrosseMeditation = 12,
|
||||
Adaptation = 18,
|
||||
Imitationszauberei = 51,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of magical traditions.
|
||||
*/
|
||||
export enum MagicalTraditionIdentifier {
|
||||
GuildMages = 1,
|
||||
Witches = 2,
|
||||
Elves = 3,
|
||||
Unicorn = 4,
|
||||
Druids = 5,
|
||||
QabalyaMages = 6,
|
||||
IntuitiveMages = 7,
|
||||
Savants = 8,
|
||||
Illusionists = 9,
|
||||
ArcaneBards = 10,
|
||||
ArcaneDancers = 11,
|
||||
Schelme = 13,
|
||||
Zauberalchimisten = 14,
|
||||
TsatuariaAnhaengerinnen = 16,
|
||||
Necker = 17,
|
||||
Animisten = 18,
|
||||
Geoden = 19,
|
||||
Zibilijas = 20,
|
||||
BrobimGeoden = 21,
|
||||
Darna = 23,
|
||||
Runenschoepfer = 24,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of magical special abilities.
|
||||
*/
|
||||
export enum MagicStyleSpecialAbilityIdentifier {
|
||||
ScholarDesMagierkollegsZuHoningen = 24,
|
||||
MadaschwesternStil = 55,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of pact gifts.
|
||||
*/
|
||||
export enum PactGiftIdentifier {
|
||||
DunklesAbbildDerBuendnisgabe = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of aspects.
|
||||
*/
|
||||
export enum AspectIdentifier {
|
||||
General = 1,
|
||||
AllgemeinSchamanenritus = 44,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of karma special abilities.
|
||||
*/
|
||||
export enum KarmaSpecialAbilityIdentifier {
|
||||
AspectKnowledge = 1,
|
||||
MasterOfAspect = 5,
|
||||
HigherOrdination = 14,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of liturgical style special abilities.
|
||||
*/
|
||||
export enum LiturgicalStyleSpecialAbilityIdentifier {
|
||||
BirdsOfPassage = 38, // Zugvögel
|
||||
HuntressesOfTheWhiteMaiden = 40, // Jägerinnen der Weißen Maid
|
||||
FollowersOfTheGoldenOne = 47, // Anhänger des Güldenen
|
||||
}
|
||||
|
||||
/**
|
||||
* Used identifiers of blessed traditions.
|
||||
*/
|
||||
export enum BlessedTraditionIdentifier {
|
||||
Praios = 1,
|
||||
Phex = 5,
|
||||
Firun = 9,
|
||||
Rahja = 12,
|
||||
}
|
||||
@@ -9,4 +9,6 @@ export type LocaleEnvironment = {
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
compare: Compare<string>
|
||||
joinConjunctionList: (list: string[]) => string
|
||||
joinDisjunctionList: (list: string[]) => string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { describe, it } from "node:test"
|
||||
import {
|
||||
joinPrerequisiteParts,
|
||||
PrerequisitePart,
|
||||
} from "../../../../src/entities/partial/prerequisites/part.js"
|
||||
import { defaultLocaleEnvironment } from "../../../helpers/locale.js"
|
||||
|
||||
describe("joinPrerequisiteParts", () => {
|
||||
it("should join normal parts by comma", () => {
|
||||
const parts: PrerequisitePart[] = [
|
||||
{ value: "A", sentenceType: undefined, isMeta: false },
|
||||
{
|
||||
label: "Label for ",
|
||||
value: "B",
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
},
|
||||
{ value: "C", sentenceType: undefined, isMeta: false },
|
||||
]
|
||||
const result = joinPrerequisiteParts(defaultLocaleEnvironment, parts)
|
||||
assert.equal(result, "A, Label for B, C")
|
||||
})
|
||||
|
||||
it("should connect connected sentence types by semicolon", () => {
|
||||
const parts: PrerequisitePart[] = [
|
||||
{ value: "A", sentenceType: undefined, isMeta: false },
|
||||
{ value: "B", sentenceType: "Connected", isMeta: false },
|
||||
{ value: "C", sentenceType: "Connected", isMeta: false },
|
||||
{ value: "D", sentenceType: undefined, isMeta: false },
|
||||
{ value: "E", sentenceType: undefined, isMeta: false },
|
||||
{ value: "F", sentenceType: "Connected", isMeta: false },
|
||||
]
|
||||
const result = joinPrerequisiteParts(defaultLocaleEnvironment, parts)
|
||||
assert.equal(result, "A; B; C; D, E; F")
|
||||
})
|
||||
|
||||
it("should connect standalone sentence types by periods", () => {
|
||||
const parts: PrerequisitePart[] = [
|
||||
{ value: "A", sentenceType: undefined, isMeta: false },
|
||||
{ value: "B", sentenceType: "Standalone", isMeta: false },
|
||||
{ value: "C", sentenceType: "Standalone", isMeta: false },
|
||||
{ value: "D", sentenceType: undefined, isMeta: false },
|
||||
{ value: "E", sentenceType: undefined, isMeta: false },
|
||||
{ value: "F.", sentenceType: "Standalone", isMeta: false },
|
||||
{ value: "G.", sentenceType: "Standalone", isMeta: false },
|
||||
{ value: "H", sentenceType: undefined, isMeta: false },
|
||||
{ value: "I", sentenceType: undefined, isMeta: false },
|
||||
{ value: "J", sentenceType: "Standalone", isMeta: false },
|
||||
]
|
||||
const result = joinPrerequisiteParts(defaultLocaleEnvironment, parts)
|
||||
assert.equal(result, "A. B. C. D, E. F. G. H, I. J.")
|
||||
})
|
||||
|
||||
it("adds “none” at the beginning if all parts are declared as meta prerequisites", () => {
|
||||
const parts: PrerequisitePart[] = [
|
||||
{ value: "A", sentenceType: undefined, isMeta: true },
|
||||
{ value: "B", sentenceType: undefined, isMeta: true },
|
||||
{ value: "C", sentenceType: undefined, isMeta: true },
|
||||
]
|
||||
const result = joinPrerequisiteParts(defaultLocaleEnvironment, parts)
|
||||
assert.equal(result, "none, A, B, C")
|
||||
})
|
||||
|
||||
it("throws an error if the sentenceType is unknown", () => {
|
||||
const parts: PrerequisitePart[] = [
|
||||
// @ts-expect-error Testing invalid input
|
||||
{ value: "A", sentenceType: "any", isMeta: true },
|
||||
]
|
||||
const block = () => joinPrerequisiteParts(defaultLocaleEnvironment, parts)
|
||||
assert.throws(block)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,75 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { describe, it } from "node:test"
|
||||
import { printStatePrerequisite } from "../../../../../src/entities/partial/prerequisites/single/state.js"
|
||||
import { GetById } from "../../../../../src/helpers/getTypes.js"
|
||||
import { defaultLocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
|
||||
describe("getStatePrerequisiteTranslation", () => {
|
||||
it("returns a PrerequisitePart object for the prerequisite", () => {
|
||||
const getStateById: GetById.Static.State = () => ({
|
||||
id: 1,
|
||||
src: [],
|
||||
translations: {
|
||||
"en-US": {
|
||||
name: "A",
|
||||
description: "Description",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
assert.deepEqual(
|
||||
printStatePrerequisite(getStateById, defaultLocaleEnvironment, {
|
||||
id: {
|
||||
tag: "State",
|
||||
state: 1,
|
||||
},
|
||||
}),
|
||||
{
|
||||
label: "State ",
|
||||
value: "*A*",
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
},
|
||||
)
|
||||
|
||||
assert.deepEqual(
|
||||
printStatePrerequisite(
|
||||
() => ({
|
||||
id: 1,
|
||||
src: [],
|
||||
translations: {},
|
||||
}),
|
||||
defaultLocaleEnvironment,
|
||||
{
|
||||
id: {
|
||||
tag: "State",
|
||||
state: 1,
|
||||
},
|
||||
},
|
||||
),
|
||||
undefined,
|
||||
)
|
||||
|
||||
assert.deepEqual(
|
||||
printStatePrerequisite(getStateById, defaultLocaleEnvironment, {
|
||||
id: {
|
||||
tag: "State",
|
||||
state: 1,
|
||||
},
|
||||
display_option: {
|
||||
tag: "ReplaceWith",
|
||||
replace_with: {
|
||||
translations: {
|
||||
"en-US": "Replacement",
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
{
|
||||
value: "Replacement",
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,38 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { describe, it } from "node:test"
|
||||
import { printTextPrerequisite } from "../../../../../src/entities/partial/prerequisites/single/text.js"
|
||||
import { MISSING_VALUE } from "../../../../../src/entities/partial/unknown.js"
|
||||
import { defaultLocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
|
||||
describe("getTextPrerequisiteTranslation", () => {
|
||||
it("returns a PrerequisitePart object for the prerequisite", () => {
|
||||
assert.deepEqual(
|
||||
printTextPrerequisite(defaultLocaleEnvironment, {
|
||||
verification: "Pass",
|
||||
sentence_type: undefined,
|
||||
translations: {
|
||||
"en-US": "A",
|
||||
},
|
||||
}),
|
||||
{
|
||||
value: "A",
|
||||
sentenceType: undefined,
|
||||
isMeta: false,
|
||||
},
|
||||
)
|
||||
|
||||
assert.deepEqual(
|
||||
printTextPrerequisite(defaultLocaleEnvironment, {
|
||||
verification: "Pass",
|
||||
sentence_type: "Standalone",
|
||||
is_meta: true,
|
||||
translations: {},
|
||||
}),
|
||||
{
|
||||
value: MISSING_VALUE,
|
||||
sentenceType: "Standalone",
|
||||
isMeta: true,
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -1,7 +1,7 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { describe, it } from "node:test"
|
||||
import { getCheckResultBasedValueTranslation } from "../../../../../src/entities/partial/rated/activatable/checkResultBased.js"
|
||||
import { translateMock } from "../../../../../src/helpers/translate.js"
|
||||
import { translateMock } from "../../../../helpers/translate.js"
|
||||
|
||||
describe("getTextForCheckResultBased", () => {
|
||||
it("should return the value text for a check-result-based parameter of an activatable skill", () => {
|
||||
|
||||
Reference in New Issue
Block a user