import { WritableSignal } from 'canvasengine'; import { Hooks } from '@rpgjs/common'; export interface ClientProjectileSpawn { id: string; type: string; ownerId?: string; origin: { x: number; y: number; }; direction: { x: number; y: number; }; speed: number; range: number; ttl: number; spawnTick: number; delay?: number; index?: number; count?: number; params?: Record; collisionMask?: number; ignoreOwner?: boolean; predictImpact?: boolean; } export interface ClientProjectileImpact { id: string; targetId?: string; x: number; y: number; distance?: number; } export interface ClientProjectileDestroy { id: string; reason?: string; targetId?: string; x?: number; y?: number; distance?: number; } export interface RenderedProjectileProps extends ClientProjectileSpawn { x: number; y: number; angle: number; distance: number; elapsed: number; progress: number; impact?: ClientProjectileImpact; impactElapsed?: number; impactProgress?: number; destroyed?: boolean; } export interface RenderedProjectile { id: string; type: string; component: any; props: RenderedProjectileProps; } export type ProjectilePredictionResolver = (projectile: ClientProjectileSpawn) => ClientProjectileImpact | null | undefined; export interface ProjectileSpawnClock { now?: number; currentServerTick?: number; tickDurationMs?: number; mapId?: string; } /** Props that change while a projectile is rendered. */ type ProjectileDynamicProp = typeof PROJECTILE_DYNAMIC_PROPS[number]; /** * Props of a rendered projectile component: spawn data as plain values and the * props that change over time as signals updated every step. */ export type ProjectileRenderProps = Omit & { [K in ProjectileDynamicProp]-?: WritableSignal; }; /** Item of `ProjectileManager.renderList`. */ export interface ProjectileRenderItem { id: string; type: string; component: any; props: ProjectileRenderProps; } declare const PROJECTILE_DYNAMIC_PROPS: readonly ["x", "y", "angle", "distance", "elapsed", "progress", "impact", "impactElapsed", "impactProgress", "destroyed"]; export declare class ProjectileManager { private readonly hooks; private readonly predictionResolver?; private readonly components; private readonly projectiles; private readonly version; /** Changes only when projectiles appear or disappear, not on every step. */ private readonly structureVersion; private readonly impactDurationMs; private mapId?; constructor(hooks: Hooks, predictionResolver?: ProjectilePredictionResolver | undefined); current: import('canvasengine').ComputedSignal; /** * Projectiles to render, with reactive props. * * Unlike `current`, this list only changes when a projectile appears or * disappears; positions and progress are pushed into each item's signals by * `step()`, so rendered components are not rebuilt on every frame. */ renderList: import('canvasengine').ComputedSignal; register(type: string, component: any): any; get(type: string): any; setMapId(mapId: string | undefined): void; getMapId(): string | undefined; spawnBatch(projectiles: ClientProjectileSpawn[], clock?: ProjectileSpawnClock): void; impactBatch(impacts: ClientProjectileImpact[], context?: { mapId?: string; }): void; destroyBatch(projectiles: ClientProjectileDestroy[], context?: { mapId?: string; }): void; clear(): void; step(): void; private toProps; private acceptsMap; private isWaitingForDelay; private setPredictedImpact; private getActivePredictedImpact; private setImpact; private resolveVisualImpact; private isSameTarget; private touch; private syncRenderProps; } export {};