Add more abilities and move contact flag
parent
18679241e9
commit
005cc9b7d5
|
@ -194,12 +194,13 @@ export class Arena {
|
||||||
}
|
}
|
||||||
|
|
||||||
isMoveWeatherCancelled(move: Move) {
|
isMoveWeatherCancelled(move: Move) {
|
||||||
return this.weather && this.weather.isMoveWeatherCancelled(move);
|
return this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(move);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAttackTypeMultiplier(attackType: Type): number {
|
getAttackTypeMultiplier(attackType: Type): number {
|
||||||
if (!this.weather)
|
if (!this.weather || this.weather.isEffectSuppressed(this.scene))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return this.weather.getAttackTypeMultiplier(attackType);
|
return this.weather.getAttackTypeMultiplier(attackType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import { Gender } from "./data/gender";
|
||||||
import { Weather, WeatherType, getRandomWeatherType, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather";
|
import { Weather, WeatherType, getRandomWeatherType, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather";
|
||||||
import { TempBattleStat } from "./data/temp-battle-stat";
|
import { TempBattleStat } from "./data/temp-battle-stat";
|
||||||
import { ArenaTrapTag, TrickRoomTag } from "./data/arena-tag";
|
import { ArenaTrapTag, TrickRoomTag } from "./data/arena-tag";
|
||||||
import { ProtectStatAttr, applyPreStatChangeAbilityAttrs } from "./data/ability";
|
import { PostWeatherLapseAbAttr, PreWeatherDamageAbAttr, ProtectStatAttr, SuppressWeatherEffectAbAttr, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreWeatherEffectAbAttrs } from "./data/ability";
|
||||||
|
|
||||||
export class SelectStarterPhase extends BattlePhase {
|
export class SelectStarterPhase extends BattlePhase {
|
||||||
constructor(scene: BattleScene) {
|
constructor(scene: BattleScene) {
|
||||||
|
@ -456,7 +456,36 @@ export class SummonMissingPhase extends SummonPhase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CommandPhase extends BattlePhase {
|
type PokemonFunc = (pokemon: Pokemon) => void;
|
||||||
|
|
||||||
|
export abstract class FieldPhase extends BattlePhase {
|
||||||
|
isPlayerDelayed(): boolean {
|
||||||
|
const playerPokemon = this.scene.getPlayerPokemon();
|
||||||
|
const enemyPokemon = this.scene.getEnemyPokemon();
|
||||||
|
|
||||||
|
const playerSpeed = playerPokemon?.getBattleStat(Stat.SPD) || 0;
|
||||||
|
const enemySpeed = enemyPokemon?.getBattleStat(Stat.SPD) || 0;
|
||||||
|
|
||||||
|
const speedDelayed = new Utils.BooleanHolder(playerSpeed < enemySpeed);
|
||||||
|
this.scene.arena.applyTags(TrickRoomTag, speedDelayed);
|
||||||
|
|
||||||
|
return speedDelayed.value || (playerSpeed === enemySpeed && Utils.randInt(2) === 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
executeForBoth(func: PokemonFunc): void {
|
||||||
|
const playerPokemon = this.scene.getPlayerPokemon();
|
||||||
|
const enemyPokemon = this.scene.getEnemyPokemon();
|
||||||
|
const delayed = this.isPlayerDelayed();
|
||||||
|
if (!delayed && playerPokemon)
|
||||||
|
func(playerPokemon);
|
||||||
|
if (enemyPokemon)
|
||||||
|
func(enemyPokemon);
|
||||||
|
if (delayed && playerPokemon)
|
||||||
|
func(playerPokemon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandPhase extends FieldPhase {
|
||||||
constructor(scene: BattleScene) {
|
constructor(scene: BattleScene) {
|
||||||
super(scene)
|
super(scene)
|
||||||
}
|
}
|
||||||
|
@ -496,9 +525,6 @@ export class CommandPhase extends BattlePhase {
|
||||||
const enemyPokemon = this.scene.getEnemyPokemon();
|
const enemyPokemon = this.scene.getEnemyPokemon();
|
||||||
let success: boolean;
|
let success: boolean;
|
||||||
|
|
||||||
const playerSpeed = playerPokemon.getBattleStat(Stat.SPD);
|
|
||||||
const enemySpeed = enemyPokemon.getBattleStat(Stat.SPD);
|
|
||||||
|
|
||||||
let isDelayed = (command: Command, playerMove: PokemonMove, enemyMove: PokemonMove) => {
|
let isDelayed = (command: Command, playerMove: PokemonMove, enemyMove: PokemonMove) => {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case Command.FIGHT:
|
case Command.FIGHT:
|
||||||
|
@ -516,10 +542,7 @@ export class CommandPhase extends BattlePhase {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const speedDelayed = new Utils.BooleanHolder(playerSpeed < enemySpeed);
|
return this.isPlayerDelayed();
|
||||||
this.scene.arena.applyTags(TrickRoomTag, speedDelayed);
|
|
||||||
|
|
||||||
return speedDelayed.value || (playerSpeed === enemySpeed && Utils.randInt(2) === 1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let playerMove: PokemonMove;
|
let playerMove: PokemonMove;
|
||||||
|
@ -573,7 +596,7 @@ export class CommandPhase extends BattlePhase {
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
if (this.scene.arena.weather)
|
if (this.scene.arena.weather)
|
||||||
this.scene.unshiftPhase(new WeatherEffectPhase(this.scene, this.scene.arena.weather, isDelayed(command, null, null)));
|
this.scene.unshiftPhase(new WeatherEffectPhase(this.scene, this.scene.arena.weather));
|
||||||
|
|
||||||
const enemyMove = enemyPokemon.getNextMove();
|
const enemyMove = enemyPokemon.getNextMove();
|
||||||
const enemyPhase = new EnemyMovePhase(this.scene, enemyPokemon, enemyMove);
|
const enemyPhase = new EnemyMovePhase(this.scene, enemyPokemon, enemyMove);
|
||||||
|
@ -608,7 +631,7 @@ export class CommandPhase extends BattlePhase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TurnEndPhase extends BattlePhase {
|
export class TurnEndPhase extends FieldPhase {
|
||||||
constructor(scene: BattleScene) {
|
constructor(scene: BattleScene) {
|
||||||
super(scene);
|
super(scene);
|
||||||
}
|
}
|
||||||
|
@ -618,9 +641,6 @@ export class TurnEndPhase extends BattlePhase {
|
||||||
|
|
||||||
this.scene.currentBattle.incrementTurn();
|
this.scene.currentBattle.incrementTurn();
|
||||||
|
|
||||||
const playerPokemon = this.scene.getPlayerPokemon();
|
|
||||||
const enemyPokemon = this.scene.getEnemyPokemon();
|
|
||||||
|
|
||||||
const handlePokemon = (pokemon: Pokemon) => {
|
const handlePokemon = (pokemon: Pokemon) => {
|
||||||
if (!pokemon || !pokemon.hp)
|
if (!pokemon || !pokemon.hp)
|
||||||
return;
|
return;
|
||||||
|
@ -644,19 +664,7 @@ export class TurnEndPhase extends BattlePhase {
|
||||||
pokemon.battleSummonData.turnCount++;
|
pokemon.battleSummonData.turnCount++;
|
||||||
};
|
};
|
||||||
|
|
||||||
const playerSpeed = playerPokemon?.getBattleStat(Stat.SPD) || 0;
|
this.executeForBoth(handlePokemon);
|
||||||
const enemySpeed = enemyPokemon?.getBattleStat(Stat.SPD) || 0;
|
|
||||||
|
|
||||||
const speedDelayed = new Utils.BooleanHolder(playerSpeed < enemySpeed);
|
|
||||||
this.scene.arena.applyTags(TrickRoomTag, speedDelayed);
|
|
||||||
|
|
||||||
const isDelayed = speedDelayed.value || (playerSpeed === enemySpeed && Utils.randInt(2) === 1);
|
|
||||||
|
|
||||||
if (!isDelayed)
|
|
||||||
handlePokemon(playerPokemon);
|
|
||||||
handlePokemon(enemyPokemon);
|
|
||||||
if (isDelayed)
|
|
||||||
handlePokemon(playerPokemon);
|
|
||||||
|
|
||||||
this.scene.arena.lapseTags();
|
this.scene.arena.lapseTags();
|
||||||
|
|
||||||
|
@ -687,7 +695,7 @@ export class BattleEndPhase extends BattlePhase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class PokemonPhase extends BattlePhase {
|
export abstract class PokemonPhase extends FieldPhase {
|
||||||
protected player: boolean;
|
protected player: boolean;
|
||||||
|
|
||||||
constructor(scene: BattleScene, player: boolean) {
|
constructor(scene: BattleScene, player: boolean) {
|
||||||
|
@ -1079,6 +1087,18 @@ export class MoveAnimTestPhase extends BattlePhase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ShowAbilityPhase extends PokemonPhase {
|
||||||
|
constructor(scene: BattleScene, player: boolean) {
|
||||||
|
super(scene, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.scene.abilityBar.showAbility(this.getPokemon());
|
||||||
|
|
||||||
|
this.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class StatChangePhase extends PokemonPhase {
|
export class StatChangePhase extends PokemonPhase {
|
||||||
private stats: BattleStat[];
|
private stats: BattleStat[];
|
||||||
private selfTarget: boolean;
|
private selfTarget: boolean;
|
||||||
|
@ -1088,6 +1108,7 @@ export class StatChangePhase extends PokemonPhase {
|
||||||
super(scene, player);
|
super(scene, player);
|
||||||
|
|
||||||
const allStats = Utils.getEnumValues(BattleStat);
|
const allStats = Utils.getEnumValues(BattleStat);
|
||||||
|
this.selfTarget = selfTarget;
|
||||||
this.stats = stats.map(s => s !== BattleStat.RAND ? s : allStats[Utils.randInt(BattleStat.SPD + 1)]);
|
this.stats = stats.map(s => s !== BattleStat.RAND ? s : allStats[Utils.randInt(BattleStat.SPD + 1)]);
|
||||||
this.levels = levels;
|
this.levels = levels;
|
||||||
}
|
}
|
||||||
|
@ -1099,7 +1120,7 @@ export class StatChangePhase extends PokemonPhase {
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
|
|
||||||
if (!this.selfTarget && this.levels < 0)
|
if (!this.selfTarget && this.levels < 0)
|
||||||
applyPreStatChangeAbilityAttrs(ProtectStatAttr, this.getPokemon(), stat, cancelled);
|
applyPreStatChangeAbAttrs(ProtectStatAttr, this.getPokemon(), stat, cancelled);
|
||||||
|
|
||||||
return !cancelled.value;
|
return !cancelled.value;
|
||||||
});
|
});
|
||||||
|
@ -1170,37 +1191,46 @@ export class StatChangePhase extends PokemonPhase {
|
||||||
|
|
||||||
export class WeatherEffectPhase extends CommonAnimPhase {
|
export class WeatherEffectPhase extends CommonAnimPhase {
|
||||||
private weather: Weather;
|
private weather: Weather;
|
||||||
private playerDelayed: boolean;
|
|
||||||
|
|
||||||
constructor(scene: BattleScene, weather: Weather, playerDelayed: boolean) {
|
constructor(scene: BattleScene, weather: Weather) {
|
||||||
super(scene, true, CommonAnim.SUNNY + (weather.weatherType - 1));
|
super(scene, true, CommonAnim.SUNNY + (weather.weatherType - 1));
|
||||||
this.weather = weather;
|
this.weather = weather;
|
||||||
this.playerDelayed = playerDelayed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
if (this.weather.isDamaging()) {
|
if (this.weather.isDamaging()) {
|
||||||
const inflictDamage = (pokemon: Pokemon) => {
|
|
||||||
this.scene.queueMessage(getWeatherDamageMessage(this.weather.weatherType, pokemon));
|
|
||||||
this.scene.unshiftPhase(new DamagePhase(this.scene, pokemon.isPlayer()));
|
|
||||||
pokemon.damage(Math.ceil(pokemon.getMaxHp() / 16));
|
|
||||||
};
|
|
||||||
|
|
||||||
const playerPokemon = this.scene.getPlayerPokemon();
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
const enemyPokemon = this.scene.getEnemyPokemon();
|
|
||||||
|
|
||||||
const playerImmune = !playerPokemon || !!playerPokemon.getTypes().filter(t => this.weather.isTypeDamageImmune(t)).length;
|
this.executeForBoth((pokemon: Pokemon) => applyPreWeatherEffectAbAttrs(SuppressWeatherEffectAbAttr, pokemon, this.weather, cancelled));
|
||||||
const enemyImmune = !enemyPokemon || !!enemyPokemon.getTypes().filter(t => this.weather.isTypeDamageImmune(t)).length;
|
|
||||||
|
|
||||||
if (!this.playerDelayed && !playerImmune)
|
if (!cancelled.value) {
|
||||||
inflictDamage(playerPokemon);
|
const inflictDamage = (pokemon: Pokemon) => {
|
||||||
if (!enemyImmune)
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
inflictDamage(enemyPokemon);
|
|
||||||
if (this.playerDelayed && !playerImmune)
|
applyPreWeatherEffectAbAttrs(PreWeatherDamageAbAttr, pokemon, this.weather, cancelled);
|
||||||
inflictDamage(playerPokemon);
|
|
||||||
|
if (cancelled.value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.scene.queueMessage(getWeatherDamageMessage(this.weather.weatherType, pokemon));
|
||||||
|
this.scene.unshiftPhase(new DamagePhase(this.scene, pokemon.isPlayer()));
|
||||||
|
pokemon.damage(Math.ceil(pokemon.getMaxHp() / 16));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.executeForBoth((pokemon: Pokemon) => {
|
||||||
|
const immune = !pokemon || !!pokemon.getTypes().filter(t => this.weather.isTypeDamageImmune(t)).length;
|
||||||
|
if (!immune)
|
||||||
|
inflictDamage(pokemon);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scene.ui.showText(getWeatherLapseMessage(this.weather.weatherType), null, () => super.start());
|
this.scene.ui.showText(getWeatherLapseMessage(this.weather.weatherType), null, () => {
|
||||||
|
this.executeForBoth((pokemon: Pokemon) => applyPostWeatherLapseAbAttrs(PostWeatherLapseAbAttr, pokemon, this.weather));
|
||||||
|
|
||||||
|
super.start();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Biome } from './data/biome';
|
||||||
import UI from './ui/ui';
|
import UI from './ui/ui';
|
||||||
import { EncounterPhase, SummonPhase, CommandPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, SelectStarterPhase, MessagePhase } from './battle-phases';
|
import { EncounterPhase, SummonPhase, CommandPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, SelectStarterPhase, MessagePhase } from './battle-phases';
|
||||||
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
|
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
|
||||||
import PokemonSpecies, { allSpecies, getPokemonSpecies } from './data/pokemon-species';
|
import PokemonSpecies, { allSpecies, getPokemonSpecies, initSpecies } from './data/pokemon-species';
|
||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PartyShareModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate } from './modifier/modifier';
|
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PartyShareModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate } from './modifier/modifier';
|
||||||
import { PokeballType } from './data/pokeball';
|
import { PokeballType } from './data/pokeball';
|
||||||
|
@ -17,9 +17,10 @@ import { Arena } from './arena';
|
||||||
import { GameData } from './system/game-data';
|
import { GameData } from './system/game-data';
|
||||||
import StarterSelectUiHandler from './ui/starter-select-ui-handler';
|
import StarterSelectUiHandler from './ui/starter-select-ui-handler';
|
||||||
import { TextStyle, addTextObject } from './ui/text';
|
import { TextStyle, addTextObject } from './ui/text';
|
||||||
import { Moves } from './data/move';
|
import { Moves, initMoves } from './data/move';
|
||||||
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave } from './modifier/modifier-type';
|
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave } from './modifier/modifier-type';
|
||||||
import AbilityBar from './ui/ability-bar';
|
import AbilityBar from './ui/ability-bar';
|
||||||
|
import { initAbilities } from './data/ability';
|
||||||
|
|
||||||
const enableAuto = true;
|
const enableAuto = true;
|
||||||
const quickStart = false;
|
const quickStart = false;
|
||||||
|
@ -58,6 +59,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
|
|
||||||
private phaseQueue: BattlePhase[];
|
private phaseQueue: BattlePhase[];
|
||||||
private phaseQueuePrepend: BattlePhase[];
|
private phaseQueuePrepend: BattlePhase[];
|
||||||
|
private phaseQueuePrependSpliceIndex: integer;
|
||||||
private currentPhase: BattlePhase;
|
private currentPhase: BattlePhase;
|
||||||
public field: Phaser.GameObjects.Container;
|
public field: Phaser.GameObjects.Container;
|
||||||
public fieldUI: Phaser.GameObjects.Container;
|
public fieldUI: Phaser.GameObjects.Container;
|
||||||
|
@ -94,10 +96,15 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('battle');
|
super('battle');
|
||||||
|
|
||||||
|
initSpecies();
|
||||||
|
initMoves();
|
||||||
|
initAbilities();
|
||||||
|
|
||||||
this.gameData = new GameData(this);
|
this.gameData = new GameData(this);
|
||||||
|
|
||||||
this.phaseQueue = [];
|
this.phaseQueue = [];
|
||||||
this.phaseQueuePrepend = [];
|
this.phaseQueuePrepend = [];
|
||||||
|
this.phaseQueuePrependSpliceIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadImage(key: string, folder: string, filename?: string) {
|
loadImage(key: string, folder: string, filename?: string) {
|
||||||
|
@ -643,14 +650,27 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
unshiftPhase(phase: BattlePhase): void {
|
unshiftPhase(phase: BattlePhase): void {
|
||||||
this.phaseQueuePrepend.push(phase);
|
if (this.phaseQueuePrependSpliceIndex === -1)
|
||||||
|
this.phaseQueuePrepend.push(phase);
|
||||||
|
else
|
||||||
|
this.phaseQueuePrepend.splice(this.phaseQueuePrependSpliceIndex, 0, phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearPhaseQueue(): void {
|
clearPhaseQueue(): void {
|
||||||
this.phaseQueue.splice(0, this.phaseQueue.length);
|
this.phaseQueue.splice(0, this.phaseQueue.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPhaseQueueSplice(): void {
|
||||||
|
this.phaseQueuePrependSpliceIndex = this.phaseQueuePrepend.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearPhaseQueueSplice(): void {
|
||||||
|
this.phaseQueuePrependSpliceIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
shiftPhase(): void {
|
shiftPhase(): void {
|
||||||
|
if (this.phaseQueuePrependSpliceIndex > -1)
|
||||||
|
this.clearPhaseQueueSplice();
|
||||||
if (this.phaseQueuePrepend.length) {
|
if (this.phaseQueuePrepend.length) {
|
||||||
while (this.phaseQueuePrepend.length)
|
while (this.phaseQueuePrepend.length)
|
||||||
this.phaseQueue.unshift(this.phaseQueuePrepend.pop());
|
this.phaseQueue.unshift(this.phaseQueuePrepend.pop());
|
||||||
|
|
|
@ -2,15 +2,20 @@ import Pokemon, { PokemonMove } from "../pokemon";
|
||||||
import { Type } from "./type";
|
import { Type } from "./type";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import { BattleStat, getBattleStatName } from "./battle-stat";
|
import { BattleStat, getBattleStatName } from "./battle-stat";
|
||||||
import { StatChangePhase } from "../battle-phases";
|
import { PokemonHealPhase, ShowAbilityPhase, StatChangePhase } from "../battle-phases";
|
||||||
import { getPokemonMessage } from "../messages";
|
import { getPokemonMessage } from "../messages";
|
||||||
|
import { Weather, WeatherType } from "./weather";
|
||||||
|
import { BattlerTagType } from "./battler-tag";
|
||||||
|
import { StatusEffect } from "./status-effect";
|
||||||
|
import { Moves, RecoilAttr } from "./move";
|
||||||
|
|
||||||
export class Ability {
|
export class Ability {
|
||||||
public id: Abilities;
|
public id: Abilities;
|
||||||
public name: string;
|
public name: string;
|
||||||
public description: string;
|
public description: string;
|
||||||
public generation: integer;
|
public generation: integer;
|
||||||
public attrs: AbilityAttr[];
|
public attrs: AbAttr[];
|
||||||
|
public conditions: AbAttrCondition[];
|
||||||
|
|
||||||
constructor(id: Abilities, name: string, description: string, generation: integer) {
|
constructor(id: Abilities, name: string, description: string, generation: integer) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -18,39 +23,70 @@ export class Ability {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.generation = generation;
|
this.generation = generation;
|
||||||
this.attrs = [];
|
this.attrs = [];
|
||||||
|
this.conditions = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
getAttrs(attrType: { new(...args: any[]): AbilityAttr }): AbilityAttr[] {
|
getAttrs(attrType: { new(...args: any[]): AbAttr }): AbAttr[] {
|
||||||
return this.attrs.filter(a => a instanceof attrType);
|
return this.attrs.filter(a => a instanceof attrType);
|
||||||
}
|
}
|
||||||
|
|
||||||
attr<T extends new (...args: any[]) => AbilityAttr>(AttrType: T, ...args: ConstructorParameters<T>): Ability {
|
attr<T extends new (...args: any[]) => AbAttr>(AttrType: T, ...args: ConstructorParameters<T>): Ability {
|
||||||
const attr = new AttrType(...args);
|
const attr = new AttrType(...args);
|
||||||
this.attrs.push(attr);
|
this.attrs.push(attr);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
condition(condition: AbAttrCondition): Ability {
|
||||||
|
this.conditions.push(condition);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class AbilityAttr {
|
type AbAttrCondition = (pokemon: Pokemon) => boolean;
|
||||||
|
|
||||||
|
export abstract class AbAttr {
|
||||||
|
apply(pokemon: Pokemon, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
getTriggerMessage(pokemon: Pokemon, ...args: any[]) {
|
getTriggerMessage(pokemon: Pokemon, ...args: any[]) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCondition(): AbAttrCondition {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PreDefendAbilityAttr extends AbilityAttr {
|
export class BlockRecoilDamageAttr extends AbAttr {
|
||||||
|
apply(pokemon: Pokemon, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
cancelled.value = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTriggerMessage(pokemon: Pokemon, ...args: any[]) {
|
||||||
|
return getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nprotected it from recoil!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PreDefendAbAttr extends AbAttr {
|
||||||
applyPreDefend(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
applyPreDefend(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TypeImmunityAttr extends PreDefendAbilityAttr {
|
export class TypeImmunityAbAttr extends PreDefendAbAttr {
|
||||||
private immuneType: Type;
|
private immuneType: Type;
|
||||||
|
private condition: AbAttrCondition;
|
||||||
|
|
||||||
constructor(immuneType: Type) {
|
constructor(immuneType: Type, condition?: AbAttrCondition) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.immuneType = immuneType;
|
this.immuneType = immuneType;
|
||||||
|
this.condition = condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPreDefend(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
applyPreDefend(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
@ -61,14 +97,18 @@ export class TypeImmunityAttr extends PreDefendAbilityAttr {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCondition(): AbAttrCondition {
|
||||||
|
return this.condition;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeImmunityStatChangeAttr extends TypeImmunityAttr {
|
class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
|
||||||
private stat: BattleStat;
|
private stat: BattleStat;
|
||||||
private levels: integer;
|
private levels: integer;
|
||||||
|
|
||||||
constructor(immuneType: Type, stat: BattleStat, levels: integer) {
|
constructor(immuneType: Type, stat: BattleStat, levels: integer, condition?: AbAttrCondition) {
|
||||||
super(immuneType);
|
super(immuneType, condition);
|
||||||
|
|
||||||
this.stat = stat;
|
this.stat = stat;
|
||||||
this.levels = levels;
|
this.levels = levels;
|
||||||
|
@ -86,13 +126,85 @@ class TypeImmunityStatChangeAttr extends TypeImmunityAttr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PreStatChangeAbilityAttr extends AbilityAttr {
|
class TypeImmunityAddBattlerTagAbAttr extends TypeImmunityAbAttr {
|
||||||
|
private tagType: BattlerTagType;
|
||||||
|
private turnCount: integer;
|
||||||
|
|
||||||
|
constructor(immuneType: Type, tagType: BattlerTagType, turnCount: integer, condition?: AbAttrCondition) {
|
||||||
|
super(immuneType, condition);
|
||||||
|
|
||||||
|
this.tagType = tagType;
|
||||||
|
this.turnCount = turnCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyPreDefend(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
const ret = super.applyPreDefend(pokemon, attacker, move, cancelled, args);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
cancelled.value = true;
|
||||||
|
pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PreAttackAbAttr extends AbAttr {
|
||||||
|
applyPreAttack(pokemon: Pokemon, defender: Pokemon, move: PokemonMove, args: any[]): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class VariableMovePowerAbAttr extends PreAttackAbAttr {
|
||||||
|
applyPreAttack(pokemon: Pokemon, defender: Pokemon, move: PokemonMove, args: any[]): boolean {
|
||||||
|
//const power = args[0] as Utils.NumberHolder;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LowHpMoveTypePowerBoostAbAttr extends VariableMovePowerAbAttr {
|
||||||
|
private boostedType: Type;
|
||||||
|
|
||||||
|
constructor(boostedType: Type) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.boostedType = boostedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyPreAttack(pokemon: Pokemon, defender: Pokemon, move: PokemonMove, args: any[]): boolean {
|
||||||
|
if (move.getMove().type === this.boostedType) {
|
||||||
|
(args[0] as Utils.NumberHolder).value *= 1.5;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCondition(): AbAttrCondition {
|
||||||
|
return (pokemon) => pokemon.getHpRatio() <= 0.33;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RecoilMovePowerBoostAbAttr extends VariableMovePowerAbAttr {
|
||||||
|
applyPreAttack(pokemon: Pokemon, defender: Pokemon, move: PokemonMove, args: any[]): boolean {
|
||||||
|
if (move.getMove().getAttrs(RecoilAttr).length && move.moveId !== Moves.STRUGGLE) {
|
||||||
|
(args[0] as Utils.NumberHolder).value *= 1.2;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PreStatChangeAbAttr extends AbAttr {
|
||||||
applyPreStatChange(pokemon: Pokemon, stat: BattleStat, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
applyPreStatChange(pokemon: Pokemon, stat: BattleStat, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProtectStatAttr extends PreStatChangeAbilityAttr {
|
export class ProtectStatAttr extends PreStatChangeAbAttr {
|
||||||
private protectedStat: BattleStat;
|
private protectedStat: BattleStat;
|
||||||
|
|
||||||
constructor(protectedStat?: BattleStat) {
|
constructor(protectedStat?: BattleStat) {
|
||||||
|
@ -115,32 +227,213 @@ export class ProtectStatAttr extends PreStatChangeAbilityAttr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyPreDefendAbilityAttrs(attrType: { new(...args: any[]): PreDefendAbilityAttr },
|
export class PreWeatherEffectAbAttr extends AbAttr {
|
||||||
pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, ...args: any[]): void {
|
applyPreWeatherEffect(pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PreWeatherDamageAbAttr extends PreWeatherEffectAbAttr { }
|
||||||
|
|
||||||
|
export class BlockWeatherDamageAttr extends PreWeatherDamageAbAttr {
|
||||||
|
applyPreWeatherEffect(pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
cancelled.value = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SuppressWeatherEffectAbAttr extends PreWeatherEffectAbAttr {
|
||||||
|
private affectsImmutable: boolean;
|
||||||
|
|
||||||
|
constructor(affectsImmutable?: boolean) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.affectsImmutable = affectsImmutable;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyPreWeatherEffect(pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
if (this.affectsImmutable || weather.isImmutable()) {
|
||||||
|
cancelled.value = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PostWeatherLapseAbAttr extends AbAttr {
|
||||||
|
applyPostWeatherLapse(pokemon: Pokemon, weather: Weather, args: any[]): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WeatherHealAbAttr extends PostWeatherLapseAbAttr {
|
||||||
|
private weatherTypes: WeatherType[];
|
||||||
|
|
||||||
|
constructor(...weatherTypes: WeatherType[]) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.weatherTypes = weatherTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyPostWeatherLapse(pokemon: Pokemon, weather: Weather, args: any[]): boolean {
|
||||||
|
if (this.weatherTypes.indexOf(weather.weatherType) > -1 && pokemon.getHpRatio() < 1) {
|
||||||
|
const scene = pokemon.scene;
|
||||||
|
scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.isPlayer(), Math.max(Math.floor(pokemon.getMaxHp() / 16), 1), getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nrestored its HP a little!`), true));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyAbAttrs(attrType: { new(...args: any[]): AbAttr }, pokemon: Pokemon, cancelled: Utils.BooleanHolder, ...args: any[]): void {
|
||||||
|
if (!pokemon.canApplyAbility())
|
||||||
|
return;
|
||||||
|
|
||||||
const ability = pokemon.getAbility();
|
const ability = pokemon.getAbility();
|
||||||
const attrs = ability.getAttrs(attrType) as PreDefendAbilityAttr[];
|
const attrs = ability.getAttrs(attrType) as AbAttr[];
|
||||||
|
console.log(attrs, ability);
|
||||||
for (let attr of attrs) {
|
for (let attr of attrs) {
|
||||||
|
if (!canApplyAttr(pokemon, attr))
|
||||||
|
continue;
|
||||||
|
pokemon.scene.setPhaseQueueSplice();
|
||||||
|
if (attr.apply(pokemon, cancelled, args)) {
|
||||||
|
queueShowAbility(pokemon);
|
||||||
|
const message = attr.getTriggerMessage(pokemon);
|
||||||
|
if (message)
|
||||||
|
pokemon.scene.queueMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pokemon.scene.clearPhaseQueueSplice();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyPreDefendAbAttrs(attrType: { new(...args: any[]): PreDefendAbAttr },
|
||||||
|
pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, ...args: any[]): void {
|
||||||
|
if (!pokemon.canApplyAbility())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ability = pokemon.getAbility();
|
||||||
|
const attrs = ability.getAttrs(attrType) as PreDefendAbAttr[];
|
||||||
|
for (let attr of attrs) {
|
||||||
|
if (!canApplyAttr(pokemon, attr))
|
||||||
|
continue;
|
||||||
|
pokemon.scene.setPhaseQueueSplice();
|
||||||
if (attr.applyPreDefend(pokemon, attacker, move, cancelled, args)) {
|
if (attr.applyPreDefend(pokemon, attacker, move, cancelled, args)) {
|
||||||
pokemon.scene.abilityBar.showAbility(pokemon);
|
queueShowAbility(pokemon);
|
||||||
const message = attr.getTriggerMessage(pokemon, attacker, move);
|
const message = attr.getTriggerMessage(pokemon, attacker, move);
|
||||||
if (message)
|
if (message)
|
||||||
pokemon.scene.queueMessage(message);
|
pokemon.scene.queueMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pokemon.scene.clearPhaseQueueSplice();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyPreStatChangeAbilityAttrs(attrType: { new(...args: any[]): PreStatChangeAbilityAttr },
|
export function applyPreAttackAbAttrs(attrType: { new(...args: any[]): PreAttackAbAttr },
|
||||||
pokemon: Pokemon, stat: BattleStat, cancelled: Utils.BooleanHolder, ...args: any[]) {
|
pokemon: Pokemon, defender: Pokemon, move: PokemonMove, ...args: any[]): void {
|
||||||
const ability = pokemon.getAbility();
|
if (!pokemon.canApplyAbility())
|
||||||
const attrs = ability.getAttrs(attrType) as PreStatChangeAbilityAttr[];
|
return;
|
||||||
for (let attr of attrs) {
|
|
||||||
if (attr.applyPreStatChange(pokemon, stat, cancelled, args)) {
|
const ability = pokemon.getAbility();
|
||||||
|
const attrs = ability.getAttrs(attrType) as PreAttackAbAttr[];
|
||||||
|
for (let attr of attrs) {
|
||||||
|
if (!canApplyAttr(pokemon, attr))
|
||||||
|
continue;
|
||||||
|
pokemon.scene.setPhaseQueueSplice();
|
||||||
|
if (attr.applyPreAttack(pokemon, defender, move, args)) {
|
||||||
|
queueShowAbility(pokemon);
|
||||||
|
const message = attr.getTriggerMessage(pokemon, defender, move);
|
||||||
|
if (message)
|
||||||
|
pokemon.scene.queueMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pokemon.scene.clearPhaseQueueSplice();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyPreStatChangeAbAttrs(attrType: { new(...args: any[]): PreStatChangeAbAttr },
|
||||||
|
pokemon: Pokemon, stat: BattleStat, cancelled: Utils.BooleanHolder, ...args: any[]): void {
|
||||||
|
if (!pokemon.canApplyAbility())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ability = pokemon.getAbility();
|
||||||
|
const attrs = ability.getAttrs(attrType) as PreStatChangeAbAttr[];
|
||||||
|
for (let attr of attrs) {
|
||||||
|
if (!canApplyAttr(pokemon, attr))
|
||||||
|
continue;
|
||||||
|
pokemon.scene.setPhaseQueueSplice();
|
||||||
|
if (attr.applyPreStatChange(pokemon, stat, cancelled, args)) {
|
||||||
|
queueShowAbility(pokemon);
|
||||||
|
const message = attr.getTriggerMessage(pokemon, stat);
|
||||||
|
if (message)
|
||||||
|
pokemon.scene.queueMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pokemon.scene.clearPhaseQueueSplice();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyPreWeatherEffectAbAttrs(attrType: { new(...args: any[]): PreWeatherEffectAbAttr },
|
||||||
|
pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, silent?: boolean, ...args: any[]): void {
|
||||||
|
if (!pokemon.canApplyAbility())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ability = pokemon.getAbility();
|
||||||
|
const attrs = ability.getAttrs(attrType) as PreWeatherEffectAbAttr[];
|
||||||
|
for (let attr of attrs) {
|
||||||
|
if (!canApplyAttr(pokemon, attr))
|
||||||
|
continue;
|
||||||
|
pokemon.scene.setPhaseQueueSplice();
|
||||||
|
if (attr.applyPreWeatherEffect(pokemon, weather, cancelled, args)) {
|
||||||
|
if (!silent) {
|
||||||
pokemon.scene.abilityBar.showAbility(pokemon);
|
pokemon.scene.abilityBar.showAbility(pokemon);
|
||||||
const message = attr.getTriggerMessage(pokemon, stat);
|
const message = attr.getTriggerMessage(pokemon, weather);
|
||||||
if (message)
|
if (message)
|
||||||
pokemon.scene.queueMessage(message);
|
pokemon.scene.queueMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pokemon.scene.clearPhaseQueueSplice();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyPostWeatherLapseAbAttrs(attrType: { new(...args: any[]): PostWeatherLapseAbAttr },
|
||||||
|
pokemon: Pokemon, weather: Weather, ...args: any[]): void {
|
||||||
|
if (!pokemon.canApplyAbility())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (weather.isEffectSuppressed(pokemon.scene))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ability = pokemon.getAbility();
|
||||||
|
|
||||||
|
const attrs = ability.getAttrs(attrType) as PostWeatherLapseAbAttr[];
|
||||||
|
for (let attr of attrs) {
|
||||||
|
if (!canApplyAttr(pokemon, attr))
|
||||||
|
continue;
|
||||||
|
pokemon.scene.setPhaseQueueSplice();
|
||||||
|
if (attr.applyPostWeatherLapse(pokemon, weather, args)) {
|
||||||
|
queueShowAbility(pokemon);
|
||||||
|
const message = attr.getTriggerMessage(pokemon, weather);
|
||||||
|
if (message)
|
||||||
|
pokemon.scene.queueMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pokemon.scene.clearPhaseQueueSplice();
|
||||||
|
}
|
||||||
|
|
||||||
|
function canApplyAttr(pokemon: Pokemon, attr: AbAttr): boolean {
|
||||||
|
const condition = attr.getCondition();
|
||||||
|
return !condition || condition(pokemon);
|
||||||
|
}
|
||||||
|
|
||||||
|
function queueShowAbility(pokemon: Pokemon): void {
|
||||||
|
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.isPlayer()));
|
||||||
|
pokemon.scene.clearPhaseQueueSplice();
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Abilities {
|
export enum Abilities {
|
||||||
|
@ -317,184 +610,199 @@ export enum Abilities {
|
||||||
NEUTRALIZING_GAS
|
NEUTRALIZING_GAS
|
||||||
}
|
}
|
||||||
|
|
||||||
export const abilities = [
|
export const abilities = [ new Ability(Abilities.NONE, "-", "", 3) ];
|
||||||
new Ability(Abilities.NONE, "- (N)", "", 3),
|
|
||||||
new Ability(Abilities.AIR_LOCK, "Air Lock (N)", "Eliminates the effects of weather.", 3),
|
export function initAbilities() {
|
||||||
new Ability(Abilities.ARENA_TRAP, "Arena Trap (N)", "Prevents the foe from fleeing.", 3),
|
abilities.push(
|
||||||
new Ability(Abilities.BATTLE_ARMOR, "Battle Armor (N)", "The POKéMON is protected against critical hits.", 3),
|
new Ability(Abilities.AIR_LOCK, "Air Lock", "Eliminates the effects of all weather.", 3)
|
||||||
new Ability(Abilities.BLAZE, "Blaze (N)", "Powers up FIRE-type moves in a pinch.", 3),
|
.attr(SuppressWeatherEffectAbAttr, true),
|
||||||
new Ability(Abilities.CHLOROPHYLL, "Chlorophyll (N)", "Boosts the POKéMON's SPEED in sunshine.", 3),
|
new Ability(Abilities.ARENA_TRAP, "Arena Trap (N)", "Prevents the foe from fleeing.", 3),
|
||||||
new Ability(Abilities.CLEAR_BODY, "Clear Body", "Prevents other POKéMON from lowering its stats.", 3)
|
new Ability(Abilities.BATTLE_ARMOR, "Battle Armor (N)", "The POKéMON is protected against critical hits.", 3),
|
||||||
.attr(ProtectStatAttr),
|
new Ability(Abilities.BLAZE, "Blaze", "Powers up FIRE-type moves in a pinch.", 3)
|
||||||
new Ability(Abilities.CLOUD_NINE, "Cloud Nine (N)", "Eliminates the effects of weather.", 3),
|
.attr(LowHpMoveTypePowerBoostAbAttr, Type.FIRE),
|
||||||
new Ability(Abilities.COLOR_CHANGE, "Color Change (N)", "Changes the POKéMON's type to the foe's move.", 3),
|
new Ability(Abilities.CHLOROPHYLL, "Chlorophyll (N)", "Boosts the POKéMON's SPEED in sunshine.", 3),
|
||||||
new Ability(Abilities.COMPOUND_EYES, "Compound Eyes (N)", "The POKéMON's accuracy is boosted.", 3),
|
new Ability(Abilities.CLEAR_BODY, "Clear Body", "Prevents other POKéMON from lowering its stats.", 3)
|
||||||
new Ability(Abilities.CUTE_CHARM, "Cute Charm (N)", "Contact with the POKéMON may cause infatuation.", 3),
|
.attr(ProtectStatAttr),
|
||||||
new Ability(Abilities.DAMP, "Damp (N)", "Prevents the use of self-destructing moves.", 3),
|
new Ability(Abilities.CLOUD_NINE, "Cloud Nine", "Eliminates the effects of non-severe weather.", 3)
|
||||||
new Ability(Abilities.DRIZZLE, "Drizzle (N)", "The POKéMON makes it rain when it enters a battle.", 3),
|
.attr(SuppressWeatherEffectAbAttr),
|
||||||
new Ability(Abilities.DROUGHT, "Drought (N)", "Turns the sunlight harsh when the POKéMON enters a battle.", 3),
|
new Ability(Abilities.COLOR_CHANGE, "Color Change (N)", "Changes the POKéMON's type to the foe's move.", 3),
|
||||||
new Ability(Abilities.EARLY_BIRD, "Early Bird (N)", "The POKéMON awakens quickly from sleep.", 3),
|
new Ability(Abilities.COMPOUND_EYES, "Compound Eyes (N)", "The POKéMON's accuracy is boosted.", 3),
|
||||||
new Ability(Abilities.EFFECT_SPORE, "Effect Spore (N)", "Contact may poison or cause paralysis or sleep.", 3),
|
new Ability(Abilities.CUTE_CHARM, "Cute Charm (N)", "Contact with the POKéMON may cause infatuation.", 3),
|
||||||
new Ability(Abilities.FLAME_BODY, "Flame Body (N)", "Contact with the POKéMON may burn the attacker.", 3),
|
new Ability(Abilities.DAMP, "Damp (N)", "Prevents the use of self-destructing moves.", 3),
|
||||||
new Ability(Abilities.FLASH_FIRE, "Flash Fire (N)", "It powers up FIRE-type moves if it's hit by one.", 3),
|
new Ability(Abilities.DRIZZLE, "Drizzle (N)", "The POKéMON makes it rain when it enters a battle.", 3),
|
||||||
new Ability(Abilities.FORECAST, "Forecast (N)", "Castform transforms with the weather.", 3),
|
new Ability(Abilities.DROUGHT, "Drought (N)", "Turns the sunlight harsh when the POKéMON enters a battle.", 3),
|
||||||
new Ability(Abilities.GUTS, "Guts (N)", "Boosts ATTACK if there is a status problem.", 3),
|
new Ability(Abilities.EARLY_BIRD, "Early Bird (N)", "The POKéMON awakens quickly from sleep.", 3),
|
||||||
new Ability(Abilities.HUGE_POWER, "Huge Power (N)", "Raises the POKéMON's ATTACK stat.", 3),
|
new Ability(Abilities.EFFECT_SPORE, "Effect Spore (N)", "Contact may poison or cause paralysis or sleep.", 3),
|
||||||
new Ability(Abilities.HUSTLE, "Hustle (N)", "Boosts the ATTACK stat, but lowers accuracy.", 3),
|
new Ability(Abilities.FLAME_BODY, "Flame Body (N)", "Contact with the POKéMON may burn the attacker.", 3),
|
||||||
new Ability(Abilities.HYPER_CUTTER, "Hyper Cutter", "Prevents other POKéMON from lowering ATTACK stat.", 3)
|
new Ability(Abilities.FLASH_FIRE, "Flash Fire", "It powers up FIRE-type moves if it's hit by one.", 3)
|
||||||
.attr(ProtectStatAttr, BattleStat.ATK),
|
.attr(TypeImmunityAddBattlerTagAbAttr, Type.FIRE, 1, BattlerTagType.FIRE_BOOST, (pokemon: Pokemon) => !pokemon.status || pokemon.status.effect !== StatusEffect.FREEZE),
|
||||||
new Ability(Abilities.ILLUMINATE, "Illuminate (N)", "Raises the likelihood of meeting wild POKéMON.", 3),
|
new Ability(Abilities.FORECAST, "Forecast (N)", "Castform transforms with the weather.", 3),
|
||||||
new Ability(Abilities.IMMUNITY, "Immunity (N)", "Prevents the POKéMON from getting poisoned.", 3),
|
new Ability(Abilities.GUTS, "Guts (N)", "Boosts ATTACK if there is a status problem.", 3),
|
||||||
new Ability(Abilities.INNER_FOCUS, "Inner Focus (N)", "The POKéMON is protected from flinching.", 3),
|
new Ability(Abilities.HUGE_POWER, "Huge Power (N)", "Raises the POKéMON's ATTACK stat.", 3),
|
||||||
new Ability(Abilities.INSOMNIA, "Insomnia (N)", "Prevents the POKéMON from falling asleep.", 3),
|
new Ability(Abilities.HUSTLE, "Hustle (N)", "Boosts the ATTACK stat, but lowers accuracy.", 3),
|
||||||
new Ability(Abilities.INTIMIDATE, "Intimidate (N)", "Lowers the foe's ATTACK stat.", 3),
|
new Ability(Abilities.HYPER_CUTTER, "Hyper Cutter", "Prevents other POKéMON from lowering ATTACK stat.", 3)
|
||||||
new Ability(Abilities.KEEN_EYE, "Keen Eye", "Prevents other POKéMON from lowering accuracy.", 3)
|
.attr(ProtectStatAttr, BattleStat.ATK),
|
||||||
.attr(ProtectStatAttr, BattleStat.ACC),
|
new Ability(Abilities.ILLUMINATE, "Illuminate (N)", "Raises the likelihood of meeting wild POKéMON.", 3),
|
||||||
new Ability(Abilities.LEVITATE, "Levitate", "Gives immunity to GROUND-type moves.", 3)
|
new Ability(Abilities.IMMUNITY, "Immunity (N)", "Prevents the POKéMON from getting poisoned.", 3),
|
||||||
.attr(TypeImmunityAttr, Type.FLYING),
|
new Ability(Abilities.INNER_FOCUS, "Inner Focus (N)", "The POKéMON is protected from flinching.", 3),
|
||||||
new Ability(Abilities.LIGHTNING_ROD, "Lightning Rod", "Draws in all ELECTRIC-type moves to up SP. ATK.", 3)
|
new Ability(Abilities.INSOMNIA, "Insomnia (N)", "Prevents the POKéMON from falling asleep.", 3),
|
||||||
.attr(TypeImmunityStatChangeAttr, Type.ELECTRIC, BattleStat.SPATK, 1),
|
new Ability(Abilities.INTIMIDATE, "Intimidate (N)", "Lowers the foe's ATTACK stat.", 3),
|
||||||
new Ability(Abilities.LIMBER, "Limber (N)", "The POKéMON is protected from paralysis.", 3),
|
new Ability(Abilities.KEEN_EYE, "Keen Eye", "Prevents other POKéMON from lowering accuracy.", 3)
|
||||||
new Ability(Abilities.LIQUID_OOZE, "Liquid Ooze (N)", "Damages attackers using any draining move.", 3),
|
.attr(ProtectStatAttr, BattleStat.ACC),
|
||||||
new Ability(Abilities.MAGMA_ARMOR, "Magma Armor (N)", "Prevents the POKéMON from becoming frozen.", 3),
|
new Ability(Abilities.LEVITATE, "Levitate", "Gives immunity to GROUND-type moves.", 3)
|
||||||
new Ability(Abilities.MAGNET_PULL, "Magnet Pull (N)", "Prevents STEEL-type POKéMON from escaping.", 3),
|
.attr(TypeImmunityAbAttr, Type.FLYING, (pokemon: Pokemon) => !pokemon.getTag(BattlerTagType.IGNORE_FLYING)),
|
||||||
new Ability(Abilities.MARVEL_SCALE, "Marvel Scale (N)", "Ups DEFENSE if there is a status problem.", 3),
|
new Ability(Abilities.LIGHTNING_ROD, "Lightning Rod", "Draws in all ELECTRIC-type moves to up SP. ATK.", 3)
|
||||||
new Ability(Abilities.MINUS, "Minus (N)", "Ups SP. ATK if another POKéMON has PLUS or MINUS.", 3),
|
.attr(TypeImmunityStatChangeAbAttr, Type.ELECTRIC, BattleStat.SPATK, 1),
|
||||||
new Ability(Abilities.NATURAL_CURE, "Natural Cure (N)", "All status problems heal when it switches out.", 3),
|
new Ability(Abilities.LIMBER, "Limber (N)", "The POKéMON is protected from paralysis.", 3),
|
||||||
new Ability(Abilities.OBLIVIOUS, "Oblivious (N)", "Prevents it from becoming infatuated.", 3),
|
new Ability(Abilities.LIQUID_OOZE, "Liquid Ooze (N)", "Damages attackers using any draining move.", 3),
|
||||||
new Ability(Abilities.OVERGROW, "Overgrow (N)", "Powers up GRASS-type moves in a pinch.", 3),
|
new Ability(Abilities.MAGMA_ARMOR, "Magma Armor (N)", "Prevents the POKéMON from becoming frozen.", 3),
|
||||||
new Ability(Abilities.OWN_TEMPO, "Own Tempo (N)", "Prevents the POKéMON from becoming confused.", 3),
|
new Ability(Abilities.MAGNET_PULL, "Magnet Pull (N)", "Prevents STEEL-type POKéMON from escaping.", 3),
|
||||||
new Ability(Abilities.PICKUP, "Pickup (N)", "The POKéMON may pick up items.", 3),
|
new Ability(Abilities.MARVEL_SCALE, "Marvel Scale (N)", "Ups DEFENSE if there is a status problem.", 3),
|
||||||
new Ability(Abilities.PLUS, "Plus (N)", "Ups SP. ATK if another POKéMON has PLUS or MINUS.", 3),
|
new Ability(Abilities.MINUS, "Minus (N)", "Ups SP. ATK if another POKéMON has PLUS or MINUS.", 3),
|
||||||
new Ability(Abilities.POISON_POINT, "Poison Point (N)", "Contact with the POKéMON may poison the attacker.", 3),
|
new Ability(Abilities.NATURAL_CURE, "Natural Cure (N)", "All status problems heal when it switches out.", 3),
|
||||||
new Ability(Abilities.PRESSURE, "Pressure (N)", "The POKéMON raises the foe's PP usage.", 3),
|
new Ability(Abilities.OBLIVIOUS, "Oblivious (N)", "Prevents it from becoming infatuated.", 3),
|
||||||
new Ability(Abilities.PURE_POWER, "Pure Power (N)", "Raises the POKéMON's ATTACK stat.", 3),
|
new Ability(Abilities.OVERGROW, "Overgrow", "Powers up GRASS-type moves in a pinch.", 3)
|
||||||
new Ability(Abilities.RAIN_DISH, "Rain Dish (N)", "The POKéMON gradually regains HP in rain.", 3),
|
.attr(LowHpMoveTypePowerBoostAbAttr, Type.GRASS),
|
||||||
new Ability(Abilities.ROCK_HEAD, "Rock Head (N)", "Protects the POKéMON from recoil damage.", 3),
|
new Ability(Abilities.OWN_TEMPO, "Own Tempo (N)", "Prevents the POKéMON from becoming confused.", 3),
|
||||||
new Ability(Abilities.ROUGH_SKIN, "Rough Skin (N)", "Inflicts damage to the attacker on contact.", 3),
|
new Ability(Abilities.PICKUP, "Pickup (N)", "The POKéMON may pick up items.", 3),
|
||||||
new Ability(Abilities.RUN_AWAY, "Run Away (N)", "Enables a sure getaway from wild POKéMON.", 3),
|
new Ability(Abilities.PLUS, "Plus (N)", "Ups SP. ATK if another POKéMON has PLUS or MINUS.", 3),
|
||||||
new Ability(Abilities.SAND_STREAM, "Sand Stream (N)", "The POKéMON summons a sandstorm in battle.", 3),
|
new Ability(Abilities.POISON_POINT, "Poison Point (N)", "Contact with the POKéMON may poison the attacker.", 3),
|
||||||
new Ability(Abilities.SAND_VEIL, "Sand Veil (N)", "Boosts the POKéMON's evasion in a sandstorm.", 3),
|
new Ability(Abilities.PRESSURE, "Pressure (N)", "The POKéMON raises the foe's PP usage.", 3),
|
||||||
new Ability(Abilities.SERENE_GRACE, "Serene Grace (N)", "Boosts the likelihood of added effects appearing.", 3),
|
new Ability(Abilities.PURE_POWER, "Pure Power (N)", "Raises the POKéMON's ATTACK stat.", 3),
|
||||||
new Ability(Abilities.SHADOW_TAG, "Shadow Tag (N)", "Prevents the foe from escaping.", 3),
|
new Ability(Abilities.RAIN_DISH, "Rain Dish", "The POKéMON gradually regains HP in rain.", 3)
|
||||||
new Ability(Abilities.SHED_SKIN, "Shed Skin (N)", "The POKéMON may heal its own status problems.", 3),
|
.attr(WeatherHealAbAttr, WeatherType.RAIN, WeatherType.HEAVY_RAIN),
|
||||||
new Ability(Abilities.SHELL_ARMOR, "Shell Armor (N)", "The POKéMON is protected against critical hits.", 3),
|
new Ability(Abilities.ROCK_HEAD, "Rock Head", "Protects the POKéMON from recoil damage.", 3)
|
||||||
new Ability(Abilities.SHIELD_DUST, "Shield Dust (N)", "Blocks the added effects of attacks taken.", 3),
|
.attr(BlockRecoilDamageAttr),
|
||||||
new Ability(Abilities.SOUNDPROOF, "Soundproof (N)", "Gives immunity to sound-based moves.", 3),
|
new Ability(Abilities.ROUGH_SKIN, "Rough Skin (N)", "Inflicts damage to the attacker on contact.", 3),
|
||||||
new Ability(Abilities.SPEED_BOOST, "Speed Boost (N)", "Its SPEED stat is gradually boosted.", 3),
|
new Ability(Abilities.RUN_AWAY, "Run Away (N)", "Enables a sure getaway from wild POKéMON.", 3),
|
||||||
new Ability(Abilities.STATIC, "Static (N)", "Contact with the POKéMON may cause paralysis.", 3),
|
new Ability(Abilities.SAND_STREAM, "Sand Stream (N)", "The POKéMON summons a sandstorm in battle.", 3),
|
||||||
new Ability(Abilities.STENCH, "Stench (N)", "The stench may cause the target to flinch.", 3),
|
new Ability(Abilities.SAND_VEIL, "Sand Veil (N)", "Boosts the POKéMON's evasion in a sandstorm.", 3),
|
||||||
new Ability(Abilities.STICKY_HOLD, "Sticky Hold (N)", "Protects the POKéMON from item theft.", 3),
|
new Ability(Abilities.SERENE_GRACE, "Serene Grace (N)", "Boosts the likelihood of added effects appearing.", 3),
|
||||||
new Ability(Abilities.STURDY, "Sturdy (N)", "It cannot be knocked out with one hit.", 3),
|
new Ability(Abilities.SHADOW_TAG, "Shadow Tag (N)", "Prevents the foe from escaping.", 3),
|
||||||
new Ability(Abilities.SUCTION_CUPS, "Suction Cups (N)", "Negates all moves that force switching out.", 3),
|
new Ability(Abilities.SHED_SKIN, "Shed Skin (N)", "The POKéMON may heal its own status problems.", 3),
|
||||||
new Ability(Abilities.SWARM, "Swarm (N)", "Powers up BUG-type moves in a pinch.", 3),
|
new Ability(Abilities.SHELL_ARMOR, "Shell Armor (N)", "The POKéMON is protected against critical hits.", 3),
|
||||||
new Ability(Abilities.SWIFT_SWIM, "Swift Swim (N)", "Boosts the POKéMON's SPEED in rain.", 3),
|
new Ability(Abilities.SHIELD_DUST, "Shield Dust (N)", "Blocks the added effects of attacks taken.", 3),
|
||||||
new Ability(Abilities.SYNCHRONIZE, "Synchronize (N)", "Passes a burn, poison, or paralysis to the foe.", 3),
|
new Ability(Abilities.SOUNDPROOF, "Soundproof (N)", "Gives immunity to sound-based moves.", 3),
|
||||||
new Ability(Abilities.THICK_FAT, "Thick Fat (N)", "Ups resistance to Fire- and ICE-type moves.", 3),
|
new Ability(Abilities.SPEED_BOOST, "Speed Boost (N)", "Its SPEED stat is gradually boosted.", 3),
|
||||||
new Ability(Abilities.TORRENT, "Torrent (N)", "Powers up WATER-type moves in a pinch.", 3),
|
new Ability(Abilities.STATIC, "Static (N)", "Contact with the POKéMON may cause paralysis.", 3),
|
||||||
new Ability(Abilities.TRACE, "Trace (N)", "The POKéMON copies a foe's Ability.", 3),
|
new Ability(Abilities.STENCH, "Stench (N)", "The stench may cause the target to flinch.", 3),
|
||||||
new Ability(Abilities.TRUANT, "Truant (N)", "POKéMON can't attack on consecutive turns.", 3),
|
new Ability(Abilities.STICKY_HOLD, "Sticky Hold (N)", "Protects the POKéMON from item theft.", 3),
|
||||||
new Ability(Abilities.VITAL_SPIRIT, "Vital Spirit (N)", "Prevents the POKéMON from falling asleep.", 3),
|
new Ability(Abilities.STURDY, "Sturdy (N)", "It cannot be knocked out with one hit.", 3),
|
||||||
new Ability(Abilities.VOLT_ABSORB, "Volt Absorb (N)", "Restores HP if hit by an ELECTRIC-type move.", 3),
|
new Ability(Abilities.SUCTION_CUPS, "Suction Cups (N)", "Negates all moves that force switching out.", 3),
|
||||||
new Ability(Abilities.WATER_ABSORB, "Water Absorb (N)", "Restores HP if hit by a WATER-type move.", 3),
|
new Ability(Abilities.SWARM, "Swarm", "Powers up BUG-type moves in a pinch.", 3)
|
||||||
new Ability(Abilities.WATER_VEIL, "Water Veil (N)", "Prevents the POKéMON from getting a burn.", 3),
|
.attr(LowHpMoveTypePowerBoostAbAttr, Type.BUG),
|
||||||
new Ability(Abilities.WHITE_SMOKE, "White Smoke", "Prevents other POKéMON from lowering its stats.", 3)
|
new Ability(Abilities.SWIFT_SWIM, "Swift Swim (N)", "Boosts the POKéMON's SPEED in rain.", 3),
|
||||||
.attr(ProtectStatAttr),
|
new Ability(Abilities.SYNCHRONIZE, "Synchronize (N)", "Passes a burn, poison, or paralysis to the foe.", 3),
|
||||||
new Ability(Abilities.WONDER_GUARD, "Wonder Guard (N)", "Only supereffective moves will hit.", 3),
|
new Ability(Abilities.THICK_FAT, "Thick Fat (N)", "Ups resistance to Fire- and ICE-type moves.", 3),
|
||||||
new Ability(Abilities.ADAPTABILITY, "Adaptability (N)", "Powers up moves of the same type.", 4),
|
new Ability(Abilities.TORRENT, "Torrent", "Powers up WATER-type moves in a pinch.", 3)
|
||||||
new Ability(Abilities.AFTERMATH, "Aftermath (N)", "Damages the attacker landing the finishing hit.", 4),
|
.attr(LowHpMoveTypePowerBoostAbAttr, Type.WATER),
|
||||||
new Ability(Abilities.ANGER_POINT, "Anger Point (N)", "Maxes ATTACK after taking a critical hit.", 4),
|
new Ability(Abilities.TRACE, "Trace (N)", "The POKéMON copies a foe's Ability.", 3),
|
||||||
new Ability(Abilities.ANTICIPATION, "Anticipation (N)", "Senses a foe's dangerous moves.", 4),
|
new Ability(Abilities.TRUANT, "Truant (N)", "POKéMON can't attack on consecutive turns.", 3),
|
||||||
new Ability(Abilities.BAD_DREAMS, "Bad Dreams (N)", "Reduces a sleeping foe's HP.", 4),
|
new Ability(Abilities.VITAL_SPIRIT, "Vital Spirit (N)", "Prevents the POKéMON from falling asleep.", 3),
|
||||||
new Ability(Abilities.DOWNLOAD, "Download (N)", "Adjusts power according to a foe's defenses.", 4),
|
new Ability(Abilities.VOLT_ABSORB, "Volt Absorb (N)", "Restores HP if hit by an ELECTRIC-type move.", 3),
|
||||||
new Ability(Abilities.DRY_SKIN, "Dry Skin (N)", "Reduces HP if it is hot. Water restores HP.", 4),
|
new Ability(Abilities.WATER_ABSORB, "Water Absorb (N)", "Restores HP if hit by a WATER-type move.", 3),
|
||||||
new Ability(Abilities.FILTER, "Filter (N)", "Reduces damage from super-effective attacks.", 4),
|
new Ability(Abilities.WATER_VEIL, "Water Veil (N)", "Prevents the POKéMON from getting a burn.", 3),
|
||||||
new Ability(Abilities.FLOWER_GIFT, "Flower Gift (N)", "Powers up party POKéMON when it is sunny.", 4),
|
new Ability(Abilities.WHITE_SMOKE, "White Smoke", "Prevents other POKéMON from lowering its stats.", 3)
|
||||||
new Ability(Abilities.FOREWARN, "Forewarn (N)", "Determines what moves a foe has.", 4),
|
.attr(ProtectStatAttr),
|
||||||
new Ability(Abilities.FRISK, "Frisk (N)", "The POKéMON can check a foe's held item.", 4),
|
new Ability(Abilities.WONDER_GUARD, "Wonder Guard (N)", "Only supereffective moves will hit.", 3),
|
||||||
new Ability(Abilities.GLUTTONY, "Gluttony (N)", "Encourages the early use of a held Berry.", 4),
|
new Ability(Abilities.ADAPTABILITY, "Adaptability (N)", "Powers up moves of the same type.", 4),
|
||||||
new Ability(Abilities.HEATPROOF, "Heatproof (N)", "Weakens the power of FIRE-type moves.", 4),
|
new Ability(Abilities.AFTERMATH, "Aftermath (N)", "Damages the attacker landing the finishing hit.", 4),
|
||||||
new Ability(Abilities.HONEY_GATHER, "Honey Gather (N)", "The POKéMON may gather Honey from somewhere.", 4),
|
new Ability(Abilities.ANGER_POINT, "Anger Point (N)", "Maxes ATTACK after taking a critical hit.", 4),
|
||||||
new Ability(Abilities.HYDRATION, "Hydration (N)", "Heals status problems if it is raining.", 4),
|
new Ability(Abilities.ANTICIPATION, "Anticipation (N)", "Senses a foe's dangerous moves.", 4),
|
||||||
new Ability(Abilities.ICE_BODY, "Ice Body (N)", "The POKéMON gradually regains HP in a hailstorm.", 4),
|
new Ability(Abilities.BAD_DREAMS, "Bad Dreams (N)", "Reduces a sleeping foe's HP.", 4),
|
||||||
new Ability(Abilities.IRON_FIST, "Iron Fist (N)", "Boosts the power of punching moves.", 4),
|
new Ability(Abilities.DOWNLOAD, "Download (N)", "Adjusts power according to a foe's defenses.", 4),
|
||||||
new Ability(Abilities.KLUTZ, "Klutz (N)", "The POKéMON can't use any held items.", 4),
|
new Ability(Abilities.DRY_SKIN, "Dry Skin (N)", "Reduces HP if it is hot. Water restores HP.", 4),
|
||||||
new Ability(Abilities.LEAF_GUARD, "Leaf Guard (N)", "Prevents problems with status in sunny weather.", 4),
|
new Ability(Abilities.FILTER, "Filter (N)", "Reduces damage from super-effective attacks.", 4),
|
||||||
new Ability(Abilities.MAGIC_GUARD, "Magic Guard (N)", "Protects the POKéMON from indirect damage.", 4),
|
new Ability(Abilities.FLOWER_GIFT, "Flower Gift (N)", "Powers up party POKéMON when it is sunny.", 4),
|
||||||
new Ability(Abilities.MOLD_BREAKER, "Mold Breaker (N)", "Moves can be used regardless of Abilities.", 4),
|
new Ability(Abilities.FOREWARN, "Forewarn (N)", "Determines what moves a foe has.", 4),
|
||||||
new Ability(Abilities.MOTOR_DRIVE, "Motor Drive (N)", "Raises SPEED if hit by an ELECTRIC-type move.", 4),
|
new Ability(Abilities.FRISK, "Frisk (N)", "The POKéMON can check a foe's held item.", 4),
|
||||||
new Ability(Abilities.MULTITYPE, "Multitype (N)", "Changes type to match the held Plate.", 4),
|
new Ability(Abilities.GLUTTONY, "Gluttony (N)", "Encourages the early use of a held Berry.", 4),
|
||||||
new Ability(Abilities.NO_GUARD, "No Guard (N)", "Ensures attacks by or against the POKéMON land.", 4),
|
new Ability(Abilities.HEATPROOF, "Heatproof (N)", "Weakens the power of FIRE-type moves.", 4),
|
||||||
new Ability(Abilities.NORMALIZE, "Normalize (N)", "All the POKéMON's moves become the NORMAL type.", 4),
|
new Ability(Abilities.HONEY_GATHER, "Honey Gather (N)", "The POKéMON may gather Honey from somewhere.", 4),
|
||||||
new Ability(Abilities.POISON_HEAL, "Poison Heal (N)", "Restores HP if the POKéMON is poisoned.", 4),
|
new Ability(Abilities.HYDRATION, "Hydration (N)", "Heals status problems if it is raining.", 4),
|
||||||
new Ability(Abilities.QUICK_FEET, "Quick Feet (N)", "Boosts SPEED if there is a status problem.", 4),
|
new Ability(Abilities.ICE_BODY, "Ice Body", "The POKéMON gradually regains HP in a hailstorm.", 4)
|
||||||
new Ability(Abilities.RECKLESS, "Reckless (N)", "Powers up moves that have recoil damage.", 4),
|
.attr(WeatherHealAbAttr, WeatherType.HAIL),
|
||||||
new Ability(Abilities.RIVALRY, "Rivalry (N)", "Deals more damage to a POKéMON of same gender.", 4),
|
new Ability(Abilities.IRON_FIST, "Iron Fist (N)", "Boosts the power of punching moves.", 4),
|
||||||
new Ability(Abilities.SCRAPPY, "Scrappy (N)", "Enables moves to hit GHOST-type POKéMON.", 4),
|
new Ability(Abilities.KLUTZ, "Klutz (N)", "The POKéMON can't use any held items.", 4),
|
||||||
new Ability(Abilities.SIMPLE, "Simple (N)", "Doubles all stat changes.", 4),
|
new Ability(Abilities.LEAF_GUARD, "Leaf Guard (N)", "Prevents problems with status in sunny weather.", 4),
|
||||||
new Ability(Abilities.SKILL_LINK, "Skill Link (N)", "Increases the frequency of multi-strike moves.", 4),
|
new Ability(Abilities.MAGIC_GUARD, "Magic Guard (N)", "Protects the POKéMON from indirect damage.", 4),
|
||||||
new Ability(Abilities.SLOW_START, "Slow Start (N)", "Temporarily halves ATTACK and SPEED.", 4),
|
new Ability(Abilities.MOLD_BREAKER, "Mold Breaker (N)", "Moves can be used regardless of Abilities.", 4),
|
||||||
new Ability(Abilities.SNIPER, "Sniper (N)", "Powers up moves if they become critical hits.", 4),
|
new Ability(Abilities.MOTOR_DRIVE, "Motor Drive (N)", "Raises SPEED if hit by an ELECTRIC-type move.", 4),
|
||||||
new Ability(Abilities.SNOW_CLOAK, "Snow Cloak (N)", "Raises evasion in a hailstorm.", 4),
|
new Ability(Abilities.MULTITYPE, "Multitype (N)", "Changes type to match the held Plate.", 4),
|
||||||
new Ability(Abilities.SNOW_WARNING, "Snow Warning (N)", "The POKéMON summons a hailstorm in battle.", 4),
|
new Ability(Abilities.NO_GUARD, "No Guard (N)", "Ensures attacks by or against the POKéMON land.", 4),
|
||||||
new Ability(Abilities.SOLAR_POWER, "Solar Power (N)", "In sunshine, SP. ATK is boosted but HP decreases.", 4),
|
new Ability(Abilities.NORMALIZE, "Normalize (N)", "All the POKéMON's moves become the NORMAL type.", 4),
|
||||||
new Ability(Abilities.SOLID_ROCK, "Solid Rock (N)", "Reduces damage from super-effective attacks.", 4),
|
new Ability(Abilities.POISON_HEAL, "Poison Heal (N)", "Restores HP if the POKéMON is poisoned.", 4),
|
||||||
new Ability(Abilities.STALL, "Stall (N)", "The POKéMON moves after all other POKéMON do.", 4),
|
new Ability(Abilities.QUICK_FEET, "Quick Feet (N)", "Boosts SPEED if there is a status problem.", 4),
|
||||||
new Ability(Abilities.STEADFAST, "Steadfast (N)", "Raises SPEED each time the POKéMON flinches.", 4),
|
new Ability(Abilities.RECKLESS, "Reckless", "Powers up moves that have recoil damage.", 4)
|
||||||
new Ability(Abilities.STORM_DRAIN, "Storm Drain", "Draws in all WATER-type moves to up SP. ATK.", 4)
|
.attr(RecoilMovePowerBoostAbAttr),
|
||||||
.attr(TypeImmunityStatChangeAttr, Type.WATER, BattleStat.SPATK, 1),
|
new Ability(Abilities.RIVALRY, "Rivalry (N)", "Deals more damage to a POKéMON of same gender.", 4),
|
||||||
new Ability(Abilities.SUPER_LUCK, "Super Luck (N)", "Heightens the critical-hit ratios of moves.", 4),
|
new Ability(Abilities.SCRAPPY, "Scrappy (N)", "Enables moves to hit GHOST-type POKéMON.", 4),
|
||||||
new Ability(Abilities.TANGLED_FEET, "Tangled Feet (N)", "Raises evasion if the POKéMON is confused.", 4),
|
new Ability(Abilities.SIMPLE, "Simple (N)", "Doubles all stat changes.", 4),
|
||||||
new Ability(Abilities.TECHNICIAN, "Technician (N)", "Powers up the POKéMON's weaker moves.", 4),
|
new Ability(Abilities.SKILL_LINK, "Skill Link (N)", "Increases the frequency of multi-strike moves.", 4),
|
||||||
new Ability(Abilities.TINTED_LENS, "Tinted Lens (N)", "Powers up “not very effective” moves.", 4),
|
new Ability(Abilities.SLOW_START, "Slow Start (N)", "Temporarily halves ATTACK and SPEED.", 4),
|
||||||
new Ability(Abilities.UNAWARE, "Unaware (N)", "Ignores any stat changes in the POKéMON.", 4),
|
new Ability(Abilities.SNIPER, "Sniper (N)", "Powers up moves if they become critical hits.", 4),
|
||||||
new Ability(Abilities.UNBURDEN, "Unburden (N)", "Raises SPEED if a held item is used.", 4),
|
new Ability(Abilities.SNOW_CLOAK, "Snow Cloak (N)", "Raises evasion in a hailstorm.", 4),
|
||||||
new Ability(Abilities.ANALYTIC, "Analytic (N)", "Boosts move power when the POKéMON moves last.", 5),
|
new Ability(Abilities.SNOW_WARNING, "Snow Warning (N)", "The POKéMON summons a hailstorm in battle.", 4),
|
||||||
new Ability(Abilities.BIG_PECKS, "Big Pecks", "Protects the POKéMON from DEFENSE-lowering attacks.", 5)
|
new Ability(Abilities.SOLAR_POWER, "Solar Power (N)", "In sunshine, SP. ATK is boosted but HP decreases.", 4),
|
||||||
.attr(ProtectStatAttr, BattleStat.DEF),
|
new Ability(Abilities.SOLID_ROCK, "Solid Rock (N)", "Reduces damage from super-effective attacks.", 4),
|
||||||
new Ability(Abilities.CONTRARY, "Contrary (N)", "Makes stat changes have an opposite effect.", 5),
|
new Ability(Abilities.STALL, "Stall (N)", "The POKéMON moves after all other POKéMON do.", 4),
|
||||||
new Ability(Abilities.CURSED_BODY, "Cursed Body (N)", "May disable a move used on the POKéMON.", 5),
|
new Ability(Abilities.STEADFAST, "Steadfast (N)", "Raises SPEED each time the POKéMON flinches.", 4),
|
||||||
new Ability(Abilities.DEFEATIST, "Defeatist (N)", "Lowers stats when HP drops below half.", 5),
|
new Ability(Abilities.STORM_DRAIN, "Storm Drain", "Draws in all WATER-type moves to up SP. ATK.", 4)
|
||||||
new Ability(Abilities.DEFIANT, "Defiant (N)", "Sharply raises ATTACK when the POKéMON's stats are lowered.", 5),
|
.attr(TypeImmunityStatChangeAbAttr, Type.WATER, BattleStat.SPATK, 1),
|
||||||
new Ability(Abilities.FLARE_BOOST, "Flare Boost (N)", "Powers up special attacks when burned.", 5),
|
new Ability(Abilities.SUPER_LUCK, "Super Luck (N)", "Heightens the critical-hit ratios of moves.", 4),
|
||||||
new Ability(Abilities.FRIEND_GUARD, "Friend Guard (N)", "Reduces damage done to allies.", 5),
|
new Ability(Abilities.TANGLED_FEET, "Tangled Feet (N)", "Raises evasion if the POKéMON is confused.", 4),
|
||||||
new Ability(Abilities.HARVEST, "Harvest (N)", "May create another Berry after one is used.", 5),
|
new Ability(Abilities.TECHNICIAN, "Technician (N)", "Powers up the POKéMON's weaker moves.", 4),
|
||||||
new Ability(Abilities.HEALER, "Healer (N)", "May heal an ally's status conditions.", 5),
|
new Ability(Abilities.TINTED_LENS, "Tinted Lens (N)", "Powers up “not very effective” moves.", 4),
|
||||||
new Ability(Abilities.HEAVY_METAL, "Heavy Metal (N)", "Doubles the POKéMON's weight.", 5),
|
new Ability(Abilities.UNAWARE, "Unaware (N)", "Ignores any stat changes in the POKéMON.", 4),
|
||||||
new Ability(Abilities.ILLUSION, "Illusion (N)", "Enters battle disguised as the last POKéMON in the party.", 5),
|
new Ability(Abilities.UNBURDEN, "Unburden (N)", "Raises SPEED if a held item is used.", 4),
|
||||||
new Ability(Abilities.IMPOSTER, "Imposter (N)", "It transforms itself into the POKéMON it is facing.", 5),
|
new Ability(Abilities.ANALYTIC, "Analytic (N)", "Boosts move power when the POKéMON moves last.", 5),
|
||||||
new Ability(Abilities.INFILTRATOR, "Infiltrator (N)", "Passes through the foe's barrier and strikes.", 5),
|
new Ability(Abilities.BIG_PECKS, "Big Pecks", "Protects the POKéMON from DEFENSE-lowering attacks.", 5)
|
||||||
new Ability(Abilities.IRON_BARBS, "Iron Barbs (N)", "Inflicts damage to the POKéMON on contact.", 5),
|
.attr(ProtectStatAttr, BattleStat.DEF),
|
||||||
new Ability(Abilities.JUSTIFIED, "Justified (N)", "Raises ATTACK when hit by a DARK-type move.", 5),
|
new Ability(Abilities.CONTRARY, "Contrary (N)", "Makes stat changes have an opposite effect.", 5),
|
||||||
new Ability(Abilities.LIGHT_METAL, "Light Metal (N)", "Halves the POKéMON's weight.", 5),
|
new Ability(Abilities.CURSED_BODY, "Cursed Body (N)", "May disable a move used on the POKéMON.", 5),
|
||||||
new Ability(Abilities.MAGIC_BOUNCE, "Magic Bounce (N)", "Reflects status- changing moves.", 5),
|
new Ability(Abilities.DEFEATIST, "Defeatist (N)", "Lowers stats when HP drops below half.", 5),
|
||||||
new Ability(Abilities.MOODY, "Moody (N)", "Raises one stat and lowers another.", 5),
|
new Ability(Abilities.DEFIANT, "Defiant (N)", "Sharply raises ATTACK when the POKéMON's stats are lowered.", 5),
|
||||||
new Ability(Abilities.MOXIE, "Moxie (N)", "Boosts ATTACK after knocking out any POKéMON.", 5),
|
new Ability(Abilities.FLARE_BOOST, "Flare Boost (N)", "Powers up special attacks when burned.", 5),
|
||||||
new Ability(Abilities.MULTISCALE, "Multiscale (N)", "Reduces damage when HP is full.", 5),
|
new Ability(Abilities.FRIEND_GUARD, "Friend Guard (N)", "Reduces damage done to allies.", 5),
|
||||||
new Ability(Abilities.MUMMY, "Mummy (N)", "Contact with this POKéMON spreads this Ability.", 5),
|
new Ability(Abilities.HARVEST, "Harvest (N)", "May create another Berry after one is used.", 5),
|
||||||
new Ability(Abilities.OVERCOAT, "Overcoat (N)", "Protects the POKéMON from weather damage.", 5),
|
new Ability(Abilities.HEALER, "Healer (N)", "May heal an ally's status conditions.", 5),
|
||||||
new Ability(Abilities.PICKPOCKET, "Pickpocket (N)", "Steals an item when hit by another POKéMON.", 5),
|
new Ability(Abilities.HEAVY_METAL, "Heavy Metal (N)", "Doubles the POKéMON's weight.", 5),
|
||||||
new Ability(Abilities.POISON_TOUCH, "Poison Touch (N)", "May poison targets when a POKéMON makes contact.", 5),
|
new Ability(Abilities.ILLUSION, "Illusion (N)", "Enters battle disguised as the last POKéMON in the party.", 5),
|
||||||
new Ability(Abilities.PRANKSTER, "Prankster (N)", "Gives priority to a status move.", 5),
|
new Ability(Abilities.IMPOSTER, "Imposter (N)", "It transforms itself into the POKéMON it is facing.", 5),
|
||||||
new Ability(Abilities.RATTLED, "Rattled (N)", "BUG, GHOST or DARK type moves scare it and boost its SPEED.", 5),
|
new Ability(Abilities.INFILTRATOR, "Infiltrator (N)", "Passes through the foe's barrier and strikes.", 5),
|
||||||
new Ability(Abilities.REGENERATOR, "Regenerator (N)", "Restores a little HP when withdrawn from battle.", 5),
|
new Ability(Abilities.IRON_BARBS, "Iron Barbs (N)", "Inflicts damage to the POKéMON on contact.", 5),
|
||||||
new Ability(Abilities.SAND_FORCE, "Sand Force (N)", "Boosts certain moves' power in a sandstorm.", 5),
|
new Ability(Abilities.JUSTIFIED, "Justified (N)", "Raises ATTACK when hit by a DARK-type move.", 5),
|
||||||
new Ability(Abilities.SAND_RUSH, "Sand Rush (N)", "Boosts the POKéMON's SPEED in a sandstorm.", 5),
|
new Ability(Abilities.LIGHT_METAL, "Light Metal (N)", "Halves the POKéMON's weight.", 5),
|
||||||
new Ability(Abilities.SAP_SIPPER, "Sap Sipper (N)", "Boosts ATTACK when hit by a GRASS-type move.", 5),
|
new Ability(Abilities.MAGIC_BOUNCE, "Magic Bounce (N)", "Reflects status- changing moves.", 5),
|
||||||
new Ability(Abilities.SHEER_FORCE, "Sheer Force (N)", "Removes added effects to increase move damage.", 5),
|
new Ability(Abilities.MOODY, "Moody (N)", "Raises one stat and lowers another.", 5),
|
||||||
new Ability(Abilities.TELEPATHY, "Telepathy (N)", "Anticipates an ally's ATTACK and dodges it.", 5),
|
new Ability(Abilities.MOXIE, "Moxie (N)", "Boosts ATTACK after knocking out any POKéMON.", 5),
|
||||||
new Ability(Abilities.TERAVOLT, "Teravolt (N)", "Moves can be used regardless of Abilities.", 5),
|
new Ability(Abilities.MULTISCALE, "Multiscale (N)", "Reduces damage when HP is full.", 5),
|
||||||
new Ability(Abilities.TOXIC_BOOST, "Toxic Boost (N)", "Powers up physical attacks when poisoned.", 5),
|
new Ability(Abilities.MUMMY, "Mummy (N)", "Contact with this POKéMON spreads this Ability.", 5),
|
||||||
new Ability(Abilities.TURBOBLAZE, "Turboblaze (N)", "Moves can be used regardless of Abilities.", 5),
|
new Ability(Abilities.OVERCOAT, "Overcoat", "Protects the POKéMON from weather damage.", 5)
|
||||||
new Ability(Abilities.UNNERVE, "Unnerve (N)", "Makes the foe nervous and unable to eat Berries.", 5),
|
.attr(BlockWeatherDamageAttr),
|
||||||
new Ability(Abilities.VICTORY_STAR, "Victory Star (N)", "Boosts the accuracy of its allies and itself.", 5),
|
new Ability(Abilities.PICKPOCKET, "Pickpocket (N)", "Once per battle, steals an item when hit by another POKéMON.", 5),
|
||||||
new Ability(Abilities.WEAK_ARMOR, "Weak Armor (N)", "Physical attacks lower DEFENSE and raise SPEED.", 5),
|
new Ability(Abilities.POISON_TOUCH, "Poison Touch (N)", "May poison targets when a POKéMON makes contact.", 5),
|
||||||
new Ability(Abilities.WONDER_SKIN, "Wonder Skin (N)", "Makes status-changing moves more likely to miss.", 5),
|
new Ability(Abilities.PRANKSTER, "Prankster (N)", "Gives priority to a status move.", 5),
|
||||||
new Ability(Abilities.ZEN_MODE, "Zen Mode (N)", "Changes form when HP drops below half.", 5),
|
new Ability(Abilities.RATTLED, "Rattled (N)", "BUG, GHOST or DARK type moves scare it and boost its SPEED.", 5),
|
||||||
new Ability(Abilities.COMPETITIVE, "Competitive (N)", "Sharply raises SP. ATK when the POKéMON's stats are lowered.", 6),
|
new Ability(Abilities.REGENERATOR, "Regenerator (N)", "Restores a little HP when withdrawn from battle.", 5),
|
||||||
new Ability(Abilities.DARK_AURA, "Dark Aura (N)", "Raises power of DARK type moves for all POKéMON in battle.", 6),
|
new Ability(Abilities.SAND_FORCE, "Sand Force (N)", "Boosts certain moves' power in a sandstorm.", 5),
|
||||||
new Ability(Abilities.FAIRY_AURA, "Fairy Aura (N)", "Raises power of FAIRY type moves for all POKéMON in battle.", 6),
|
new Ability(Abilities.SAND_RUSH, "Sand Rush (N)", "Boosts the POKéMON's SPEED in a sandstorm.", 5),
|
||||||
new Ability(Abilities.PROTEAN, "Protean (N)", "Changes the POKéMON's type to its last used move.", 6),
|
new Ability(Abilities.SAP_SIPPER, "Sap Sipper (N)", "Boosts ATTACK when hit by a GRASS-type move.", 5),
|
||||||
new Ability(Abilities.SLUSH_RUSH, "Slush Rush (N)", "Boosts the POKéMON's SPEED stat in a hailstorm.", 7),
|
new Ability(Abilities.SHEER_FORCE, "Sheer Force (N)", "Removes added effects to increase move damage.", 5),
|
||||||
new Ability(Abilities.NEUTRALIZING_GAS, "Neutralizing Gas (N)", "Neutralizes abilities of all POKéMON in battle.", 8)
|
new Ability(Abilities.TELEPATHY, "Telepathy (N)", "Anticipates an ally's ATTACK and dodges it.", 5),
|
||||||
];
|
new Ability(Abilities.TERAVOLT, "Teravolt (N)", "Moves can be used regardless of Abilities.", 5),
|
||||||
|
new Ability(Abilities.TOXIC_BOOST, "Toxic Boost (N)", "Powers up physical attacks when poisoned.", 5),
|
||||||
|
new Ability(Abilities.TURBOBLAZE, "Turboblaze (N)", "Moves can be used regardless of Abilities.", 5),
|
||||||
|
new Ability(Abilities.UNNERVE, "Unnerve (N)", "Makes the foe nervous and unable to eat Berries.", 5),
|
||||||
|
new Ability(Abilities.VICTORY_STAR, "Victory Star (N)", "Boosts the accuracy of its allies and itself.", 5),
|
||||||
|
new Ability(Abilities.WEAK_ARMOR, "Weak Armor (N)", "Physical attacks lower DEFENSE and raise SPEED.", 5),
|
||||||
|
new Ability(Abilities.WONDER_SKIN, "Wonder Skin (N)", "Makes status-changing moves more likely to miss.", 5),
|
||||||
|
new Ability(Abilities.ZEN_MODE, "Zen Mode (N)", "Changes form when HP drops below half.", 5),
|
||||||
|
new Ability(Abilities.COMPETITIVE, "Competitive (N)", "Sharply raises SP. ATK when the POKéMON's stats are lowered.", 6),
|
||||||
|
new Ability(Abilities.DARK_AURA, "Dark Aura (N)", "Raises power of DARK type moves for all POKéMON in battle.", 6),
|
||||||
|
new Ability(Abilities.FAIRY_AURA, "Fairy Aura (N)", "Raises power of FAIRY type moves for all POKéMON in battle.", 6),
|
||||||
|
new Ability(Abilities.PROTEAN, "Protean (N)", "Changes the POKéMON's type to its last used move.", 6),
|
||||||
|
new Ability(Abilities.SLUSH_RUSH, "Slush Rush (N)", "Boosts the POKéMON's SPEED stat in a hailstorm.", 7),
|
||||||
|
new Ability(Abilities.NEUTRALIZING_GAS, "Neutralizing Gas (N)", "Neutralizes abilities of all POKéMON in battle.", 8)
|
||||||
|
);
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ export enum BattlerTagType {
|
||||||
FLYING,
|
FLYING,
|
||||||
UNDERGROUND,
|
UNDERGROUND,
|
||||||
HIDDEN,
|
HIDDEN,
|
||||||
|
FIRE_BOOST,
|
||||||
CRIT_BOOST,
|
CRIT_BOOST,
|
||||||
NO_CRIT,
|
NO_CRIT,
|
||||||
BYPASS_SLEEP,
|
BYPASS_SLEEP,
|
||||||
|
@ -464,6 +465,20 @@ export class HideSpriteTag extends BattlerTag {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class TypeBoostTag extends BattlerTag {
|
||||||
|
public boostedType: Type;
|
||||||
|
|
||||||
|
constructor(tagType: BattlerTagType, sourceMove: Moves, boostedType: Type) {
|
||||||
|
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
|
||||||
|
|
||||||
|
this.boostedType = boostedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
|
return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class CritBoostTag extends BattlerTag {
|
export class CritBoostTag extends BattlerTag {
|
||||||
constructor(tagType: BattlerTagType, sourceMove: Moves) {
|
constructor(tagType: BattlerTagType, sourceMove: Moves) {
|
||||||
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
|
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
|
||||||
|
@ -526,6 +541,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
|
||||||
case BattlerTagType.UNDERGROUND:
|
case BattlerTagType.UNDERGROUND:
|
||||||
case BattlerTagType.HIDDEN:
|
case BattlerTagType.HIDDEN:
|
||||||
return new HideSpriteTag(tagType, turnCount, sourceMove);
|
return new HideSpriteTag(tagType, turnCount, sourceMove);
|
||||||
|
case BattlerTagType.FIRE_BOOST:
|
||||||
|
return new TypeBoostTag(tagType, sourceMove, Type.FIRE);
|
||||||
case BattlerTagType.CRIT_BOOST:
|
case BattlerTagType.CRIT_BOOST:
|
||||||
return new CritBoostTag(tagType, sourceMove);
|
return new CritBoostTag(tagType, sourceMove);
|
||||||
case BattlerTagType.NO_CRIT:
|
case BattlerTagType.NO_CRIT:
|
||||||
|
|
2190
src/data/move.ts
2190
src/data/move.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,8 @@ import Pokemon from "../pokemon";
|
||||||
import { Type } from "./type";
|
import { Type } from "./type";
|
||||||
import Move, { AttackMove } from "./move";
|
import Move, { AttackMove } from "./move";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
|
import BattleScene from "../battle-scene";
|
||||||
|
import { SuppressWeatherEffectAbAttr, applyPreWeatherEffectAbAttrs } from "./ability";
|
||||||
|
|
||||||
export enum WeatherType {
|
export enum WeatherType {
|
||||||
NONE,
|
NONE,
|
||||||
|
@ -96,6 +98,21 @@ export class Weather {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isEffectSuppressed(scene: BattleScene): boolean {
|
||||||
|
const playerPokemon = scene.getPlayerPokemon();
|
||||||
|
const enemyPokemon = scene.getEnemyPokemon();
|
||||||
|
|
||||||
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
|
|
||||||
|
if (playerPokemon)
|
||||||
|
applyPreWeatherEffectAbAttrs(SuppressWeatherEffectAbAttr, playerPokemon, this, cancelled, true);
|
||||||
|
|
||||||
|
if (enemyPokemon)
|
||||||
|
applyPreWeatherEffectAbAttrs(SuppressWeatherEffectAbAttr, enemyPokemon, this, cancelled, true);
|
||||||
|
|
||||||
|
return cancelled.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getWeatherStartMessage(weatherType: WeatherType) {
|
export function getWeatherStartMessage(weatherType: WeatherType) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Phaser from 'phaser';
|
import Phaser from 'phaser';
|
||||||
import BattleScene from './battle-scene';
|
import BattleScene from './battle-scene';
|
||||||
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from './ui/battle-info';
|
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from './ui/battle-info';
|
||||||
import Move, { StatChangeAttr, HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariablePowerAttr, Moves, allMoves, MoveCategory } from "./data/move";
|
import Move, { StatChangeAttr, HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariablePowerAttr, Moves, allMoves, MoveCategory, TypelessAttr } from "./data/move";
|
||||||
import { pokemonLevelMoves } from './data/pokemon-level-moves';
|
import { pokemonLevelMoves } from './data/pokemon-level-moves';
|
||||||
import { default as PokemonSpecies, PokemonSpeciesForm, getPokemonSpecies } from './data/pokemon-species';
|
import { default as PokemonSpecies, PokemonSpeciesForm, getPokemonSpecies } from './data/pokemon-species';
|
||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
|
@ -17,13 +17,13 @@ import { tmSpecies } from './data/tms';
|
||||||
import { pokemonEvolutions, pokemonPrevolutions, SpeciesEvolution, SpeciesEvolutionCondition } from './data/pokemon-evolutions';
|
import { pokemonEvolutions, pokemonPrevolutions, SpeciesEvolution, SpeciesEvolutionCondition } from './data/pokemon-evolutions';
|
||||||
import { DamagePhase, FaintPhase } from './battle-phases';
|
import { DamagePhase, FaintPhase } from './battle-phases';
|
||||||
import { BattleStat } from './data/battle-stat';
|
import { BattleStat } from './data/battle-stat';
|
||||||
import { BattlerTag, BattlerTagLapseType, BattlerTagType, getBattlerTag } from './data/battler-tag';
|
import { BattlerTag, BattlerTagLapseType, BattlerTagType, TypeBoostTag, getBattlerTag } from './data/battler-tag';
|
||||||
import { Species } from './data/species';
|
import { Species } from './data/species';
|
||||||
import { WeatherType } from './data/weather';
|
import { WeatherType } from './data/weather';
|
||||||
import { TempBattleStat } from './data/temp-battle-stat';
|
import { TempBattleStat } from './data/temp-battle-stat';
|
||||||
import { WeakenMoveTypeTag } from './data/arena-tag';
|
import { WeakenMoveTypeTag } from './data/arena-tag';
|
||||||
import { Biome } from './data/biome';
|
import { Biome } from './data/biome';
|
||||||
import { Abilities, Ability, TypeImmunityAttr, abilities, applyPreDefendAbilityAttrs } from './data/ability';
|
import { Abilities, Ability, TypeImmunityAbAttr, VariableMovePowerAbAttr, abilities, applyPreAttackAbAttrs, applyPreDefendAbAttrs } from './data/ability';
|
||||||
|
|
||||||
export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
public id: integer;
|
public id: integer;
|
||||||
|
@ -350,6 +350,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
return abilities[this.species.getAbility(this.abilityIndex)];
|
return abilities[this.species.getAbility(this.abilityIndex)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canApplyAbility(): boolean {
|
||||||
|
return !this.getAbility().conditions.find(condition => !condition(this));
|
||||||
|
}
|
||||||
|
|
||||||
getAttackMoveEffectiveness(moveType: Type): TypeDamageMultiplier {
|
getAttackMoveEffectiveness(moveType: Type): TypeDamageMultiplier {
|
||||||
const types = this.getTypes();
|
const types = this.getTypes();
|
||||||
return getTypeDamageMultiplier(moveType, types[0]) * (types.length ? getTypeDamageMultiplier(moveType, types[1]) : 1) as TypeDamageMultiplier;
|
return getTypeDamageMultiplier(moveType, types[0]) * (types.length ? getTypeDamageMultiplier(moveType, types[1]) : 1) as TypeDamageMultiplier;
|
||||||
|
@ -423,6 +427,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
console.log(allMoves[movePool[moveIndex]]);
|
console.log(allMoves[movePool[moveIndex]]);
|
||||||
movePool.splice(moveIndex, 1);
|
movePool.splice(moveIndex, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.isPlayer())
|
||||||
|
this.moveset[1].moveId = Moves.TAKE_DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
trySelectMove(moveIndex: integer): boolean {
|
trySelectMove(moveIndex: integer): boolean {
|
||||||
|
@ -484,18 +491,28 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
case MoveCategory.PHYSICAL:
|
case MoveCategory.PHYSICAL:
|
||||||
case MoveCategory.SPECIAL:
|
case MoveCategory.SPECIAL:
|
||||||
const isPhysical = moveCategory === MoveCategory.PHYSICAL;
|
const isPhysical = moveCategory === MoveCategory.PHYSICAL;
|
||||||
|
const typeless = move.getAttrs(TypelessAttr).length
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
const power = new Utils.NumberHolder(move.power);
|
const power = new Utils.NumberHolder(move.power);
|
||||||
const typeMultiplier = new Utils.NumberHolder(getTypeDamageMultiplier(move.type, this.getSpeciesForm().type1) * (this.getSpeciesForm().type2 !== null ? getTypeDamageMultiplier(move.type, this.getSpeciesForm().type2) : 1));
|
const typeMultiplier = new Utils.NumberHolder(!typeless
|
||||||
const weatherTypeMultiplier = this.scene.arena.getAttackTypeMultiplier(move.type);
|
? getTypeDamageMultiplier(move.type, this.getSpeciesForm().type1) * (this.getSpeciesForm().type2 !== null ? getTypeDamageMultiplier(move.type, this.getSpeciesForm().type2) : 1)
|
||||||
applyPreDefendAbilityAttrs(TypeImmunityAttr, this, source, battlerMove, cancelled, typeMultiplier);
|
: 1);
|
||||||
|
if (typeless)
|
||||||
|
typeMultiplier.value = 1;
|
||||||
|
applyPreAttackAbAttrs(VariableMovePowerAbAttr, source, this, battlerMove, power)
|
||||||
|
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, battlerMove, cancelled, typeMultiplier);
|
||||||
|
|
||||||
if (cancelled.value)
|
if (cancelled.value)
|
||||||
result = MoveResult.NO_EFFECT;
|
result = MoveResult.NO_EFFECT;
|
||||||
else {
|
else {
|
||||||
|
if (source.findTag(t => t instanceof TypeBoostTag && (t as TypeBoostTag).boostedType === move.type))
|
||||||
|
power.value *= 1.5;
|
||||||
|
const weatherTypeMultiplier = this.scene.arena.getAttackTypeMultiplier(move.type);
|
||||||
applyMoveAttrs(VariablePowerAttr, source, this, move, power);
|
applyMoveAttrs(VariablePowerAttr, source, this, move, power);
|
||||||
this.scene.arena.applyTags(WeakenMoveTypeTag, move.type, power);
|
if (!typeless) {
|
||||||
this.scene.applyModifiers(AttackTypeBoosterModifier, source.isPlayer(), source, power);
|
this.scene.arena.applyTags(WeakenMoveTypeTag, move.type, power);
|
||||||
|
this.scene.applyModifiers(AttackTypeBoosterModifier, source.isPlayer(), source, power);
|
||||||
|
}
|
||||||
const critLevel = new Utils.IntegerHolder(0);
|
const critLevel = new Utils.IntegerHolder(0);
|
||||||
applyMoveAttrs(HighCritAttr, source, this, move, critLevel);
|
applyMoveAttrs(HighCritAttr, source, this, move, critLevel);
|
||||||
this.scene.applyModifiers(TempBattleStatBoosterModifier, source.isPlayer(), TempBattleStat.CRIT, critLevel);
|
this.scene.applyModifiers(TempBattleStatBoosterModifier, source.isPlayer(), TempBattleStat.CRIT, critLevel);
|
||||||
|
|
|
@ -2,6 +2,9 @@ import BattleScene from "../battle-scene";
|
||||||
import Pokemon from "../pokemon";
|
import Pokemon from "../pokemon";
|
||||||
import { TextStyle, addTextObject } from "./text";
|
import { TextStyle, addTextObject } from "./text";
|
||||||
|
|
||||||
|
const hiddenX = -91;
|
||||||
|
const shownX = 10;
|
||||||
|
|
||||||
export default class AbilityBar extends Phaser.GameObjects.Container {
|
export default class AbilityBar extends Phaser.GameObjects.Container {
|
||||||
private bg: Phaser.GameObjects.Image;
|
private bg: Phaser.GameObjects.Image;
|
||||||
private pokemonNameText: Phaser.GameObjects.Text;
|
private pokemonNameText: Phaser.GameObjects.Text;
|
||||||
|
@ -12,7 +15,7 @@ export default class AbilityBar extends Phaser.GameObjects.Container {
|
||||||
public shown: boolean;
|
public shown: boolean;
|
||||||
|
|
||||||
constructor(scene: BattleScene) {
|
constructor(scene: BattleScene) {
|
||||||
super(scene, -91, (-scene.game.canvas.height / 6) + 64);
|
super(scene, hiddenX, (-scene.game.canvas.height / 6) + 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup(): void {
|
setup(): void {
|
||||||
|
@ -21,11 +24,11 @@ export default class AbilityBar extends Phaser.GameObjects.Container {
|
||||||
|
|
||||||
this.add(this.bg);
|
this.add(this.bg);
|
||||||
|
|
||||||
this.pokemonNameText = addTextObject(this.scene, 5, 3, 'Pokemon', TextStyle.MESSAGE, { fontSize: '72px' });
|
this.pokemonNameText = addTextObject(this.scene, 5, 3, '', TextStyle.MESSAGE, { fontSize: '72px' });
|
||||||
this.pokemonNameText.setOrigin(0, 0);
|
this.pokemonNameText.setOrigin(0, 0);
|
||||||
this.add(this.pokemonNameText);
|
this.add(this.pokemonNameText);
|
||||||
|
|
||||||
this.abilityNameText = addTextObject(this.scene, 87, 16, 'Chlorophyll', TextStyle.WINDOW, { fontSize: '72px' });
|
this.abilityNameText = addTextObject(this.scene, 87, 16, '', TextStyle.WINDOW, { fontSize: '72px' });
|
||||||
this.abilityNameText.setOrigin(1, 0);
|
this.abilityNameText.setOrigin(1, 0);
|
||||||
this.add(this.abilityNameText);
|
this.add(this.abilityNameText);
|
||||||
|
|
||||||
|
@ -33,16 +36,19 @@ export default class AbilityBar extends Phaser.GameObjects.Container {
|
||||||
this.shown = false;
|
this.shown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
showAbility(pokemon: Pokemon) {
|
showAbility(pokemon: Pokemon): void {
|
||||||
this.pokemonNameText.setText(`${pokemon.name}'s`);
|
this.pokemonNameText.setText(`${pokemon.name}'s`);
|
||||||
this.abilityNameText.setText(pokemon.getAbility().name);
|
this.abilityNameText.setText(pokemon.getAbility().name);
|
||||||
|
|
||||||
|
if (this.shown)
|
||||||
|
return;
|
||||||
|
|
||||||
if (this.tween)
|
if (this.tween)
|
||||||
this.tween.stop();
|
this.tween.stop();
|
||||||
|
|
||||||
this.tween = this.scene.tweens.add({
|
this.tween = this.scene.tweens.add({
|
||||||
targets: this,
|
targets: this,
|
||||||
x: 10,
|
x: shownX,
|
||||||
duration: 500,
|
duration: 500,
|
||||||
ease: 'Sine.easeOut',
|
ease: 'Sine.easeOut',
|
||||||
onComplete: () => this.tween = null
|
onComplete: () => this.tween = null
|
||||||
|
@ -52,7 +58,10 @@ export default class AbilityBar extends Phaser.GameObjects.Container {
|
||||||
this.shown = true;
|
this.shown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide(): void {
|
||||||
|
if (!this.shown)
|
||||||
|
return;
|
||||||
|
|
||||||
if (this.tween)
|
if (this.tween)
|
||||||
this.tween.stop();
|
this.tween.stop();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue