Merge branch 'main' of github.com:pagefaultgames/pokerogue into qol/setting_party_exp
@ -44,6 +44,7 @@ Check out our [Trello Board](https://trello.com/b/z10B703R/pokerogue-board) to s
|
|||||||
- Arata Iiyoshi
|
- Arata Iiyoshi
|
||||||
- Atsuhiro Ishizuna
|
- Atsuhiro Ishizuna
|
||||||
- Pokémon Black/White 2
|
- Pokémon Black/White 2
|
||||||
|
- Firel (Additional biome themes)
|
||||||
- edifette (Title screen music)
|
- edifette (Title screen music)
|
||||||
|
|
||||||
### 🎵 Sound Effects
|
### 🎵 Sound Effects
|
||||||
|
BIN
public/images/arenas/island_a.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
public/images/arenas/island_b.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
public/images/arenas/island_b_1.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
public/images/arenas/island_b_2.png
Normal file
After Width: | Height: | Size: 910 B |
BIN
public/images/arenas/island_b_3.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
public/images/arenas/island_bg.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
public/images/arenas/jungle_a.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
public/images/arenas/jungle_b.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
public/images/arenas/jungle_b_1.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
public/images/arenas/jungle_b_2.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
public/images/arenas/jungle_b_3.png
Normal file
After Width: | Height: | Size: 1022 B |
BIN
public/images/arenas/jungle_bg.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 931 B |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 821 B |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 752 B |
Before Width: | Height: | Size: 776 B After Width: | Height: | Size: 4.7 KiB |
BIN
public/images/arenas/metropolis_a.png
Normal file
After Width: | Height: | Size: 750 B |
BIN
public/images/arenas/metropolis_b.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
public/images/arenas/metropolis_b_1.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
public/images/arenas/metropolis_b_2.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
public/images/arenas/metropolis_b_3.png
Normal file
After Width: | Height: | Size: 885 B |
BIN
public/images/arenas/metropolis_bg.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 2.1 KiB |
BIN
public/images/arenas/snowy_forest_b_1.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
public/images/arenas/snowy_forest_b_2.png
Normal file
After Width: | Height: | Size: 921 B |
BIN
public/images/arenas/snowy_forest_b_3.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 781 B After Width: | Height: | Size: 4.7 KiB |
10817
public/images/items.json
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 50 KiB |
BIN
public/images/items/bronze_ribbon.png
Normal file
After Width: | Height: | Size: 400 B |
BIN
public/images/items/great_ribbon.png
Normal file
After Width: | Height: | Size: 408 B |
BIN
public/images/items/master_ribbon.png
Normal file
After Width: | Height: | Size: 408 B |
BIN
public/images/items/rogue_ribbon.png
Normal file
After Width: | Height: | Size: 407 B |
BIN
public/images/items/ultra_ribbon.png
Normal file
After Width: | Height: | Size: 406 B |
BIN
public/images/ui/champion_ribbon.png
Normal file
After Width: | Height: | Size: 285 B |
BIN
public/images/ui/legacy/champion_ribbon.png
Normal file
After Width: | Height: | Size: 285 B |
55
public/update-source-comments.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
filenames = [['src/data/enums/moves.ts', 'move'], ['src/data/enums/abilities.ts', 'ability'], ['src/data/enums/species.ts', 'Pokémon']]
|
||||||
|
|
||||||
|
commentBlockStart = re.compile('\/\*[^\*].*') # Regex for the start of a comment block
|
||||||
|
commentBlockEnd = re.compile('.*,\*\/') # Regex for the end of a comment block
|
||||||
|
|
||||||
|
commentExp = re.compile('(?:\/\*\*.*\*\/)') # Regex for a url comment that already existed in the file
|
||||||
|
enumExp = re.compile('.*,') # Regex for a regular enum line
|
||||||
|
|
||||||
|
numberExp = re.compile(' +\= +\d+,')
|
||||||
|
|
||||||
|
replaceList = ['ALOLA', 'ETERNAL', 'GALAR', 'HISUI', 'PALDEA', 'BLOODMOON']
|
||||||
|
|
||||||
|
for args in filenames:
|
||||||
|
|
||||||
|
output = ''
|
||||||
|
|
||||||
|
skip = False # True when we should completely stop adding url comments for any reason
|
||||||
|
blockComment = False # True when currently reading a comment block
|
||||||
|
|
||||||
|
file = open(args[0], 'r')
|
||||||
|
line = file.readline()
|
||||||
|
|
||||||
|
while line:
|
||||||
|
if(skip): # Appends the next line in the file and moves on if we already hit the end of the enum
|
||||||
|
output += line
|
||||||
|
line = file.readline()
|
||||||
|
continue
|
||||||
|
|
||||||
|
skip = line.find('};') != -1 # True if we reached the end of an enum definition
|
||||||
|
|
||||||
|
# Determines when a comment block has started and we should stop adding url comments
|
||||||
|
if (commentBlockStart.findall(line)):
|
||||||
|
blockComment = True
|
||||||
|
|
||||||
|
if(not commentExp.findall(line)):
|
||||||
|
urlInsert = numberExp.sub('', line).strip().rstrip('\n').rstrip(',').title() # Clean up the enum line to only the enum
|
||||||
|
for replace in replaceList:
|
||||||
|
urlInsert = urlInsert.replace(replace.title() + '_', '')
|
||||||
|
if (not blockComment and enumExp.findall(line)):
|
||||||
|
output += ' /**{@link https://bulbapedia.bulbagarden.net/wiki/' + urlInsert + '_(' + args[1] + ') | Source} */\n'
|
||||||
|
output += line # Add the line to output since it isn't an existing url comment
|
||||||
|
|
||||||
|
# Determines if we're at the end of a comment block and can resume adding url comments
|
||||||
|
if (blockComment):
|
||||||
|
blockComment = not commentBlockEnd.findall(line)
|
||||||
|
|
||||||
|
line = file.readline()
|
||||||
|
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
file = open(args[0], 'w', encoding='utf-8')
|
||||||
|
file.write(output,)
|
||||||
|
file.close
|
@ -4,7 +4,7 @@ import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePh
|
|||||||
import Pokemon, { PlayerPokemon, EnemyPokemon } from './field/pokemon';
|
import Pokemon, { PlayerPokemon, EnemyPokemon } from './field/pokemon';
|
||||||
import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies, speciesStarters } from './data/pokemon-species';
|
import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies, speciesStarters } from './data/pokemon-species';
|
||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier } from './modifier/modifier';
|
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier, overrideModifiers, overrideHeldItems } from './modifier/modifier';
|
||||||
import { PokeballType } from './data/pokeball';
|
import { PokeballType } from './data/pokeball';
|
||||||
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from './data/battle-anims';
|
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from './data/battle-anims';
|
||||||
import { Phase } from './phase';
|
import { Phase } from './phase';
|
||||||
@ -59,7 +59,7 @@ import { SceneBase } from './scene-base';
|
|||||||
import CandyBar from './ui/candy-bar';
|
import CandyBar from './ui/candy-bar';
|
||||||
import { Variant, variantData } from './data/variant';
|
import { Variant, variantData } from './data/variant';
|
||||||
import { Localizable } from './plugins/i18n';
|
import { Localizable } from './plugins/i18n';
|
||||||
import { STARTING_WAVE_OVERRIDE, OPP_SPECIES_OVERRIDE, SEED_OVERRIDE, STARTING_BIOME_OVERRIDE } from './overrides';
|
import * as Overrides from './overrides';
|
||||||
import {InputsController} from "./inputs-controller";
|
import {InputsController} from "./inputs-controller";
|
||||||
import {UiInputs} from "./ui-inputs";
|
import {UiInputs} from "./ui-inputs";
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
|||||||
|
|
||||||
const DEBUG_RNG = false;
|
const DEBUG_RNG = false;
|
||||||
|
|
||||||
export const startingWave = STARTING_WAVE_OVERRIDE || 1;
|
export const startingWave = Overrides.STARTING_WAVE_OVERRIDE || 1;
|
||||||
|
|
||||||
const expSpriteKeys: string[] = [];
|
const expSpriteKeys: string[] = [];
|
||||||
|
|
||||||
@ -625,9 +625,11 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addEnemyPokemon(species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean = false, dataSource?: PokemonData, postProcess?: (enemyPokemon: EnemyPokemon) => void): EnemyPokemon {
|
addEnemyPokemon(species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean = false, dataSource?: PokemonData, postProcess?: (enemyPokemon: EnemyPokemon) => void): EnemyPokemon {
|
||||||
if (OPP_SPECIES_OVERRIDE)
|
if (Overrides.OPP_SPECIES_OVERRIDE)
|
||||||
species = getPokemonSpecies(OPP_SPECIES_OVERRIDE);
|
species = getPokemonSpecies(Overrides.OPP_SPECIES_OVERRIDE);
|
||||||
const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource);
|
const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource);
|
||||||
|
overrideModifiers(this, false);
|
||||||
|
overrideHeldItems(this, pokemon, false);
|
||||||
if (boss && !dataSource) {
|
if (boss && !dataSource) {
|
||||||
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295));
|
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295));
|
||||||
|
|
||||||
@ -718,7 +720,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
|
|
||||||
this.gameMode = gameModes[GameModes.CLASSIC];
|
this.gameMode = gameModes[GameModes.CLASSIC];
|
||||||
|
|
||||||
this.setSeed(SEED_OVERRIDE || Utils.randomString(24));
|
this.setSeed(Overrides.SEED_OVERRIDE || Utils.randomString(24));
|
||||||
console.log('Seed:', this.seed);
|
console.log('Seed:', this.seed);
|
||||||
|
|
||||||
this.disableMenu = false;
|
this.disableMenu = false;
|
||||||
@ -755,7 +757,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
|
|
||||||
[ this.luckLabelText, this.luckText ].map(t => t.setVisible(false));
|
[ this.luckLabelText, this.luckText ].map(t => t.setVisible(false));
|
||||||
|
|
||||||
this.newArena(STARTING_BIOME_OVERRIDE || Biome.TOWN);
|
this.newArena(Overrides.STARTING_BIOME_OVERRIDE || Biome.TOWN);
|
||||||
|
|
||||||
this.arenaBgTransition.setPosition(0, 0);
|
this.arenaBgTransition.setPosition(0, 0);
|
||||||
this.arenaPlayer.setPosition(300, 0);
|
this.arenaPlayer.setPosition(300, 0);
|
||||||
@ -855,6 +857,9 @@ export default class BattleScene extends SceneBase {
|
|||||||
} else if (!battleConfig)
|
} else if (!battleConfig)
|
||||||
newDouble = !!double;
|
newDouble = !!double;
|
||||||
|
|
||||||
|
if (Overrides.DOUBLE_BATTLE_OVERRIDE)
|
||||||
|
newDouble = true;
|
||||||
|
|
||||||
const lastBattle = this.currentBattle;
|
const lastBattle = this.currentBattle;
|
||||||
|
|
||||||
if (lastBattle?.double && !newDouble)
|
if (lastBattle?.double && !newDouble)
|
||||||
@ -1777,6 +1782,19 @@ export default class BattleScene extends SceneBase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all modifiers from enemy of PersistentModifier type
|
||||||
|
*/
|
||||||
|
clearEnemyModifiers(): void {
|
||||||
|
const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PersistentModifier);
|
||||||
|
for (let m of modifiersToRemove)
|
||||||
|
this.enemyModifiers.splice(this.enemyModifiers.indexOf(m), 1);
|
||||||
|
this.updateModifiers(false).then(() => this.updateUIPositions());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all modifiers from enemy of PokemonHeldItemModifier type
|
||||||
|
*/
|
||||||
clearEnemyHeldItemModifiers(): void {
|
clearEnemyHeldItemModifiers(): void {
|
||||||
const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PokemonHeldItemModifier);
|
const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PokemonHeldItemModifier);
|
||||||
for (let m of modifiersToRemove)
|
for (let m of modifiersToRemove)
|
||||||
|
@ -562,19 +562,28 @@ export class PostDefendStatChangeAbAttr extends PostDefendAbAttr {
|
|||||||
private stat: BattleStat;
|
private stat: BattleStat;
|
||||||
private levels: integer;
|
private levels: integer;
|
||||||
private selfTarget: boolean;
|
private selfTarget: boolean;
|
||||||
|
private allOthers: boolean;
|
||||||
|
|
||||||
constructor(condition: PokemonDefendCondition, stat: BattleStat, levels: integer, selfTarget: boolean = true) {
|
constructor(condition: PokemonDefendCondition, stat: BattleStat, levels: integer, selfTarget: boolean = true, allOthers: boolean = false) {
|
||||||
super(true);
|
super(true);
|
||||||
|
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
this.stat = stat;
|
this.stat = stat;
|
||||||
this.levels = levels;
|
this.levels = levels;
|
||||||
this.selfTarget = selfTarget;
|
this.selfTarget = selfTarget;
|
||||||
|
this.allOthers = allOthers;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move.getMove())) {
|
if (this.condition(pokemon, attacker, move.getMove())) {
|
||||||
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, [ this.stat ], this.levels));
|
if (this.allOthers) {
|
||||||
|
let otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents();
|
||||||
|
for (let other of otherPokemon) {
|
||||||
|
other.scene.unshiftPhase(new StatChangePhase(other.scene, (other).getBattlerIndex(), false, [ this.stat ], this.levels));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), this.selfTarget, [ this.stat ], this.levels));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -851,6 +860,36 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
|
||||||
|
private chance: integer;
|
||||||
|
private attacker: Pokemon;
|
||||||
|
private move: PokemonMove;
|
||||||
|
|
||||||
|
constructor(chance: integer) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.chance = chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||||
|
if (!attacker.summonData.disabledMove) {
|
||||||
|
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !attacker.isMax()) {
|
||||||
|
this.attacker = attacker;
|
||||||
|
this.move = move;
|
||||||
|
|
||||||
|
attacker.summonData.disabledMove = move.moveId;
|
||||||
|
attacker.summonData.disabledTurns = 4;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
||||||
|
return getPokemonMessage(this.attacker, `'s ${this.move.getName()}\nwas disabled!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class PostStatChangeStatChangeAbAttr extends PostStatChangeAbAttr {
|
export class PostStatChangeStatChangeAbAttr extends PostStatChangeAbAttr {
|
||||||
private condition: PokemonStatChangeCondition;
|
private condition: PokemonStatChangeCondition;
|
||||||
private statsToChange: BattleStat[];
|
private statsToChange: BattleStat[];
|
||||||
@ -1826,6 +1865,19 @@ function getAnticipationCondition(): AbAttrCondition {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an ability condition that causes the ability to fail if that ability
|
||||||
|
* has already been used by that pokemon that battle. It requires an ability to
|
||||||
|
* be specified due to current limitations in how conditions on abilities work.
|
||||||
|
* @param {Abilities} ability The ability to check if it's already been applied
|
||||||
|
* @returns {AbAttrCondition} The condition
|
||||||
|
*/
|
||||||
|
function getOncePerBattleCondition(ability: Abilities): AbAttrCondition {
|
||||||
|
return (pokemon: Pokemon) => {
|
||||||
|
return !pokemon.battleData?.abilitiesApplied.includes(ability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class ForewarnAbAttr extends PostSummonAbAttr {
|
export class ForewarnAbAttr extends PostSummonAbAttr {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(true);
|
super(true);
|
||||||
@ -2003,13 +2055,30 @@ export class PostTurnAbAttr extends AbAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After the turn ends, resets the status of either the ability holder or their ally
|
||||||
|
* @param {boolean} allyTarget Whether to target ally, defaults to false (self-target)
|
||||||
|
*/
|
||||||
export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
|
export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
|
||||||
|
private allyTarget: boolean;
|
||||||
|
private target: Pokemon;
|
||||||
|
|
||||||
|
constructor(allyTarget: boolean = false) {
|
||||||
|
super(true);
|
||||||
|
this.allyTarget = allyTarget;
|
||||||
|
}
|
||||||
|
|
||||||
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
|
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
|
||||||
if (pokemon.status) {
|
if (this.allyTarget) {
|
||||||
|
this.target = pokemon.getAlly();
|
||||||
|
} else {
|
||||||
|
this.target = pokemon;
|
||||||
|
}
|
||||||
|
if (this.target?.status) {
|
||||||
|
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status?.effect)));
|
this.target.scene.queueMessage(getPokemonMessage(this.target, getStatusEffectHealText(this.target.status?.effect)));
|
||||||
pokemon.resetStatus();
|
this.target.resetStatus(false);
|
||||||
pokemon.updateInfo();
|
this.target.updateInfo();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2483,11 +2552,11 @@ export class IgnoreTypeImmunityAbAttr extends AbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
if (this.defenderType !== (args[1] as Type)) {
|
if (this.defenderType === (args[1] as Type) && this.allowedMoveTypes.includes(args[0] as Type)) {
|
||||||
return false;
|
cancelled.value = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
return this.allowedMoveTypes.some(type => type === (args[0] as Type));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2522,6 +2591,9 @@ function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any
|
|||||||
return applyNextAbAttr();
|
return applyNextAbAttr();
|
||||||
pokemon.scene.setPhaseQueueSplice();
|
pokemon.scene.setPhaseQueueSplice();
|
||||||
const onApplySuccess = () => {
|
const onApplySuccess = () => {
|
||||||
|
if (pokemon.battleData && !pokemon.battleData.abilitiesApplied.includes(ability.id)) {
|
||||||
|
pokemon.battleData.abilitiesApplied.push(ability.id);
|
||||||
|
}
|
||||||
if (attr.showAbility && !quiet) {
|
if (attr.showAbility && !quiet) {
|
||||||
if (showAbilityInstant)
|
if (showAbilityInstant)
|
||||||
pokemon.scene.abilityBar.showAbility(pokemon, passive);
|
pokemon.scene.abilityBar.showAbility(pokemon, passive);
|
||||||
@ -3019,7 +3091,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.FRISK, 4)
|
new Ability(Abilities.FRISK, 4)
|
||||||
.attr(FriskAbAttr),
|
.attr(FriskAbAttr),
|
||||||
new Ability(Abilities.RECKLESS, 4)
|
new Ability(Abilities.RECKLESS, 4)
|
||||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.getAttrs(RecoilAttr).length && move.id !== Moves.STRUGGLE, 1.2),
|
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.RECKLESS_MOVE), 1.2),
|
||||||
new Ability(Abilities.MULTITYPE, 4)
|
new Ability(Abilities.MULTITYPE, 4)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
@ -3051,9 +3123,10 @@ export function initAbilities() {
|
|||||||
.attr(BattleStatMultiplierAbAttr, BattleStat.SPATK, 0.5)
|
.attr(BattleStatMultiplierAbAttr, BattleStat.SPATK, 0.5)
|
||||||
.condition((pokemon) => pokemon.getHpRatio() <= 0.5),
|
.condition((pokemon) => pokemon.getHpRatio() <= 0.5),
|
||||||
new Ability(Abilities.CURSED_BODY, 5)
|
new Ability(Abilities.CURSED_BODY, 5)
|
||||||
.unimplemented(),
|
.attr(PostDefendMoveDisableAbAttr, 30)
|
||||||
|
.bypassFaint(),
|
||||||
new Ability(Abilities.HEALER, 5)
|
new Ability(Abilities.HEALER, 5)
|
||||||
.unimplemented(),
|
.conditionalAttr(pokemon => pokemon.getAlly() && Utils.randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true),
|
||||||
new Ability(Abilities.FRIEND_GUARD, 5)
|
new Ability(Abilities.FRIEND_GUARD, 5)
|
||||||
.ignorable()
|
.ignorable()
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
@ -3232,7 +3305,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.EMERGENCY_EXIT, 7)
|
new Ability(Abilities.EMERGENCY_EXIT, 7)
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new Ability(Abilities.WATER_COMPACTION, 7)
|
new Ability(Abilities.WATER_COMPACTION, 7)
|
||||||
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.type === Type.WATER, BattleStat.DEF, 2),
|
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.type === Type.WATER && move.category !== MoveCategory.STATUS, BattleStat.DEF, 2),
|
||||||
new Ability(Abilities.MERCILESS, 7)
|
new Ability(Abilities.MERCILESS, 7)
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new Ability(Abilities.SHIELDS_DOWN, 7)
|
new Ability(Abilities.SHIELDS_DOWN, 7)
|
||||||
@ -3379,15 +3452,18 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.NEUROFORCE, 7)
|
new Ability(Abilities.NEUROFORCE, 7)
|
||||||
.attr(MovePowerBoostAbAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 1.25),
|
.attr(MovePowerBoostAbAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 1.25),
|
||||||
new Ability(Abilities.INTREPID_SWORD, 8)
|
new Ability(Abilities.INTREPID_SWORD, 8)
|
||||||
.attr(PostSummonStatChangeAbAttr, BattleStat.ATK, 1, true),
|
.attr(PostSummonStatChangeAbAttr, BattleStat.ATK, 1, true)
|
||||||
|
.condition(getOncePerBattleCondition(Abilities.INTREPID_SWORD)),
|
||||||
new Ability(Abilities.DAUNTLESS_SHIELD, 8)
|
new Ability(Abilities.DAUNTLESS_SHIELD, 8)
|
||||||
.attr(PostSummonStatChangeAbAttr, BattleStat.DEF, 1, true),
|
.attr(PostSummonStatChangeAbAttr, BattleStat.DEF, 1, true)
|
||||||
|
.condition(getOncePerBattleCondition(Abilities.DAUNTLESS_SHIELD)),
|
||||||
new Ability(Abilities.LIBERO, 8)
|
new Ability(Abilities.LIBERO, 8)
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new Ability(Abilities.BALL_FETCH, 8)
|
new Ability(Abilities.BALL_FETCH, 8)
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new Ability(Abilities.COTTON_DOWN, 8)
|
new Ability(Abilities.COTTON_DOWN, 8)
|
||||||
.unimplemented(),
|
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, BattleStat.SPD, -1, false, true)
|
||||||
|
.bypassFaint(),
|
||||||
new Ability(Abilities.PROPELLER_TAIL, 8)
|
new Ability(Abilities.PROPELLER_TAIL, 8)
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new Ability(Abilities.MIRROR_ARMOR, 8)
|
new Ability(Abilities.MIRROR_ARMOR, 8)
|
||||||
@ -3588,9 +3664,11 @@ export function initAbilities() {
|
|||||||
.partial(),
|
.partial(),
|
||||||
new Ability(Abilities.MINDS_EYE, 9)
|
new Ability(Abilities.MINDS_EYE, 9)
|
||||||
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING])
|
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING])
|
||||||
.ignorable(), // TODO: evasiveness bypass should not be ignored, but accuracy immunity should
|
.ignorable() // TODO: evasiveness bypass should not be ignored, but accuracy immunity should
|
||||||
|
.partial(),
|
||||||
new Ability(Abilities.SUPERSWEET_SYRUP, 9)
|
new Ability(Abilities.SUPERSWEET_SYRUP, 9)
|
||||||
.unimplemented(),
|
.attr(PostSummonStatChangeAbAttr, BattleStat.EVA, -1)
|
||||||
|
.condition(getOncePerBattleCondition(Abilities.SUPERSWEET_SYRUP)),
|
||||||
new Ability(Abilities.HOSPITALITY, 9)
|
new Ability(Abilities.HOSPITALITY, 9)
|
||||||
.attr(PostSummonAllyHealAbAttr, 4, true),
|
.attr(PostSummonAllyHealAbAttr, 4, true),
|
||||||
new Ability(Abilities.TOXIC_CHAIN, 9)
|
new Ability(Abilities.TOXIC_CHAIN, 9)
|
||||||
|
@ -68,6 +68,17 @@ export class BattlerTag {
|
|||||||
? allMoves[this.sourceMove].name
|
? allMoves[this.sourceMove].name
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* This is meant to be inherited from by any battler tag with custom attributes
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
this.turnCount = source.turnCount;
|
||||||
|
this.sourceMove = source.sourceMove;
|
||||||
|
this.sourceId = source.sourceId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WeatherBattlerTag {
|
export interface WeatherBattlerTag {
|
||||||
@ -299,6 +310,15 @@ export class SeedTag extends BattlerTag {
|
|||||||
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId);
|
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.sourceIndex = source.sourceIndex;
|
||||||
|
}
|
||||||
|
|
||||||
canAdd(pokemon: Pokemon): boolean {
|
canAdd(pokemon: Pokemon): boolean {
|
||||||
return !pokemon.isOfType(Type.GRASS);
|
return !pokemon.isOfType(Type.GRASS);
|
||||||
}
|
}
|
||||||
@ -404,6 +424,15 @@ export class EncoreTag extends BattlerTag {
|
|||||||
super(BattlerTagType.ENCORE, BattlerTagLapseType.AFTER_MOVE, 3, Moves.ENCORE, sourceId);
|
super(BattlerTagType.ENCORE, BattlerTagLapseType.AFTER_MOVE, 3, Moves.ENCORE, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.moveId = source.moveId as Moves;
|
||||||
|
}
|
||||||
|
|
||||||
canAdd(pokemon: Pokemon): boolean {
|
canAdd(pokemon: Pokemon): boolean {
|
||||||
if (pokemon.isMax())
|
if (pokemon.isMax())
|
||||||
return false;
|
return false;
|
||||||
@ -553,6 +582,15 @@ export abstract class DamagingTrapTag extends TrappedTag {
|
|||||||
this.commonAnim = commonAnim;
|
this.commonAnim = commonAnim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.commonAnim = source.commonAnim as CommonAnim;
|
||||||
|
}
|
||||||
|
|
||||||
canAdd(pokemon: Pokemon): boolean {
|
canAdd(pokemon: Pokemon): boolean {
|
||||||
return !pokemon.isOfType(Type.GHOST) && !pokemon.findTag(t => t instanceof DamagingTrapTag);
|
return !pokemon.isOfType(Type.GHOST) && !pokemon.findTag(t => t instanceof DamagingTrapTag);
|
||||||
}
|
}
|
||||||
@ -709,6 +747,15 @@ export class ContactDamageProtectedTag extends ProtectedTag {
|
|||||||
this.damageRatio = damageRatio;
|
this.damageRatio = damageRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.damageRatio = source.damageRatio;
|
||||||
|
}
|
||||||
|
|
||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
const ret = super.lapse(pokemon, lapseType);
|
const ret = super.lapse(pokemon, lapseType);
|
||||||
|
|
||||||
@ -735,6 +782,16 @@ export class ContactStatChangeProtectedTag extends ProtectedTag {
|
|||||||
this.levels = levels;
|
this.levels = levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.stat = source.stat as BattleStat;
|
||||||
|
this.levels = source.levels;
|
||||||
|
}
|
||||||
|
|
||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
const ret = super.lapse(pokemon, lapseType);
|
const ret = super.lapse(pokemon, lapseType);
|
||||||
|
|
||||||
@ -855,6 +912,15 @@ export class AbilityBattlerTag extends BattlerTag {
|
|||||||
|
|
||||||
this.ability = ability;
|
this.ability = ability;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.ability = source.ability as Abilities;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TruantTag extends AbilityBattlerTag {
|
export class TruantTag extends AbilityBattlerTag {
|
||||||
@ -912,6 +978,16 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
|
|||||||
super(tagType, ability, BattlerTagLapseType.CUSTOM, 1);
|
super(tagType, ability, BattlerTagLapseType.CUSTOM, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.stat = source.stat as Stat;
|
||||||
|
this.multiplier = source.multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
|
|
||||||
@ -953,6 +1029,15 @@ export class WeatherHighestStatBoostTag extends HighestStatBoostTag implements W
|
|||||||
super(tagType, ability);
|
super(tagType, ability);
|
||||||
this.weatherTypes = weatherTypes;
|
this.weatherTypes = weatherTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.weatherTypes = source.weatherTypes.map(w => w as WeatherType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TerrainHighestStatBoostTag extends HighestStatBoostTag implements TerrainBattlerTag {
|
export class TerrainHighestStatBoostTag extends HighestStatBoostTag implements TerrainBattlerTag {
|
||||||
@ -962,6 +1047,15 @@ export class TerrainHighestStatBoostTag extends HighestStatBoostTag implements T
|
|||||||
super(tagType, ability);
|
super(tagType, ability);
|
||||||
this.terrainTypes = terrainTypes;
|
this.terrainTypes = terrainTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.terrainTypes = source.terrainTypes.map(w => w as TerrainType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HideSpriteTag extends BattlerTag {
|
export class HideSpriteTag extends BattlerTag {
|
||||||
@ -989,6 +1083,15 @@ export class TypeImmuneTag extends BattlerTag {
|
|||||||
constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number) {
|
constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number) {
|
||||||
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
|
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.immuneType = source.immuneType as Type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MagnetRisenTag extends TypeImmuneTag {
|
export class MagnetRisenTag extends TypeImmuneTag {
|
||||||
@ -1010,6 +1113,17 @@ export class TypeBoostTag extends BattlerTag {
|
|||||||
this.oneUse = oneUse;
|
this.oneUse = oneUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.boostedType = source.boostedType as Type;
|
||||||
|
this.boostValue = source.boostValue;
|
||||||
|
this.oneUse = source.oneUse;
|
||||||
|
}
|
||||||
|
|
||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||||
}
|
}
|
||||||
@ -1056,6 +1170,15 @@ export class SaltCuredTag extends BattlerTag {
|
|||||||
super(BattlerTagType.SALT_CURED, BattlerTagLapseType.TURN_END, 1, Moves.SALT_CURE, sourceId);
|
super(BattlerTagType.SALT_CURED, BattlerTagLapseType.TURN_END, 1, Moves.SALT_CURE, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.sourceIndex = source.sourceIndex;
|
||||||
|
}
|
||||||
|
|
||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
|
|
||||||
@ -1091,6 +1214,15 @@ export class CursedTag extends BattlerTag {
|
|||||||
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId);
|
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
*/
|
||||||
|
loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.sourceIndex = source.sourceIndex;
|
||||||
|
}
|
||||||
|
|
||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
|
|
||||||
@ -1231,4 +1363,15 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
|
|||||||
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, creates an actual BattlerTag object with the same data.
|
||||||
|
* @param {BattlerTag | any} source A battler tag
|
||||||
|
* @return {BattlerTag} The valid battler tag
|
||||||
|
*/
|
||||||
|
export function loadBattlerTag(source: BattlerTag | any): BattlerTag {
|
||||||
|
const tag = getBattlerTag(source.tagType, source.turnCount, source.sourceMove, source.sourceId);
|
||||||
|
tag.loadTag(source);
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1639,7 +1639,8 @@ export const trainerTypeDialogue = {
|
|||||||
},
|
},
|
||||||
[TrainerType.HAU]: {
|
[TrainerType.HAU]: {
|
||||||
encounter: [
|
encounter: [
|
||||||
`I wonder if a Trainer battles differently depending on whether they're from a warm region or a cold region. Let's test it out!`,
|
`I wonder if a Trainer battles differently depending on whether they're from a warm region or a cold region.
|
||||||
|
$Let's test it out!`,
|
||||||
],
|
],
|
||||||
victory: [
|
victory: [
|
||||||
`That was awesome! I think I kinda understand your vibe a little better now!`,
|
`That was awesome! I think I kinda understand your vibe a little better now!`,
|
||||||
@ -1919,7 +1920,8 @@ export const trainerTypeDialogue = {
|
|||||||
},
|
},
|
||||||
[TrainerType.WULFRIC]: {
|
[TrainerType.WULFRIC]: {
|
||||||
encounter: [
|
encounter: [
|
||||||
`You know what? We all talk big about what you learn from battling and bonds and all that, but really, I just do it 'cause it's fun.
|
`You know what? We all talk big about what you learn from battling and bonds and all that…
|
||||||
|
$But really, I just do it 'cause it's fun.
|
||||||
$Who cares about the grandstanding? Let's get to battling!`,
|
$Who cares about the grandstanding? Let's get to battling!`,
|
||||||
],
|
],
|
||||||
victory: [
|
victory: [
|
||||||
|
@ -1,313 +1,624 @@
|
|||||||
export enum Abilities {
|
export enum Abilities {
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/None_(ability) | Source} */
|
||||||
NONE,
|
NONE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Stench_(ability) | Source} */
|
||||||
STENCH,
|
STENCH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Drizzle_(ability) | Source} */
|
||||||
DRIZZLE,
|
DRIZZLE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Speed_Boost_(ability) | Source} */
|
||||||
SPEED_BOOST,
|
SPEED_BOOST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Battle_Armor_(ability) | Source} */
|
||||||
BATTLE_ARMOR,
|
BATTLE_ARMOR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sturdy_(ability) | Source} */
|
||||||
STURDY,
|
STURDY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Damp_(ability) | Source} */
|
||||||
DAMP,
|
DAMP,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Limber_(ability) | Source} */
|
||||||
LIMBER,
|
LIMBER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sand_Veil_(ability) | Source} */
|
||||||
SAND_VEIL,
|
SAND_VEIL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Static_(ability) | Source} */
|
||||||
STATIC,
|
STATIC,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Volt_Absorb_(ability) | Source} */
|
||||||
VOLT_ABSORB,
|
VOLT_ABSORB,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Water_Absorb_(ability) | Source} */
|
||||||
WATER_ABSORB,
|
WATER_ABSORB,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Oblivious_(ability) | Source} */
|
||||||
OBLIVIOUS,
|
OBLIVIOUS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Cloud_Nine_(ability) | Source} */
|
||||||
CLOUD_NINE,
|
CLOUD_NINE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Compound_Eyes_(ability) | Source} */
|
||||||
COMPOUND_EYES,
|
COMPOUND_EYES,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Insomnia_(ability) | Source} */
|
||||||
INSOMNIA,
|
INSOMNIA,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Color_Change_(ability) | Source} */
|
||||||
COLOR_CHANGE,
|
COLOR_CHANGE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Immunity_(ability) | Source} */
|
||||||
IMMUNITY,
|
IMMUNITY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Flash_Fire_(ability) | Source} */
|
||||||
FLASH_FIRE,
|
FLASH_FIRE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Shield_Dust_(ability) | Source} */
|
||||||
SHIELD_DUST,
|
SHIELD_DUST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Own_Tempo_(ability) | Source} */
|
||||||
OWN_TEMPO,
|
OWN_TEMPO,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Suction_Cups_(ability) | Source} */
|
||||||
SUCTION_CUPS,
|
SUCTION_CUPS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Intimidate_(ability) | Source} */
|
||||||
INTIMIDATE,
|
INTIMIDATE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Shadow_Tag_(ability) | Source} */
|
||||||
SHADOW_TAG,
|
SHADOW_TAG,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Rough_Skin_(ability) | Source} */
|
||||||
ROUGH_SKIN,
|
ROUGH_SKIN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Wonder_Guard_(ability) | Source} */
|
||||||
WONDER_GUARD,
|
WONDER_GUARD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Levitate_(ability) | Source} */
|
||||||
LEVITATE,
|
LEVITATE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Effect_Spore_(ability) | Source} */
|
||||||
EFFECT_SPORE,
|
EFFECT_SPORE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Synchronize_(ability) | Source} */
|
||||||
SYNCHRONIZE,
|
SYNCHRONIZE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Clear_Body_(ability) | Source} */
|
||||||
CLEAR_BODY,
|
CLEAR_BODY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Natural_Cure_(ability) | Source} */
|
||||||
NATURAL_CURE,
|
NATURAL_CURE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Lightning_Rod_(ability) | Source} */
|
||||||
LIGHTNING_ROD,
|
LIGHTNING_ROD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Serene_Grace_(ability) | Source} */
|
||||||
SERENE_GRACE,
|
SERENE_GRACE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Swift_Swim_(ability) | Source} */
|
||||||
SWIFT_SWIM,
|
SWIFT_SWIM,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Chlorophyll_(ability) | Source} */
|
||||||
CHLOROPHYLL,
|
CHLOROPHYLL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Illuminate_(ability) | Source} */
|
||||||
ILLUMINATE,
|
ILLUMINATE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Trace_(ability) | Source} */
|
||||||
TRACE,
|
TRACE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Huge_Power_(ability) | Source} */
|
||||||
HUGE_POWER,
|
HUGE_POWER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Poison_Point_(ability) | Source} */
|
||||||
POISON_POINT,
|
POISON_POINT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Inner_Focus_(ability) | Source} */
|
||||||
INNER_FOCUS,
|
INNER_FOCUS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Magma_Armor_(ability) | Source} */
|
||||||
MAGMA_ARMOR,
|
MAGMA_ARMOR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Water_Veil_(ability) | Source} */
|
||||||
WATER_VEIL,
|
WATER_VEIL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Magnet_Pull_(ability) | Source} */
|
||||||
MAGNET_PULL,
|
MAGNET_PULL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Soundproof_(ability) | Source} */
|
||||||
SOUNDPROOF,
|
SOUNDPROOF,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Rain_Dish_(ability) | Source} */
|
||||||
RAIN_DISH,
|
RAIN_DISH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sand_Stream_(ability) | Source} */
|
||||||
SAND_STREAM,
|
SAND_STREAM,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Pressure_(ability) | Source} */
|
||||||
PRESSURE,
|
PRESSURE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Thick_Fat_(ability) | Source} */
|
||||||
THICK_FAT,
|
THICK_FAT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Early_Bird_(ability) | Source} */
|
||||||
EARLY_BIRD,
|
EARLY_BIRD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Flame_Body_(ability) | Source} */
|
||||||
FLAME_BODY,
|
FLAME_BODY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Run_Away_(ability) | Source} */
|
||||||
RUN_AWAY,
|
RUN_AWAY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Keen_Eye_(ability) | Source} */
|
||||||
KEEN_EYE,
|
KEEN_EYE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Hyper_Cutter_(ability) | Source} */
|
||||||
HYPER_CUTTER,
|
HYPER_CUTTER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Pickup_(ability) | Source} */
|
||||||
PICKUP,
|
PICKUP,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Truant_(ability) | Source} */
|
||||||
TRUANT,
|
TRUANT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Hustle_(ability) | Source} */
|
||||||
HUSTLE,
|
HUSTLE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Cute_Charm_(ability) | Source} */
|
||||||
CUTE_CHARM,
|
CUTE_CHARM,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Plus_(ability) | Source} */
|
||||||
PLUS,
|
PLUS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Minus_(ability) | Source} */
|
||||||
MINUS,
|
MINUS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Forecast_(ability) | Source} */
|
||||||
FORECAST,
|
FORECAST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sticky_Hold_(ability) | Source} */
|
||||||
STICKY_HOLD,
|
STICKY_HOLD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Shed_Skin_(ability) | Source} */
|
||||||
SHED_SKIN,
|
SHED_SKIN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Guts_(ability) | Source} */
|
||||||
GUTS,
|
GUTS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Marvel_Scale_(ability) | Source} */
|
||||||
MARVEL_SCALE,
|
MARVEL_SCALE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Liquid_Ooze_(ability) | Source} */
|
||||||
LIQUID_OOZE,
|
LIQUID_OOZE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Overgrow_(ability) | Source} */
|
||||||
OVERGROW,
|
OVERGROW,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Blaze_(ability) | Source} */
|
||||||
BLAZE,
|
BLAZE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Torrent_(ability) | Source} */
|
||||||
TORRENT,
|
TORRENT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Swarm_(ability) | Source} */
|
||||||
SWARM,
|
SWARM,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Rock_Head_(ability) | Source} */
|
||||||
ROCK_HEAD,
|
ROCK_HEAD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Drought_(ability) | Source} */
|
||||||
DROUGHT,
|
DROUGHT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Arena_Trap_(ability) | Source} */
|
||||||
ARENA_TRAP,
|
ARENA_TRAP,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Vital_Spirit_(ability) | Source} */
|
||||||
VITAL_SPIRIT,
|
VITAL_SPIRIT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/White_Smoke_(ability) | Source} */
|
||||||
WHITE_SMOKE,
|
WHITE_SMOKE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Pure_Power_(ability) | Source} */
|
||||||
PURE_POWER,
|
PURE_POWER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Shell_Armor_(ability) | Source} */
|
||||||
SHELL_ARMOR,
|
SHELL_ARMOR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Air_Lock_(ability) | Source} */
|
||||||
AIR_LOCK,
|
AIR_LOCK,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Tangled_Feet_(ability) | Source} */
|
||||||
TANGLED_FEET,
|
TANGLED_FEET,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Motor_Drive_(ability) | Source} */
|
||||||
MOTOR_DRIVE,
|
MOTOR_DRIVE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Rivalry_(ability) | Source} */
|
||||||
RIVALRY,
|
RIVALRY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Steadfast_(ability) | Source} */
|
||||||
STEADFAST,
|
STEADFAST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Snow_Cloak_(ability) | Source} */
|
||||||
SNOW_CLOAK,
|
SNOW_CLOAK,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Gluttony_(ability) | Source} */
|
||||||
GLUTTONY,
|
GLUTTONY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Anger_Point_(ability) | Source} */
|
||||||
ANGER_POINT,
|
ANGER_POINT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Unburden_(ability) | Source} */
|
||||||
UNBURDEN,
|
UNBURDEN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Heatproof_(ability) | Source} */
|
||||||
HEATPROOF,
|
HEATPROOF,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Simple_(ability) | Source} */
|
||||||
SIMPLE,
|
SIMPLE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Dry_Skin_(ability) | Source} */
|
||||||
DRY_SKIN,
|
DRY_SKIN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Download_(ability) | Source} */
|
||||||
DOWNLOAD,
|
DOWNLOAD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Iron_Fist_(ability) | Source} */
|
||||||
IRON_FIST,
|
IRON_FIST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Poison_Heal_(ability) | Source} */
|
||||||
POISON_HEAL,
|
POISON_HEAL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Adaptability_(ability) | Source} */
|
||||||
ADAPTABILITY,
|
ADAPTABILITY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Skill_Link_(ability) | Source} */
|
||||||
SKILL_LINK,
|
SKILL_LINK,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Hydration_(ability) | Source} */
|
||||||
HYDRATION,
|
HYDRATION,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Solar_Power_(ability) | Source} */
|
||||||
SOLAR_POWER,
|
SOLAR_POWER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Quick_Feet_(ability) | Source} */
|
||||||
QUICK_FEET,
|
QUICK_FEET,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Normalize_(ability) | Source} */
|
||||||
NORMALIZE,
|
NORMALIZE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sniper_(ability) | Source} */
|
||||||
SNIPER,
|
SNIPER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Magic_Guard_(ability) | Source} */
|
||||||
MAGIC_GUARD,
|
MAGIC_GUARD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/No_Guard_(ability) | Source} */
|
||||||
NO_GUARD,
|
NO_GUARD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Stall_(ability) | Source} */
|
||||||
STALL,
|
STALL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Technician_(ability) | Source} */
|
||||||
TECHNICIAN,
|
TECHNICIAN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Leaf_Guard_(ability) | Source} */
|
||||||
LEAF_GUARD,
|
LEAF_GUARD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Klutz_(ability) | Source} */
|
||||||
KLUTZ,
|
KLUTZ,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Mold_Breaker_(ability) | Source} */
|
||||||
MOLD_BREAKER,
|
MOLD_BREAKER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Super_Luck_(ability) | Source} */
|
||||||
SUPER_LUCK,
|
SUPER_LUCK,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Aftermath_(ability) | Source} */
|
||||||
AFTERMATH,
|
AFTERMATH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Anticipation_(ability) | Source} */
|
||||||
ANTICIPATION,
|
ANTICIPATION,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Forewarn_(ability) | Source} */
|
||||||
FOREWARN,
|
FOREWARN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Unaware_(ability) | Source} */
|
||||||
UNAWARE,
|
UNAWARE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Tinted_Lens_(ability) | Source} */
|
||||||
TINTED_LENS,
|
TINTED_LENS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Filter_(ability) | Source} */
|
||||||
FILTER,
|
FILTER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Slow_Start_(ability) | Source} */
|
||||||
SLOW_START,
|
SLOW_START,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Scrappy_(ability) | Source} */
|
||||||
SCRAPPY,
|
SCRAPPY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Storm_Drain_(ability) | Source} */
|
||||||
STORM_DRAIN,
|
STORM_DRAIN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Ice_Body_(ability) | Source} */
|
||||||
ICE_BODY,
|
ICE_BODY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Solid_Rock_(ability) | Source} */
|
||||||
SOLID_ROCK,
|
SOLID_ROCK,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Snow_Warning_(ability) | Source} */
|
||||||
SNOW_WARNING,
|
SNOW_WARNING,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Honey_Gather_(ability) | Source} */
|
||||||
HONEY_GATHER,
|
HONEY_GATHER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Frisk_(ability) | Source} */
|
||||||
FRISK,
|
FRISK,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Reckless_(ability) | Source} */
|
||||||
RECKLESS,
|
RECKLESS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Multitype_(ability) | Source} */
|
||||||
MULTITYPE,
|
MULTITYPE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Flower_Gift_(ability) | Source} */
|
||||||
FLOWER_GIFT,
|
FLOWER_GIFT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Bad_Dreams_(ability) | Source} */
|
||||||
BAD_DREAMS,
|
BAD_DREAMS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Pickpocket_(ability) | Source} */
|
||||||
PICKPOCKET,
|
PICKPOCKET,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sheer_Force_(ability) | Source} */
|
||||||
SHEER_FORCE,
|
SHEER_FORCE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Contrary_(ability) | Source} */
|
||||||
CONTRARY,
|
CONTRARY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Unnerve_(ability) | Source} */
|
||||||
UNNERVE,
|
UNNERVE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Defiant_(ability) | Source} */
|
||||||
DEFIANT,
|
DEFIANT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Defeatist_(ability) | Source} */
|
||||||
DEFEATIST,
|
DEFEATIST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Cursed_Body_(ability) | Source} */
|
||||||
CURSED_BODY,
|
CURSED_BODY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Healer_(ability) | Source} */
|
||||||
HEALER,
|
HEALER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Friend_Guard_(ability) | Source} */
|
||||||
FRIEND_GUARD,
|
FRIEND_GUARD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Weak_Armor_(ability) | Source} */
|
||||||
WEAK_ARMOR,
|
WEAK_ARMOR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Heavy_Metal_(ability) | Source} */
|
||||||
HEAVY_METAL,
|
HEAVY_METAL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Light_Metal_(ability) | Source} */
|
||||||
LIGHT_METAL,
|
LIGHT_METAL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Multiscale_(ability) | Source} */
|
||||||
MULTISCALE,
|
MULTISCALE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Toxic_Boost_(ability) | Source} */
|
||||||
TOXIC_BOOST,
|
TOXIC_BOOST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Flare_Boost_(ability) | Source} */
|
||||||
FLARE_BOOST,
|
FLARE_BOOST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Harvest_(ability) | Source} */
|
||||||
HARVEST,
|
HARVEST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Telepathy_(ability) | Source} */
|
||||||
TELEPATHY,
|
TELEPATHY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Moody_(ability) | Source} */
|
||||||
MOODY,
|
MOODY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Overcoat_(ability) | Source} */
|
||||||
OVERCOAT,
|
OVERCOAT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Poison_Touch_(ability) | Source} */
|
||||||
POISON_TOUCH,
|
POISON_TOUCH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Regenerator_(ability) | Source} */
|
||||||
REGENERATOR,
|
REGENERATOR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Big_Pecks_(ability) | Source} */
|
||||||
BIG_PECKS,
|
BIG_PECKS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sand_Rush_(ability) | Source} */
|
||||||
SAND_RUSH,
|
SAND_RUSH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Wonder_Skin_(ability) | Source} */
|
||||||
WONDER_SKIN,
|
WONDER_SKIN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Analytic_(ability) | Source} */
|
||||||
ANALYTIC,
|
ANALYTIC,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Illusion_(ability) | Source} */
|
||||||
ILLUSION,
|
ILLUSION,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Imposter_(ability) | Source} */
|
||||||
IMPOSTER,
|
IMPOSTER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Infiltrator_(ability) | Source} */
|
||||||
INFILTRATOR,
|
INFILTRATOR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Mummy_(ability) | Source} */
|
||||||
MUMMY,
|
MUMMY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Moxie_(ability) | Source} */
|
||||||
MOXIE,
|
MOXIE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Justified_(ability) | Source} */
|
||||||
JUSTIFIED,
|
JUSTIFIED,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Rattled_(ability) | Source} */
|
||||||
RATTLED,
|
RATTLED,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Magic_Bounce_(ability) | Source} */
|
||||||
MAGIC_BOUNCE,
|
MAGIC_BOUNCE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sap_Sipper_(ability) | Source} */
|
||||||
SAP_SIPPER,
|
SAP_SIPPER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Prankster_(ability) | Source} */
|
||||||
PRANKSTER,
|
PRANKSTER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sand_Force_(ability) | Source} */
|
||||||
SAND_FORCE,
|
SAND_FORCE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Iron_Barbs_(ability) | Source} */
|
||||||
IRON_BARBS,
|
IRON_BARBS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Zen_Mode_(ability) | Source} */
|
||||||
ZEN_MODE,
|
ZEN_MODE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Victory_Star_(ability) | Source} */
|
||||||
VICTORY_STAR,
|
VICTORY_STAR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Turboblaze_(ability) | Source} */
|
||||||
TURBOBLAZE,
|
TURBOBLAZE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Teravolt_(ability) | Source} */
|
||||||
TERAVOLT,
|
TERAVOLT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Aroma_Veil_(ability) | Source} */
|
||||||
AROMA_VEIL,
|
AROMA_VEIL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Flower_Veil_(ability) | Source} */
|
||||||
FLOWER_VEIL,
|
FLOWER_VEIL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Cheek_Pouch_(ability) | Source} */
|
||||||
CHEEK_POUCH,
|
CHEEK_POUCH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Protean_(ability) | Source} */
|
||||||
PROTEAN,
|
PROTEAN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Fur_Coat_(ability) | Source} */
|
||||||
FUR_COAT,
|
FUR_COAT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Magician_(ability) | Source} */
|
||||||
MAGICIAN,
|
MAGICIAN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Bulletproof_(ability) | Source} */
|
||||||
BULLETPROOF,
|
BULLETPROOF,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Competitive_(ability) | Source} */
|
||||||
COMPETITIVE,
|
COMPETITIVE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Strong_Jaw_(ability) | Source} */
|
||||||
STRONG_JAW,
|
STRONG_JAW,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Refrigerate_(ability) | Source} */
|
||||||
REFRIGERATE,
|
REFRIGERATE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sweet_Veil_(ability) | Source} */
|
||||||
SWEET_VEIL,
|
SWEET_VEIL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Stance_Change_(ability) | Source} */
|
||||||
STANCE_CHANGE,
|
STANCE_CHANGE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Gale_Wings_(ability) | Source} */
|
||||||
GALE_WINGS,
|
GALE_WINGS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Mega_Launcher_(ability) | Source} */
|
||||||
MEGA_LAUNCHER,
|
MEGA_LAUNCHER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Grass_Pelt_(ability) | Source} */
|
||||||
GRASS_PELT,
|
GRASS_PELT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Symbiosis_(ability) | Source} */
|
||||||
SYMBIOSIS,
|
SYMBIOSIS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Tough_Claws_(ability) | Source} */
|
||||||
TOUGH_CLAWS,
|
TOUGH_CLAWS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Pixilate_(ability) | Source} */
|
||||||
PIXILATE,
|
PIXILATE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Gooey_(ability) | Source} */
|
||||||
GOOEY,
|
GOOEY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Aerilate_(ability) | Source} */
|
||||||
AERILATE,
|
AERILATE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Parental_Bond_(ability) | Source} */
|
||||||
PARENTAL_BOND,
|
PARENTAL_BOND,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Dark_Aura_(ability) | Source} */
|
||||||
DARK_AURA,
|
DARK_AURA,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Fairy_Aura_(ability) | Source} */
|
||||||
FAIRY_AURA,
|
FAIRY_AURA,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Aura_Break_(ability) | Source} */
|
||||||
AURA_BREAK,
|
AURA_BREAK,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Primordial_Sea_(ability) | Source} */
|
||||||
PRIMORDIAL_SEA,
|
PRIMORDIAL_SEA,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Desolate_Land_(ability) | Source} */
|
||||||
DESOLATE_LAND,
|
DESOLATE_LAND,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Delta_Stream_(ability) | Source} */
|
||||||
DELTA_STREAM,
|
DELTA_STREAM,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Stamina_(ability) | Source} */
|
||||||
STAMINA,
|
STAMINA,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Wimp_Out_(ability) | Source} */
|
||||||
WIMP_OUT,
|
WIMP_OUT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Emergency_Exit_(ability) | Source} */
|
||||||
EMERGENCY_EXIT,
|
EMERGENCY_EXIT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Water_Compaction_(ability) | Source} */
|
||||||
WATER_COMPACTION,
|
WATER_COMPACTION,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Merciless_(ability) | Source} */
|
||||||
MERCILESS,
|
MERCILESS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Shields_Down_(ability) | Source} */
|
||||||
SHIELDS_DOWN,
|
SHIELDS_DOWN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Stakeout_(ability) | Source} */
|
||||||
STAKEOUT,
|
STAKEOUT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Water_Bubble_(ability) | Source} */
|
||||||
WATER_BUBBLE,
|
WATER_BUBBLE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Steelworker_(ability) | Source} */
|
||||||
STEELWORKER,
|
STEELWORKER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Berserk_(ability) | Source} */
|
||||||
BERSERK,
|
BERSERK,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Slush_Rush_(ability) | Source} */
|
||||||
SLUSH_RUSH,
|
SLUSH_RUSH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Long_Reach_(ability) | Source} */
|
||||||
LONG_REACH,
|
LONG_REACH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Liquid_Voice_(ability) | Source} */
|
||||||
LIQUID_VOICE,
|
LIQUID_VOICE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Triage_(ability) | Source} */
|
||||||
TRIAGE,
|
TRIAGE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Galvanize_(ability) | Source} */
|
||||||
GALVANIZE,
|
GALVANIZE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Surge_Surfer_(ability) | Source} */
|
||||||
SURGE_SURFER,
|
SURGE_SURFER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Schooling_(ability) | Source} */
|
||||||
SCHOOLING,
|
SCHOOLING,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Disguise_(ability) | Source} */
|
||||||
DISGUISE,
|
DISGUISE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Battle_Bond_(ability) | Source} */
|
||||||
BATTLE_BOND,
|
BATTLE_BOND,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Power_Construct_(ability) | Source} */
|
||||||
POWER_CONSTRUCT,
|
POWER_CONSTRUCT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Corrosion_(ability) | Source} */
|
||||||
CORROSION,
|
CORROSION,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Comatose_(ability) | Source} */
|
||||||
COMATOSE,
|
COMATOSE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Queenly_Majesty_(ability) | Source} */
|
||||||
QUEENLY_MAJESTY,
|
QUEENLY_MAJESTY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Innards_Out_(ability) | Source} */
|
||||||
INNARDS_OUT,
|
INNARDS_OUT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Dancer_(ability) | Source} */
|
||||||
DANCER,
|
DANCER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Battery_(ability) | Source} */
|
||||||
BATTERY,
|
BATTERY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Fluffy_(ability) | Source} */
|
||||||
FLUFFY,
|
FLUFFY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Dazzling_(ability) | Source} */
|
||||||
DAZZLING,
|
DAZZLING,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Soul_Heart_(ability) | Source} */
|
||||||
SOUL_HEART,
|
SOUL_HEART,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Tangling_Hair_(ability) | Source} */
|
||||||
TANGLING_HAIR,
|
TANGLING_HAIR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Receiver_(ability) | Source} */
|
||||||
RECEIVER,
|
RECEIVER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Power_Of_Alchemy_(ability) | Source} */
|
||||||
POWER_OF_ALCHEMY,
|
POWER_OF_ALCHEMY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Beast_Boost_(ability) | Source} */
|
||||||
BEAST_BOOST,
|
BEAST_BOOST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Rks_System_(ability) | Source} */
|
||||||
RKS_SYSTEM,
|
RKS_SYSTEM,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Electric_Surge_(ability) | Source} */
|
||||||
ELECTRIC_SURGE,
|
ELECTRIC_SURGE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Psychic_Surge_(ability) | Source} */
|
||||||
PSYCHIC_SURGE,
|
PSYCHIC_SURGE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Misty_Surge_(ability) | Source} */
|
||||||
MISTY_SURGE,
|
MISTY_SURGE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Grassy_Surge_(ability) | Source} */
|
||||||
GRASSY_SURGE,
|
GRASSY_SURGE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Full_Metal_Body_(ability) | Source} */
|
||||||
FULL_METAL_BODY,
|
FULL_METAL_BODY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Shadow_Shield_(ability) | Source} */
|
||||||
SHADOW_SHIELD,
|
SHADOW_SHIELD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Prism_Armor_(ability) | Source} */
|
||||||
PRISM_ARMOR,
|
PRISM_ARMOR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Neuroforce_(ability) | Source} */
|
||||||
NEUROFORCE,
|
NEUROFORCE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Intrepid_Sword_(ability) | Source} */
|
||||||
INTREPID_SWORD,
|
INTREPID_SWORD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Dauntless_Shield_(ability) | Source} */
|
||||||
DAUNTLESS_SHIELD,
|
DAUNTLESS_SHIELD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Libero_(ability) | Source} */
|
||||||
LIBERO,
|
LIBERO,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Ball_Fetch_(ability) | Source} */
|
||||||
BALL_FETCH,
|
BALL_FETCH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Cotton_Down_(ability) | Source} */
|
||||||
COTTON_DOWN,
|
COTTON_DOWN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Propeller_Tail_(ability) | Source} */
|
||||||
PROPELLER_TAIL,
|
PROPELLER_TAIL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Mirror_Armor_(ability) | Source} */
|
||||||
MIRROR_ARMOR,
|
MIRROR_ARMOR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Gulp_Missile_(ability) | Source} */
|
||||||
GULP_MISSILE,
|
GULP_MISSILE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Stalwart_(ability) | Source} */
|
||||||
STALWART,
|
STALWART,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Steam_Engine_(ability) | Source} */
|
||||||
STEAM_ENGINE,
|
STEAM_ENGINE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Punk_Rock_(ability) | Source} */
|
||||||
PUNK_ROCK,
|
PUNK_ROCK,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sand_Spit_(ability) | Source} */
|
||||||
SAND_SPIT,
|
SAND_SPIT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Ice_Scales_(ability) | Source} */
|
||||||
ICE_SCALES,
|
ICE_SCALES,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Ripen_(ability) | Source} */
|
||||||
RIPEN,
|
RIPEN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Ice_Face_(ability) | Source} */
|
||||||
ICE_FACE,
|
ICE_FACE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Power_Spot_(ability) | Source} */
|
||||||
POWER_SPOT,
|
POWER_SPOT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Mimicry_(ability) | Source} */
|
||||||
MIMICRY,
|
MIMICRY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Screen_Cleaner_(ability) | Source} */
|
||||||
SCREEN_CLEANER,
|
SCREEN_CLEANER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Steely_Spirit_(ability) | Source} */
|
||||||
STEELY_SPIRIT,
|
STEELY_SPIRIT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Perish_Body_(ability) | Source} */
|
||||||
PERISH_BODY,
|
PERISH_BODY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Wandering_Spirit_(ability) | Source} */
|
||||||
WANDERING_SPIRIT,
|
WANDERING_SPIRIT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Gorilla_Tactics_(ability) | Source} */
|
||||||
GORILLA_TACTICS,
|
GORILLA_TACTICS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Neutralizing_Gas_(ability) | Source} */
|
||||||
NEUTRALIZING_GAS,
|
NEUTRALIZING_GAS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Pastel_Veil_(ability) | Source} */
|
||||||
PASTEL_VEIL,
|
PASTEL_VEIL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Hunger_Switch_(ability) | Source} */
|
||||||
HUNGER_SWITCH,
|
HUNGER_SWITCH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Quick_Draw_(ability) | Source} */
|
||||||
QUICK_DRAW,
|
QUICK_DRAW,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Unseen_Fist_(ability) | Source} */
|
||||||
UNSEEN_FIST,
|
UNSEEN_FIST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Curious_Medicine_(ability) | Source} */
|
||||||
CURIOUS_MEDICINE,
|
CURIOUS_MEDICINE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Transistor_(ability) | Source} */
|
||||||
TRANSISTOR,
|
TRANSISTOR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Dragons_Maw_(ability) | Source} */
|
||||||
DRAGONS_MAW,
|
DRAGONS_MAW,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Chilling_Neigh_(ability) | Source} */
|
||||||
CHILLING_NEIGH,
|
CHILLING_NEIGH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Grim_Neigh_(ability) | Source} */
|
||||||
GRIM_NEIGH,
|
GRIM_NEIGH,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/As_One_Glastrier_(ability) | Source} */
|
||||||
AS_ONE_GLASTRIER,
|
AS_ONE_GLASTRIER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/As_One_Spectrier_(ability) | Source} */
|
||||||
AS_ONE_SPECTRIER,
|
AS_ONE_SPECTRIER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Lingering_Aroma_(ability) | Source} */
|
||||||
LINGERING_AROMA,
|
LINGERING_AROMA,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Seed_Sower_(ability) | Source} */
|
||||||
SEED_SOWER,
|
SEED_SOWER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Thermal_Exchange_(ability) | Source} */
|
||||||
THERMAL_EXCHANGE,
|
THERMAL_EXCHANGE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Anger_Shell_(ability) | Source} */
|
||||||
ANGER_SHELL,
|
ANGER_SHELL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Purifying_Salt_(ability) | Source} */
|
||||||
PURIFYING_SALT,
|
PURIFYING_SALT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Well_Baked_Body_(ability) | Source} */
|
||||||
WELL_BAKED_BODY,
|
WELL_BAKED_BODY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Wind_Rider_(ability) | Source} */
|
||||||
WIND_RIDER,
|
WIND_RIDER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Guard_Dog_(ability) | Source} */
|
||||||
GUARD_DOG,
|
GUARD_DOG,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Rocky_Payload_(ability) | Source} */
|
||||||
ROCKY_PAYLOAD,
|
ROCKY_PAYLOAD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Wind_Power_(ability) | Source} */
|
||||||
WIND_POWER,
|
WIND_POWER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Zero_To_Hero_(ability) | Source} */
|
||||||
ZERO_TO_HERO,
|
ZERO_TO_HERO,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Commander_(ability) | Source} */
|
||||||
COMMANDER,
|
COMMANDER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Electromorphosis_(ability) | Source} */
|
||||||
ELECTROMORPHOSIS,
|
ELECTROMORPHOSIS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Protosynthesis_(ability) | Source} */
|
||||||
PROTOSYNTHESIS,
|
PROTOSYNTHESIS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Quark_Drive_(ability) | Source} */
|
||||||
QUARK_DRIVE,
|
QUARK_DRIVE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Good_As_Gold_(ability) | Source} */
|
||||||
GOOD_AS_GOLD,
|
GOOD_AS_GOLD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Vessel_Of_Ruin_(ability) | Source} */
|
||||||
VESSEL_OF_RUIN,
|
VESSEL_OF_RUIN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sword_Of_Ruin_(ability) | Source} */
|
||||||
SWORD_OF_RUIN,
|
SWORD_OF_RUIN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Tablets_Of_Ruin_(ability) | Source} */
|
||||||
TABLETS_OF_RUIN,
|
TABLETS_OF_RUIN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Beads_Of_Ruin_(ability) | Source} */
|
||||||
BEADS_OF_RUIN,
|
BEADS_OF_RUIN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Orichalcum_Pulse_(ability) | Source} */
|
||||||
ORICHALCUM_PULSE,
|
ORICHALCUM_PULSE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Hadron_Engine_(ability) | Source} */
|
||||||
HADRON_ENGINE,
|
HADRON_ENGINE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Opportunist_(ability) | Source} */
|
||||||
OPPORTUNIST,
|
OPPORTUNIST,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Cud_Chew_(ability) | Source} */
|
||||||
CUD_CHEW,
|
CUD_CHEW,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Sharpness_(ability) | Source} */
|
||||||
SHARPNESS,
|
SHARPNESS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Supreme_Overlord_(ability) | Source} */
|
||||||
SUPREME_OVERLORD,
|
SUPREME_OVERLORD,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Costar_(ability) | Source} */
|
||||||
COSTAR,
|
COSTAR,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Toxic_Debris_(ability) | Source} */
|
||||||
TOXIC_DEBRIS,
|
TOXIC_DEBRIS,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Armor_Tail_(ability) | Source} */
|
||||||
ARMOR_TAIL,
|
ARMOR_TAIL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Earth_Eater_(ability) | Source} */
|
||||||
EARTH_EATER,
|
EARTH_EATER,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Mycelium_Might_(ability) | Source} */
|
||||||
MYCELIUM_MIGHT,
|
MYCELIUM_MIGHT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Minds_Eye_(ability) | Source} */
|
||||||
MINDS_EYE,
|
MINDS_EYE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Supersweet_Syrup_(ability) | Source} */
|
||||||
SUPERSWEET_SYRUP,
|
SUPERSWEET_SYRUP,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Hospitality_(ability) | Source} */
|
||||||
HOSPITALITY,
|
HOSPITALITY,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Toxic_Chain_(ability) | Source} */
|
||||||
TOXIC_CHAIN,
|
TOXIC_CHAIN,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Embody_Aspect_Teal_(ability) | Source} */
|
||||||
EMBODY_ASPECT_TEAL,
|
EMBODY_ASPECT_TEAL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Embody_Aspect_Wellspring_(ability) | Source} */
|
||||||
EMBODY_ASPECT_WELLSPRING,
|
EMBODY_ASPECT_WELLSPRING,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Embody_Aspect_Hearthflame_(ability) | Source} */
|
||||||
EMBODY_ASPECT_HEARTHFLAME,
|
EMBODY_ASPECT_HEARTHFLAME,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Embody_Aspect_Cornerstone_(ability) | Source} */
|
||||||
EMBODY_ASPECT_CORNERSTONE,
|
EMBODY_ASPECT_CORNERSTONE,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Tera_Shift_(ability) | Source} */
|
||||||
TERA_SHIFT,
|
TERA_SHIFT,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Tera_Shell_(ability) | Source} */
|
||||||
TERA_SHELL,
|
TERA_SHELL,
|
||||||
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Teraform_Zero_(ability) | Source} */
|
||||||
TERAFORM_ZERO,
|
TERAFORM_ZERO,
|
||||||
POISON_PUPPETEER
|
/**{@link https://bulbapedia.bulbagarden.net/wiki/Poison_Puppeteer_(ability) | Source} */
|
||||||
|
POISON_PUPPETEER,
|
||||||
}
|
}
|
||||||
|
433
src/data/move.ts
@ -1,6 +1,6 @@
|
|||||||
import { Moves } from "./enums/moves";
|
import { Moves } from "./enums/moves";
|
||||||
import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims";
|
import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims";
|
||||||
import { BattleEndPhase, MovePhase, NewBattlePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases";
|
import { BattleEndPhase, MovePhase, NewBattlePhase, PartyEffectPhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases";
|
||||||
import { BattleStat, getBattleStatName } from "./battle-stat";
|
import { BattleStat, getBattleStatName } from "./battle-stat";
|
||||||
import { EncoreTag } from "./battler-tags";
|
import { EncoreTag } from "./battler-tags";
|
||||||
import { BattlerTagType } from "./enums/battler-tag-type";
|
import { BattlerTagType } from "./enums/battler-tag-type";
|
||||||
@ -50,26 +50,33 @@ export enum MoveTarget {
|
|||||||
ALL,
|
ALL,
|
||||||
USER_SIDE,
|
USER_SIDE,
|
||||||
ENEMY_SIDE,
|
ENEMY_SIDE,
|
||||||
BOTH_SIDES
|
BOTH_SIDES,
|
||||||
|
PARTY
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MoveFlags {
|
export enum MoveFlags {
|
||||||
MAKES_CONTACT = 1,
|
NONE = 0,
|
||||||
IGNORE_PROTECT = 2,
|
MAKES_CONTACT = 1 << 0,
|
||||||
IGNORE_VIRTUAL = 4,
|
IGNORE_PROTECT = 1 << 1,
|
||||||
SOUND_BASED = 8,
|
IGNORE_VIRTUAL = 1 << 2,
|
||||||
HIDE_USER = 16,
|
SOUND_BASED = 1 << 3,
|
||||||
HIDE_TARGET = 32,
|
HIDE_USER = 1 << 4,
|
||||||
BITING_MOVE = 64,
|
HIDE_TARGET = 1 << 5,
|
||||||
PULSE_MOVE = 128,
|
BITING_MOVE = 1 << 6,
|
||||||
PUNCHING_MOVE = 256,
|
PULSE_MOVE = 1 << 7,
|
||||||
SLICING_MOVE = 512,
|
PUNCHING_MOVE = 1 << 8,
|
||||||
BALLBOMB_MOVE = 1024,
|
SLICING_MOVE = 1 << 9,
|
||||||
POWDER_MOVE = 2048,
|
/**
|
||||||
DANCE_MOVE = 4096,
|
* Indicates a move should be affected by {@link Abilities.RECKLESS}
|
||||||
WIND_MOVE = 8192,
|
* @see {@link Move.recklessMove()}
|
||||||
TRIAGE_MOVE = 16384,
|
*/
|
||||||
IGNORE_ABILITIES = 32768
|
RECKLESS_MOVE = 1 << 10,
|
||||||
|
BALLBOMB_MOVE = 1 << 11,
|
||||||
|
POWDER_MOVE = 1 << 12,
|
||||||
|
DANCE_MOVE = 1 << 13,
|
||||||
|
WIND_MOVE = 1 << 14,
|
||||||
|
TRIAGE_MOVE = 1 << 15,
|
||||||
|
IGNORE_ABILITIES = 1 << 16,
|
||||||
}
|
}
|
||||||
|
|
||||||
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
|
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
|
||||||
@ -269,6 +276,17 @@ export default class Move implements Localizable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link MoveFlags.RECKLESS_MOVE} flag for the calling Move
|
||||||
|
* @see {@link Abilities.RECKLESS}
|
||||||
|
* @param {boolean} recklessMove The value to set the flag to
|
||||||
|
* @returns {Move} The {@link Move} that called this function
|
||||||
|
*/
|
||||||
|
recklessMove(recklessMove?: boolean): this {
|
||||||
|
this.setFlag(MoveFlags.RECKLESS_MOVE, recklessMove);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
ballBombMove(ballBombMove?: boolean): this {
|
ballBombMove(ballBombMove?: boolean): this {
|
||||||
this.setFlag(MoveFlags.BALLBOMB_MOVE, ballBombMove);
|
this.setFlag(MoveFlags.BALLBOMB_MOVE, ballBombMove);
|
||||||
return this;
|
return this;
|
||||||
@ -815,6 +833,34 @@ export class HealAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cures the user's party of non-volatile status conditions, ie. Heal Bell, Aromatherapy
|
||||||
|
* @param {string} message Message to display after using move
|
||||||
|
* @param {Abilities} abilityCondition Skips mons with this ability, ie. Soundproof
|
||||||
|
*/
|
||||||
|
export class PartyStatusCureAttr extends MoveEffectAttr {
|
||||||
|
private message: string;
|
||||||
|
private abilityCondition: Abilities;
|
||||||
|
|
||||||
|
constructor(message: string, abilityCondition: Abilities) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.message = message;
|
||||||
|
this.abilityCondition = abilityCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
if (!super.apply(user, target, move, args))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this.addPartyCurePhase(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
addPartyCurePhase(user: Pokemon) {
|
||||||
|
user.scene.unshiftPhase(new PartyStatusCurePhase(user.scene, user, this.message, this.abilityCondition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class SacrificialFullRestoreAttr extends SacrificialAttr {
|
export class SacrificialFullRestoreAttr extends SacrificialAttr {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -1544,6 +1590,29 @@ export class StatChangeAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PostVictoryStatChangeAttr extends MoveAttr {
|
||||||
|
private stats: BattleStat[];
|
||||||
|
private levels: integer;
|
||||||
|
private condition: MoveConditionFunc;
|
||||||
|
private showMessage: boolean;
|
||||||
|
|
||||||
|
constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean, condition?: MoveConditionFunc, showMessage: boolean = true, firstHitOnly: boolean = false) {
|
||||||
|
super();
|
||||||
|
this.stats = typeof(stats) === 'number'
|
||||||
|
? [ stats as BattleStat ]
|
||||||
|
: stats as BattleStat[];
|
||||||
|
this.levels = levels;
|
||||||
|
this.condition = condition || null;
|
||||||
|
this.showMessage = showMessage;
|
||||||
|
}
|
||||||
|
applyPostVictory(user: Pokemon, target: Pokemon, move: Move): void {
|
||||||
|
if(this.condition && !this.condition(user, target, move))
|
||||||
|
return false;
|
||||||
|
const statChangeAttr = new StatChangeAttr(this.stats, this.levels, this.showMessage);
|
||||||
|
statChangeAttr.apply(user, target, move);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class AcupressureStatChangeAttr extends MoveEffectAttr {
|
export class AcupressureStatChangeAttr extends MoveEffectAttr {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -1558,7 +1627,7 @@ export class AcupressureStatChangeAttr extends MoveEffectAttr {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GrowthStatChangeAttr extends StatChangeAttr {
|
export class GrowthStatChangeAttr extends StatChangeAttr {
|
||||||
@ -2961,6 +3030,42 @@ export class AddArenaTrapTagAttr extends AddArenaTagAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class RemoveArenaTrapAttr extends MoveEffectAttr {
|
||||||
|
|
||||||
|
private targetBothSides: boolean;
|
||||||
|
|
||||||
|
constructor(targetBothSides: boolean = false) {
|
||||||
|
super(true, MoveEffectTrigger.PRE_APPLY);
|
||||||
|
this.targetBothSides = targetBothSides;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
|
||||||
|
if (!super.apply(user, target, move, args))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(this.targetBothSides){
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.PLAYER);
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.TOXIC_SPIKES, ArenaTagSide.PLAYER);
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.STEALTH_ROCK, ArenaTagSide.PLAYER);
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.STICKY_WEB, ArenaTagSide.PLAYER);
|
||||||
|
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY);
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.TOXIC_SPIKES, ArenaTagSide.ENEMY);
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.STEALTH_ROCK, ArenaTagSide.ENEMY);
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.STICKY_WEB, ArenaTagSide.ENEMY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.SPIKES, target.isPlayer() ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER);
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.TOXIC_SPIKES, target.isPlayer() ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER);
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.STEALTH_ROCK, target.isPlayer() ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER);
|
||||||
|
user.scene.arena.removeTagOnSide(ArenaTagType.STICKY_WEB, target.isPlayer() ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class RemoveScreensAttr extends MoveEffectAttr {
|
export class RemoveScreensAttr extends MoveEffectAttr {
|
||||||
|
|
||||||
private targetBothSides: boolean;
|
private targetBothSides: boolean;
|
||||||
@ -3927,6 +4032,7 @@ export function getMoveTargets(user: Pokemon, move: Moves): MoveTargetSet {
|
|||||||
|
|
||||||
switch (moveTarget) {
|
switch (moveTarget) {
|
||||||
case MoveTarget.USER:
|
case MoveTarget.USER:
|
||||||
|
case MoveTarget.PARTY:
|
||||||
set = [ user];
|
set = [ user];
|
||||||
break;
|
break;
|
||||||
case MoveTarget.NEAR_OTHER:
|
case MoveTarget.NEAR_OTHER:
|
||||||
@ -4037,7 +4143,8 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.JUMP_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 95, 10, -1, 0, 1)
|
new AttackMove(Moves.JUMP_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 95, 10, -1, 0, 1)
|
||||||
.attr(MissEffectAttr, crashDamageFunc)
|
.attr(MissEffectAttr, crashDamageFunc)
|
||||||
.attr(NoEffectAttr, crashDamageFunc)
|
.attr(NoEffectAttr, crashDamageFunc)
|
||||||
.condition(failOnGravityCondition),
|
.condition(failOnGravityCondition)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.ROLLING_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 85, 15, 30, 0, 1)
|
new AttackMove(Moves.ROLLING_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 85, 15, 30, 0, 1)
|
||||||
.attr(FlinchAttr),
|
.attr(FlinchAttr),
|
||||||
new StatusMove(Moves.SAND_ATTACK, Type.GROUND, 100, 15, -1, 0, 1)
|
new StatusMove(Moves.SAND_ATTACK, Type.GROUND, 100, 15, -1, 0, 1)
|
||||||
@ -4056,13 +4163,15 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.WRAP, Type.NORMAL, MoveCategory.PHYSICAL, 15, 90, 20, 100, 0, 1)
|
new AttackMove(Moves.WRAP, Type.NORMAL, MoveCategory.PHYSICAL, 15, 90, 20, 100, 0, 1)
|
||||||
.attr(TrapAttr, BattlerTagType.WRAP),
|
.attr(TrapAttr, BattlerTagType.WRAP),
|
||||||
new AttackMove(Moves.TAKE_DOWN, Type.NORMAL, MoveCategory.PHYSICAL, 90, 85, 20, -1, 0, 1)
|
new AttackMove(Moves.TAKE_DOWN, Type.NORMAL, MoveCategory.PHYSICAL, 90, 85, 20, -1, 0, 1)
|
||||||
.attr(RecoilAttr),
|
.attr(RecoilAttr)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.THRASH, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 1)
|
new AttackMove(Moves.THRASH, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 1)
|
||||||
.attr(FrenzyAttr)
|
.attr(FrenzyAttr)
|
||||||
.attr(MissEffectAttr, frenzyMissFunc)
|
.attr(MissEffectAttr, frenzyMissFunc)
|
||||||
.target(MoveTarget.RANDOM_NEAR_ENEMY),
|
.target(MoveTarget.RANDOM_NEAR_ENEMY),
|
||||||
new AttackMove(Moves.DOUBLE_EDGE, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 1)
|
new AttackMove(Moves.DOUBLE_EDGE, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 1)
|
||||||
.attr(RecoilAttr, false, 0.33),
|
.attr(RecoilAttr, false, 0.33)
|
||||||
|
.recklessMove(),
|
||||||
new StatusMove(Moves.TAIL_WHIP, Type.NORMAL, 100, 30, -1, 0, 1)
|
new StatusMove(Moves.TAIL_WHIP, Type.NORMAL, 100, 30, -1, 0, 1)
|
||||||
.attr(StatChangeAttr, BattleStat.DEF, -1)
|
.attr(StatChangeAttr, BattleStat.DEF, -1)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
@ -4134,7 +4243,8 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.PECK, Type.FLYING, MoveCategory.PHYSICAL, 35, 100, 35, -1, 0, 1),
|
new AttackMove(Moves.PECK, Type.FLYING, MoveCategory.PHYSICAL, 35, 100, 35, -1, 0, 1),
|
||||||
new AttackMove(Moves.DRILL_PECK, Type.FLYING, MoveCategory.PHYSICAL, 80, 100, 20, -1, 0, 1),
|
new AttackMove(Moves.DRILL_PECK, Type.FLYING, MoveCategory.PHYSICAL, 80, 100, 20, -1, 0, 1),
|
||||||
new AttackMove(Moves.SUBMISSION, Type.FIGHTING, MoveCategory.PHYSICAL, 80, 80, 20, -1, 0, 1)
|
new AttackMove(Moves.SUBMISSION, Type.FIGHTING, MoveCategory.PHYSICAL, 80, 80, 20, -1, 0, 1)
|
||||||
.attr(RecoilAttr),
|
.attr(RecoilAttr)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.LOW_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, -1, 100, 20, -1, 0, 1)
|
new AttackMove(Moves.LOW_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, -1, 100, 20, -1, 0, 1)
|
||||||
.attr(WeightPowerAttr)
|
.attr(WeightPowerAttr)
|
||||||
.condition(failOnMaxCondition),
|
.condition(failOnMaxCondition),
|
||||||
@ -4322,7 +4432,8 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.HIGH_JUMP_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 130, 90, 10, -1, 0, 1)
|
new AttackMove(Moves.HIGH_JUMP_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 130, 90, 10, -1, 0, 1)
|
||||||
.attr(MissEffectAttr, crashDamageFunc)
|
.attr(MissEffectAttr, crashDamageFunc)
|
||||||
.attr(NoEffectAttr, crashDamageFunc)
|
.attr(NoEffectAttr, crashDamageFunc)
|
||||||
.condition(failOnGravityCondition),
|
.condition(failOnGravityCondition)
|
||||||
|
.recklessMove(),
|
||||||
new StatusMove(Moves.GLARE, Type.NORMAL, 100, 30, -1, 0, 1)
|
new StatusMove(Moves.GLARE, Type.NORMAL, 100, 30, -1, 0, 1)
|
||||||
.attr(StatusEffectAttr, StatusEffect.PARALYSIS),
|
.attr(StatusEffectAttr, StatusEffect.PARALYSIS),
|
||||||
new AttackMove(Moves.DREAM_EATER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 15, -1, 0, 1)
|
new AttackMove(Moves.DREAM_EATER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 15, -1, 0, 1)
|
||||||
@ -4547,9 +4658,9 @@ export function initMoves() {
|
|||||||
.condition((user, target, move) => user.status?.effect === StatusEffect.SLEEP)
|
.condition((user, target, move) => user.status?.effect === StatusEffect.SLEEP)
|
||||||
.ignoresVirtual(),
|
.ignoresVirtual(),
|
||||||
new StatusMove(Moves.HEAL_BELL, Type.NORMAL, -1, 5, -1, 0, 2)
|
new StatusMove(Moves.HEAL_BELL, Type.NORMAL, -1, 5, -1, 0, 2)
|
||||||
|
.attr(PartyStatusCureAttr, "A bell chimed!", Abilities.SOUNDPROOF)
|
||||||
.soundBased()
|
.soundBased()
|
||||||
.target(MoveTarget.USER_AND_ALLIES)
|
.target(MoveTarget.PARTY),
|
||||||
.unimplemented(),
|
|
||||||
new AttackMove(Moves.RETURN, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 20, -1, 0, 2)
|
new AttackMove(Moves.RETURN, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 20, -1, 0, 2)
|
||||||
.attr(FriendshipPowerAttr),
|
.attr(FriendshipPowerAttr),
|
||||||
new AttackMove(Moves.PRESENT, Type.NORMAL, MoveCategory.PHYSICAL, -1, 90, 15, -1, 0, 2)
|
new AttackMove(Moves.PRESENT, Type.NORMAL, MoveCategory.PHYSICAL, -1, 90, 15, -1, 0, 2)
|
||||||
@ -4602,7 +4713,7 @@ export function initMoves() {
|
|||||||
BattlerTagType.SEEDED,
|
BattlerTagType.SEEDED,
|
||||||
BattlerTagType.INFESTATION
|
BattlerTagType.INFESTATION
|
||||||
], true)
|
], true)
|
||||||
.partial(),
|
.attr(RemoveArenaTrapAttr),
|
||||||
new StatusMove(Moves.SWEET_SCENT, Type.NORMAL, 100, 20, -1, 0, 2)
|
new StatusMove(Moves.SWEET_SCENT, Type.NORMAL, 100, 20, -1, 0, 2)
|
||||||
.attr(StatChangeAttr, BattleStat.EVA, -1)
|
.attr(StatChangeAttr, BattleStat.EVA, -1)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
@ -4709,7 +4820,7 @@ export function initMoves() {
|
|||||||
.ignoresVirtual(),
|
.ignoresVirtual(),
|
||||||
new SelfStatusMove(Moves.CHARGE, Type.ELECTRIC, -1, 20, -1, 0, 3)
|
new SelfStatusMove(Moves.CHARGE, Type.ELECTRIC, -1, 20, -1, 0, 3)
|
||||||
.attr(StatChangeAttr, BattleStat.SPDEF, 1, true)
|
.attr(StatChangeAttr, BattleStat.SPDEF, 1, true)
|
||||||
.attr(AddBattlerTagAttr, BattlerTagType.CHARGED, true, true),
|
.attr(AddBattlerTagAttr, BattlerTagType.CHARGED, true, false),
|
||||||
new StatusMove(Moves.TAUNT, Type.DARK, 100, 20, -1, 0, 3)
|
new StatusMove(Moves.TAUNT, Type.DARK, 100, 20, -1, 0, 3)
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new StatusMove(Moves.HELPING_HAND, Type.NORMAL, -1, 20, -1, 5, 3)
|
new StatusMove(Moves.HELPING_HAND, Type.NORMAL, -1, 20, -1, 5, 3)
|
||||||
@ -4820,8 +4931,8 @@ export function initMoves() {
|
|||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => [WeatherType.SUNNY, WeatherType.RAIN, WeatherType.SANDSTORM, WeatherType.HAIL, WeatherType.SNOW, WeatherType.FOG, WeatherType.HEAVY_RAIN, WeatherType.HARSH_SUN].includes(user.scene.arena.weather?.weatherType) && !user.scene.arena.weather?.isEffectSuppressed(user.scene) ? 2 : 1)
|
.attr(MovePowerMultiplierAttr, (user, target, move) => [WeatherType.SUNNY, WeatherType.RAIN, WeatherType.SANDSTORM, WeatherType.HAIL, WeatherType.SNOW, WeatherType.FOG, WeatherType.HEAVY_RAIN, WeatherType.HARSH_SUN].includes(user.scene.arena.weather?.weatherType) && !user.scene.arena.weather?.isEffectSuppressed(user.scene) ? 2 : 1)
|
||||||
.ballBombMove(),
|
.ballBombMove(),
|
||||||
new StatusMove(Moves.AROMATHERAPY, Type.GRASS, -1, 5, -1, 0, 3)
|
new StatusMove(Moves.AROMATHERAPY, Type.GRASS, -1, 5, -1, 0, 3)
|
||||||
.target(MoveTarget.USER_AND_ALLIES)
|
.attr(PartyStatusCureAttr, "A soothing aroma wafted through the area!", Abilities.SAP_SIPPER)
|
||||||
.unimplemented(),
|
.target(MoveTarget.PARTY),
|
||||||
new StatusMove(Moves.FAKE_TEARS, Type.DARK, 100, 20, -1, 0, 3)
|
new StatusMove(Moves.FAKE_TEARS, Type.DARK, 100, 20, -1, 0, 3)
|
||||||
.attr(StatChangeAttr, BattleStat.SPDEF, -2),
|
.attr(StatChangeAttr, BattleStat.SPDEF, -2),
|
||||||
new AttackMove(Moves.AIR_CUTTER, Type.FLYING, MoveCategory.SPECIAL, 60, 95, 25, -1, 0, 3)
|
new AttackMove(Moves.AIR_CUTTER, Type.FLYING, MoveCategory.SPECIAL, 60, 95, 25, -1, 0, 3)
|
||||||
@ -4907,7 +5018,8 @@ export function initMoves() {
|
|||||||
.attr(StealHeldItemChanceAttr, 0.3),
|
.attr(StealHeldItemChanceAttr, 0.3),
|
||||||
new AttackMove(Moves.VOLT_TACKLE, Type.ELECTRIC, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 3)
|
new AttackMove(Moves.VOLT_TACKLE, Type.ELECTRIC, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 3)
|
||||||
.attr(RecoilAttr, false, 0.33)
|
.attr(RecoilAttr, false, 0.33)
|
||||||
.attr(StatusEffectAttr, StatusEffect.PARALYSIS),
|
.attr(StatusEffectAttr, StatusEffect.PARALYSIS)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.MAGICAL_LEAF, Type.GRASS, MoveCategory.SPECIAL, 60, -1, 20, -1, 0, 3),
|
new AttackMove(Moves.MAGICAL_LEAF, Type.GRASS, MoveCategory.SPECIAL, 60, -1, 20, -1, 0, 3),
|
||||||
new StatusMove(Moves.WATER_SPORT, Type.WATER, -1, 15, -1, 0, 3)
|
new StatusMove(Moves.WATER_SPORT, Type.WATER, -1, 15, -1, 0, 3)
|
||||||
.attr(AddArenaTagAttr, ArenaTagType.WATER_SPORT, 5)
|
.attr(AddArenaTagAttr, ArenaTagType.WATER_SPORT, 5)
|
||||||
@ -5050,7 +5162,7 @@ export function initMoves() {
|
|||||||
.attr(RecoilAttr, false, 0.33)
|
.attr(RecoilAttr, false, 0.33)
|
||||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||||
.attr(StatusEffectAttr, StatusEffect.BURN)
|
.attr(StatusEffectAttr, StatusEffect.BURN)
|
||||||
.condition(failOnGravityCondition),
|
.recklessMove(),
|
||||||
new AttackMove(Moves.FORCE_PALM, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, 30, 0, 4)
|
new AttackMove(Moves.FORCE_PALM, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, 30, 0, 4)
|
||||||
.attr(StatusEffectAttr, StatusEffect.PARALYSIS),
|
.attr(StatusEffectAttr, StatusEffect.PARALYSIS),
|
||||||
new AttackMove(Moves.AURA_SPHERE, Type.FIGHTING, MoveCategory.SPECIAL, 80, -1, 20, -1, 0, 4)
|
new AttackMove(Moves.AURA_SPHERE, Type.FIGHTING, MoveCategory.SPECIAL, 80, -1, 20, -1, 0, 4)
|
||||||
@ -5095,7 +5207,8 @@ export function initMoves() {
|
|||||||
.attr(StatChangeAttr, BattleStat.SPDEF, -1)
|
.attr(StatChangeAttr, BattleStat.SPDEF, -1)
|
||||||
.ballBombMove(),
|
.ballBombMove(),
|
||||||
new AttackMove(Moves.BRAVE_BIRD, Type.FLYING, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 4)
|
new AttackMove(Moves.BRAVE_BIRD, Type.FLYING, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 4)
|
||||||
.attr(RecoilAttr, false, 0.33),
|
.attr(RecoilAttr, false, 0.33)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.EARTH_POWER, Type.GROUND, MoveCategory.SPECIAL, 90, 100, 10, 10, 0, 4)
|
new AttackMove(Moves.EARTH_POWER, Type.GROUND, MoveCategory.SPECIAL, 90, 100, 10, 10, 0, 4)
|
||||||
.attr(StatChangeAttr, BattleStat.SPDEF, -1),
|
.attr(StatChangeAttr, BattleStat.SPDEF, -1),
|
||||||
new StatusMove(Moves.SWITCHEROO, Type.DARK, 100, 10, -1, 0, 4)
|
new StatusMove(Moves.SWITCHEROO, Type.DARK, 100, 10, -1, 0, 4)
|
||||||
@ -5144,7 +5257,8 @@ export function initMoves() {
|
|||||||
.attr(StatChangeAttr, BattleStat.EVA, -1)
|
.attr(StatChangeAttr, BattleStat.EVA, -1)
|
||||||
.attr(ClearWeatherAttr, WeatherType.FOG)
|
.attr(ClearWeatherAttr, WeatherType.FOG)
|
||||||
.attr(ClearTerrainAttr)
|
.attr(ClearTerrainAttr)
|
||||||
.attr(RemoveScreensAttr, true),
|
.attr(RemoveScreensAttr, false)
|
||||||
|
.attr(RemoveArenaTrapAttr, true),
|
||||||
new StatusMove(Moves.TRICK_ROOM, Type.PSYCHIC, -1, 5, -1, -7, 4)
|
new StatusMove(Moves.TRICK_ROOM, Type.PSYCHIC, -1, 5, -1, -7, 4)
|
||||||
.attr(AddArenaTagAttr, ArenaTagType.TRICK_ROOM, 5)
|
.attr(AddArenaTagAttr, ArenaTagType.TRICK_ROOM, 5)
|
||||||
.ignoresProtect()
|
.ignoresProtect()
|
||||||
@ -5200,7 +5314,8 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.CHARGE_BEAM, Type.ELECTRIC, MoveCategory.SPECIAL, 50, 90, 10, 70, 0, 4)
|
new AttackMove(Moves.CHARGE_BEAM, Type.ELECTRIC, MoveCategory.SPECIAL, 50, 90, 10, 70, 0, 4)
|
||||||
.attr(StatChangeAttr, BattleStat.SPATK, 1, true),
|
.attr(StatChangeAttr, BattleStat.SPATK, 1, true),
|
||||||
new AttackMove(Moves.WOOD_HAMMER, Type.GRASS, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 4)
|
new AttackMove(Moves.WOOD_HAMMER, Type.GRASS, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 4)
|
||||||
.attr(RecoilAttr, false, 0.33),
|
.attr(RecoilAttr, false, 0.33)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.AQUA_JET, Type.WATER, MoveCategory.PHYSICAL, 40, 100, 20, -1, 1, 4),
|
new AttackMove(Moves.AQUA_JET, Type.WATER, MoveCategory.PHYSICAL, 40, 100, 20, -1, 1, 4),
|
||||||
new AttackMove(Moves.ATTACK_ORDER, Type.BUG, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 4)
|
new AttackMove(Moves.ATTACK_ORDER, Type.BUG, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 4)
|
||||||
.attr(HighCritAttr)
|
.attr(HighCritAttr)
|
||||||
@ -5211,7 +5326,8 @@ export function initMoves() {
|
|||||||
.attr(HealAttr, 0.5)
|
.attr(HealAttr, 0.5)
|
||||||
.triageMove(),
|
.triageMove(),
|
||||||
new AttackMove(Moves.HEAD_SMASH, Type.ROCK, MoveCategory.PHYSICAL, 150, 80, 5, -1, 0, 4)
|
new AttackMove(Moves.HEAD_SMASH, Type.ROCK, MoveCategory.PHYSICAL, 150, 80, 5, -1, 0, 4)
|
||||||
.attr(RecoilAttr, false, 0.5),
|
.attr(RecoilAttr, false, 0.5)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.DOUBLE_HIT, Type.NORMAL, MoveCategory.PHYSICAL, 35, 90, 10, -1, 0, 4)
|
new AttackMove(Moves.DOUBLE_HIT, Type.NORMAL, MoveCategory.PHYSICAL, 35, 90, 10, -1, 0, 4)
|
||||||
.attr(MultiHitAttr, MultiHitType._2),
|
.attr(MultiHitAttr, MultiHitType._2),
|
||||||
new AttackMove(Moves.ROAR_OF_TIME, Type.DRAGON, MoveCategory.SPECIAL, 150, 90, 5, -1, 0, 4)
|
new AttackMove(Moves.ROAR_OF_TIME, Type.DRAGON, MoveCategory.SPECIAL, 150, 90, 5, -1, 0, 4)
|
||||||
@ -5399,7 +5515,8 @@ export function initMoves() {
|
|||||||
.attr(StatChangeAttr, BattleStat.SPD, -1)
|
.attr(StatChangeAttr, BattleStat.SPD, -1)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
new AttackMove(Moves.WILD_CHARGE, Type.ELECTRIC, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 5)
|
new AttackMove(Moves.WILD_CHARGE, Type.ELECTRIC, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 5)
|
||||||
.attr(RecoilAttr),
|
.attr(RecoilAttr)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.DRILL_RUN, Type.GROUND, MoveCategory.PHYSICAL, 80, 95, 10, -1, 0, 5)
|
new AttackMove(Moves.DRILL_RUN, Type.GROUND, MoveCategory.PHYSICAL, 80, 95, 10, -1, 0, 5)
|
||||||
.attr(HighCritAttr),
|
.attr(HighCritAttr),
|
||||||
new AttackMove(Moves.DUAL_CHOP, Type.DRAGON, MoveCategory.PHYSICAL, 40, 90, 15, -1, 0, 5)
|
new AttackMove(Moves.DUAL_CHOP, Type.DRAGON, MoveCategory.PHYSICAL, 40, 90, 15, -1, 0, 5)
|
||||||
@ -5436,7 +5553,8 @@ export function initMoves() {
|
|||||||
.attr(HitsTagAttr, BattlerTagType.FLYING, false)
|
.attr(HitsTagAttr, BattlerTagType.FLYING, false)
|
||||||
.windMove(),
|
.windMove(),
|
||||||
new AttackMove(Moves.HEAD_CHARGE, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 5)
|
new AttackMove(Moves.HEAD_CHARGE, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 5)
|
||||||
.attr(RecoilAttr),
|
.attr(RecoilAttr)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.GEAR_GRIND, Type.STEEL, MoveCategory.PHYSICAL, 50, 85, 15, -1, 0, 5)
|
new AttackMove(Moves.GEAR_GRIND, Type.STEEL, MoveCategory.PHYSICAL, 50, 85, 15, -1, 0, 5)
|
||||||
.attr(MultiHitAttr, MultiHitType._2),
|
.attr(MultiHitAttr, MultiHitType._2),
|
||||||
new AttackMove(Moves.SEARING_SHOT, Type.FIRE, MoveCategory.SPECIAL, 100, 100, 5, 30, 0, 5)
|
new AttackMove(Moves.SEARING_SHOT, Type.FIRE, MoveCategory.SPECIAL, 100, 100, 5, 30, 0, 5)
|
||||||
@ -5499,7 +5617,7 @@ export function initMoves() {
|
|||||||
.attr(AddArenaTrapTagAttr, ArenaTagType.STICKY_WEB)
|
.attr(AddArenaTrapTagAttr, ArenaTagType.STICKY_WEB)
|
||||||
.target(MoveTarget.ENEMY_SIDE),
|
.target(MoveTarget.ENEMY_SIDE),
|
||||||
new AttackMove(Moves.FELL_STINGER, Type.BUG, MoveCategory.PHYSICAL, 50, 100, 25, -1, 0, 6)
|
new AttackMove(Moves.FELL_STINGER, Type.BUG, MoveCategory.PHYSICAL, 50, 100, 25, -1, 0, 6)
|
||||||
.partial(),
|
.attr(PostVictoryStatChangeAttr, BattleStat.ATK, 3, true ),
|
||||||
new AttackMove(Moves.PHANTOM_FORCE, Type.GHOST, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6)
|
new AttackMove(Moves.PHANTOM_FORCE, Type.GHOST, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6)
|
||||||
.attr(ChargeAttr, ChargeAnim.PHANTOM_FORCE_CHARGING, 'vanished\ninstantly!', BattlerTagType.HIDDEN)
|
.attr(ChargeAttr, ChargeAnim.PHANTOM_FORCE_CHARGING, 'vanished\ninstantly!', BattlerTagType.HIDDEN)
|
||||||
.ignoresProtect()
|
.ignoresProtect()
|
||||||
@ -5650,7 +5768,8 @@ export function initMoves() {
|
|||||||
.makesContact(false)
|
.makesContact(false)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
new AttackMove(Moves.LIGHT_OF_RUIN, Type.FAIRY, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 6)
|
new AttackMove(Moves.LIGHT_OF_RUIN, Type.FAIRY, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 6)
|
||||||
.attr(RecoilAttr, false, 0.5),
|
.attr(RecoilAttr, false, 0.5)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.ORIGIN_PULSE, Type.WATER, MoveCategory.SPECIAL, 110, 85, 10, -1, 0, 6)
|
new AttackMove(Moves.ORIGIN_PULSE, Type.WATER, MoveCategory.SPECIAL, 110, 85, 10, -1, 0, 6)
|
||||||
.pulseMove()
|
.pulseMove()
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
@ -5664,79 +5783,116 @@ export function initMoves() {
|
|||||||
.ignoresProtect(),
|
.ignoresProtect(),
|
||||||
/* Unused */
|
/* Unused */
|
||||||
new AttackMove(Moves.BREAKNECK_BLITZ__PHYSICAL, Type.NORMAL, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.BREAKNECK_BLITZ__PHYSICAL, Type.NORMAL, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.BREAKNECK_BLITZ__SPECIAL, Type.NORMAL, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.BREAKNECK_BLITZ__SPECIAL, Type.NORMAL, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.ALL_OUT_PUMMELING__PHYSICAL, Type.FIGHTING, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.ALL_OUT_PUMMELING__PHYSICAL, Type.FIGHTING, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.ALL_OUT_PUMMELING__SPECIAL, Type.FIGHTING, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.ALL_OUT_PUMMELING__SPECIAL, Type.FIGHTING, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SUPERSONIC_SKYSTRIKE__PHYSICAL, Type.FLYING, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SUPERSONIC_SKYSTRIKE__PHYSICAL, Type.FLYING, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SUPERSONIC_SKYSTRIKE__SPECIAL, Type.FLYING, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SUPERSONIC_SKYSTRIKE__SPECIAL, Type.FLYING, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.ACID_DOWNPOUR__PHYSICAL, Type.POISON, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.ACID_DOWNPOUR__PHYSICAL, Type.POISON, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.ACID_DOWNPOUR__SPECIAL, Type.POISON, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.ACID_DOWNPOUR__SPECIAL, Type.POISON, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.TECTONIC_RAGE__PHYSICAL, Type.GROUND, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.TECTONIC_RAGE__PHYSICAL, Type.GROUND, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.TECTONIC_RAGE__SPECIAL, Type.GROUND, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.TECTONIC_RAGE__SPECIAL, Type.GROUND, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.CONTINENTAL_CRUSH__PHYSICAL, Type.ROCK, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.CONTINENTAL_CRUSH__PHYSICAL, Type.ROCK, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.CONTINENTAL_CRUSH__SPECIAL, Type.ROCK, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.CONTINENTAL_CRUSH__SPECIAL, Type.ROCK, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SAVAGE_SPIN_OUT__PHYSICAL, Type.BUG, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SAVAGE_SPIN_OUT__PHYSICAL, Type.BUG, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SAVAGE_SPIN_OUT__SPECIAL, Type.BUG, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SAVAGE_SPIN_OUT__SPECIAL, Type.BUG, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.NEVER_ENDING_NIGHTMARE__PHYSICAL, Type.GHOST, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.NEVER_ENDING_NIGHTMARE__PHYSICAL, Type.GHOST, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.NEVER_ENDING_NIGHTMARE__SPECIAL, Type.GHOST, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.NEVER_ENDING_NIGHTMARE__SPECIAL, Type.GHOST, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.CORKSCREW_CRASH__PHYSICAL, Type.STEEL, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.CORKSCREW_CRASH__PHYSICAL, Type.STEEL, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.CORKSCREW_CRASH__SPECIAL, Type.STEEL, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.CORKSCREW_CRASH__SPECIAL, Type.STEEL, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.INFERNO_OVERDRIVE__PHYSICAL, Type.FIRE, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.INFERNO_OVERDRIVE__PHYSICAL, Type.FIRE, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.INFERNO_OVERDRIVE__SPECIAL, Type.FIRE, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.INFERNO_OVERDRIVE__SPECIAL, Type.FIRE, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.HYDRO_VORTEX__PHYSICAL, Type.WATER, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.HYDRO_VORTEX__PHYSICAL, Type.WATER, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.HYDRO_VORTEX__SPECIAL, Type.WATER, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.HYDRO_VORTEX__SPECIAL, Type.WATER, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.BLOOM_DOOM__PHYSICAL, Type.GRASS, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.BLOOM_DOOM__PHYSICAL, Type.GRASS, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.BLOOM_DOOM__SPECIAL, Type.GRASS, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.BLOOM_DOOM__SPECIAL, Type.GRASS, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.GIGAVOLT_HAVOC__PHYSICAL, Type.ELECTRIC, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.GIGAVOLT_HAVOC__PHYSICAL, Type.ELECTRIC, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.GIGAVOLT_HAVOC__SPECIAL, Type.ELECTRIC, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.GIGAVOLT_HAVOC__SPECIAL, Type.ELECTRIC, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SHATTERED_PSYCHE__PHYSICAL, Type.PSYCHIC, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SHATTERED_PSYCHE__PHYSICAL, Type.PSYCHIC, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SHATTERED_PSYCHE__SPECIAL, Type.PSYCHIC, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SHATTERED_PSYCHE__SPECIAL, Type.PSYCHIC, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SUBZERO_SLAMMER__PHYSICAL, Type.ICE, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SUBZERO_SLAMMER__PHYSICAL, Type.ICE, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SUBZERO_SLAMMER__SPECIAL, Type.ICE, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SUBZERO_SLAMMER__SPECIAL, Type.ICE, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.DEVASTATING_DRAKE__PHYSICAL, Type.DRAGON, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.DEVASTATING_DRAKE__PHYSICAL, Type.DRAGON, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.DEVASTATING_DRAKE__SPECIAL, Type.DRAGON, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.DEVASTATING_DRAKE__SPECIAL, Type.DRAGON, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.BLACK_HOLE_ECLIPSE__PHYSICAL, Type.DARK, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.BLACK_HOLE_ECLIPSE__PHYSICAL, Type.DARK, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.BLACK_HOLE_ECLIPSE__SPECIAL, Type.DARK, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.BLACK_HOLE_ECLIPSE__SPECIAL, Type.DARK, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.TWINKLE_TACKLE__PHYSICAL, Type.FAIRY, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.TWINKLE_TACKLE__PHYSICAL, Type.FAIRY, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.TWINKLE_TACKLE__SPECIAL, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.TWINKLE_TACKLE__SPECIAL, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.CATASTROPIKA, Type.ELECTRIC, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.CATASTROPIKA, Type.ELECTRIC, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
/* End Unused */
|
/* End Unused */
|
||||||
new SelfStatusMove(Moves.SHORE_UP, Type.GROUND, -1, 5, -1, 0, 7)
|
new SelfStatusMove(Moves.SHORE_UP, Type.GROUND, -1, 5, -1, 0, 7)
|
||||||
.attr(SandHealAttr)
|
.attr(SandHealAttr)
|
||||||
@ -5844,23 +6000,32 @@ export function initMoves() {
|
|||||||
/* Unused */
|
/* Unused */
|
||||||
new AttackMove(Moves.SINISTER_ARROW_RAID, Type.GHOST, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SINISTER_ARROW_RAID, Type.GHOST, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7)
|
||||||
.makesContact(false)
|
.makesContact(false)
|
||||||
.partial(),
|
.partial()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MALICIOUS_MOONSAULT, Type.DARK, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.MALICIOUS_MOONSAULT, Type.DARK, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7)
|
||||||
.partial(),
|
.partial()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.OCEANIC_OPERETTA, Type.WATER, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.OCEANIC_OPERETTA, Type.WATER, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
|
||||||
.partial(),
|
.partial()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.GUARDIAN_OF_ALOLA, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.GUARDIAN_OF_ALOLA, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SOUL_STEALING_7_STAR_STRIKE, Type.GHOST, MoveCategory.PHYSICAL, 195, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SOUL_STEALING_7_STAR_STRIKE, Type.GHOST, MoveCategory.PHYSICAL, 195, -1, 1, -1, 0, 7)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.STOKED_SPARKSURFER, Type.ELECTRIC, MoveCategory.SPECIAL, 175, -1, 1, 100, 0, 7)
|
new AttackMove(Moves.STOKED_SPARKSURFER, Type.ELECTRIC, MoveCategory.SPECIAL, 175, -1, 1, 100, 0, 7)
|
||||||
.partial(),
|
.partial()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.PULVERIZING_PANCAKE, Type.NORMAL, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.PULVERIZING_PANCAKE, Type.NORMAL, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7)
|
||||||
.partial(),
|
.partial()
|
||||||
|
.ignoresVirtual(),
|
||||||
new SelfStatusMove(Moves.EXTREME_EVOBOOST, Type.NORMAL, -1, 1, 100, 0, 7)
|
new SelfStatusMove(Moves.EXTREME_EVOBOOST, Type.NORMAL, -1, 1, 100, 0, 7)
|
||||||
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 2, true),
|
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 2, true)
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.GENESIS_SUPERNOVA, Type.PSYCHIC, MoveCategory.SPECIAL, 185, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.GENESIS_SUPERNOVA, Type.PSYCHIC, MoveCategory.SPECIAL, 185, -1, 1, -1, 0, 7)
|
||||||
.attr(TerrainChangeAttr, TerrainType.PSYCHIC),
|
.attr(TerrainChangeAttr, TerrainType.PSYCHIC)
|
||||||
|
.ignoresVirtual(),
|
||||||
/* End Unused */
|
/* End Unused */
|
||||||
new AttackMove(Moves.SHELL_TRAP, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, -3, 7)
|
new AttackMove(Moves.SHELL_TRAP, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, -3, 7)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
||||||
@ -5898,7 +6063,8 @@ export function initMoves() {
|
|||||||
.partial(),
|
.partial(),
|
||||||
/* Unused */
|
/* Unused */
|
||||||
new AttackMove(Moves.TEN_MILLION_VOLT_THUNDERBOLT, Type.ELECTRIC, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.TEN_MILLION_VOLT_THUNDERBOLT, Type.ELECTRIC, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
|
||||||
.partial(),
|
.partial()
|
||||||
|
.ignoresVirtual(),
|
||||||
/* End Unused */
|
/* End Unused */
|
||||||
new AttackMove(Moves.MIND_BLOWN, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 7)
|
new AttackMove(Moves.MIND_BLOWN, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 7)
|
||||||
.condition(failIfDampCondition)
|
.condition(failIfDampCondition)
|
||||||
@ -5914,21 +6080,27 @@ export function initMoves() {
|
|||||||
/* Unused */
|
/* Unused */
|
||||||
new AttackMove(Moves.LIGHT_THAT_BURNS_THE_SKY, Type.PSYCHIC, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.LIGHT_THAT_BURNS_THE_SKY, Type.PSYCHIC, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7)
|
||||||
.attr(PhotonGeyserCategoryAttr)
|
.attr(PhotonGeyserCategoryAttr)
|
||||||
.ignoresAbilities(),
|
.ignoresAbilities()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SEARING_SUNRAZE_SMASH, Type.STEEL, MoveCategory.PHYSICAL, 200, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SEARING_SUNRAZE_SMASH, Type.STEEL, MoveCategory.PHYSICAL, 200, -1, 1, -1, 0, 7)
|
||||||
.ignoresAbilities(),
|
.ignoresAbilities()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MENACING_MOONRAZE_MAELSTROM, Type.GHOST, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.MENACING_MOONRAZE_MAELSTROM, Type.GHOST, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7)
|
||||||
.ignoresAbilities(),
|
.ignoresAbilities()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.LETS_SNUGGLE_FOREVER, Type.FAIRY, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.LETS_SNUGGLE_FOREVER, Type.FAIRY, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7)
|
||||||
.partial(),
|
.partial()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.SPLINTERED_STORMSHARDS, Type.ROCK, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7)
|
new AttackMove(Moves.SPLINTERED_STORMSHARDS, Type.ROCK, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7)
|
||||||
.attr(ClearTerrainAttr)
|
.attr(ClearTerrainAttr)
|
||||||
.makesContact(false),
|
.makesContact(false)
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.CLANGOROUS_SOULBLAZE, Type.DRAGON, MoveCategory.SPECIAL, 185, -1, 1, 100, 0, 7)
|
new AttackMove(Moves.CLANGOROUS_SOULBLAZE, Type.DRAGON, MoveCategory.SPECIAL, 185, -1, 1, 100, 0, 7)
|
||||||
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, true)
|
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, true)
|
||||||
.soundBased()
|
.soundBased()
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
||||||
.partial(),
|
.partial()
|
||||||
|
.ignoresVirtual(),
|
||||||
/* End Unused */
|
/* End Unused */
|
||||||
new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 100, 2, 7)
|
new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 100, 2, 7)
|
||||||
.attr(CritOnlyAttr),
|
.attr(CritOnlyAttr),
|
||||||
@ -5941,7 +6113,8 @@ export function initMoves() {
|
|||||||
.attr(FriendshipPowerAttr),
|
.attr(FriendshipPowerAttr),
|
||||||
new AttackMove(Moves.BOUNCY_BUBBLE, Type.WATER, MoveCategory.SPECIAL, 60, 100, 20, -1, 0, 7)
|
new AttackMove(Moves.BOUNCY_BUBBLE, Type.WATER, MoveCategory.SPECIAL, 60, 100, 20, -1, 0, 7)
|
||||||
.attr(HitHealAttr, 1.0)
|
.attr(HitHealAttr, 1.0)
|
||||||
.triageMove(),
|
.triageMove()
|
||||||
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
new AttackMove(Moves.BUZZY_BUZZ, Type.ELECTRIC, MoveCategory.SPECIAL, 60, 100, 20, 100, 0, 7)
|
new AttackMove(Moves.BUZZY_BUZZ, Type.ELECTRIC, MoveCategory.SPECIAL, 60, 100, 20, 100, 0, 7)
|
||||||
.attr(StatusEffectAttr, StatusEffect.PARALYSIS),
|
.attr(StatusEffectAttr, StatusEffect.PARALYSIS),
|
||||||
new AttackMove(Moves.SIZZLY_SLIDE, Type.FIRE, MoveCategory.PHYSICAL, 60, 100, 20, 100, 0, 7)
|
new AttackMove(Moves.SIZZLY_SLIDE, Type.FIRE, MoveCategory.PHYSICAL, 60, 100, 20, 100, 0, 7)
|
||||||
@ -5964,7 +6137,8 @@ export function initMoves() {
|
|||||||
.punchingMove(),
|
.punchingMove(),
|
||||||
/* Unused */
|
/* Unused */
|
||||||
new SelfStatusMove(Moves.MAX_GUARD, Type.NORMAL, -1, 10, -1, 4, 8)
|
new SelfStatusMove(Moves.MAX_GUARD, Type.NORMAL, -1, 10, -1, 4, 8)
|
||||||
.attr(ProtectAttr),
|
.attr(ProtectAttr)
|
||||||
|
.ignoresVirtual(),
|
||||||
/* End Unused */
|
/* End Unused */
|
||||||
new AttackMove(Moves.DYNAMAX_CANNON, Type.DRAGON, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 8)
|
new AttackMove(Moves.DYNAMAX_CANNON, Type.DRAGON, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 8)
|
||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => target.level > 200 ? 2 : 1)
|
.attr(MovePowerMultiplierAttr, (user, target, move) => target.level > 200 ? 2 : 1)
|
||||||
@ -6008,58 +6182,76 @@ export function initMoves() {
|
|||||||
/* Unused */
|
/* Unused */
|
||||||
new AttackMove(Moves.MAX_FLARE, Type.FIRE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_FLARE, Type.FIRE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_FLUTTERBY, Type.BUG, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_FLUTTERBY, Type.BUG, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_LIGHTNING, Type.ELECTRIC, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_LIGHTNING, Type.ELECTRIC, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_STRIKE, Type.NORMAL, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_STRIKE, Type.NORMAL, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_KNUCKLE, Type.FIGHTING, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_KNUCKLE, Type.FIGHTING, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_PHANTASM, Type.GHOST, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_PHANTASM, Type.GHOST, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_HAILSTORM, Type.ICE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_HAILSTORM, Type.ICE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_OOZE, Type.POISON, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_OOZE, Type.POISON, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_GEYSER, Type.WATER, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_GEYSER, Type.WATER, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_AIRSTREAM, Type.FLYING, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_AIRSTREAM, Type.FLYING, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_STARFALL, Type.FAIRY, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_STARFALL, Type.FAIRY, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_WYRMWIND, Type.DRAGON, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_WYRMWIND, Type.DRAGON, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_MINDSTORM, Type.PSYCHIC, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_MINDSTORM, Type.PSYCHIC, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_ROCKFALL, Type.ROCK, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_ROCKFALL, Type.ROCK, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_QUAKE, Type.GROUND, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_QUAKE, Type.GROUND, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_DARKNESS, Type.DARK, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_DARKNESS, Type.DARK, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_OVERGROWTH, Type.GRASS, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_OVERGROWTH, Type.GRASS, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
new AttackMove(Moves.MAX_STEELSPIKE, Type.STEEL, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
new AttackMove(Moves.MAX_STEELSPIKE, Type.STEEL, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
|
||||||
.target(MoveTarget.NEAR_ENEMY)
|
.target(MoveTarget.NEAR_ENEMY)
|
||||||
.unimplemented(),
|
.unimplemented()
|
||||||
|
.ignoresVirtual(),
|
||||||
/* End Unused */
|
/* End Unused */
|
||||||
new SelfStatusMove(Moves.CLANGOROUS_SOUL, Type.DRAGON, 100, 5, 100, 0, 8)
|
new SelfStatusMove(Moves.CLANGOROUS_SOUL, Type.DRAGON, 100, 5, 100, 0, 8)
|
||||||
.attr(CutHpStatBoostAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, 3)
|
.attr(CutHpStatBoostAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, 3)
|
||||||
@ -6230,7 +6422,8 @@ export function initMoves() {
|
|||||||
.attr(MissEffectAttr, frenzyMissFunc)
|
.attr(MissEffectAttr, frenzyMissFunc)
|
||||||
.target(MoveTarget.RANDOM_NEAR_ENEMY),
|
.target(MoveTarget.RANDOM_NEAR_ENEMY),
|
||||||
new AttackMove(Moves.WAVE_CRASH, Type.WATER, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 8)
|
new AttackMove(Moves.WAVE_CRASH, Type.WATER, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 8)
|
||||||
.attr(RecoilAttr, false, 0.33),
|
.attr(RecoilAttr, false, 0.33)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.CHLOROBLAST, Type.GRASS, MoveCategory.SPECIAL, 150, 95, 5, -1, 0, 8)
|
new AttackMove(Moves.CHLOROBLAST, Type.GRASS, MoveCategory.SPECIAL, 150, 95, 5, -1, 0, 8)
|
||||||
.attr(RecoilAttr, true, 0.5),
|
.attr(RecoilAttr, true, 0.5),
|
||||||
new AttackMove(Moves.MOUNTAIN_GALE, Type.ICE, MoveCategory.PHYSICAL, 100, 85, 10, 30, 0, 8)
|
new AttackMove(Moves.MOUNTAIN_GALE, Type.ICE, MoveCategory.PHYSICAL, 100, 85, 10, 30, 0, 8)
|
||||||
@ -6394,7 +6587,8 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.AXE_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 90, 10, 30, 0, 9)
|
new AttackMove(Moves.AXE_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 90, 10, 30, 0, 9)
|
||||||
.attr(MissEffectAttr, crashDamageFunc)
|
.attr(MissEffectAttr, crashDamageFunc)
|
||||||
.attr(NoEffectAttr, crashDamageFunc)
|
.attr(NoEffectAttr, crashDamageFunc)
|
||||||
.attr(ConfuseAttr),
|
.attr(ConfuseAttr)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.LAST_RESPECTS, Type.GHOST, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 9)
|
new AttackMove(Moves.LAST_RESPECTS, Type.GHOST, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 9)
|
||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => {
|
.attr(MovePowerMultiplierAttr, (user, target, move) => {
|
||||||
return user.scene.getParty().reduce((acc, pokemonInParty) => acc + (pokemonInParty.status?.effect == StatusEffect.FAINT ? 1 : 0),
|
return user.scene.getParty().reduce((acc, pokemonInParty) => acc + (pokemonInParty.status?.effect == StatusEffect.FAINT ? 1 : 0),
|
||||||
@ -6444,6 +6638,7 @@ export function initMoves() {
|
|||||||
BattlerTagType.INFESTATION
|
BattlerTagType.INFESTATION
|
||||||
], true)
|
], true)
|
||||||
.attr(StatusEffectAttr, StatusEffect.POISON)
|
.attr(StatusEffectAttr, StatusEffect.POISON)
|
||||||
|
.attr(RemoveArenaTrapAttr)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
new StatusMove(Moves.DOODLE, Type.NORMAL, 100, 10, -1, 0, 9)
|
new StatusMove(Moves.DOODLE, Type.NORMAL, 100, 10, -1, 0, 9)
|
||||||
.attr(AbilityCopyAttr, true),
|
.attr(AbilityCopyAttr, true),
|
||||||
@ -6487,7 +6682,7 @@ export function initMoves() {
|
|||||||
.target(MoveTarget.BOTH_SIDES),
|
.target(MoveTarget.BOTH_SIDES),
|
||||||
new SelfStatusMove(Moves.TIDY_UP, Type.NORMAL, -1, 10, 100, 0, 9)
|
new SelfStatusMove(Moves.TIDY_UP, Type.NORMAL, -1, 10, 100, 0, 9)
|
||||||
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.SPD ], 1, true)
|
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.SPD ], 1, true)
|
||||||
.partial(),
|
.attr(RemoveArenaTrapAttr),
|
||||||
new StatusMove(Moves.SNOWSCAPE, Type.ICE, -1, 10, -1, 0, 9)
|
new StatusMove(Moves.SNOWSCAPE, Type.ICE, -1, 10, -1, 0, 9)
|
||||||
.attr(WeatherChangeAttr, WeatherType.SNOW)
|
.attr(WeatherChangeAttr, WeatherType.SNOW)
|
||||||
.target(MoveTarget.BOTH_SIDES),
|
.target(MoveTarget.BOTH_SIDES),
|
||||||
@ -6575,7 +6770,7 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.FICKLE_BEAM, Type.DRAGON, MoveCategory.SPECIAL, 80, 100, 5, 30, 0, 9)
|
new AttackMove(Moves.FICKLE_BEAM, Type.DRAGON, MoveCategory.SPECIAL, 80, 100, 5, 30, 0, 9)
|
||||||
.attr(PreMoveMessageAttr, doublePowerChanceMessageFunc)
|
.attr(PreMoveMessageAttr, doublePowerChanceMessageFunc)
|
||||||
.attr(DoublePowerChanceAttr),
|
.attr(DoublePowerChanceAttr),
|
||||||
new StatusMove(Moves.BURNING_BULWARK, Type.FIRE, -1, 10, 100, 4, 9)
|
new SelfStatusMove(Moves.BURNING_BULWARK, Type.FIRE, -1, 10, 100, 4, 9)
|
||||||
.attr(ProtectAttr, BattlerTagType.BURNING_BULWARK),
|
.attr(ProtectAttr, BattlerTagType.BURNING_BULWARK),
|
||||||
new AttackMove(Moves.THUNDERCLAP, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 5, -1, 1, 9)
|
new AttackMove(Moves.THUNDERCLAP, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 5, -1, 1, 9)
|
||||||
.condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()].move.move].category !== MoveCategory.STATUS),
|
.condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()].move.move].category !== MoveCategory.STATUS),
|
||||||
@ -6592,12 +6787,14 @@ export function initMoves() {
|
|||||||
.target(MoveTarget.NEAR_ALLY)
|
.target(MoveTarget.NEAR_ALLY)
|
||||||
.partial(),
|
.partial(),
|
||||||
new AttackMove(Moves.ALLURING_VOICE, Type.FAIRY, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 9)
|
new AttackMove(Moves.ALLURING_VOICE, Type.FAIRY, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 9)
|
||||||
|
.soundBased()
|
||||||
.partial(),
|
.partial(),
|
||||||
new AttackMove(Moves.TEMPER_FLARE, Type.FIRE, MoveCategory.PHYSICAL, 75, 100, 10, -1, 0, 9)
|
new AttackMove(Moves.TEMPER_FLARE, Type.FIRE, MoveCategory.PHYSICAL, 75, 100, 10, -1, 0, 9)
|
||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => user.getLastXMoves(2)[1]?.result == MoveResult.MISS || user.getLastXMoves(2)[1]?.result == MoveResult.FAIL ? 2 : 1),
|
.attr(MovePowerMultiplierAttr, (user, target, move) => user.getLastXMoves(2)[1]?.result == MoveResult.MISS || user.getLastXMoves(2)[1]?.result == MoveResult.FAIL ? 2 : 1),
|
||||||
new AttackMove(Moves.SUPERCELL_SLAM, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 95, 15, -1, 0, 9)
|
new AttackMove(Moves.SUPERCELL_SLAM, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 95, 15, -1, 0, 9)
|
||||||
.attr(MissEffectAttr, crashDamageFunc)
|
.attr(MissEffectAttr, crashDamageFunc)
|
||||||
.attr(NoEffectAttr, crashDamageFunc),
|
.attr(NoEffectAttr, crashDamageFunc)
|
||||||
|
.recklessMove(),
|
||||||
new AttackMove(Moves.PSYCHIC_NOISE, Type.PSYCHIC, MoveCategory.SPECIAL, 75, 100, 10, -1, 0, 9)
|
new AttackMove(Moves.PSYCHIC_NOISE, Type.PSYCHIC, MoveCategory.SPECIAL, 75, 100, 10, -1, 0, 9)
|
||||||
.soundBased()
|
.soundBased()
|
||||||
.partial(),
|
.partial(),
|
||||||
|
@ -2313,7 +2313,7 @@ export function initSpecies() {
|
|||||||
new PokemonSpecies(Species.QUAXWELL, 9, false, false, false, "Practicing Pokémon", Type.WATER, null, 1.2, 21.5, Abilities.TORRENT, Abilities.NONE, Abilities.MOXIE, 410, 70, 85, 65, 65, 60, 65, 45, 50, 144, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
new PokemonSpecies(Species.QUAXWELL, 9, false, false, false, "Practicing Pokémon", Type.WATER, null, 1.2, 21.5, Abilities.TORRENT, Abilities.NONE, Abilities.MOXIE, 410, 70, 85, 65, 65, 60, 65, 45, 50, 144, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||||
new PokemonSpecies(Species.QUAQUAVAL, 9, false, false, false, "Dancer Pokémon", Type.WATER, Type.FIGHTING, 1.8, 61.9, Abilities.TORRENT, Abilities.NONE, Abilities.MOXIE, 530, 85, 120, 80, 85, 75, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
new PokemonSpecies(Species.QUAQUAVAL, 9, false, false, false, "Dancer Pokémon", Type.WATER, Type.FIGHTING, 1.8, 61.9, Abilities.TORRENT, Abilities.NONE, Abilities.MOXIE, 530, 85, 120, 80, 85, 75, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||||
new PokemonSpecies(Species.LECHONK, 9, false, false, false, "Hog Pokémon", Type.NORMAL, null, 0.5, 10.2, Abilities.AROMA_VEIL, Abilities.GLUTTONY, Abilities.THICK_FAT, 254, 54, 45, 40, 35, 45, 35, 255, 50, 51, GrowthRate.MEDIUM_FAST, 50, false),
|
new PokemonSpecies(Species.LECHONK, 9, false, false, false, "Hog Pokémon", Type.NORMAL, null, 0.5, 10.2, Abilities.AROMA_VEIL, Abilities.GLUTTONY, Abilities.THICK_FAT, 254, 54, 45, 40, 35, 45, 35, 255, 50, 51, GrowthRate.MEDIUM_FAST, 50, false),
|
||||||
new PokemonSpecies(Species.OINKOLOGNE, 9, false, false, false, "Hog Pokémon", Type.NORMAL, null, 1, 120, Abilities.LINGERING_AROMA, Abilities.GLUTTONY, Abilities.THICK_FAT, 489, 110, 100, 75, 59, 80, 65, 100, 50, 171, GrowthRate.MEDIUM_FAST, 100, false, false,
|
new PokemonSpecies(Species.OINKOLOGNE, 9, false, false, false, "Hog Pokémon", Type.NORMAL, null, 1, 120, Abilities.LINGERING_AROMA, Abilities.GLUTTONY, Abilities.THICK_FAT, 489, 110, 100, 75, 59, 80, 65, 100, 50, 171, GrowthRate.MEDIUM_FAST, 50, false, false,
|
||||||
new PokemonForm("Male", "male", Type.NORMAL, null, 1, 120, Abilities.LINGERING_AROMA, Abilities.GLUTTONY, Abilities.THICK_FAT, 489, 110, 100, 75, 59, 80, 65, 100, 50, 171, false, ""),
|
new PokemonForm("Male", "male", Type.NORMAL, null, 1, 120, Abilities.LINGERING_AROMA, Abilities.GLUTTONY, Abilities.THICK_FAT, 489, 110, 100, 75, 59, 80, 65, 100, 50, 171, false, ""),
|
||||||
new PokemonForm("Female", "female", Type.NORMAL, null, 1, 120, Abilities.AROMA_VEIL, Abilities.GLUTTONY, Abilities.THICK_FAT, 489, 115, 90, 70, 59, 90, 65, 100, 50, 171),
|
new PokemonForm("Female", "female", Type.NORMAL, null, 1, 120, Abilities.AROMA_VEIL, Abilities.GLUTTONY, Abilities.THICK_FAT, 489, 115, 90, 70, 59, 90, 65, 100, 50, 171),
|
||||||
),
|
),
|
||||||
|
@ -18,7 +18,7 @@ import { TimeOfDay } from "../data/enums/time-of-day";
|
|||||||
import { Terrain, TerrainType } from "../data/terrain";
|
import { Terrain, TerrainType } from "../data/terrain";
|
||||||
import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability";
|
import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability";
|
||||||
import Pokemon from "./pokemon";
|
import Pokemon from "./pokemon";
|
||||||
import { WEATHER_OVERRIDE } from '../overrides';
|
import * as Overrides from '../overrides';
|
||||||
|
|
||||||
export class Arena {
|
export class Arena {
|
||||||
public scene: BattleScene;
|
public scene: BattleScene;
|
||||||
@ -273,6 +273,11 @@ export class Arena {
|
|||||||
return 131 / 180;
|
return 131 / 180;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets weather to the override specified in overrides.ts
|
||||||
|
* @param weather new weather to set of type WeatherType
|
||||||
|
* @returns true to force trySetWeather to return true
|
||||||
|
*/
|
||||||
trySetWeatherOverride(weather: WeatherType): boolean {
|
trySetWeatherOverride(weather: WeatherType): boolean {
|
||||||
this.weather = new Weather(weather, 0);
|
this.weather = new Weather(weather, 0);
|
||||||
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
|
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
|
||||||
@ -280,10 +285,15 @@ export class Arena {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to set a new weather to the battle
|
||||||
|
* @param weather new weather to set of type WeatherType
|
||||||
|
* @param hasPokemonSource is the new weather from a pokemon
|
||||||
|
* @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use
|
||||||
|
*/
|
||||||
trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean {
|
trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean {
|
||||||
// override hook for debugging
|
if (Overrides.WEATHER_OVERRIDE)
|
||||||
if (WEATHER_OVERRIDE)
|
return this.trySetWeatherOverride(Overrides.WEATHER_OVERRIDE);
|
||||||
return this.trySetWeatherOverride(WEATHER_OVERRIDE);
|
|
||||||
|
|
||||||
if (this.weather?.weatherType === (weather || undefined))
|
if (this.weather?.weatherType === (weather || undefined))
|
||||||
return false;
|
return false;
|
||||||
@ -572,7 +582,7 @@ export class Arena {
|
|||||||
case Biome.TALL_GRASS:
|
case Biome.TALL_GRASS:
|
||||||
return 9.608;
|
return 9.608;
|
||||||
case Biome.METROPOLIS:
|
case Biome.METROPOLIS:
|
||||||
return 4.867;
|
return 141.470;
|
||||||
case Biome.FOREST:
|
case Biome.FOREST:
|
||||||
return 4.294;
|
return 4.294;
|
||||||
case Biome.SEA:
|
case Biome.SEA:
|
||||||
@ -626,7 +636,7 @@ export class Arena {
|
|||||||
case Biome.ISLAND:
|
case Biome.ISLAND:
|
||||||
return 2.751;
|
return 2.751;
|
||||||
case Biome.LABORATORY:
|
case Biome.LABORATORY:
|
||||||
return 0.797;
|
return 114.862;
|
||||||
case Biome.SLUM:
|
case Biome.SLUM:
|
||||||
return 1.221;
|
return 1.221;
|
||||||
case Biome.SNOWY_FOREST:
|
case Biome.SNOWY_FOREST:
|
||||||
@ -636,19 +646,12 @@ export class Arena {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getBiomeKey(biome: Biome): string {
|
export function getBiomeKey(biome: Biome): string {
|
||||||
switch (biome) {
|
|
||||||
case Biome.METROPOLIS:
|
|
||||||
return 'slum';
|
|
||||||
case Biome.JUNGLE:
|
|
||||||
return 'tall_grass';
|
|
||||||
case Biome.ISLAND:
|
|
||||||
return 'beach';
|
|
||||||
}
|
|
||||||
return Biome[biome].toLowerCase();
|
return Biome[biome].toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBiomeHasProps(biomeType: Biome): boolean {
|
export function getBiomeHasProps(biomeType: Biome): boolean {
|
||||||
switch (biomeType) {
|
switch (biomeType) {
|
||||||
|
case Biome.METROPOLIS:
|
||||||
case Biome.BEACH:
|
case Biome.BEACH:
|
||||||
case Biome.LAKE:
|
case Biome.LAKE:
|
||||||
case Biome.SEABED:
|
case Biome.SEABED:
|
||||||
@ -666,8 +669,11 @@ export function getBiomeHasProps(biomeType: Biome): boolean {
|
|||||||
case Biome.WASTELAND:
|
case Biome.WASTELAND:
|
||||||
case Biome.ABYSS:
|
case Biome.ABYSS:
|
||||||
case Biome.CONSTRUCTION_SITE:
|
case Biome.CONSTRUCTION_SITE:
|
||||||
|
case Biome.JUNGLE:
|
||||||
case Biome.FAIRY_CAVE:
|
case Biome.FAIRY_CAVE:
|
||||||
case Biome.TEMPLE:
|
case Biome.TEMPLE:
|
||||||
|
case Biome.SNOWY_FOREST:
|
||||||
|
case Biome.ISLAND:
|
||||||
case Biome.LABORATORY:
|
case Biome.LABORATORY:
|
||||||
case Biome.END:
|
case Biome.END:
|
||||||
return true;
|
return true;
|
||||||
|
@ -43,7 +43,7 @@ import { Nature, getNatureStatMultiplier } from '../data/nature';
|
|||||||
import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from '../data/pokemon-forms';
|
import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from '../data/pokemon-forms';
|
||||||
import { TerrainType } from '../data/terrain';
|
import { TerrainType } from '../data/terrain';
|
||||||
import { TrainerSlot } from '../data/trainer-config';
|
import { TrainerSlot } from '../data/trainer-config';
|
||||||
import { ABILITY_OVERRIDE, MOVE_OVERRIDE, MOVE_OVERRIDE_2, OPP_ABILITY_OVERRIDE, OPP_MOVE_OVERRIDE, OPP_MOVE_OVERRIDE_2, OPP_SHINY_OVERRIDE, OPP_VARIANT_OVERRIDE } from '../overrides';
|
import * as Overrides from '../overrides';
|
||||||
import { BerryType } from '../data/berry';
|
import { BerryType } from '../data/berry';
|
||||||
import i18next from '../plugins/i18n';
|
import i18next from '../plugins/i18n';
|
||||||
|
|
||||||
@ -725,15 +725,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
? this.summonData.moveset
|
? this.summonData.moveset
|
||||||
: this.moveset;
|
: this.moveset;
|
||||||
|
|
||||||
if (MOVE_OVERRIDE && this.isPlayer())
|
// Overrides moveset based on arrays specified in overrides.ts
|
||||||
this.moveset[0] = new PokemonMove(MOVE_OVERRIDE, Math.min(this.moveset[0].ppUsed, allMoves[MOVE_OVERRIDE].pp));
|
const overrideArray: Array<Moves> = this.isPlayer() ? Overrides.MOVESET_OVERRIDE : Overrides.OPP_MOVESET_OVERRIDE;
|
||||||
else if (OPP_MOVE_OVERRIDE && !this.isPlayer())
|
if (overrideArray.length > 0) {
|
||||||
this.moveset[0] = new PokemonMove(OPP_MOVE_OVERRIDE, Math.min(this.moveset[0].ppUsed, allMoves[OPP_MOVE_OVERRIDE].pp));
|
overrideArray.forEach((move: Moves, index: number) => {
|
||||||
if (MOVE_OVERRIDE_2 && this.isPlayer())
|
const ppUsed = this.moveset[index]?.ppUp || 0;
|
||||||
this.moveset[1] = new PokemonMove(MOVE_OVERRIDE_2, Math.min(this.moveset[1].ppUsed, allMoves[MOVE_OVERRIDE_2].pp));
|
this.moveset[index] = new PokemonMove(move, Math.min(ppUsed, allMoves[move].pp))
|
||||||
else if (OPP_MOVE_OVERRIDE_2 && !this.isPlayer())
|
});
|
||||||
this.moveset[1] = new PokemonMove(OPP_MOVE_OVERRIDE_2, Math.min(this.moveset[1].ppUsed, allMoves[OPP_MOVE_OVERRIDE_2].pp));
|
}
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -798,10 +797,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
getAbility(ignoreOverride?: boolean): Ability {
|
getAbility(ignoreOverride?: boolean): Ability {
|
||||||
if (!ignoreOverride && this.summonData?.ability)
|
if (!ignoreOverride && this.summonData?.ability)
|
||||||
return allAbilities[this.summonData.ability];
|
return allAbilities[this.summonData.ability];
|
||||||
if (ABILITY_OVERRIDE && this.isPlayer())
|
if (Overrides.ABILITY_OVERRIDE && this.isPlayer())
|
||||||
return allAbilities[ABILITY_OVERRIDE];
|
return allAbilities[Overrides.ABILITY_OVERRIDE];
|
||||||
if (OPP_ABILITY_OVERRIDE && !this.isPlayer())
|
if (Overrides.OPP_ABILITY_OVERRIDE && !this.isPlayer())
|
||||||
return allAbilities[OPP_ABILITY_OVERRIDE];
|
return allAbilities[Overrides.OPP_ABILITY_OVERRIDE];
|
||||||
if (this.isFusion())
|
if (this.isFusion())
|
||||||
return allAbilities[this.getFusionSpeciesForm(ignoreOverride).getAbility(this.fusionAbilityIndex)];
|
return allAbilities[this.getFusionSpeciesForm(ignoreOverride).getAbility(this.fusionAbilityIndex)];
|
||||||
let abilityId = this.getSpeciesForm(ignoreOverride).getAbility(this.abilityIndex);
|
let abilityId = this.getSpeciesForm(ignoreOverride).getAbility(this.abilityIndex);
|
||||||
@ -811,13 +810,29 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getPassiveAbility(): Ability {
|
getPassiveAbility(): Ability {
|
||||||
|
if (Overrides.PASSIVE_ABILITY_OVERRIDE && this.isPlayer())
|
||||||
|
return allAbilities[Overrides.PASSIVE_ABILITY_OVERRIDE];
|
||||||
|
if (Overrides.OPP_PASSIVE_ABILITY_OVERRIDE && !this.isPlayer())
|
||||||
|
return allAbilities[Overrides.OPP_PASSIVE_ABILITY_OVERRIDE];
|
||||||
|
|
||||||
let starterSpeciesId = this.species.speciesId;
|
let starterSpeciesId = this.species.speciesId;
|
||||||
while (pokemonPrevolutions.hasOwnProperty(starterSpeciesId))
|
while (pokemonPrevolutions.hasOwnProperty(starterSpeciesId))
|
||||||
starterSpeciesId = pokemonPrevolutions[starterSpeciesId];
|
starterSpeciesId = pokemonPrevolutions[starterSpeciesId];
|
||||||
return allAbilities[starterPassiveAbilities[starterSpeciesId]];
|
return allAbilities[starterPassiveAbilities[starterSpeciesId]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a pokemon has a passive either from:
|
||||||
|
* - bought with starter candy
|
||||||
|
* - set by override
|
||||||
|
* - is a boss pokemon
|
||||||
|
* @returns whether or not a pokemon should have a passive
|
||||||
|
*/
|
||||||
hasPassive(): boolean {
|
hasPassive(): boolean {
|
||||||
|
// returns override if valid for current case
|
||||||
|
if ((Overrides.PASSIVE_ABILITY_OVERRIDE !== Abilities.NONE && this.isPlayer()) ||
|
||||||
|
(Overrides.OPP_PASSIVE_ABILITY_OVERRIDE !== Abilities.NONE && !this.isPlayer()))
|
||||||
|
return true;
|
||||||
return this.passive || this.isBoss();
|
return this.passive || this.isBoss();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -901,14 +916,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return this.isTerastallized() ? 2 : 1;
|
return this.isTerastallized() ? 2 : 1;
|
||||||
const types = this.getTypes(true, true);
|
const types = this.getTypes(true, true);
|
||||||
|
|
||||||
const ignorableImmunities = source?.getAbility()?.getAttrs(IgnoreTypeImmunityAbAttr) || [];
|
let multiplier = types.map(defType => {
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
if (source) {
|
||||||
|
const ignoreImmunity = new Utils.BooleanHolder(false);
|
||||||
|
applyAbAttrs(IgnoreTypeImmunityAbAttr, source, ignoreImmunity, moveType, defType);
|
||||||
|
if (ignoreImmunity.value)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
let multiplier = types.map(defType =>
|
return getTypeDamageMultiplier(moveType, defType);
|
||||||
ignorableImmunities.some(attr => attr.apply(source, false, cancelled, [moveType, defType]))
|
}).reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier;
|
||||||
? 1
|
|
||||||
: getTypeDamageMultiplier(moveType, defType)
|
|
||||||
).reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier;
|
|
||||||
|
|
||||||
// Handle strong winds lowering effectiveness of types super effective against pure flying
|
// Handle strong winds lowering effectiveness of types super effective against pure flying
|
||||||
if (this.scene.arena.weather?.weatherType === WeatherType.STRONG_WINDS && !this.scene.arena.weather.isEffectSuppressed(this.scene) && multiplier >= 2 && this.isOfType(Type.FLYING) && getTypeDamageMultiplier(moveType, Type.FLYING) === 2)
|
if (this.scene.arena.weather?.weatherType === WeatherType.STRONG_WINDS && !this.scene.arena.weather.isEffectSuppressed(this.scene) && multiplier >= 2 && this.isOfType(Type.FLYING) && getTypeDamageMultiplier(moveType, Type.FLYING) === 2)
|
||||||
@ -1315,7 +1332,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
if (typeBoost) {
|
if (typeBoost) {
|
||||||
power.value *= typeBoost.boostValue;
|
power.value *= typeBoost.boostValue;
|
||||||
if (typeBoost.oneUse) {
|
if (typeBoost.oneUse) {
|
||||||
this.removeTag(typeBoost.tagType);
|
source.removeTag(typeBoost.tagType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const arenaAttackTypeMultiplier = this.scene.arena.getAttackTypeMultiplier(type, source.isGrounded());
|
const arenaAttackTypeMultiplier = this.scene.arena.getAttackTypeMultiplier(type, source.isGrounded());
|
||||||
@ -1701,18 +1718,19 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cry(soundConfig?: Phaser.Types.Sound.SoundConfig): AnySound {
|
cry(soundConfig?: Phaser.Types.Sound.SoundConfig, sceneOverride?: BattleScene): AnySound {
|
||||||
const cry = this.getSpeciesForm().cry(this.scene, soundConfig);
|
const scene = sceneOverride || this.scene;
|
||||||
|
const cry = this.getSpeciesForm().cry(scene, soundConfig);
|
||||||
let duration = cry.totalDuration * 1000;
|
let duration = cry.totalDuration * 1000;
|
||||||
if (this.fusionSpecies) {
|
if (this.fusionSpecies) {
|
||||||
let fusionCry = this.getFusionSpeciesForm().cry(this.scene, soundConfig, true);
|
let fusionCry = this.getFusionSpeciesForm().cry(scene, soundConfig, true);
|
||||||
duration = Math.min(duration, fusionCry.totalDuration * 1000);
|
duration = Math.min(duration, fusionCry.totalDuration * 1000);
|
||||||
fusionCry.destroy();
|
fusionCry.destroy();
|
||||||
this.scene.time.delayedCall(Utils.fixedInt(Math.ceil(duration * 0.4)), () => {
|
scene.time.delayedCall(Utils.fixedInt(Math.ceil(duration * 0.4)), () => {
|
||||||
try {
|
try {
|
||||||
SoundFade.fadeOut(this.scene, cry, Utils.fixedInt(Math.ceil(duration * 0.2)));
|
SoundFade.fadeOut(scene, cry, Utils.fixedInt(Math.ceil(duration * 0.2)));
|
||||||
fusionCry = this.getFusionSpeciesForm().cry(this.scene, Object.assign({ seek: Math.max(fusionCry.totalDuration * 0.4, 0) }, soundConfig));
|
fusionCry = this.getFusionSpeciesForm().cry(scene, Object.assign({ seek: Math.max(fusionCry.totalDuration * 0.4, 0) }, soundConfig));
|
||||||
SoundFade.fadeIn(this.scene, fusionCry, Utils.fixedInt(Math.ceil(duration * 0.2)), this.scene.masterVolume * this.scene.seVolume, 0);
|
SoundFade.fadeIn(scene, fusionCry, Utils.fixedInt(Math.ceil(duration * 0.2)), scene.masterVolume * scene.seVolume, 0);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
@ -1949,8 +1967,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetStatus(): void {
|
/**
|
||||||
|
* Resets the status of a pokemon
|
||||||
|
* @param revive whether revive should be cured, defaults to true
|
||||||
|
*/
|
||||||
|
resetStatus(revive: boolean = true): void {
|
||||||
const lastStatus = this.status?.effect;
|
const lastStatus = this.status?.effect;
|
||||||
|
if (!revive && lastStatus === StatusEffect.FAINT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.status = undefined;
|
this.status = undefined;
|
||||||
if (lastStatus === StatusEffect.SLEEP) {
|
if (lastStatus === StatusEffect.SLEEP) {
|
||||||
this.setFrameRate(12);
|
this.setFrameRate(12);
|
||||||
@ -2675,14 +2700,14 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
this.generateAndPopulateMoveset();
|
this.generateAndPopulateMoveset();
|
||||||
|
|
||||||
this.trySetShiny();
|
this.trySetShiny();
|
||||||
if (OPP_SHINY_OVERRIDE) {
|
if (Overrides.OPP_SHINY_OVERRIDE) {
|
||||||
this.shiny = true;
|
this.shiny = true;
|
||||||
this.initShinySparkle();
|
this.initShinySparkle();
|
||||||
}
|
}
|
||||||
if (this.shiny) {
|
if (this.shiny) {
|
||||||
this.variant = this.generateVariant();
|
this.variant = this.generateVariant();
|
||||||
if (OPP_VARIANT_OVERRIDE)
|
if (Overrides.OPP_VARIANT_OVERRIDE)
|
||||||
this.variant = OPP_VARIANT_OVERRIDE;
|
this.variant = Overrides.OPP_VARIANT_OVERRIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.luck = (this.shiny ? this.variant + 1 : 0) + (this.fusionShiny ? this.fusionVariant + 1 : 0);
|
this.luck = (this.shiny ? this.variant + 1 : 0) + (this.fusionShiny ? this.fusionVariant + 1 : 0);
|
||||||
@ -3126,6 +3151,7 @@ export class PokemonBattleData {
|
|||||||
public hitCount: integer = 0;
|
public hitCount: integer = 0;
|
||||||
public endured: boolean = false;
|
public endured: boolean = false;
|
||||||
public berriesEaten: BerryType[] = [];
|
public berriesEaten: BerryType[] = [];
|
||||||
|
public abilitiesApplied: Abilities[] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PokemonBattleSummonData {
|
export class PokemonBattleSummonData {
|
||||||
@ -3195,6 +3221,14 @@ export class PokemonMove {
|
|||||||
return allMoves[this.moveId];
|
return allMoves[this.moveId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets {@link ppUsed} for this move and ensures the value does not exceed {@link getMovePp}
|
||||||
|
* @param {number} count Amount of PP to use
|
||||||
|
*/
|
||||||
|
usePp(count: number = 1) {
|
||||||
|
this.ppUsed = Math.min(this.ppUsed + count, this.getMovePp());
|
||||||
|
}
|
||||||
|
|
||||||
getMovePp(): integer {
|
getMovePp(): integer {
|
||||||
return this.getMove().pp + this.ppUp * Math.max(Math.floor(this.getMove().pp / 5), 1);
|
return this.getMove().pp + this.ppUp * Math.max(Math.floor(this.getMove().pp / 5), 1);
|
||||||
}
|
}
|
||||||
@ -3206,4 +3240,13 @@ export class PokemonMove {
|
|||||||
getName(): string {
|
getName(): string {
|
||||||
return this.getMove().name;
|
return this.getMove().name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies an existing move or creates a valid PokemonMove object from json representing one
|
||||||
|
* @param {PokemonMove | any} source The data for the move to copy
|
||||||
|
* @return {PokemonMove} A valid pokemonmove object
|
||||||
|
*/
|
||||||
|
static loadMove(source: PokemonMove | any): PokemonMove {
|
||||||
|
return new PokemonMove(source.moveId, source.ppUsed, source.ppUp, source.virtual);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
const difficultyWaveIndex = this.scene.gameMode.getWaveForDifficulty(waveIndex);
|
const difficultyWaveIndex = this.scene.gameMode.getWaveForDifficulty(waveIndex);
|
||||||
let baseLevel = 1 + difficultyWaveIndex / 2 + Math.pow(difficultyWaveIndex / 25, 2);
|
let baseLevel = 1 + difficultyWaveIndex / 2 + Math.pow(difficultyWaveIndex / 25, 2);
|
||||||
|
|
||||||
|
if (this.isDouble() && partyTemplate.size < 2)
|
||||||
|
partyTemplate.size = 2;
|
||||||
|
|
||||||
for (let i = 0; i < partyTemplate.size; i++) {
|
for (let i = 0; i < partyTemplate.size; i++) {
|
||||||
let multiplier = 1;
|
let multiplier = 1;
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import { Species } from "./data/enums/species";
|
|||||||
import PokemonSpecies, { allSpecies } from "./data/pokemon-species";
|
import PokemonSpecies, { allSpecies } from "./data/pokemon-species";
|
||||||
import { Arena } from "./field/arena";
|
import { Arena } from "./field/arena";
|
||||||
import * as Utils from "./utils";
|
import * as Utils from "./utils";
|
||||||
import { STARTING_BIOME_OVERRIDE, STARTING_LEVEL_OVERRIDE, STARTING_MONEY_OVERRIDE } from './overrides';
|
import * as Overrides from './overrides';
|
||||||
|
|
||||||
export enum GameModes {
|
export enum GameModes {
|
||||||
CLASSIC,
|
CLASSIC,
|
||||||
@ -45,9 +45,15 @@ export class GameMode implements GameModeConfig {
|
|||||||
Object.assign(this, config);
|
Object.assign(this, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns either:
|
||||||
|
* - override from overrides.ts
|
||||||
|
* - 20 for Daily Runs
|
||||||
|
* - 5 for all other modes
|
||||||
|
*/
|
||||||
getStartingLevel(): integer {
|
getStartingLevel(): integer {
|
||||||
if (STARTING_LEVEL_OVERRIDE)
|
if (Overrides.STARTING_LEVEL_OVERRIDE)
|
||||||
return STARTING_LEVEL_OVERRIDE;
|
return Overrides.STARTING_LEVEL_OVERRIDE;
|
||||||
switch (this.modeId) {
|
switch (this.modeId) {
|
||||||
case GameModes.DAILY:
|
case GameModes.DAILY:
|
||||||
return 20;
|
return 20;
|
||||||
@ -56,16 +62,28 @@ export class GameMode implements GameModeConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns either:
|
||||||
|
* - override from overrides.ts
|
||||||
|
* - 1000
|
||||||
|
*/
|
||||||
getStartingMoney(): integer {
|
getStartingMoney(): integer {
|
||||||
return STARTING_MONEY_OVERRIDE || 1000;
|
return Overrides.STARTING_MONEY_OVERRIDE || 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param scene current BattleScene
|
||||||
|
* @returns either:
|
||||||
|
* - random biome for Daily mode
|
||||||
|
* - override from overrides.ts
|
||||||
|
* - Town
|
||||||
|
*/
|
||||||
getStartingBiome(scene: BattleScene): Biome {
|
getStartingBiome(scene: BattleScene): Biome {
|
||||||
switch (this.modeId) {
|
switch (this.modeId) {
|
||||||
case GameModes.DAILY:
|
case GameModes.DAILY:
|
||||||
return scene.generateRandomBiome(this.getWaveForDifficulty(1));
|
return scene.generateRandomBiome(this.getWaveForDifficulty(1));
|
||||||
default:
|
default:
|
||||||
return STARTING_BIOME_OVERRIDE || Biome.TOWN;
|
return Overrides.STARTING_BIOME_OVERRIDE || Biome.TOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ export class LoadingScene extends SceneBase {
|
|||||||
this.loadImage('shiny_star_small_1', 'ui', 'shiny_small_1.png');
|
this.loadImage('shiny_star_small_1', 'ui', 'shiny_small_1.png');
|
||||||
this.loadImage('shiny_star_small_2', 'ui', 'shiny_small_2.png');
|
this.loadImage('shiny_star_small_2', 'ui', 'shiny_small_2.png');
|
||||||
this.loadImage('ha_capsule', 'ui', 'ha_capsule.png');
|
this.loadImage('ha_capsule', 'ui', 'ha_capsule.png');
|
||||||
|
this.loadImage('champion_ribbon', 'ui', 'champion_ribbon.png');
|
||||||
this.loadImage('icon_spliced', 'ui');
|
this.loadImage('icon_spliced', 'ui');
|
||||||
this.loadImage('icon_tera', 'ui');
|
this.loadImage('icon_tera', 'ui');
|
||||||
this.loadImage('type_tera', 'ui');
|
this.loadImage('type_tera', 'ui');
|
||||||
|
@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
|
|||||||
"runAwayCannotEscape": 'You can\'t escape!',
|
"runAwayCannotEscape": 'You can\'t escape!',
|
||||||
"escapeVerbSwitch": "auswechseln",
|
"escapeVerbSwitch": "auswechseln",
|
||||||
"escapeVerbFlee": "flucht",
|
"escapeVerbFlee": "flucht",
|
||||||
"notDisabled": "{{moveName}} ist\nnicht mehr deaktiviert!",
|
"notDisabled": "{{pokemonName}}'s {{moveName}} ist\nnicht mehr deaktiviert!",
|
||||||
"skipItemQuestion": "Are you sure you want to skip taking an item?",
|
"skipItemQuestion": "Are you sure you want to skip taking an item?",
|
||||||
"eggHatching": "Oh?",
|
"eggHatching": "Oh?",
|
||||||
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?"
|
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?"
|
||||||
|
@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
|
|||||||
"runAwayCannotEscape": 'You can\'t escape!',
|
"runAwayCannotEscape": 'You can\'t escape!',
|
||||||
"escapeVerbSwitch": "switching",
|
"escapeVerbSwitch": "switching",
|
||||||
"escapeVerbFlee": "fleeing",
|
"escapeVerbFlee": "fleeing",
|
||||||
"notDisabled": "{{moveName}} is disabled\nno more!",
|
"notDisabled": "{{pokemonName}}'s {{moveName}} is disabled\nno more!",
|
||||||
"skipItemQuestion": "Are you sure you want to skip taking an item?",
|
"skipItemQuestion": "Are you sure you want to skip taking an item?",
|
||||||
"eggHatching": "Oh?",
|
"eggHatching": "Oh?",
|
||||||
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?"
|
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?"
|
||||||
|
@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
|
|||||||
"runAwayCannotEscape": "¡No has podido escapar!",
|
"runAwayCannotEscape": "¡No has podido escapar!",
|
||||||
"escapeVerbSwitch": "cambiar",
|
"escapeVerbSwitch": "cambiar",
|
||||||
"escapeVerbFlee": "huir",
|
"escapeVerbFlee": "huir",
|
||||||
"notDisabled": "¡El movimiento {{moveName}}\nya no está anulado!",
|
"notDisabled": "¡El movimiento {{moveName}} de {{pokemonName}}\nya no está anulado!",
|
||||||
"skipItemQuestion": "¿Estás seguro de que no quieres coger un objeto?",
|
"skipItemQuestion": "¿Estás seguro de que no quieres coger un objeto?",
|
||||||
"eggHatching": "¿Y esto?",
|
"eggHatching": "¿Y esto?",
|
||||||
"ivScannerUseQuestion": "¿Quieres usar el Escáner de IVs en {{pokemonName}}?"
|
"ivScannerUseQuestion": "¿Quieres usar el Escáner de IVs en {{pokemonName}}?"
|
||||||
|
@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
|
|||||||
"runAwayCannotEscape": "Fuite impossible !",
|
"runAwayCannotEscape": "Fuite impossible !",
|
||||||
"escapeVerbSwitch": "le changement",
|
"escapeVerbSwitch": "le changement",
|
||||||
"escapeVerbFlee": "la fuite",
|
"escapeVerbFlee": "la fuite",
|
||||||
"notDisabled": "{{moveName}} n’est plus sous entrave !",
|
"notDisabled": "La capacité {{moveName}}\nde {{pokemonName}} n’est plus sous entrave !",
|
||||||
"skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre d’objet ?",
|
"skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre d’objet ?",
|
||||||
"eggHatching": "Oh ?",
|
"eggHatching": "Oh ?",
|
||||||
"ivScannerUseQuestion": "Utiliser le Scanner d’IV sur {{pokemonName}} ?"
|
"ivScannerUseQuestion": "Utiliser le Scanner d’IV sur {{pokemonName}} ?"
|
||||||
|
@ -24,7 +24,7 @@ export const menu: SimpleTranslationEntries = {
|
|||||||
"confirmPassword": "Confirmer le MDP",
|
"confirmPassword": "Confirmer le MDP",
|
||||||
"registrationAgeWarning": "Vous confirmez en vous inscrivant que vous avez 13 ans ou plus.",
|
"registrationAgeWarning": "Vous confirmez en vous inscrivant que vous avez 13 ans ou plus.",
|
||||||
"backToLogin": "Retour",
|
"backToLogin": "Retour",
|
||||||
"failedToLoadSaveData": "Échec du chargement des données. Veuillez recharger la page.\nSi cela continue, veuillez contacter l’administrateur.",
|
"failedToLoadSaveData": "Échec du chargement des données. Veuillez recharger\nla page. Si cela persiste, contactez l’administrateur.",
|
||||||
"sessionSuccess": "Session chargée avec succès.",
|
"sessionSuccess": "Session chargée avec succès.",
|
||||||
"failedToLoadSession": "Vos données de session n’ont pas pu être chargées.\nElles pourraient être corrompues.",
|
"failedToLoadSession": "Vos données de session n’ont pas pu être chargées.\nElles pourraient être corrompues.",
|
||||||
"boyOrGirl": "Es-tu un garçon ou une fille ?",
|
"boyOrGirl": "Es-tu un garçon ou une fille ?",
|
||||||
|
@ -482,7 +482,7 @@ export const move: MoveTranslationEntries = {
|
|||||||
effect: "Le lanceur explose en blessant tous les Pokémon autour de lui. Le lanceur tombe K.O."
|
effect: "Le lanceur explose en blessant tous les Pokémon autour de lui. Le lanceur tombe K.O."
|
||||||
},
|
},
|
||||||
"eggBomb": {
|
"eggBomb": {
|
||||||
name: "Bombe Oeuf",
|
name: "Bombe Œuf",
|
||||||
effect: "De toutes ses forces, le lanceur jette un gros œuf sur l’ennemi pour lui infliger des dégâts."
|
effect: "De toutes ses forces, le lanceur jette un gros œuf sur l’ennemi pour lui infliger des dégâts."
|
||||||
},
|
},
|
||||||
"lick": {
|
"lick": {
|
||||||
@ -1426,7 +1426,7 @@ export const move: MoveTranslationEntries = {
|
|||||||
effect: "Pendant cinq tours, les Pokémon Vol ou qui ont Lévitation deviennent sensibles aux capacités Sol, et les capacités volantes deviennent inutilisables."
|
effect: "Pendant cinq tours, les Pokémon Vol ou qui ont Lévitation deviennent sensibles aux capacités Sol, et les capacités volantes deviennent inutilisables."
|
||||||
},
|
},
|
||||||
"miracleEye": {
|
"miracleEye": {
|
||||||
name: "Oeil Miracle",
|
name: "Œil Miracle",
|
||||||
effect: "Permet de toucher un Pokémon Ténèbres avec les capacités de type Psy ou de toucher un ennemi ayant beaucoup d’esquive."
|
effect: "Permet de toucher un Pokémon Ténèbres avec les capacités de type Psy ou de toucher un ennemi ayant beaucoup d’esquive."
|
||||||
},
|
},
|
||||||
"wakeUpSlap": {
|
"wakeUpSlap": {
|
||||||
@ -1562,8 +1562,8 @@ export const move: MoveTranslationEntries = {
|
|||||||
effect: "Le lanceur éparpille des pics autour de la cible, ce qui empoisonne les Pokémon entrant au combat de ce côté."
|
effect: "Le lanceur éparpille des pics autour de la cible, ce qui empoisonne les Pokémon entrant au combat de ce côté."
|
||||||
},
|
},
|
||||||
"heartSwap": {
|
"heartSwap": {
|
||||||
name: "Permucoeur",
|
name: "Permucœur",
|
||||||
effect: "Cette capacité ne peut pas être utilisée. Il est recommandé de l’oublier, même s’il sera impossible de se la remémorer une fois oubliée."
|
effect: "Le lanceur utilise un pouvoir psychique pour échanger ses changements de stats avec la cible."
|
||||||
},
|
},
|
||||||
"aquaRing": {
|
"aquaRing": {
|
||||||
name: "Anneau Hydro",
|
name: "Anneau Hydro",
|
||||||
@ -2122,7 +2122,7 @@ export const move: MoveTranslationEntries = {
|
|||||||
effect: "Le lanceur frappe l’ennemi deux fois d’affilée avec les parties les plus robustes de son corps."
|
effect: "Le lanceur frappe l’ennemi deux fois d’affilée avec les parties les plus robustes de son corps."
|
||||||
},
|
},
|
||||||
"heartStamp": {
|
"heartStamp": {
|
||||||
name: "Crève-Coeur",
|
name: "Crève-Cœur",
|
||||||
effect: "Déconcentre l’ennemi avec des mouvements mignons avant de le frapper violemment. Peut aussi l’apeurer (30% de chances)."
|
effect: "Déconcentre l’ennemi avec des mouvements mignons avant de le frapper violemment. Peut aussi l’apeurer (30% de chances)."
|
||||||
},
|
},
|
||||||
"hornLeech": {
|
"hornLeech": {
|
||||||
@ -3742,7 +3742,7 @@ export const move: MoveTranslationEntries = {
|
|||||||
effect: "Le lanceur remue son thé et en bombarde la cible. La moitié des dégâts infligés sont convertis en PV pour le lanceur. Cette capacité peut aussi brûler la cible."
|
effect: "Le lanceur remue son thé et en bombarde la cible. La moitié des dégâts infligés sont convertis en PV pour le lanceur. Cette capacité peut aussi brûler la cible."
|
||||||
},
|
},
|
||||||
"syrupBomb": {
|
"syrupBomb": {
|
||||||
name: "Bombe au sirop",
|
name: "Bombe au Sirop",
|
||||||
effect: "Le lanceur jette une bombe qui recouvre la cible de sirop gluant et fait progressivement baisser la Vitesse de la cible pendant trois tours."
|
effect: "Le lanceur jette une bombe qui recouvre la cible de sirop gluant et fait progressivement baisser la Vitesse de la cible pendant trois tours."
|
||||||
},
|
},
|
||||||
"ivyCudgel": {
|
"ivyCudgel": {
|
||||||
|
@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
|
|||||||
"runAwayCannotEscape": 'Non puoi fuggire!',
|
"runAwayCannotEscape": 'Non puoi fuggire!',
|
||||||
"escapeVerbSwitch": "cambiando",
|
"escapeVerbSwitch": "cambiando",
|
||||||
"escapeVerbFlee": "fuggendo",
|
"escapeVerbFlee": "fuggendo",
|
||||||
"notDisabled": "{{moveName}} non è più\ndisabilitata!",
|
"notDisabled": "{{pokemonName}}'s {{moveName}} non è più\ndisabilitata!",
|
||||||
"skipItemQuestion": "Sei sicuro di non voler prendere nessun oggetto?",
|
"skipItemQuestion": "Sei sicuro di non voler prendere nessun oggetto?",
|
||||||
"eggHatching": "Oh?",
|
"eggHatching": "Oh?",
|
||||||
"ivScannerUseQuestion": "Vuoi usare lo scanner di IV su {{pokemonName}}?"
|
"ivScannerUseQuestion": "Vuoi usare lo scanner di IV su {{pokemonName}}?"
|
||||||
|
1244
src/locales/zh_CN/ability.ts
Normal file
53
src/locales/zh_CN/battle.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
|
|
||||||
|
export const battle: SimpleTranslationEntries = {
|
||||||
|
"bossAppeared": "{{bossName}} 出现了。",
|
||||||
|
"trainerAppeared": "{{trainerName}}\n想要和你对战!",
|
||||||
|
"singleWildAppeared": "一只野生 {{pokemonName}} 出现了。!",
|
||||||
|
"multiWildAppeared": "野生的 {{pokemonName1}}\n和 {{pokemonName2}} 出现了。!",
|
||||||
|
"playerComeBack": "回来吧, {{pokemonName}}!",
|
||||||
|
"trainerComeBack": "{{trainerName}} 收回了 {{pokemonName}}!",
|
||||||
|
"playerGo": "去吧! {{pokemonName}}!",
|
||||||
|
"trainerGo": "{{trainerName}} 派出了 {{pokemonName}}!",
|
||||||
|
"switchQuestion": "要更换\n{{pokemonName}}吗?",
|
||||||
|
"trainerDefeated": `你击败了\n{{trainerName}}!`,
|
||||||
|
"pokemonCaught": "{{pokemonName}} 被抓住了!",
|
||||||
|
"pokemon": "宝可梦",
|
||||||
|
"sendOutPokemon": "上吧! {{pokemonName}}!",
|
||||||
|
"hitResultCriticalHit": "击中了要害!",
|
||||||
|
"hitResultSuperEffective": "效果拔群!",
|
||||||
|
"hitResultNotVeryEffective": "收效甚微…",
|
||||||
|
"hitResultNoEffect": "对 {{pokemonName}} 没有效果!!",
|
||||||
|
"hitResultOneHitKO": "一击必杀!",
|
||||||
|
"attackFailed": "但是失败了!",
|
||||||
|
"attackHitsCount": `击中 {{count}} 次!`,
|
||||||
|
"expGain": "{{pokemonName}} 获得了 {{exp}} 经验值!",
|
||||||
|
"levelUp": "{{pokemonName}} 升级到 Lv. {{level}}!",
|
||||||
|
"learnMove": "{{pokemonName}} 学会了 {{moveName}}!",
|
||||||
|
"learnMovePrompt": "{{pokemonName}} 想要学习 {{moveName}}。",
|
||||||
|
"learnMoveLimitReached": "但是,{{pokemonName}} 已经学会了\n四个技能",
|
||||||
|
"learnMoveReplaceQuestion": "要忘记一个技能并学习 {{moveName}} 吗?",
|
||||||
|
"learnMoveStopTeaching": "不再尝试学习 {{moveName}}?",
|
||||||
|
"learnMoveNotLearned": "{{pokemonName}} 没有学会 {{moveName}}。",
|
||||||
|
"learnMoveForgetQuestion": "要忘记哪个技能?",
|
||||||
|
"learnMoveForgetSuccess": "{{pokemonName}} 忘记了\n如何使用 {{moveName}}。",
|
||||||
|
"levelCapUp": "等级上限提升到 {{levelCap}}!",
|
||||||
|
"moveNotImplemented": "{{moveName}} 尚未实装,无法选择。",
|
||||||
|
"moveNoPP": "这个技能的 PP 用完了",
|
||||||
|
"moveDisabled": "{{moveName}} 被禁用!",
|
||||||
|
"noPokeballForce": "一股无形的力量阻止了你使用精灵球。",
|
||||||
|
"noPokeballTrainer": "你不能捕捉其他训练家的宝可梦!",
|
||||||
|
"noPokeballMulti": "只能在剩下一只宝可梦时才能扔出精灵球!",
|
||||||
|
"noPokeballStrong": "目标宝可梦太强了,无法捕捉!你需要先削弱它!",
|
||||||
|
"noEscapeForce": "一股无形的力量阻止你逃跑。",
|
||||||
|
"noEscapeTrainer": "你不能从训练家战斗中逃跑!",
|
||||||
|
"noEscapePokemon": "{{pokemonName}} 的 {{moveName}} 阻止了你 {{escapeVerb}}!",
|
||||||
|
"runAwaySuccess": "你成功逃脱了!",
|
||||||
|
"runAwayCannotEscape": '你无法逃脱!',
|
||||||
|
"escapeVerbSwitch": "切换",
|
||||||
|
"escapeVerbFlee": "逃跑",
|
||||||
|
"notDisabled": "{{moveName}} 不再被禁用!",
|
||||||
|
"skipItemQuestion": "你确定要跳过拾取道具吗?",
|
||||||
|
"eggHatching": "咦?",
|
||||||
|
"ivScannerUseQuestion": "对 {{pokemonName}} 使用个体值扫描仪?"
|
||||||
|
} as const;
|
9
src/locales/zh_CN/command-ui-handler.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
|
|
||||||
|
export const commandUiHandler: SimpleTranslationEntries = {
|
||||||
|
"fight": "战斗",
|
||||||
|
"ball": "精灵球",
|
||||||
|
"pokemon": "宝可梦",
|
||||||
|
"run": "逃跑",
|
||||||
|
"actionMessage": "要让\n{{pokemonName}} 做什么?",
|
||||||
|
} as const;
|
28
src/locales/zh_CN/config.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { ability } from "./ability";
|
||||||
|
import { battle } from "./battle";
|
||||||
|
import { commandUiHandler } from "./command-ui-handler";
|
||||||
|
import { fightUiHandler } from "./fight-ui-handler";
|
||||||
|
import { menu } from "./menu";
|
||||||
|
import { menuUiHandler } from "./menu-ui-handler";
|
||||||
|
import { move } from "./move";
|
||||||
|
import { pokeball } from "./pokeball";
|
||||||
|
import { pokemon } from "./pokemon";
|
||||||
|
import { pokemonStat } from "./pokemon-stat";
|
||||||
|
import { starterSelectUiHandler } from "./starter-select-ui-handler";
|
||||||
|
import { tutorial } from "./tutorial";
|
||||||
|
|
||||||
|
|
||||||
|
export const zhCnConfig = {
|
||||||
|
ability: ability,
|
||||||
|
battle: battle,
|
||||||
|
commandUiHandler: commandUiHandler,
|
||||||
|
fightUiHandler: fightUiHandler,
|
||||||
|
menuUiHandler: menuUiHandler,
|
||||||
|
menu: menu,
|
||||||
|
move: move,
|
||||||
|
pokeball: pokeball,
|
||||||
|
pokemonStat: pokemonStat,
|
||||||
|
pokemon: pokemon,
|
||||||
|
starterSelectUiHandler: starterSelectUiHandler,
|
||||||
|
tutorial: tutorial
|
||||||
|
}
|
6
src/locales/zh_CN/fight-ui-handler.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
|
|
||||||
|
export const fightUiHandler: SimpleTranslationEntries = {
|
||||||
|
"pp": "PP",
|
||||||
|
"power": "POWER",
|
||||||
|
} as const;
|
23
src/locales/zh_CN/menu-ui-handler.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
|
|
||||||
|
export const menuUiHandler: SimpleTranslationEntries = {
|
||||||
|
"GAME_SETTINGS": '游戏设置',
|
||||||
|
"ACHIEVEMENTS": "成就",
|
||||||
|
"STATS": "数据统计",
|
||||||
|
"VOUCHERS": "兑换券",
|
||||||
|
"EGG_LIST": "蛋列表",
|
||||||
|
"EGG_GACHA": "蛋扭蛋",
|
||||||
|
"MANAGE_DATA": "管理数据",
|
||||||
|
"COMMUNITY": "社区",
|
||||||
|
"RETURN_TO_TITLE": "返回标题画面",
|
||||||
|
"LOG_OUT": "登出",
|
||||||
|
"slot": "存档位 {{slotNumber}}",
|
||||||
|
"importSession": "导入存档",
|
||||||
|
"importSlotSelect": "选择要导入到的存档位。",
|
||||||
|
"exportSession": "导出存档",
|
||||||
|
"exportSlotSelect": "选择要导出的存档位。",
|
||||||
|
"importData": "导入数据",
|
||||||
|
"exportData": "导出数据",
|
||||||
|
"cancel": "取消",
|
||||||
|
"losingProgressionWarning": "你将失去自战斗开始以来的所有进度。是否继续?"
|
||||||
|
} as const;
|
46
src/locales/zh_CN/menu.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The menu namespace holds most miscellaneous text that isn't directly part of the game's
|
||||||
|
* contents or directly related to Pokemon data. This includes menu navigation, settings,
|
||||||
|
* account interactions, descriptive text, etc.
|
||||||
|
*/
|
||||||
|
export const menu: SimpleTranslationEntries = {
|
||||||
|
"cancel": "取消",
|
||||||
|
"continue": "继续",
|
||||||
|
"dailyRun": "每日挑战 (Beta)",
|
||||||
|
"loadGame": "加载游戏",
|
||||||
|
"newGame": "新游戏",
|
||||||
|
"selectGameMode": "选择一个游戏模式",
|
||||||
|
"logInOrCreateAccount": "登录或创建账户以开始游戏。无需邮箱!",
|
||||||
|
"username": "用户名",
|
||||||
|
"password": "密码",
|
||||||
|
"login": "登录",
|
||||||
|
"register": "注册",
|
||||||
|
"emptyUsername": "用户名不能为空",
|
||||||
|
"invalidLoginUsername": "提供的用户名无效",
|
||||||
|
"invalidRegisterUsername": "用户名只能包含字母、数字或下划线",
|
||||||
|
"invalidLoginPassword": "提供的密码无效",
|
||||||
|
"invalidRegisterPassword": "密码必须至少包含 6 个字符",
|
||||||
|
"usernameAlreadyUsed": "提供的用户名已被使用",
|
||||||
|
"accountNonExistent": "提供的用户不存在",
|
||||||
|
"unmatchingPassword": "提供的密码不匹配",
|
||||||
|
"passwordNotMatchingConfirmPassword": "密码必须与确认密码一致",
|
||||||
|
"confirmPassword": "确认密码",
|
||||||
|
"registrationAgeWarning": "注册即表示您确认您已年满 13 岁。",
|
||||||
|
"backToLogin": "返回登录",
|
||||||
|
"failedToLoadSaveData": "读取存档数据失败。请重新加载页面。如果问题仍然存在,请联系管理员。",
|
||||||
|
"sessionSuccess": "会话加载成功。",
|
||||||
|
"failedToLoadSession": "无法加载您的会话数据。它可能已损坏。",
|
||||||
|
"boyOrGirl": "你是男孩还是女孩?",
|
||||||
|
"boy": "男孩",
|
||||||
|
"girl": "女孩",
|
||||||
|
"dailyRankings": "每日排名",
|
||||||
|
"weeklyRankings": "每周排名",
|
||||||
|
"noRankings": "无排名",
|
||||||
|
"loading": "加载中…",
|
||||||
|
"playersOnline": "在线玩家",
|
||||||
|
"empty": "空",
|
||||||
|
"yes": "是",
|
||||||
|
"no": "否",
|
||||||
|
} as const;
|
3812
src/locales/zh_CN/move.ts
Normal file
10
src/locales/zh_CN/pokeball.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
|
|
||||||
|
export const pokeball: SimpleTranslationEntries = {
|
||||||
|
"pokeBall": "精灵球",
|
||||||
|
"greatBall": "超级球",
|
||||||
|
"ultraBall": "高级球",
|
||||||
|
"rogueBall": "肉鸽球",
|
||||||
|
"masterBall": "大师球",
|
||||||
|
"luxuryBall": "豪华球",
|
||||||
|
} as const;
|
16
src/locales/zh_CN/pokemon-stat.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
|
|
||||||
|
export const pokemonStat: SimpleTranslationEntries = {
|
||||||
|
"HP": "最大HP",
|
||||||
|
"HPshortened": "最大HP",
|
||||||
|
"ATK": "攻击",
|
||||||
|
"ATKshortened": "攻击",
|
||||||
|
"DEF": "防御",
|
||||||
|
"DEFshortened": "防御",
|
||||||
|
"SPATK": "特攻",
|
||||||
|
"SPATKshortened": "特攻",
|
||||||
|
"SPDEF": "特防",
|
||||||
|
"SPDEFshortened": "特防",
|
||||||
|
"SPD": "速度",
|
||||||
|
"SPDshortened": "速度"
|
||||||
|
} as const;
|
1086
src/locales/zh_CN/pokemon.ts
Normal file
32
src/locales/zh_CN/starter-select-ui-handler.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The menu namespace holds most miscellaneous text that isn't directly part of the game's
|
||||||
|
* contents or directly related to Pokemon data. This includes menu navigation, settings,
|
||||||
|
* account interactions, descriptive text, etc.
|
||||||
|
*/
|
||||||
|
export const starterSelectUiHandler: SimpleTranslationEntries = {
|
||||||
|
"confirmStartTeam":'使用这些宝可梦开始游戏吗?',
|
||||||
|
"growthRate": "成长速度:",
|
||||||
|
"ability": "特性:",
|
||||||
|
"passive": "被动:",
|
||||||
|
"nature": "性格:",
|
||||||
|
"eggMoves": '蛋招式',
|
||||||
|
"start": "开始",
|
||||||
|
"addToParty": "加入队伍",
|
||||||
|
"toggleIVs": '切换个体值',
|
||||||
|
"manageMoves": '管理招式',
|
||||||
|
"useCandies": '使用糖果',
|
||||||
|
"selectMoveSwapOut": "选择要替换的招式。",
|
||||||
|
"selectMoveSwapWith": "选择要替换成的招式",
|
||||||
|
"unlockPassive": "解锁被动",
|
||||||
|
"reduceCost": "降低花费",
|
||||||
|
"cycleShiny": "R: 切换闪光",
|
||||||
|
"cycleForm": 'F: 切换形态',
|
||||||
|
"cycleGender": 'G: 切换性别',
|
||||||
|
"cycleAbility": 'E: 切换特性',
|
||||||
|
"cycleNature": 'N: 切换性格',
|
||||||
|
"cycleVariant": 'V: 切换变种',
|
||||||
|
"enablePassive": "启用被动",
|
||||||
|
"disablePassive": "禁用被动"
|
||||||
|
}
|
42
src/locales/zh_CN/tutorial.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
|
|
||||||
|
export const tutorial: SimpleTranslationEntries = {
|
||||||
|
"intro": `欢迎来到PokéRogue!这是一款以战斗为核心的融合了roguelite元素的宝可梦同人游戏。
|
||||||
|
$本游戏未进行商业化,我们没有Pokémon或Pokémon使用的版权资产的所有权。
|
||||||
|
$游戏仍在开发中,但已可完整游玩。\n如需报告错误,请使用 Discord 社区。
|
||||||
|
$如果游戏运行缓慢,请确保在浏览器设置中打开了“硬件加速”。`,
|
||||||
|
|
||||||
|
"accessMenu": `在等待输入时,按 M 或 Escape 键可访问菜单。\n菜单包含设置和各种功能。`,
|
||||||
|
|
||||||
|
"menu": `在此菜单中,您可以访问设置。
|
||||||
|
$在设置中,您可以更改游戏速度、窗口样式和其他选项。
|
||||||
|
$这里还有各种其他功能,请务必全部查看!`,
|
||||||
|
|
||||||
|
"starterSelect": `在此页面中,您可以选择您的初始宝可梦。\n这些是您最初的队伍成员。
|
||||||
|
$每个初始宝可梦都有一个费用。您的队伍最多可以拥有\n6 名成员,只要总费用不超过 10。
|
||||||
|
$您还可以根据\n您捕获或孵化的变种选择性别、特性和形态。
|
||||||
|
$一个物种的个体值是您捕获或孵化的所有宝可梦中最好的,所以尽量获得更多同种宝可梦!`,
|
||||||
|
|
||||||
|
"pokerus": `每天随机 3 个可选的初始宝可梦会有紫色边框。
|
||||||
|
$如果您看到您拥有的初始宝可梦带有紫色边框,\n请尝试将其添加到您的队伍中。请务必查看其概况!`,
|
||||||
|
|
||||||
|
"statChange": `只要您的宝可梦没有被召回,属性变化就会在战斗中持续存在。
|
||||||
|
$在训练家战斗之前和进入新的宝可梦群落之前,您的宝可梦会被召回。
|
||||||
|
$您还可以通过按住 C 或 Shift 键来查看场上宝可梦的能力变化。`,
|
||||||
|
|
||||||
|
"selectItem": `每次战斗后,您都可以选择 3 个随机物品。\n您只能选择其中一个。
|
||||||
|
$这些物品包括消耗品、宝可梦携带物品和永久被动道具。
|
||||||
|
$大多数非消耗品的效果会以各种方式叠加。
|
||||||
|
$某些物品只有在可以使用时才会出现,例如进化物品。
|
||||||
|
$您还可以使用转移选项在宝可梦之间转移携带物品。
|
||||||
|
$一旦您获得了携带物品,转移选项就会出现在右下角。
|
||||||
|
$您可以用金钱购买消耗品,并且随着您游戏的深入,将会有更多种类的消耗品可供选择。
|
||||||
|
$请务必在选择随机物品之前购买这些消耗品,因为一旦您选择,游戏就会进入下一场战斗。`,
|
||||||
|
|
||||||
|
"eggGacha": `在此页面中,您可以使用您的兑换券兑换\n宝可梦蛋。
|
||||||
|
$蛋需要孵化,并且在每场战斗后都会减少孵化周期。稀有蛋需要更长时间才能孵化。
|
||||||
|
$孵化的宝可梦不会被添加到您的队伍中,它们将被添加到您的初始宝可梦中。
|
||||||
|
$从蛋中孵化的宝可梦通常比\n野生宝可梦具有更好的个体值。
|
||||||
|
$有些宝可梦只能从蛋中获得。
|
||||||
|
$有 3 种不同的扭蛋机可供选择,每种扭蛋机都有不同的\n奖励,请选择最适合您的!`,
|
||||||
|
} as const;
|
@ -144,9 +144,16 @@ class AddPokeballModifierType extends ModifierType implements Localizable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
localize(): void {
|
localize(): void {
|
||||||
|
// TODO: Actually use i18n to localize this description.
|
||||||
this.name = `${this.count}x ${getPokeballName(this.pokeballType)}`;
|
this.name = `${this.count}x ${getPokeballName(this.pokeballType)}`;
|
||||||
this.description = `Receive ${getPokeballName(this.pokeballType)} x${this.count}\nCatch Rate: ${getPokeballCatchMultiplier(this.pokeballType) > -1 ? `${getPokeballCatchMultiplier(this.pokeballType)}x` : 'Certain'}`;
|
this.description = `Receive ${getPokeballName(this.pokeballType)} x${this.count} (Inventory: {AMOUNT}) \nCatch Rate: ${getPokeballCatchMultiplier(this.pokeballType) > -1 ? `${getPokeballCatchMultiplier(this.pokeballType)}x` : 'Certain'}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDescription(scene: BattleScene): string {
|
||||||
|
this.localize();
|
||||||
|
return this.description.replace('{AMOUNT}', scene.pokeballCounts[this.pokeballType].toString());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AddVoucherModifierType extends ModifierType {
|
class AddVoucherModifierType extends ModifierType {
|
||||||
@ -299,7 +306,7 @@ export class PokemonNatureChangeModifierType extends PokemonModifierType {
|
|||||||
protected nature: Nature;
|
protected nature: Nature;
|
||||||
|
|
||||||
constructor(nature: Nature) {
|
constructor(nature: Nature) {
|
||||||
super(`${getNatureName(nature)} Mint`, `Changes a Pokémon\'s nature to ${getNatureName(nature, true, true, true)}`, ((_type, args) => new Modifiers.PokemonNatureChangeModifier(this, (args[0] as PlayerPokemon).id, this.nature)),
|
super(`${getNatureName(nature)} Mint`, `Changes a Pokémon\'s nature to ${getNatureName(nature, true, true, true)} and permanently unlocks the nature for the starter.`, ((_type, args) => new Modifiers.PokemonNatureChangeModifier(this, (args[0] as PlayerPokemon).id, this.nature)),
|
||||||
((pokemon: PlayerPokemon) => {
|
((pokemon: PlayerPokemon) => {
|
||||||
if (pokemon.getNature() === this.nature)
|
if (pokemon.getNature() === this.nature)
|
||||||
return PartyUiHandler.NoEffectMessage;
|
return PartyUiHandler.NoEffectMessage;
|
||||||
@ -948,7 +955,7 @@ export const modifierTypes = {
|
|||||||
ENEMY_DAMAGE_BOOSTER: () => new ModifierType('Damage Token', 'Increases damage by 5%', (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 5), 'wl_item_drop'),
|
ENEMY_DAMAGE_BOOSTER: () => new ModifierType('Damage Token', 'Increases damage by 5%', (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 5), 'wl_item_drop'),
|
||||||
ENEMY_DAMAGE_REDUCTION: () => new ModifierType('Protection Token', 'Reduces incoming damage by 2.5%', (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 2.5), 'wl_guard_spec'),
|
ENEMY_DAMAGE_REDUCTION: () => new ModifierType('Protection Token', 'Reduces incoming damage by 2.5%', (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 2.5), 'wl_guard_spec'),
|
||||||
//ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new Modifiers.EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'),
|
//ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new Modifiers.EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'),
|
||||||
ENEMY_HEAL: () => new ModifierType('Recovery Token', 'Heals 3% of max HP every turn', (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 3), 'wl_potion'),
|
ENEMY_HEAL: () => new ModifierType('Recovery Token', 'Heals 2% of max HP every turn', (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 2), 'wl_potion'),
|
||||||
ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Poison Token', 10, StatusEffect.POISON, 'wl_antidote'),
|
ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Poison Token', 10, StatusEffect.POISON, 'wl_antidote'),
|
||||||
ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Paralyze Token', 10, StatusEffect.PARALYSIS, 'wl_paralyze_heal'),
|
ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Paralyze Token', 10, StatusEffect.PARALYSIS, 'wl_paralyze_heal'),
|
||||||
ENEMY_ATTACK_SLEEP_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Sleep Token', 10, StatusEffect.SLEEP, 'wl_awakening'),
|
ENEMY_ATTACK_SLEEP_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Sleep Token', 10, StatusEffect.SLEEP, 'wl_awakening'),
|
||||||
@ -997,7 +1004,7 @@ const modifierPool: ModifierPool = {
|
|||||||
new WeightedModifierType(modifierTypes.REVIVE, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.REVIVE, (party: Pokemon[]) => {
|
||||||
const faintedPartyMemberCount = Math.min(party.filter(p => p.isFainted()).length, 3);
|
const faintedPartyMemberCount = Math.min(party.filter(p => p.isFainted()).length, 3);
|
||||||
return faintedPartyMemberCount * 9;
|
return faintedPartyMemberCount * 9;
|
||||||
}, 3),
|
}, 27),
|
||||||
new WeightedModifierType(modifierTypes.MAX_REVIVE, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.MAX_REVIVE, (party: Pokemon[]) => {
|
||||||
const faintedPartyMemberCount = Math.min(party.filter(p => p.isFainted()).length, 3);
|
const faintedPartyMemberCount = Math.min(party.filter(p => p.isFainted()).length, 3);
|
||||||
return faintedPartyMemberCount * 3;
|
return faintedPartyMemberCount * 3;
|
||||||
|
@ -8,20 +8,20 @@ import { Stat } from "../data/pokemon-stat";
|
|||||||
import { addTextObject, TextStyle } from "../ui/text";
|
import { addTextObject, TextStyle } from "../ui/text";
|
||||||
import { Type } from '../data/type';
|
import { Type } from '../data/type';
|
||||||
import { EvolutionPhase } from '../evolution-phase';
|
import { EvolutionPhase } from '../evolution-phase';
|
||||||
import { FusionSpeciesFormEvolution, pokemonEvolutions } from '../data/pokemon-evolutions';
|
import { FusionSpeciesFormEvolution, pokemonEvolutions, pokemonPrevolutions } from '../data/pokemon-evolutions';
|
||||||
import { getPokemonMessage } from '../messages';
|
import { getPokemonMessage } from '../messages';
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import { TempBattleStat } from '../data/temp-battle-stat';
|
import { TempBattleStat } from '../data/temp-battle-stat';
|
||||||
import { BerryType, getBerryEffectFunc, getBerryPredicate } from '../data/berry';
|
import { BerryType, getBerryEffectFunc, getBerryPredicate } from '../data/berry';
|
||||||
import { StatusEffect, getStatusEffectHealText } from '../data/status-effect';
|
import { StatusEffect, getStatusEffectHealText } from '../data/status-effect';
|
||||||
import { MoneyAchv, achvs } from '../system/achv';
|
import { achvs } from '../system/achv';
|
||||||
import { VoucherType } from '../system/voucher';
|
import { VoucherType } from '../system/voucher';
|
||||||
import { PreventBerryUseAbAttr, applyAbAttrs } from '../data/ability';
|
|
||||||
import { FormChangeItem, SpeciesFormChangeItemTrigger } from '../data/pokemon-forms';
|
import { FormChangeItem, SpeciesFormChangeItemTrigger } from '../data/pokemon-forms';
|
||||||
import { Nature } from '#app/data/nature';
|
import { Nature } from '#app/data/nature';
|
||||||
import { BattlerTagType } from '#app/data/enums/battler-tag-type';
|
import { BattlerTagType } from '#app/data/enums/battler-tag-type';
|
||||||
|
import * as Overrides from '../overrides';
|
||||||
|
import { ModifierType, modifierTypes } from './modifier-type';
|
||||||
|
|
||||||
type ModifierType = ModifierTypes.ModifierType;
|
|
||||||
export type ModifierPredicate = (modifier: Modifier) => boolean;
|
export type ModifierPredicate = (modifier: Modifier) => boolean;
|
||||||
|
|
||||||
const iconOverflowIndex = 24;
|
const iconOverflowIndex = 24;
|
||||||
@ -1090,6 +1090,13 @@ export class PokemonNatureChangeModifier extends ConsumablePokemonModifier {
|
|||||||
apply(args: any[]): boolean {
|
apply(args: any[]): boolean {
|
||||||
const pokemon = args[0] as Pokemon;
|
const pokemon = args[0] as Pokemon;
|
||||||
pokemon.natureOverride = this.nature;
|
pokemon.natureOverride = this.nature;
|
||||||
|
let speciesId = pokemon.species.speciesId;
|
||||||
|
pokemon.scene.gameData.dexData[speciesId].natureAttr |= Math.pow(2, this.nature + 1);
|
||||||
|
|
||||||
|
while (pokemonPrevolutions.hasOwnProperty(speciesId)) {
|
||||||
|
speciesId = pokemonPrevolutions[speciesId];
|
||||||
|
pokemon.scene.gameData.dexData[speciesId].natureAttr |= Math.pow(2, this.nature + 1);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1998,7 +2005,7 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier {
|
|||||||
super(type, stackCount);
|
super(type, stackCount);
|
||||||
|
|
||||||
// Hardcode temporarily
|
// Hardcode temporarily
|
||||||
this.healPercent = 3;
|
this.healPercent = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
match(modifier: Modifier): boolean {
|
match(modifier: Modifier): boolean {
|
||||||
@ -2027,7 +2034,7 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getMaxStackCount(scene: BattleScene): integer {
|
getMaxStackCount(scene: BattleScene): integer {
|
||||||
return 10;
|
return 15;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2169,4 +2176,63 @@ export class EnemyFusionChanceModifier extends EnemyPersistentModifier {
|
|||||||
getMaxStackCount(scene: BattleScene): integer {
|
getMaxStackCount(scene: BattleScene): integer {
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses override from overrides.ts to set PersistentModifiers for starting a new game
|
||||||
|
* @param scene current BattleScene
|
||||||
|
* @param player is this for player for enemy
|
||||||
|
*/
|
||||||
|
export function overrideModifiers(scene: BattleScene, player: boolean = true): void {
|
||||||
|
const modifierOverride = player ? Overrides.STARTING_MODIFIER_OVERRIDE : Overrides.OPP_MODIFIER_OVERRIDE;
|
||||||
|
if (!modifierOverride || modifierOverride.length === 0 || !scene) return; // if no override, do nothing
|
||||||
|
// if it's the opponent, we clear all his current modifiers to avoid stacking
|
||||||
|
if (!player) {
|
||||||
|
scene.clearEnemyModifiers();
|
||||||
|
}
|
||||||
|
// we loop through all the modifier name given in the override file
|
||||||
|
modifierOverride.forEach(item => {
|
||||||
|
const modifierName = item.name;
|
||||||
|
const qty = item.count || 1;
|
||||||
|
if (!modifierTypes.hasOwnProperty(modifierName)) return; // if the modifier does not exist, we skip it
|
||||||
|
const modifierType: ModifierType = modifierTypes[modifierName]();
|
||||||
|
const modifier: PersistentModifier = modifierType.withIdFromFunc(modifierTypes[modifierName]).newModifier() as PersistentModifier;
|
||||||
|
modifier.stackCount = qty;
|
||||||
|
if (player) {
|
||||||
|
scene.addModifier(modifier, true, false, false, true);
|
||||||
|
} else {
|
||||||
|
scene.addEnemyModifier(modifier, true, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses override from overrides.ts to set PokemonHeldItemModifiers for starting a new game
|
||||||
|
* @param scene current BattleScene
|
||||||
|
* @param player is this for player for enemy
|
||||||
|
*/
|
||||||
|
export function overrideHeldItems(scene: BattleScene, pokemon: Pokemon, player: boolean = true): void {
|
||||||
|
const heldItemsOverride = player ? Overrides.STARTING_HELD_ITEMS_OVERRIDE : Overrides.OPP_HELD_ITEMS_OVERRIDE;
|
||||||
|
if (!heldItemsOverride || heldItemsOverride.length === 0 || !scene) return; // if no override, do nothing
|
||||||
|
// we loop through all the itemName given in the override file
|
||||||
|
heldItemsOverride.forEach(item => {
|
||||||
|
const itemName = item.name;
|
||||||
|
const qty = item.count || 1;
|
||||||
|
if (!modifierTypes.hasOwnProperty(itemName)) return; // if the item does not exist, we skip it
|
||||||
|
const modifierType: ModifierType = modifierTypes[itemName](); // we retrieve the item in the list
|
||||||
|
var itemModifier: PokemonHeldItemModifier;
|
||||||
|
if (modifierType instanceof ModifierTypes.ModifierTypeGenerator) {
|
||||||
|
itemModifier = modifierType.generateType(null, [item.type]).withIdFromFunc(modifierTypes[itemName]).newModifier(pokemon) as PokemonHeldItemModifier;
|
||||||
|
} else {
|
||||||
|
itemModifier = modifierType.withIdFromFunc(modifierTypes[itemName]).newModifier(pokemon) as PokemonHeldItemModifier;
|
||||||
|
}
|
||||||
|
// we create the item
|
||||||
|
itemModifier.pokemonId = pokemon.id; // we assign the created item to the pokemon
|
||||||
|
itemModifier.stackCount = qty; // we say how many items we want
|
||||||
|
if (player) {
|
||||||
|
scene.addModifier(itemModifier, true, false, false, true);
|
||||||
|
} else {
|
||||||
|
scene.addEnemyModifier(itemModifier, true, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
@ -3,23 +3,84 @@ import { Abilities } from "./data/enums/abilities";
|
|||||||
import { Biome } from "./data/enums/biome";
|
import { Biome } from "./data/enums/biome";
|
||||||
import { Moves } from "./data/enums/moves";
|
import { Moves } from "./data/enums/moves";
|
||||||
import { WeatherType } from "./data/weather";
|
import { WeatherType } from "./data/weather";
|
||||||
|
import { Variant } from './data/variant';
|
||||||
|
import { BerryType } from './data/berry';
|
||||||
|
import { TempBattleStat } from './data/temp-battle-stat';
|
||||||
|
import { Nature } from './data/nature';
|
||||||
|
import { Type } from './data/type';
|
||||||
|
import { Stat } from './data/pokemon-stat';
|
||||||
|
|
||||||
export const SEED_OVERRIDE = '';
|
/**
|
||||||
export const STARTER_SPECIES_OVERRIDE = 0;
|
* Overrides for testing different in game situations
|
||||||
export const STARTER_FORM_OVERRIDE = 0;
|
* if an override name starts with "STARTING", it will apply when a new run begins
|
||||||
export const STARTING_LEVEL_OVERRIDE = 0;
|
*/
|
||||||
export const STARTING_WAVE_OVERRIDE = 0;
|
|
||||||
export const STARTING_BIOME_OVERRIDE = Biome.TOWN;
|
|
||||||
export const STARTING_MONEY_OVERRIDE = 0;
|
|
||||||
export const WEATHER_OVERRIDE = WeatherType.NONE;
|
|
||||||
|
|
||||||
export const ABILITY_OVERRIDE = Abilities.NONE;
|
/**
|
||||||
export const MOVE_OVERRIDE = Moves.NONE;
|
* OVERALL OVERRIDES
|
||||||
export const MOVE_OVERRIDE_2 = Moves.NONE;
|
*/
|
||||||
export const OPP_SPECIES_OVERRIDE = 0;
|
|
||||||
export const OPP_ABILITY_OVERRIDE = Abilities.NONE;
|
|
||||||
export const OPP_MOVE_OVERRIDE = Moves.NONE;
|
|
||||||
export const OPP_MOVE_OVERRIDE_2 = Moves.NONE;
|
|
||||||
|
|
||||||
export const OPP_SHINY_OVERRIDE = false;
|
// a specific seed (default: a random string of 24 characters)
|
||||||
export const OPP_VARIANT_OVERRIDE = 0;
|
export const SEED_OVERRIDE: string = '';
|
||||||
|
export const WEATHER_OVERRIDE: WeatherType = WeatherType.NONE;
|
||||||
|
export const DOUBLE_BATTLE_OVERRIDE: boolean = false;
|
||||||
|
export const STARTING_WAVE_OVERRIDE: integer = 0;
|
||||||
|
export const STARTING_BIOME_OVERRIDE: Biome = Biome.TOWN;
|
||||||
|
// default 1000
|
||||||
|
export const STARTING_MONEY_OVERRIDE: integer = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PLAYER OVERRIDES
|
||||||
|
*/
|
||||||
|
|
||||||
|
// forms can be found in pokemon-species.ts
|
||||||
|
export const STARTER_FORM_OVERRIDE: integer = 0;
|
||||||
|
// default 5 or 20 for Daily
|
||||||
|
export const STARTING_LEVEL_OVERRIDE: integer = 0;
|
||||||
|
export const ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
||||||
|
export const PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
||||||
|
export const MOVESET_OVERRIDE: Array<Moves> = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OPPONENT / ENEMY OVERRIDES
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const OPP_ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
||||||
|
export const OPP_PASSIVE_ABILITY_OVERRIDE = Abilities.NONE;
|
||||||
|
export const OPP_MOVESET_OVERRIDE: Array<Moves> = [];
|
||||||
|
export const OPP_SHINY_OVERRIDE: boolean = false;
|
||||||
|
export const OPP_VARIANT_OVERRIDE: Variant = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPECIES OVERRIDE
|
||||||
|
* will only apply to the first starter in your party or each enemy pokemon
|
||||||
|
* default is 0 to not override
|
||||||
|
* @example SPECIES_OVERRIDE = Species.Bulbasaur;
|
||||||
|
*/
|
||||||
|
export const STARTER_SPECIES_OVERRIDE: Species | integer = 0;
|
||||||
|
export const OPP_SPECIES_OVERRIDE: Species | integer = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MODIFIER / ITEM OVERRIDES
|
||||||
|
* if count is not provided, it will default to 1
|
||||||
|
* @example Modifier Override [{name: "EXP_SHARE", count: 2}]
|
||||||
|
* @example Held Item Override [{name: "LUCKY_EGG"}]
|
||||||
|
*
|
||||||
|
* Some items are generated based on a sub-type (i.e. berries), to override those:
|
||||||
|
* @example [{name: "BERRY", count: 5, type: BerryType.SITRUS}]
|
||||||
|
* types are listed in interface below
|
||||||
|
* - TempBattleStat is for TEMP_STAT_BOOSTER / X Items (Dire hit is separate)
|
||||||
|
* - Stat is for BASE_STAT_BOOSTER / Vitamin
|
||||||
|
* - Nature is for MINT
|
||||||
|
* - Type is for TERA_SHARD or ATTACK_TYPE_BOOSTER (type boosting items i.e Silk Scarf)
|
||||||
|
* - BerryType is for BERRY
|
||||||
|
*/
|
||||||
|
interface ModifierOverride {
|
||||||
|
name: string,
|
||||||
|
count?: integer
|
||||||
|
type?: TempBattleStat|Stat|Nature|Type|BerryType
|
||||||
|
}
|
||||||
|
export const STARTING_MODIFIER_OVERRIDE: Array<ModifierOverride> = [];
|
||||||
|
export const OPP_MODIFIER_OVERRIDE: Array<ModifierOverride> = [];
|
||||||
|
|
||||||
|
export const STARTING_HELD_ITEMS_OVERRIDE: Array<ModifierOverride> = [];
|
||||||
|
export const OPP_HELD_ITEMS_OVERRIDE: Array<ModifierOverride> = [];
|
||||||
|
172
src/phases.ts
@ -1,12 +1,12 @@
|
|||||||
import BattleScene, { bypassLogin, startingWave } from "./battle-scene";
|
import BattleScene, { AnySound, bypassLogin, startingWave } from "./battle-scene";
|
||||||
import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon";
|
import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon";
|
||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
import { Moves } from "./data/enums/moves";
|
import { Moves } from "./data/enums/moves";
|
||||||
import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, FixedDamageAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariableTargetAttr } from "./data/move";
|
import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, FixedDamageAttr, PostVictoryStatChangeAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariableTargetAttr } from "./data/move";
|
||||||
import { Mode } from './ui/ui';
|
import { Mode } from './ui/ui';
|
||||||
import { Command } from "./ui/command-ui-handler";
|
import { Command } from "./ui/command-ui-handler";
|
||||||
import { Stat } from "./data/pokemon-stat";
|
import { Stat } from "./data/pokemon-stat";
|
||||||
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, PokemonMoveAccuracyBoosterModifier } from "./modifier/modifier";
|
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, PokemonMoveAccuracyBoosterModifier, overrideModifiers, overrideHeldItems } from "./modifier/modifier";
|
||||||
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
|
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
|
||||||
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
|
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
|
||||||
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
|
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
|
||||||
@ -23,7 +23,7 @@ import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFu
|
|||||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||||
import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TrappedTag } from "./data/battler-tags";
|
import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TrappedTag } from "./data/battler-tags";
|
||||||
import { BattlerTagType } from "./data/enums/battler-tag-type";
|
import { BattlerTagType } from "./data/enums/battler-tag-type";
|
||||||
import { getPokemonMessage } from "./messages";
|
import { getPokemonMessage, getPokemonPrefix } from "./messages";
|
||||||
import { Starter } from "./ui/starter-select-ui-handler";
|
import { Starter } from "./ui/starter-select-ui-handler";
|
||||||
import { Gender } from "./data/gender";
|
import { Gender } from "./data/gender";
|
||||||
import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather";
|
import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather";
|
||||||
@ -55,10 +55,10 @@ import { OptionSelectConfig, OptionSelectItem } from "./ui/abstact-option-select
|
|||||||
import { SaveSlotUiMode } from "./ui/save-slot-select-ui-handler";
|
import { SaveSlotUiMode } from "./ui/save-slot-select-ui-handler";
|
||||||
import { fetchDailyRunSeed, getDailyRunStarters } from "./data/daily-run";
|
import { fetchDailyRunSeed, getDailyRunStarters } from "./data/daily-run";
|
||||||
import { GameModes, gameModes } from "./game-mode";
|
import { GameModes, gameModes } from "./game-mode";
|
||||||
import { getPokemonSpecies, speciesStarters } from "./data/pokemon-species";
|
import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./data/pokemon-species";
|
||||||
import i18next from './plugins/i18n';
|
import i18next from './plugins/i18n';
|
||||||
import { Abilities } from "./data/enums/abilities";
|
import { Abilities } from "./data/enums/abilities";
|
||||||
import { STARTER_FORM_OVERRIDE, STARTER_SPECIES_OVERRIDE } from './overrides';
|
import * as Overrides from './overrides';
|
||||||
|
|
||||||
export class LoginPhase extends Phase {
|
export class LoginPhase extends Phase {
|
||||||
private showText: boolean;
|
private showText: boolean;
|
||||||
@ -487,12 +487,12 @@ export class SelectStarterPhase extends Phase {
|
|||||||
const party = this.scene.getParty();
|
const party = this.scene.getParty();
|
||||||
const loadPokemonAssets: Promise<void>[] = [];
|
const loadPokemonAssets: Promise<void>[] = [];
|
||||||
starters.forEach((starter: Starter, i: integer) => {
|
starters.forEach((starter: Starter, i: integer) => {
|
||||||
if (!i && STARTER_SPECIES_OVERRIDE)
|
if (!i && Overrides.STARTER_SPECIES_OVERRIDE)
|
||||||
starter.species = getPokemonSpecies(STARTER_SPECIES_OVERRIDE as Species);
|
starter.species = getPokemonSpecies(Overrides.STARTER_SPECIES_OVERRIDE as Species);
|
||||||
const starterProps = this.scene.gameData.getSpeciesDexAttrProps(starter.species, starter.dexAttr);
|
const starterProps = this.scene.gameData.getSpeciesDexAttrProps(starter.species, starter.dexAttr);
|
||||||
let starterFormIndex = Math.min(starterProps.formIndex, Math.max(starter.species.forms.length - 1, 0));
|
let starterFormIndex = Math.min(starterProps.formIndex, Math.max(starter.species.forms.length - 1, 0));
|
||||||
if (!i && STARTER_SPECIES_OVERRIDE)
|
if (!i && Overrides.STARTER_SPECIES_OVERRIDE)
|
||||||
starterFormIndex = STARTER_FORM_OVERRIDE;
|
starterFormIndex = Overrides.STARTER_FORM_OVERRIDE;
|
||||||
const starterGender = starter.species.malePercent !== null
|
const starterGender = starter.species.malePercent !== null
|
||||||
? !starterProps.female ? Gender.MALE : Gender.FEMALE
|
? !starterProps.female ? Gender.MALE : Gender.FEMALE
|
||||||
: Gender.GENDERLESS;
|
: Gender.GENDERLESS;
|
||||||
@ -510,6 +510,8 @@ export class SelectStarterPhase extends Phase {
|
|||||||
party.push(starterPokemon);
|
party.push(starterPokemon);
|
||||||
loadPokemonAssets.push(starterPokemon.loadAssets());
|
loadPokemonAssets.push(starterPokemon.loadAssets());
|
||||||
});
|
});
|
||||||
|
overrideModifiers(this.scene);
|
||||||
|
overrideHeldItems(this.scene, party[0]);
|
||||||
Promise.all(loadPokemonAssets).then(() => {
|
Promise.all(loadPokemonAssets).then(() => {
|
||||||
SoundFade.fadeOut(this.scene, this.scene.sound.get('menu'), 500, true);
|
SoundFade.fadeOut(this.scene, this.scene.sound.get('menu'), 500, true);
|
||||||
this.scene.time.delayedCall(500, () => this.scene.playBgm());
|
this.scene.time.delayedCall(500, () => this.scene.playBgm());
|
||||||
@ -2046,7 +2048,7 @@ export class TurnEndPhase extends FieldPhase {
|
|||||||
pokemon.lapseTags(BattlerTagLapseType.TURN_END);
|
pokemon.lapseTags(BattlerTagLapseType.TURN_END);
|
||||||
|
|
||||||
if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) {
|
if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) {
|
||||||
this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('battle:notDisabled', { moveName: allMoves[pokemon.summonData.disabledMove].name })));
|
this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('battle:notDisabled', { pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, moveName: allMoves[pokemon.summonData.disabledMove].name })));
|
||||||
pokemon.summonData.disabledMove = Moves.NONE;
|
pokemon.summonData.disabledMove = Moves.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2158,6 +2160,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
public targets: BattlerIndex[];
|
public targets: BattlerIndex[];
|
||||||
protected followUp: boolean;
|
protected followUp: boolean;
|
||||||
protected ignorePp: boolean;
|
protected ignorePp: boolean;
|
||||||
|
protected failed: boolean;
|
||||||
protected cancelled: boolean;
|
protected cancelled: boolean;
|
||||||
|
|
||||||
constructor(scene: BattleScene, pokemon: Pokemon, targets: BattlerIndex[], move: PokemonMove, followUp?: boolean, ignorePp?: boolean) {
|
constructor(scene: BattleScene, pokemon: Pokemon, targets: BattlerIndex[], move: PokemonMove, followUp?: boolean, ignorePp?: boolean) {
|
||||||
@ -2168,6 +2171,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
this.move = move;
|
this.move = move;
|
||||||
this.followUp = !!followUp;
|
this.followUp = !!followUp;
|
||||||
this.ignorePp = !!ignorePp;
|
this.ignorePp = !!ignorePp;
|
||||||
|
this.failed = false;
|
||||||
this.cancelled = false;
|
this.cancelled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2175,6 +2179,12 @@ export class MovePhase extends BattlePhase {
|
|||||||
return this.pokemon.isActive(true) && this.move.isUsable(this.pokemon, this.ignorePp) && !!this.targets.length;
|
return this.pokemon.isActive(true) && this.move.isUsable(this.pokemon, this.ignorePp) && !!this.targets.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Signifies the current move should fail but still use PP */
|
||||||
|
fail(): void {
|
||||||
|
this.failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Signifies the current move should cancel and retain PP */
|
||||||
cancel(): void {
|
cancel(): void {
|
||||||
this.cancelled = true;
|
this.cancelled = true;
|
||||||
}
|
}
|
||||||
@ -2214,7 +2224,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
this.targets[0] = attacker.getBattlerIndex();
|
this.targets[0] = attacker.getBattlerIndex();
|
||||||
}
|
}
|
||||||
if (this.targets[0] === BattlerIndex.ATTACKER) {
|
if (this.targets[0] === BattlerIndex.ATTACKER) {
|
||||||
this.cancel();
|
this.fail(); // Marks the move as failed for later in doMove
|
||||||
this.showMoveText();
|
this.showMoveText();
|
||||||
this.showFailedText();
|
this.showFailedText();
|
||||||
}
|
}
|
||||||
@ -2234,11 +2244,24 @@ export class MovePhase extends BattlePhase {
|
|||||||
this.pokemon.turnData.acted = true; // Record that the move was attempted, even if it fails
|
this.pokemon.turnData.acted = true; // Record that the move was attempted, even if it fails
|
||||||
|
|
||||||
this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE);
|
this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE);
|
||||||
|
|
||||||
|
let ppUsed = 1;
|
||||||
|
// Filter all opponents to include only those this move is targeting
|
||||||
|
const targetedOpponents = this.pokemon.getOpponents().filter(o => this.targets.includes(o.getBattlerIndex()));
|
||||||
|
for (let opponent of targetedOpponents) {
|
||||||
|
if (this.move.ppUsed + ppUsed >= this.move.getMovePp()) // If we're already at max PP usage, stop checking
|
||||||
|
break;
|
||||||
|
if (opponent.hasAbilityWithAttr(IncreasePpAbAttr)) // Accounting for abilities like Pressure
|
||||||
|
ppUsed++;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.followUp && this.canMove() && !this.cancelled) {
|
if (!this.followUp && this.canMove() && !this.cancelled) {
|
||||||
this.pokemon.lapseTags(BattlerTagLapseType.MOVE);
|
this.pokemon.lapseTags(BattlerTagLapseType.MOVE);
|
||||||
}
|
}
|
||||||
if (this.cancelled) {
|
if (this.cancelled || this.failed) {
|
||||||
|
if (this.failed)
|
||||||
|
this.move.usePp(ppUsed); // Only use PP if the move failed
|
||||||
|
|
||||||
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
|
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
|
||||||
return this.end();
|
return this.end();
|
||||||
}
|
}
|
||||||
@ -2253,23 +2276,12 @@ export class MovePhase extends BattlePhase {
|
|||||||
if ((moveQueue.length && moveQueue[0].move === Moves.NONE) || !targets.length) {
|
if ((moveQueue.length && moveQueue[0].move === Moves.NONE) || !targets.length) {
|
||||||
moveQueue.shift();
|
moveQueue.shift();
|
||||||
this.cancel();
|
this.cancel();
|
||||||
}
|
|
||||||
|
|
||||||
if (this.cancelled) {
|
|
||||||
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
|
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
|
||||||
return this.end();
|
return this.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!moveQueue.length || !moveQueue.shift().ignorePP) {
|
if (!moveQueue.length || !moveQueue.shift().ignorePP) // using .shift here clears out two turn moves once they've been used
|
||||||
this.move.ppUsed++;
|
this.move.usePp(ppUsed);
|
||||||
const targetedOpponents = this.pokemon.getOpponents().filter(o => this.targets.includes(o.getBattlerIndex()));
|
|
||||||
for (let opponent of targetedOpponents) {
|
|
||||||
if (this.move.ppUsed === this.move.getMove().pp)
|
|
||||||
break;
|
|
||||||
if (opponent.hasAbilityWithAttr(IncreasePpAbAttr))
|
|
||||||
this.move.ppUsed = Math.min(this.move.ppUsed + 1, this.move.getMovePp());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!allMoves[this.move.moveId].getAttrs(CopyMoveAttr).length)
|
if (!allMoves[this.move.moveId].getAttrs(CopyMoveAttr).length)
|
||||||
this.scene.currentBattle.lastMove = this.move.moveId;
|
this.scene.currentBattle.lastMove = this.move.moveId;
|
||||||
@ -3142,8 +3154,16 @@ export class FaintPhase extends PokemonPhase {
|
|||||||
alivePlayField.forEach(p => applyPostKnockOutAbAttrs(PostKnockOutAbAttr, p, pokemon));
|
alivePlayField.forEach(p => applyPostKnockOutAbAttrs(PostKnockOutAbAttr, p, pokemon));
|
||||||
if (pokemon.turnData?.attacksReceived?.length) {
|
if (pokemon.turnData?.attacksReceived?.length) {
|
||||||
const defeatSource = this.scene.getPokemonById(pokemon.turnData.attacksReceived[0].sourceId);
|
const defeatSource = this.scene.getPokemonById(pokemon.turnData.attacksReceived[0].sourceId);
|
||||||
if (defeatSource?.isOnField())
|
if (defeatSource?.isOnField()) {
|
||||||
applyPostVictoryAbAttrs(PostVictoryAbAttr, defeatSource);
|
applyPostVictoryAbAttrs(PostVictoryAbAttr, defeatSource);
|
||||||
|
const pvmove = allMoves[pokemon.turnData.attacksReceived[0].move];
|
||||||
|
const pvattrs = pvmove.getAttrs(PostVictoryStatChangeAttr);
|
||||||
|
if (pvattrs.length) {
|
||||||
|
for (let pvattr of pvattrs) {
|
||||||
|
pvattr.applyPostVictory(defeatSource, defeatSource, pvmove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.player) {
|
if (this.player) {
|
||||||
@ -3472,8 +3492,40 @@ export class GameOverModifierRewardPhase extends ModifierRewardPhase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class RibbonModifierRewardPhase extends ModifierRewardPhase {
|
||||||
|
private species: PokemonSpecies;
|
||||||
|
|
||||||
|
constructor(scene: BattleScene, modifierTypeFunc: ModifierTypeFunc, species: PokemonSpecies) {
|
||||||
|
super(scene, modifierTypeFunc);
|
||||||
|
|
||||||
|
this.species = species;
|
||||||
|
}
|
||||||
|
|
||||||
|
doReward(): Promise<void> {
|
||||||
|
return new Promise<void>(resolve => {
|
||||||
|
const newModifier = this.modifierType.newModifier();
|
||||||
|
this.scene.addModifier(newModifier).then(() => {
|
||||||
|
this.scene.gameData.saveSystem().then(success => {
|
||||||
|
if (success) {
|
||||||
|
this.scene.playSound('level_up_fanfare');
|
||||||
|
this.scene.ui.setMode(Mode.MESSAGE);
|
||||||
|
this.scene.arenaBg.setVisible(false);
|
||||||
|
this.scene.ui.fadeIn(250).then(() => {
|
||||||
|
this.scene.ui.showText(`${this.species.name} beat ${this.scene.gameMode.getName()} Mode for the first time!\nYou received ${newModifier.type.name}!`, null, () => {
|
||||||
|
resolve();
|
||||||
|
}, null, true, 1500);
|
||||||
|
});
|
||||||
|
} else
|
||||||
|
this.scene.reset(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class GameOverPhase extends BattlePhase {
|
export class GameOverPhase extends BattlePhase {
|
||||||
private victory: boolean;
|
private victory: boolean;
|
||||||
|
private firstRibbons: PokemonSpecies[] = [];
|
||||||
|
|
||||||
constructor(scene: BattleScene, victory?: boolean) {
|
constructor(scene: BattleScene, victory?: boolean) {
|
||||||
super(scene);
|
super(scene);
|
||||||
@ -3525,6 +3577,13 @@ export class GameOverPhase extends BattlePhase {
|
|||||||
if (this.scene.gameMode.isClassic) {
|
if (this.scene.gameMode.isClassic) {
|
||||||
firstClear = this.scene.validateAchv(achvs.CLASSIC_VICTORY);
|
firstClear = this.scene.validateAchv(achvs.CLASSIC_VICTORY);
|
||||||
this.scene.gameData.gameStats.sessionsWon++;
|
this.scene.gameData.gameStats.sessionsWon++;
|
||||||
|
for (let pokemon of this.scene.getParty()) {
|
||||||
|
this.awardRibbon(pokemon);
|
||||||
|
|
||||||
|
if (pokemon.species.getRootSpeciesId() != pokemon.species.getRootSpeciesId(true)) {
|
||||||
|
this.awardRibbon(pokemon, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (this.scene.gameMode.isDaily && success[1])
|
} else if (this.scene.gameMode.isDaily && success[1])
|
||||||
this.scene.gameData.gameStats.dailyRunSessionsWon++;
|
this.scene.gameData.gameStats.dailyRunSessionsWon++;
|
||||||
}
|
}
|
||||||
@ -3536,8 +3595,12 @@ export class GameOverPhase extends BattlePhase {
|
|||||||
this.scene.clearPhaseQueue();
|
this.scene.clearPhaseQueue();
|
||||||
this.scene.ui.clearText();
|
this.scene.ui.clearText();
|
||||||
this.handleUnlocks();
|
this.handleUnlocks();
|
||||||
if (this.victory && !firstClear && success[1])
|
if (this.victory && success[1]) {
|
||||||
this.scene.unshiftPhase(new GameOverModifierRewardPhase(this.scene, modifierTypes.VOUCHER_PREMIUM));
|
for (let species of this.firstRibbons)
|
||||||
|
this.scene.unshiftPhase(new RibbonModifierRewardPhase(this.scene, modifierTypes.VOUCHER_PLUS, species));
|
||||||
|
if (!firstClear)
|
||||||
|
this.scene.unshiftPhase(new GameOverModifierRewardPhase(this.scene, modifierTypes.VOUCHER_PREMIUM));
|
||||||
|
}
|
||||||
this.scene.reset();
|
this.scene.reset();
|
||||||
this.scene.unshiftPhase(new TitlePhase(this.scene));
|
this.scene.unshiftPhase(new TitlePhase(this.scene));
|
||||||
this.end();
|
this.end();
|
||||||
@ -3556,6 +3619,15 @@ export class GameOverPhase extends BattlePhase {
|
|||||||
this.scene.unshiftPhase(new UnlockPhase(this.scene, Unlockables.MINI_BLACK_HOLE));
|
this.scene.unshiftPhase(new UnlockPhase(this.scene, Unlockables.MINI_BLACK_HOLE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
awardRibbon(pokemon: Pokemon, forStarter: boolean = false): void {
|
||||||
|
const speciesId = getPokemonSpecies(pokemon.species.speciesId)
|
||||||
|
const speciesRibbonCount = this.scene.gameData.incrementRibbonCount(speciesId, forStarter);
|
||||||
|
// first time classic win, award voucher
|
||||||
|
if (speciesRibbonCount === 1) {
|
||||||
|
this.firstRibbons.push(getPokemonSpecies(pokemon.species.getRootSpeciesId(forStarter)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UnlockPhase extends Phase {
|
export class UnlockPhase extends Phase {
|
||||||
@ -4491,6 +4563,48 @@ export class AddEnemyBuffModifierPhase extends Phase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cures the party of all non-volatile status conditions, shows a message
|
||||||
|
* @param {BattleScene} scene The current scene
|
||||||
|
* @param {Pokemon} user The user of the move that cures the party
|
||||||
|
* @param {string} message The message that should be displayed
|
||||||
|
* @param {Abilities} abilityCondition Pokemon with this ability will not be affected ie. Soundproof
|
||||||
|
*/
|
||||||
|
export class PartyStatusCurePhase extends BattlePhase {
|
||||||
|
private user: Pokemon;
|
||||||
|
private message: string;
|
||||||
|
private abilityCondition: Abilities;
|
||||||
|
|
||||||
|
constructor(scene: BattleScene, user: Pokemon, message: string, abilityCondition: Abilities) {
|
||||||
|
super(scene);
|
||||||
|
|
||||||
|
this.user = user;
|
||||||
|
this.message = message;
|
||||||
|
this.abilityCondition = abilityCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
super.start();
|
||||||
|
for (let pokemon of this.scene.getParty()) {
|
||||||
|
if (!pokemon.isOnField() || pokemon === this.user) {
|
||||||
|
pokemon.resetStatus(false);
|
||||||
|
pokemon.updateInfo(true);
|
||||||
|
} else {
|
||||||
|
if (!pokemon.hasAbility(this.abilityCondition)) {
|
||||||
|
pokemon.resetStatus();
|
||||||
|
pokemon.updateInfo(true);
|
||||||
|
} else {
|
||||||
|
// Manually show ability bar, since we're not hooked into the targeting system
|
||||||
|
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, pokemon.getPassiveAbility()?.id === this.abilityCondition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.message)
|
||||||
|
this.scene.queueMessage(this.message);
|
||||||
|
this.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class PartyHealPhase extends BattlePhase {
|
export class PartyHealPhase extends BattlePhase {
|
||||||
private resumeBgm: boolean;
|
private resumeBgm: boolean;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import { enConfig } from '#app/locales/en/config.js';
|
|||||||
import { esConfig } from '#app/locales/es/config.js';
|
import { esConfig } from '#app/locales/es/config.js';
|
||||||
import { frConfig } from '#app/locales/fr/config.js';
|
import { frConfig } from '#app/locales/fr/config.js';
|
||||||
import { itConfig } from '#app/locales/it/config.js';
|
import { itConfig } from '#app/locales/it/config.js';
|
||||||
|
import { zhCnConfig } from '#app/locales/zh_CN/config.js';
|
||||||
|
|
||||||
export interface SimpleTranslationEntries {
|
export interface SimpleTranslationEntries {
|
||||||
[key: string]: string
|
[key: string]: string
|
||||||
@ -58,7 +59,7 @@ export function initI18n(): void {
|
|||||||
i18next.use(LanguageDetector).init({
|
i18next.use(LanguageDetector).init({
|
||||||
lng: lang,
|
lng: lang,
|
||||||
fallbackLng: 'en',
|
fallbackLng: 'en',
|
||||||
supportedLngs: ['en', 'es', 'fr', 'it', 'de'],
|
supportedLngs: ['en', 'es', 'fr', 'it', 'de', 'zh_CN'],
|
||||||
debug: true,
|
debug: true,
|
||||||
interpolation: {
|
interpolation: {
|
||||||
escapeValue: false,
|
escapeValue: false,
|
||||||
@ -78,6 +79,9 @@ export function initI18n(): void {
|
|||||||
},
|
},
|
||||||
de: {
|
de: {
|
||||||
...deConfig
|
...deConfig
|
||||||
|
},
|
||||||
|
zh_CN: {
|
||||||
|
...zhCnConfig
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -51,9 +51,9 @@ export class Achv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTier(): AchvTier {
|
getTier(): AchvTier {
|
||||||
if (this.score >= 150)
|
|
||||||
return AchvTier.MASTER;
|
|
||||||
if (this.score >= 100)
|
if (this.score >= 100)
|
||||||
|
return AchvTier.MASTER;
|
||||||
|
if (this.score >= 75)
|
||||||
return AchvTier.ROGUE;
|
return AchvTier.ROGUE;
|
||||||
if (this.score >= 50)
|
if (this.score >= 50)
|
||||||
return AchvTier.ULTRA;
|
return AchvTier.ULTRA;
|
||||||
@ -73,6 +73,16 @@ export class MoneyAchv extends Achv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class RibbonAchv extends Achv {
|
||||||
|
private ribbonAmount: integer;
|
||||||
|
|
||||||
|
constructor(name: string, ribbonAmount: integer, iconImage: string, score: integer) {
|
||||||
|
super(name, `Accumulate a total of ${ribbonAmount.toLocaleString('en-US')} Ribbons`, iconImage, score, (scene: BattleScene, _args: any[]) => scene.gameData.gameStats.ribbonsOwned >= this.ribbonAmount);
|
||||||
|
|
||||||
|
this.ribbonAmount = ribbonAmount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class DamageAchv extends Achv {
|
export class DamageAchv extends Achv {
|
||||||
private damageAmount: integer;
|
private damageAmount: integer;
|
||||||
|
|
||||||
@ -125,6 +135,11 @@ export const achvs = {
|
|||||||
LV_100: new LevelAchv('But Wait, There\'s More!', 100, 'rare_candy', 25).setSecret(),
|
LV_100: new LevelAchv('But Wait, There\'s More!', 100, 'rare_candy', 25).setSecret(),
|
||||||
LV_250: new LevelAchv('Elite', 250, 'rarer_candy', 50).setSecret(true),
|
LV_250: new LevelAchv('Elite', 250, 'rarer_candy', 50).setSecret(true),
|
||||||
LV_1000: new LevelAchv('To Go Even Further Beyond', 1000, 'candy_jar', 100).setSecret(true),
|
LV_1000: new LevelAchv('To Go Even Further Beyond', 1000, 'candy_jar', 100).setSecret(true),
|
||||||
|
_10_RIBBONS: new RibbonAchv('Pokémon League Champion', 10, 'bronze_ribbon', 10),
|
||||||
|
_25_RIBBONS: new RibbonAchv('Great League Champion', 25, 'great_ribbon', 25).setSecret(true),
|
||||||
|
_50_RIBBONS: new RibbonAchv('Ultra League Champion', 50, 'ultra_ribbon', 50).setSecret(true),
|
||||||
|
_75_RIBBONS: new RibbonAchv('Rogue League Champion', 75, 'rogue_ribbon', 75).setSecret(true),
|
||||||
|
_100_RIBBONS: new RibbonAchv('Master League Champion', 100, 'master_ribbon', 100).setSecret(true),
|
||||||
TRANSFER_MAX_BATTLE_STAT: new Achv('Teamwork', 'Baton pass to another party member with at least one stat maxed out', 'stick', 20),
|
TRANSFER_MAX_BATTLE_STAT: new Achv('Teamwork', 'Baton pass to another party member with at least one stat maxed out', 'stick', 20),
|
||||||
MAX_FRIENDSHIP: new Achv('Friendmaxxing', 'Reach max friendship on a Pokémon', 'soothe_bell', 25),
|
MAX_FRIENDSHIP: new Achv('Friendmaxxing', 'Reach max friendship on a Pokémon', 'soothe_bell', 25),
|
||||||
MEGA_EVOLVE: new Achv('Megamorph', 'Mega evolve a Pokémon', 'mega_bracelet', 50),
|
MEGA_EVOLVE: new Achv('Megamorph', 'Mega evolve a Pokémon', 'mega_bracelet', 50),
|
||||||
|
@ -173,6 +173,7 @@ export interface StarterDataEntry {
|
|||||||
abilityAttr: integer;
|
abilityAttr: integer;
|
||||||
passiveAttr: integer;
|
passiveAttr: integer;
|
||||||
valueReduction: integer;
|
valueReduction: integer;
|
||||||
|
classicWinCount: integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StarterData {
|
export interface StarterData {
|
||||||
@ -194,7 +195,8 @@ const systemShortKeys = {
|
|||||||
eggMoves: '$em',
|
eggMoves: '$em',
|
||||||
candyCount: '$x',
|
candyCount: '$x',
|
||||||
passive: '$p',
|
passive: '$p',
|
||||||
valueReduction: '$vr'
|
valueReduction: '$vr',
|
||||||
|
classicWinCount: '$wc'
|
||||||
};
|
};
|
||||||
|
|
||||||
export class GameData {
|
export class GameData {
|
||||||
@ -248,58 +250,52 @@ export class GameData {
|
|||||||
public saveSystem(): Promise<boolean> {
|
public saveSystem(): Promise<boolean> {
|
||||||
return new Promise<boolean>(resolve => {
|
return new Promise<boolean>(resolve => {
|
||||||
this.scene.ui.savingIcon.show();
|
this.scene.ui.savingIcon.show();
|
||||||
updateUserInfo().then(response => {
|
const data: SystemSaveData = {
|
||||||
if (!response[0]) {
|
trainerId: this.trainerId,
|
||||||
this.scene.ui.savingIcon.hide();
|
secretId: this.secretId,
|
||||||
return resolve(false);
|
gender: this.gender,
|
||||||
}
|
dexData: this.dexData,
|
||||||
const data: SystemSaveData = {
|
starterData: this.starterData,
|
||||||
trainerId: this.trainerId,
|
gameStats: this.gameStats,
|
||||||
secretId: this.secretId,
|
unlocks: this.unlocks,
|
||||||
gender: this.gender,
|
achvUnlocks: this.achvUnlocks,
|
||||||
dexData: this.dexData,
|
voucherUnlocks: this.voucherUnlocks,
|
||||||
starterData: this.starterData,
|
voucherCounts: this.voucherCounts,
|
||||||
gameStats: this.gameStats,
|
eggs: this.eggs.map(e => new EggData(e)),
|
||||||
unlocks: this.unlocks,
|
gameVersion: this.scene.game.config.gameVersion,
|
||||||
achvUnlocks: this.achvUnlocks,
|
timestamp: new Date().getTime()
|
||||||
voucherUnlocks: this.voucherUnlocks,
|
};
|
||||||
voucherCounts: this.voucherCounts,
|
|
||||||
eggs: this.eggs.map(e => new EggData(e)),
|
|
||||||
gameVersion: this.scene.game.config.gameVersion,
|
|
||||||
timestamp: new Date().getTime()
|
|
||||||
};
|
|
||||||
|
|
||||||
const maxIntAttrValue = Math.pow(2, 31);
|
const maxIntAttrValue = Math.pow(2, 31);
|
||||||
const systemData = JSON.stringify(data, (k: any, v: any) => typeof v === 'bigint' ? v <= maxIntAttrValue ? Number(v) : v.toString() : v);
|
const systemData = JSON.stringify(data, (k: any, v: any) => typeof v === 'bigint' ? v <= maxIntAttrValue ? Number(v) : v.toString() : v);
|
||||||
|
|
||||||
if (!bypassLogin) {
|
if (!bypassLogin) {
|
||||||
Utils.apiPost(`savedata/update?datatype=${GameDataType.SYSTEM}`, systemData, undefined, true)
|
Utils.apiPost(`savedata/update?datatype=${GameDataType.SYSTEM}`, systemData, undefined, true)
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(error => {
|
.then(error => {
|
||||||
this.scene.ui.savingIcon.hide();
|
this.scene.ui.savingIcon.hide();
|
||||||
if (error) {
|
if (error) {
|
||||||
if (error.startsWith('client version out of date')) {
|
if (error.startsWith('client version out of date')) {
|
||||||
this.scene.clearPhaseQueue();
|
this.scene.clearPhaseQueue();
|
||||||
this.scene.unshiftPhase(new OutdatedPhase(this.scene));
|
this.scene.unshiftPhase(new OutdatedPhase(this.scene));
|
||||||
} else if (error.startsWith('session out of date')) {
|
} else if (error.startsWith('session out of date')) {
|
||||||
this.scene.clearPhaseQueue();
|
this.scene.clearPhaseQueue();
|
||||||
this.scene.unshiftPhase(new ReloadSessionPhase(this.scene));
|
this.scene.unshiftPhase(new ReloadSessionPhase(this.scene));
|
||||||
}
|
|
||||||
console.error(error);
|
|
||||||
return resolve(false);
|
|
||||||
}
|
}
|
||||||
resolve(true);
|
console.error(error);
|
||||||
});
|
return resolve(false);
|
||||||
} else {
|
}
|
||||||
localStorage.setItem('data_bak', localStorage.getItem('data'));
|
resolve(true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
localStorage.setItem('data_bak', localStorage.getItem('data'));
|
||||||
|
|
||||||
localStorage.setItem('data', btoa(systemData));
|
localStorage.setItem('data', btoa(systemData));
|
||||||
|
|
||||||
this.scene.ui.savingIcon.hide();
|
this.scene.ui.savingIcon.hide();
|
||||||
|
|
||||||
resolve(true);
|
resolve(true);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,7 +418,7 @@ export class GameData {
|
|||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (!response.length || response[0] !== '{') {
|
if (!response.length || response[0] !== '{') {
|
||||||
if (response.startsWith('failed to open save file')) {
|
if (response.startsWith('sql: no rows in result set')) {
|
||||||
this.scene.queueMessage('Save data could not be found. If this is a new account, you can safely ignore this message.', null, true);
|
this.scene.queueMessage('Save data could not be found. If this is a new account, you can safely ignore this message.', null, true);
|
||||||
return resolve(true);
|
return resolve(true);
|
||||||
} else if (response.indexOf('Too many connections') > -1) {
|
} else if (response.indexOf('Too many connections') > -1) {
|
||||||
@ -573,7 +569,7 @@ export class GameData {
|
|||||||
resolve(true);
|
resolve(true);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
localStorage.setItem('sessionData', btoa(JSON.stringify(sessionData)));
|
localStorage.setItem(`sessionData${scene.sessionSlotId ? scene.sessionSlotId : ''}`, btoa(JSON.stringify(sessionData)));
|
||||||
|
|
||||||
console.debug('Session data saved');
|
console.debug('Session data saved');
|
||||||
|
|
||||||
@ -995,7 +991,8 @@ export class GameData {
|
|||||||
friendship: 0,
|
friendship: 0,
|
||||||
abilityAttr: defaultStarterSpecies.includes(speciesId) ? AbilityAttr.ABILITY_1 : 0,
|
abilityAttr: defaultStarterSpecies.includes(speciesId) ? AbilityAttr.ABILITY_1 : 0,
|
||||||
passiveAttr: 0,
|
passiveAttr: 0,
|
||||||
valueReduction: 0
|
valueReduction: 0,
|
||||||
|
classicWinCount: 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1089,6 +1086,32 @@ export class GameData {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
incrementRibbonCount(species: PokemonSpecies, forStarter: boolean = false): integer {
|
||||||
|
const speciesIdToIncrement: Species = species.getRootSpeciesId(forStarter);
|
||||||
|
|
||||||
|
if (!this.starterData[speciesIdToIncrement].classicWinCount) {
|
||||||
|
this.starterData[speciesIdToIncrement].classicWinCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.starterData[speciesIdToIncrement].classicWinCount)
|
||||||
|
this.scene.gameData.gameStats.ribbonsOwned++;
|
||||||
|
|
||||||
|
const ribbonsInStats: integer = this.scene.gameData.gameStats.ribbonsOwned;
|
||||||
|
|
||||||
|
if (ribbonsInStats >= 100)
|
||||||
|
this.scene.validateAchv(achvs._100_RIBBONS);
|
||||||
|
if (ribbonsInStats >= 75)
|
||||||
|
this.scene.validateAchv(achvs._75_RIBBONS);
|
||||||
|
if (ribbonsInStats >= 50)
|
||||||
|
this.scene.validateAchv(achvs._50_RIBBONS);
|
||||||
|
if (ribbonsInStats >= 25)
|
||||||
|
this.scene.validateAchv(achvs._25_RIBBONS);
|
||||||
|
if (ribbonsInStats >= 10)
|
||||||
|
this.scene.validateAchv(achvs._10_RIBBONS);
|
||||||
|
|
||||||
|
return ++this.starterData[speciesIdToIncrement].classicWinCount;
|
||||||
|
}
|
||||||
|
|
||||||
addStarterCandy(species: PokemonSpecies, count: integer): void {
|
addStarterCandy(species: PokemonSpecies, count: integer): void {
|
||||||
this.scene.candyBar.showStarterSpeciesCandy(species.speciesId, count);
|
this.scene.candyBar.showStarterSpeciesCandy(species.speciesId, count);
|
||||||
this.starterData[species.speciesId].candyCount += count;
|
this.starterData[species.speciesId].candyCount += count;
|
||||||
|
@ -6,6 +6,7 @@ export class GameStats {
|
|||||||
public battles: integer;
|
public battles: integer;
|
||||||
public classicSessionsPlayed: integer;
|
public classicSessionsPlayed: integer;
|
||||||
public sessionsWon: integer;
|
public sessionsWon: integer;
|
||||||
|
public ribbonsOwned: integer;
|
||||||
public dailyRunSessionsPlayed: integer;
|
public dailyRunSessionsPlayed: integer;
|
||||||
public dailyRunSessionsWon: integer;
|
public dailyRunSessionsWon: integer;
|
||||||
public endlessSessionsPlayed: integer;
|
public endlessSessionsPlayed: integer;
|
||||||
@ -43,6 +44,7 @@ export class GameStats {
|
|||||||
this.battles = source?.battles || 0;
|
this.battles = source?.battles || 0;
|
||||||
this.classicSessionsPlayed = source?.classicSessionsPlayed || 0;
|
this.classicSessionsPlayed = source?.classicSessionsPlayed || 0;
|
||||||
this.sessionsWon = source?.sessionsWon || 0;
|
this.sessionsWon = source?.sessionsWon || 0;
|
||||||
|
this.ribbonsOwned = source?.ribbonsOwned || 0;
|
||||||
this.dailyRunSessionsPlayed = source?.dailyRunSessionsPlayed || 0;
|
this.dailyRunSessionsPlayed = source?.dailyRunSessionsPlayed || 0;
|
||||||
this.dailyRunSessionsWon = source?.dailyRunSessionsWon || 0;
|
this.dailyRunSessionsWon = source?.dailyRunSessionsWon || 0;
|
||||||
this.endlessSessionsPlayed = source?.endlessSessionsPlayed || 0;
|
this.endlessSessionsPlayed = source?.endlessSessionsPlayed || 0;
|
||||||
@ -64,7 +66,7 @@ export class GameStats {
|
|||||||
this.legendaryPokemonHatched = source?.legendaryPokemonHatched || 0;
|
this.legendaryPokemonHatched = source?.legendaryPokemonHatched || 0;
|
||||||
this.mythicalPokemonSeen = source?.mythicalPokemonSeen || 0;
|
this.mythicalPokemonSeen = source?.mythicalPokemonSeen || 0;
|
||||||
this.mythicalPokemonCaught = source?.mythicalPokemonCaught || 0;
|
this.mythicalPokemonCaught = source?.mythicalPokemonCaught || 0;
|
||||||
this.mythicalPokemonHatched = source?.mythicalPokemonCaught || 0;
|
this.mythicalPokemonHatched = source?.mythicalPokemonHatched || 0;
|
||||||
this.shinyPokemonSeen = source?.shinyPokemonSeen || 0;
|
this.shinyPokemonSeen = source?.shinyPokemonSeen || 0;
|
||||||
this.shinyPokemonCaught = source?.shinyPokemonCaught || 0;
|
this.shinyPokemonCaught = source?.shinyPokemonCaught || 0;
|
||||||
this.shinyPokemonHatched = source?.shinyPokemonHatched || 0;
|
this.shinyPokemonHatched = source?.shinyPokemonHatched || 0;
|
||||||
|
@ -11,6 +11,7 @@ import Pokemon, { EnemyPokemon, PokemonMove, PokemonSummonData } from "../field/
|
|||||||
import { TrainerSlot } from "../data/trainer-config";
|
import { TrainerSlot } from "../data/trainer-config";
|
||||||
import { Moves } from "../data/enums/moves";
|
import { Moves } from "../data/enums/moves";
|
||||||
import { Variant } from "#app/data/variant";
|
import { Variant } from "#app/data/variant";
|
||||||
|
import { loadBattlerTag } from '../data/battler-tags';
|
||||||
|
|
||||||
export default class PokemonData {
|
export default class PokemonData {
|
||||||
public id: integer;
|
public id: integer;
|
||||||
@ -112,9 +113,18 @@ export default class PokemonData {
|
|||||||
if (!forHistory && source.summonData) {
|
if (!forHistory && source.summonData) {
|
||||||
this.summonData.battleStats = source.summonData.battleStats;
|
this.summonData.battleStats = source.summonData.battleStats;
|
||||||
this.summonData.moveQueue = source.summonData.moveQueue;
|
this.summonData.moveQueue = source.summonData.moveQueue;
|
||||||
this.summonData.tags = []; // TODO
|
this.summonData.disabledMove = source.summonData.disabledMove;
|
||||||
this.summonData.moveset = source.summonData.moveset;
|
this.summonData.disabledTurns = source.summonData.disabledTurns;
|
||||||
|
this.summonData.abilitySuppressed = source.summonData.abilitySuppressed;
|
||||||
|
|
||||||
|
this.summonData.ability = source.summonData.ability;
|
||||||
|
this.summonData.moveset = source.summonData.moveset?.map(m => PokemonMove.loadMove(m));
|
||||||
this.summonData.types = source.summonData.types;
|
this.summonData.types = source.summonData.types;
|
||||||
|
|
||||||
|
if (source.summonData.tags)
|
||||||
|
this.summonData.tags = source.summonData.tags?.map(t => loadBattlerTag(t));
|
||||||
|
else
|
||||||
|
this.summonData.tags = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,21 +189,25 @@ export function setSetting(scene: BattleScene, setting: Setting, value: integer)
|
|||||||
handler: () => changeLocaleHandler('en')
|
handler: () => changeLocaleHandler('en')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Spanish',
|
label: 'Español',
|
||||||
handler: () => changeLocaleHandler('es')
|
handler: () => changeLocaleHandler('es')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Italian',
|
label: 'Italiano',
|
||||||
handler: () => changeLocaleHandler('it')
|
handler: () => changeLocaleHandler('it')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'French',
|
label: 'Français',
|
||||||
handler: () => changeLocaleHandler('fr')
|
handler: () => changeLocaleHandler('fr')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'German',
|
label: 'Deutsch',
|
||||||
handler: () => changeLocaleHandler('de')
|
handler: () => changeLocaleHandler('de')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '简体中文',
|
||||||
|
handler: () => changeLocaleHandler('zh_CN')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'Cancel',
|
label: 'Cancel',
|
||||||
handler: () => cancelHandler()
|
handler: () => cancelHandler()
|
||||||
|
@ -417,7 +417,10 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
if (nameUpdated || teraTypeUpdated) {
|
if (nameUpdated || teraTypeUpdated) {
|
||||||
this.splicedIcon.setVisible(!!pokemon.fusionSpecies);
|
this.splicedIcon.setVisible(!!pokemon.fusionSpecies);
|
||||||
|
|
||||||
|
this.teraIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + this.genderText.displayWidth + 1, 2);
|
||||||
this.splicedIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + this.genderText.displayWidth + 1 + (this.teraIcon.visible ? this.teraIcon.displayWidth + 1 : 0), 1.5);
|
this.splicedIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + this.genderText.displayWidth + 1 + (this.teraIcon.visible ? this.teraIcon.displayWidth + 1 : 0), 1.5);
|
||||||
|
this.shinyIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + this.genderText.displayWidth + 1 + (this.teraIcon.visible ? this.teraIcon.displayWidth + 1 : 0) + (this.splicedIcon.visible ? this.splicedIcon.displayWidth + 1 : 0), 2.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.lastStatus !== (pokemon.status?.effect || StatusEffect.NONE)) {
|
if (this.lastStatus !== (pokemon.status?.effect || StatusEffect.NONE)) {
|
||||||
|
@ -51,6 +51,7 @@ const displayStats: DisplayStats = {
|
|||||||
return `${caughtCount} (${Math.floor((caughtCount / Object.keys(gameData.dexData).length) * 1000) / 10}%)`;
|
return `${caughtCount} (${Math.floor((caughtCount / Object.keys(gameData.dexData).length) * 1000) / 10}%)`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
ribbonsOwned: 'Ribbons Owned',
|
||||||
classicSessionsPlayed: 'Classic Runs',
|
classicSessionsPlayed: 'Classic Runs',
|
||||||
sessionsWon: 'Classic Wins',
|
sessionsWon: 'Classic Wins',
|
||||||
dailyRunSessionsPlayed: 'Daily Run Attempts',
|
dailyRunSessionsPlayed: 'Daily Run Attempts',
|
||||||
|
@ -174,6 +174,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
private starterValueLabels: Phaser.GameObjects.Text[];
|
private starterValueLabels: Phaser.GameObjects.Text[];
|
||||||
private shinyIcons: Phaser.GameObjects.Image[][];
|
private shinyIcons: Phaser.GameObjects.Image[][];
|
||||||
private hiddenAbilityIcons: Phaser.GameObjects.Image[];
|
private hiddenAbilityIcons: Phaser.GameObjects.Image[];
|
||||||
|
private classicWinIcons: Phaser.GameObjects.Image[];
|
||||||
|
|
||||||
private iconAnimHandler: PokemonIconAnimHandler;
|
private iconAnimHandler: PokemonIconAnimHandler;
|
||||||
|
|
||||||
@ -410,6 +411,17 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.classicWinIcons = new Array(81).fill(null).map((_, i) => {
|
||||||
|
const x = (i % 9) * 18;
|
||||||
|
const y = Math.floor(i / 9) * 18;
|
||||||
|
const ret = this.scene.add.image(x + 153, y + 21, 'champion_ribbon');
|
||||||
|
ret.setOrigin(0, 0);
|
||||||
|
ret.setScale(0.5);
|
||||||
|
ret.setVisible(false);
|
||||||
|
this.starterSelectContainer.add(ret);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
this.pokemonSprite = this.scene.add.sprite(53, 63, `pkmn__sub`);
|
this.pokemonSprite = this.scene.add.sprite(53, 63, `pkmn__sub`);
|
||||||
this.pokemonSprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
|
this.pokemonSprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
|
||||||
this.starterSelectContainer.add(this.pokemonSprite);
|
this.starterSelectContainer.add(this.pokemonSprite);
|
||||||
@ -450,7 +462,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.pokemonCandyDarknessOverlay.setScale(0.5);
|
this.pokemonCandyDarknessOverlay.setScale(0.5);
|
||||||
this.pokemonCandyDarknessOverlay.setOrigin(0, 0);
|
this.pokemonCandyDarknessOverlay.setOrigin(0, 0);
|
||||||
this.pokemonCandyDarknessOverlay.setTint(0x000000);
|
this.pokemonCandyDarknessOverlay.setTint(0x000000);
|
||||||
this.pokemonCandyDarknessOverlay.setAlpha(0.5);
|
this.pokemonCandyDarknessOverlay.setAlpha(0.50);
|
||||||
this.pokemonCandyDarknessOverlay.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains);
|
this.pokemonCandyDarknessOverlay.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains);
|
||||||
this.starterSelectContainer.add(this.pokemonCandyDarknessOverlay);
|
this.starterSelectContainer.add(this.pokemonCandyDarknessOverlay);
|
||||||
|
|
||||||
@ -1086,7 +1098,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
// starterMoveData doesn't have base form moves or is using the single form format
|
// starterMoveData doesn't have base form moves or is using the single form format
|
||||||
if (!this.scene.gameData.starterData[speciesId].moveset || Array.isArray(this.scene.gameData.starterData[speciesId].moveset))
|
if (!this.scene.gameData.starterData[speciesId].moveset || Array.isArray(this.scene.gameData.starterData[speciesId].moveset))
|
||||||
this.scene.gameData.starterData[speciesId].moveset = { [props.formIndex]: this.starterMoveset.slice(0) as StarterMoveset };
|
this.scene.gameData.starterData[speciesId].moveset = { [props.formIndex]: this.starterMoveset.slice(0) as StarterMoveset };
|
||||||
const starterMoveData = this.scene.gameData.starterData[speciesId].moveset[props.formIndex];
|
const starterMoveData = this.scene.gameData.starterData[speciesId].moveset;
|
||||||
|
|
||||||
// starterMoveData doesn't have active form moves
|
// starterMoveData doesn't have active form moves
|
||||||
if (!starterMoveData.hasOwnProperty(props.formIndex))
|
if (!starterMoveData.hasOwnProperty(props.formIndex))
|
||||||
@ -1192,6 +1204,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.shinyIcons[s][v].setTint(getVariantTint(speciesVariants[v] === DexAttr.DEFAULT_VARIANT ? 0 : speciesVariants[v] === DexAttr.VARIANT_2 ? 1 : 2));
|
this.shinyIcons[s][v].setTint(getVariantTint(speciesVariants[v] === DexAttr.DEFAULT_VARIANT ? 0 : speciesVariants[v] === DexAttr.VARIANT_2 ? 1 : 2));
|
||||||
}
|
}
|
||||||
this.hiddenAbilityIcons[s].setVisible(slotVisible && !!this.scene.gameData.dexData[speciesId].caughtAttr && !!(this.scene.gameData.starterData[speciesId].abilityAttr & 4));
|
this.hiddenAbilityIcons[s].setVisible(slotVisible && !!this.scene.gameData.dexData[speciesId].caughtAttr && !!(this.scene.gameData.starterData[speciesId].abilityAttr & 4));
|
||||||
|
this.classicWinIcons[s].setVisible(slotVisible && this.scene.gameData.starterData[speciesId].classicWinCount > 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
changed = super.setCursor(cursor);
|
changed = super.setCursor(cursor);
|
||||||
@ -1319,7 +1332,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.pokemonCandyDarknessOverlay.setCrop(0,0,16, candyCropY);
|
this.pokemonCandyDarknessOverlay.setCrop(0,0,16, candyCropY);
|
||||||
this.pokemonCandyDarknessOverlay.setCrop(0,0,16, candyCropY);
|
|
||||||
}
|
}
|
||||||
this.iconAnimHandler.addOrUpdate(this.starterSelectGenIconContainers[species.generation - 1].getAt(this.genSpecies[species.generation - 1].indexOf(species)) as Phaser.GameObjects.Sprite, PokemonIconAnimMode.PASSIVE);
|
this.iconAnimHandler.addOrUpdate(this.starterSelectGenIconContainers[species.generation - 1].getAt(this.genSpecies[species.generation - 1].indexOf(species)) as Phaser.GameObjects.Sprite, PokemonIconAnimMode.PASSIVE);
|
||||||
|
|
||||||
|
@ -50,6 +50,8 @@ export default class SummaryUiHandler extends UiHandler {
|
|||||||
private candyShadow: Phaser.GameObjects.Sprite;
|
private candyShadow: Phaser.GameObjects.Sprite;
|
||||||
private candyIcon: Phaser.GameObjects.Sprite;
|
private candyIcon: Phaser.GameObjects.Sprite;
|
||||||
private candyOverlay: Phaser.GameObjects.Sprite;
|
private candyOverlay: Phaser.GameObjects.Sprite;
|
||||||
|
private candyCountText: Phaser.GameObjects.Text;
|
||||||
|
private championRibbon: Phaser.GameObjects.Image;
|
||||||
private statusContainer: Phaser.GameObjects.Container;
|
private statusContainer: Phaser.GameObjects.Container;
|
||||||
private status: Phaser.GameObjects.Image;
|
private status: Phaser.GameObjects.Image;
|
||||||
private summaryPageContainer: Phaser.GameObjects.Container;
|
private summaryPageContainer: Phaser.GameObjects.Container;
|
||||||
@ -142,12 +144,6 @@ export default class SummaryUiHandler extends UiHandler {
|
|||||||
this.pokeball.setOrigin(0, 1);
|
this.pokeball.setOrigin(0, 1);
|
||||||
this.summaryContainer.add(this.pokeball);
|
this.summaryContainer.add(this.pokeball);
|
||||||
|
|
||||||
this.candyShadow = this.scene.add.sprite(13, -140, 'candy');
|
|
||||||
this.candyShadow.setTint(0x141414)
|
|
||||||
this.candyShadow.setScale(0.8);
|
|
||||||
this.candyShadow.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains);
|
|
||||||
this.summaryContainer.add(this.candyShadow);
|
|
||||||
|
|
||||||
this.candyIcon = this.scene.add.sprite(13, -140, 'candy');
|
this.candyIcon = this.scene.add.sprite(13, -140, 'candy');
|
||||||
this.candyIcon.setScale(0.8);
|
this.candyIcon.setScale(0.8);
|
||||||
this.summaryContainer.add(this.candyIcon);
|
this.summaryContainer.add(this.candyIcon);
|
||||||
@ -156,6 +152,24 @@ export default class SummaryUiHandler extends UiHandler {
|
|||||||
this.candyOverlay.setScale(0.8);
|
this.candyOverlay.setScale(0.8);
|
||||||
this.summaryContainer.add(this.candyOverlay);
|
this.summaryContainer.add(this.candyOverlay);
|
||||||
|
|
||||||
|
this.candyShadow = this.scene.add.sprite(13, -140, 'candy');
|
||||||
|
this.candyShadow.setTint(0x000000);
|
||||||
|
this.candyShadow.setAlpha(0.50);
|
||||||
|
this.candyShadow.setScale(0.8);
|
||||||
|
this.candyShadow.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains);
|
||||||
|
this.summaryContainer.add(this.candyShadow);
|
||||||
|
|
||||||
|
this.candyCountText = addTextObject(this.scene, 20, -146, 'x0', TextStyle.WINDOW_ALT, { fontSize: '76px' });
|
||||||
|
this.candyCountText.setOrigin(0, 0);
|
||||||
|
this.summaryContainer.add(this.candyCountText);
|
||||||
|
|
||||||
|
this.championRibbon = this.scene.add.image(88, -146, 'champion_ribbon');
|
||||||
|
this.championRibbon.setOrigin(0, 0);
|
||||||
|
//this.championRibbon.setScale(0.8);
|
||||||
|
this.championRibbon.setScale(1.25);
|
||||||
|
this.summaryContainer.add(this.championRibbon);
|
||||||
|
this.championRibbon.setVisible(false);
|
||||||
|
|
||||||
this.levelText = addTextObject(this.scene, 36, -17, '', TextStyle.SUMMARY_ALT);
|
this.levelText = addTextObject(this.scene, 36, -17, '', TextStyle.SUMMARY_ALT);
|
||||||
this.levelText.setOrigin(0, 1);
|
this.levelText.setOrigin(0, 1);
|
||||||
this.summaryContainer.add(this.levelText);
|
this.summaryContainer.add(this.levelText);
|
||||||
@ -275,6 +289,11 @@ export default class SummaryUiHandler extends UiHandler {
|
|||||||
this.splicedIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip());
|
this.splicedIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()].classicWinCount > 0 && this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId(true)].classicWinCount > 0)
|
||||||
|
this.championRibbon.setVisible(true);
|
||||||
|
else
|
||||||
|
this.championRibbon.setVisible(false);
|
||||||
|
|
||||||
var currentFriendship = this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()].friendship;
|
var currentFriendship = this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()].friendship;
|
||||||
if (!currentFriendship || currentFriendship === undefined)
|
if (!currentFriendship || currentFriendship === undefined)
|
||||||
currentFriendship = 0;
|
currentFriendship = 0;
|
||||||
@ -287,8 +306,9 @@ export default class SummaryUiHandler extends UiHandler {
|
|||||||
this.candyShadow.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip());
|
this.candyShadow.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.candyIcon.setCrop(0,candyCropY,16, 16);
|
this.candyCountText.setText(`x${this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()].candyCount}`);
|
||||||
this.candyOverlay.setCrop(0,candyCropY,16, 16);
|
|
||||||
|
this.candyShadow.setCrop(0,0,16, candyCropY);
|
||||||
|
|
||||||
const doubleShiny = isFusion && this.pokemon.shiny && this.pokemon.fusionShiny;
|
const doubleShiny = isFusion && this.pokemon.shiny && this.pokemon.fusionShiny;
|
||||||
const baseVariant = !doubleShiny ? this.pokemon.getVariant() : this.pokemon.variant;
|
const baseVariant = !doubleShiny ? this.pokemon.getVariant() : this.pokemon.variant;
|
||||||
|
@ -84,7 +84,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
|
|||||||
|
|
||||||
this.updateTitleStats();
|
this.updateTitleStats();
|
||||||
|
|
||||||
this.titleStatsTimer = setInterval(() => this.updateTitleStats(), 30000);
|
this.titleStatsTimer = setInterval(() => this.updateTitleStats(), 60000);
|
||||||
|
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
targets: [ this.titleContainer, ui.getMessageHandler().bg ],
|
targets: [ this.titleContainer, ui.getMessageHandler().bg ],
|
||||||
|
33
src/utils.ts
@ -220,9 +220,10 @@ export function executeIf<T>(condition: boolean, promiseFunc: () => Promise<T>):
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const sessionIdKey = 'pokerogue_sessionId';
|
export const sessionIdKey = 'pokerogue_sessionId';
|
||||||
export const isLocal = window.location.hostname === 'localhost';
|
export const isLocal = window.location.hostname === 'localhost' || window.location.hostname === '';
|
||||||
export const serverUrl = isLocal ? 'http://localhost:8001' : '';
|
export const serverUrl = isLocal ? 'http://localhost:8001' : '';
|
||||||
export const apiUrl = isLocal ? serverUrl : 'api';
|
export const apiUrl = isLocal ? serverUrl : 'https://api.pokerogue.net';
|
||||||
|
export const fallbackApiUrl = isLocal ? serverUrl : 'api';
|
||||||
|
|
||||||
export function setCookie(cName: string, cValue: string): void {
|
export function setCookie(cName: string, cValue: string): void {
|
||||||
const expiration = new Date();
|
const expiration = new Date();
|
||||||
@ -243,7 +244,7 @@ export function getCookie(cName: string): string {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function apiFetch(path: string, authed: boolean = false): Promise<Response> {
|
export function apiFetch(path: string, authed: boolean = false, fallback: boolean = false): Promise<Response> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const request = {};
|
const request = {};
|
||||||
if (authed) {
|
if (authed) {
|
||||||
@ -251,13 +252,22 @@ export function apiFetch(path: string, authed: boolean = false): Promise<Respons
|
|||||||
if (sId)
|
if (sId)
|
||||||
request['headers'] = { 'Authorization': sId };
|
request['headers'] = { 'Authorization': sId };
|
||||||
}
|
}
|
||||||
fetch(`${apiUrl}/${path}`, request)
|
fetch(`${!fallback ? apiUrl : fallbackApiUrl}/${path}`, request)
|
||||||
.then(response => resolve(response))
|
.then(response => {
|
||||||
.catch(err => reject(err));
|
if (!response.ok && response.status === 404 && !fallback)
|
||||||
|
return apiFetch(path, authed, true).then(res => resolve(res));
|
||||||
|
resolve(response);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (fallback)
|
||||||
|
reject(err);
|
||||||
|
else
|
||||||
|
apiFetch(path, authed, true).then(res => resolve(res));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function apiPost(path: string, data?: any, contentType: string = 'application/json', authed: boolean = false): Promise<Response> {
|
export function apiPost(path: string, data?: any, contentType: string = 'application/json', authed: boolean = false, fallback: boolean = false): Promise<Response> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const headers = {
|
const headers = {
|
||||||
'Accept': contentType,
|
'Accept': contentType,
|
||||||
@ -268,9 +278,14 @@ export function apiPost(path: string, data?: any, contentType: string = 'applica
|
|||||||
if (sId)
|
if (sId)
|
||||||
headers['Authorization'] = sId;
|
headers['Authorization'] = sId;
|
||||||
}
|
}
|
||||||
fetch(`${apiUrl}/${path}`, { method: 'POST', headers: headers, body: data })
|
fetch(`${!fallback ? apiUrl : fallbackApiUrl}/${path}`, { method: 'POST', headers: headers, body: data })
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(err => reject(err));
|
.catch(err => {
|
||||||
|
if (fallback)
|
||||||
|
reject(err);
|
||||||
|
else
|
||||||
|
apiPost(path, data, contentType, authed, true).then(res => resolve(res));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|