fix: render ap value from explicit select options
This commit is contained in:
@@ -19,6 +19,62 @@ import type { BaseActivatable, BaseActivatableTranslation } from "../activatable
|
||||
import { evaluateMathOperation } from "./mathOperation.js"
|
||||
import { MISSING_VALUE } from "./unknown.js"
|
||||
|
||||
const typographicSign = (num: number): string => (num > 0 ? "" : "−") + Math.abs(num).toFixed()
|
||||
|
||||
const renderFixedSelectOptionsAdventurePointsValue = (
|
||||
locale: LocaleEnvironment,
|
||||
getAllSelectOptions: () => ResolvedSelectOption[],
|
||||
getNameForSelectOptionId: (id: ResolvedSelectOptionIdentifier) => string | undefined,
|
||||
getApValueForSelectOption: (
|
||||
item: ResolvedSelectOption,
|
||||
id: ResolvedSelectOptionIdentifier,
|
||||
) => number | string,
|
||||
applyNegative: (numValue: number) => number,
|
||||
) => {
|
||||
const entriesMap = Map.groupBy(
|
||||
getAllSelectOptions().map((item): [apValue: number | string, item: ResolvedSelectOption] => [
|
||||
getApValueForSelectOption(item, item.id),
|
||||
item,
|
||||
]),
|
||||
item => item[0],
|
||||
)
|
||||
.entries()
|
||||
.toArray()
|
||||
|
||||
if (
|
||||
entriesMap.every(
|
||||
(entry): entry is [number, [[apValue: number, item: ResolvedSelectOption]]] =>
|
||||
typeof entry[0] === "number" && entry[1].length === 1,
|
||||
)
|
||||
) {
|
||||
const entriesSortedByApValue = entriesMap.toSorted(on(item => item[0], numAsc))
|
||||
return entriesSortedByApValue
|
||||
.map(entry => locale.translateMap(entry[1][0][1].content.translations)?.name ?? MISSING_VALUE)
|
||||
.join("/")
|
||||
.concat(
|
||||
`: ${locale.translate("{$value} Adventure Points", { value: entriesSortedByApValue.map(entry => typographicSign(applyNegative(entry[0]))).join("/") })}`,
|
||||
)
|
||||
} else {
|
||||
return entriesMap
|
||||
.map(([apValue, items]): [number | string, string] => [
|
||||
apValue,
|
||||
locale.join(
|
||||
items
|
||||
.map(item => getNameForSelectOptionId(item[1].id))
|
||||
.filter(name => name !== undefined)
|
||||
.toSorted(locale.compare),
|
||||
"conjunction",
|
||||
),
|
||||
])
|
||||
.toSorted(on(item => item[1], locale.compare))
|
||||
.map(
|
||||
([apValue, itemNames]) =>
|
||||
`${itemNames}: ${locale.translate("{$value} Adventure Points", { value: typeof apValue === "number" ? applyNegative(apValue) : apValue })}`,
|
||||
)
|
||||
.join("; ")
|
||||
}
|
||||
}
|
||||
|
||||
const renderSelectOptionsAdventurePointsValue = <T extends ResolvedSelectOptionIdentifier>(
|
||||
locale: LocaleEnvironment,
|
||||
derivedLabel: () => string,
|
||||
@@ -43,32 +99,15 @@ const renderSelectOptionsAdventurePointsValue = <T extends ResolvedSelectOptionI
|
||||
})}`
|
||||
}
|
||||
case "Fixed":
|
||||
return Map.groupBy(
|
||||
getAllSelectOptions().map((item): [apValue: number, item: ResolvedSelectOption] => [
|
||||
return renderFixedSelectOptionsAdventurePointsValue(
|
||||
locale,
|
||||
getAllSelectOptions,
|
||||
getNameForSelectOptionId,
|
||||
item =>
|
||||
config.Fixed.map.find(mapItem => deepEqual(mapItem.id, item.id))?.ap_value ??
|
||||
config.Fixed.default,
|
||||
item,
|
||||
]),
|
||||
item => item[0],
|
||||
config.Fixed.default,
|
||||
applyNegative,
|
||||
)
|
||||
.entries()
|
||||
.map(([apValue, items]): [number, string] => [
|
||||
apValue,
|
||||
locale.join(
|
||||
items
|
||||
.map(item => getNameForSelectOptionId(item[1].id))
|
||||
.filter(name => name !== undefined)
|
||||
.toSorted(locale.compare),
|
||||
"conjunction",
|
||||
),
|
||||
])
|
||||
.toArray()
|
||||
.toSorted(on(item => item[1], locale.compare))
|
||||
.map(
|
||||
([apValue, itemNames]) =>
|
||||
`${itemNames}: ${locale.translate("{$value} Adventure Points", { value: applyNegative(apValue) })}`,
|
||||
)
|
||||
.join("; ")
|
||||
default:
|
||||
return assertExhaustive(config)
|
||||
}
|
||||
@@ -137,7 +176,31 @@ export const renderAdventurePointsValue = (
|
||||
case "DerivedFromSelection": {
|
||||
const derivedSelectOptions = entry.select_options?.derived
|
||||
if (derivedSelectOptions === undefined) {
|
||||
return MISSING_VALUE
|
||||
return renderFixedSelectOptionsAdventurePointsValue(
|
||||
locale,
|
||||
getAllSelectOptions,
|
||||
getNameForSelectOptionId,
|
||||
item => {
|
||||
switch (item.content.ap_value?.kind) {
|
||||
case "Fixed":
|
||||
return item.content.ap_value.Fixed
|
||||
case "DependingOnActiveInstances":
|
||||
switch (item.content.ap_value.DependingOnActiveInstances.kind) {
|
||||
case "Threshold":
|
||||
return item.content.ap_value.DependingOnActiveInstances.Threshold.normal
|
||||
case "Expression":
|
||||
return MISSING_VALUE
|
||||
default:
|
||||
return assertExhaustive(item.content.ap_value.DependingOnActiveInstances)
|
||||
}
|
||||
case undefined:
|
||||
return MISSING_VALUE
|
||||
default:
|
||||
return assertExhaustive(item.content.ap_value)
|
||||
}
|
||||
},
|
||||
applyNegative,
|
||||
)
|
||||
}
|
||||
switch (derivedSelectOptions.kind) {
|
||||
case "Blessings":
|
||||
|
||||
Reference in New Issue
Block a user