import { World } from './world'; import { addBridge } from 'scriptcraft-core'; import { PlayerEntity } from './entity'; import { ActionResult, Hand, Pos, Direction } from './core'; /** * Event * @typeParam T Event Data Type * @typeParam K Event Return Type */ export class Event { #listeners: ((obj: T) => K)[] = []; #defaultValue: K; /** * Create Event * @param defaultValue Default Return Value If There Are No Events (Can be Null) */ constructor(defaultValue: K) { this.#defaultValue = defaultValue; } /** * Add Event Listener * @param listener Event Listener */ addListener(listener: (obj: T) => K): void { this.#listeners.push(listener); } /** * Remove Event Listener * @param listener Event Listener */ removeListener(listener: (obj: T) => K): void { const index = this.#listeners.indexOf(listener, 0); if (index > -1) { this.#listeners.splice(index, 1); } } /** * Trigger Event * @param obj Event Data * @returns Event Return Value */ trigger(obj: T): K { for (const listener of this.#listeners) { const value = listener(obj); if (this.#defaultValue !== null && value != this.#defaultValue) { return value; } } return this.#defaultValue; } } /** * World Event */ export class WorldEvent { readonly #world: World; /** * Get World * @returns World */ getWorld(): World { return this.#world; } /** * Create World Event * @param world World */ constructor(world: World) { this.#world = world; } } /** * Block Event */ export class BlockEvent { readonly #world: World; readonly #player: PlayerEntity; readonly #hand: Hand; readonly #pos: Pos; readonly #side: Direction; /** * Get World * @returns World */ getWorld(): World { return this.#world; } /** * Get Player * @returns Player */ getPlayer(): PlayerEntity { return this.#player; } /** * Get Hand * @returns Hand */ getHand(): Hand { return this.#hand; } /** * Get Block Position * @returns Block Position */ getPos(): Pos { return this.#pos; } /** * Get Block Side * @returns Block Side */ getSide(): Direction { return this.#side; } /** * Create Block Event * @param player Player * @param world World * @param hand Hand * @param pos Position * @param side Block Side */ constructor(player: PlayerEntity, world: World, hand: Hand, pos: Pos, side: Direction) { this.#player = player; this.#world = world; this.#hand = hand; this.#pos = pos; this.#side = side; } } /** * Item Event */ export class ItemEvent { readonly #world: World; readonly #player: PlayerEntity; readonly #hand: Hand; /** * Get World * @returns World */ getWorld(): World { return this.#world; } /** * Get Player * @returns Player */ getPlayer(): PlayerEntity { return this.#player; } /** * Get Hand * @returns Hand */ getHand(): Hand { return this.#hand; } /** * Create Item Event * @param player Player * @param world World * @param hand Hand */ constructor(player: PlayerEntity, world: World, hand: Hand) { this.#player = player; this.#world = world; this.#hand = hand; } } /** * All Events */ export class Events { /** * World Tick Event */ static WORLD_TICK = new Event(null); /** * Attack Block Event */ static ATTACK_BLOCK = new Event(ActionResult.PASS); /** * Use Block Event */ static USE_BLOCK = new Event(ActionResult.PASS); /** * Use Item Event */ static USE_ITEM = new Event(ActionResult.PASS); } addBridge('Event.worldTick', (world: JavaObject) => Events.WORLD_TICK.trigger(new WorldEvent(new World(world)))); addBridge('Event.attackBlock', (player: JavaObject, world: JavaObject, hand: keyof typeof Hand, x: number, y: number, z: number, side: keyof typeof Direction) => Events.ATTACK_BLOCK.trigger(new BlockEvent(new PlayerEntity(player), new World(world), Hand[hand], new Pos(x, y, z), Direction[side]))); addBridge('Event.useBlock', (player: JavaObject, world: JavaObject, hand: keyof typeof Hand, x: number, y: number, z: number, side: keyof typeof Direction) => Events.USE_BLOCK.trigger(new BlockEvent(new PlayerEntity(player), new World(world), Hand[hand], new Pos(x, y, z), Direction[side]))); addBridge('Event.useItem', (player: JavaObject, world: JavaObject, hand: keyof typeof Hand) => Events.USE_ITEM.trigger(new ItemEvent(new PlayerEntity(player), new World(world), Hand[hand])));