import { PlayerCtor, Skill } from '@rpgjs/common'; import { RpgPlayer } from './Player'; /** * Type for skill class constructor */ export type SkillClass = { new (): SkillObject; readonly name: string; readonly id?: string; }; export type SkillChangeAction = "learn" | "forget"; export interface SkillChangeOptions { source?: "manual" | "level" | "class" | "studio" | string; level?: number; } export interface SkillChangePayload extends SkillChangeOptions { action: SkillChangeAction; skill: SkillClass | SkillObject | string; skillId: string; } /** * Interface defining the hooks that can be implemented on skill classes or objects * * These hooks are called at specific moments during the skill lifecycle: * - `onLearn`: When the skill is learned by the player * - `onUse`: When the skill is successfully used * - `onUseFailed`: When the skill usage fails (e.g., chance roll failed) * - `onForget`: When the skill is forgotten * * @example * ```ts * const skillHooks: SkillHooks = { * onLearn(player) { * console.log('Skill learned!'); * }, * onUse(player, target) { * console.log('Skill used on target'); * } * }; * ``` */ export interface SkillHooks { /** * Called when the skill is learned by the player * * @param player - The player learning the skill */ onLearn?: (player: RpgPlayer) => void | Promise; /** * Called when the skill is successfully used * * @param player - The player using the skill * @param target - The target player(s) if any */ onUse?: (player: RpgPlayer, target?: RpgPlayer | RpgPlayer[]) => void | Promise; /** * Called when the skill usage fails (e.g., chance roll failed) * * @param player - The player attempting to use the skill * @param target - The intended target player(s) if any */ onUseFailed?: (player: RpgPlayer, target?: RpgPlayer | RpgPlayer[]) => void | Promise; /** * Called when the skill is forgotten * * @param player - The player forgetting the skill */ onForget?: (player: RpgPlayer) => void | Promise; } /** * Interface for skill object definition * * Defines the properties that a skill can have when defined as an object. * Skills can be defined as objects, classes, or string IDs referencing the database. * * @example * ```ts * const fireSkill: SkillObject = { * id: 'fire', * name: 'Fire', * description: 'A basic fire spell', * spCost: 10, * hitRate: 0.9, * power: 50, * onUse(player) { * console.log('Fire spell cast!'); * } * }; * * player.learnSkill(fireSkill); * ``` */ export interface SkillObject extends SkillHooks { /** * Unique identifier for the skill * If not provided, one will be auto-generated */ id?: string; /** * Display name of the skill */ name?: string; /** * Description of the skill */ description?: string; /** * SP (Skill Points) cost to use the skill * @default 0 */ spCost?: number; /** * Hit rate (0-1) - probability of successful skill usage * @default 1 */ hitRate?: number; /** * Base power of the skill for damage calculation */ power?: number; /** * Coefficient multipliers for damage calculation */ coefficient?: Record; /** * Type marker for database */ _type?: 'skill'; /** * Allow additional properties */ [key: string]: unknown; } export type SkillData = Skill | SkillObject; /** * Skill Manager Mixin * * Provides skill management capabilities to any class. This mixin handles * learning, forgetting, and using skills, including SP cost management, * hit rate calculations, and skill effects application. * * Supports three input formats for skills: * - **String ID**: References a skill in the database * - **Class**: A skill class that will be instantiated * - **Object**: A skill object with properties and hooks * * @param Base - The base class to extend with skill management * @returns Extended class with skill management methods * * @example * ```ts * // Using string ID (from database) * player.learnSkill('fire'); * * // Using skill class * player.learnSkill(FireSkill); * * // Using skill object * player.learnSkill({ * id: 'ice', * name: 'Ice', * spCost: 15, * onUse(player) { * console.log('Ice spell cast!'); * } * }); * ``` */ export declare function WithSkillManager(Base: TBase): TBase; /** * Interface for Skill Manager functionality * * Provides skill management capabilities including learning, forgetting, and using skills. * This interface defines the public API of the SkillManager mixin. */ export interface ISkillManager { /** * Retrieves a learned skill. Returns null if not found * * @param skillInput - Skill class, object, or data id * @returns The skill data or null */ getSkill(skillInput: SkillClass | SkillObject | string): Skill | null; /** * Learn a skill * * Supports three input formats: * - String ID: Retrieves from database * - Class: Creates instance and adds to database * - Object: Uses directly and adds to database * * @param skillInput - Skill class, object, or data id * @returns The learned skill data * @throws SkillLog.alreadyLearned if the player already knows the skill */ learnSkill(skillInput: SkillClass | SkillObject | string, options?: SkillChangeOptions): SkillObject; /** * Forget a skill * * @param skillInput - Skill class, object, or data id * @returns The forgotten skill data * @throws SkillLog.notLearned if trying to forget a skill not learned */ forgetSkill(skillInput: SkillClass | SkillObject | string, options?: SkillChangeOptions): SkillData; /** * Use a skill * * @param skillInput - Skill class, object, or data id * @param otherPlayer - Optional target player(s) to apply skill to * @returns The used skill data * @throws SkillLog.restriction if player has Effect.CAN_NOT_SKILL * @throws SkillLog.notLearned if player tries to use an unlearned skill * @throws SkillLog.notEnoughSp if player does not have enough SP * @throws SkillLog.chanceToUseFailed if the chance to use the skill has failed */ useSkill(skillInput: SkillClass | SkillObject | string, otherPlayer?: RpgPlayer | RpgPlayer[]): SkillData; }