build: extract ap function into other package
This commit is contained in:
Generated
+10
@@ -10,6 +10,7 @@
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"@elyukai/utils": "^0.2.8",
|
||||
"@optolith/adventure-points": "^0.1.1",
|
||||
"@optolith/helpers": "^0.2.2",
|
||||
"messageformat": "^4.0.0",
|
||||
"tsondb": "^0.19.8"
|
||||
@@ -811,6 +812,15 @@
|
||||
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@optolith/adventure-points": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@optolith/adventure-points/-/adventure-points-0.1.1.tgz",
|
||||
"integrity": "sha512-xfzZrs+4F+dBIQngAxnMSWExP9VUALrMQdR4Yrp3nve2OM2o+tx/ZsxyEoX7HYFZ0liICQ66FKjZ1kbfIMGrhQ==",
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"@elyukai/utils": "^0.2.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@optolith/helpers": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@optolith/helpers/-/helpers-0.2.2.tgz",
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"homepage": "https://github.com/Optolith/entity-descriptions#readme",
|
||||
"dependencies": {
|
||||
"@elyukai/utils": "^0.2.8",
|
||||
"@optolith/adventure-points": "^0.1.1",
|
||||
"@optolith/helpers": "^0.2.2",
|
||||
"messageformat": "^4.0.0",
|
||||
"tsondb": "^0.19.8"
|
||||
|
||||
@@ -38,7 +38,6 @@ import {
|
||||
} from "./partial/commonnessRatedAdvantagesAndDisadvantages.js"
|
||||
import { getProfessionName } from "./partial/professions.js"
|
||||
import { parensIf } from "./partial/rated/activatable/parensIf.js"
|
||||
import { calculateAdventurePointsFromImprovementCost } from "./partial/rated/improvementCost.js"
|
||||
import {
|
||||
translateR,
|
||||
type EnvMap,
|
||||
@@ -46,6 +45,7 @@ import {
|
||||
type StdReader,
|
||||
} from "./partial/reader.js"
|
||||
import { MISSING_VALUE } from "./partial/unknown.js"
|
||||
import { getAdventurePointsForRatingRange } from "@optolith/adventure-points/improvement-cost"
|
||||
|
||||
const renderListOperation = (
|
||||
operation: CommonProfessionConstraintsOperation,
|
||||
@@ -407,10 +407,7 @@ const renderCulturalPackage = (
|
||||
|
||||
return [
|
||||
`${instanceTranslation.name ?? MISSING_VALUE} ${sign(item.points)}`,
|
||||
calculateAdventurePointsFromImprovementCost(
|
||||
instance.improvement_cost,
|
||||
[1, item.points],
|
||||
),
|
||||
getAdventurePointsForRatingRange(instance.improvement_cost.kind, 0, item.points),
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { rangeSize, type RangeBounds } from "@elyukai/utils/range"
|
||||
import { assertExhaustive } from "@elyukai/utils/typeSafety"
|
||||
import type { ImprovementCost } from "optolith-database-schema/gen"
|
||||
import { type RawDefinitionListEntityDescriptionSectionItem } from "../../../index.js"
|
||||
import { translateR, type StdReader } from "../reader.js"
|
||||
@@ -7,9 +5,8 @@ import { translateR, type StdReader } from "../reader.js"
|
||||
/**
|
||||
* Renders an improvement cost value as a string.
|
||||
*/
|
||||
export const renderImprovementCostValue = (
|
||||
improvementCost: ImprovementCost,
|
||||
): string => improvementCost.kind
|
||||
export const renderImprovementCostValue = (improvementCost: ImprovementCost): string =>
|
||||
improvementCost.kind
|
||||
|
||||
/**
|
||||
* Returns the improvement cost as an inline library property.
|
||||
@@ -21,73 +18,3 @@ export const renderImprovementCost = (
|
||||
label,
|
||||
value: renderImprovementCostValue(improvementCost),
|
||||
}))
|
||||
|
||||
/**
|
||||
* Calculates the adventure points for an improvement cost.
|
||||
* @throws {RangeError} if the rating range is invalid (max < min).
|
||||
*/
|
||||
export const calculateAdventurePointsFromImprovementCost = (
|
||||
improvementCost:
|
||||
| ImprovementCost
|
||||
| ImprovementCost["kind"]
|
||||
| { kind: "E" }
|
||||
| "E",
|
||||
rating: number | RangeBounds = 1,
|
||||
): number => {
|
||||
const normalized =
|
||||
typeof improvementCost === "string" ? improvementCost : improvementCost.kind
|
||||
|
||||
const base = (() => {
|
||||
switch (normalized) {
|
||||
case "A":
|
||||
return 1
|
||||
case "B":
|
||||
return 2
|
||||
case "C":
|
||||
return 3
|
||||
case "D":
|
||||
return 4
|
||||
case "E":
|
||||
return 15
|
||||
default:
|
||||
return assertExhaustive(normalized)
|
||||
}
|
||||
})()
|
||||
|
||||
const lastRatingOfSameValue = (() => {
|
||||
switch (normalized) {
|
||||
case "A":
|
||||
case "B":
|
||||
case "C":
|
||||
case "D":
|
||||
return 12
|
||||
case "E":
|
||||
return 14
|
||||
default:
|
||||
return assertExhaustive(normalized)
|
||||
}
|
||||
})()
|
||||
|
||||
if (typeof rating === "number") {
|
||||
return (
|
||||
base *
|
||||
(rating < lastRatingOfSameValue ? 1 : rating - lastRatingOfSameValue + 1)
|
||||
)
|
||||
} else {
|
||||
const [min, max] = rating
|
||||
|
||||
if (max < min) {
|
||||
throw new RangeError(`Invalid rating range: ${min} - ${max}`)
|
||||
}
|
||||
|
||||
const size = rangeSize(rating)
|
||||
const constantRangeSize = Math.min(size, lastRatingOfSameValue - min + 1)
|
||||
const variableRangeSize = size - constantRangeSize
|
||||
|
||||
const constantCost = base * constantRangeSize
|
||||
const variableCost =
|
||||
base * (((variableRangeSize + 1) * (variableRangeSize + 2)) / 2 - 1)
|
||||
|
||||
return constantCost + variableCost
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import { equal, throws } from "node:assert/strict"
|
||||
import { describe, it } from "node:test"
|
||||
import { calculateAdventurePointsFromImprovementCost } from "../../../../src/entities/partial/rated/improvementCost.js"
|
||||
|
||||
describe("calculateAdventurePointsFromImprovementCost", () => {
|
||||
it("calculates the correct adventure points for a single rating", () => {
|
||||
equal(calculateAdventurePointsFromImprovementCost("A", 1), 1)
|
||||
equal(calculateAdventurePointsFromImprovementCost("A", 12), 1)
|
||||
equal(calculateAdventurePointsFromImprovementCost("A", 13), 2)
|
||||
equal(calculateAdventurePointsFromImprovementCost("A", 14), 3)
|
||||
equal(calculateAdventurePointsFromImprovementCost("A", 15), 4)
|
||||
equal(calculateAdventurePointsFromImprovementCost("D", 1), 4)
|
||||
equal(calculateAdventurePointsFromImprovementCost("D", 12), 4)
|
||||
equal(calculateAdventurePointsFromImprovementCost("D", 13), 8)
|
||||
equal(calculateAdventurePointsFromImprovementCost("D", 14), 12)
|
||||
equal(calculateAdventurePointsFromImprovementCost("D", 15), 16)
|
||||
equal(calculateAdventurePointsFromImprovementCost("E", 1), 15)
|
||||
equal(calculateAdventurePointsFromImprovementCost("E", 12), 15)
|
||||
equal(calculateAdventurePointsFromImprovementCost("E", 13), 15)
|
||||
equal(calculateAdventurePointsFromImprovementCost("E", 14), 15)
|
||||
equal(calculateAdventurePointsFromImprovementCost("E", 15), 30)
|
||||
equal(calculateAdventurePointsFromImprovementCost("E", 16), 45)
|
||||
})
|
||||
|
||||
it("calculates the correct adventure points for a rating range", () => {
|
||||
equal(calculateAdventurePointsFromImprovementCost("A", [1, 1]), 1)
|
||||
equal(calculateAdventurePointsFromImprovementCost("A", [1, 12]), 12)
|
||||
equal(calculateAdventurePointsFromImprovementCost("A", [1, 13]), 14)
|
||||
equal(calculateAdventurePointsFromImprovementCost("A", [1, 14]), 17)
|
||||
equal(calculateAdventurePointsFromImprovementCost("A", [1, 15]), 21)
|
||||
equal(calculateAdventurePointsFromImprovementCost("D", [1, 15]), 84)
|
||||
equal(calculateAdventurePointsFromImprovementCost("E", [1, 16]), 285)
|
||||
})
|
||||
|
||||
it("throws a RangeError for an invalid rating range", () => {
|
||||
throws(() => calculateAdventurePointsFromImprovementCost("A", [13, 12]), {
|
||||
name: "RangeError",
|
||||
message: "Invalid rating range: 13 - 12",
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user