refactor: restructure activatable skill partial helpers
This commit is contained in:
+1
-1
@@ -7,7 +7,7 @@
|
||||
"build": "tsc -b",
|
||||
"watch": "tsc -b -w",
|
||||
"release": "commit-and-tag-version",
|
||||
"test": "glob -c \"node --import tsx --test\" \"./src/**/*.test.ts\""
|
||||
"test": "glob -c \"node --import tsx --test\" \"./test/**/*.ts\""
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -13,17 +13,17 @@ import {
|
||||
createLibraryEntryCreator,
|
||||
LibraryEntryContent,
|
||||
} from "../libraryEntry.js"
|
||||
import { getTextForBlessingDuration } from "./partial/rated/activatable/duration.js"
|
||||
import { getDurationTranslationForBlessing } from "./partial/rated/activatable/duration.js"
|
||||
import { getTextForEffect } from "./partial/rated/activatable/effect.js"
|
||||
import { Entity } from "./partial/rated/activatable/entity.js"
|
||||
import {
|
||||
getTextForFastOneTimePerformanceParameters,
|
||||
getTextForFastSustainedPerformanceParameters,
|
||||
getTextForSlowOneTimePerformanceParameters,
|
||||
getTextForSlowSustainedPerformanceParameters,
|
||||
getFastOneTimePerformanceParametersTranslations,
|
||||
getFastSustainedPerformanceParametersTranslations,
|
||||
getSlowOneTimePerformanceParametersTranslations,
|
||||
getSlowSustainedPerformanceParametersTranslations,
|
||||
} from "./partial/rated/activatable/index.js"
|
||||
import { getTextForBlessingRange } from "./partial/rated/activatable/range.js"
|
||||
import { getTextForTargetCategory } from "./partial/rated/activatable/targetCategory.js"
|
||||
import { getTargetCategoryTranslation } from "./partial/rated/activatable/targetCategory.js"
|
||||
import { createImprovementCost } from "./partial/rated/improvementCost.js"
|
||||
import { getTextForCheck } from "./partial/rated/skillCheck.js"
|
||||
import { ResponsiveTextSize } from "./partial/responsiveText.js"
|
||||
@@ -92,23 +92,24 @@ export const getBlessingLibraryEntry = createLibraryEntryCreator<
|
||||
{
|
||||
getTargetCategoryById: GetById.Static.TargetCategory
|
||||
}
|
||||
>((entry, { getTargetCategoryById }) => ({ translate, translateMap }) => {
|
||||
>((entry, { getTargetCategoryById }) => (locale) => {
|
||||
const { translate, translateMap } = locale
|
||||
const translation = translateMap(entry.translations)
|
||||
|
||||
if (translation === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const range = getTextForBlessingRange({ translate }, entry.parameters.range, {
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
})
|
||||
const range = getTextForBlessingRange(
|
||||
locale,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.range
|
||||
)
|
||||
|
||||
const duration = getTextForBlessingDuration(
|
||||
{ translate, translateMap },
|
||||
entry.parameters.duration,
|
||||
{
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
const duration = getDurationTranslationForBlessing(
|
||||
locale,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.duration
|
||||
)
|
||||
|
||||
return {
|
||||
@@ -133,10 +134,7 @@ export const getBlessingLibraryEntry = createLibraryEntryCreator<
|
||||
? `***${duration}*** (${translation.duration})`
|
||||
: duration,
|
||||
},
|
||||
getTextForTargetCategory(
|
||||
{ translate, translateMap, getTargetCategoryById },
|
||||
entry.target
|
||||
),
|
||||
getTargetCategoryTranslation(getTargetCategoryById, locale, entry.target),
|
||||
],
|
||||
src: entry.src,
|
||||
}
|
||||
@@ -169,7 +167,8 @@ export const getLiturgicalChantLibraryEntry = createLibraryEntryCreator<
|
||||
getAspectById,
|
||||
}
|
||||
) =>
|
||||
({ translate, translateMap, localeCompare }) => {
|
||||
(locale) => {
|
||||
const { translate, translateMap, compare: localeCompare } = locale
|
||||
const translation = translateMap(entry.translations)
|
||||
|
||||
if (translation === undefined) {
|
||||
@@ -179,31 +178,21 @@ export const getLiturgicalChantLibraryEntry = createLibraryEntryCreator<
|
||||
const { castingTime, cost, range, duration } = (() => {
|
||||
switch (entry.parameters.tag) {
|
||||
case "OneTime":
|
||||
return getTextForFastOneTimePerformanceParameters(
|
||||
{
|
||||
getSkillModificationLevelById,
|
||||
translate,
|
||||
translateMap,
|
||||
},
|
||||
entry.parameters.one_time,
|
||||
{
|
||||
entity: Entity.LiturgicalChant,
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
return getFastOneTimePerformanceParametersTranslations(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Entity.LiturgicalChant,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.one_time
|
||||
)
|
||||
|
||||
case "Sustained":
|
||||
return getTextForFastSustainedPerformanceParameters(
|
||||
{
|
||||
getSkillModificationLevelById,
|
||||
translate,
|
||||
translateMap,
|
||||
},
|
||||
entry.parameters.sustained,
|
||||
{
|
||||
entity: Entity.LiturgicalChant,
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
return getFastSustainedPerformanceParametersTranslations(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Entity.LiturgicalChant,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.sustained
|
||||
)
|
||||
|
||||
default:
|
||||
@@ -225,7 +214,7 @@ export const getLiturgicalChantLibraryEntry = createLibraryEntryCreator<
|
||||
getToughness,
|
||||
}
|
||||
),
|
||||
...getTextForEffect(translation.effect, translate),
|
||||
...getTextForEffect(locale, translation.effect),
|
||||
{
|
||||
label: translate("Liturgical Time"),
|
||||
value:
|
||||
@@ -254,8 +243,9 @@ export const getLiturgicalChantLibraryEntry = createLibraryEntryCreator<
|
||||
? `***${duration}*** (${translation.duration.full})`
|
||||
: duration,
|
||||
},
|
||||
getTextForTargetCategory(
|
||||
{ translate, translateMap, getTargetCategoryById },
|
||||
getTargetCategoryTranslation(
|
||||
getTargetCategoryById,
|
||||
locale,
|
||||
entry.target
|
||||
),
|
||||
getTextForTraditions(
|
||||
@@ -302,7 +292,8 @@ export const getCeremonyLibraryEntry = createLibraryEntryCreator<
|
||||
getAspectById,
|
||||
}
|
||||
) =>
|
||||
({ translate, translateMap, localeCompare }) => {
|
||||
(locale) => {
|
||||
const { translate, translateMap, compare: localeCompare } = locale
|
||||
const translation = translateMap(entry.translations)
|
||||
|
||||
if (translation === undefined) {
|
||||
@@ -312,31 +303,21 @@ export const getCeremonyLibraryEntry = createLibraryEntryCreator<
|
||||
const { castingTime, cost, range, duration } = (() => {
|
||||
switch (entry.parameters.tag) {
|
||||
case "OneTime":
|
||||
return getTextForSlowOneTimePerformanceParameters(
|
||||
{
|
||||
getSkillModificationLevelById,
|
||||
translate,
|
||||
translateMap,
|
||||
},
|
||||
entry.parameters.one_time,
|
||||
{
|
||||
entity: Entity.Ceremony,
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
return getSlowOneTimePerformanceParametersTranslations(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Entity.Ritual,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.one_time
|
||||
)
|
||||
|
||||
case "Sustained":
|
||||
return getTextForSlowSustainedPerformanceParameters(
|
||||
{
|
||||
getSkillModificationLevelById,
|
||||
translate,
|
||||
translateMap,
|
||||
},
|
||||
entry.parameters.sustained,
|
||||
{
|
||||
entity: Entity.Ceremony,
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
return getSlowSustainedPerformanceParametersTranslations(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Entity.Ceremony,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.sustained
|
||||
)
|
||||
|
||||
default:
|
||||
@@ -358,7 +339,7 @@ export const getCeremonyLibraryEntry = createLibraryEntryCreator<
|
||||
getToughness,
|
||||
}
|
||||
),
|
||||
...getTextForEffect(translation.effect, translate),
|
||||
...getTextForEffect(locale, translation.effect),
|
||||
{
|
||||
label: translate("Ceremonial Time"),
|
||||
value:
|
||||
@@ -387,8 +368,9 @@ export const getCeremonyLibraryEntry = createLibraryEntryCreator<
|
||||
? `***${duration}*** (${translation.duration.full})`
|
||||
: duration,
|
||||
},
|
||||
getTextForTargetCategory(
|
||||
{ translate, translateMap, getTargetCategoryById },
|
||||
getTargetCategoryTranslation(
|
||||
getTargetCategoryById,
|
||||
locale,
|
||||
entry.target
|
||||
),
|
||||
getTextForTraditions(
|
||||
|
||||
@@ -3,6 +3,7 @@ import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import {
|
||||
CastingTime,
|
||||
CastingTimeDuringLovemaking,
|
||||
CastingTimeIncludingLovemaking,
|
||||
FastCastingTime,
|
||||
FastSkillNonModifiableCastingTime,
|
||||
ModifiableCastingTime,
|
||||
@@ -10,188 +11,179 @@ import {
|
||||
SlowSkillNonModifiableCastingTime,
|
||||
} from "optolith-database-schema/types/_ActivatableSkillCastingTime"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { Translate } from "../../../../helpers/translate.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { ResponsiveTextSize } from "../../responsiveText.js"
|
||||
import { formatTimeSpan } from "../../units/timeSpan.js"
|
||||
import { MISSING_VALUE } from "../../unknown.js"
|
||||
import { Entity } from "./entity.js"
|
||||
import { ModifiableParameter } from "./modifiableParameter.js"
|
||||
import { getTextForNonModifiableSuffix } from "./nonModifiable.js"
|
||||
import { Speed } from "./speed.js"
|
||||
import { formatTimeSpan } from "./units.js"
|
||||
import {
|
||||
getNonModifiableSuffixTranslation,
|
||||
ModifiableParameter,
|
||||
} from "./nonModifiableSuffix.js"
|
||||
import { getModifiableBySpeed, Speed } from "./speed.js"
|
||||
|
||||
const getTextForModifiableCastingTime = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
},
|
||||
value: ModifiableCastingTime,
|
||||
env: {
|
||||
speed: Speed
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
const getModifiableCastingTimeTranslation = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: ModifiableCastingTime
|
||||
): string =>
|
||||
mapNullable(
|
||||
deps.getSkillModificationLevelById(value.initial_modification_level),
|
||||
({
|
||||
fast: { casting_time: fastTime },
|
||||
slow: { casting_time: slowTime },
|
||||
}) => {
|
||||
switch (env.speed) {
|
||||
case Speed.Fast:
|
||||
return formatTimeSpan(
|
||||
deps.translate,
|
||||
env.responsiveText,
|
||||
getSkillModificationLevelById(value.initial_modification_level),
|
||||
(modificationLevel) =>
|
||||
getModifiableBySpeed(
|
||||
(config) =>
|
||||
formatTimeSpan(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
"Actions",
|
||||
fastTime
|
||||
)
|
||||
case Speed.Slow:
|
||||
return formatTimeSpan(
|
||||
deps.translate,
|
||||
env.responsiveText,
|
||||
slowTime.unit,
|
||||
slowTime.value
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(env.speed)
|
||||
}
|
||||
}
|
||||
config.casting_time
|
||||
),
|
||||
(config) =>
|
||||
formatTimeSpan(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
config.casting_time.unit,
|
||||
config.casting_time.value
|
||||
),
|
||||
speed,
|
||||
modificationLevel
|
||||
)
|
||||
) ?? MISSING_VALUE
|
||||
|
||||
const getTextForFastSkillNonModifiableCastingTime = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
},
|
||||
value: FastSkillNonModifiableCastingTime,
|
||||
env: {
|
||||
entity: Entity
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
const getFastSkillNonModifiableCastingTimeTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: FastSkillNonModifiableCastingTime
|
||||
): string =>
|
||||
formatTimeSpan(deps.translate, env.responsiveText, "Actions", value.actions) +
|
||||
getTextForNonModifiableSuffix(
|
||||
deps.translate,
|
||||
env.entity,
|
||||
ModifiableParameter.CastingTime,
|
||||
env.responsiveText
|
||||
)
|
||||
formatTimeSpan(locale, responsiveTextSize, "Actions", value.actions)
|
||||
|
||||
const getTextForSlowSkillNonModifiableCastingTime = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
},
|
||||
value: SlowSkillNonModifiableCastingTime,
|
||||
env: {
|
||||
entity: Entity
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
): string =>
|
||||
formatTimeSpan(deps.translate, env.responsiveText, value.unit, value.value) +
|
||||
getTextForNonModifiableSuffix(
|
||||
deps.translate,
|
||||
env.entity,
|
||||
ModifiableParameter.CastingTime,
|
||||
env.responsiveText
|
||||
)
|
||||
const getSlowSkillNonModifiableCastingTimeTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: SlowSkillNonModifiableCastingTime
|
||||
): string => formatTimeSpan(locale, responsiveTextSize, value.unit, value.value)
|
||||
|
||||
const getTextForCastingTime = <NonModifiable extends object>(
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
},
|
||||
value: CastingTime<NonModifiable>,
|
||||
env: {
|
||||
speed: Speed
|
||||
responsiveText: ResponsiveTextSize
|
||||
},
|
||||
getTextForNonModifiableCastingTime: (value: NonModifiable) => string
|
||||
const getCastingTimeTranslation = <NonModifiable extends object>(
|
||||
getNonModifiableCastingTimeTranslation: (value: NonModifiable) => string,
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: CastingTime<NonModifiable>
|
||||
): string => {
|
||||
switch (value.tag) {
|
||||
case "Modifiable":
|
||||
return getTextForModifiableCastingTime(deps, value.modifiable, env)
|
||||
return getModifiableCastingTimeTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
speed,
|
||||
responsiveTextSize,
|
||||
value.modifiable
|
||||
)
|
||||
case "NonModifiable":
|
||||
return getTextForNonModifiableCastingTime(value.non_modifiable)
|
||||
return (
|
||||
getNonModifiableCastingTimeTranslation(value.non_modifiable) +
|
||||
getNonModifiableSuffixTranslation(
|
||||
locale,
|
||||
entity,
|
||||
ModifiableParameter.CastingTime,
|
||||
responsiveTextSize
|
||||
)
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(value)
|
||||
}
|
||||
}
|
||||
|
||||
const getTextForCastingTimeDuringLovemaking = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
},
|
||||
value: CastingTimeDuringLovemaking,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
): string =>
|
||||
formatTimeSpan(deps.translate, env.responsiveText, value.unit, value.value)
|
||||
const getCastingTimeDuringLovemakingTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: CastingTimeDuringLovemaking
|
||||
): string => formatTimeSpan(locale, responsiveTextSize, value.unit, value.value)
|
||||
|
||||
const getCastingTimeIncludingLovemakingTranslation = <
|
||||
NonModifiable extends object
|
||||
>(
|
||||
getNonModifiableCastingTimeTranslation: (value: NonModifiable) => string,
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: CastingTimeIncludingLovemaking<NonModifiable>
|
||||
) =>
|
||||
[
|
||||
mapNullable(value.default, (def) =>
|
||||
getCastingTimeTranslation(
|
||||
getNonModifiableCastingTimeTranslation,
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
speed,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
def
|
||||
)
|
||||
),
|
||||
mapNullable(value.during_lovemaking, (duringLovemaking) =>
|
||||
getCastingTimeDuringLovemakingTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
duringLovemaking
|
||||
)
|
||||
),
|
||||
]
|
||||
.filter(isNotNullish)
|
||||
.join(" / ")
|
||||
|
||||
/**
|
||||
* Get the text for the casting time of a fast activatable skill.
|
||||
*/
|
||||
export const getTextForFastCastingTime = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
},
|
||||
value: FastCastingTime,
|
||||
env: {
|
||||
entity: Entity
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
export const getFastCastingTimeTranslation = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: FastCastingTime
|
||||
): string =>
|
||||
[
|
||||
mapNullable(value.default, (def) =>
|
||||
getTextForCastingTime(
|
||||
deps,
|
||||
def,
|
||||
{ ...env, speed: Speed.Fast },
|
||||
(nonModifiableValue) =>
|
||||
getTextForFastSkillNonModifiableCastingTime(
|
||||
deps,
|
||||
nonModifiableValue,
|
||||
env
|
||||
)
|
||||
)
|
||||
),
|
||||
mapNullable(value.during_lovemaking, (duringLovemaking) =>
|
||||
getTextForCastingTimeDuringLovemaking(deps, duringLovemaking, env)
|
||||
),
|
||||
]
|
||||
.filter(isNotNullish)
|
||||
.join(" / ")
|
||||
getCastingTimeIncludingLovemakingTranslation(
|
||||
(nonModifiableValue) =>
|
||||
getFastSkillNonModifiableCastingTimeTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
nonModifiableValue
|
||||
),
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Speed.Fast,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value
|
||||
)
|
||||
|
||||
/**
|
||||
* Get the text for the casting time of a slow activatable skill.
|
||||
*/
|
||||
export const getTextForSlowCastingTime = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
},
|
||||
value: SlowCastingTime,
|
||||
env: {
|
||||
entity: Entity
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
export const getSlowCastingTimeTranslation = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: SlowCastingTime
|
||||
): string =>
|
||||
[
|
||||
mapNullable(value.default, (def) =>
|
||||
getTextForCastingTime(
|
||||
deps,
|
||||
def,
|
||||
{ ...env, speed: Speed.Slow },
|
||||
(nonModifiableValue) =>
|
||||
getTextForSlowSkillNonModifiableCastingTime(
|
||||
deps,
|
||||
nonModifiableValue,
|
||||
env
|
||||
)
|
||||
)
|
||||
),
|
||||
mapNullable(value.during_lovemaking, (duringLovemaking) =>
|
||||
getTextForCastingTimeDuringLovemaking(deps, duringLovemaking, env)
|
||||
),
|
||||
]
|
||||
.filter(isNotNullish)
|
||||
.join(" / ")
|
||||
getCastingTimeIncludingLovemakingTranslation(
|
||||
(nonModifiableValue) =>
|
||||
getSlowSkillNonModifiableCastingTimeTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
nonModifiableValue
|
||||
),
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Speed.Slow,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value
|
||||
)
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { describe, it } from "node:test"
|
||||
import { translateMock } from "../../../../helpers/translate.js"
|
||||
import { getTextForCheckResultBased } from "./checkResultBased.js"
|
||||
|
||||
describe("getTextForCheckResultBased", () => {
|
||||
it("should return the value text for a check-result-based parameter of an activatable skill", () => {
|
||||
assert.equal(
|
||||
getTextForCheckResultBased({ base: "QualityLevels" }, translateMock),
|
||||
"QL"
|
||||
)
|
||||
assert.equal(
|
||||
getTextForCheckResultBased({ base: "SkillPoints" }, translateMock),
|
||||
"SP"
|
||||
)
|
||||
assert.equal(
|
||||
getTextForCheckResultBased(
|
||||
{ base: "QualityLevels", modifier: { arithmetic: "Divide", value: 2 } },
|
||||
translateMock
|
||||
),
|
||||
"QL / 2"
|
||||
)
|
||||
assert.equal(
|
||||
getTextForCheckResultBased(
|
||||
{ base: "SkillPoints", modifier: { arithmetic: "Multiply", value: 3 } },
|
||||
translateMock
|
||||
),
|
||||
"SP × 3"
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -7,9 +7,9 @@ import {
|
||||
} from "optolith-database-schema/types/_ActivatableSkillCheckResultBased"
|
||||
import { Translate } from "../../../../helpers/translate.js"
|
||||
|
||||
const getCheckResultBaseValue = (
|
||||
baseValue: CheckResultValue,
|
||||
translate: Translate
|
||||
const getCheckResultBaseValueTranslation = (
|
||||
translate: Translate,
|
||||
baseValue: CheckResultValue
|
||||
) => {
|
||||
switch (baseValue) {
|
||||
case "QualityLevels":
|
||||
@@ -36,11 +36,11 @@ const getArithmeticSymbol = (arithmetic: CheckResultArithmetic) => {
|
||||
* Returns the value text for a check-result-based parameter of an activatable
|
||||
* skill.
|
||||
*/
|
||||
export const getTextForCheckResultBased = (
|
||||
value: CheckResultBased,
|
||||
translate: Translate
|
||||
export const getCheckResultBasedValueTranslation = (
|
||||
translate: Translate,
|
||||
value: CheckResultBased
|
||||
): string =>
|
||||
getCheckResultBaseValue(value.base, translate) +
|
||||
getCheckResultBaseValueTranslation(translate, value.base) +
|
||||
mapNullableDefault(
|
||||
value.modifier,
|
||||
(modifier) => getArithmeticSymbol(modifier.arithmetic) + modifier.value,
|
||||
|
||||
@@ -4,247 +4,246 @@ import {
|
||||
CostMap,
|
||||
IndefiniteOneTimeCost,
|
||||
ModifiableOneTimeCost,
|
||||
ModifiableSustainedCost,
|
||||
MultipleOneTimeCosts,
|
||||
NonModifiableOneTimeCost,
|
||||
NonModifiableOneTimeCostPerCountable,
|
||||
NonModifiableSustainedCost,
|
||||
OneTimeCost,
|
||||
SingleOneTimeCost,
|
||||
SustainedCost,
|
||||
} from "optolith-database-schema/types/_ActivatableSkillCost"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { Translate, TranslateMap } from "../../../../helpers/translate.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import {
|
||||
appendNoteIfRequested,
|
||||
getResponsiveText,
|
||||
getResponsiveTextOptional,
|
||||
replaceTextIfRequested,
|
||||
responsive,
|
||||
ResponsiveTextSize,
|
||||
} from "../../responsiveText.js"
|
||||
import { formatEnergyByEntity } from "../../units/energy.js"
|
||||
import { formatTimeSpan } from "../../units/timeSpan.js"
|
||||
import { MISSING_VALUE } from "../../unknown.js"
|
||||
import { Entity } from "./entity.js"
|
||||
import { ModifiableParameter } from "./modifiableParameter.js"
|
||||
import { getTextForNonModifiableSuffix } from "./nonModifiable.js"
|
||||
import { wrapIfMinimum } from "./isMinimumMaximum.js"
|
||||
import {
|
||||
getNonModifiableSuffixTranslation,
|
||||
ModifiableParameter,
|
||||
} from "./nonModifiableSuffix.js"
|
||||
import { getModifiableBySpeed, Speed } from "./speed.js"
|
||||
import { formatCost, formatTimeSpan } from "./units.js"
|
||||
|
||||
const getTextForModifiableOneTimeCost = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: ModifiableOneTimeCost,
|
||||
env: {
|
||||
speed: Speed
|
||||
entity: Entity
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
const getModifiableOneTimeCostTranslation = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
entity: Entity,
|
||||
speed: Speed,
|
||||
value: ModifiableOneTimeCost
|
||||
): string =>
|
||||
mapNullable(
|
||||
deps.getSkillModificationLevelById(value.initial_modification_level),
|
||||
getSkillModificationLevelById(value.initial_modification_level),
|
||||
(modificationLevel) => {
|
||||
const cost = getModifiableBySpeed(
|
||||
modificationLevel,
|
||||
env.speed,
|
||||
(config) => config.cost,
|
||||
(config) => config.cost
|
||||
(config) => config.cost,
|
||||
speed,
|
||||
modificationLevel
|
||||
)
|
||||
|
||||
return replaceTextIfRequested(
|
||||
"replacement",
|
||||
value.translations,
|
||||
formatCost(deps.translate, env.entity, cost),
|
||||
deps.translateMap,
|
||||
env.responsiveText
|
||||
locale.translateMap,
|
||||
responsiveTextSize,
|
||||
formatEnergyByEntity(locale, entity, cost)
|
||||
)
|
||||
}
|
||||
) ?? MISSING_VALUE
|
||||
|
||||
const getMinimumText = (
|
||||
isMinimum: boolean | undefined,
|
||||
translate: Translate,
|
||||
responsiveText: ResponsiveTextSize
|
||||
) =>
|
||||
isMinimum !== true
|
||||
? ""
|
||||
: responsive(
|
||||
responsiveText,
|
||||
() => translate("at least "),
|
||||
() => translate("min. ")
|
||||
)
|
||||
|
||||
const getTextForNonModifiableOneTimeCostPerCountable = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
formatCost: (x: number | string) => string
|
||||
},
|
||||
value: NonModifiableOneTimeCostPerCountable | undefined,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
const getNonModifiableOneTimeCostPerCountableTranslation = (
|
||||
formatCost: (x: number | string) => string,
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: NonModifiableOneTimeCostPerCountable | undefined
|
||||
) =>
|
||||
mapNullable(value, (perCountable) => {
|
||||
const entity = getResponsiveText(
|
||||
locale.translateMap(perCountable.translations)?.countable,
|
||||
responsiveTextSize
|
||||
)
|
||||
|
||||
const countableText = responsive(
|
||||
env.responsiveText,
|
||||
(entity) => deps.translate(" per {0}", entity),
|
||||
(entity) => deps.translate("/{0}", entity),
|
||||
getResponsiveText(
|
||||
deps.translateMap(perCountable.translations)?.countable,
|
||||
env.responsiveText
|
||||
)
|
||||
responsiveTextSize,
|
||||
() => locale.translate(" per {0}", entity),
|
||||
() => locale.translate("/{0}", entity)
|
||||
)
|
||||
|
||||
const minimumTotalText =
|
||||
mapNullable(perCountable.minimum_total, (minimumTotal) =>
|
||||
deps.translate(", minimum of {0}", deps.formatCost(minimumTotal))
|
||||
locale.translate(", minimum of {0}", formatCost(minimumTotal))
|
||||
) ?? ""
|
||||
|
||||
return countableText + minimumTotalText
|
||||
}) ?? ""
|
||||
|
||||
const getTextForPermanentValue = (
|
||||
value: number | undefined,
|
||||
responsiveText: ResponsiveTextSize,
|
||||
translate: Translate
|
||||
const getPermanentValueTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
permanentValue: number | undefined
|
||||
) =>
|
||||
value === undefined
|
||||
permanentValue === undefined
|
||||
? ""
|
||||
: responsive(
|
||||
responsiveText,
|
||||
(perm) => translate(", {0} of which are permanent", perm),
|
||||
(perm) => translate(" ({0} perm.)", perm),
|
||||
value
|
||||
responsiveTextSize,
|
||||
() => locale.translate(", {0} of which are permanent", permanentValue),
|
||||
() => locale.translate(" ({0} perm.)", permanentValue)
|
||||
)
|
||||
|
||||
const getTextForNonModifiableOneTimeCost = (
|
||||
deps: { translate: Translate; translateMap: TranslateMap },
|
||||
value: NonModifiableOneTimeCost,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
entity: Entity
|
||||
}
|
||||
const getNonModifiableOneTimeCostTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: NonModifiableOneTimeCost
|
||||
): string => {
|
||||
const isMinimum = getMinimumText(
|
||||
const formatCostP = formatEnergyByEntity.bind(this, locale, entity)
|
||||
|
||||
const perCountable = getNonModifiableOneTimeCostPerCountableTranslation(
|
||||
formatCostP,
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.per
|
||||
)
|
||||
|
||||
const permanentValue = getPermanentValueTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.permanent_value
|
||||
)
|
||||
|
||||
const costWrappedIfMinimum = wrapIfMinimum(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.is_minimum,
|
||||
deps.translate,
|
||||
env.responsiveText
|
||||
)
|
||||
const formatCostP = formatCost.bind(this, deps.translate, env.entity)
|
||||
const per = getTextForNonModifiableOneTimeCostPerCountable(
|
||||
{ ...deps, formatCost: formatCostP },
|
||||
value.per,
|
||||
env
|
||||
)
|
||||
const permanent = getTextForPermanentValue(
|
||||
value.permanent_value,
|
||||
env.responsiveText,
|
||||
deps.translate
|
||||
)
|
||||
const translation = deps.translateMap(value.translations)
|
||||
const note = mapNullableDefault(
|
||||
translation === undefined || translation.note === undefined
|
||||
? undefined
|
||||
: getResponsiveTextOptional(translation.note, env.responsiveText),
|
||||
(noteIfPresent) => ` (${noteIfPresent})`,
|
||||
""
|
||||
formatCostP(value.value) + perCountable + permanentValue
|
||||
)
|
||||
|
||||
const cannotModify = getTextForNonModifiableSuffix(
|
||||
deps.translate,
|
||||
env.entity,
|
||||
const withNote = appendNoteIfRequested(
|
||||
"note",
|
||||
value.translations,
|
||||
locale.translateMap,
|
||||
responsiveTextSize,
|
||||
costWrappedIfMinimum
|
||||
)
|
||||
|
||||
const cannotModify = getNonModifiableSuffixTranslation(
|
||||
locale,
|
||||
entity,
|
||||
ModifiableParameter.Cost,
|
||||
env.responsiveText
|
||||
responsiveTextSize
|
||||
)
|
||||
|
||||
return (
|
||||
isMinimum + formatCostP(value.value) + per + permanent + note + cannotModify
|
||||
)
|
||||
return withNote + cannotModify
|
||||
}
|
||||
|
||||
const getTextForIndefiniteOneTimeCost = (
|
||||
deps: { translate: Translate; translateMap: TranslateMap },
|
||||
value: IndefiniteOneTimeCost,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
entity: Entity
|
||||
}
|
||||
const getIndefiniteOneTimeCostTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: IndefiniteOneTimeCost
|
||||
): string =>
|
||||
(getResponsiveText(
|
||||
deps.translateMap(value.translations)?.description,
|
||||
env.responsiveText
|
||||
) ?? "") +
|
||||
getTextForNonModifiableSuffix(
|
||||
deps.translate,
|
||||
env.entity,
|
||||
getResponsiveText(
|
||||
locale.translateMap(value.translations)?.description,
|
||||
responsiveTextSize
|
||||
) +
|
||||
getNonModifiableSuffixTranslation(
|
||||
locale,
|
||||
entity,
|
||||
ModifiableParameter.Cost,
|
||||
env.responsiveText
|
||||
responsiveTextSize
|
||||
)
|
||||
|
||||
const getTextForSingleOneTimeCost = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: SingleOneTimeCost,
|
||||
env: {
|
||||
speed: Speed
|
||||
responsiveText: ResponsiveTextSize
|
||||
entity: Entity
|
||||
}
|
||||
const getSingleOneTimeCostTranslation = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: SingleOneTimeCost
|
||||
): string => {
|
||||
switch (value.tag) {
|
||||
case "Modifiable":
|
||||
return getTextForModifiableOneTimeCost(deps, value.modifiable, env)
|
||||
return getModifiableOneTimeCostTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
entity,
|
||||
speed,
|
||||
value.modifiable
|
||||
)
|
||||
case "NonModifiable":
|
||||
return getTextForNonModifiableOneTimeCost(deps, value.non_modifiable, env)
|
||||
return getNonModifiableOneTimeCostTranslation(
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.non_modifiable
|
||||
)
|
||||
case "Indefinite":
|
||||
return getTextForIndefiniteOneTimeCost(deps, value.indefinite, env)
|
||||
return getIndefiniteOneTimeCostTranslation(
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.indefinite
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(value)
|
||||
}
|
||||
}
|
||||
|
||||
const getTextForMultipleOneTimeCosts = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: MultipleOneTimeCosts,
|
||||
const getMultipleOneTimeCostsTranslation = (
|
||||
type: "conjunction" | "disjunction",
|
||||
env: {
|
||||
speed: Speed
|
||||
responsiveText: ResponsiveTextSize
|
||||
entity: Entity
|
||||
}
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: MultipleOneTimeCosts
|
||||
): string => {
|
||||
const modifiable = !value.every((part) => part.tag === "Modifiable")
|
||||
? getTextForNonModifiableSuffix(
|
||||
deps.translate,
|
||||
env.entity,
|
||||
? getNonModifiableSuffixTranslation(
|
||||
locale,
|
||||
entity,
|
||||
ModifiableParameter.Cost,
|
||||
env.responsiveText
|
||||
responsiveTextSize
|
||||
)
|
||||
: ""
|
||||
|
||||
return (
|
||||
value
|
||||
.map((part) => getTextForSingleOneTimeCost(deps, part, env))
|
||||
.map((part) =>
|
||||
getSingleOneTimeCostTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
speed,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
part
|
||||
)
|
||||
)
|
||||
.join(
|
||||
(() => {
|
||||
switch (type) {
|
||||
case "conjunction":
|
||||
return responsive(
|
||||
env.responsiveText,
|
||||
() => deps.translate(" and "),
|
||||
() => deps.translate(" + ")
|
||||
responsiveTextSize,
|
||||
() => locale.translate(" and "),
|
||||
() => locale.translate(" + ")
|
||||
)
|
||||
case "disjunction":
|
||||
return responsive(
|
||||
env.responsiveText,
|
||||
() => deps.translate(" or "),
|
||||
() => deps.translate(" / ")
|
||||
responsiveTextSize,
|
||||
() => locale.translate(" or "),
|
||||
() => locale.translate(" / ")
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(type)
|
||||
@@ -254,18 +253,13 @@ const getTextForMultipleOneTimeCosts = (
|
||||
)
|
||||
}
|
||||
|
||||
const getTextForCostMap = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: CostMap,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
entity: Entity
|
||||
}
|
||||
const getCostMapTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: CostMap
|
||||
): string => {
|
||||
const translation = deps.translateMap(value.translations)
|
||||
const translation = locale.translateMap(value.translations)
|
||||
|
||||
if (value.translations !== undefined && translation === undefined) {
|
||||
return MISSING_VALUE
|
||||
@@ -275,29 +269,33 @@ const getTextForCostMap = (
|
||||
return translation.replacement
|
||||
}
|
||||
|
||||
const costs = value.options.map((option) => option.value).join("/")
|
||||
const labels = value.options
|
||||
.map(
|
||||
(option) => deps.translateMap(option.translations)?.label ?? MISSING_VALUE
|
||||
(option) =>
|
||||
locale.translateMap(option.translations)?.label ?? MISSING_VALUE
|
||||
)
|
||||
.join("/")
|
||||
|
||||
const costs = value.options.map((option) => option.value).join("/")
|
||||
|
||||
const permanentCosts = value.options.every(
|
||||
(option) => option.permanent_value !== undefined
|
||||
)
|
||||
? value.options.map((option) => option.permanent_value!).join("/")
|
||||
: undefined
|
||||
|
||||
const formatCostP = formatCost.bind(this, deps.translate, env.entity)
|
||||
const notModifiable = getTextForNonModifiableSuffix(
|
||||
deps.translate,
|
||||
env.entity,
|
||||
const formatCostP = formatEnergyByEntity.bind(this, locale, entity)
|
||||
|
||||
const notModifiable = getNonModifiableSuffixTranslation(
|
||||
locale,
|
||||
entity,
|
||||
ModifiableParameter.Cost,
|
||||
env.responsiveText
|
||||
responsiveTextSize
|
||||
)
|
||||
|
||||
return (
|
||||
formatCostP(costs) +
|
||||
deps.translate(" for ") +
|
||||
locale.translate(" for ") +
|
||||
mapNullableDefault(
|
||||
translation?.list_prepend,
|
||||
(listPrepend) => `${listPrepend} `,
|
||||
@@ -306,7 +304,7 @@ const getTextForCostMap = (
|
||||
labels +
|
||||
(translation?.list_append ?? "") +
|
||||
(permanentCosts !== undefined
|
||||
? deps.translate(
|
||||
? locale.translate(
|
||||
", {0} of which are permanent",
|
||||
formatCostP(permanentCosts)
|
||||
)
|
||||
@@ -318,172 +316,203 @@ const getTextForCostMap = (
|
||||
/**
|
||||
* Returns the text for the cost of a one-time activatable skill.
|
||||
*/
|
||||
export const getTextForOneTimeCost = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: OneTimeCost,
|
||||
env: {
|
||||
speed: Speed
|
||||
responsiveText: ResponsiveTextSize
|
||||
entity: Entity
|
||||
}
|
||||
export const getOneTimeCostTranslation = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: OneTimeCost
|
||||
): string => {
|
||||
switch (value.tag) {
|
||||
case "Single":
|
||||
return getTextForSingleOneTimeCost(deps, value.single, env)
|
||||
return getSingleOneTimeCostTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
speed,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.single
|
||||
)
|
||||
case "Conjunction":
|
||||
return getTextForMultipleOneTimeCosts(
|
||||
deps,
|
||||
value.conjunction,
|
||||
return getMultipleOneTimeCostsTranslation(
|
||||
"conjunction",
|
||||
env
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
speed,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.conjunction
|
||||
)
|
||||
case "Disjunction":
|
||||
return getTextForMultipleOneTimeCosts(
|
||||
deps,
|
||||
value.disjunction,
|
||||
return getMultipleOneTimeCostsTranslation(
|
||||
"disjunction",
|
||||
env
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
speed,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.disjunction
|
||||
)
|
||||
case "Map":
|
||||
return getTextForCostMap(deps, value.map, env)
|
||||
return getCostMapTranslation(
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.map
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(value)
|
||||
}
|
||||
}
|
||||
|
||||
const getModifiableSustainedCostTranslation = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: ModifiableSustainedCost
|
||||
) =>
|
||||
mapNullable(
|
||||
getSkillModificationLevelById(value.initial_modification_level),
|
||||
(modificationLevel) => {
|
||||
const cost = getModifiableBySpeed(
|
||||
(config) => config.cost,
|
||||
(config) => config.cost,
|
||||
speed,
|
||||
modificationLevel
|
||||
)
|
||||
|
||||
const formatCostP = formatEnergyByEntity.bind(this, locale, entity)
|
||||
|
||||
const interval = formatTimeSpan(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.interval.unit,
|
||||
value.interval.value
|
||||
)
|
||||
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() =>
|
||||
`${formatCostP(cost) + locale.translate(" (casting)")} + ${
|
||||
formatCostP(cost / 2) + locale.translate(" per {0}", interval)
|
||||
}`,
|
||||
() =>
|
||||
`${formatCostP(cost)} + ${
|
||||
formatCostP(cost / 2) + locale.translate("/{0}", interval)
|
||||
}`
|
||||
)
|
||||
}
|
||||
) ?? MISSING_VALUE
|
||||
|
||||
const getNonModifiableSustainedCostTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: NonModifiableSustainedCost
|
||||
) => {
|
||||
const formatCostP = formatEnergyByEntity.bind(this, locale, entity)
|
||||
|
||||
const per = (() => {
|
||||
if (value.per === undefined) {
|
||||
return { countable: "", minimumTotal: "" }
|
||||
}
|
||||
|
||||
const countable = responsive(
|
||||
responsiveTextSize,
|
||||
(entity) => locale.translate(" per {0}", entity),
|
||||
(entity) => locale.translate("/{0}", entity),
|
||||
getResponsiveText(
|
||||
locale.translateMap(value.per.translations)?.countable,
|
||||
responsiveTextSize
|
||||
)
|
||||
)
|
||||
|
||||
const minimumTotal =
|
||||
value.per.minimum_total !== undefined
|
||||
? locale.translate(
|
||||
", minimum of {0}",
|
||||
formatCostP(value.per.minimum_total)
|
||||
)
|
||||
: ""
|
||||
|
||||
return { countable, minimumTotal }
|
||||
})()
|
||||
|
||||
const interval = formatTimeSpan(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.interval.unit,
|
||||
value.interval.value
|
||||
)
|
||||
|
||||
const cost =
|
||||
responsive(
|
||||
responsiveTextSize,
|
||||
() =>
|
||||
`${formatCostP(value.value) + locale.translate(" (casting)")} + ${
|
||||
(value.is_minimum === true
|
||||
? locale.translate("half of the activation cost")
|
||||
: formatCostP(value.value / 2)) +
|
||||
per.countable +
|
||||
locale.translate(" per {0}", interval)
|
||||
}`,
|
||||
() =>
|
||||
`${formatCostP(value.value)} + ${
|
||||
(value.is_minimum === true ? "50%" : formatCostP(value.value / 2)) +
|
||||
per.countable +
|
||||
locale.translate("/{0}", interval)
|
||||
}`
|
||||
) + per.minimumTotal
|
||||
|
||||
const costWrappedIfMinimum = wrapIfMinimum(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.is_minimum,
|
||||
cost
|
||||
)
|
||||
|
||||
return (
|
||||
costWrappedIfMinimum +
|
||||
getNonModifiableSuffixTranslation(
|
||||
locale,
|
||||
entity,
|
||||
ModifiableParameter.Cost,
|
||||
responsiveTextSize
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text for the cost of a sustained activatable skill.
|
||||
*/
|
||||
export const getTextForSustainedCost = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: SustainedCost,
|
||||
env: {
|
||||
speed: Speed
|
||||
responsiveText: ResponsiveTextSize
|
||||
entity: Entity
|
||||
}
|
||||
export const getSustainedCostTranslation = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: SustainedCost
|
||||
): string => {
|
||||
switch (value.tag) {
|
||||
case "Modifiable": {
|
||||
const modificationLevel = deps.getSkillModificationLevelById(
|
||||
value.modifiable.initial_modification_level
|
||||
case "Modifiable":
|
||||
return getModifiableSustainedCostTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
speed,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.modifiable
|
||||
)
|
||||
|
||||
if (modificationLevel === undefined) {
|
||||
return MISSING_VALUE
|
||||
}
|
||||
|
||||
const cost = (() => {
|
||||
switch (env.speed) {
|
||||
case Speed.Fast:
|
||||
return modificationLevel.fast.cost
|
||||
case Speed.Slow:
|
||||
return modificationLevel.slow.cost
|
||||
default:
|
||||
return assertExhaustive(env.speed)
|
||||
}
|
||||
})()
|
||||
|
||||
const formatCostP = formatCost.bind(this, deps.translate, env.entity)
|
||||
const interval = formatTimeSpan(
|
||||
deps.translate,
|
||||
env.responsiveText,
|
||||
value.modifiable.interval.unit,
|
||||
value.modifiable.interval.value
|
||||
case "NonModifiable":
|
||||
return getNonModifiableSustainedCostTranslation(
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.non_modifiable
|
||||
)
|
||||
|
||||
return responsive(
|
||||
env.responsiveText,
|
||||
() =>
|
||||
`${formatCostP(cost) + deps.translate(" (casting)")} + ${
|
||||
formatCostP(cost / 2) + deps.translate(" per {0}", interval)
|
||||
}`,
|
||||
() =>
|
||||
`${formatCostP(cost)} + ${
|
||||
formatCostP(cost / 2) + deps.translate("/{0}", interval)
|
||||
}`
|
||||
)
|
||||
}
|
||||
case "NonModifiable": {
|
||||
const isMinimum = getMinimumText(
|
||||
value.non_modifiable.is_minimum,
|
||||
deps.translate,
|
||||
env.responsiveText
|
||||
)
|
||||
const cost = value.non_modifiable.value
|
||||
const formatCostP = formatCost.bind(this, deps.translate, env.entity)
|
||||
|
||||
const per = (() => {
|
||||
if (value.non_modifiable.per === undefined) {
|
||||
return { countable: "", minimumTotal: "" }
|
||||
}
|
||||
|
||||
const countable = responsive(
|
||||
env.responsiveText,
|
||||
(entity) => deps.translate(" per {0}", entity),
|
||||
(entity) => deps.translate("/{0}", entity),
|
||||
getResponsiveText(
|
||||
deps.translateMap(value.non_modifiable.per.translations)?.countable,
|
||||
env.responsiveText
|
||||
)
|
||||
)
|
||||
|
||||
const minimumTotal =
|
||||
value.non_modifiable.per.minimum_total !== undefined
|
||||
? deps.translate(
|
||||
", minimum of {0}",
|
||||
formatCostP(value.non_modifiable.per.minimum_total)
|
||||
)
|
||||
: ""
|
||||
|
||||
return { countable, minimumTotal }
|
||||
})()
|
||||
|
||||
const interval = formatTimeSpan(
|
||||
deps.translate,
|
||||
env.responsiveText,
|
||||
value.non_modifiable.interval.unit,
|
||||
value.non_modifiable.interval.value
|
||||
)
|
||||
|
||||
return (
|
||||
isMinimum +
|
||||
responsive(
|
||||
env.responsiveText,
|
||||
() =>
|
||||
`${formatCostP(cost) + deps.translate(" (casting)")} + ${
|
||||
(value.non_modifiable.is_minimum === true
|
||||
? deps.translate("half of the activation cost")
|
||||
: formatCostP(cost / 2)) +
|
||||
per.countable +
|
||||
deps.translate(" per {0}", interval)
|
||||
}`,
|
||||
() =>
|
||||
`${formatCostP(cost)} + ${
|
||||
(value.non_modifiable.is_minimum === true
|
||||
? "50%"
|
||||
: formatCostP(cost / 2)) +
|
||||
per.countable +
|
||||
deps.translate("/{0}", interval)
|
||||
}`
|
||||
) +
|
||||
per.minimumTotal +
|
||||
getTextForNonModifiableSuffix(
|
||||
deps.translate,
|
||||
env.entity,
|
||||
ModifiableParameter.Cost,
|
||||
env.responsiveText
|
||||
)
|
||||
)
|
||||
}
|
||||
default:
|
||||
return assertExhaustive(value)
|
||||
}
|
||||
|
||||
@@ -1,176 +1,165 @@
|
||||
import { mapNullableDefault } from "@optolith/helpers/nullable"
|
||||
import { mapNullable } from "@optolith/helpers/nullable"
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { CastingTimeDuringLovemaking } from "optolith-database-schema/types/_ActivatableSkillCastingTime"
|
||||
import {
|
||||
CheckResultBasedDuration,
|
||||
DurationForOneTime,
|
||||
DurationForSustained,
|
||||
FixedDuration,
|
||||
Immediate,
|
||||
IndefiniteDuration,
|
||||
PermanentDuration,
|
||||
} from "optolith-database-schema/types/_ActivatableSkillDuration"
|
||||
import { BlessingDuration } from "optolith-database-schema/types/Blessing"
|
||||
import { CantripDuration } from "optolith-database-schema/types/Cantrip"
|
||||
import { Translate, TranslateMap } from "../../../../helpers/translate.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import {
|
||||
getResponsiveText,
|
||||
replaceTextIfRequested,
|
||||
responsive,
|
||||
ResponsiveTextSize,
|
||||
} from "../../responsiveText.js"
|
||||
import { getTextForCheckResultBased } from "./checkResultBased.js"
|
||||
import { getTextForIsMaximum } from "./isMaximum.js"
|
||||
import { formatTimeSpan } from "./units.js"
|
||||
import { formatTimeSpan } from "../../units/timeSpan.js"
|
||||
import { getCheckResultBasedValueTranslation } from "./checkResultBased.js"
|
||||
import { wrapAsMaximum, wrapIfMaximum } from "./isMinimumMaximum.js"
|
||||
import { appendInParensIfNotEmpty } from "./parensIf.js"
|
||||
|
||||
const getTextForImmediateDuration = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: Immediate,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
const getImmediateDurationTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: Immediate
|
||||
): string => {
|
||||
const text =
|
||||
deps.translate("Immediate") +
|
||||
mapNullableDefault(
|
||||
value.maximum,
|
||||
(max) => {
|
||||
const maxText = formatTimeSpan(
|
||||
deps.translate,
|
||||
env.responsiveText,
|
||||
max.unit,
|
||||
max.value
|
||||
)
|
||||
const text = appendInParensIfNotEmpty(
|
||||
mapNullable(value.maximum, (max) => {
|
||||
const maxText = formatTimeSpan(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
max.unit,
|
||||
max.value
|
||||
)
|
||||
|
||||
return responsive(
|
||||
env.responsiveText,
|
||||
() => deps.translate(" (no more than {0})", maxText),
|
||||
() => deps.translate(" (max. {0})", maxText)
|
||||
)
|
||||
},
|
||||
""
|
||||
)
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => locale.translate("no more than {0}", maxText),
|
||||
() => locale.translate("max. {0}", maxText)
|
||||
)
|
||||
}),
|
||||
locale.translate("Immediate")
|
||||
)
|
||||
|
||||
return replaceTextIfRequested(
|
||||
"replacement",
|
||||
value.translations,
|
||||
text,
|
||||
deps.translateMap,
|
||||
env.responsiveText
|
||||
locale.translateMap,
|
||||
responsiveTextSize,
|
||||
text
|
||||
)
|
||||
}
|
||||
|
||||
const getTextForPermanentDuration = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: PermanentDuration,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
): string => {
|
||||
const translation = deps.translateMap(value.translations)
|
||||
const text = deps.translate("Permanent")
|
||||
|
||||
if (translation?.replacement !== undefined) {
|
||||
return getResponsiveText(
|
||||
translation.replacement,
|
||||
env.responsiveText
|
||||
).replace("$1", text)
|
||||
} else {
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
const getTextForFixedDuration = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: FixedDuration,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
): string => {
|
||||
const isMaximum = getTextForIsMaximum(
|
||||
value.is_maximum,
|
||||
deps.translate,
|
||||
env.responsiveText
|
||||
const getPermanentDurationTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: PermanentDuration
|
||||
): string =>
|
||||
replaceTextIfRequested(
|
||||
"replacement",
|
||||
value.translations,
|
||||
locale.translateMap,
|
||||
responsiveTextSize,
|
||||
locale.translate("Permanent")
|
||||
)
|
||||
const unitValue = formatTimeSpan(
|
||||
deps.translate,
|
||||
env.responsiveText,
|
||||
|
||||
const getFixedDurationTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: FixedDuration
|
||||
): string => {
|
||||
const duration = formatTimeSpan(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.unit,
|
||||
value.value
|
||||
)
|
||||
const text = isMaximum + unitValue
|
||||
const translation = deps.translateMap(value.translations)
|
||||
|
||||
if (translation?.replacement !== undefined) {
|
||||
return getResponsiveText(
|
||||
translation.replacement,
|
||||
env.responsiveText
|
||||
).replace("$1", text)
|
||||
} else {
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
const getTextForCheckResultBasedDuration = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: CheckResultBasedDuration,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
): string => {
|
||||
const isMaximum = getTextForIsMaximum(
|
||||
const durationWrappedIfMaximum = wrapIfMaximum(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.is_maximum,
|
||||
deps.translate,
|
||||
env.responsiveText
|
||||
duration
|
||||
)
|
||||
|
||||
return formatTimeSpan(
|
||||
deps.translate,
|
||||
env.responsiveText,
|
||||
value.unit,
|
||||
isMaximum + getTextForCheckResultBased(value, deps.translate)
|
||||
return replaceTextIfRequested(
|
||||
"replacement",
|
||||
value.translations,
|
||||
locale.translateMap,
|
||||
responsiveTextSize,
|
||||
durationWrappedIfMaximum
|
||||
)
|
||||
}
|
||||
|
||||
const getCheckResultBasedDurationTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: CheckResultBasedDuration
|
||||
): string => {
|
||||
const duration = formatTimeSpan(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.unit,
|
||||
getCheckResultBasedValueTranslation(locale.translate, value)
|
||||
)
|
||||
|
||||
return wrapIfMaximum(locale, responsiveTextSize, value.is_maximum, duration)
|
||||
}
|
||||
|
||||
const getIndefiniteDurationTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: IndefiniteDuration
|
||||
) =>
|
||||
getResponsiveText(
|
||||
locale.translateMap(value.translations)?.description,
|
||||
responsiveTextSize
|
||||
)
|
||||
|
||||
/**
|
||||
* Returns the text for the duration of a one-time activatable skill.
|
||||
*/
|
||||
export const getTextForDurationForOneTime = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: DurationForOneTime,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
export const getDurationForOneTimeTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: DurationForOneTime
|
||||
): string => {
|
||||
switch (value.tag) {
|
||||
case "Immediate":
|
||||
return getTextForImmediateDuration(deps, value.immediate, env)
|
||||
return getImmediateDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.immediate
|
||||
)
|
||||
case "Permanent":
|
||||
return getTextForPermanentDuration(deps, value.permanent, env)
|
||||
return getPermanentDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.permanent
|
||||
)
|
||||
case "Fixed":
|
||||
return getTextForFixedDuration(deps, value.fixed, env)
|
||||
return getFixedDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.fixed
|
||||
)
|
||||
case "CheckResultBased":
|
||||
return getTextForCheckResultBasedDuration(
|
||||
deps,
|
||||
value.check_result_based,
|
||||
env
|
||||
return getCheckResultBasedDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.check_result_based
|
||||
)
|
||||
case "Indefinite":
|
||||
return getResponsiveText(
|
||||
deps.translateMap(value.indefinite.translations)?.description,
|
||||
env.responsiveText
|
||||
return getIndefiniteDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.indefinite
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(value)
|
||||
@@ -180,61 +169,67 @@ export const getTextForDurationForOneTime = (
|
||||
/**
|
||||
* Returns the text for the duration of a sustained activatable skill.
|
||||
*/
|
||||
export const getTextForDurationForSustained = (
|
||||
deps: { translate: Translate },
|
||||
value: DurationForSustained | undefined,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
export const getDurationForSustainedTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: DurationForSustained | undefined
|
||||
): string =>
|
||||
value === undefined
|
||||
? responsive(
|
||||
env.responsiveText,
|
||||
() => deps.translate("Sustained"),
|
||||
() => deps.translate("(S)")
|
||||
responsiveTextSize,
|
||||
() => locale.translate("Sustained"),
|
||||
() => locale.translate("(S)")
|
||||
)
|
||||
: responsive(
|
||||
env.responsiveText,
|
||||
() => deps.translate("no more than "),
|
||||
() => deps.translate("max. ")
|
||||
) +
|
||||
formatTimeSpan(
|
||||
deps.translate,
|
||||
env.responsiveText,
|
||||
value.maximum.unit,
|
||||
value.maximum.value
|
||||
: wrapAsMaximum(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
formatTimeSpan(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.maximum.unit,
|
||||
value.maximum.value
|
||||
)
|
||||
)
|
||||
|
||||
const getDurationDuringLovemakingTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: CastingTimeDuringLovemaking
|
||||
): string => formatTimeSpan(locale, responsiveTextSize, value.unit, value.value)
|
||||
|
||||
/**
|
||||
* Returns the text for the duration of a cantrip.
|
||||
*/
|
||||
export const getTextForCantripDuration = (
|
||||
deps: { translate: Translate; translateMap: TranslateMap },
|
||||
value: CantripDuration,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
export const getDurationTranslationForCantrip = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: CantripDuration
|
||||
): string => {
|
||||
switch (value.tag) {
|
||||
case "Immediate":
|
||||
return getTextForImmediateDuration(deps, value.immediate, env)
|
||||
return getImmediateDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.immediate
|
||||
)
|
||||
case "Fixed":
|
||||
return getTextForFixedDuration(deps, value.fixed, env)
|
||||
return getFixedDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.fixed
|
||||
)
|
||||
case "Indefinite":
|
||||
return getResponsiveText(
|
||||
deps.translateMap(value.indefinite.translations)?.description,
|
||||
env.responsiveText
|
||||
return getIndefiniteDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.indefinite
|
||||
)
|
||||
case "DuringLovemaking": {
|
||||
const { value: lovemakingValue, unit: lovemakingUnit } =
|
||||
case "DuringLovemaking":
|
||||
return getDurationDuringLovemakingTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.during_lovemaking
|
||||
return formatTimeSpan(
|
||||
deps.translate,
|
||||
env.responsiveText,
|
||||
lovemakingUnit,
|
||||
lovemakingValue
|
||||
)
|
||||
}
|
||||
default:
|
||||
return assertExhaustive(value)
|
||||
}
|
||||
@@ -243,22 +238,29 @@ export const getTextForCantripDuration = (
|
||||
/**
|
||||
* Returns the text for the duration of a blessing.
|
||||
*/
|
||||
export const getTextForBlessingDuration = (
|
||||
deps: { translate: Translate; translateMap: TranslateMap },
|
||||
value: BlessingDuration,
|
||||
env: {
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
export const getDurationTranslationForBlessing = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: BlessingDuration
|
||||
): string => {
|
||||
switch (value.tag) {
|
||||
case "Immediate":
|
||||
return getTextForImmediateDuration(deps, value.immediate, env)
|
||||
return getImmediateDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.immediate
|
||||
)
|
||||
case "Fixed":
|
||||
return getTextForFixedDuration(deps, value.fixed, env)
|
||||
return getFixedDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.fixed
|
||||
)
|
||||
case "Indefinite":
|
||||
return getResponsiveText(
|
||||
deps.translateMap(value.indefinite.translations)?.description,
|
||||
env.responsiveText
|
||||
return getIndefiniteDurationTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.indefinite
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(value)
|
||||
|
||||
@@ -2,26 +2,26 @@ 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 { Translate } from "../../../../helpers/translate.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { LibraryEntryContent } from "../../../../libraryEntry.js"
|
||||
|
||||
const getContentPartsForQualityLevels = (
|
||||
getQualityLevelString: (index: number) => string | number,
|
||||
locale: LocaleEnvironment,
|
||||
source: {
|
||||
text_before: string
|
||||
quality_levels: string[]
|
||||
text_after?: string
|
||||
},
|
||||
getQualityLevelString: (index: number) => string | number,
|
||||
translate: Translate
|
||||
}
|
||||
): LibraryEntryContent[] =>
|
||||
filterNonNullable([
|
||||
{
|
||||
label: translate("Effect"),
|
||||
label: locale.translate("Effect"),
|
||||
value: source.text_before,
|
||||
},
|
||||
...source.quality_levels.map((text, index) => ({
|
||||
value: text,
|
||||
label: translate("QL {0}", getQualityLevelString(index)),
|
||||
label: locale.translate("QL {0}", getQualityLevelString(index)),
|
||||
})),
|
||||
mapNullable(source.text_after, (textAfter) => ({
|
||||
value: textAfter,
|
||||
@@ -33,28 +33,28 @@ const getContentPartsForQualityLevels = (
|
||||
* Gets the text for the effect of an activatable skill.
|
||||
*/
|
||||
export const getTextForEffect = (
|
||||
effect: Effect,
|
||||
translate: Translate
|
||||
locale: LocaleEnvironment,
|
||||
effect: Effect
|
||||
): LibraryEntryContent[] => {
|
||||
switch (effect.tag) {
|
||||
case "Plain":
|
||||
return [
|
||||
{
|
||||
label: translate("Effect"),
|
||||
label: locale.translate("Effect"),
|
||||
value: effect.plain.text,
|
||||
},
|
||||
]
|
||||
case "ForEachQualityLevel":
|
||||
return getContentPartsForQualityLevels(
|
||||
effect.for_each_quality_level,
|
||||
(index) => index + 1,
|
||||
translate
|
||||
locale,
|
||||
effect.for_each_quality_level
|
||||
)
|
||||
case "ForEachTwoQualityLevels":
|
||||
return getContentPartsForQualityLevels(
|
||||
effect.for_each_two_quality_levels,
|
||||
(index) => `${index * 2 + 1}–${index * 2 + 2}`,
|
||||
translate
|
||||
locale,
|
||||
effect.for_each_two_quality_levels
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(effect)
|
||||
|
||||
@@ -5,16 +5,19 @@ import {
|
||||
SlowSustainedPerformanceParameters,
|
||||
} from "optolith-database-schema/types/_ActivatableSkill"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { Translate, TranslateMap } from "../../../../helpers/translate.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { ResponsiveTextSize } from "../../responsiveText.js"
|
||||
import {
|
||||
getTextForFastCastingTime,
|
||||
getTextForSlowCastingTime,
|
||||
getFastCastingTimeTranslation,
|
||||
getSlowCastingTimeTranslation,
|
||||
} from "./castingTime.js"
|
||||
import { getTextForOneTimeCost, getTextForSustainedCost } from "./cost.js"
|
||||
import {
|
||||
getTextForDurationForOneTime,
|
||||
getTextForDurationForSustained,
|
||||
getOneTimeCostTranslation,
|
||||
getSustainedCostTranslation,
|
||||
} from "./cost.js"
|
||||
import {
|
||||
getDurationForOneTimeTranslation,
|
||||
getDurationForSustainedTranslation,
|
||||
} from "./duration.js"
|
||||
import { Entity } from "./entity.js"
|
||||
import { getTextForActivatableSkillRange } from "./range.js"
|
||||
@@ -23,121 +26,179 @@ import { Speed } from "./speed.js"
|
||||
/**
|
||||
* Get the texts for all fast one-time performance parameters.
|
||||
*/
|
||||
export const getTextForFastOneTimePerformanceParameters = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: FastOneTimePerformanceParameters,
|
||||
env: {
|
||||
entity: Entity
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
export const getFastOneTimePerformanceParametersTranslations = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: FastOneTimePerformanceParameters
|
||||
): {
|
||||
castingTime: string
|
||||
cost: string
|
||||
range: string
|
||||
duration: string
|
||||
} => ({
|
||||
castingTime: getTextForFastCastingTime(deps, value.casting_time, env),
|
||||
cost: getTextForOneTimeCost(deps, value.cost, { speed: Speed.Fast, ...env }),
|
||||
range: getTextForActivatableSkillRange(deps, value.range, {
|
||||
speed: Speed.Fast,
|
||||
...env,
|
||||
}),
|
||||
duration: getTextForDurationForOneTime(deps, value.duration, env),
|
||||
castingTime: getFastCastingTimeTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.casting_time
|
||||
),
|
||||
cost: getOneTimeCostTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Speed.Fast,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.cost
|
||||
),
|
||||
range: getTextForActivatableSkillRange(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Speed.Fast,
|
||||
responsiveTextSize,
|
||||
entity,
|
||||
value.range
|
||||
),
|
||||
duration: getDurationForOneTimeTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.duration
|
||||
),
|
||||
})
|
||||
|
||||
/**
|
||||
* Get the texts for all fast sustained performance parameters.
|
||||
*/
|
||||
export const getTextForFastSustainedPerformanceParameters = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: FastSustainedPerformanceParameters,
|
||||
env: {
|
||||
entity: Entity
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
export const getFastSustainedPerformanceParametersTranslations = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: FastSustainedPerformanceParameters
|
||||
): {
|
||||
castingTime: string
|
||||
cost: string
|
||||
range: string
|
||||
duration: string
|
||||
} => ({
|
||||
castingTime: getTextForFastCastingTime(deps, value.casting_time, env),
|
||||
cost: getTextForSustainedCost(deps, value.cost, {
|
||||
speed: Speed.Fast,
|
||||
...env,
|
||||
}),
|
||||
range: getTextForActivatableSkillRange(deps, value.range, {
|
||||
speed: Speed.Fast,
|
||||
...env,
|
||||
}),
|
||||
duration: getTextForDurationForSustained(deps, value.duration, env),
|
||||
castingTime: getFastCastingTimeTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.casting_time
|
||||
),
|
||||
cost: getSustainedCostTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Speed.Fast,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.cost
|
||||
),
|
||||
range: getTextForActivatableSkillRange(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Speed.Fast,
|
||||
responsiveTextSize,
|
||||
entity,
|
||||
value.range
|
||||
),
|
||||
duration: getDurationForSustainedTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.duration
|
||||
),
|
||||
})
|
||||
|
||||
/**
|
||||
* Get the texts for all slow one-time performance parameters.
|
||||
*/
|
||||
export const getTextForSlowOneTimePerformanceParameters = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: SlowOneTimePerformanceParameters,
|
||||
env: {
|
||||
entity: Entity
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
export const getSlowOneTimePerformanceParametersTranslations = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: SlowOneTimePerformanceParameters
|
||||
): {
|
||||
castingTime: string
|
||||
cost: string
|
||||
range: string
|
||||
duration: string
|
||||
} => ({
|
||||
castingTime: getTextForSlowCastingTime(deps, value.casting_time, env),
|
||||
cost: getTextForOneTimeCost(deps, value.cost, { speed: Speed.Slow, ...env }),
|
||||
range: getTextForActivatableSkillRange(deps, value.range, {
|
||||
speed: Speed.Slow,
|
||||
...env,
|
||||
}),
|
||||
duration: getTextForDurationForOneTime(deps, value.duration, env),
|
||||
castingTime: getSlowCastingTimeTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.casting_time
|
||||
),
|
||||
cost: getOneTimeCostTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Speed.Slow,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.cost
|
||||
),
|
||||
range: getTextForActivatableSkillRange(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Speed.Slow,
|
||||
responsiveTextSize,
|
||||
entity,
|
||||
value.range
|
||||
),
|
||||
duration: getDurationForOneTimeTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.duration
|
||||
),
|
||||
})
|
||||
|
||||
/**
|
||||
* Get the texts for all slow sustained performance parameters.
|
||||
*/
|
||||
export const getTextForSlowSustainedPerformanceParameters = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: SlowSustainedPerformanceParameters,
|
||||
env: {
|
||||
entity: Entity
|
||||
responsiveText: ResponsiveTextSize
|
||||
}
|
||||
export const getSlowSustainedPerformanceParametersTranslations = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: SlowSustainedPerformanceParameters
|
||||
): {
|
||||
castingTime: string
|
||||
cost: string
|
||||
range: string
|
||||
duration: string
|
||||
} => ({
|
||||
castingTime: getTextForSlowCastingTime(deps, value.casting_time, env),
|
||||
cost: getTextForSustainedCost(deps, value.cost, {
|
||||
speed: Speed.Slow,
|
||||
...env,
|
||||
}),
|
||||
range: getTextForActivatableSkillRange(deps, value.range, {
|
||||
speed: Speed.Slow,
|
||||
...env,
|
||||
}),
|
||||
duration: getTextForDurationForSustained(deps, value.duration, env),
|
||||
castingTime: getSlowCastingTimeTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.casting_time
|
||||
),
|
||||
cost: getSustainedCostTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Speed.Slow,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.cost
|
||||
),
|
||||
range: getTextForActivatableSkillRange(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Speed.Slow,
|
||||
responsiveTextSize,
|
||||
entity,
|
||||
value.range
|
||||
),
|
||||
duration: getDurationForSustainedTranslation(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.duration
|
||||
),
|
||||
})
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Translate } from "../../../../helpers/translate.js"
|
||||
import { responsive, ResponsiveTextSize } from "../../responsiveText.js"
|
||||
|
||||
/**
|
||||
* Returns the text to prepend for the `is_maximum` property.
|
||||
*/
|
||||
export const getTextForIsMaximum = (
|
||||
is_maximum: boolean | undefined,
|
||||
translate: Translate,
|
||||
responsiveText: ResponsiveTextSize
|
||||
): string => {
|
||||
if (is_maximum !== true) {
|
||||
return ""
|
||||
}
|
||||
|
||||
return responsive(
|
||||
responsiveText,
|
||||
() => translate("no more than "),
|
||||
() => translate("max. ")
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { responsive, ResponsiveTextSize } from "../../responsiveText.js"
|
||||
|
||||
/**
|
||||
* Wraps the text in a translation that indicates it’s a minimum value.
|
||||
*/
|
||||
export const wrapAsMinimum = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
text: string
|
||||
): string =>
|
||||
responsive(
|
||||
responsiveTextSize,
|
||||
() => locale.translate("at least {0}", text),
|
||||
() => locale.translate("min. {0}", text)
|
||||
)
|
||||
|
||||
/**
|
||||
* Wraps the text in a translation that indicates it’s a minimum value if the
|
||||
* `is_minimum` property says it’s a minimum value.
|
||||
*/
|
||||
export const wrapIfMinimum = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
is_minimum: boolean | undefined,
|
||||
text: string
|
||||
) =>
|
||||
is_minimum === true ? wrapAsMinimum(locale, responsiveTextSize, text) : ""
|
||||
|
||||
/**
|
||||
* Wraps the text in a translation that indicates it’s a maximum value.
|
||||
*/
|
||||
export const wrapAsMaximum = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
text: string
|
||||
): string =>
|
||||
responsive(
|
||||
responsiveTextSize,
|
||||
() => locale.translate("no more than {0}", text),
|
||||
() => locale.translate("max. {0}", text)
|
||||
)
|
||||
|
||||
/**
|
||||
* Wraps the text in a translation that indicates it’s a maximum value if the
|
||||
* `is_maximum` property says it’s a maximum value.
|
||||
*/
|
||||
export const wrapIfMaximum = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
is_maximum: boolean | undefined,
|
||||
text: string
|
||||
): string =>
|
||||
is_maximum === true ? wrapAsMaximum(locale, responsiveTextSize, text) : ""
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* A parameter that is designed to be modifiable.
|
||||
*/
|
||||
export enum ModifiableParameter {
|
||||
CastingTime,
|
||||
Cost,
|
||||
Range,
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { Translate } from "../../../../helpers/translate.js"
|
||||
import { ResponsiveTextSize } from "../../responsiveText.js"
|
||||
import { Entity } from "./entity.js"
|
||||
import { ModifiableParameter } from "./modifiableParameter.js"
|
||||
|
||||
/**
|
||||
* Returns the suffix for the text of a non-modifiable parameter that indicates
|
||||
* that the parameter cannot be modified.
|
||||
*/
|
||||
export const getTextForNonModifiableSuffix = (
|
||||
translate: Translate,
|
||||
entity: Entity,
|
||||
param: ModifiableParameter,
|
||||
responsiveText: ResponsiveTextSize
|
||||
): string => {
|
||||
if (responsiveText === ResponsiveTextSize.Compressed) {
|
||||
switch (entity) {
|
||||
case Entity.Spell:
|
||||
case Entity.Ritual:
|
||||
case Entity.LiturgicalChant:
|
||||
case Entity.Ceremony:
|
||||
return translate(" (cannot modify)")
|
||||
case Entity.Cantrip:
|
||||
case Entity.Blessing:
|
||||
return ""
|
||||
default:
|
||||
return assertExhaustive(entity)
|
||||
}
|
||||
}
|
||||
|
||||
switch (entity) {
|
||||
case Entity.Spell:
|
||||
switch (param) {
|
||||
case ModifiableParameter.CastingTime:
|
||||
return translate(
|
||||
" (you cannot use a modification on this spell’s casting time)"
|
||||
)
|
||||
case ModifiableParameter.Cost:
|
||||
return translate(
|
||||
" (you cannot use a modification on this spell’s cost)"
|
||||
)
|
||||
case ModifiableParameter.Range:
|
||||
return translate(
|
||||
" (you cannot use a modification on this spell’s range)"
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(param)
|
||||
}
|
||||
case Entity.Ritual:
|
||||
switch (param) {
|
||||
case ModifiableParameter.CastingTime:
|
||||
return translate(
|
||||
" (you cannot use a modification on this ritual’s ritual time)"
|
||||
)
|
||||
case ModifiableParameter.Cost:
|
||||
return translate(
|
||||
" (you cannot use a modification on this ritual’s cost)"
|
||||
)
|
||||
case ModifiableParameter.Range:
|
||||
return translate(
|
||||
" (you cannot use a modification on this ritual’s range)"
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(param)
|
||||
}
|
||||
case Entity.LiturgicalChant:
|
||||
switch (param) {
|
||||
case ModifiableParameter.CastingTime:
|
||||
return translate(
|
||||
" (you cannot use a modification on this chant’s liturgical time)"
|
||||
)
|
||||
case ModifiableParameter.Cost:
|
||||
return translate(
|
||||
" (you cannot use a modification on this chant’s cost)"
|
||||
)
|
||||
case ModifiableParameter.Range:
|
||||
return translate(
|
||||
" (you cannot use a modification on this chant’s range)"
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(param)
|
||||
}
|
||||
case Entity.Ceremony:
|
||||
switch (param) {
|
||||
case ModifiableParameter.CastingTime:
|
||||
return translate(
|
||||
" (you cannot use a modification on this ceremony’s ceremonial time)"
|
||||
)
|
||||
case ModifiableParameter.Cost:
|
||||
return translate(
|
||||
" (you cannot use a modification on this ceremony’s cost)"
|
||||
)
|
||||
case ModifiableParameter.Range:
|
||||
return translate(
|
||||
" (you cannot use a modification on this ceremony’s range)"
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(param)
|
||||
}
|
||||
case Entity.Cantrip:
|
||||
case Entity.Blessing:
|
||||
return ""
|
||||
default:
|
||||
return assertExhaustive(entity)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { mapNullable } from "@optolith/helpers/nullable"
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { UI } from "optolith-database-schema/types/UI"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { responsive, ResponsiveTextSize } from "../../responsiveText.js"
|
||||
import { Entity } from "./entity.js"
|
||||
|
||||
/**
|
||||
* A parameter that is designed to be modifiable.
|
||||
*/
|
||||
export enum ModifiableParameter {
|
||||
CastingTime,
|
||||
Cost,
|
||||
Range,
|
||||
}
|
||||
|
||||
const translationKeyForNonModifiableSuffix: {
|
||||
[key in Entity]:
|
||||
| {
|
||||
[key in ModifiableParameter]: keyof UI
|
||||
}
|
||||
| undefined
|
||||
} = {
|
||||
[Entity.Spell]: {
|
||||
[ModifiableParameter.CastingTime]:
|
||||
" (you cannot use a modification on this spell’s casting time)",
|
||||
[ModifiableParameter.Cost]:
|
||||
" (you cannot use a modification on this spell’s cost)",
|
||||
[ModifiableParameter.Range]:
|
||||
" (you cannot use a modification on this spell’s range)",
|
||||
},
|
||||
[Entity.Ritual]: {
|
||||
[ModifiableParameter.CastingTime]:
|
||||
" (you cannot use a modification on this ritual’s ritual time)",
|
||||
[ModifiableParameter.Cost]:
|
||||
" (you cannot use a modification on this ritual’s cost)",
|
||||
[ModifiableParameter.Range]:
|
||||
" (you cannot use a modification on this ritual’s range)",
|
||||
},
|
||||
[Entity.LiturgicalChant]: {
|
||||
[ModifiableParameter.CastingTime]:
|
||||
" (you cannot use a modification on this chant’s liturgical time)",
|
||||
[ModifiableParameter.Cost]:
|
||||
" (you cannot use a modification on this chant’s cost)",
|
||||
[ModifiableParameter.Range]:
|
||||
" (you cannot use a modification on this chant’s range)",
|
||||
},
|
||||
[Entity.Ceremony]: {
|
||||
[ModifiableParameter.CastingTime]:
|
||||
" (you cannot use a modification on this ceremony’s ceremonial time)",
|
||||
[ModifiableParameter.Cost]:
|
||||
" (you cannot use a modification on this ceremony’s cost)",
|
||||
[ModifiableParameter.Range]:
|
||||
" (you cannot use a modification on this ceremony’s range)",
|
||||
},
|
||||
[Entity.Cantrip]: undefined,
|
||||
[Entity.Blessing]: undefined,
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the suffix for the text of a non-modifiable parameter that indicates
|
||||
* that the parameter cannot be modified.
|
||||
*/
|
||||
export const getNonModifiableSuffixTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
param: ModifiableParameter,
|
||||
responsiveTextSize: ResponsiveTextSize
|
||||
): string =>
|
||||
responsive(
|
||||
responsiveTextSize,
|
||||
() =>
|
||||
mapNullable(
|
||||
translationKeyForNonModifiableSuffix[entity]?.[param],
|
||||
(key) => locale.translate(key)
|
||||
) ?? "",
|
||||
() => {
|
||||
switch (entity) {
|
||||
case Entity.Spell:
|
||||
case Entity.Ritual:
|
||||
case Entity.LiturgicalChant:
|
||||
case Entity.Ceremony:
|
||||
return locale.translate(" (cannot modify)")
|
||||
case Entity.Cantrip:
|
||||
case Entity.Blessing:
|
||||
return ""
|
||||
default:
|
||||
return assertExhaustive(entity)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -9,8 +9,10 @@ export const parensIf = (text: string | undefined): string =>
|
||||
* Appends a string in parentheses with a leading space if it is not empty or
|
||||
* `undefined`.
|
||||
*/
|
||||
export const appendInParens = (
|
||||
text: string,
|
||||
append: string | undefined
|
||||
export const appendInParensIfNotEmpty = (
|
||||
textToAppend: string | undefined,
|
||||
text: string
|
||||
): string =>
|
||||
append === undefined || append === "" ? text : `${text} (${append})`
|
||||
textToAppend === undefined || textToAppend === ""
|
||||
? text
|
||||
: `${text} (${textToAppend})`
|
||||
|
||||
@@ -1,47 +1,174 @@
|
||||
import { mapNullable } from "@optolith/helpers/nullable"
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import {
|
||||
CheckResultBasedRange,
|
||||
FixedRange,
|
||||
ModifiableRange,
|
||||
Range,
|
||||
RangeUnit,
|
||||
RangeValue,
|
||||
} from "optolith-database-schema/types/_ActivatableSkillRange"
|
||||
import { BlessingRange } from "optolith-database-schema/types/Blessing"
|
||||
import { CantripRange } from "optolith-database-schema/types/Cantrip"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { Translate, TranslateMap } from "../../../../helpers/translate.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import {
|
||||
getResponsiveText,
|
||||
getResponsiveTextOptional,
|
||||
responsive,
|
||||
appendNoteIfRequested,
|
||||
replaceTextIfRequested,
|
||||
ResponsiveTextSize,
|
||||
} from "../../responsiveText.js"
|
||||
import { formatLength } from "../../units/length.js"
|
||||
import { MISSING_VALUE } from "../../unknown.js"
|
||||
import { getTextForCheckResultBased } from "./checkResultBased.js"
|
||||
import { getCheckResultBasedValueTranslation } from "./checkResultBased.js"
|
||||
import { Entity } from "./entity.js"
|
||||
import { getTextForIsMaximum } from "./isMaximum.js"
|
||||
import { ModifiableParameter } from "./modifiableParameter.js"
|
||||
import { getTextForNonModifiableSuffix } from "./nonModifiable.js"
|
||||
import { Speed } from "./speed.js"
|
||||
import { wrapIfMaximum } from "./isMinimumMaximum.js"
|
||||
import {
|
||||
getNonModifiableSuffixTranslation,
|
||||
ModifiableParameter,
|
||||
} from "./nonModifiableSuffix.js"
|
||||
import { getModifiableBySpeed, Speed } from "./speed.js"
|
||||
|
||||
const toRangeUnit = (
|
||||
unit: RangeUnit,
|
||||
value: number | string,
|
||||
translate: Translate,
|
||||
responsiveText: ResponsiveTextSize
|
||||
) => {
|
||||
switch (unit) {
|
||||
case "Steps":
|
||||
return responsive(
|
||||
responsiveText,
|
||||
() => translate("{0} yards", value),
|
||||
() => translate("{0} yd", value)
|
||||
const getModifiableRangeTranslation = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: ModifiableRange
|
||||
) =>
|
||||
mapNullable(
|
||||
getSkillModificationLevelById(value.initial_modification_level),
|
||||
(modificationLevel) => {
|
||||
const range = getModifiableBySpeed(
|
||||
(config) => config.range,
|
||||
(config) => config.range,
|
||||
speed,
|
||||
modificationLevel
|
||||
)
|
||||
case "Miles":
|
||||
return responsive(
|
||||
responsiveText,
|
||||
() => translate("{0} miles", value),
|
||||
() => translate("{0} mi.", value)
|
||||
|
||||
if (range === 1) {
|
||||
return locale.translate("Touch")
|
||||
}
|
||||
|
||||
return formatLength(locale, responsiveTextSize, "Steps", range)
|
||||
}
|
||||
) ?? MISSING_VALUE
|
||||
|
||||
const getSightTranslation = (locale: LocaleEnvironment) =>
|
||||
locale.translate("Sight")
|
||||
|
||||
const getSelfTranslation = (locale: LocaleEnvironment) =>
|
||||
locale.translate("Self")
|
||||
|
||||
const getGlobalTranslation = (locale: LocaleEnvironment) =>
|
||||
locale.translate("Global")
|
||||
|
||||
const getTouchTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize
|
||||
) =>
|
||||
locale.translate("Touch") +
|
||||
getNonModifiableSuffixTranslation(
|
||||
locale,
|
||||
entity,
|
||||
ModifiableParameter.Range,
|
||||
responsiveTextSize
|
||||
)
|
||||
|
||||
const getFixedRangeTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: FixedRange
|
||||
) =>
|
||||
formatLength(locale, responsiveTextSize, value.unit, value.value) +
|
||||
getNonModifiableSuffixTranslation(
|
||||
locale,
|
||||
entity,
|
||||
ModifiableParameter.Range,
|
||||
responsiveTextSize
|
||||
)
|
||||
|
||||
const wrapIfRadius = (
|
||||
locale: LocaleEnvironment,
|
||||
is_radius: boolean | undefined,
|
||||
text: string
|
||||
) => (is_radius === true ? `${text} ${locale.translate("Radius")}` : text)
|
||||
|
||||
const getCheckResultBasedRangeTranslation = (
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: CheckResultBasedRange
|
||||
) => {
|
||||
const range = formatLength(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.unit,
|
||||
getCheckResultBasedValueTranslation(locale.translate, value)
|
||||
)
|
||||
|
||||
const rangeWrappedIfRadius = wrapIfRadius(locale, value.is_radius, range)
|
||||
|
||||
const rangeWrappedIfRadiusAndIfMaximum = wrapIfMaximum(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
value.is_maximum,
|
||||
rangeWrappedIfRadius
|
||||
)
|
||||
|
||||
return (
|
||||
rangeWrappedIfRadiusAndIfMaximum +
|
||||
getNonModifiableSuffixTranslation(
|
||||
locale,
|
||||
entity,
|
||||
ModifiableParameter.Range,
|
||||
responsiveTextSize
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
const getRangeValueTranslation = (
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
entity: Entity,
|
||||
value: RangeValue
|
||||
) => {
|
||||
switch (value.tag) {
|
||||
case "Modifiable":
|
||||
return getModifiableRangeTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
speed,
|
||||
responsiveTextSize,
|
||||
value.modifiable
|
||||
)
|
||||
case "Sight":
|
||||
return getSightTranslation(locale)
|
||||
case "Self":
|
||||
return getSelfTranslation(locale)
|
||||
case "Global":
|
||||
return getGlobalTranslation(locale)
|
||||
case "Touch":
|
||||
return getTouchTranslation(locale, entity, responsiveTextSize)
|
||||
case "Fixed": {
|
||||
return getFixedRangeTranslation(
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.fixed
|
||||
)
|
||||
}
|
||||
case "CheckResultBased":
|
||||
return getCheckResultBasedRangeTranslation(
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.check_result_based
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(unit)
|
||||
return assertExhaustive(value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,194 +176,88 @@ const toRangeUnit = (
|
||||
* Returns the text for the range of an activatable skill.
|
||||
*/
|
||||
export const getTextForActivatableSkillRange = (
|
||||
deps: {
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
},
|
||||
value: Range,
|
||||
env: {
|
||||
speed: Speed
|
||||
responsiveText: ResponsiveTextSize
|
||||
entity: Entity
|
||||
}
|
||||
getSkillModificationLevelById: GetById.Static.SkillModificationLevel,
|
||||
locale: LocaleEnvironment,
|
||||
speed: Speed,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
entity: Entity,
|
||||
value: Range
|
||||
): string => {
|
||||
const translation = deps.translateMap(value.translations)
|
||||
const rangeValue = getRangeValueTranslation(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
speed,
|
||||
responsiveTextSize,
|
||||
entity,
|
||||
value.value
|
||||
)
|
||||
|
||||
if (value.translations !== undefined && translation === undefined) {
|
||||
return MISSING_VALUE
|
||||
const withReplacement = replaceTextIfRequested(
|
||||
"replacement",
|
||||
value.translations,
|
||||
locale.translateMap,
|
||||
responsiveTextSize,
|
||||
rangeValue
|
||||
)
|
||||
|
||||
return appendNoteIfRequested(
|
||||
"note",
|
||||
value.translations,
|
||||
locale.translateMap,
|
||||
responsiveTextSize,
|
||||
withReplacement
|
||||
)
|
||||
}
|
||||
|
||||
const getTextForTinyAcitvatableRange = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
entity: Entity,
|
||||
value: CantripRange | BlessingRange
|
||||
): string => {
|
||||
switch (value.tag) {
|
||||
case "Self":
|
||||
return getSelfTranslation(locale)
|
||||
case "Touch":
|
||||
return getTouchTranslation(locale, entity, responsiveTextSize)
|
||||
case "Fixed":
|
||||
return getFixedRangeTranslation(
|
||||
locale,
|
||||
entity,
|
||||
responsiveTextSize,
|
||||
value.fixed
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(value)
|
||||
}
|
||||
|
||||
const rangeValue = (() => {
|
||||
switch (value.value.tag) {
|
||||
case "Modifiable": {
|
||||
const modificationLevel = deps.getSkillModificationLevelById(
|
||||
value.value.modifiable.initial_modification_level
|
||||
)
|
||||
|
||||
if (modificationLevel === undefined) {
|
||||
return MISSING_VALUE
|
||||
}
|
||||
|
||||
const range = (() => {
|
||||
switch (env.speed) {
|
||||
case Speed.Fast:
|
||||
return modificationLevel.fast.range
|
||||
case Speed.Slow:
|
||||
return modificationLevel.slow.range
|
||||
default:
|
||||
return assertExhaustive(env.speed)
|
||||
}
|
||||
})()
|
||||
|
||||
if (range === 1) {
|
||||
return deps.translate("Touch")
|
||||
}
|
||||
|
||||
return toRangeUnit("Steps", range, deps.translate, env.responsiveText)
|
||||
}
|
||||
case "Sight":
|
||||
return deps.translate("Sight")
|
||||
case "Self":
|
||||
return deps.translate("Self")
|
||||
case "Global":
|
||||
return deps.translate("Global")
|
||||
case "Touch":
|
||||
return (
|
||||
deps.translate("Touch") +
|
||||
getTextForNonModifiableSuffix(
|
||||
deps.translate,
|
||||
env.entity,
|
||||
ModifiableParameter.Range,
|
||||
env.responsiveText
|
||||
)
|
||||
)
|
||||
case "Fixed": {
|
||||
return (
|
||||
toRangeUnit(
|
||||
value.value.fixed.unit,
|
||||
value.value.fixed.value,
|
||||
deps.translate,
|
||||
env.responsiveText
|
||||
) +
|
||||
getTextForNonModifiableSuffix(
|
||||
deps.translate,
|
||||
env.entity,
|
||||
ModifiableParameter.Range,
|
||||
env.responsiveText
|
||||
)
|
||||
)
|
||||
}
|
||||
case "CheckResultBased": {
|
||||
const isMaximum = getTextForIsMaximum(
|
||||
value.value.check_result_based.is_maximum,
|
||||
deps.translate,
|
||||
env.responsiveText
|
||||
)
|
||||
|
||||
const isRadius =
|
||||
value.value.check_result_based.is_radius === true
|
||||
? ` ${deps.translate("Radius")}`
|
||||
: ""
|
||||
|
||||
return (
|
||||
isMaximum +
|
||||
toRangeUnit(
|
||||
value.value.check_result_based.unit,
|
||||
getTextForCheckResultBased(
|
||||
value.value.check_result_based,
|
||||
deps.translate
|
||||
),
|
||||
deps.translate,
|
||||
env.responsiveText
|
||||
) +
|
||||
isRadius +
|
||||
getTextForNonModifiableSuffix(
|
||||
deps.translate,
|
||||
env.entity,
|
||||
ModifiableParameter.Range,
|
||||
env.responsiveText
|
||||
)
|
||||
)
|
||||
}
|
||||
default:
|
||||
return assertExhaustive(value.value)
|
||||
}
|
||||
})()
|
||||
|
||||
const withReplacement =
|
||||
translation?.replacement !== undefined
|
||||
? getResponsiveText(translation.replacement, env.responsiveText).replace(
|
||||
"$1",
|
||||
rangeValue
|
||||
)
|
||||
: rangeValue
|
||||
|
||||
const withNote = (() => {
|
||||
if (translation?.note === undefined) {
|
||||
return withReplacement
|
||||
}
|
||||
|
||||
const note = getResponsiveTextOptional(translation.note, env.responsiveText)
|
||||
|
||||
if (note === undefined) {
|
||||
return withReplacement
|
||||
}
|
||||
|
||||
return `${withReplacement} (${note})`
|
||||
})()
|
||||
|
||||
return withNote
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text for the range of a cantrip.
|
||||
*/
|
||||
export const getTextForCantripRange = (
|
||||
deps: { translate: Translate },
|
||||
value: CantripRange,
|
||||
env: { responsiveText: ResponsiveTextSize }
|
||||
): string => {
|
||||
switch (value.tag) {
|
||||
case "Self":
|
||||
return deps.translate("Self")
|
||||
case "Touch":
|
||||
return deps.translate("Touch")
|
||||
case "Fixed": {
|
||||
return toRangeUnit(
|
||||
value.fixed.unit,
|
||||
value.fixed.value,
|
||||
deps.translate,
|
||||
env.responsiveText
|
||||
)
|
||||
}
|
||||
default:
|
||||
return assertExhaustive(value)
|
||||
}
|
||||
}
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: CantripRange
|
||||
): string =>
|
||||
getTextForTinyAcitvatableRange(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
Entity.Cantrip,
|
||||
value
|
||||
)
|
||||
|
||||
/**
|
||||
* Returns the text for the range of a blessing.
|
||||
*/
|
||||
export const getTextForBlessingRange = (
|
||||
deps: { translate: Translate },
|
||||
value: BlessingRange,
|
||||
env: { responsiveText: ResponsiveTextSize }
|
||||
): string => {
|
||||
switch (value.tag) {
|
||||
case "Self":
|
||||
return deps.translate("Self")
|
||||
case "Touch":
|
||||
return deps.translate("Touch")
|
||||
case "Fixed": {
|
||||
return toRangeUnit(
|
||||
value.fixed.unit,
|
||||
value.fixed.value,
|
||||
deps.translate,
|
||||
env.responsiveText
|
||||
)
|
||||
}
|
||||
default:
|
||||
return assertExhaustive(value)
|
||||
}
|
||||
}
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
value: BlessingRange
|
||||
): string =>
|
||||
getTextForTinyAcitvatableRange(
|
||||
locale,
|
||||
responsiveTextSize,
|
||||
Entity.Blessing,
|
||||
value
|
||||
)
|
||||
|
||||
@@ -17,10 +17,10 @@ export enum Speed {
|
||||
* Returns a common value for a skill modification level depending on the speed.
|
||||
*/
|
||||
export const getModifiableBySpeed = <T>(
|
||||
level: SkillModificationLevel,
|
||||
speed: Speed,
|
||||
fast: (config: FastSkillModificationLevelConfig) => T,
|
||||
slow: (config: SlowSkillModificationLevelConfig) => T
|
||||
slow: (config: SlowSkillModificationLevelConfig) => T,
|
||||
speed: Speed,
|
||||
level: SkillModificationLevel
|
||||
): T => {
|
||||
switch (speed) {
|
||||
case Speed.Fast:
|
||||
|
||||
@@ -1,59 +1,92 @@
|
||||
import { mapNullable } from "@optolith/helpers/nullable"
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { TargetCategory } from "optolith-database-schema/types/_ActivatableSkillTargetCategory"
|
||||
import {
|
||||
TargetCategory,
|
||||
TargetCategoryIdentifier,
|
||||
} from "optolith-database-schema/types/_ActivatableSkillTargetCategory"
|
||||
import { TargetCategoryReference } from "optolith-database-schema/types/_SimpleReferences"
|
||||
import { GetById } from "../../../../helpers/getTypes.js"
|
||||
import { Translate, TranslateMap } from "../../../../helpers/translate.js"
|
||||
import { LocaleEnvironment } from "../../../../helpers/locale.js"
|
||||
import { LibraryEntryContent } from "../../../../libraryEntry.js"
|
||||
import { MISSING_VALUE } from "../../unknown.js"
|
||||
import { appendInParens } from "./parensIf.js"
|
||||
import { appendInParensIfNotEmpty } from "./parensIf.js"
|
||||
|
||||
const getSelfTranslation = (locale: LocaleEnvironment) =>
|
||||
locale.translate("Self")
|
||||
|
||||
const getZoneTranslation = (locale: LocaleEnvironment) =>
|
||||
locale.translate("Zone")
|
||||
|
||||
const getLiturgicalChantsAndCeremoniesTranslation = (
|
||||
locale: LocaleEnvironment
|
||||
) => locale.translate("Liturgical Chants and Ceremonies")
|
||||
|
||||
const getCantripsTranslation = (locale: LocaleEnvironment) =>
|
||||
locale.translate("Cantrips")
|
||||
|
||||
const getPredefinedTranslation = (
|
||||
getTargetCategoryById: GetById.Static.TargetCategory,
|
||||
locale: LocaleEnvironment,
|
||||
value: TargetCategoryReference
|
||||
) => {
|
||||
const numericId = value.id.target_category
|
||||
const specificTargetCategory = getTargetCategoryById(numericId)
|
||||
|
||||
return (
|
||||
mapNullable(
|
||||
locale.translateMap(specificTargetCategory?.translations),
|
||||
(translation) => translation.name
|
||||
) ?? MISSING_VALUE
|
||||
)
|
||||
}
|
||||
|
||||
const getTargetCategoryTranslationByType = (
|
||||
getTargetCategoryById: GetById.Static.TargetCategory,
|
||||
locale: LocaleEnvironment,
|
||||
id: TargetCategoryIdentifier
|
||||
) => {
|
||||
switch (id.tag) {
|
||||
case "Self":
|
||||
return getSelfTranslation(locale)
|
||||
case "Zone":
|
||||
return getZoneTranslation(locale)
|
||||
case "LiturgicalChantsAndCeremonies":
|
||||
return getLiturgicalChantsAndCeremoniesTranslation(locale)
|
||||
case "Cantrips":
|
||||
return getCantripsTranslation(locale)
|
||||
case "Predefined":
|
||||
return getPredefinedTranslation(
|
||||
getTargetCategoryById,
|
||||
locale,
|
||||
id.predefined
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text for the target category.
|
||||
*/
|
||||
export const getTextForTargetCategory = (
|
||||
deps: {
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
getTargetCategoryById: GetById.Static.TargetCategory
|
||||
},
|
||||
export const getTargetCategoryTranslation = (
|
||||
getTargetCategoryById: GetById.Static.TargetCategory,
|
||||
locale: LocaleEnvironment,
|
||||
values: TargetCategory
|
||||
): LibraryEntryContent => ({
|
||||
label: deps.translate("Target Category"),
|
||||
label: locale.translate("Target Category"),
|
||||
value:
|
||||
values.length === 0
|
||||
? deps.translate("all")
|
||||
? locale.translate("all")
|
||||
: values
|
||||
.map(({ id, translations }) => {
|
||||
const mainName = (() => {
|
||||
switch (id.tag) {
|
||||
case "Self":
|
||||
return deps.translate("Self")
|
||||
case "Zone":
|
||||
return deps.translate("Zone")
|
||||
case "LiturgicalChantsAndCeremonies":
|
||||
return deps.translate("Liturgical Chants and Ceremonies")
|
||||
case "Cantrips":
|
||||
return deps.translate("Cantrips")
|
||||
case "Predefined": {
|
||||
const numericId = id.predefined.id.target_category
|
||||
const specificTargetCategory =
|
||||
deps.getTargetCategoryById(numericId)
|
||||
return (
|
||||
mapNullable(
|
||||
deps.translateMap(specificTargetCategory?.translations),
|
||||
(translation) => translation.name
|
||||
) ?? MISSING_VALUE
|
||||
)
|
||||
}
|
||||
default:
|
||||
return assertExhaustive(id)
|
||||
}
|
||||
})()
|
||||
|
||||
return appendInParens(
|
||||
mainName,
|
||||
deps.translateMap(translations)?.note
|
||||
.map(({ id, translations }) =>
|
||||
appendInParensIfNotEmpty(
|
||||
locale.translateMap(translations)?.note,
|
||||
getTargetCategoryTranslationByType(
|
||||
getTargetCategoryById,
|
||||
locale,
|
||||
id
|
||||
)
|
||||
)
|
||||
})
|
||||
)
|
||||
.join(", "),
|
||||
})
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { Translate } from "../../../../helpers/translate.js"
|
||||
import { responsive, ResponsiveTextSize } from "../../responsiveText.js"
|
||||
import { Entity } from "./entity.js"
|
||||
|
||||
type TimeSpanUnit =
|
||||
| "Seconds"
|
||||
| "Minutes"
|
||||
| "Hours"
|
||||
| "Days"
|
||||
| "Weeks"
|
||||
| "Months"
|
||||
| "Years"
|
||||
| "Centuries"
|
||||
| "Actions"
|
||||
| "CombatRounds"
|
||||
| "SeductionActions"
|
||||
| "Rounds"
|
||||
|
||||
/**
|
||||
* Returns the text for a time span unit.
|
||||
*/
|
||||
export const formatTimeSpan = (
|
||||
translate: Translate,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
unit: TimeSpanUnit,
|
||||
value: number | string
|
||||
): string => {
|
||||
switch (unit) {
|
||||
case "Seconds":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} seconds", value),
|
||||
() => translate("{0} s", value)
|
||||
)
|
||||
case "Minutes":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} minutes", value),
|
||||
() => translate("{0} min", value)
|
||||
)
|
||||
case "Hours":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} hours", value),
|
||||
() => translate("{0} h", value)
|
||||
)
|
||||
case "Days":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} days", value),
|
||||
() => translate("{0} d", value)
|
||||
)
|
||||
case "Weeks":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} weeks", value),
|
||||
() => translate("{0} wks.", value)
|
||||
)
|
||||
case "Months":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} months", value),
|
||||
() => translate("{0} mos.", value)
|
||||
)
|
||||
case "Years":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} years", value),
|
||||
() => translate("{0} yrs.", value)
|
||||
)
|
||||
case "Centuries":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} centuries", value),
|
||||
() => translate("{0} cent.", value)
|
||||
)
|
||||
case "Actions":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} actions", value),
|
||||
() => translate("{0} act", value)
|
||||
)
|
||||
case "CombatRounds":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} combat rounds", value),
|
||||
() => translate("{0} CR", value)
|
||||
)
|
||||
case "SeductionActions":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} seduction actions", value),
|
||||
() => translate("{0} SA", value)
|
||||
)
|
||||
case "Rounds":
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => translate("{0} rounds", value),
|
||||
() => translate("{0} rnds", value)
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(unit)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text for a cost unit that is based on the entity type.
|
||||
*/
|
||||
export const formatCost = (
|
||||
translate: Translate,
|
||||
entity: Entity,
|
||||
value: number | string
|
||||
) => {
|
||||
switch (entity) {
|
||||
case Entity.Cantrip:
|
||||
case Entity.Spell:
|
||||
case Entity.Ritual:
|
||||
return translate("{0} AE", value)
|
||||
case Entity.Blessing:
|
||||
case Entity.LiturgicalChant:
|
||||
case Entity.Ceremony:
|
||||
return translate("{0} KP", value)
|
||||
default:
|
||||
return assertExhaustive(entity)
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
ResponsiveTextReplace,
|
||||
} from "optolith-database-schema/types/_ResponsiveText"
|
||||
import { TranslateMap } from "../../helpers/translate.js"
|
||||
import { appendInParensIfNotEmpty } from "./rated/activatable/parensIf.js"
|
||||
import { MISSING_VALUE } from "./unknown.js"
|
||||
|
||||
/**
|
||||
@@ -76,14 +77,33 @@ export const getResponsiveTextOptional = (
|
||||
|
||||
/**
|
||||
* Replaces a text with a given value if a replacement is requested, otherwise
|
||||
* just return the .
|
||||
* just return the given value.
|
||||
*/
|
||||
export const replaceTextIfRequested = (
|
||||
translation: LocaleMap<{ replacement?: ResponsiveTextReplace }> | undefined,
|
||||
valueToReplace: string,
|
||||
export const replaceTextIfRequested = <Key extends string>(
|
||||
key: Key,
|
||||
translation: LocaleMap<{ [K in Key]?: ResponsiveTextReplace }> | undefined,
|
||||
translateMap: TranslateMap,
|
||||
responsiveText: ResponsiveTextSize
|
||||
responsiveText: ResponsiveTextSize,
|
||||
valueToReplace: string
|
||||
) =>
|
||||
mapNullable(translateMap(translation)?.replacement, (replacement) =>
|
||||
mapNullable(translateMap(translation)?.[key], (replacement) =>
|
||||
getResponsiveText(replacement, responsiveText).replace("$1", valueToReplace)
|
||||
) ?? valueToReplace
|
||||
|
||||
/**
|
||||
* Appends a note to a given value if a note is requested, otherwise just return
|
||||
* the given value.
|
||||
*/
|
||||
export const appendNoteIfRequested = <Key extends string>(
|
||||
key: Key,
|
||||
translation: LocaleMap<{ [K in Key]?: ResponsiveTextOptional }> | undefined,
|
||||
translateMap: TranslateMap,
|
||||
responsiveText: ResponsiveTextSize,
|
||||
valueToAppendTo: string
|
||||
) =>
|
||||
mapNullable(translateMap(translation)?.[key], (note) =>
|
||||
appendInParensIfNotEmpty(
|
||||
getResponsiveTextOptional(note, responsiveText),
|
||||
valueToAppendTo
|
||||
)
|
||||
) ?? valueToAppendTo
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { assertExhaustive } from "@optolith/helpers/typeSafety"
|
||||
import { UI } from "optolith-database-schema/types/UI"
|
||||
import { LocaleEnvironment } from "../../../helpers/locale.js"
|
||||
import { Entity } from "../rated/activatable/entity.js"
|
||||
|
||||
type EnergyUnit = "ArcaneEnergy" | "KarmaPoints"
|
||||
|
||||
const lengthUnitTranslationKeys: {
|
||||
[key in EnergyUnit]: keyof UI
|
||||
} = {
|
||||
ArcaneEnergy: "{0} AE",
|
||||
KarmaPoints: "{0} KP",
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text for an energy unit.
|
||||
*/
|
||||
export const formatEnergy = (
|
||||
locale: LocaleEnvironment,
|
||||
unit: EnergyUnit,
|
||||
value: number | string
|
||||
): string => {
|
||||
const key = lengthUnitTranslationKeys[unit]
|
||||
|
||||
return locale.translate(key, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text for an energy unit that is based on the entity type.
|
||||
*/
|
||||
export const formatEnergyByEntity = (
|
||||
locale: LocaleEnvironment,
|
||||
entity: Entity,
|
||||
value: number | string
|
||||
) => {
|
||||
switch (entity) {
|
||||
case Entity.Cantrip:
|
||||
case Entity.Spell:
|
||||
case Entity.Ritual:
|
||||
return formatEnergy(locale, "ArcaneEnergy", value)
|
||||
case Entity.Blessing:
|
||||
case Entity.LiturgicalChant:
|
||||
case Entity.Ceremony:
|
||||
return formatEnergy(locale, "KarmaPoints", value)
|
||||
default:
|
||||
return assertExhaustive(entity)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { UI } from "optolith-database-schema/types/UI"
|
||||
import { LocaleEnvironment } from "../../../helpers/locale.js"
|
||||
import { responsive, ResponsiveTextSize } from "../responsiveText.js"
|
||||
|
||||
type LengthUnit = "Steps" | "Miles"
|
||||
|
||||
const lengthUnitTranslationKeys: {
|
||||
[key in LengthUnit]: [full: keyof UI, compressed: keyof UI]
|
||||
} = {
|
||||
Steps: ["{0} yards", "{0} yd"],
|
||||
Miles: ["{0} miles", "{0} mi."],
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text for a length unit.
|
||||
*/
|
||||
export const formatLength = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
unit: LengthUnit,
|
||||
value: number | string
|
||||
) => {
|
||||
const [fullKey, compressedKey] = lengthUnitTranslationKeys[unit]
|
||||
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => locale.translate(fullKey, value),
|
||||
() => locale.translate(compressedKey, value)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { UI } from "optolith-database-schema/types/UI"
|
||||
import { LocaleEnvironment } from "../../../helpers/locale.js"
|
||||
import { ResponsiveTextSize, responsive } from "../responsiveText.js"
|
||||
|
||||
type TimeSpanUnit =
|
||||
| "Seconds"
|
||||
| "Minutes"
|
||||
| "Hours"
|
||||
| "Days"
|
||||
| "Weeks"
|
||||
| "Months"
|
||||
| "Years"
|
||||
| "Centuries"
|
||||
| "Actions"
|
||||
| "CombatRounds"
|
||||
| "SeductionActions"
|
||||
| "Rounds"
|
||||
|
||||
const timeSpanUnitTranslationKeys: {
|
||||
[key in TimeSpanUnit]: [full: keyof UI, compressed: keyof UI]
|
||||
} = {
|
||||
Seconds: ["{0} seconds", "{0} s"],
|
||||
Minutes: ["{0} minutes", "{0} min"],
|
||||
Hours: ["{0} hours", "{0} h"],
|
||||
Days: ["{0} days", "{0} d"],
|
||||
Weeks: ["{0} weeks", "{0} wks."],
|
||||
Months: ["{0} months", "{0} mos."],
|
||||
Years: ["{0} years", "{0} yrs."],
|
||||
Centuries: ["{0} centuries", "{0} cent."],
|
||||
Actions: ["{0} actions", "{0} act"],
|
||||
CombatRounds: ["{0} combat rounds", "{0} CR"],
|
||||
SeductionActions: ["{0} seduction actions", "{0} SA"],
|
||||
Rounds: ["{0} rounds", "{0} rnds"],
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text for a time span unit.
|
||||
*/
|
||||
export const formatTimeSpan = (
|
||||
locale: LocaleEnvironment,
|
||||
responsiveTextSize: ResponsiveTextSize,
|
||||
unit: TimeSpanUnit,
|
||||
value: number | string
|
||||
): string => {
|
||||
const [fullKey, compressedKey] = timeSpanUnitTranslationKeys[unit]
|
||||
|
||||
return responsive(
|
||||
responsiveTextSize,
|
||||
() => locale.translate(fullKey, value),
|
||||
() => locale.translate(compressedKey, value)
|
||||
)
|
||||
}
|
||||
@@ -21,7 +21,7 @@ export const getSkillLibraryEntry = createLibraryEntryCreator<
|
||||
}
|
||||
>(
|
||||
(entry, { getAttributeById, blessedTraditions, diseases, regions, cache }) =>
|
||||
({ translate, translateMap, localeCompare }) => {
|
||||
({ translate, translateMap, compare: localeCompare }) => {
|
||||
const translation = translateMap(entry.translations)
|
||||
|
||||
if (translation === undefined) {
|
||||
|
||||
+54
-72
@@ -16,18 +16,18 @@ import {
|
||||
createLibraryEntryCreator,
|
||||
LibraryEntryContent,
|
||||
} from "../libraryEntry.js"
|
||||
import { getTextForCantripDuration } from "./partial/rated/activatable/duration.js"
|
||||
import { getDurationTranslationForCantrip } from "./partial/rated/activatable/duration.js"
|
||||
import { getTextForEffect } from "./partial/rated/activatable/effect.js"
|
||||
import { Entity } from "./partial/rated/activatable/entity.js"
|
||||
import {
|
||||
getTextForFastOneTimePerformanceParameters,
|
||||
getTextForFastSustainedPerformanceParameters,
|
||||
getTextForSlowOneTimePerformanceParameters,
|
||||
getTextForSlowSustainedPerformanceParameters,
|
||||
getFastOneTimePerformanceParametersTranslations,
|
||||
getFastSustainedPerformanceParametersTranslations,
|
||||
getSlowOneTimePerformanceParametersTranslations,
|
||||
getSlowSustainedPerformanceParametersTranslations,
|
||||
} from "./partial/rated/activatable/index.js"
|
||||
import { parensIf } from "./partial/rated/activatable/parensIf.js"
|
||||
import { getTextForCantripRange } from "./partial/rated/activatable/range.js"
|
||||
import { getTextForTargetCategory } from "./partial/rated/activatable/targetCategory.js"
|
||||
import { getTargetCategoryTranslation } from "./partial/rated/activatable/targetCategory.js"
|
||||
import { createImprovementCost } from "./partial/rated/improvementCost.js"
|
||||
import { getTextForCheck } from "./partial/rated/skillCheck.js"
|
||||
import { ResponsiveTextSize } from "./partial/responsiveText.js"
|
||||
@@ -124,7 +124,8 @@ export const getCantripLibraryEntry = createLibraryEntryCreator<
|
||||
getCurriculumById,
|
||||
}
|
||||
) =>
|
||||
({ translate, translateMap, localeCompare }) => {
|
||||
(locale) => {
|
||||
const { translate, translateMap, compare: localeCompare } = locale
|
||||
const translation = translateMap(entry.translations)
|
||||
|
||||
if (translation === undefined) {
|
||||
@@ -132,19 +133,15 @@ export const getCantripLibraryEntry = createLibraryEntryCreator<
|
||||
}
|
||||
|
||||
const range = getTextForCantripRange(
|
||||
{ translate },
|
||||
entry.parameters.range,
|
||||
{
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
locale,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.range
|
||||
)
|
||||
|
||||
const duration = getTextForCantripDuration(
|
||||
{ translate, translateMap },
|
||||
entry.parameters.duration,
|
||||
{
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
const duration = getDurationTranslationForCantrip(
|
||||
locale,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.duration
|
||||
)
|
||||
|
||||
return {
|
||||
@@ -169,8 +166,9 @@ export const getCantripLibraryEntry = createLibraryEntryCreator<
|
||||
? `***${duration}*** (${translation.duration})`
|
||||
: duration,
|
||||
},
|
||||
getTextForTargetCategory(
|
||||
{ translate, translateMap, getTargetCategoryById },
|
||||
getTargetCategoryTranslation(
|
||||
getTargetCategoryById,
|
||||
locale,
|
||||
entry.target
|
||||
),
|
||||
getTextForProperty(
|
||||
@@ -266,7 +264,8 @@ export const getSpellLibraryEntry = createLibraryEntryCreator<
|
||||
getMagicalTraditionById,
|
||||
}
|
||||
) =>
|
||||
({ translate, translateMap, localeCompare }) => {
|
||||
(locale) => {
|
||||
const { translate, translateMap, compare: localeCompare } = locale
|
||||
const translation = translateMap(entry.translations)
|
||||
|
||||
if (translation === undefined) {
|
||||
@@ -276,31 +275,21 @@ export const getSpellLibraryEntry = createLibraryEntryCreator<
|
||||
const { castingTime, cost, range, duration } = (() => {
|
||||
switch (entry.parameters.tag) {
|
||||
case "OneTime":
|
||||
return getTextForFastOneTimePerformanceParameters(
|
||||
{
|
||||
getSkillModificationLevelById,
|
||||
translate,
|
||||
translateMap,
|
||||
},
|
||||
entry.parameters.one_time,
|
||||
{
|
||||
entity: Entity.Spell,
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
return getFastOneTimePerformanceParametersTranslations(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Entity.Spell,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.one_time
|
||||
)
|
||||
|
||||
case "Sustained":
|
||||
return getTextForFastSustainedPerformanceParameters(
|
||||
{
|
||||
getSkillModificationLevelById,
|
||||
translate,
|
||||
translateMap,
|
||||
},
|
||||
entry.parameters.sustained,
|
||||
{
|
||||
entity: Entity.Spell,
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
return getFastSustainedPerformanceParametersTranslations(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Entity.Spell,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.sustained
|
||||
)
|
||||
|
||||
default:
|
||||
@@ -322,7 +311,7 @@ export const getSpellLibraryEntry = createLibraryEntryCreator<
|
||||
getToughness,
|
||||
}
|
||||
),
|
||||
...getTextForEffect(translation.effect, translate),
|
||||
...getTextForEffect(locale, translation.effect),
|
||||
{
|
||||
label: translate("Casting Time"),
|
||||
value:
|
||||
@@ -351,8 +340,9 @@ export const getSpellLibraryEntry = createLibraryEntryCreator<
|
||||
? `***${duration}*** (${translation.duration.full})`
|
||||
: duration,
|
||||
},
|
||||
getTextForTargetCategory(
|
||||
{ translate, translateMap, getTargetCategoryById },
|
||||
getTargetCategoryTranslation(
|
||||
getTargetCategoryById,
|
||||
locale,
|
||||
entry.target
|
||||
),
|
||||
getTextForProperty(
|
||||
@@ -397,7 +387,8 @@ export const getRitualLibraryEntry = createLibraryEntryCreator<
|
||||
getMagicalTraditionById,
|
||||
}
|
||||
) =>
|
||||
({ translate, translateMap, localeCompare }) => {
|
||||
(locale) => {
|
||||
const { translate, translateMap, compare: localeCompare } = locale
|
||||
const translation = translateMap(entry.translations)
|
||||
|
||||
if (translation === undefined) {
|
||||
@@ -407,31 +398,21 @@ export const getRitualLibraryEntry = createLibraryEntryCreator<
|
||||
const { castingTime, cost, range, duration } = (() => {
|
||||
switch (entry.parameters.tag) {
|
||||
case "OneTime":
|
||||
return getTextForSlowOneTimePerformanceParameters(
|
||||
{
|
||||
getSkillModificationLevelById,
|
||||
translate,
|
||||
translateMap,
|
||||
},
|
||||
entry.parameters.one_time,
|
||||
{
|
||||
entity: Entity.Ritual,
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
return getSlowOneTimePerformanceParametersTranslations(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Entity.Ritual,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.one_time
|
||||
)
|
||||
|
||||
case "Sustained":
|
||||
return getTextForSlowSustainedPerformanceParameters(
|
||||
{
|
||||
getSkillModificationLevelById,
|
||||
translate,
|
||||
translateMap,
|
||||
},
|
||||
entry.parameters.sustained,
|
||||
{
|
||||
entity: Entity.Ritual,
|
||||
responsiveText: ResponsiveTextSize.Full,
|
||||
}
|
||||
return getSlowSustainedPerformanceParametersTranslations(
|
||||
getSkillModificationLevelById,
|
||||
locale,
|
||||
Entity.Ritual,
|
||||
ResponsiveTextSize.Full,
|
||||
entry.parameters.sustained
|
||||
)
|
||||
|
||||
default:
|
||||
@@ -453,7 +434,7 @@ export const getRitualLibraryEntry = createLibraryEntryCreator<
|
||||
getToughness,
|
||||
}
|
||||
),
|
||||
...getTextForEffect(translation.effect, translate),
|
||||
...getTextForEffect(locale, translation.effect),
|
||||
{
|
||||
label: translate("Ritual Time"),
|
||||
value:
|
||||
@@ -482,8 +463,9 @@ export const getRitualLibraryEntry = createLibraryEntryCreator<
|
||||
? `***${duration}*** (${translation.duration.full})`
|
||||
: duration,
|
||||
},
|
||||
getTextForTargetCategory(
|
||||
{ translate, translateMap, getTargetCategoryById },
|
||||
getTargetCategoryTranslation(
|
||||
getTargetCategoryById,
|
||||
locale,
|
||||
entry.target
|
||||
),
|
||||
getTextForProperty(
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Compare } from "@optolith/helpers/compare"
|
||||
import { Translate, TranslateMap } from "./translate.js"
|
||||
|
||||
export type LocaleEnvironment = {
|
||||
id: string
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
compare: Compare<string>
|
||||
}
|
||||
+4
-7
@@ -1,7 +1,6 @@
|
||||
import { filterNonNullable } from "@optolith/helpers/array"
|
||||
import { Compare } from "@optolith/helpers/compare"
|
||||
import { PublicationRefs } from "optolith-database-schema/types/source/_PublicationRef"
|
||||
import { Translate, TranslateMap } from "./helpers/translate.js"
|
||||
import { LocaleEnvironment } from "./helpers/locale.js"
|
||||
|
||||
/**
|
||||
* Creates a function that creates the JSON representation of the rules text for
|
||||
@@ -40,11 +39,9 @@ export type LibraryEntryCreator<T, A = undefined, R = LibraryEntry> = (
|
||||
* A function that is already configures for a specific entity and returns the
|
||||
* JSON representation of the rules text for a ibrary entry.
|
||||
*/
|
||||
export type LibraryEntryConfiguredCreator<R = LibraryEntry> = (params: {
|
||||
translate: Translate
|
||||
translateMap: TranslateMap
|
||||
localeCompare: Compare<string>
|
||||
}) => R | undefined
|
||||
export type LibraryEntryConfiguredCreator<R = LibraryEntry> = (
|
||||
locale: LocaleEnvironment
|
||||
) => R | undefined
|
||||
|
||||
/**
|
||||
* A JSON representation of the rules text for a library entry.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"noImplicitThis": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noUncheckedSideEffectImports": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"outDir": "../lib",
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
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"
|
||||
|
||||
describe("getTextForCheckResultBased", () => {
|
||||
it("should return the value text for a check-result-based parameter of an activatable skill", () => {
|
||||
assert.equal(
|
||||
getCheckResultBasedValueTranslation(translateMock, {
|
||||
base: "QualityLevels",
|
||||
}),
|
||||
"QL"
|
||||
)
|
||||
assert.equal(
|
||||
getCheckResultBasedValueTranslation(translateMock, {
|
||||
base: "SkillPoints",
|
||||
}),
|
||||
"SP"
|
||||
)
|
||||
assert.equal(
|
||||
getCheckResultBasedValueTranslation(translateMock, {
|
||||
base: "QualityLevels",
|
||||
modifier: { arithmetic: "Divide", value: 2 },
|
||||
}),
|
||||
"QL / 2"
|
||||
)
|
||||
assert.equal(
|
||||
getCheckResultBasedValueTranslation(translateMock, {
|
||||
base: "SkillPoints",
|
||||
modifier: { arithmetic: "Multiply", value: 3 },
|
||||
}),
|
||||
"SP × 3"
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": ["esnext"],
|
||||
"module": "NodeNext",
|
||||
"noEmit": true,
|
||||
"noEmitHelpers": true,
|
||||
"noErrorTruncation": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noUncheckedSideEffectImports": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"strict": true,
|
||||
"target": "ESNext",
|
||||
"useUnknownInCatchVariables": true,
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../src" },
|
||||
]
|
||||
}
|
||||
@@ -2,5 +2,6 @@
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "src" },
|
||||
{ "path": "test" },
|
||||
],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user