Merge branch 'pagefaultgames:main' into main
10817
public/images/items.json
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 400 B |
After Width: | Height: | Size: 408 B |
After Width: | Height: | Size: 408 B |
After Width: | Height: | Size: 407 B |
After Width: | Height: | Size: 406 B |
After Width: | Height: | Size: 285 B |
After Width: | Height: | Size: 285 B |
|
@ -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
|
|
@ -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 { STARTING_WAVE_OVERRIDE, OPP_SPECIES_OVERRIDE, SEED_OVERRIDE, STARTING_BIOME_OVERRIDE, DOUBLE_BATTLE_OVERRIDE } from './overrides';
|
||||||
import {InputsController} from "./inputs-controller";
|
import {InputsController} from "./inputs-controller";
|
||||||
import {UiInputs} from "./ui-inputs";
|
import {UiInputs} from "./ui-inputs";
|
||||||
|
|
||||||
|
@ -842,6 +842,9 @@ export default class BattleScene extends SceneBase {
|
||||||
} else if (!battleConfig)
|
} else if (!battleConfig)
|
||||||
newDouble = !!double;
|
newDouble = !!double;
|
||||||
|
|
||||||
|
if (DOUBLE_BATTLE_OVERRIDE)
|
||||||
|
newDouble = true;
|
||||||
|
|
||||||
const lastBattle = this.currentBattle;
|
const lastBattle = this.currentBattle;
|
||||||
|
|
||||||
if (lastBattle?.double && !newDouble)
|
if (lastBattle?.double && !newDouble)
|
||||||
|
|
|
@ -1826,6 +1826,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);
|
||||||
|
@ -2483,11 +2496,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 +2535,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 +3035,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)
|
||||||
|
@ -3379,9 +3395,11 @@ 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)
|
||||||
|
@ -3588,9 +3606,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)
|
||||||
|
|
|
@ -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!`,
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
169
src/data/move.ts
|
@ -54,22 +54,28 @@ export enum MoveTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 +275,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;
|
||||||
|
@ -1575,6 +1592,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();
|
||||||
|
@ -3089,6 +3129,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;
|
||||||
|
@ -4165,7 +4241,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)
|
||||||
|
@ -4184,13 +4261,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),
|
||||||
|
@ -4262,7 +4341,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),
|
||||||
|
@ -4450,7 +4530,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)
|
||||||
|
@ -4730,7 +4811,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),
|
||||||
|
@ -5051,7 +5132,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)
|
||||||
|
@ -5194,7 +5276,8 @@ 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),
|
.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)
|
||||||
|
@ -5239,7 +5322,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)
|
||||||
|
@ -5288,7 +5372,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()
|
||||||
|
@ -5344,7 +5429,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)
|
||||||
|
@ -5355,7 +5441,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)
|
||||||
|
@ -5543,7 +5630,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)
|
||||||
|
@ -5580,7 +5668,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)
|
||||||
|
@ -5643,7 +5732,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()
|
||||||
|
@ -5794,7 +5883,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),
|
||||||
|
@ -6085,7 +6175,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)
|
||||||
|
@ -6374,7 +6465,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)
|
||||||
|
@ -6538,7 +6630,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),
|
||||||
|
@ -6588,6 +6681,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),
|
||||||
|
@ -6631,7 +6725,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),
|
||||||
|
@ -6741,7 +6835,8 @@ export function initMoves() {
|
||||||
.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(),
|
||||||
|
|
|
@ -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 { ABILITY_OVERRIDE, MOVE_OVERRIDE, MOVE_OVERRIDE_2, OPP_ABILITY_OVERRIDE, OPP_MOVE_OVERRIDE, OPP_MOVE_OVERRIDE_2, OPP_PASSIVE_ABILITY_OVERRIDE, OPP_SHINY_OVERRIDE, OPP_VARIANT_OVERRIDE, PASSIVE_ABILITY_OVERRIDE } from '../overrides';
|
||||||
import { BerryType } from '../data/berry';
|
import { BerryType } from '../data/berry';
|
||||||
import i18next from '../plugins/i18n';
|
import i18next from '../plugins/i18n';
|
||||||
|
|
||||||
|
@ -811,6 +811,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
getPassiveAbility(): Ability {
|
getPassiveAbility(): Ability {
|
||||||
|
if (PASSIVE_ABILITY_OVERRIDE && this.isPlayer())
|
||||||
|
return allAbilities[PASSIVE_ABILITY_OVERRIDE];
|
||||||
|
if (OPP_PASSIVE_ABILITY_OVERRIDE && !this.isPlayer())
|
||||||
|
return allAbilities[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];
|
||||||
|
@ -818,6 +823,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPassive(): boolean {
|
hasPassive(): boolean {
|
||||||
|
if ((PASSIVE_ABILITY_OVERRIDE !== Abilities.NONE && this.isPlayer()) || (OPP_PASSIVE_ABILITY_OVERRIDE !== Abilities.NONE && !this.isPlayer()))
|
||||||
|
return true;
|
||||||
return this.passive || this.isBoss();
|
return this.passive || this.isBoss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,14 +908,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)
|
||||||
|
@ -1701,18 +1710,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);
|
||||||
}
|
}
|
||||||
|
@ -3126,6 +3136,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 {
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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 deConfig = {
|
||||||
|
ability: ability,
|
||||||
|
battle: battle,
|
||||||
|
commandUiHandler: commandUiHandler,
|
||||||
|
fightUiHandler: fightUiHandler,
|
||||||
|
menuUiHandler: menuUiHandler,
|
||||||
|
menu: menu,
|
||||||
|
move: move,
|
||||||
|
pokeball: pokeball,
|
||||||
|
pokemonStat: pokemonStat,
|
||||||
|
pokemon: pokemon,
|
||||||
|
starterSelectUiHandler: starterSelectUiHandler,
|
||||||
|
tutorial: tutorial
|
||||||
|
}
|
|
@ -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 enConfig = {
|
||||||
|
ability: ability,
|
||||||
|
battle: battle,
|
||||||
|
commandUiHandler: commandUiHandler,
|
||||||
|
fightUiHandler: fightUiHandler,
|
||||||
|
menuUiHandler: menuUiHandler,
|
||||||
|
menu: menu,
|
||||||
|
move: move,
|
||||||
|
pokeball: pokeball,
|
||||||
|
pokemonStat: pokemonStat,
|
||||||
|
pokemon: pokemon,
|
||||||
|
starterSelectUiHandler: starterSelectUiHandler,
|
||||||
|
tutorial: tutorial
|
||||||
|
}
|
|
@ -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 esConfig = {
|
||||||
|
ability: ability,
|
||||||
|
battle: battle,
|
||||||
|
commandUiHandler: commandUiHandler,
|
||||||
|
fightUiHandler: fightUiHandler,
|
||||||
|
menuUiHandler: menuUiHandler,
|
||||||
|
menu: menu,
|
||||||
|
move: move,
|
||||||
|
pokeball: pokeball,
|
||||||
|
pokemonStat: pokemonStat,
|
||||||
|
pokemon: pokemon,
|
||||||
|
starterSelectUiHandler: starterSelectUiHandler,
|
||||||
|
tutorial: tutorial
|
||||||
|
}
|
|
@ -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 frConfig = {
|
||||||
|
ability: ability,
|
||||||
|
battle: battle,
|
||||||
|
commandUiHandler: commandUiHandler,
|
||||||
|
fightUiHandler: fightUiHandler,
|
||||||
|
menuUiHandler: menuUiHandler,
|
||||||
|
menu: menu,
|
||||||
|
move: move,
|
||||||
|
pokeball: pokeball,
|
||||||
|
pokemonStat: pokemonStat,
|
||||||
|
pokemon: pokemon,
|
||||||
|
starterSelectUiHandler: starterSelectUiHandler,
|
||||||
|
tutorial: tutorial
|
||||||
|
}
|
|
@ -7,26 +7,26 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
*/
|
*/
|
||||||
export const starterSelectUiHandler: SimpleTranslationEntries = {
|
export const starterSelectUiHandler: SimpleTranslationEntries = {
|
||||||
"confirmStartTeam":'Commencer avec ces Pokémon ?',
|
"confirmStartTeam":'Commencer avec ces Pokémon ?',
|
||||||
"growthRate": "Growth Rate:",
|
"growthRate": "Croissance :",
|
||||||
"ability": "Ability:",
|
"ability": "Talent :",
|
||||||
"passive": "Passive:",
|
"passive": "Passif :",
|
||||||
"nature": "Nature:",
|
"nature": "Nature :",
|
||||||
"eggMoves": 'Egg Moves',
|
"eggMoves": "Capacités Œuf",
|
||||||
"start": "Start",
|
"start": "Lancer",
|
||||||
"addToParty": "Add to Party",
|
"addToParty": "Ajouter à l’équipe",
|
||||||
"toggleIVs": 'Toggle IVs',
|
"toggleIVs": "Voir IVs",
|
||||||
"manageMoves": 'Manage Moves',
|
"manageMoves": "Gérer Capacités",
|
||||||
"useCandies": 'Use Candies',
|
"useCandies": "Utiliser Bonbons",
|
||||||
"selectMoveSwapOut": "Select a move to swap out.",
|
"selectMoveSwapOut": "Sélectionnez la capacité à échanger.",
|
||||||
"selectMoveSwapWith": "Select a move to swap with",
|
"selectMoveSwapWith": "Sélectionnez laquelle échanger avec",
|
||||||
"unlockPassive": "Unlock Passive",
|
"unlockPassive": "Débloquer Passif",
|
||||||
"reduceCost": "Reduce Cost",
|
"reduceCost": "Diminuer le cout",
|
||||||
"cycleShiny": "R: Cycle Shiny",
|
"cycleShiny": "R: » Chromatiques",
|
||||||
"cycleForm": 'F: Cycle Form',
|
"cycleForm": "F: » Formes",
|
||||||
"cycleGender": 'G: Cycle Gender',
|
"cycleGender": "G: » Sexes",
|
||||||
"cycleAbility": 'E: Cycle Ability',
|
"cycleAbility": "E: » Talents",
|
||||||
"cycleNature": 'N: Cycle Nature',
|
"cycleNature": "N: » Natures",
|
||||||
"cycleVariant": 'V: Cycle Variant',
|
"cycleVariant": "V: » Variants",
|
||||||
"enablePassive": "Enable Passive",
|
"enablePassive": "Activer Passif",
|
||||||
"disablePassive": "Disable Passive"
|
"disablePassive": "Désactiver Passif"
|
||||||
}
|
}
|
|
@ -11,18 +11,18 @@ export const battle: SimpleTranslationEntries = {
|
||||||
"trainerGo": "{{trainerName}} manda in campo {{pokemonName}}!",
|
"trainerGo": "{{trainerName}} manda in campo {{pokemonName}}!",
|
||||||
"switchQuestion": "Vuoi cambiare\n{{pokemonName}}?",
|
"switchQuestion": "Vuoi cambiare\n{{pokemonName}}?",
|
||||||
"trainerDefeated": `Hai sconfitto\n{{trainerName}}!`,
|
"trainerDefeated": `Hai sconfitto\n{{trainerName}}!`,
|
||||||
"pokemonCaught": "{{pokemonName}} è stato catturato!",
|
"pokemonCaught": "Preso! {{pokemonName}} è stato catturato!",
|
||||||
"pokemon": "Pokémon",
|
"pokemon": "Pokémon",
|
||||||
"sendOutPokemon": "Vai! {{pokemonName}}!",
|
"sendOutPokemon": "Vai! {{pokemonName}}!",
|
||||||
"hitResultCriticalHit": "Brutto colpo!",
|
"hitResultCriticalHit": "Brutto colpo!",
|
||||||
"hitResultSuperEffective": "È superefficace!",
|
"hitResultSuperEffective": "È superefficace!",
|
||||||
"hitResultNotVeryEffective": "Non è molto efficace…",
|
"hitResultNotVeryEffective": "Non è molto efficace…",
|
||||||
"hitResultNoEffect": "Non ha effetto su {{pokemonName}}!",
|
"hitResultNoEffect": "Non ha effetto su {{pokemonName}}!",
|
||||||
"hitResultOneHitKO": "È KO con un colpo solo!",
|
"hitResultOneHitKO": "KO con un colpo!",
|
||||||
"attackFailed": "Ma ha fallito!",
|
"attackFailed": "Ma ha fallito!",
|
||||||
"attackHitsCount": `Colpito {{count}} volta/e!`,
|
"attackHitsCount": `Colpito {{count}} volta/e!`,
|
||||||
"expGain": "{{pokemonName}} ha guadagnato\n{{exp}} Punti Esperienza!",
|
"expGain": "{{pokemonName}} ha guadagnato\n{{exp}} Punti Esperienza!",
|
||||||
"levelUp": "{{pokemonName}} è salito al \nLivello {{level}}!",
|
"levelUp": "{{pokemonName}} è salito al \nlivello {{level}}!",
|
||||||
"learnMove": "{{pokemonName}} impara \n{{moveName}}!",
|
"learnMove": "{{pokemonName}} impara \n{{moveName}}!",
|
||||||
"learnMovePrompt": "{{pokemonName}} vorrebbe imparare\n{{moveName}}.",
|
"learnMovePrompt": "{{pokemonName}} vorrebbe imparare\n{{moveName}}.",
|
||||||
"learnMoveLimitReached": "Tuttavia, {{pokemonName}} \nconosce già quattro mosse.",
|
"learnMoveLimitReached": "Tuttavia, {{pokemonName}} \nconosce già quattro mosse.",
|
||||||
|
@ -33,16 +33,16 @@ export const battle: SimpleTranslationEntries = {
|
||||||
"learnMoveForgetSuccess": "{{pokemonName}} ha dimenticato la mossa\n{{moveName}}.",
|
"learnMoveForgetSuccess": "{{pokemonName}} ha dimenticato la mossa\n{{moveName}}.",
|
||||||
"levelCapUp": "Il livello massimo\nè aumentato a {{levelCap}}!",
|
"levelCapUp": "Il livello massimo\nè aumentato a {{levelCap}}!",
|
||||||
"moveNotImplemented": "{{moveName}} non è ancora implementata e non può essere selezionata.",
|
"moveNotImplemented": "{{moveName}} non è ancora implementata e non può essere selezionata.",
|
||||||
"moveNoPP": "There's no PP left for\nthis move!",
|
"moveNoPP": "Non ci sono PP rimanenti\nper questa mossa!",
|
||||||
"moveDisabled": "{{moveName}} è disabilitata!",
|
"moveDisabled": "{{moveName}} è disabilitata!",
|
||||||
"noPokeballForce": "Una forza misteriosa\nimpedisce l'uso dell Poké Ball.",
|
"noPokeballForce": "Una forza misteriosa\nimpedisce l'uso dell Poké Ball.",
|
||||||
"noPokeballTrainer": "Non puoi catturare\nPokémon di altri allenatori!",
|
"noPokeballTrainer": "Non puoi catturare\nPokémon di altri allenatori!",
|
||||||
"noPokeballMulti": "Puoi lanciare una Poké Ball\nquando rimane un solo Pokémon!",
|
"noPokeballMulti": "Puoi lanciare una Poké Ball\nquando rimane un solo Pokémon!",
|
||||||
"noPokeballStrong": "Il Pokémon avversario è troppo forte per essere catturato!\nDevi prima indebolirlo!",
|
"noPokeballStrong": "Il Pokémon avversario è troppo forte per essere catturato!\nDevi prima indebolirlo!",
|
||||||
"noEscapeForce": "Una forza misteriosa\nimpedisce la fuga.",
|
"noEscapeForce": "Una forza misteriosa\nimpedisce la fuga.",
|
||||||
"noEscapeTrainer": "Non puoi fuggire\nda una battaglia contro un'allenatore!",
|
"noEscapeTrainer": "Non puoi sottrarti\nalla lotta con un'allenatore!",
|
||||||
"noEscapePokemon": "{{moveName}} di {{pokemonName}}\npreviene la {{escapeVerb}}!",
|
"noEscapePokemon": "{{moveName}} di {{pokemonName}}\npreviene la {{escapeVerb}}!",
|
||||||
"runAwaySuccess": "Sei riuscito a fuggire!",
|
"runAwaySuccess": "Scampato pericolo!",
|
||||||
"runAwayCannotEscape": 'Non puoi fuggire!',
|
"runAwayCannotEscape": 'Non puoi fuggire!',
|
||||||
"escapeVerbSwitch": "cambiando",
|
"escapeVerbSwitch": "cambiando",
|
||||||
"escapeVerbFlee": "fuggendo",
|
"escapeVerbFlee": "fuggendo",
|
||||||
|
|
|
@ -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 itConfig = {
|
||||||
|
ability: ability,
|
||||||
|
battle: battle,
|
||||||
|
commandUiHandler: commandUiHandler,
|
||||||
|
fightUiHandler: fightUiHandler,
|
||||||
|
menuUiHandler: menuUiHandler,
|
||||||
|
menu: menu,
|
||||||
|
move: move,
|
||||||
|
pokeball: pokeball,
|
||||||
|
pokemonStat: pokemonStat,
|
||||||
|
pokemon: pokemon,
|
||||||
|
starterSelectUiHandler: starterSelectUiHandler,
|
||||||
|
tutorial: tutorial
|
||||||
|
}
|
|
@ -7,26 +7,26 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||||
*/
|
*/
|
||||||
export const starterSelectUiHandler: SimpleTranslationEntries = {
|
export const starterSelectUiHandler: SimpleTranslationEntries = {
|
||||||
"confirmStartTeam":'Vuoi iniziare con questi Pokémon?',
|
"confirmStartTeam":'Vuoi iniziare con questi Pokémon?',
|
||||||
"growthRate": "Growth Rate:",
|
"growthRate": "Vel. Crescita:",
|
||||||
"ability": "Ability:",
|
"ability": "Abilità:",
|
||||||
"passive": "Passive:",
|
"passive": "Passiva:",
|
||||||
"nature": "Nature:",
|
"nature": "Natura:",
|
||||||
"eggMoves": 'Egg Moves',
|
"eggMoves": 'Mosse delle uova',
|
||||||
"start": "Start",
|
"start": "Inizia",
|
||||||
"addToParty": "Add to Party",
|
"addToParty": "Aggiungi al Gruppo",
|
||||||
"toggleIVs": 'Toggle IVs',
|
"toggleIVs": 'Vedi/Nascondi IV',
|
||||||
"manageMoves": 'Manage Moves',
|
"manageMoves": 'Gestisci Mosse',
|
||||||
"useCandies": 'Use Candies',
|
"useCandies": 'Usa Caramelle',
|
||||||
"selectMoveSwapOut": "Select a move to swap out.",
|
"selectMoveSwapOut": "Seleziona una mossa da scambiare.",
|
||||||
"selectMoveSwapWith": "Select a move to swap with",
|
"selectMoveSwapWith": "Seleziona una mossa da scambiare con",
|
||||||
"unlockPassive": "Unlock Passive",
|
"unlockPassive": "Sblocca Passiva",
|
||||||
"reduceCost": "Reduce Cost",
|
"reduceCost": "Riduci Costo",
|
||||||
"cycleShiny": "R: Cycle Shiny",
|
"cycleShiny": "R: Alterna Shiny",
|
||||||
"cycleForm": 'F: Cycle Form',
|
"cycleForm": 'F: Alterna Forma',
|
||||||
"cycleGender": 'G: Cycle Gender',
|
"cycleGender": 'G: Alterna Sesso',
|
||||||
"cycleAbility": 'E: Cycle Ability',
|
"cycleAbility": 'E: Alterna Abilità',
|
||||||
"cycleNature": 'N: Cycle Nature',
|
"cycleNature": 'N: Alterna Natura',
|
||||||
"cycleVariant": 'V: Cycle Variant',
|
"cycleVariant": 'V: Alterna Variante',
|
||||||
"enablePassive": "Enable Passive",
|
"enablePassive": "Attiva Passiva",
|
||||||
"disablePassive": "Disable Passive"
|
"disablePassive": "Disattiva Passiva"
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
@ -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,15 +8,14 @@ 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';
|
||||||
|
@ -1090,6 +1089,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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,15 @@ export const STARTING_WAVE_OVERRIDE = 0;
|
||||||
export const STARTING_BIOME_OVERRIDE = Biome.TOWN;
|
export const STARTING_BIOME_OVERRIDE = Biome.TOWN;
|
||||||
export const STARTING_MONEY_OVERRIDE = 0;
|
export const STARTING_MONEY_OVERRIDE = 0;
|
||||||
export const WEATHER_OVERRIDE = WeatherType.NONE;
|
export const WEATHER_OVERRIDE = WeatherType.NONE;
|
||||||
|
export const DOUBLE_BATTLE_OVERRIDE = false;
|
||||||
|
|
||||||
export const ABILITY_OVERRIDE = Abilities.NONE;
|
export const ABILITY_OVERRIDE = Abilities.NONE;
|
||||||
|
export const PASSIVE_ABILITY_OVERRIDE = Abilities.NONE;
|
||||||
export const MOVE_OVERRIDE = Moves.NONE;
|
export const MOVE_OVERRIDE = Moves.NONE;
|
||||||
export const MOVE_OVERRIDE_2 = Moves.NONE;
|
export const MOVE_OVERRIDE_2 = Moves.NONE;
|
||||||
export const OPP_SPECIES_OVERRIDE = 0;
|
export const OPP_SPECIES_OVERRIDE = 0;
|
||||||
export const OPP_ABILITY_OVERRIDE = Abilities.NONE;
|
export const OPP_ABILITY_OVERRIDE = Abilities.NONE;
|
||||||
|
export const OPP_PASSIVE_ABILITY_OVERRIDE = Abilities.NONE;
|
||||||
export const OPP_MOVE_OVERRIDE = Moves.NONE;
|
export const OPP_MOVE_OVERRIDE = Moves.NONE;
|
||||||
export const OPP_MOVE_OVERRIDE_2 = Moves.NONE;
|
export const OPP_MOVE_OVERRIDE_2 = Moves.NONE;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
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";
|
||||||
|
@ -55,7 +55,7 @@ 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 { STARTER_FORM_OVERRIDE, STARTER_SPECIES_OVERRIDE } from './overrides';
|
||||||
|
@ -3142,8 +3142,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 +3480,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 +3565,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 +3583,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]) {
|
||||||
|
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.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 +3607,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 {
|
||||||
|
|
|
@ -1,77 +1,11 @@
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||||
|
|
||||||
import { menu as enMenu } from '../locales/en/menu';
|
import { deConfig } from '#app/locales/de/config.js';
|
||||||
import { menu as esMenu } from '../locales/es/menu';
|
import { enConfig } from '#app/locales/en/config.js';
|
||||||
import { menu as itMenu } from '../locales/it/menu';
|
import { esConfig } from '#app/locales/es/config.js';
|
||||||
import { menu as frMenu } from '../locales/fr/menu';
|
import { frConfig } from '#app/locales/fr/config.js';
|
||||||
import { menu as deMenu } from '../locales/de/menu';
|
import { itConfig } from '#app/locales/it/config.js';
|
||||||
|
|
||||||
import { menuUiHandler as enMenuUiHandler } from '../locales/en/menu-ui-handler.js';
|
|
||||||
import { menuUiHandler as esMenuUiHandler } from '../locales/es/menu-ui-handler.js';
|
|
||||||
import { menuUiHandler as frMenuUiHandler } from '../locales/fr/menu-ui-handler.js';
|
|
||||||
import { menuUiHandler as itMenuUiHandler } from '../locales/it/menu-ui-handler.js';
|
|
||||||
import { menuUiHandler as deMenuUiHandler } from '../locales/de/menu-ui-handler.js';
|
|
||||||
|
|
||||||
import { battle as enBattle } from '../locales/en/battle';
|
|
||||||
import { battle as esBattle } from '../locales/es/battle';
|
|
||||||
import { battle as itBattle } from '../locales/it/battle';
|
|
||||||
import { battle as frBattle } from '../locales/fr/battle';
|
|
||||||
import { battle as deBattle } from '../locales/de/battle';
|
|
||||||
|
|
||||||
import { move as enMove } from '../locales/en/move';
|
|
||||||
import { move as esMove } from '../locales/es/move';
|
|
||||||
import { move as itMove } from '../locales/it/move';
|
|
||||||
import { move as frMove } from '../locales/fr/move';
|
|
||||||
import { move as deMove } from '../locales/de/move';
|
|
||||||
|
|
||||||
import { ability as enAbility } from '../locales/en/ability';
|
|
||||||
import { ability as esAbility } from '../locales/es/ability';
|
|
||||||
import { ability as itAbility } from '../locales/it/ability';
|
|
||||||
import { ability as frAbility } from '../locales/fr/ability';
|
|
||||||
import { ability as deAbility } from '../locales/de/ability';
|
|
||||||
|
|
||||||
import { pokeball as enPokeball } from '../locales/en/pokeball';
|
|
||||||
import { pokeball as esPokeball } from '../locales/es/pokeball';
|
|
||||||
import { pokeball as itPokeball } from '../locales/it/pokeball';
|
|
||||||
import { pokeball as frPokeball } from '../locales/fr/pokeball';
|
|
||||||
import { pokeball as dePokeball } from '../locales/de/pokeball';
|
|
||||||
|
|
||||||
import { pokemon as enPokemon } from '../locales/en/pokemon';
|
|
||||||
import { pokemon as esPokemon } from '../locales/es/pokemon';
|
|
||||||
import { pokemon as itPokemon } from '../locales/it/pokemon';
|
|
||||||
import { pokemon as frPokemon } from '../locales/fr/pokemon';
|
|
||||||
import { pokemon as dePokemon } from '../locales/de/pokemon';
|
|
||||||
|
|
||||||
import { pokemonStat as enPokemonStat } from '../locales/en/pokemon-stat';
|
|
||||||
import { pokemonStat as esPokemonStat } from '../locales/es/pokemon-stat';
|
|
||||||
import { pokemonStat as frPokemonStat } from '../locales/fr/pokemon-stat';
|
|
||||||
import { pokemonStat as itPokemonStat } from '../locales/it/pokemon-stat';
|
|
||||||
import { pokemonStat as dePokemonStat } from '../locales/de/pokemon-stat';
|
|
||||||
|
|
||||||
import { commandUiHandler as enCommandUiHandler } from '../locales/en/command-ui-handler';
|
|
||||||
import { commandUiHandler as esCommandUiHandler } from '../locales/es/command-ui-handler';
|
|
||||||
import { commandUiHandler as itCommandUiHandler } from '../locales/it/command-ui-handler';
|
|
||||||
import { commandUiHandler as frCommandUiHandler } from '../locales/fr/command-ui-handler';
|
|
||||||
import { commandUiHandler as deCommandUiHandler } from '../locales/de/command-ui-handler';
|
|
||||||
|
|
||||||
import { fightUiHandler as enFightUiHandler } from '../locales/en/fight-ui-handler';
|
|
||||||
import { fightUiHandler as esFightUiHandler } from '../locales/es/fight-ui-handler';
|
|
||||||
import { fightUiHandler as frFightUiHandler } from '../locales/fr/fight-ui-handler';
|
|
||||||
import { fightUiHandler as itFightUiHandler } from '../locales/it/fight-ui-handler';
|
|
||||||
import { fightUiHandler as deFightUiHandler } from '../locales/de/fight-ui-handler';
|
|
||||||
|
|
||||||
import { tutorial as enTutorial } from '../locales/en/tutorial';
|
|
||||||
import { tutorial as esTutorial } from '../locales/es/tutorial';
|
|
||||||
import { tutorial as frTutorial } from '../locales/fr/tutorial';
|
|
||||||
import { tutorial as itTutorial} from '../locales/it/tutorial';
|
|
||||||
import { tutorial as deTutorial } from '../locales/de/tutorial';
|
|
||||||
|
|
||||||
import { starterSelectUiHandler as enStarterSelectUiHandler } from '../locales/en/starter-select-ui-handler';
|
|
||||||
import { starterSelectUiHandler as esStarterSelectUiHandler } from '../locales/es/starter-select-ui-handler';
|
|
||||||
import { starterSelectUiHandler as frStarterSelectUiHandler } from '../locales/fr/starter-select-ui-handler';
|
|
||||||
import { starterSelectUiHandler as itStarterSelectUiHandler} from '../locales/it/starter-select-ui-handler';
|
|
||||||
import { starterSelectUiHandler as deStarterSelectUiHandler } from '../locales/de/starter-select-ui-handler';
|
|
||||||
|
|
||||||
export interface SimpleTranslationEntries {
|
export interface SimpleTranslationEntries {
|
||||||
[key: string]: string
|
[key: string]: string
|
||||||
|
@ -131,74 +65,19 @@ export function initI18n(): void {
|
||||||
},
|
},
|
||||||
resources: {
|
resources: {
|
||||||
en: {
|
en: {
|
||||||
menu: enMenu,
|
...enConfig
|
||||||
menuUiHandler: enMenuUiHandler,
|
|
||||||
battle: enBattle,
|
|
||||||
move: enMove,
|
|
||||||
ability: enAbility,
|
|
||||||
pokeball: enPokeball,
|
|
||||||
pokemon: enPokemon,
|
|
||||||
pokemonStat: enPokemonStat,
|
|
||||||
commandUiHandler: enCommandUiHandler,
|
|
||||||
fightUiHandler: enFightUiHandler,
|
|
||||||
tutorial: enTutorial,
|
|
||||||
starterSelectUiHandler: enStarterSelectUiHandler
|
|
||||||
},
|
},
|
||||||
es: {
|
es: {
|
||||||
menu: esMenu,
|
...esConfig
|
||||||
menuUiHandler: esMenuUiHandler,
|
|
||||||
battle: esBattle,
|
|
||||||
move: esMove,
|
|
||||||
ability: esAbility,
|
|
||||||
pokeball: esPokeball,
|
|
||||||
pokemon: esPokemon,
|
|
||||||
pokemonStat: esPokemonStat,
|
|
||||||
commandUiHandler: esCommandUiHandler,
|
|
||||||
fightUiHandler: esFightUiHandler,
|
|
||||||
tutorial: esTutorial,
|
|
||||||
starterSelectUiHandler: esStarterSelectUiHandler
|
|
||||||
},
|
},
|
||||||
fr: {
|
fr: {
|
||||||
menu: frMenu,
|
...frConfig
|
||||||
menuUiHandler: frMenuUiHandler,
|
|
||||||
battle: frBattle,
|
|
||||||
move: frMove,
|
|
||||||
ability: frAbility,
|
|
||||||
pokeball: frPokeball,
|
|
||||||
pokemon: frPokemon,
|
|
||||||
pokemonStat: frPokemonStat,
|
|
||||||
commandUiHandler: frCommandUiHandler,
|
|
||||||
fightUiHandler: frFightUiHandler,
|
|
||||||
tutorial: frTutorial,
|
|
||||||
starterSelectUiHandler: frStarterSelectUiHandler
|
|
||||||
},
|
},
|
||||||
it: {
|
it: {
|
||||||
menu: itMenu,
|
...itConfig
|
||||||
menuUiHandler: itMenuUiHandler,
|
|
||||||
battle: itBattle,
|
|
||||||
move: itMove,
|
|
||||||
ability: itAbility,
|
|
||||||
pokeball: itPokeball,
|
|
||||||
pokemon: itPokemon,
|
|
||||||
pokemonStat: itPokemonStat,
|
|
||||||
commandUiHandler: itCommandUiHandler,
|
|
||||||
fightUiHandler: itFightUiHandler,
|
|
||||||
tutorial: itTutorial,
|
|
||||||
starterSelectUiHandler: itStarterSelectUiHandler
|
|
||||||
},
|
},
|
||||||
de: {
|
de: {
|
||||||
menu: deMenu,
|
...deConfig
|
||||||
menuUiHandler: deMenuUiHandler,
|
|
||||||
battle: deBattle,
|
|
||||||
move: deMove,
|
|
||||||
ability: deAbility,
|
|
||||||
pokeball: dePokeball,
|
|
||||||
pokemon: dePokemon,
|
|
||||||
pokemonStat: dePokemonStat,
|
|
||||||
commandUiHandler: deCommandUiHandler,
|
|
||||||
fightUiHandler: deFightUiHandler,
|
|
||||||
tutorial: deTutorial,
|
|
||||||
starterSelectUiHandler: deStarterSelectUiHandler
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -208,18 +87,18 @@ export function initI18n(): void {
|
||||||
declare module 'i18next' {
|
declare module 'i18next' {
|
||||||
interface CustomTypeOptions {
|
interface CustomTypeOptions {
|
||||||
resources: {
|
resources: {
|
||||||
menu: typeof enMenu;
|
menu: SimpleTranslationEntries;
|
||||||
menuUiHandler: typeof enMenuUiHandler;
|
menuUiHandler: SimpleTranslationEntries;
|
||||||
move: typeof enMove;
|
move: MoveTranslationEntries;
|
||||||
battle: typeof enBattle,
|
battle: SimpleTranslationEntries,
|
||||||
ability: typeof enAbility;
|
ability: AbilityTranslationEntries;
|
||||||
pokeball: typeof enPokeball;
|
pokeball: SimpleTranslationEntries;
|
||||||
pokemon: typeof enPokemon;
|
pokemon: SimpleTranslationEntries;
|
||||||
pokemonStat: typeof enPokemonStat;
|
pokemonStat: SimpleTranslationEntries;
|
||||||
commandUiHandler: typeof enCommandUiHandler;
|
commandUiHandler: SimpleTranslationEntries;
|
||||||
fightUiHandler: typeof enFightUiHandler;
|
fightUiHandler: SimpleTranslationEntries;
|
||||||
tutorial: typeof enTutorial;
|
tutorial: SimpleTranslationEntries;
|
||||||
starterSelectUiHandler: typeof enStarterSelectUiHandler;
|
starterSelectUiHandler: SimpleTranslationEntries;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,11 +250,6 @@ 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 => {
|
|
||||||
if (!response[0]) {
|
|
||||||
this.scene.ui.savingIcon.hide();
|
|
||||||
return resolve(false);
|
|
||||||
}
|
|
||||||
const data: SystemSaveData = {
|
const data: SystemSaveData = {
|
||||||
trainerId: this.trainerId,
|
trainerId: this.trainerId,
|
||||||
secretId: this.secretId,
|
secretId: this.secretId,
|
||||||
|
@ -300,7 +297,6 @@ export class GameData {
|
||||||
resolve(true);
|
resolve(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadSystem(): Promise<boolean> {
|
public loadSystem(): Promise<boolean> {
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -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 + 152, y + 16, '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);
|
||||||
|
@ -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);
|
||||||
|
|
31
src/utils.ts
|
@ -222,7 +222,8 @@ 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';
|
||||||
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));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|