import { Hooks, RpgCommonPlayer, Direction, AttachShapeOptions, RpgShape, I18nParams, RpgContext, RpgReadableSignal, RpgWritableSignal, RpgRoomTarget, SaveSlotMeta } from '@rpgjs/common'; import { Vector2 } from '@rpgjs/physic'; import { IComponentManager } from './ComponentManager'; import { RpgMap, EventPosOption } from '../rooms/map'; import { IGuiManager } from './GuiManager'; import { IMoveManager } from './MoveManager'; import { IGoldManager } from './GoldManager'; import { IVariableManager } from './VariableManager'; import { IParameterManager } from './ParameterManager'; import { IItemManager } from './ItemManager'; import { IEffectManager } from './EffectManager'; import { IElementManager } from './ElementManager'; import { ISkillManager } from './SkillManager'; import { IBattleManager } from './BattleManager'; import { IClassManager } from './ClassManager'; import { IStateManager } from './StateManager'; import { IHotbarManager } from './HotbarManager'; import { SaveRequestContext, SaveSlotIndex } from '../services/save'; import { RpgPlayerProjectiles } from '../projectiles'; import { RpgPlayerSaveResult, RpgPlayerSlotLoadResult, RpgPlayerSnapshot, RpgPlayerSnapshotLoadResult, RpgSyncSchema } from './types'; export interface RpgTiledTile { [key: string]: unknown; } type CameraFollowEase = "linear" | "easeInQuad" | "easeOutQuad" | "easeInOutQuad" | "easeInCubic" | "easeOutCubic" | "easeInOutCubic" | "easeInQuart" | "easeOutQuart" | "easeInOutQuart" | "easeInQuint" | "easeOutQuint" | "easeInOutQuint" | "easeInSine" | "easeOutSine" | "easeInOutSine" | "easeInExpo" | "easeOutExpo" | "easeInOutExpo" | "easeInCirc" | "easeOutCirc" | "easeInOutCirc" | "easeInElastic" | "easeOutElastic" | "easeInOutElastic" | "easeInBack" | "easeOutBack" | "easeInOutBack" | "easeInBounce" | "easeOutBounce" | "easeInOutBounce"; /** * RPG Player class with component management capabilities * * Combines all player mixins to provide a complete player implementation * with graphics, movement, inventory, skills, and battle capabilities. * * @example * ```ts * // Create a new player * const player = new RpgPlayer(); * * // Set player graphics * player.setGraphic("hero"); * * // Add parameters and items * player.addParameter("strength", { start: 10, end: 100 }); * player.addItem(sword); * ``` */ /** Structural contract shared by lobby, map, and custom gameplay rooms. */ export interface RpgPlayerRoom { $send(connection: Parameters[0], packet: unknown): void; $sessionTransfer(connection: Parameters[0], roomId: string): Promise; } declare const RpgPlayer_base: typeof RpgCommonPlayer; export declare class RpgPlayer extends RpgPlayer_base { map: RpgMap | null; /** Active RPGJS room. Unlike `map`, this also covers non-spatial gameplay rooms. */ room: RpgPlayerRoom | null; context?: RpgContext; conn: Parameters[0] | null; touchSide: boolean; private continueMovementOnNextMapChange; private _clientListeners; private _projectiles?; private locale?; private _syncChangesDepth; /** * Computed signal for world X position * * Calculates the absolute world X position from the map's world position * plus the player's local X position. Returns 0 if no map is assigned. * * @example * ```ts * const worldX = player.worldX(); * console.log(`Player is at world X: ${worldX}`); * ``` */ get worldPositionX(): RpgReadableSignal; /** * Computed signal for world Y position * * Calculates the absolute world Y position from the map's world position * plus the player's local Y position. Returns 0 if no map is assigned. * * @example * ```ts * const worldY = player.worldY(); * console.log(`Player is at world Y: ${worldY}`); * ``` */ get worldPositionY(): RpgReadableSignal; private _worldPositionSignals; private _getComputedWorldPosition; /** Internal: Shapes attached to this player */ private _attachedShapes; /** Internal: Shapes where this player is currently located */ private _inShapes; /** Server-clock deadline used to stop idle movement. */ lastProcessedInputTs: number; /** Last client-authored timestamp, kept separately for anti-cheat validation. */ lastProcessedClientInputTs: number; /** Client physics tick attached to the last processed movement input. */ lastProcessedInputTick: number | null; /** Server physics tick at which that client tick was applied. */ lastProcessedInputServerTick: number | null; /** Last processed client input frame for reconciliation with server tick */ _lastFramePositions: { frame: number; position: { x: number; y: number; direction: Direction; }; serverTick?: number; } | null; frames: { x: number; y: number; ts: number; }[]; events: RpgWritableSignal; /** Internal: named map position to resolve after the target map data is ready */ pendingMapPosition: RpgWritableSignal; constructor(); private _getClientListenerBucket; _dispatchClientEvent(key: string, data: unknown): Promise; _onInit(): Promise; /** * Apply the built-in default parameter curves to this player. * * Use this when you want RPGJS to provide the initial parameter setup * instead of restoring values from your own database or a saved snapshot. * * This method only defines the parameter curves and related defaults. * It does not restore custom persisted data for you. * * @method player.applyDefaultParameters() * @returns {void} */ applyDefaultParameters(): void; /** * Initialize the built-in default player stats. * * This applies the default parameter curves and then restores HP/SP to their * current maximum values so the client receives coherent bars on first load. * * Call this manually in `onConnected()` or `onStart()` when your game relies * on the built-in defaults. Do not call it after loading a snapshot or * hydrating player data from your own database unless you explicitly want to * overwrite those values. * * @method player.initializeDefaultStats() * @returns {void} */ initializeDefaultStats(): void; get hooks(): Hooks; get server(): RpgMap | null; get projectiles(): RpgPlayerProjectiles; setLocale(locale: string): void; getLocale(): string; t(key: string, params?: I18nParams): string; i18n(): { locale: string; t: (key: string, params?: I18nParams) => string; }; setMap(map: RpgMap): void; applyFrames(): void; execMethod(method: string, methodData?: unknown[], target?: object): Promise; /** * Change the map for this player * * @param mapId - The ID of the map to change to * @param positions - Optional positions to place the player at * @returns A promise that resolves when the map change is complete * * @example * ```ts * // Change player to map "town" at position {x: 10, y: 20} * await player.changeMap("town", {x: 10, y: 20}); * * // Change player to map "dungeon" at a named position * await player.changeMap("dungeon", "entrance"); * * // Change player to map "town" at the Tiled "start" position, if present * await player.changeMap("town"); * ``` */ changeMap(mapId: string, positions?: { x: number; y: number; z?: number; } | string): Promise; /** * Transfer this player to a registered custom gameplay room. * * The server resolves the destination, runs authorization hooks, creates a * Signe session-transfer token, and tells the client which scene kind to * mount. Clients cannot select a destination on their own. * * @method player.changeRoom(target) * @param target - Registered room kind and values for its path placeholders. * @returns `false` when a hook rejects the transfer; otherwise `true`. * * @example * ```ts * await player.changeRoom({ * kind: "battle", * params: { id: "encounter-42" }, * }) * ``` */ changeRoom(target: RpgRoomTarget): Promise; /** * Return the active RPGJS room. * * The result is a lobby, map, or registered custom gameplay room. Use * `getCurrentMap()` when map-only APIs are required. * * @method player.getCurrentRoom() * @returns The active room, or `null` before the player joins one. * * @example * ```ts * const battle = player.getCurrentRoom() * if (battle?.descriptor.kind === "battle") { * console.log(battle.state()) * } * ``` */ getCurrentRoom(): T | null; private transferRoom; autoChangeMap(nextPosition: Vector2): Promise; teleport(positions: { x: number; y: number; }): Promise; getCurrentMap(): T | null; /** * Legacy v4 position object. * * Prefer the reactive `x`, `y`, and `z` signals in new code. * * @deprecated Use `player.x()`, `player.y()`, `player.z()` and `player.teleport()` instead. * @returns Current top-left player position. */ get position(): { x: number; y: number; z: number; }; /** * Set the legacy v4 position object. * * This updates the player's top-left coordinates and keeps the physics body in sync * when the player is currently attached to a map. * * @deprecated Use `player.teleport({ x, y })` and `player.z.set(z)` instead. */ set position(position: { x: number; y: number; z?: number; }); /** * Legacy v4 helper to create a dynamic event from the player's current map. * * Prefer `player.getCurrentMap()?.createDynamicEvent(...)` in new code. * * @deprecated Use `map.createDynamicEvent(...)` instead. * @param eventObj - Event definition and position. * @returns The created event id, or `undefined` if the player is not on a map. */ createDynamicEvent(eventObj: EventPosOption): Promise | undefined; /** * Legacy v4 list of shapes attached to this player. * * Prefer `player.getShapes()` in new code. * * @deprecated Use `player.getShapes()` instead. * @returns Shapes created with `player.attachShape(...)`. */ get shapes(): RpgShape[]; /** * Legacy v4 list of Tiled tiles currently covered by the player's hitbox. * * This helper is available only when the current map was loaded through * `@rpgjs/tiledmap` / `@canvasengine/tiled`. For non-Tiled maps, it returns `[]`. * * @deprecated Use Tiled map APIs from `player.getCurrentMap()?.tiled` instead. * @returns Tile information for each Tiled cell touched by the player. */ get tiles(): RpgTiledTile[]; /** * Legacy v4 list of other players or events currently colliding with this player. * * @deprecated Prefer explicit physics queries on `player.getCurrentMap()`. * @returns Runtime players and events whose physics bodies overlap this player. */ get otherPlayersCollision(): Array; /** * Legacy v4 size setter. * * In v5, collision size is represented by the hitbox. This bridge maps the * legacy object to `setHitbox(...)`. * * @deprecated Use `player.setHitbox(width, height)` instead. * @param obj - Legacy size object. * @param key - Legacy size key (`width`, `height`, or `hitbox`). * @param value - Legacy size value. */ setSizes(obj: { width: number; height: number; hitbox?: { width: number; height: number; }; }): void; setSizes(key: "width" | "height" | "hitbox", value: number | { width?: number; height?: number; }): void; /** * Legacy v4 Tiled tile lookup. * * This helper is available only when the current map was loaded through * `@rpgjs/tiledmap` / `@canvasengine/tiled`. Coordinates are pixel positions, * matching CanvasEngine Tiled's `getTileByPosition(...)` API. * * @deprecated Use `player.getCurrentMap()?.tiled.getTileByPosition(...)` instead. * @param x - X position in pixels. * @param y - Y position in pixels. * @param z - Optional layer index. * @returns Tiled tile information, or `undefined` when unavailable. */ getTile(x: number, y: number, z?: number): RpgTiledTile | undefined; /** * Send a custom event to the current player's client. * * Use this to push arbitrary websocket payloads to one client only. * On the client side, receive the event by injecting `WebSocketToken` * and subscribing with `socket.on(...)`. * * @method player.emit(type, value) * @param type - Custom event name sent to the client * @param value - Payload sent with the event * @returns {void} * * @example * ```ts * player.emit("inventory:updated", { * slots: player.items().length, * }); * ``` * * @example * ```ts * import { inject } from "@rpgjs/client"; * import { WebSocketToken, type AbstractWebsocket } from "@rpgjs/client"; * * const socket = inject(WebSocketToken); * * socket.on("inventory:updated", (payload) => { * console.log(payload.slots); * }); * ``` */ emit(type: string, value?: T): void; /** * Trigger a named client visual for this player only. * * Client visuals are registered in the client module with `clientVisuals`. * They group existing client-side visual primitives such as flash, sound, * component animations, sprite animations, or camera shake. The server sends * only the visual name and a serializable payload, which keeps rendering * details on the client and avoids sending several visual packets for one * gameplay moment. * * Use direct APIs like `playSound()`, `flash()`, or * `showComponentAnimation()` for one-off visuals. Use `clientVisual()` when * several visuals should be orchestrated together by the client. * * @param name - Visual name registered on the client * @param data - Serializable payload passed to the client visual handler * * @example * ```ts * player.clientVisual("hit", { * targetId: enemy.id, * damage: 25, * }); * ``` */ clientVisual = Record>(name: string, data?: TData): void; private normalizeSnapshotHitbox; private normalizeSnapshotHitboxDimension; /** * Capture serializable authoritative player state in RPG and MMORPG modes. * Derived parameters are recalculated from saved curves, bounds and modifiers. * @title Player Snapshot * @method player.snapshot() * @returns Player state suitable for serialization and later restoration. * @memberof RpgPlayer * @example * ```ts * const saved = JSON.stringify(player.snapshot()); * ``` */ snapshot(): RpgPlayerSnapshot; /** * Restore authoritative player state without new-game initialization in RPG * and MMORPG modes, then run the server onLoad hooks. * @title Apply Player Snapshot * @method player.applySnapshot(snapshot) * @param snapshot - A serialized snapshot or a parsed player snapshot. * @returns The resolved snapshot after database references have been restored. * @memberof RpgPlayer * @example * ```ts * await player.applySnapshot(saved); * ``` */ applySnapshot(snapshot: string | RpgPlayerSnapshot): Promise; private _isSnapshotInput; /** * Save the player state. * * For v4 compatibility, calling `save()` without arguments returns a JSON * snapshot string. Pass a slot (`"auto"` or a number) to use the v5 storage * strategy. */ save(): Promise; save(slot: SaveSlotIndex, meta?: SaveSlotMeta, context?: SaveRequestContext): Promise; /** * Load player state. * * For v4 compatibility, pass a JSON string or plain snapshot object to apply * it directly. Pass a slot (`"auto"` or a number) to use the v5 storage * strategy. */ load(slot: SaveSlotIndex, context?: SaveRequestContext, options?: { changeMap?: boolean; }): Promise; load(snapshot: string | RpgPlayerSnapshot, context?: SaveRequestContext, options?: { changeMap?: boolean; }): Promise; /** * @deprecated Use setGraphicAnimation instead. * @param animationName - The name of the animation to play (e.g., 'attack', 'skill', 'walk') * @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous) */ setAnimation(animationName: string, nbTimes?: number): void; /** * @deprecated Use setGraphicAnimation instead. * @param graphic - The graphic to use for the animation (e.g., 'attack', 'skill', 'walk') * @param animationName - The name of the animation to play (e.g., 'attack', 'skill', 'walk') * @param replaceGraphic - Whether to replace the player's graphic (default: false) */ showAnimation(graphic: string, animationName: string, replaceGraphic?: boolean): void; /** * Listen to custom data sent by the current player's client. * * This listens to websocket actions emitted from the client with * `socket.emit(key, data)`. It is intended for custom client events * that are not already handled by built-in server actions such as * `move`, `action`, or GUI interactions. * * @title Listen to data from the client * @method player.on(key, cb) * @param key - Event name emitted by the client * @param cb - Callback invoked with the payload sent by the client * @returns {void} * @since 3.0.0-beta.5 * * @example * ```ts * player.on("chat:message", ({ text }) => { * console.log("Client says:", text); * }); * ``` * * @example * ```ts * import { inject } from "@rpgjs/client"; * import { WebSocketToken, type AbstractWebsocket } from "@rpgjs/client"; * * const socket = inject(WebSocketToken); * socket.emit("chat:message", { text: "Hello server" }); * ``` */ on(key: string, cb: (data: T) => void | Promise): void; /** * Listen one time to custom data sent by the current player's client. * * After the first matching event is received, the listener is removed * automatically. * * @title Listen one-time to data from the client * @method player.once(key, cb) * @param key - Event name emitted by the client * @param cb - Callback invoked only once with the payload sent by the client * @returns {void} * @since 3.0.0-beta.5 * * @example * ```ts * player.once("tutorial:ready", (payload) => { * console.log("Ready once:", payload.step); * }); * ``` */ once(key: string, cb: (data: T) => void | Promise): void; /** * Remove all listeners for a custom client event on this player. * * @title Remove listeners of the client event * @method player.off(key) * @param key - Event name to clear * @returns {void} * @since 3.0.0-beta.5 * * @example * ```ts * player.off("chat:message"); * ``` */ off(key: string): void; /** * Set the current animation of the player's sprite * * This method changes the animation state of the player's current sprite. * It's used to trigger character animations like attack, skill, or custom movements. * When `nbTimes` is set to a finite number, the animation will play that many times * before returning to the previous animation state. * * If `animationFixed` is true, this method will not change the animation. * * @param animationName - The name of the animation to play (e.g., 'attack', 'skill', 'walk') * @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous) */ setGraphicAnimation(animationName: string, nbTimes: number): void; setGraphicAnimation(animationName: string): void; /** * Set the current animation of the player's sprite with a temporary graphic change * * This method changes the animation state of the player's current sprite and temporarily * changes the player's graphic (sprite sheet) during the animation. The graphic is * automatically reset when the animation finishes. * * When `nbTimes` is set to a finite number, the animation will play that many times * before returning to the previous animation state and graphic. * * If `animationFixed` is true, this method will not change the animation. * * @param animationName - The name of the animation to play (e.g., 'attack', 'skill', 'walk') * @param graphic - The graphic(s) to temporarily use during the animation * @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous) */ setGraphicAnimation(animationName: string, graphic: string | string[], nbTimes: number): void; setGraphicAnimation(animationName: string, graphic: string | string[]): void; /** * Run the change detection cycle. Normally, as soon as a hook is called in a class, the cycle is started. But you can start it manually * The method calls the `onChanges` method on events and synchronizes all map data with the client. * @title Run Sync Changes * @method player.syncChanges() * @returns {void} * @memberof Player */ syncChanges(): void; databaseById(id: string): T | undefined; private _eventChanges; /** * Attach a zone shape to this player using the physic zone system * * This method creates a zone attached to the player's entity in the physics engine. * The zone can be circular or cone-shaped and will detect other entities (players/events) * entering or exiting the zone. * * @param id - Optional zone identifier. If not provided, a unique ID will be generated * @param options - Zone configuration options * * @example * ```ts * // Create a circular detection zone * player.attachShape("vision", { * radius: 150, * angle: 360, * }); * * // Create a cone-shaped vision zone * player.attachShape("vision", { * radius: 200, * angle: 120, * direction: Direction.Right, * limitedByWalls: true, * }); * * // Create a zone with width/height (radius calculated automatically) * player.attachShape({ * width: 100, * height: 100, * positioning: "center", * }); * ``` */ attachShape(idOrOptions: string | AttachShapeOptions, options?: AttachShapeOptions): RpgShape | undefined; /** * Get all shapes attached to this player * * Returns all shapes that were created using `attachShape()` on this player. * * @returns Array of RpgShape instances attached to this player * * @example * ```ts * player.attachShape("vision", { radius: 150 }); * player.attachShape("detection", { radius: 100 }); * * const shapes = player.getShapes(); * console.log(shapes.length); // 2 * ``` */ getShapes(): RpgShape[]; /** * Get all shapes where this player is currently located * * Returns all shapes (from any player/event) where this player is currently inside. * This is updated automatically when the player enters or exits shapes. * * @returns Array of RpgShape instances where this player is located * * @example * ```ts * // Another player has a detection zone * otherPlayer.attachShape("detection", { radius: 200 }); * * // Check if this player is in any shape * const inShapes = player.getInShapes(); * if (inShapes.length > 0) { * console.log("Player is being detected!"); * } * ``` */ getInShapes(): RpgShape[]; /** * Show a temporary component animation on this player * * This method broadcasts a component animation to all clients, allowing * temporary visual effects like hit indicators, spell effects, or status animations * to be displayed on the player. * * @param id - The ID of the component animation to display * @param params - Parameters to pass to the component animation * * @example * ```ts * // Show a hit animation with damage text * player.showComponentAnimation("hit", { * text: "150", * color: "red" * }); * * // Show a heal animation * player.showComponentAnimation("heal", { * amount: 50 * }); * ``` */ showComponentAnimation = Record>(id: string, params?: TParams): void; showHit(text: string): void; /** * Play a sound on the client side for this player only * * This method emits an event to play a sound only for this specific player. * The sound must be defined on the client side (in the client module configuration). * * ## Design * * The sound is sent only to this player's client connection, making it ideal * for personal feedback sounds like UI interactions, notifications, or personal * achievements. For map-wide sounds that all players should hear, use `map.playSound()` instead. * * @param soundId - Sound identifier, defined on the client side * @param options - Optional sound configuration, or `true` to play the sound for every player on the map (v4 compatibility) * @param options.volume - Volume level (0.0 to 1.0, default: 1.0) * @param options.loop - Whether the sound should loop (default: false) * * @example * ```ts * // Play a sound for this player only (default behavior) * player.playSound("item-pickup"); * * // Play a sound with volume and loop * player.playSound("background-music", { * volume: 0.5, * loop: true * }); * * // Play a notification sound at low volume * player.playSound("notification", { volume: 0.3 }); * ``` */ playSound(soundId: string, options?: { volume?: number; loop?: boolean; } | boolean): void; /** * Stop a sound that is currently playing for this player * * This method stops a sound that was previously started with `playSound()`. * The sound must be defined on the client side. * * @param soundId - Sound identifier to stop * * @example * ```ts * // Start a looping background music * player.playSound("background-music", { loop: true }); * * // Later, stop it * player.stopSound("background-music"); * ``` */ stopSound(soundId: string): void; /** * Stop all currently playing sounds for this player * * This method stops all sounds that are currently playing for the player. * Useful when changing maps to prevent sound overlap. * * @example * ```ts * // Stop all sounds before changing map * player.stopAllSounds(); * await player.changeMap("new-map"); * ``` */ stopAllSounds(): void; /** * Make the camera follow another player or event * * This method sends an instruction to the client to fix the viewport on another sprite. * The camera will follow the specified player or event, with optional smooth animation. * * ## Design * * The camera follow instruction is sent only to this player's client connection. * This allows each player to have their own camera target, useful for cutscenes, * following NPCs, or focusing on specific events. * * @param otherPlayer - The player or event that the camera should follow * @param options - Camera follow options * @param options.smoothMove - Enable smooth animation. Can be a boolean (default: true) or an object with animation parameters * @param options.smoothMove.time - Time duration for the animation in milliseconds (optional) * @param options.smoothMove.ease - Easing function name. Visit https://easings.net for available functions (optional) * @param options.smoothMove.speed - Continuous follow speed after the transition (optional) * @param options.smoothMove.acceleration - Continuous follow acceleration after the transition (optional) * @param options.smoothMove.radius - Center radius where the target can move without moving the viewport (optional) * * @example * ```ts * // Follow another player with default smooth animation * player.cameraFollow(otherPlayer, { smoothMove: true }); * * // Follow an event with custom smooth animation * player.cameraFollow(npcEvent, { * smoothMove: { * time: 1000, * ease: "easeInOutQuad" * } * }); * * // Follow without animation (instant) * player.cameraFollow(targetPlayer, { smoothMove: false }); * ``` */ cameraFollow(otherPlayer: RpgPlayer | RpgEvent, options?: { smoothMove?: boolean | { enabled?: boolean; time?: number; ease?: CameraFollowEase; speed?: number; acceleration?: number | null; radius?: number | null; }; }): void; /** * Trigger a flash animation on this player * * This method sends a flash animation event to the client, creating a visual * feedback effect on the player's sprite. The flash can be configured with * various options including type (alpha, tint, or both), duration, cycles, and color. * * ## Design * * The flash is sent as a broadcast event to all clients viewing this player. * This is useful for visual feedback when the player takes damage, receives * a buff, or when an important event occurs. * * @param options - Flash configuration options * @param options.type - Type of flash effect: 'alpha' (opacity), 'tint' (color), or 'both' (default: 'alpha') * @param options.duration - Duration of the flash animation in milliseconds (default: 300) * @param options.cycles - Number of flash cycles (flash on/off) (default: 1) * @param options.alpha - Alpha value when flashing, from 0 to 1 (default: 0.3) * @param options.tint - Tint color when flashing as hex value or color name (default: 0xffffff - white) * * @example * ```ts * // Simple flash with default settings (alpha flash) * player.flash(); * * // Flash with red tint when taking damage * player.flash({ type: 'tint', tint: 0xff0000 }); * * // Flash with both alpha and tint for dramatic effect * player.flash({ * type: 'both', * alpha: 0.5, * tint: 0xff0000, * duration: 200, * cycles: 2 * }); * * // Quick damage flash * player.flash({ * type: 'tint', * tint: 'red', * duration: 150, * cycles: 1 * }); * ``` */ flash(options?: { type?: 'alpha' | 'tint' | 'both'; duration?: number; cycles?: number; alpha?: number; tint?: number | string; }): void; /** * Set the hitbox of the player for collision detection * * This method defines the hitbox used for collision detection in the physics engine. * The hitbox can be smaller or larger than the visual representation of the player, * allowing for precise collision detection. * * ## Design * * The hitbox is used by the physics engine to detect collisions with other entities, * static obstacles, and shapes. Changing the hitbox will immediately update the * collision detection without affecting the visual appearance of the player. * * @param width - Width of the hitbox in pixels * @param height - Height of the hitbox in pixels * * @example * ```ts * // Set a 20x20 hitbox for precise collision detection * player.setHitbox(20, 20); * * // Set a larger hitbox for easier collision detection * player.setHitbox(40, 40); * ``` */ setHitbox(width: number, height: number): void; /** * Set the physical mass for this player or event. * * A mass of `0` or `Infinity` makes the physics body immovable. * * @param mass - New mass value */ setMass(mass: number): void; /** * Set the sync schema for the map * @param schema - The schema to set */ setSync(schema: RpgSyncSchema): void; isEvent(): boolean; } export declare class RpgEvent extends RpgPlayer { constructor(); execMethod(methodName: string, methodData?: unknown[], instance?: object): Promise; /** * Remove this event from the map * * Stops all movements before removing to prevent "unable to resolve entity" errors * from the MovementManager when the entity is destroyed while moving. * * Pass options to keep the sprite visible briefly on clients while * `sprite.onBeforeRemove` runs a visual transition. Gameplay collision is * removed immediately; the event is deleted from the map after `timeoutMs`. * * The server only sends the removal context. The client decides how to render * `transition` in `sprite.onBeforeRemove`, so the payload can describe an * animation, sound, particle effect, GUI transition, or project-specific data. * * @example * ```ts * event.remove({ * reason: 'defeated', * transition: { * type: 'enemy-death', * animation: 'die', * graphic: 'slime_die', * sound: 'slime-death', * duration: 700 * }, * timeoutMs: 700 * }) * ``` */ remove(options?: { reason?: string; data?: unknown; transition?: { animation?: string; graphic?: string | string[]; duration?: number; effect?: string; }; timeoutMs?: number; }): void; isEvent(): boolean; } /** * Interface extension for RpgPlayer * * Extends the RpgPlayer class with additional interfaces from mixins. * This provides proper TypeScript support for all mixin methods and properties. */ export interface RpgPlayer extends IVariableManager, IMoveManager, IGoldManager, IComponentManager, IGuiManager, IItemManager, IEffectManager, IParameterManager, IElementManager, ISkillManager, IBattleManager, IClassManager, IStateManager, IHotbarManager { } export {};