import type { PhysicsWorld } from "./physicsWorld.js"; export interface GrappleConfig { /** Metres per second the rope shortens under `reel` / lengthens under `payOut`. Default 8. */ reelSpeed?: number; /** Rope refuses to shorten past this — the traveller stops on top of the anchor, not inside it. Default 1.5. */ minLength?: number; /** Firing range; `fire` beyond this misses. Default 40. */ maxLength?: number; /** Elastic rope (spring) that yanks and bounces, vs a rigid `distance` cable that holds a hard length. Default false. */ elastic?: boolean; /** Spring restoring rate when `elastic`. Default 40. */ stiffness?: number; /** Spring damping when `elastic`. Default 6. */ damping?: number; } /** * A fired-anchor rope on the joint API — grapple (reel toward a hit point), zipline (rigid cable to a * far anchor you then slide/reel along), swing (rigid rope + gravity = a pendulum). `fire` attaches a * `distance`/`spring` joint from the traveller body to a fixed world point; `reel` shrinks its rest * length so the constraint drags the body in; `moveAnchor` re-points it (zipline glide, grapple-to- * moving-target). The pick — a raycast to find the anchor — is the caller's; core owns the constraint. */ export declare class Grapple { readonly body: number; private readonly world; private readonly reelSpeed; private readonly minLength; private readonly maxLength; private readonly elastic; private readonly stiffness; private readonly damping; private joint; private length; private ax; private ay; private az; constructor(world: PhysicsWorld, body: number, config?: GrappleConfig); get attached(): boolean; get ropeLength(): number; anchor(): readonly [number, number, number] | null; distanceToAnchor(): number; /** Attach to a world anchor point. Returns false (a miss) when the point is beyond `maxLength`. */ fire(x: number, y: number, z: number): boolean; /** Shorten the rope by `reelSpeed * dt`, pulling the traveller toward the anchor. Clamps at `minLength`. */ reel(dt: number): void; /** Pay out slack, lengthening the rope up to `maxLength`. */ payOut(dt: number): void; /** Re-point the anchor (slide a zipline attachment along the cable, or track a moving target). */ moveAnchor(x: number, y: number, z: number): void; release(): void; } export interface GlideConfig { /** Fraction of world gravity the glider still feels — 1 is normal fall, 0 hangs. Default 0.25. */ gravityScale?: number; /** Forward acceleration applied along the steer vector each `apply`. Default 6. */ thrust?: number; /** Terminal descent clamp so a glide never plummets. Default 8. */ maxFallSpeed?: number; } /** * A reduced-gravity, forward-thrust glide over a physics body — wingsuit / glider / paraglider * (Enshrouded, Grounded). Call `apply(dt, steerX, steerZ)` each frame *before* `world.step`: it feeds * back most of the gravity the sim is about to apply (leaving `gravityScale` of it), pushes the body * along the steer vector by `thrust`, and clamps descent to `maxFallSpeed`. Stop calling it to fall * normally again — no attach/detach state to leak. */ export declare class Glide { readonly body: number; private readonly world; private readonly gravityScale; private readonly thrust; private readonly maxFallSpeed; constructor(world: PhysicsWorld, body: number, config?: GlideConfig); apply(dt: number, steerX?: number, steerZ?: number): void; }