diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 0036075f04a..f29e5eada8c 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -71,32 +71,40 @@ import { inSpeedOrder } from "#utils/speed-order-generator"; import { toCamelCase } from "#utils/strings"; import i18next from "i18next"; +//#region Bit sets /** Bit set for an ability's `bypass faint` flag */ -const AB_FLAG_BYPASS_FAINT = 1; +const AB_FLAG_BYPASS_FAINT = 1 << 0; /** Bit set for an ability's `ignorable` flag */ -const AB_FLAG_IGNORABLE = 2; +const AB_FLAG_IGNORABLE = 1 << 1; /** Bit set for an ability's `suppressable` flag */ -const AB_FLAG_UNSUPPRESSABLE = 4; +const AB_FLAG_UNSUPPRESSABLE = 1 << 2; /** Bit set for an ability's `uncopiable` flag */ -const AB_FLAG_UNCOPIABLE = 8; +const AB_FLAG_UNCOPIABLE = 1 << 3; /** Bit set for an ability's `unreplaceable` flag */ -const AB_FLAG_UNREPLACEABLE = 16; +const AB_FLAG_UNREPLACEABLE = 1 << 4; /** Bit set for an ability's `unimplemented` flag */ -const AB_FLAG_UNIMPLEMENTED = 32; +const AB_FLAG_UNIMPLEMENTED = 1 << 5; /** Bit set for an ability's `partial` flag */ -const AB_FLAG_PARTIAL = 64; - -/** Bits set for a swappable ability */ +const AB_FLAG_PARTIAL = 1 << 6; +/** Bit set for an unswappable ability */ const AB_FLAG_UNSWAPPABLE = AB_FLAG_UNCOPIABLE | AB_FLAG_UNREPLACEABLE; +//#endregion Bit sets + +/** + * An Ability is a class representing the various Abilities Pokemon may have. \ + * Each has one or more {@linkcode AbAttr | attributes} that can apply independently + * of one another. + */ export class Ability { /** The ability's unique identifier */ public readonly id: AbilityId; - /** Key used to localize the ability's name */ + /** The locales key for the ability's name. */ private readonly i18nKey: string; - /** The localized ability name + /** + * The localized ability name. * @remarks - * Includes The (P) or (N) suffix, if the ability is partial/unimplemented + * Includes the `"(P)"` or `"(N)"` suffix if the ability is partial/unimplemented */ public get name(): string { if (this.id === AbilityId.NONE) { @@ -124,35 +132,65 @@ export class Ability { } return i18next.t(`ability:${this.i18nKey}.description`); } - /** Whether the retains its effects through a faint */ + + /** + * Whether this ability can activate even if the user faints. + * @remarks + * If `true`, the ability will also activate when revived via Reviver Seed. + */ public get bypassFaint(): boolean { return (this.flags & AB_FLAG_BYPASS_FAINT) !== 0; } - /** Whether the ability is ignorable by mold breaker like effects */ + /** + * Whether this ability can be ignored by effects like + * {@linkcode MoveId.SUNSTEEL_STRIKE | Sunsteel Strike} or {@linkcode AbilityId.MOLD_BREAKER | Mold Breaker}. + */ public get ignorable(): boolean { return (this.flags & AB_FLAG_IGNORABLE) !== 0; } - /** Whether the ability can be suppressed by gastro acid and neutralizing gas */ + /** + * Whether this ability can be suppressed by effects like + * {@linkcode MoveId.GASTRO_ACID | Gastro Acid} or {@linkcode AbilityId.NEUTRALIZING_GAS | Neutralizing Gas}. + */ public get suppressable(): boolean { return !(this.flags & AB_FLAG_UNSUPPRESSABLE); } - /** Whether the ability can be copied, such as via trace */ + /** + * Whether this ability can be copied by effects like + * {@linkcode MoveId.ROLE_PLAY | Role Play} or {@linkcode AbilityId.TRACE | Trace}. + */ public get copiable(): boolean { return !(this.flags & AB_FLAG_UNCOPIABLE); } - /** Whether the ability can be replaced, such as via entrainment */ + /** + * Whether this ability can be replaced by effects like + * {@linkcode MoveId.SIMPLE_BEAM | Simple Beam} or {@linkcode MoveId.ENTRAINMENT | Entrainment}. + */ public get replaceable(): boolean { return !(this.flags & AB_FLAG_UNREPLACEABLE); } - /** Whether the ability is partially implemented. Mutually exclusive with {@linkcode unimplemented} */ + /** + * Whether this ability is partially implemented. + * @remarks + * Mutually exclusive with {@linkcode unimplemented} + */ public get partial(): boolean { return (this.flags & AB_FLAG_PARTIAL) !== 0; } - /** Whether the ability is unimplemented. Mutually exclusive with {@linkcode partial} */ + /** + * Whether this ability is unimplemented. + * @remarks + * Mutually exclusive with {@linkcode partial} + */ public get unimplemented(): boolean { return (this.flags & AB_FLAG_UNIMPLEMENTED) !== 0; } - /** Whether this ability can be swapped via moves like skill swap */ + /** + * Whether this ability can be swapped via effects like {@linkcode MoveId.SKILL_SWAP | Skill Swap}. + * @remarks + * Logically equivalent to `this.copiable && this.replaceable`, albeit slightly faster + * due to using a pre-computed bitmask. + */ public get swappable(): boolean { return !(this.flags & AB_FLAG_UNSWAPPABLE); } @@ -238,8 +276,8 @@ class AbBuilder { * @param args - The arguments needed to instantiate the given class. * @returns `this` */ - attr>(AttrType: T, ...args: ConstructorParameters): this { - const attr = new AttrType(...args); + attr>(attrType: T, ...args: ConstructorParameters): this { + const attr = new attrType(...args); this.attrs.push(attr); return this;