- Fix Allium spec syntax: type→value, enum for Status, remove implies chaining - Fix factions.spec: add missing type declarations (Health, Level, Status) - Fix magical-objects.spec: add type declarations, use .value for Health access, remove entity inheritance syntax, remove invalid invariants - Implement Changing Level: add totalDamageTaken + factionsJoined to Character - Add level-up logic in dealDamage() and joinFaction() - Add Level.damageThresholdForLevel() static method - Fix changing-level.spec.ts properties: handle target survival, compute expected level from threshold crossings
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
/**
|
|
* Level value object — constrained to 1..10.
|
|
*
|
|
* "I can't believe it's not Haskell": invalid states are unrepresentable.
|
|
* Level progression (next) and combat modifiers (diff) belong to later stories.
|
|
*/
|
|
export class Level {
|
|
#value: number;
|
|
|
|
private constructor(n: number) {
|
|
this.#value = n;
|
|
}
|
|
|
|
static create(n: number): Level {
|
|
if (n < 1 || n > 10) {
|
|
throw new Error(`Level must be between 1 and 10, got ${n}`);
|
|
}
|
|
return new Level(n);
|
|
}
|
|
|
|
get value(): number {
|
|
return this.#value;
|
|
}
|
|
|
|
/** Maximum health for this level: 1000 until level 6, 1500 from level 6 onward. */
|
|
static maxHealthForLevel(level: number): number {
|
|
return level >= 6 ? 1500 : 1000;
|
|
}
|
|
|
|
/** Signed level difference: this level minus target level. Positive = this is higher. */
|
|
diff(target: Level): number {
|
|
return this.value - target.value;
|
|
}
|
|
|
|
/** Damage threshold to reach the given level.
|
|
* Level 1→2: 1000, Level 2→3: 3000, Level 3→4: 6000, etc.
|
|
* Formula: 1000 * N * (N+1) / 2
|
|
*/
|
|
static damageThresholdForLevel(level: number): number {
|
|
return (1000 * level * (level + 1)) / 2;
|
|
}
|
|
}
|