101 lines
2.4 KiB
TypeScript
101 lines
2.4 KiB
TypeScript
/**
|
|
* Enum for game-wide event types.
|
|
*/
|
|
export enum Events {
|
|
DAMAGE_DEALT = 'combat:damage_dealt',
|
|
ENTITY_DIED = 'combat:entity_died',
|
|
EVOLVED = 'evolution:evolved',
|
|
MUTATION_GAINED = 'evolution:mutation_gained',
|
|
EXP_GAINED = 'stats:exp_gained',
|
|
LEVEL_UP = 'stats:level_up',
|
|
SKILL_LEARNED = 'skills:learned',
|
|
ATTACK_PERFORMED = 'combat:attack_performed',
|
|
SKILL_COOLDOWN_STARTED = 'skills:cooldown_started',
|
|
}
|
|
|
|
/**
|
|
* Event data types
|
|
*/
|
|
export interface DamageDealtEvent {
|
|
x: number;
|
|
y: number;
|
|
value: number;
|
|
color: string;
|
|
}
|
|
|
|
export interface MutationGainedEvent {
|
|
name: string;
|
|
description?: string;
|
|
}
|
|
|
|
export interface SkillLearnedEvent {
|
|
id: string;
|
|
}
|
|
|
|
export interface EntityDiedEvent {
|
|
entity: unknown;
|
|
}
|
|
|
|
export interface AttackPerformedEvent {
|
|
entity: unknown;
|
|
angle: number;
|
|
}
|
|
|
|
type EventCallback = (data?: unknown) => void;
|
|
|
|
/**
|
|
* Lightweight EventBus for pub/sub communication between systems.
|
|
*/
|
|
export class EventBus {
|
|
private listeners: Map<string, EventCallback[]>;
|
|
|
|
constructor() {
|
|
this.listeners = new Map();
|
|
}
|
|
|
|
/**
|
|
* Subscribe to an event with a callback.
|
|
* @param event - The event name from the Events enum
|
|
* @param callback - The function to call when the event is emitted
|
|
* @returns An unsubscribe function
|
|
*/
|
|
on(event: string, callback: EventCallback): () => void {
|
|
if (!this.listeners.has(event)) {
|
|
this.listeners.set(event, []);
|
|
}
|
|
const callbacks = this.listeners.get(event);
|
|
if (callbacks) {
|
|
callbacks.push(callback);
|
|
}
|
|
return () => this.off(event, callback);
|
|
}
|
|
|
|
/**
|
|
* Unsubscribe a specific callback from an event.
|
|
* @param event - The event name
|
|
* @param callback - The original callback function to remove
|
|
*/
|
|
off(event: string, callback: EventCallback): void {
|
|
if (!this.listeners.has(event)) return;
|
|
const callbacks = this.listeners.get(event);
|
|
if (callbacks) {
|
|
const index = callbacks.indexOf(callback);
|
|
if (index > -1) {
|
|
callbacks.splice(index, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Emit an event to all subscribers.
|
|
* @param event - The event name
|
|
* @param data - Data to pass to the callbacks
|
|
*/
|
|
emit(event: string, data?: unknown): void {
|
|
if (!this.listeners.has(event)) return;
|
|
const callbacks = this.listeners.get(event);
|
|
if (callbacks) {
|
|
callbacks.forEach((callback) => callback(data));
|
|
}
|
|
}
|
|
}
|