import { HotbarEntry, HotbarEntryPresentation, HotbarState, PlayerCtor } from '@rpgjs/common'; import { RpgPlayer } from './Player'; /** Authoritative context passed to a registered hotbar entry type. */ export interface HotbarUseContext { /** Zero-based slot used by the player. */ slot: number; /** Optional targeting data supplied by the client or battle module. */ target?: unknown; } /** * Server-side contract for a built-in or plugin-provided hotbar entry type. * * The definition owns availability validation, client presentation, and use so * serialized slot data never grants gameplay authority to the client. */ export interface HotbarEntryTypeDefinition { /** Unique serialized entry type. */ type: string; /** Throw when the player may not assign or use this entry. */ validate(player: RpgPlayer, id: string): void; /** Build the serializable presentation sent to the current player. */ resolve(player: RpgPlayer, id: string): HotbarEntryPresentation; /** Execute the authoritative gameplay action. */ use(player: RpgPlayer, id: string, context: HotbarUseContext): unknown | Promise; } /** Static capacity or per-player capacity resolver, clamped between 1 and 10. */ export type HotbarCapacityResolver = number | ((player: RpgPlayer) => number); /** Static unlock hint or per-player, per-slot hint resolver. */ export type HotbarLockedSlotHintResolver = string | ((player: RpgPlayer, slot: number) => string | undefined); /** * Static allowed entry types or a resolver evaluated for the current player. * * Entries whose type is not allowed remain persisted, but cannot be displayed, * assigned, or used until the configuration allows them again. */ export type HotbarAllowedEntryTypesResolver = readonly string[] | ((player: RpgPlayer) => readonly string[]); /** Per-player capacity, entry filtering, and locked-slot presentation options. */ export interface HotbarConfiguration { /** Number of currently accessible slots or a dynamic player resolver. */ capacity?: HotbarCapacityResolver; /** * Entry types available in this hotbar. * * Omit this option to allow every registered entry type. */ allowedEntryTypes?: HotbarAllowedEntryTypesResolver; /** Player-visible unlock hint or a per-slot resolver. */ lockedSlotHint?: HotbarLockedSlotHintResolver; } /** Payload delivered to the server `onHotbarChange` player hook. */ export interface HotbarChangePayload { /** Mutation or refresh that produced the snapshot. */ action: "initialize" | "assign" | "clear" | "select" | "refresh"; /** Affected zero-based slot when the action targets one slot. */ slot?: number; /** Assigned or selected entry when available. */ entry?: HotbarEntry; /** Detached state after the change. */ state: HotbarState; } /** * Register a server-side hotbar entry type. * * The definition owns validation, client presentation, and authoritative use. * The returned function restores the previous definition. * * @param definition - Type definition shared by every player on this server. * @returns A cleanup function that restores the previous definition. * * @example * ```ts * const unregister = registerHotbarEntryType({ * type: "emote", * validate(_player, id) { * if (id !== "wave") throw new Error("Unknown emote"); * }, * resolve(_player, id) { * return { * id, * type: "emote", * name: "Wave", * usable: true, * activation: { mode: "instant" }, * }; * }, * use(player) { * player.showAnimation("wave"); * }, * }); * ``` */ export declare function registerHotbarEntryType(definition: HotbarEntryTypeDefinition): () => void; /** * Return the registered definition for an entry type. * * @param type - Serialized entry type. * @returns The definition, or `undefined` when the type is unknown. */ export declare function getHotbarEntryType(type: string): HotbarEntryTypeDefinition | undefined; /** * Resolve the serializable client presentation for a hotbar entry. * * Unavailable or unknown entries return a disabled fallback instead of * exposing an authoritative validation error to the client. * * @param player - Player receiving the presentation. * @param entry - Persistent entry reference. * @returns Serializable presentation for the generic hotbar GUI. */ export declare function resolveHotbarEntryPresentation(player: RpgPlayer, entry: HotbarEntry): HotbarEntryPresentation; export declare function WithHotbarManager(Base: TBase): new (...args: ConstructorParameters) => InstanceType & IHotbarManager; export interface IHotbarManager { configureHotbar(options?: HotbarConfiguration): HotbarState; getHotbar(): HotbarState; getHotbarCapacity(): number; isHotbarEntryTypeAllowed(type: string): boolean; getHotbarLockedSlotHint(slot: number): string | undefined; refreshHotbar(): HotbarState; initializeHotbar(entries?: HotbarEntry[]): HotbarState; assignHotbarSlot(slot: number, entry: HotbarEntry): HotbarState; clearHotbarSlot(slot: number): HotbarState; selectHotbarSlot(slot: number): HotbarState; useHotbarSlot(slot: number, target?: unknown): unknown; useActiveHotbarSlot(target?: unknown): unknown; }