Spaces:
Running
Running
File size: 4,192 Bytes
5c2ed06 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
import type { PokemonEventMethods, ConditionData } from './dex-conditions';
import { assignMissingFields, BasicEffect, toID } from './dex-data';
import { Utils } from '../lib/utils';
interface AbilityEventMethods {
onCheckShow?: (this: Battle, pokemon: Pokemon) => void;
onEnd?: (this: Battle, target: Pokemon & Side & Field) => void;
onStart?: (this: Battle, target: Pokemon) => void;
}
/* Possible Ability flags */
interface AbilityFlags {
breakable?: 1; // Can be suppressed by Mold Breaker and related effects
cantsuppress?: 1; // Ability can't be suppressed by e.g. Gastro Acid or Neutralizing Gas
failroleplay?: 1; // Role Play fails if target has this Ability
failskillswap?: 1; // Skill Swap fails if either the user or target has this Ability
noentrain?: 1; // Entrainment fails if user has this Ability
noreceiver?: 1; // Receiver and Power of Alchemy will not activate if an ally faints with this Ability
notrace?: 1; // Trace cannot copy this Ability
notransform?: 1; // Disables the Ability if the user is Transformed
}
export interface AbilityData extends Partial<Ability>, AbilityEventMethods, PokemonEventMethods {
name: string;
}
export type ModdedAbilityData = AbilityData | Partial<AbilityData> & { inherit: true };
export interface AbilityDataTable { [abilityid: IDEntry]: AbilityData }
export interface ModdedAbilityDataTable { [abilityid: IDEntry]: ModdedAbilityData }
export class Ability extends BasicEffect implements Readonly<BasicEffect> {
declare readonly effectType: 'Ability';
/** Rating from -1 Detrimental to +5 Essential; see `data/abilities.ts` for details. */
readonly rating: number;
readonly suppressWeather: boolean;
readonly flags: AbilityFlags;
declare readonly condition?: ConditionData;
constructor(data: AnyObject) {
super(data);
this.fullname = `ability: ${this.name}`;
this.effectType = 'Ability';
this.suppressWeather = !!data.suppressWeather;
this.flags = data.flags || {};
this.rating = data.rating || 0;
if (!this.gen) {
if (this.num >= 268) {
this.gen = 9;
} else if (this.num >= 234) {
this.gen = 8;
} else if (this.num >= 192) {
this.gen = 7;
} else if (this.num >= 165) {
this.gen = 6;
} else if (this.num >= 124) {
this.gen = 5;
} else if (this.num >= 77) {
this.gen = 4;
} else if (this.num >= 1) {
this.gen = 3;
}
}
assignMissingFields(this, data);
}
}
const EMPTY_ABILITY = Utils.deepFreeze(new Ability({ id: '', name: '', exists: false }));
export class DexAbilities {
readonly dex: ModdedDex;
readonly abilityCache = new Map<ID, Ability>();
allCache: readonly Ability[] | null = null;
constructor(dex: ModdedDex) {
this.dex = dex;
}
get(name: string | Ability = ''): Ability {
if (name && typeof name !== 'string') return name;
const id = toID(name.trim());
return this.getByID(id);
}
getByID(id: ID): Ability {
if (id === '') return EMPTY_ABILITY;
let ability = this.abilityCache.get(id);
if (ability) return ability;
if (this.dex.data.Aliases.hasOwnProperty(id)) {
ability = this.get(this.dex.data.Aliases[id]);
} else if (id && this.dex.data.Abilities.hasOwnProperty(id)) {
const abilityData = this.dex.data.Abilities[id] as any;
const abilityTextData = this.dex.getDescs('Abilities', id, abilityData);
ability = new Ability({
name: id,
...abilityData,
...abilityTextData,
});
if (ability.gen > this.dex.gen) {
(ability as any).isNonstandard = 'Future';
}
if (this.dex.currentMod === 'gen7letsgo' && ability.id !== 'noability') {
(ability as any).isNonstandard = 'Past';
}
if ((this.dex.currentMod === 'gen7letsgo' || this.dex.gen <= 2) && ability.id === 'noability') {
(ability as any).isNonstandard = null;
}
} else {
ability = new Ability({
id, name: id, exists: false,
});
}
if (ability.exists) this.abilityCache.set(id, this.dex.deepFreeze(ability));
return ability;
}
all(): readonly Ability[] {
if (this.allCache) return this.allCache;
const abilities = [];
for (const id in this.dex.data.Abilities) {
abilities.push(this.getByID(id as ID));
}
this.allCache = abilities;
return this.allCache;
}
}
|