import type { EngineModule, EntityState, ResolvedEvent, ScalarValue, WorldState } from '@ai-rpg-engine/core'; import type { ItemCatalog, Loadout } from './types.js'; /** * Formula-registry id under which createEquipmentCore publishes the pack's * construction-frozen item catalog — the same per-engine transport ability-core * uses for ABILITY_CATALOG_FORMULA ('ability-core:catalog'). The registry lives * on the ModuleManager, so same-engine consumers (CLI layers, observability * modules) resolve the full ItemDefinition[] without every starter re-threading * it, while parallel engines with different packs never cross-contaminate. * Formulas are code, never serialized, and re-register on Engine.deserialize. */ export declare const EQUIPMENT_CATALOG_FORMULA = "equipment-core:catalog"; /** Persisted module-state namespace key (world.modules[EQUIPMENT_STATE_KEY]). */ export declare const EQUIPMENT_STATE_KEY = "equipment-core"; /** * Status id carried by an entity while an item is equipped. Deliberately * colon-free: terminal-ui's humanizeStateId strips a `namespace:` prefix, and * "Equipped" is player-meaningful, not a namespace — `equipped-trident-and-net` * renders as "Equipped Trident And Net" on the HUD Status line. */ export declare function equipStatusId(itemId: string): string; /** * Structural subset of @ai-rpg-engine/content-schema's StatusDefinition — * declared locally so this package adds no dependency edge. Every field is * assignable to the real StatusDefinition, so modules' * registerStatusDefinitions accepts these arrays directly. */ export type EquipmentStatusDefinition = { id: string; name: string; tags: string[]; stacking: 'replace'; duration: { type: 'permanent'; }; modifiers?: { stat: string; operation: 'add'; value: number; }[]; ui?: { icon?: string; color?: string; description?: string; }; }; /** * The status operations this module needs, shaped to match what * @ai-rpg-engine/modules already exports — a pack wires them verbatim: * * ```ts * import { registerStatusDefinitions, applyStatus, removeStatus } from '@ai-rpg-engine/modules'; * createEquipmentCore({ * catalog: itemCatalog, * statuses: { registerDefinitions: registerStatusDefinitions, apply: applyStatus, remove: removeStatus }, * }); * ``` */ export type EquipmentStatusOps = { /** modules' registerStatusDefinitions — idempotent content-metadata registry. */ registerDefinitions: (defs: EquipmentStatusDefinition[]) => void; /** modules' applyStatus — applies an AppliedStatus instance to the entity. */ apply: (entity: EntityState, statusId: string, tick: number, options?: { stacking?: 'replace' | 'stack' | 'refresh'; sourceId?: string; data?: Record; }, world?: WorldState) => ResolvedEvent; /** modules' removeStatus — removes the instance; null when absent. */ remove: (entity: EntityState, statusId: string, tick: number) => ResolvedEvent | null; }; /** Persistence shape: per-entity loadouts, keyed by entity id. */ export type EquipmentModuleState = { loadouts: Record; }; /** * Synthesize-and-attach state access (world-tick's pattern): a world whose * namespace was never initialized (pure-WorldState harness, no engine) gets a * fresh default written back, so reads and writes always land on the world. */ export declare function getEquipmentState(world: WorldState): EquipmentModuleState; /** An entity's current loadout, or undefined when it has never equipped. */ export declare function getEntityLoadout(world: WorldState, entityId: string): Loadout | undefined; /** * One StatusDefinition per catalog item: `equipped-`, permanent, * replace-stacking, modifiers mirroring the item's statModifiers as `add` * operations. Registered at module construction AND on every re-construction * (Engine.deserialize re-runs register), so a restored save's applied statuses * always resolve their modifiers. * * Tags stay inside modules' fixed semantic vocabulary ('buff') — equipment is * a passive benefit, and resistance checks only run on ability-applied * statuses, never on this module's direct application. */ export declare function buildEquipmentStatusDefinitions(catalog: ItemCatalog): EquipmentStatusDefinition[]; export type EquipmentCoreConfig = { /** The pack's item catalog — published under EQUIPMENT_CATALOG_FORMULA at construction. */ catalog: ItemCatalog; /** The engine build's status machinery (modules' registerStatusDefinitions / applyStatus / removeStatus). */ statuses: EquipmentStatusOps; }; /** * Equip/unequip verbs over this package's Loadout model. * * - Catalog transport: publishes the construction-frozen catalog under * {@link EQUIPMENT_CATALOG_FORMULA}; its own handlers read back through the * formula registry (the per-engine transport), falling back to the frozen * config only if the registry is unavailable. * - Loadout state: persisted under the 'equipment-core' namespace * ({@link EquipmentModuleState}), one Loadout per entity. * - Stat carry: `equipped-` statuses (one per equipped item) whose * modifiers mirror the item's statModifiers; modules' effectiveStat * aggregates them into every combat formula read. Definitions re-register on * every construction, so save/load restores the numbers. * - Slot semantics: this package's own equipItem/unequipItem — occupied slot * swaps the displaced item back to inventory; requiredTags gate rejects with * the package's own error strings. * * Non-goals of this slice (reported in item.equipped payloads, not applied): * grantedTags, grantedVerbs, and resourceModifiers. */ export declare function createEquipmentCore(config: EquipmentCoreConfig): EngineModule; //# sourceMappingURL=equipment-core.d.ts.map