/** One possible drop in a {@link LootTableDef} — an item, currency, or generated item, its count range, and its odds. */ export interface LootEntry { item?: string; currency?: string; /** * Roll a procedurally generated item instead of a static catalog id (a rolled unique gun, an * affixed relic) — invoked with the roll's rng and returning the generated item's runtime id, the * one `content.itemById` and inventories treat exactly like a static id (#536.1). Compose it with * `item/itemInstanceRegistry`'s `proceduralLootEntry` over any procedural roller (e.g. `item/affix`'s * `createAffixRoller`). */ generate?: (rng: () => number) => string; count: number | [number, number]; /** Relative pick weight — required in `"weighted"` mode, forbidden in `"independent"` mode. */ weight?: number; /** Per-entry drop probability in `(0, 1]` — required in `"independent"` mode, forbidden in `"weighted"` mode. */ chance?: number; } /** A named, validated loot table — its roll count, weighted-vs-independent mode, and candidate entries. */ export interface LootTableDef { id: string; rolls?: number; /** * `"weighted"` (default): each roll picks exactly one entry by relative `weight`. * `"independent"`: each roll gives every entry its own `chance` — classic drop lists * where a kill can yield several items (or nothing) without filler entries. */ mode?: "weighted" | "independent"; entries: LootEntry[]; } /** A resolved loot outcome — one item or currency grant with its rolled count. */ export interface Drop { item?: string; currency?: string; count: number; } export interface LootRegistry { register(def: LootTableDef): void; has(id: string): boolean; roll(id: string, rng?: () => number): Drop[]; /** Registered tables in registration order; plain JSON unless an entry uses `generate`. */ snapshot(): LootTableDef[]; /** Replaces every registered table with `next`, validating each. */ restore(next: readonly LootTableDef[]): void; } /** Options for {@link createLootRegistry} — inject a default RNG so bare `roll(id)` uses the world stream. */ export interface LootRegistryOptions { /** * Default `[0,1)` stream when `roll` is called without an explicit rng. * Prefer the world stream from `createGameContext` (`ctx.rng`); bare registries * still fall back to `Math.random` (warning once) for portable call sites outside a game context. */ rng?: () => number; } /** * Register named loot tables and roll weighted randomized drops from them. * * @capability loot-table register loot tables and roll weighted randomized drops */ export declare function createLootRegistry(options?: LootRegistryOptions): LootRegistry; /** * Validates a loot table definition and returns it unchanged, for use with {@link createLootRegistry}. * * @capability loot-table validate a loot table definition for use with the registry */ export declare function lootTable(def: LootTableDef): LootTableDef; export declare function grantDrops(drops: Drop[], appliers: { putItem: (itemId: string, count: number) => unknown; grantCurrency: (currencyId: string, amount: number) => unknown; }): void;