import { BuildingNode, emitter, EventSuffix, ItemEvent, ItemNode, WallEvent, WallNode, } from "@pascal-app/core"; import { ThreeEvent } from "@react-three/fiber"; import { BuildingEvent } from "../../../core/src/events/bus"; type NodeConfig = { item: { node: ItemNode; event: ItemEvent }; wall: { node: WallNode; event: WallEvent }; building: { node: BuildingNode; event: BuildingEvent }; }; type NodeType = keyof NodeConfig; export function useNodeEvents( node: NodeConfig[T]["node"], type: T, ) { const emit = (suffix: EventSuffix, e: ThreeEvent) => { const eventKey = `${type}:${suffix}` as `${T}:${EventSuffix}`; const localPoint = e.object.worldToLocal(e.point.clone()); const payload = { node, position: [e.point.x, e.point.y, e.point.z], localPosition: [localPoint.x, localPoint.y, localPoint.z], normal: e.face ? [e.face.normal.x, e.face.normal.y, e.face.normal.z] : undefined, stopPropagation: () => e.stopPropagation(), } as NodeConfig[T]["event"]; emitter.emit(eventKey, payload); }; return { onPointerDown: (e: ThreeEvent) => { if (e.button !== 0) return; emit("pointerdown", e); }, onPointerUp: (e: ThreeEvent) => { if (e.button !== 0) return; emit("pointerup", e); }, onClick: (e: ThreeEvent) => { if (e.button !== 0) return; emit("click", e); }, onPointerEnter: (e: ThreeEvent) => emit("enter", e), onPointerLeave: (e: ThreeEvent) => emit("leave", e), onPointerMove: (e: ThreeEvent) => emit("move", e), onDoubleClick: (e: ThreeEvent) => emit("double-click", e), onContextMenu: (e: ThreeEvent) => emit("context-menu", e), }; }