parent
5010facd74
commit
6e9c33f04a
@ -0,0 +1,321 @@ |
||||
import { |
||||
checkValidCurrentEnergy, |
||||
checkValidEnergy, |
||||
checkValidMaxStamina, damageEnergy, damageStamina, |
||||
Energy, |
||||
energyToString, isValidCurrentEnergy, |
||||
isValidEnergy, |
||||
isValidMaxStamina, recoverEnergy, recoverStamina, setCurrentEnergy, setCurrentStamina, setMaxStamina |
||||
} from "./Energy"; |
||||
import {assertion, AssertionConfig} from "./Assertions"; |
||||
|
||||
let originalConfig: AssertionConfig.Type |
||||
|
||||
beforeEach(() => { |
||||
originalConfig = assertion.config |
||||
assertion.config = AssertionConfig.Throw |
||||
}); |
||||
|
||||
afterEach(() => { |
||||
assertion.config = originalConfig |
||||
}); |
||||
|
||||
const InvalidEnergy: Energy = {maxStamina: 0, currentStamina: 0, currentEnergy: 0} |
||||
|
||||
describe("energyToString", () => { |
||||
const values: [Energy, string][] = [ |
||||
[{currentEnergy: 10, currentStamina: 20, maxStamina: 30}, "{Energy 10/20/30}"], |
||||
[{currentEnergy: 30, currentStamina: 30, maxStamina: 30}, "{Energy 30/30/30}"], |
||||
[{currentEnergy: 100, currentStamina: 5000, maxStamina: 9999}, "{Energy 100/5000/9999}"], |
||||
] |
||||
values.forEach(([energy, expected]) => { |
||||
test(`for ${JSON.stringify(energy)} returns "${expected}"`, () => { |
||||
expect(energyToString(energy)).toEqual(expected) |
||||
}) |
||||
}) |
||||
}) |
||||
|
||||
describe("isValidEnergy", () => { |
||||
const validValues: Energy[] = [ |
||||
{currentEnergy: 0, currentStamina: 0, maxStamina: 1}, |
||||
{currentEnergy: 99999, currentStamina: 99999, maxStamina: 99999}, |
||||
{currentEnergy: 10, currentStamina: 20, maxStamina: 30}, |
||||
{currentEnergy: 10, currentStamina: 30, maxStamina: 30}, |
||||
{currentEnergy: 10, currentStamina: 10, maxStamina: 30}, |
||||
] |
||||
validValues.forEach((energy) => { |
||||
test(`for ${energyToString(energy)} returns true`, () => { |
||||
expect(isValidEnergy(energy)).toEqual(true) |
||||
}) |
||||
}) |
||||
const invalidValues: Energy[] = [ |
||||
{currentEnergy: 0, currentStamina: 0, maxStamina: 0}, |
||||
{currentEnergy: 5, currentStamina: 3, maxStamina: 3}, |
||||
{currentEnergy: 5, currentStamina: 5, maxStamina: 3}, |
||||
{currentEnergy: 99999, currentStamina: 99999, maxStamina: 100000}, |
||||
] |
||||
invalidValues.forEach((energy) => { |
||||
test(`for ${energyToString(energy)} returns false`, () => { |
||||
expect(isValidEnergy(energy)).toEqual(false) |
||||
}) |
||||
}) |
||||
}) |
||||
|
||||
describe("isValidMaxStamina", () => { |
||||
const validValues: number[] = [1, 2, 1000, 99999] |
||||
validValues.forEach((maxEnergy) => { |
||||
test(`for ${maxEnergy} returns true`, () => { |
||||
expect(isValidMaxStamina(maxEnergy)).toBe(true) |
||||
}) |
||||
}) |
||||
const invalidValues: number[] = [0, -1, 100000, 0.5, NaN] |
||||
invalidValues.forEach((maxEnergy) => { |
||||
test(`for ${maxEnergy} returns false`, () => { |
||||
expect(isValidMaxStamina(maxEnergy)).toBe(false) |
||||
}) |
||||
}) |
||||
}) |
||||
|
||||
describe("isValidCurrentEnergy", () => { |
||||
const validValues: [number,number][] = [[0, 0], [0, 1], [2, 1000], [99999, 99999]] |
||||
validValues.forEach(([value, max]) => { |
||||
test(`for ${value}/${max} returns true`, () => { |
||||
expect(isValidCurrentEnergy(value, max)).toBe(true) |
||||
}) |
||||
}) |
||||
const invalidValues: [number,number][] = [[0, -1], [-1, -1], [0.5, 70], [NaN, 20]] |
||||
invalidValues.forEach(([value, max]) => { |
||||
test(`for ${value}/${max} returns false`, () => { |
||||
expect(isValidCurrentEnergy(value, max)).toBe(false) |
||||
}) |
||||
}) |
||||
}) |
||||
|
||||
describe("checkValidEnergy", () => { |
||||
test(`returns the input on success`, () => { |
||||
const energy = {currentEnergy: 99999, currentStamina: 99999, maxStamina: 99999} |
||||
expect(checkValidEnergy(energy)).toStrictEqual(energy) |
||||
}) |
||||
test(`throws on failure`, () => { |
||||
expect(() => checkValidEnergy({currentEnergy: 99999, currentStamina: 99999, maxStamina: 100000})).toThrow() |
||||
}) |
||||
}) |
||||
|
||||
describe("checkValidMaxStamina", function () { |
||||
test(`returns the input on success`, () => { |
||||
expect(checkValidMaxStamina(1)).toStrictEqual(1) |
||||
}) |
||||
test("throws on failure", () => { |
||||
expect(() => checkValidMaxStamina(NaN)).toThrow() |
||||
}) |
||||
}); |
||||
|
||||
describe("checkValidCurrentEnergy", function () { |
||||
test(`returns the input on success`, () => { |
||||
expect(checkValidCurrentEnergy(25, 50)).toStrictEqual(25) |
||||
}) |
||||
test("throws on failure", () => { |
||||
expect(() => checkValidCurrentEnergy(100, 50)).toThrow() |
||||
}) |
||||
}); |
||||
|
||||
describe("setMaxStamina", function () { |
||||
const invalidValues: [Energy, number][] = [ |
||||
[InvalidEnergy, 90], |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, 0], |
||||
] |
||||
invalidValues.forEach(([energy, max]) => { |
||||
test(`throws for ${energyToString(energy)} -> ${max}`, () => { |
||||
expect(() => setMaxStamina(energy, max)).toThrow() |
||||
}) |
||||
}) |
||||
const values: [Energy, number, Partial<Energy>][] = [ |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, 100, {}], |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, 10, {maxStamina: 10, currentStamina: 10, currentEnergy: 10}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 50, {maxStamina: 50}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 20, {maxStamina: 20, currentStamina: 20}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 10, {maxStamina: 10, currentStamina: 10}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 1, {maxStamina: 1, currentStamina: 1, currentEnergy: 1}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 150, {maxStamina: 150}], |
||||
] |
||||
values.forEach(([energy, max, expectedChanges]) => { |
||||
const expected = {...energy, ...expectedChanges} |
||||
test(`for ${energyToString(energy)} -> ${max} = ${energyToString(expected)}`, () => { |
||||
expect(setMaxStamina(energy, max)).toStrictEqual(expected) |
||||
}) |
||||
}) |
||||
}) |
||||
|
||||
describe("damageStamina", () => { |
||||
const invalidValues: [Energy, number][] = [ |
||||
[InvalidEnergy, 90], |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, -1], |
||||
] |
||||
invalidValues.forEach(([energy, damage]) => { |
||||
test(`for ${damage} on ${energyToString(energy)} throws`, () => { |
||||
expect(() => damageStamina(energy, damage, {damageEnergy: false})).toThrow() |
||||
}) |
||||
}) |
||||
const values: [Energy, number, {damageEnergy: boolean}, Partial<Energy>][] = [ |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 0, {damageEnergy: true}, {}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 0, {damageEnergy: false}, {}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 19, {damageEnergy: true}, {currentStamina: 61, currentEnergy: 41}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 19, {damageEnergy: false}, {currentStamina: 61}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 20, {damageEnergy: true}, {currentStamina: 60, currentEnergy: 40}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 20, {damageEnergy: false}, {currentStamina: 60}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 21, {damageEnergy: true}, {currentStamina: 59, currentEnergy: 39}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 21, {damageEnergy: false}, {currentStamina: 59, currentEnergy: 59}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 60, {damageEnergy: true}, {currentStamina: 20, currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 61, {damageEnergy: true}, {currentStamina: 19, currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 80, {damageEnergy: true}, {currentStamina: 0, currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 80, {damageEnergy: false}, {currentStamina: 0, currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 81, {damageEnergy: false}, {currentStamina: 0, currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 100, {damageEnergy: false}, {currentStamina: 0, currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 101, {damageEnergy: false}, {currentStamina: 0, currentEnergy: 0}], |
||||
] |
||||
values.forEach(([energy, damage, options, expectedChanges]) => { |
||||
const expected = {...energy, ...expectedChanges} |
||||
test(`for ${damage} on ${energyToString(energy)} with damageEnergy ${options.damageEnergy ? "on" : "off"} equals ${energyToString(expected)}`, () => { |
||||
expect(damageStamina(energy, damage, options)).toEqual(expected) |
||||
}) |
||||
}) |
||||
}) |
||||
|
||||
describe("recoverStamina", () => { |
||||
const invalidValues: [Energy, number][] = [ |
||||
[InvalidEnergy, 90], |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, -1], |
||||
] |
||||
invalidValues.forEach(([energy, recovery]) => { |
||||
test(`for ${recovery} on ${energyToString(energy)} throws`, () => { |
||||
expect(() => recoverStamina(energy, recovery, {recoverEnergy: false})).toThrow() |
||||
}) |
||||
}) |
||||
const values: [Energy, number, {recoverEnergy: boolean}, Partial<Energy>][] = [ |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 0, {recoverEnergy: true}, {}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 0, {recoverEnergy: false}, {}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 19, {recoverEnergy: true}, {currentStamina: 99, currentEnergy: 79}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 19, {recoverEnergy: false}, {currentStamina: 99}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 20, {recoverEnergy: true}, {currentStamina: 100, currentEnergy: 80}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 20, {recoverEnergy: false}, {currentStamina: 100}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 21, {recoverEnergy: true}, {currentStamina: 100, currentEnergy: 80}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 21, {recoverEnergy: false}, {currentStamina: 100}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 101, {recoverEnergy: true}, {currentStamina: 100, currentEnergy: 80}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 101, {recoverEnergy: false}, {currentStamina: 100}], |
||||
] |
||||
values.forEach(([energy, recovery, options, expectedChanges]) => { |
||||
const expected = {...energy, ...expectedChanges} |
||||
test(`for ${recovery} on ${energyToString(energy)} with recoverEnergy ${options.recoverEnergy ? "on" : "off"} equals ${energyToString(expected)}`, () => { |
||||
expect(recoverStamina(energy, recovery, options)).toEqual(expected) |
||||
}) |
||||
}) |
||||
}) |
||||
|
||||
describe("setCurrentStamina", function () { |
||||
const invalidValues: [Energy, number][] = [ |
||||
[InvalidEnergy, 90], |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, -1], |
||||
[{maxStamina: 105, currentStamina: 100, currentEnergy: 100}, 106], |
||||
] |
||||
invalidValues.forEach(([energy, value]) => { |
||||
test(`throws for ${energyToString(energy)} -> ${value}`, () => { |
||||
expect(() => setCurrentStamina(energy, value)).toThrow() |
||||
}) |
||||
}) |
||||
const values: [Energy, number, Partial<Energy>][] = [ |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, 100, {}], |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, 10, {currentStamina: 10, currentEnergy: 10}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 100, {currentStamina: 100}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 10, {currentStamina: 10}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 9, {currentStamina: 9, currentEnergy: 9}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 0, {currentStamina: 0, currentEnergy: 0}], |
||||
] |
||||
values.forEach(([energy, value, expectedChanges]) => { |
||||
const expected = {...energy, ...expectedChanges} |
||||
test(`for ${energyToString(energy)} -> ${value} = ${energyToString(expected)}`, () => { |
||||
expect(setCurrentStamina(energy, value)).toStrictEqual(expected) |
||||
}) |
||||
}) |
||||
}) |
||||
|
||||
describe("damageEnergy", () => { |
||||
const invalidValues: [Energy, number][] = [ |
||||
[InvalidEnergy, 90], |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, -1], |
||||
] |
||||
invalidValues.forEach(([energy, damage]) => { |
||||
test(`for ${damage} on ${energyToString(energy)} throws`, () => { |
||||
expect(() => damageEnergy(energy, damage)).toThrow() |
||||
}) |
||||
}) |
||||
const values: [Energy, number, Partial<Energy>][] = [ |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 0, {}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 19, {currentEnergy: 41}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 20, {currentEnergy: 40}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 21, {currentEnergy: 39}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 60, {currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 61, {currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 80, {currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 81, {currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 100, {currentEnergy: 0}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 101, {currentEnergy: 0}], |
||||
] |
||||
values.forEach(([energy, damage, expectedChanges]) => { |
||||
const expected = {...energy, ...expectedChanges} |
||||
test(`for ${damage} on ${energyToString(energy)} equals ${energyToString(expected)}`, () => { |
||||
expect(damageEnergy(energy, damage)).toEqual(expected) |
||||
}) |
||||
}) |
||||
}) |
||||
|
||||
describe("recoverEnergy", () => { |
||||
const invalidValues: [Energy, number][] = [ |
||||
[InvalidEnergy, 90], |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, -1], |
||||
] |
||||
invalidValues.forEach(([energy, recovery]) => { |
||||
test(`for ${recovery} on ${energyToString(energy)} throws`, () => { |
||||
expect(() => recoverEnergy(energy, recovery)).toThrow() |
||||
}) |
||||
}) |
||||
const values: [Energy, number, Partial<Energy>][] = [ |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 0, {}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 0, {}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 19, {currentEnergy: 79}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 20, {currentEnergy: 80}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 21, {currentEnergy: 80}], |
||||
[{maxStamina: 100, currentStamina: 80, currentEnergy: 60}, 101, {currentEnergy: 80}], |
||||
] |
||||
values.forEach(([energy, recovery, expectedChanges]) => { |
||||
const expected = {...energy, ...expectedChanges} |
||||
test(`for ${recovery} on ${energyToString(energy)} equals ${energyToString(expected)}`, () => { |
||||
expect(recoverEnergy(energy, recovery)).toEqual(expected) |
||||
}) |
||||
}) |
||||
}) |
||||
|
||||
describe("setCurrentEnergy", function () { |
||||
const invalidValues: [Energy, number][] = [ |
||||
[InvalidEnergy, 90], |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, -1], |
||||
[{maxStamina: 105, currentStamina: 80, currentEnergy: 60}, 106], |
||||
[{maxStamina: 105, currentStamina: 80, currentEnergy: 60}, 81], |
||||
] |
||||
invalidValues.forEach(([energy, value]) => { |
||||
test(`throws for ${energyToString(energy)} -> ${value}`, () => { |
||||
expect(() => setCurrentEnergy(energy, value)).toThrow() |
||||
}) |
||||
}) |
||||
const values: [Energy, number, Partial<Energy>][] = [ |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, 100, {}], |
||||
[{maxStamina: 100, currentStamina: 100, currentEnergy: 100}, 10, {currentEnergy: 10}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 9, {currentEnergy: 9}], |
||||
[{maxStamina: 100, currentStamina: 50, currentEnergy: 10}, 0, {currentEnergy: 0}], |
||||
] |
||||
values.forEach(([energy, value, expectedChanges]) => { |
||||
const expected = {...energy, ...expectedChanges} |
||||
test(`for ${energyToString(energy)} -> ${value} = ${energyToString(expected)}`, () => { |
||||
expect(setCurrentEnergy(energy, value)).toStrictEqual(expected) |
||||
}) |
||||
}) |
||||
}) |
@ -0,0 +1,161 @@ |
||||
import {assertion} from "./Assertions"; |
||||
|
||||
/** The interface managing a character's Stamina and Energy. */ |
||||
export interface Energy { |
||||
/** The character's maximum Stamina, which they are returned to when they rest. >= 1, <= 99999. */ |
||||
readonly maxStamina: number |
||||
/** The character's current Stamina, which their energy returns to when they complete a battle. >= 0, <= maxStamina. */ |
||||
readonly currentStamina: number |
||||
/** The character's current Energy, used for special abilities. >= 0, <= currentStamina. */ |
||||
readonly currentEnergy: number |
||||
} |
||||
|
||||
/** Formats the given Energy object into a string suitable for logging. Should never throw. */ |
||||
export function energyToString(energy: Energy): string { |
||||
return `{Energy ${energy.currentEnergy}/${energy.currentStamina}/${energy.maxStamina}}` |
||||
} |
||||
|
||||
/** |
||||
* Returns whether the given Energy object is valid, i.e., it has currentEnergy <= currentStamina <= maxStamina, and |
||||
* all three are positive integers or zero. |
||||
*/ |
||||
export function isValidEnergy(energy: Energy): boolean { |
||||
return isValidMaxStamina(energy.maxStamina) |
||||
&& isValidCurrentEnergy(energy.currentStamina, energy.maxStamina) |
||||
&& isValidCurrentEnergy(energy.currentEnergy, energy.currentStamina) |
||||
} |
||||
|
||||
/** Returns whether the given value is valid for max stamina, i.e., it's an integer between 1 and 99999. */ |
||||
export function isValidMaxStamina(maxStamina: number): boolean { |
||||
return Number.isSafeInteger(maxStamina) && maxStamina >= 1 && maxStamina <= 99999 |
||||
} |
||||
|
||||
/** Returns whether the given value is valid for current energy or stamina, i.e., it's an integer between 0 and max. */ |
||||
export function isValidCurrentEnergy(value: number, max: number): boolean { |
||||
return Number.isSafeInteger(value) && value >= 0 && value <= max |
||||
} |
||||
|
||||
/** Asserts that the given Energy object is valid (see the documentation for isValidEnergy). */ |
||||
export function checkValidEnergy(energy: Energy): Energy { |
||||
return assertion.check(energy, isValidEnergy, (energy) => `Invalid energy: ${energyToString(energy)}`) |
||||
} |
||||
|
||||
/** Asserts that the given value is valid for maxStamina. */ |
||||
export function checkValidMaxStamina(maxStamina: number): number { |
||||
return assertion.check(maxStamina, isValidMaxStamina, (maxStamina) => `Invalid max stamina: ${maxStamina}`) |
||||
} |
||||
|
||||
/** Asserts that the given value is valid for currentStamina or currentEnergy. */ |
||||
export function checkValidCurrentEnergy(value: number, max: number): number { |
||||
return assertion.check(value, (value) => isValidCurrentEnergy(value, max), (value) => `Invalid current energy: ${value}`) |
||||
} |
||||
|
||||
/** |
||||
* Sets the max stamina value on the given Energy. This may result in the currentStamina (and possibly currentEnergy) |
||||
* values decreasing to fit under the new ceiling. |
||||
*/ |
||||
export function setMaxStamina(energy: Energy, maxStamina: number): Energy { |
||||
checkValidEnergy(energy) |
||||
checkValidMaxStamina(maxStamina) |
||||
|
||||
const currentStamina = Math.min(energy.currentStamina, maxStamina) |
||||
const currentEnergy = Math.min(energy.currentEnergy, currentStamina) |
||||
|
||||
return checkValidEnergy({...energy, maxStamina, currentStamina, currentEnergy}) |
||||
} |
||||
|
||||
/** |
||||
* Deals damage to the Stamina of the given Energy. currentStamina will be decreased; currentEnergy will also be |
||||
* decreased if damageEnergy is true, or if the new Stamina is lower than the Energy. Neither can drop below 0 this way. |
||||
*/ |
||||
export function damageStamina(energy: Energy, damage: number, options: {damageEnergy: boolean}): Energy { |
||||
checkValidEnergy(energy) |
||||
assertion.checkPositiveIntegerOrZero(damage, () => `Invalid damage: ${damage}`) |
||||
|
||||
const currentStamina = Math.max(0, energy.currentStamina - damage) |
||||
const currentEnergy = options.damageEnergy ? Math.max(0, energy.currentEnergy - damage) : Math.min(energy.currentEnergy, currentStamina) |
||||
|
||||
return checkValidEnergy({ |
||||
...energy, |
||||
currentStamina, |
||||
currentEnergy, |
||||
}) |
||||
} |
||||
|
||||
/** |
||||
* Recovers the Stamina of the given Energy. currentStamina will be increased; currentEnergy will also be increased |
||||
* if recoverEnergy is true. Neither can exceed maxStamina this way. |
||||
*/ |
||||
export function recoverStamina(energy: Energy, recovery: number, options: {recoverEnergy: boolean}): Energy { |
||||
checkValidEnergy(energy) |
||||
assertion.checkPositiveIntegerOrZero(recovery, () => `Invalid healing: ${recovery}`) |
||||
|
||||
const currentStamina = Math.min(energy.maxStamina, energy.currentStamina + recovery) |
||||
const currentEnergy = options.recoverEnergy ? energy.currentEnergy + (currentStamina - energy.currentStamina) : energy.currentEnergy |
||||
|
||||
return checkValidEnergy({ |
||||
...energy, |
||||
currentStamina, |
||||
currentEnergy, |
||||
}) |
||||
} |
||||
|
||||
/** |
||||
* Sets the Stamina of the given Energy. currentEnergy will be decreased if it's lower than the new Stamina. |
||||
*/ |
||||
export function setCurrentStamina(energy: Energy, value: number): Energy { |
||||
checkValidEnergy(energy) |
||||
checkValidCurrentEnergy(value, energy.maxStamina) |
||||
|
||||
const currentStamina = value |
||||
const currentEnergy = Math.min(currentStamina, energy.currentEnergy) |
||||
|
||||
return checkValidEnergy({ |
||||
...energy, |
||||
currentStamina, |
||||
currentEnergy |
||||
}) |
||||
} |
||||
|
||||
/** |
||||
* Deals damage to the Energy of the given Energy. It can't drop below 0 this way. |
||||
*/ |
||||
export function damageEnergy(energy: Energy, damage: number): Energy { |
||||
checkValidEnergy(energy) |
||||
assertion.checkPositiveIntegerOrZero(damage, () => `Invalid damage: ${damage}`) |
||||
|
||||
const currentEnergy = Math.max(0, energy.currentEnergy - damage) |
||||
|
||||
return checkValidEnergy({ |
||||
...energy, |
||||
currentEnergy, |
||||
}) |
||||
} |
||||
|
||||
/** |
||||
* Recovers the Energy of the given Energy. It can't exceed currentStamina this way. |
||||
*/ |
||||
export function recoverEnergy(energy: Energy, recovery: number): Energy { |
||||
checkValidEnergy(energy) |
||||
assertion.checkPositiveIntegerOrZero(recovery, () => `Invalid healing: ${recovery}`) |
||||
|
||||
const currentEnergy = Math.min(energy.currentStamina, energy.currentEnergy + recovery) |
||||
|
||||
return checkValidEnergy({ |
||||
...energy, |
||||
currentEnergy |
||||
}) |
||||
} |
||||
|
||||
/** |
||||
* Sets the current Energy of the given Energy. |
||||
*/ |
||||
export function setCurrentEnergy(energy: Energy, value: number): Energy { |
||||
checkValidEnergy(energy) |
||||
checkValidCurrentEnergy(value, energy.currentStamina) |
||||
|
||||
return checkValidEnergy({ |
||||
...energy, |
||||
currentEnergy: value |
||||
}) |
||||
} |
Loading…
Reference in new issue