46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
/**
|
|
* MagicalObject — shared base for all magical items in the game.
|
|
*
|
|
* Invariants enforced at construction:
|
|
* - Health is non-negative
|
|
* - Health never exceeds maxHealth
|
|
* - Status derived from health (0 = destroyed, > 0 = alive)
|
|
*/
|
|
|
|
export type MagicalObjectStatus = { readonly kind: 'alive' } | { readonly kind: 'destroyed' };
|
|
|
|
export class MagicalObject {
|
|
readonly #health: number;
|
|
readonly #maxHealth: number;
|
|
readonly #status: MagicalObjectStatus;
|
|
|
|
protected constructor(health: number, maxHealth: number, status: MagicalObjectStatus) {
|
|
this.#health = health;
|
|
this.#maxHealth = maxHealth;
|
|
this.#status = status;
|
|
}
|
|
|
|
get health(): number {
|
|
return this.#health;
|
|
}
|
|
|
|
get maxHealth(): number {
|
|
return this.#maxHealth;
|
|
}
|
|
|
|
get status(): MagicalObjectStatus {
|
|
return this.#status;
|
|
}
|
|
|
|
/** Create a destroyed object (health = 0). */
|
|
static createDestroyed(maxHealth: number): MagicalObject {
|
|
if (maxHealth < 0) throw new Error('MaxHealth cannot be negative');
|
|
return new MagicalObject(0, maxHealth, { kind: 'destroyed' });
|
|
}
|
|
|
|
/** Check if this object is alive. */
|
|
isAlive(): boolean {
|
|
return this.#status.kind === 'alive';
|
|
}
|
|
}
|