Compare commits

...

12 Commits

Author SHA1 Message Date
innerthunder
0221c9faba
[Ability][Move] Rewrite Type Resolution and Effectiveness Calculation Functions (#3704)
* Make type/category read-only

* Fix protean/libero tests

* Refactor Pokemon type effectiveness calculation

* Merge getMoveEffectiveness and getAttackMoveEffectiveness

* Move priority-blocking ability check

* Fix incorrect early stopping implementation in MultiHitAttr

* Fix Aerilate, etc. affecting variable-type moves

* Thunder Wave now respects Attack type immunities

* Use final move types for pre-defend abilities

* Steal some things from flx's PR hehe

* Fix Thousand Arrows + "No effect" messages

* Fix status type effectiveness check

* Another status move effectiveness update + some docs

* changing status logic again...

* Fix unnecessary "No Effect" message for Volt Absorb, etc

* Add type effectiveness unit test

* Add Galvanize integration tests

* Add multi-hit test to galvanize tests

* Add power check to first Galvanize test

* Add missing doc line

Co-authored-by: Amani H. <109637146+xsn34kzx@users.noreply.github.com>

* Resolve torranx's nits

* Apply suggestions from Kev's code review

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* More suggestions I missed

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Optimize effectiveness test and make others more stylish (#3)

* Resolve Kev's remaining nits and some test issues

---------

Co-authored-by: Amani H. <109637146+xsn34kzx@users.noreply.github.com>
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: flx-sta
Co-authored-by: frutescens
2024-08-25 19:11:01 -07:00
NightKev
443e4bd24c
Multi-target damage reduction is now properly calculated (#3734) 2024-08-25 17:40:43 -07:00
Leo Kim
387d3ac999
[Enhancement] Slightly improve the challenge selection UI, achievement UI, and achievement message window. (#3731)
* resize achv box default width

* add language font size option. DE font size 80px

* resize challenge desc window width. fix cursor width. shrink font size of desc. set middle align start label
2024-08-25 17:11:03 -07:00
Blitzy
0bdb23d41f
[Balance] Give Partner Eevee and G-Max Eevee access to their signatures / Fix G-Max Pikachu Learnset (#2474)
* Add Moves to Eevee

* Add Level Up Moves to G-Max Eevee

* Fix Pikachu G-Max Learnset
2024-08-25 15:26:19 -07:00
damocleas
b7d71df466
[Balance] Gigantamax State/Form Rebalance (#2442)
* [Balance] Gigantamax State/Form Rebalance (WIP)

* GMAX Ability for Orbeetle adjusted

* fixed typo on CHLOROPHYLL

* Adjusted stats so there was a less intense drop in some stats

* Added comments to GMAX Pikachu, Eevee, Meowth

* Updated ability for GMAX Kingler and Eevee

* Added Stellar typing to GMAX Eevee

* Fixed typing on GMAX Eevee and Snorlax

* GMax Garbodor- Toxic Debris > Corrosion

* Corrected Trubbish passive to not overlap with GMax Garbodor

* Update pokemonFixed Coalossal, Flapple, and Centiskorch BST, Alcremie Ability Change

* Changed Alcremie Passive in adjustment with Gmax ability

* Undid Eevee being Stellar

* Gmax Sandaconda Sand Stream -> Sand Spit

* Balance Sweep of changes by damo, less dropped stats and simpler spreads

* fixed 5 Appletun BST I missed

* fixed missing Hatterene BST
2024-08-25 22:51:00 +02:00
Asdar
1c715d74b1
[Localisation] [IT] Old PRs to .json and screenshots (#3737)
* [Localisation] Italian PRs to .json and screenshots

* Update src/locales/it/trainer-titles.json

Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>

---------

Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com>
2024-08-25 13:44:08 -07:00
Lugiad
6b11632114
[Localization] Some French corrections + new dialogues translations (#3727)
* Update ability-trigger.json

* Update ability.json

* Update achv-female.json

* Update achv-male.json

* Update battle-info.json

* Update bgm-name.json

* Update egg.json

* Update menu.json

* Update modifier-type.json

* Update modifier.json

* Update modifier.json

* Update trainer-classes.json

* Update move.json

* Update dialogue-male.json

* Update dialogue-male.json

* Update dialogue-female.json

* Update dialogue-male.json

* Update dialogue-female.json

* Update dialogue-male.json

* Update dialogue-female.json

* Update dialogue-double-battle-female.json

* Update dialogue-double-battle-male.json

* Update dialogue-male.json

* Update dialogue-male.json

* Update dialogue-female.json

* Update bgm-name.json

* Update bgm-name.json

* Update move.json

* Update bgm-name.json

* Update dialogue-male.json

* Update dialogue-female.json

* Update dialogue-male.json

* Update dialogue-female.json

* Update dialogue-male.json

* Update dialogue-male.json

* Update dialogue-male.json

* Update dialogue-female.json

* Update dialogue-male.json

* Update dialogue-female.json

* Update dialogue-male.json

* Update dialogue-female.json

* Update modifier.json

* Update dialogue-male.json

* Update dialogue-female.json

* Update dialogue-male.json

* Update dialogue-female.json
2024-08-25 22:09:01 +02:00
gitlocalize-app[bot]
3bcc9f76f1
Translate modifier-type.json via GitLocalize (#3758)
Co-authored-by: Asdar <asdargmng@gmail.com>
2024-08-25 22:06:36 +02:00
schmidtc1
93f658b624
[Bug] Fixes Lunar Blessing only healing twice on the user instead of ally (#3701)
* Sets Lunar Blessing selfTarget healing to false

* Removes redundant lines

* Adds unit test for Lunar Blessing

* Adjusts unit tests to spy on function calls
2024-08-26 03:58:28 +08:00
NightKev
4162762a0e
[Test] Refactor/consolidate Forecast tests (#3754) 2024-08-25 12:24:44 -07:00
gitlocalize-app[bot]
4ac726f79e
Translate menu.json via GitLocalize (#3752)
Co-authored-by: Asdar <asdargmng@gmail.com>
2024-08-25 12:19:32 -07:00
Blitzy
96a404a3d5
[Balance] Revert Zippy Zap back to its LGPE Implementation (#3495)
* Update move.ts

* Update Move Description

* Update move.ts

---------

Co-authored-by: xsn34kzx <xsn34kzx@gmail.com>
2024-08-25 11:35:58 -07:00
52 changed files with 1808 additions and 1053 deletions

View File

@ -8,7 +8,7 @@ import { Weather, WeatherType } from "./weather";
import { BattlerTag, GroundedTag, GulpMissileTag, SemiInvulnerableTag } from "./battler-tags"; import { BattlerTag, GroundedTag, GulpMissileTag, SemiInvulnerableTag } from "./battler-tags";
import { StatusEffect, getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect"; import { StatusEffect, getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
import { Gender } from "./gender"; import { Gender } from "./gender";
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, ChargeAttr, SacrificialAttr, SacrificialAttrOnHit } from "./move"; import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, ChargeAttr, SacrificialAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr } from "./move";
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
import { Stat, getStatName } from "./pokemon-stat"; import { Stat, getStatName } from "./pokemon-stat";
import { BerryModifier, PokemonHeldItemModifier } from "../modifier/modifier"; import { BerryModifier, PokemonHeldItemModifier } from "../modifier/modifier";
@ -349,7 +349,7 @@ export class TypeImmunityAbAttr extends PreDefendAbAttr {
if ([ MoveTarget.BOTH_SIDES, MoveTarget.ENEMY_SIDE, MoveTarget.USER_SIDE ].includes(move.moveTarget)) { if ([ MoveTarget.BOTH_SIDES, MoveTarget.ENEMY_SIDE, MoveTarget.USER_SIDE ].includes(move.moveTarget)) {
return false; return false;
} }
if (attacker !== pokemon && move.type === this.immuneType) { if (attacker !== pokemon && attacker.getMoveType(move) === this.immuneType) {
(args[0] as Utils.NumberHolder).value = 0; (args[0] as Utils.NumberHolder).value = 0;
return true; return true;
} }
@ -372,7 +372,8 @@ export class AttackTypeImmunityAbAttr extends TypeImmunityAbAttr {
* Example: Levitate * Example: Levitate
*/ */
applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (move.category !== MoveCategory.STATUS) { // this is a hacky way to fix the Levitate/Thousand Arrows interaction, but it works for now...
if (move.category !== MoveCategory.STATUS && !move.hasAttr(NeutralDamageAgainstFlyingTypeMultiplierAttr)) {
return super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args); return super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args);
} }
return false; return false;
@ -392,6 +393,7 @@ export class TypeImmunityHealAbAttr extends TypeImmunityAbAttr {
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name; const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(),
Utils.toDmgValue(pokemon.getMaxHp() / 4), i18next.t("abilityTriggers:typeImmunityHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true)); Utils.toDmgValue(pokemon.getMaxHp() / 4), i18next.t("abilityTriggers:typeImmunityHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true));
cancelled.value = true; // Suppresses "No Effect" message
} }
return true; return true;
} }
@ -415,7 +417,7 @@ class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
const ret = super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args); const ret = super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args);
if (ret) { if (ret) {
cancelled.value = true; cancelled.value = true; // Suppresses "No Effect" message
if (!simulated) { if (!simulated) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
} }
@ -440,7 +442,7 @@ class TypeImmunityAddBattlerTagAbAttr extends TypeImmunityAbAttr {
const ret = super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args); const ret = super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args);
if (ret) { if (ret) {
cancelled.value = true; cancelled.value = true; // Suppresses "No Effect" message
if (!simulated) { if (!simulated) {
pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id); pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id);
} }
@ -456,8 +458,8 @@ export class NonSuperEffectiveImmunityAbAttr extends TypeImmunityAbAttr {
} }
applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (move instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.type, attacker) < 2) { if (move instanceof AttackMove && pokemon.getAttackTypeEffectiveness(pokemon.getMoveType(move), attacker) < 2) {
cancelled.value = true; cancelled.value = true; // Suppresses "No Effect" message
(args[0] as Utils.NumberHolder).value = 0; (args[0] as Utils.NumberHolder).value = 0;
return true; return true;
} }
@ -764,7 +766,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
if (simulated) { if (simulated) {
return true; return true;
} }
const type = move.type; const type = attacker.getMoveType(move);
const pokemonTypes = pokemon.getTypes(true); const pokemonTypes = pokemon.getTypes(true);
if (pokemonTypes.length !== 1 || pokemonTypes[0] !== type) { if (pokemonTypes.length !== 1 || pokemonTypes[0] !== type) {
pokemon.summonData.types = [ type ]; pokemon.summonData.types = [ type ];
@ -1212,7 +1214,7 @@ export class FieldMultiplyBattleStatAbAttr extends AbAttr {
} }
export class MoveTypeChangeAttr extends PreAttackAbAttr { export class MoveTypeChangeAbAttr extends PreAttackAbAttr {
constructor( constructor(
private newType: Type, private newType: Type,
private powerMultiplier: number, private powerMultiplier: number,
@ -1221,11 +1223,14 @@ export class MoveTypeChangeAttr extends PreAttackAbAttr {
super(true); super(true);
} }
// TODO: Decouple this into two attributes (type change / power boost)
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean {
if (this.condition && this.condition(pokemon, defender, move)) { if (this.condition && this.condition(pokemon, defender, move)) {
move.type = this.newType;
if (args[0] && args[0] instanceof Utils.NumberHolder) { if (args[0] && args[0] instanceof Utils.NumberHolder) {
args[0].value *= this.powerMultiplier; args[0].value = this.newType;
}
if (args[1] && args[1] instanceof Utils.NumberHolder) {
args[1].value *= this.powerMultiplier;
} }
return true; return true;
} }
@ -1257,22 +1262,12 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr {
attr instanceof CopyMoveAttr attr instanceof CopyMoveAttr
) )
) { ) {
// TODO remove this copy when phase order is changed so that damage, type, category, etc. const moveType = pokemon.getMoveType(move);
// TODO are all calculated prior to playing the move animation.
const moveCopy = new Move(move.id, move.type, move.category, move.moveTarget, move.power, move.accuracy, move.pp, move.chance, move.priority, move.generation);
moveCopy.attrs = move.attrs;
// Moves like Weather Ball ignore effects of abilities like Normalize and Refrigerate if (pokemon.getTypes().some((t) => t !== moveType)) {
if (move.findAttr(attr => attr instanceof VariableMoveTypeAttr)) {
applyMoveAttrs(VariableMoveTypeAttr, pokemon, null, moveCopy);
} else {
applyPreAttackAbAttrs(MoveTypeChangeAttr, pokemon, null, moveCopy);
}
if (pokemon.getTypes().some((t) => t !== moveCopy.type)) {
if (!simulated) { if (!simulated) {
this.moveType = moveCopy.type; this.moveType = moveType;
pokemon.summonData.types = [moveCopy.type]; pokemon.summonData.types = [moveType];
pokemon.updateInfo(); pokemon.updateInfo();
} }
@ -2978,16 +2973,20 @@ function getAnticipationCondition(): AbAttrCondition {
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
for (const opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
for (const move of opponent.moveset) { for (const move of opponent.moveset) {
// move is super effective // ignore null/undefined moves
if (move!.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move!.getMove().type, opponent, true) >= 2) { // TODO: is this bang correct? if (!move) {
continue;
}
// the move's base type (not accounting for variable type changes) is super effective
if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent, true) >= 2) {
return true; return true;
} }
// move is a OHKO // move is a OHKO
if (move?.getMove().hasAttr(OneHitKOAttr)) { if (move.getMove().hasAttr(OneHitKOAttr)) {
return true; return true;
} }
// edge case for hidden power, type is computed // edge case for hidden power, type is computed
if (move?.getMove().id === Moves.HIDDEN_POWER) { if (move.getMove().id === Moves.HIDDEN_POWER) {
const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1) const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1)
+(opponent.ivs[Stat.ATK] & 1) * 2 +(opponent.ivs[Stat.ATK] & 1) * 2
+(opponent.ivs[Stat.DEF] & 1) * 4 +(opponent.ivs[Stat.DEF] & 1) * 4
@ -5019,7 +5018,7 @@ export function initAbilities() {
.conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, BattleStatMultiplierAbAttr, BattleStat.SPD, 2) .conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, BattleStatMultiplierAbAttr, BattleStat.SPD, 2)
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), BattleStatMultiplierAbAttr, BattleStat.SPD, 1.5), .conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), BattleStatMultiplierAbAttr, BattleStat.SPD, 1.5),
new Ability(Abilities.NORMALIZE, 4) new Ability(Abilities.NORMALIZE, 4)
.attr(MoveTypeChangeAttr, Type.NORMAL, 1.2, (user, target, move) => { .attr(MoveTypeChangeAbAttr, Type.NORMAL, 1.2, (user, target, move) => {
return ![Moves.HIDDEN_POWER, Moves.WEATHER_BALL, Moves.NATURAL_GIFT, Moves.JUDGMENT, Moves.TECHNO_BLAST].includes(move.id); return ![Moves.HIDDEN_POWER, Moves.WEATHER_BALL, Moves.NATURAL_GIFT, Moves.JUDGMENT, Moves.TECHNO_BLAST].includes(move.id);
}), }),
new Ability(Abilities.SNIPER, 4) new Ability(Abilities.SNIPER, 4)
@ -5260,7 +5259,7 @@ export function initAbilities() {
new Ability(Abilities.STRONG_JAW, 6) new Ability(Abilities.STRONG_JAW, 6)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.BITING_MOVE), 1.5), .attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.BITING_MOVE), 1.5),
new Ability(Abilities.REFRIGERATE, 6) new Ability(Abilities.REFRIGERATE, 6)
.attr(MoveTypeChangeAttr, Type.ICE, 1.2, (user, target, move) => move.type === Type.NORMAL), .attr(MoveTypeChangeAbAttr, Type.ICE, 1.2, (user, target, move) => move.type === Type.NORMAL && !move.hasAttr(VariableMoveTypeAttr)),
new Ability(Abilities.SWEET_VEIL, 6) new Ability(Abilities.SWEET_VEIL, 6)
.attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.SLEEP) .attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.SLEEP)
.attr(UserFieldBattlerTagImmunityAbAttr, BattlerTagType.DROWSY) .attr(UserFieldBattlerTagImmunityAbAttr, BattlerTagType.DROWSY)
@ -5283,11 +5282,11 @@ export function initAbilities() {
new Ability(Abilities.TOUGH_CLAWS, 6) new Ability(Abilities.TOUGH_CLAWS, 6)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 1.3), .attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 1.3),
new Ability(Abilities.PIXILATE, 6) new Ability(Abilities.PIXILATE, 6)
.attr(MoveTypeChangeAttr, Type.FAIRY, 1.2, (user, target, move) => move.type === Type.NORMAL), .attr(MoveTypeChangeAbAttr, Type.FAIRY, 1.2, (user, target, move) => move.type === Type.NORMAL && !move.hasAttr(VariableMoveTypeAttr)),
new Ability(Abilities.GOOEY, 6) new Ability(Abilities.GOOEY, 6)
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), BattleStat.SPD, -1, false), .attr(PostDefendStatChangeAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), BattleStat.SPD, -1, false),
new Ability(Abilities.AERILATE, 6) new Ability(Abilities.AERILATE, 6)
.attr(MoveTypeChangeAttr, Type.FLYING, 1.2, (user, target, move) => move.type === Type.NORMAL), .attr(MoveTypeChangeAbAttr, Type.FLYING, 1.2, (user, target, move) => move.type === Type.NORMAL && !move.hasAttr(VariableMoveTypeAttr)),
new Ability(Abilities.PARENTAL_BOND, 6) new Ability(Abilities.PARENTAL_BOND, 6)
.attr(AddSecondStrikeAbAttr, 0.25), .attr(AddSecondStrikeAbAttr, 0.25),
new Ability(Abilities.DARK_AURA, 6) new Ability(Abilities.DARK_AURA, 6)
@ -5359,11 +5358,11 @@ export function initAbilities() {
new Ability(Abilities.LONG_REACH, 7) new Ability(Abilities.LONG_REACH, 7)
.attr(IgnoreContactAbAttr), .attr(IgnoreContactAbAttr),
new Ability(Abilities.LIQUID_VOICE, 7) new Ability(Abilities.LIQUID_VOICE, 7)
.attr(MoveTypeChangeAttr, Type.WATER, 1, (user, target, move) => move.hasFlag(MoveFlags.SOUND_BASED)), .attr(MoveTypeChangeAbAttr, Type.WATER, 1, (user, target, move) => move.hasFlag(MoveFlags.SOUND_BASED)),
new Ability(Abilities.TRIAGE, 7) new Ability(Abilities.TRIAGE, 7)
.attr(ChangeMovePriorityAbAttr, (pokemon, move) => move.hasFlag(MoveFlags.TRIAGE_MOVE), 3), .attr(ChangeMovePriorityAbAttr, (pokemon, move) => move.hasFlag(MoveFlags.TRIAGE_MOVE), 3),
new Ability(Abilities.GALVANIZE, 7) new Ability(Abilities.GALVANIZE, 7)
.attr(MoveTypeChangeAttr, Type.ELECTRIC, 1.2, (user, target, move) => move.type === Type.NORMAL), .attr(MoveTypeChangeAbAttr, Type.ELECTRIC, 1.2, (user, target, move) => move.type === Type.NORMAL && !move.hasAttr(VariableMoveTypeAttr)),
new Ability(Abilities.SURGE_SURFER, 7) new Ability(Abilities.SURGE_SURFER, 7)
.conditionalAttr(getTerrainCondition(TerrainType.ELECTRIC), BattleStatMultiplierAbAttr, BattleStat.SPD, 2), .conditionalAttr(getTerrainCondition(TerrainType.ELECTRIC), BattleStatMultiplierAbAttr, BattleStat.SPD, 2),
new Ability(Abilities.SCHOOLING, 7) new Ability(Abilities.SCHOOLING, 7)

View File

@ -9,7 +9,7 @@ import { Constructor } from "#app/utils";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { WeatherType } from "./weather"; import { WeatherType } from "./weather";
import { ArenaTagSide, ArenaTrapTag, WeakenMoveTypeTag } from "./arena-tag"; import { ArenaTagSide, ArenaTrapTag, WeakenMoveTypeTag } from "./arena-tag";
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, BlockItemTheftAbAttr, applyPostAttackAbAttrs, ConfusionOnStatusEffectAbAttr, HealFromBerryUseAbAttr, IgnoreProtectOnContactAbAttr, IgnoreMoveEffectsAbAttr, applyPreDefendAbAttrs, MoveEffectChanceMultiplierAbAttr, WonderSkinAbAttr, applyPreAttackAbAttrs, MoveTypeChangeAttr, UserFieldMoveTypePowerBoostAbAttr, FieldMoveTypePowerBoostAbAttr, AllyMoveCategoryPowerBoostAbAttr, VariableMovePowerAbAttr } from "./ability"; import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, BlockItemTheftAbAttr, applyPostAttackAbAttrs, ConfusionOnStatusEffectAbAttr, HealFromBerryUseAbAttr, IgnoreProtectOnContactAbAttr, IgnoreMoveEffectsAbAttr, applyPreDefendAbAttrs, MoveEffectChanceMultiplierAbAttr, WonderSkinAbAttr, applyPreAttackAbAttrs, MoveTypeChangeAbAttr, UserFieldMoveTypePowerBoostAbAttr, FieldMoveTypePowerBoostAbAttr, AllyMoveCategoryPowerBoostAbAttr, VariableMovePowerAbAttr } from "./ability";
import { allAbilities } from "./ability"; import { allAbilities } from "./ability";
import { PokemonHeldItemModifier, BerryModifier, PreserveBerryModifier, PokemonMoveAccuracyBoosterModifier, AttackTypeBoosterModifier, PokemonMultiHitModifier } from "../modifier/modifier"; import { PokemonHeldItemModifier, BerryModifier, PreserveBerryModifier, PokemonMoveAccuracyBoosterModifier, AttackTypeBoosterModifier, PokemonMultiHitModifier } from "../modifier/modifier";
import { BattlerIndex, BattleType } from "../battle"; import { BattlerIndex, BattleType } from "../battle";
@ -113,9 +113,8 @@ type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean;
export default class Move implements Localizable { export default class Move implements Localizable {
public id: Moves; public id: Moves;
public name: string; public name: string;
public type: Type; private _type: Type;
public defaultType: Type; private _category: MoveCategory;
public category: MoveCategory;
public moveTarget: MoveTarget; public moveTarget: MoveTarget;
public power: integer; public power: integer;
public accuracy: integer; public accuracy: integer;
@ -133,9 +132,8 @@ export default class Move implements Localizable {
this.id = id; this.id = id;
this.nameAppend = ""; this.nameAppend = "";
this.type = type; this._type = type;
this.defaultType = type; this._category = category;
this.category = category;
this.moveTarget = defaultMoveTarget; this.moveTarget = defaultMoveTarget;
this.power = power; this.power = power;
this.accuracy = accuracy; this.accuracy = accuracy;
@ -158,6 +156,13 @@ export default class Move implements Localizable {
this.localize(); this.localize();
} }
get type() {
return this._type;
}
get category() {
return this._category;
}
localize(): void { localize(): void {
const i18nKey = Moves[this.id].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as unknown as string; const i18nKey = Moves[this.id].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as unknown as string;
@ -733,7 +738,7 @@ export default class Move implements Localizable {
const power = new Utils.NumberHolder(this.power); const power = new Utils.NumberHolder(this.power);
const typeChangeMovePowerMultiplier = new Utils.NumberHolder(1); const typeChangeMovePowerMultiplier = new Utils.NumberHolder(1);
applyPreAttackAbAttrs(MoveTypeChangeAttr, source, target, this, simulated, typeChangeMovePowerMultiplier); applyPreAttackAbAttrs(MoveTypeChangeAbAttr, source, target, this, true, null, typeChangeMovePowerMultiplier);
const sourceTeraType = source.getTeraType(); const sourceTeraType = source.getTeraType();
if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr(MultiHitAttr) && !source.scene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) { if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr(MultiHitAttr) && !source.scene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) {
@ -1083,15 +1088,12 @@ export class PreMoveMessageAttr extends MoveAttr {
} }
} }
export class StatusMoveTypeImmunityAttr extends MoveAttr { /**
public immuneType: Type; * Attribute for Status moves that take attack type effectiveness
* into consideration (i.e. {@linkcode https://bulbapedia.bulbagarden.net/wiki/Thunder_Wave_(move) | Thunder Wave})
constructor(immuneType: Type) { * @extends MoveAttr
super(false); */
export class RespectAttackTypeImmunityAttr extends MoveAttr { }
this.immuneType = immuneType;
}
}
export class IgnoreOpponentStatChangesAttr extends MoveAttr { export class IgnoreOpponentStatChangesAttr extends MoveAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
@ -1851,19 +1853,11 @@ export class MultiHitAttr extends MoveAttr {
* @returns True * @returns True
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
let hitTimes: integer; const hitType = new Utils.NumberHolder(this.multiHitType);
applyMoveAttrs(ChangeMultiHitTypeAttr, user, target, move, hitType);
this.multiHitType = hitType.value;
if (target.getAttackMoveEffectiveness(user, new PokemonMove(move.id)) === 0) { (args[0] as Utils.NumberHolder).value = this.getHitCount(user, target);
// If there is a type immunity, the attack will stop no matter what
hitTimes = 1;
} else {
const hitType = new Utils.IntegerHolder(this.multiHitType);
applyMoveAttrs(ChangeMultiHitTypeAttr, user, target, move, hitType);
this.multiHitType = hitType.value;
hitTimes = this.getHitCount(user, target);
}
(args[0] as Utils.IntegerHolder).value = hitTimes;
return true; return true;
} }
@ -3762,7 +3756,7 @@ export class VariableMoveCategoryAttr extends MoveAttr {
export class PhotonGeyserCategoryAttr extends VariableMoveCategoryAttr { export class PhotonGeyserCategoryAttr extends VariableMoveCategoryAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const category = (args[0] as Utils.IntegerHolder); const category = (args[0] as Utils.NumberHolder);
if (user.getBattleStat(Stat.ATK, target, move) > user.getBattleStat(Stat.SPATK, target, move)) { if (user.getBattleStat(Stat.ATK, target, move) > user.getBattleStat(Stat.SPATK, target, move)) {
category.value = MoveCategory.PHYSICAL; category.value = MoveCategory.PHYSICAL;
@ -3775,7 +3769,7 @@ export class PhotonGeyserCategoryAttr extends VariableMoveCategoryAttr {
export class TeraBlastCategoryAttr extends VariableMoveCategoryAttr { export class TeraBlastCategoryAttr extends VariableMoveCategoryAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const category = (args[0] as Utils.IntegerHolder); const category = (args[0] as Utils.NumberHolder);
if (user.isTerastallized() && user.getBattleStat(Stat.ATK, target, move) > user.getBattleStat(Stat.SPATK, target, move)) { if (user.isTerastallized() && user.getBattleStat(Stat.ATK, target, move) > user.getBattleStat(Stat.SPATK, target, move)) {
category.value = MoveCategory.PHYSICAL; category.value = MoveCategory.PHYSICAL;
@ -3791,18 +3785,21 @@ export class TeraBlastCategoryAttr extends VariableMoveCategoryAttr {
* @extends VariablePowerAttr * @extends VariablePowerAttr
*/ */
export class TeraBlastPowerAttr extends VariablePowerAttr { export class TeraBlastPowerAttr extends VariablePowerAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
/** /**
* @param user {@linkcode Pokemon} Pokemon using the move * Sets Tera Blast's power to 100 if the user is terastallized with
* @param target {@linkcode Pokemon} N/A * the Stellar tera type.
* @param move {@linkcode Move} {@linkcode Move.TERA_BLAST} * @param user {@linkcode Pokemon} the Pokemon using this move
* @param {any[]} args N/A * @param target n/a
* @returns true or false * @param move {@linkcode Move} the Move with this attribute (i.e. Tera Blast)
* @param args
* - [0] {@linkcode Utils.NumberHolder} the applied move's power, factoring in
* previously applied power modifiers.
* @returns
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const power = args[0] as Utils.NumberHolder; const power = args[0] as Utils.NumberHolder;
if (user.isTerastallized() && move.type === Type.STELLAR) { if (user.isTerastallized() && user.getTeraType() === Type.STELLAR) {
//200 instead of 100 to reflect lack of stellar being 2x dmg on any type power.value = 100;
power.value = 200;
return true; return true;
} }
@ -3862,10 +3859,15 @@ export class VariableMoveTypeAttr extends MoveAttr {
export class FormChangeItemTypeAttr extends VariableMoveTypeAttr { export class FormChangeItemTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveType = args[0];
if (!(moveType instanceof Utils.NumberHolder)) {
return false;
}
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.ARCEUS) || [user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.SILVALLY)) { if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.ARCEUS) || [user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.SILVALLY)) {
const form = user.species.speciesId === Species.ARCEUS || user.species.speciesId === Species.SILVALLY ? user.formIndex : user.fusionSpecies?.formIndex!; // TODO: is this bang correct? const form = user.species.speciesId === Species.ARCEUS || user.species.speciesId === Species.SILVALLY ? user.formIndex : user.fusionSpecies?.formIndex!; // TODO: is this bang correct?
move.type = Type[Type[form]]; moveType.value = Type[Type[form]];
return true; return true;
} }
@ -3875,24 +3877,29 @@ export class FormChangeItemTypeAttr extends VariableMoveTypeAttr {
export class TechnoBlastTypeAttr extends VariableMoveTypeAttr { export class TechnoBlastTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveType = args[0];
if (!(moveType instanceof Utils.NumberHolder)) {
return false;
}
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.GENESECT)) { if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.GENESECT)) {
const form = user.species.speciesId === Species.GENESECT ? user.formIndex : user.fusionSpecies?.formIndex; const form = user.species.speciesId === Species.GENESECT ? user.formIndex : user.fusionSpecies?.formIndex;
switch (form) { switch (form) {
case 1: // Shock Drive case 1: // Shock Drive
move.type = Type.ELECTRIC; moveType.value = Type.ELECTRIC;
break; break;
case 2: // Burn Drive case 2: // Burn Drive
move.type = Type.FIRE; moveType.value = Type.FIRE;
break; break;
case 3: // Chill Drive case 3: // Chill Drive
move.type = Type.ICE; moveType.value = Type.ICE;
break; break;
case 4: // Douse Drive case 4: // Douse Drive
move.type = Type.WATER; moveType.value = Type.WATER;
break; break;
default: default:
move.type = Type.NORMAL; moveType.value = Type.NORMAL;
break; break;
} }
return true; return true;
@ -3904,15 +3911,20 @@ export class TechnoBlastTypeAttr extends VariableMoveTypeAttr {
export class AuraWheelTypeAttr extends VariableMoveTypeAttr { export class AuraWheelTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveType = args[0];
if (!(moveType instanceof Utils.NumberHolder)) {
return false;
}
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.MORPEKO)) { if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.MORPEKO)) {
const form = user.species.speciesId === Species.MORPEKO ? user.formIndex : user.fusionSpecies?.formIndex; const form = user.species.speciesId === Species.MORPEKO ? user.formIndex : user.fusionSpecies?.formIndex;
switch (form) { switch (form) {
case 1: // Hangry Mode case 1: // Hangry Mode
move.type = Type.DARK; moveType.value = Type.DARK;
break; break;
default: // Full Belly Mode default: // Full Belly Mode
move.type = Type.ELECTRIC; moveType.value = Type.ELECTRIC;
break; break;
} }
return true; return true;
@ -3924,18 +3936,23 @@ export class AuraWheelTypeAttr extends VariableMoveTypeAttr {
export class RagingBullTypeAttr extends VariableMoveTypeAttr { export class RagingBullTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveType = args[0];
if (!(moveType instanceof Utils.NumberHolder)) {
return false;
}
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.PALDEA_TAUROS)) { if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.PALDEA_TAUROS)) {
const form = user.species.speciesId === Species.PALDEA_TAUROS ? user.formIndex : user.fusionSpecies?.formIndex; const form = user.species.speciesId === Species.PALDEA_TAUROS ? user.formIndex : user.fusionSpecies?.formIndex;
switch (form) { switch (form) {
case 1: // Blaze breed case 1: // Blaze breed
move.type = Type.FIRE; moveType.value = Type.FIRE;
break; break;
case 2: // Aqua breed case 2: // Aqua breed
move.type = Type.WATER; moveType.value = Type.WATER;
break; break;
default: default:
move.type = Type.FIGHTING; moveType.value = Type.FIGHTING;
break; break;
} }
return true; return true;
@ -3947,25 +3964,30 @@ export class RagingBullTypeAttr extends VariableMoveTypeAttr {
export class IvyCudgelTypeAttr extends VariableMoveTypeAttr { export class IvyCudgelTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveType = args[0];
if (!(moveType instanceof Utils.NumberHolder)) {
return false;
}
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.OGERPON)) { if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.OGERPON)) {
const form = user.species.speciesId === Species.OGERPON ? user.formIndex : user.fusionSpecies?.formIndex; const form = user.species.speciesId === Species.OGERPON ? user.formIndex : user.fusionSpecies?.formIndex;
switch (form) { switch (form) {
case 1: // Wellspring Mask case 1: // Wellspring Mask
case 5: // Wellspring Mask Tera case 5: // Wellspring Mask Tera
move.type = Type.WATER; moveType.value = Type.WATER;
break; break;
case 2: // Hearthflame Mask case 2: // Hearthflame Mask
case 6: // Hearthflame Mask Tera case 6: // Hearthflame Mask Tera
move.type = Type.FIRE; moveType.value = Type.FIRE;
break; break;
case 3: // Cornerstone Mask case 3: // Cornerstone Mask
case 7: // Cornerstone Mask Tera case 7: // Cornerstone Mask Tera
move.type = Type.ROCK; moveType.value = Type.ROCK;
break; break;
case 4: // Teal Mask Tera case 4: // Teal Mask Tera
default: default:
move.type = Type.GRASS; moveType.value = Type.GRASS;
break; break;
} }
return true; return true;
@ -3977,22 +3999,27 @@ export class IvyCudgelTypeAttr extends VariableMoveTypeAttr {
export class WeatherBallTypeAttr extends VariableMoveTypeAttr { export class WeatherBallTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveType = args[0];
if (!(moveType instanceof Utils.NumberHolder)) {
return false;
}
if (!user.scene.arena.weather?.isEffectSuppressed(user.scene)) { if (!user.scene.arena.weather?.isEffectSuppressed(user.scene)) {
switch (user.scene.arena.weather?.weatherType) { switch (user.scene.arena.weather?.weatherType) {
case WeatherType.SUNNY: case WeatherType.SUNNY:
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
move.type = Type.FIRE; moveType.value = Type.FIRE;
break; break;
case WeatherType.RAIN: case WeatherType.RAIN:
case WeatherType.HEAVY_RAIN: case WeatherType.HEAVY_RAIN:
move.type = Type.WATER; moveType.value = Type.WATER;
break; break;
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
move.type = Type.ROCK; moveType.value = Type.ROCK;
break; break;
case WeatherType.HAIL: case WeatherType.HAIL:
case WeatherType.SNOW: case WeatherType.SNOW:
move.type = Type.ICE; moveType.value = Type.ICE;
break; break;
default: default:
return false; return false;
@ -4015,10 +4042,15 @@ export class TerrainPulseTypeAttr extends VariableMoveTypeAttr {
* @param user {@linkcode Pokemon} using this move * @param user {@linkcode Pokemon} using this move
* @param target N/A * @param target N/A
* @param move N/A * @param move N/A
* @param args [0] {@linkcode Utils.IntegerHolder} The move's type to be modified * @param args [0] {@linkcode Utils.NumberHolder} The move's type to be modified
* @returns true if the function succeeds * @returns true if the function succeeds
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveType = args[0];
if (!(moveType instanceof Utils.NumberHolder)) {
return false;
}
if (!user.isGrounded()) { if (!user.isGrounded()) {
return false; return false;
} }
@ -4026,16 +4058,16 @@ export class TerrainPulseTypeAttr extends VariableMoveTypeAttr {
const currentTerrain = user.scene.arena.getTerrainType(); const currentTerrain = user.scene.arena.getTerrainType();
switch (currentTerrain) { switch (currentTerrain) {
case TerrainType.MISTY: case TerrainType.MISTY:
move.type = Type.FAIRY; moveType.value = Type.FAIRY;
break; break;
case TerrainType.ELECTRIC: case TerrainType.ELECTRIC:
move.type = Type.ELECTRIC; moveType.value = Type.ELECTRIC;
break; break;
case TerrainType.GRASSY: case TerrainType.GRASSY:
move.type = Type.GRASS; moveType.value = Type.GRASS;
break; break;
case TerrainType.PSYCHIC: case TerrainType.PSYCHIC:
move.type = Type.PSYCHIC; moveType.value = Type.PSYCHIC;
break; break;
default: default:
return false; return false;
@ -4044,8 +4076,17 @@ export class TerrainPulseTypeAttr extends VariableMoveTypeAttr {
} }
} }
/**
* Changes type based on the user's IVs
* @extends VariableMoveTypeAttr
*/
export class HiddenPowerTypeAttr extends VariableMoveTypeAttr { export class HiddenPowerTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveType = args[0];
if (!(moveType instanceof Utils.NumberHolder)) {
return false;
}
const iv_val = Math.floor(((user.ivs[Stat.HP] & 1) const iv_val = Math.floor(((user.ivs[Stat.HP] & 1)
+(user.ivs[Stat.ATK] & 1) * 2 +(user.ivs[Stat.ATK] & 1) * 2
+(user.ivs[Stat.DEF] & 1) * 4 +(user.ivs[Stat.DEF] & 1) * 4
@ -4053,7 +4094,7 @@ export class HiddenPowerTypeAttr extends VariableMoveTypeAttr {
+(user.ivs[Stat.SPATK] & 1) * 16 +(user.ivs[Stat.SPATK] & 1) * 16
+(user.ivs[Stat.SPDEF] & 1) * 32) * 15/63); +(user.ivs[Stat.SPDEF] & 1) * 32) * 15/63);
move.type = [ moveType.value = [
Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND, Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND,
Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL, Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL,
Type.FIRE, Type.WATER, Type.GRASS, Type.ELECTRIC, Type.FIRE, Type.WATER, Type.GRASS, Type.ELECTRIC,
@ -4068,16 +4109,21 @@ export class HiddenPowerTypeAttr extends VariableMoveTypeAttr {
* @extends VariableMoveTypeAttr * @extends VariableMoveTypeAttr
*/ */
export class TeraBlastTypeAttr extends VariableMoveTypeAttr { export class TeraBlastTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
/** /**
* @param user {@linkcode Pokemon} the user's type is checked * @param user {@linkcode Pokemon} the user of the move
* @param target {@linkcode Pokemon} N/A * @param target {@linkcode Pokemon} N/A
* @param move {@linkcode Move} {@linkcode Move.TeraBlastTypeAttr} * @param move {@linkcode Move} the move with this attribute
* @param {any[]} args N/A * @param args `[0]` the move's type to be modified
* @returns true or false * @returns `true` if the move's type was modified; `false` otherwise
*/ */
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveType = args[0];
if (!(moveType instanceof Utils.NumberHolder)) {
return false;
}
if (user.isTerastallized()) { if (user.isTerastallized()) {
move.type = user.getTeraType(); //changes move type to tera type moveType.value = user.getTeraType(); // changes move type to tera type
return true; return true;
} }
@ -4087,14 +4133,18 @@ export class TeraBlastTypeAttr extends VariableMoveTypeAttr {
export class MatchUserTypeAttr extends VariableMoveTypeAttr { export class MatchUserTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveType = args[0];
if (!(moveType instanceof Utils.NumberHolder)) {
return false;
}
const userTypes = user.getTypes(true); const userTypes = user.getTypes(true);
if (userTypes.includes(Type.STELLAR)) { // will not change to stellar type if (userTypes.includes(Type.STELLAR)) { // will not change to stellar type
const nonTeraTypes = user.getTypes(); const nonTeraTypes = user.getTypes();
move.type = nonTeraTypes[0]; moveType.value = nonTeraTypes[0];
return true; return true;
} else if (userTypes.length > 0) { } else if (userTypes.length > 0) {
move.type = userTypes[0]; moveType.value = userTypes[0];
return true; return true;
} else { } else {
return false; return false;
@ -4113,8 +4163,8 @@ export class NeutralDamageAgainstFlyingTypeMultiplierAttr extends VariableMoveTy
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if (!target.getTag(BattlerTagType.IGNORE_FLYING)) { if (!target.getTag(BattlerTagType.IGNORE_FLYING)) {
const multiplier = args[0] as Utils.NumberHolder; const multiplier = args[0] as Utils.NumberHolder;
//When a flying type is hit, the first hit is always 1x multiplier. Levitating pokemon are instantly affected by typing //When a flying type is hit, the first hit is always 1x multiplier.
if (target.isOfType(Type.FLYING) || target.hasAbility(Abilities.LEVITATE)) { if (target.isOfType(Type.FLYING)) {
multiplier.value = 1; multiplier.value = 1;
} }
return true; return true;
@ -6505,7 +6555,7 @@ export function initMoves() {
.attr(StatusEffectAttr, StatusEffect.PARALYSIS), .attr(StatusEffectAttr, StatusEffect.PARALYSIS),
new StatusMove(Moves.THUNDER_WAVE, Type.ELECTRIC, 90, 20, -1, 0, 1) new StatusMove(Moves.THUNDER_WAVE, Type.ELECTRIC, 90, 20, -1, 0, 1)
.attr(StatusEffectAttr, StatusEffect.PARALYSIS) .attr(StatusEffectAttr, StatusEffect.PARALYSIS)
.attr(StatusMoveTypeImmunityAttr, Type.GROUND), .attr(RespectAttackTypeImmunityAttr),
new AttackMove(Moves.THUNDER, Type.ELECTRIC, MoveCategory.SPECIAL, 110, 70, 10, 30, 0, 1) new AttackMove(Moves.THUNDER, Type.ELECTRIC, MoveCategory.SPECIAL, 110, 70, 10, 30, 0, 1)
.attr(StatusEffectAttr, StatusEffect.PARALYSIS) .attr(StatusEffectAttr, StatusEffect.PARALYSIS)
.attr(ThunderAccuracyAttr) .attr(ThunderAccuracyAttr)
@ -8345,8 +8395,8 @@ export function initMoves() {
.partial() .partial()
.ignoresVirtual(), .ignoresVirtual(),
/* End Unused */ /* End Unused */
new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 100, 2, 7) new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 50, 100, 15, 100, 2, 7) //LGPE Implementation
.attr(StatChangeAttr, BattleStat.EVA, 1, true), .attr(CritOnlyAttr),
new AttackMove(Moves.SPLISHY_SPLASH, Type.WATER, MoveCategory.SPECIAL, 90, 100, 15, 30, 0, 7) new AttackMove(Moves.SPLISHY_SPLASH, Type.WATER, MoveCategory.SPECIAL, 90, 100, 15, 30, 0, 7)
.attr(StatusEffectAttr, StatusEffect.PARALYSIS) .attr(StatusEffectAttr, StatusEffect.PARALYSIS)
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
@ -8632,7 +8682,6 @@ export function initMoves() {
.attr(StatusEffectAttr, StatusEffect.BURN), .attr(StatusEffectAttr, StatusEffect.BURN),
new StatusMove(Moves.JUNGLE_HEALING, Type.GRASS, -1, 10, -1, 0, 8) new StatusMove(Moves.JUNGLE_HEALING, Type.GRASS, -1, 10, -1, 0, 8)
.attr(HealAttr, 0.25, true, false) .attr(HealAttr, 0.25, true, false)
.attr(HealStatusEffectAttr, true, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP)
.attr(HealStatusEffectAttr, false, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP) .attr(HealStatusEffectAttr, false, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP)
.target(MoveTarget.USER_AND_ALLIES), .target(MoveTarget.USER_AND_ALLIES),
new AttackMove(Moves.WICKED_BLOW, Type.DARK, MoveCategory.PHYSICAL, 75, 100, 5, -1, 0, 8) new AttackMove(Moves.WICKED_BLOW, Type.DARK, MoveCategory.PHYSICAL, 75, 100, 5, -1, 0, 8)
@ -8736,8 +8785,7 @@ export function initMoves() {
.windMove() .windMove()
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
new StatusMove(Moves.LUNAR_BLESSING, Type.PSYCHIC, -1, 5, -1, 0, 8) new StatusMove(Moves.LUNAR_BLESSING, Type.PSYCHIC, -1, 5, -1, 0, 8)
.attr(HealAttr, 0.25) .attr(HealAttr, 0.25, true, false)
.attr(HealStatusEffectAttr, true, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP)
.attr(HealStatusEffectAttr, false, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP) .attr(HealStatusEffectAttr, false, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP)
.target(MoveTarget.USER_AND_ALLIES) .target(MoveTarget.USER_AND_ALLIES)
.triageMove(), .triageMove(),

View File

@ -18800,6 +18800,85 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
[ 44, Moves.THUNDER ], [ 44, Moves.THUNDER ],
[ 48, Moves.PIKA_PAPOW ], [ 48, Moves.PIKA_PAPOW ],
], ],
8: [
[ 1, Moves.TAIL_WHIP ],
[ 1, Moves.GROWL ],
[ 1, Moves.THUNDER_SHOCK ],
[ 1, Moves.QUICK_ATTACK ],
[ 1, Moves.SWEET_KISS ],
[ 1, Moves.CHARM ],
[ 1, Moves.NASTY_PLOT ],
[ 1, Moves.PLAY_NICE ],
[ 1, Moves.NUZZLE ],
[ 4, Moves.THUNDER_WAVE ],
[ 8, Moves.DOUBLE_TEAM ],
[ 12, Moves.ELECTRO_BALL ],
[ 16, Moves.FEINT ],
[ 20, Moves.ZIPPY_ZAP ], //Custom
[ 24, Moves.AGILITY ],
[ 28, Moves.IRON_TAIL ],
[ 32, Moves.DISCHARGE ],
[ 34, Moves.FLOATY_FALL ], //Custom
[ 36, Moves.THUNDERBOLT ],
[ 40, Moves.LIGHT_SCREEN ],
[ 42, Moves.SPLISHY_SPLASH ], //Custom
[ 44, Moves.THUNDER ],
[ 48, Moves.PIKA_PAPOW ],
],
},
[Species.EEVEE]: { //Custom
1: [
[ 1, Moves.TACKLE ],
[ 1, Moves.TAIL_WHIP ],
[ 1, Moves.GROWL ],
[ 1, Moves.HELPING_HAND ],
[ 1, Moves.COVET ],
[ 5, Moves.SAND_ATTACK ],
[ 10, Moves.QUICK_ATTACK ],
[ 15, Moves.BABY_DOLL_EYES ],
[ 18, Moves.BOUNCY_BUBBLE ], //Custom
[ 18, Moves.SIZZLY_SLIDE ], //Custom
[ 18, Moves.BUZZY_BUZZ ], //Custom
[ 20, Moves.SWIFT ],
[ 25, Moves.BITE ],
[ 30, Moves.COPYCAT ],
[ 33, Moves.BADDY_BAD ], //Custom
[ 33, Moves.GLITZY_GLOW ], //Custom
[ 35, Moves.BATON_PASS ],
[ 40, Moves.VEEVEE_VOLLEY ], //Custom, replaces Take Down
[ 43, Moves.FREEZY_FROST ], //Custom
[ 43, Moves.SAPPY_SEED ], //Custom
[ 45, Moves.CHARM ],
[ 50, Moves.DOUBLE_EDGE ],
[ 53, Moves.SPARKLY_SWIRL ], //Custom
[ 55, Moves.LAST_RESORT ],
],
2: [
[ 1, Moves.TACKLE ],
[ 1, Moves.TAIL_WHIP ],
[ 1, Moves.GROWL ],
[ 1, Moves.HELPING_HAND ],
[ 1, Moves.COVET ],
[ 5, Moves.SAND_ATTACK ],
[ 10, Moves.QUICK_ATTACK ],
[ 15, Moves.BABY_DOLL_EYES ],
[ 18, Moves.BOUNCY_BUBBLE ], //Custom
[ 18, Moves.SIZZLY_SLIDE ], //Custom
[ 18, Moves.BUZZY_BUZZ ], //Custom
[ 20, Moves.SWIFT ],
[ 25, Moves.BITE ],
[ 30, Moves.COPYCAT ],
[ 33, Moves.BADDY_BAD ], //Custom
[ 33, Moves.GLITZY_GLOW ], //Custom
[ 35, Moves.BATON_PASS ],
[ 40, Moves.VEEVEE_VOLLEY ], //Custom, replaces Take Down
[ 43, Moves.FREEZY_FROST ], //Custom
[ 43, Moves.SAPPY_SEED ], //Custom
[ 45, Moves.CHARM ],
[ 50, Moves.DOUBLE_EDGE ],
[ 53, Moves.SPARKLY_SWIRL ], //Custom
[ 55, Moves.LAST_RESORT ],
],
}, },
[Species.DEOXYS]: { [Species.DEOXYS]: {
1: [ 1: [

View File

@ -913,7 +913,7 @@ export function initSpecies() {
new PokemonSpecies(Species.VENUSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true, new PokemonSpecies(Species.VENUSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true,
new PokemonForm("Normal", "", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, true, null, true), new PokemonForm("Normal", "", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, true, null, true),
new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GRASS, Type.POISON, 2.4, 155.5, Abilities.THICK_FAT, Abilities.THICK_FAT, Abilities.THICK_FAT, 625, 80, 100, 123, 122, 120, 80, 45, 50, 263, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GRASS, Type.POISON, 2.4, 155.5, Abilities.THICK_FAT, Abilities.THICK_FAT, Abilities.THICK_FAT, 625, 80, 100, 123, 122, 120, 80, 45, 50, 263, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 625, 100, 90, 120, 110, 130, 75, 45, 50, 263, true), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 100, Abilities.CHLOROPHYLL, Abilities.CHLOROPHYLL, Abilities.CHLOROPHYLL, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true),
), ),
new PokemonSpecies(Species.CHARMANDER, 1, false, false, false, "Lizard Pokémon", Type.FIRE, null, 0.6, 8.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 309, 39, 52, 43, 60, 50, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.CHARMANDER, 1, false, false, false, "Lizard Pokémon", Type.FIRE, null, 0.6, 8.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 309, 39, 52, 43, 60, 50, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.CHARMELEON, 1, false, false, false, "Flame Pokémon", Type.FIRE, null, 1.1, 19, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 405, 58, 64, 58, 80, 65, 80, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.CHARMELEON, 1, false, false, false, "Flame Pokémon", Type.FIRE, null, 1.1, 19, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 405, 58, 64, 58, 80, 65, 80, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false),
@ -921,20 +921,20 @@ export function initSpecies() {
new PokemonForm("Normal", "", Type.FIRE, Type.FLYING, 1.7, 90.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 534, 78, 84, 78, 109, 85, 100, 45, 50, 267, false, null, true), new PokemonForm("Normal", "", Type.FIRE, Type.FLYING, 1.7, 90.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 534, 78, 84, 78, 109, 85, 100, 45, 50, 267, false, null, true),
new PokemonForm("Mega X", SpeciesFormKey.MEGA_X, Type.FIRE, Type.DRAGON, 1.7, 110.5, Abilities.TOUGH_CLAWS, Abilities.NONE, Abilities.TOUGH_CLAWS, 634, 78, 130, 111, 130, 85, 100, 45, 50, 267), new PokemonForm("Mega X", SpeciesFormKey.MEGA_X, Type.FIRE, Type.DRAGON, 1.7, 110.5, Abilities.TOUGH_CLAWS, Abilities.NONE, Abilities.TOUGH_CLAWS, 634, 78, 130, 111, 130, 85, 100, 45, 50, 267),
new PokemonForm("Mega Y", SpeciesFormKey.MEGA_Y, Type.FIRE, Type.FLYING, 1.7, 100.5, Abilities.DROUGHT, Abilities.NONE, Abilities.DROUGHT, 634, 78, 104, 78, 159, 115, 100, 45, 50, 267), new PokemonForm("Mega Y", SpeciesFormKey.MEGA_Y, Type.FIRE, Type.FLYING, 1.7, 100.5, Abilities.DROUGHT, Abilities.NONE, Abilities.DROUGHT, 634, 78, 104, 78, 159, 115, 100, 45, 50, 267),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, Type.FLYING, 28, 90.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 634, 98, 100, 96, 135, 110, 95, 45, 50, 267), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, Type.FLYING, 28, 90.5, Abilities.SOLAR_POWER, Abilities.SOLAR_POWER, Abilities.SOLAR_POWER, 634, 118, 84, 93, 139, 110, 100, 45, 50, 267),
), ),
new PokemonSpecies(Species.SQUIRTLE, 1, false, false, false, "Tiny Turtle Pokémon", Type.WATER, null, 0.5, 9, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 314, 44, 48, 65, 50, 64, 43, 45, 50, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.SQUIRTLE, 1, false, false, false, "Tiny Turtle Pokémon", Type.WATER, null, 0.5, 9, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 314, 44, 48, 65, 50, 64, 43, 45, 50, 63, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.WARTORTLE, 1, false, false, false, "Turtle Pokémon", Type.WATER, null, 1, 22.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 405, 59, 63, 80, 65, 80, 58, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.WARTORTLE, 1, false, false, false, "Turtle Pokémon", Type.WATER, null, 1, 22.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 405, 59, 63, 80, 65, 80, 58, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.BLASTOISE, 1, false, false, false, "Shellfish Pokémon", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonSpecies(Species.BLASTOISE, 1, false, false, false, "Shellfish Pokémon", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true,
new PokemonForm("Normal", "", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, false, null, true), new PokemonForm("Normal", "", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, false, null, true),
new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.WATER, null, 1.6, 101.1, Abilities.MEGA_LAUNCHER, Abilities.NONE, Abilities.MEGA_LAUNCHER, 630, 79, 103, 120, 135, 115, 78, 45, 50, 265), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.WATER, null, 1.6, 101.1, Abilities.MEGA_LAUNCHER, Abilities.NONE, Abilities.MEGA_LAUNCHER, 630, 79, 103, 120, 135, 115, 78, 45, 50, 265),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 25, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 630, 100, 95, 130, 105, 125, 75, 45, 50, 265), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 85.5, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 630, 119, 83, 130, 115, 115, 68, 45, 50, 265),
), ),
new PokemonSpecies(Species.CATERPIE, 1, false, false, false, "Worm Pokémon", Type.BUG, null, 0.3, 2.9, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 45, 30, 35, 20, 20, 45, 255, 50, 39, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.CATERPIE, 1, false, false, false, "Worm Pokémon", Type.BUG, null, 0.3, 2.9, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 45, 30, 35, 20, 20, 45, 255, 50, 39, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.METAPOD, 1, false, false, false, "Cocoon Pokémon", Type.BUG, null, 0.7, 9.9, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.METAPOD, 1, false, false, false, "Cocoon Pokémon", Type.BUG, null, 0.7, 9.9, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.BUTTERFREE, 1, false, false, false, "Butterfly Pokémon", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, GrowthRate.MEDIUM_FAST, 50, true, true, new PokemonSpecies(Species.BUTTERFREE, 1, false, false, false, "Butterfly Pokémon", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, GrowthRate.MEDIUM_FAST, 50, true, true,
new PokemonForm("Normal", "", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, true, null, true), new PokemonForm("Normal", "", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, true, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.FLYING, 17, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 495, 75, 50, 75, 120, 100, 75, 45, 50, 198, true), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.FLYING, 17, 32, Abilities.TINTED_LENS, Abilities.TINTED_LENS, Abilities.TINTED_LENS, 495, 85, 35, 80, 120, 90, 85, 45, 50, 198, true),
), ),
new PokemonSpecies(Species.WEEDLE, 1, false, false, false, "Hairy Bug Pokémon", Type.BUG, Type.POISON, 0.3, 3.2, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 40, 35, 30, 20, 20, 50, 255, 70, 39, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.WEEDLE, 1, false, false, false, "Hairy Bug Pokémon", Type.BUG, Type.POISON, 0.3, 3.2, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 40, 35, 30, 20, 20, 50, 255, 70, 39, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.KAKUNA, 1, false, false, false, "Cocoon Pokémon", Type.BUG, Type.POISON, 0.6, 10, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 45, 25, 50, 25, 25, 35, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.KAKUNA, 1, false, false, false, "Cocoon Pokémon", Type.BUG, Type.POISON, 0.6, 10, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 45, 25, 50, 25, 25, 35, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false),
@ -963,7 +963,7 @@ export function initSpecies() {
new PokemonForm("Cute Cosplay", "cute-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom new PokemonForm("Cute Cosplay", "cute-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom
new PokemonForm("Smart Cosplay", "smart-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom new PokemonForm("Smart Cosplay", "smart-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom
new PokemonForm("Tough Cosplay", "tough-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom new PokemonForm("Tough Cosplay", "tough-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, null, 21, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 420, 45, 60, 65, 100, 75, 75, 190, 50, 112), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, null, 21, 6, Abilities.LIGHTNING_ROD, Abilities.LIGHTNING_ROD, Abilities.LIGHTNING_ROD, 530, 125, 95, 60, 90, 70, 90, 190, 50, 112), //+100 BST from Partner Form
), ),
new PokemonSpecies(Species.RAICHU, 1, false, false, false, "Mouse Pokémon", Type.ELECTRIC, null, 0.8, 30, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 485, 60, 90, 55, 90, 80, 110, 75, 50, 243, GrowthRate.MEDIUM_FAST, 50, true), new PokemonSpecies(Species.RAICHU, 1, false, false, false, "Mouse Pokémon", Type.ELECTRIC, null, 0.8, 30, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 485, 60, 90, 55, 90, 80, 110, 75, 50, 243, GrowthRate.MEDIUM_FAST, 50, true),
new PokemonSpecies(Species.SANDSHREW, 1, false, false, false, "Mouse Pokémon", Type.GROUND, null, 0.6, 12, Abilities.SAND_VEIL, Abilities.NONE, Abilities.SAND_RUSH, 300, 50, 75, 85, 20, 30, 40, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.SANDSHREW, 1, false, false, false, "Mouse Pokémon", Type.GROUND, null, 0.6, 12, Abilities.SAND_VEIL, Abilities.NONE, Abilities.SAND_RUSH, 300, 50, 75, 85, 20, 30, 40, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false),
@ -993,7 +993,7 @@ export function initSpecies() {
new PokemonSpecies(Species.DUGTRIO, 1, false, false, false, "Mole Pokémon", Type.GROUND, null, 0.7, 33.3, Abilities.SAND_VEIL, Abilities.ARENA_TRAP, Abilities.SAND_FORCE, 425, 35, 100, 50, 50, 70, 120, 50, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.DUGTRIO, 1, false, false, false, "Mole Pokémon", Type.GROUND, null, 0.7, 33.3, Abilities.SAND_VEIL, Abilities.ARENA_TRAP, Abilities.SAND_FORCE, 425, 35, 100, 50, 50, 70, 120, 50, 50, 149, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.MEOWTH, 1, false, false, false, "Scratch Cat Pokémon", Type.NORMAL, null, 0.4, 4.2, Abilities.PICKUP, Abilities.TECHNICIAN, Abilities.UNNERVE, 290, 40, 45, 35, 40, 40, 90, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonSpecies(Species.MEOWTH, 1, false, false, false, "Scratch Cat Pokémon", Type.NORMAL, null, 0.4, 4.2, Abilities.PICKUP, Abilities.TECHNICIAN, Abilities.UNNERVE, 290, 40, 45, 35, 40, 40, 90, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false, true,
new PokemonForm("Normal", "", Type.NORMAL, null, 0.4, 4.2, Abilities.PICKUP, Abilities.TECHNICIAN, Abilities.UNNERVE, 290, 40, 45, 35, 40, 40, 90, 255, 50, 58, false, null, true), new PokemonForm("Normal", "", Type.NORMAL, null, 0.4, 4.2, Abilities.PICKUP, Abilities.TECHNICIAN, Abilities.UNNERVE, 290, 40, 45, 35, 40, 40, 90, 255, 50, 58, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.NORMAL, null, 33, 4.2, Abilities.PICKUP, Abilities.TECHNICIAN, Abilities.UNNERVE, 390, 50, 85, 60, 70, 50, 75, 255, 50, 58), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.NORMAL, null, 33, 4.2, Abilities.TECHNICIAN, Abilities.TECHNICIAN, Abilities.TECHNICIAN, 540, 115, 110, 65, 65, 70, 115, 255, 50, 58), //+100 BST from Persian
), ),
new PokemonSpecies(Species.PERSIAN, 1, false, false, false, "Classy Cat Pokémon", Type.NORMAL, null, 1, 32, Abilities.LIMBER, Abilities.TECHNICIAN, Abilities.UNNERVE, 440, 65, 70, 60, 65, 65, 115, 90, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.PERSIAN, 1, false, false, false, "Classy Cat Pokémon", Type.NORMAL, null, 1, 32, Abilities.LIMBER, Abilities.TECHNICIAN, Abilities.UNNERVE, 440, 65, 70, 60, 65, 65, 115, 90, 50, 154, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.PSYDUCK, 1, false, false, false, "Duck Pokémon", Type.WATER, null, 0.8, 19.6, Abilities.DAMP, Abilities.CLOUD_NINE, Abilities.SWIFT_SWIM, 320, 50, 52, 48, 65, 50, 55, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.PSYDUCK, 1, false, false, false, "Duck Pokémon", Type.WATER, null, 0.8, 19.6, Abilities.DAMP, Abilities.CLOUD_NINE, Abilities.SWIFT_SWIM, 320, 50, 52, 48, 65, 50, 55, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false),
@ -1015,7 +1015,7 @@ export function initSpecies() {
new PokemonSpecies(Species.MACHOKE, 1, false, false, false, "Superpower Pokémon", Type.FIGHTING, null, 1.5, 70.5, Abilities.GUTS, Abilities.NO_GUARD, Abilities.STEADFAST, 405, 80, 100, 70, 50, 60, 45, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 75, false), new PokemonSpecies(Species.MACHOKE, 1, false, false, false, "Superpower Pokémon", Type.FIGHTING, null, 1.5, 70.5, Abilities.GUTS, Abilities.NO_GUARD, Abilities.STEADFAST, 405, 80, 100, 70, 50, 60, 45, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 75, false),
new PokemonSpecies(Species.MACHAMP, 1, false, false, false, "Superpower Pokémon", Type.FIGHTING, null, 1.6, 130, Abilities.GUTS, Abilities.NO_GUARD, Abilities.STEADFAST, 505, 90, 130, 80, 65, 85, 55, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 75, false, true, new PokemonSpecies(Species.MACHAMP, 1, false, false, false, "Superpower Pokémon", Type.FIGHTING, null, 1.6, 130, Abilities.GUTS, Abilities.NO_GUARD, Abilities.STEADFAST, 505, 90, 130, 80, 65, 85, 55, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 75, false, true,
new PokemonForm("Normal", "", Type.FIGHTING, null, 1.6, 130, Abilities.GUTS, Abilities.NO_GUARD, Abilities.STEADFAST, 505, 90, 130, 80, 65, 85, 55, 45, 50, 253, false, null, true), new PokemonForm("Normal", "", Type.FIGHTING, null, 1.6, 130, Abilities.GUTS, Abilities.NO_GUARD, Abilities.STEADFAST, 505, 90, 130, 80, 65, 85, 55, 45, 50, 253, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIGHTING, null, 25, 130, Abilities.GUTS, Abilities.NO_GUARD, Abilities.STEADFAST, 605, 113, 170, 90, 70, 95, 67, 45, 50, 253), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIGHTING, null, 25, 130, Abilities.GUTS, Abilities.GUTS, Abilities.GUTS, 605, 115, 170, 95, 65, 95, 65, 45, 50, 253),
), ),
new PokemonSpecies(Species.BELLSPROUT, 1, false, false, false, "Flower Pokémon", Type.GRASS, Type.POISON, 0.7, 4, Abilities.CHLOROPHYLL, Abilities.NONE, Abilities.GLUTTONY, 300, 50, 75, 35, 70, 30, 40, 255, 70, 60, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.BELLSPROUT, 1, false, false, false, "Flower Pokémon", Type.GRASS, Type.POISON, 0.7, 4, Abilities.CHLOROPHYLL, Abilities.NONE, Abilities.GLUTTONY, 300, 50, 75, 35, 70, 30, 40, 255, 70, 60, GrowthRate.MEDIUM_SLOW, 50, false),
new PokemonSpecies(Species.WEEPINBELL, 1, false, false, false, "Flycatcher Pokémon", Type.GRASS, Type.POISON, 1, 6.4, Abilities.CHLOROPHYLL, Abilities.NONE, Abilities.GLUTTONY, 390, 65, 90, 50, 85, 45, 55, 120, 70, 137, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.WEEPINBELL, 1, false, false, false, "Flycatcher Pokémon", Type.GRASS, Type.POISON, 1, 6.4, Abilities.CHLOROPHYLL, Abilities.NONE, Abilities.GLUTTONY, 390, 65, 90, 50, 85, 45, 55, 120, 70, 137, GrowthRate.MEDIUM_SLOW, 50, false),
@ -1048,7 +1048,7 @@ export function initSpecies() {
new PokemonSpecies(Species.GENGAR, 1, false, false, false, "Shadow Pokémon", Type.GHOST, Type.POISON, 1.5, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false, true, new PokemonSpecies(Species.GENGAR, 1, false, false, false, "Shadow Pokémon", Type.GHOST, Type.POISON, 1.5, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false, true,
new PokemonForm("Normal", "", Type.GHOST, Type.POISON, 1.5, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, false, null, true), new PokemonForm("Normal", "", Type.GHOST, Type.POISON, 1.5, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, false, null, true),
new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GHOST, Type.POISON, 1.4, 40.5, Abilities.SHADOW_TAG, Abilities.NONE, Abilities.NONE, 600, 60, 65, 80, 170, 95, 130, 45, 50, 250), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GHOST, Type.POISON, 1.4, 40.5, Abilities.SHADOW_TAG, Abilities.NONE, Abilities.NONE, 600, 60, 65, 80, 170, 95, 130, 45, 50, 250),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GHOST, Type.POISON, 20, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 600, 75, 95, 85, 160, 95, 90, 45, 50, 250), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GHOST, Type.POISON, 20, 40.5, Abilities.CURSED_BODY, Abilities.CURSED_BODY, Abilities.CURSED_BODY, 600, 140, 65, 70, 140, 85, 100, 45, 50, 250),
), ),
new PokemonSpecies(Species.ONIX, 1, false, false, false, "Rock Snake Pokémon", Type.ROCK, Type.GROUND, 8.8, 210, Abilities.ROCK_HEAD, Abilities.STURDY, Abilities.WEAK_ARMOR, 385, 35, 45, 160, 30, 45, 70, 45, 50, 77, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.ONIX, 1, false, false, false, "Rock Snake Pokémon", Type.ROCK, Type.GROUND, 8.8, 210, Abilities.ROCK_HEAD, Abilities.STURDY, Abilities.WEAK_ARMOR, 385, 35, 45, 160, 30, 45, 70, 45, 50, 77, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.DROWZEE, 1, false, false, false, "Hypnosis Pokémon", Type.PSYCHIC, null, 1, 32.4, Abilities.INSOMNIA, Abilities.FOREWARN, Abilities.INNER_FOCUS, 328, 60, 48, 45, 43, 90, 42, 190, 70, 66, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.DROWZEE, 1, false, false, false, "Hypnosis Pokémon", Type.PSYCHIC, null, 1, 32.4, Abilities.INSOMNIA, Abilities.FOREWARN, Abilities.INNER_FOCUS, 328, 60, 48, 45, 43, 90, 42, 190, 70, 66, GrowthRate.MEDIUM_FAST, 50, false),
@ -1056,7 +1056,7 @@ export function initSpecies() {
new PokemonSpecies(Species.KRABBY, 1, false, false, false, "River Crab Pokémon", Type.WATER, null, 0.4, 6.5, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 325, 30, 105, 90, 25, 25, 50, 225, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.KRABBY, 1, false, false, false, "River Crab Pokémon", Type.WATER, null, 0.4, 6.5, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 325, 30, 105, 90, 25, 25, 50, 225, 50, 65, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.KINGLER, 1, false, false, false, "Pincer Pokémon", Type.WATER, null, 1.3, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonSpecies(Species.KINGLER, 1, false, false, false, "Pincer Pokémon", Type.WATER, null, 1.3, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true,
new PokemonForm("Normal", "", Type.WATER, null, 1.3, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, false, null, true), new PokemonForm("Normal", "", Type.WATER, null, 1.3, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 19, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 575, 70, 165, 145, 60, 70, 65, 60, 50, 166), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 19, 60, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, 575, 90, 155, 140, 50, 80, 70, 60, 50, 166),
), ),
new PokemonSpecies(Species.VOLTORB, 1, false, false, false, "Ball Pokémon", Type.ELECTRIC, null, 0.5, 10.4, Abilities.SOUNDPROOF, Abilities.STATIC, Abilities.AFTERMATH, 330, 40, 30, 50, 55, 55, 100, 190, 70, 66, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.VOLTORB, 1, false, false, false, "Ball Pokémon", Type.ELECTRIC, null, 0.5, 10.4, Abilities.SOUNDPROOF, Abilities.STATIC, Abilities.AFTERMATH, 330, 40, 30, 50, 55, 55, 100, 190, 70, 66, GrowthRate.MEDIUM_FAST, null, false),
new PokemonSpecies(Species.ELECTRODE, 1, false, false, false, "Ball Pokémon", Type.ELECTRIC, null, 1.2, 66.6, Abilities.SOUNDPROOF, Abilities.STATIC, Abilities.AFTERMATH, 490, 60, 50, 70, 80, 80, 150, 60, 70, 172, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.ELECTRODE, 1, false, false, false, "Ball Pokémon", Type.ELECTRIC, null, 1.2, 66.6, Abilities.SOUNDPROOF, Abilities.STATIC, Abilities.AFTERMATH, 490, 60, 50, 70, 80, 80, 150, 60, 70, 172, GrowthRate.MEDIUM_FAST, null, false),
@ -1100,13 +1100,13 @@ export function initSpecies() {
), ),
new PokemonSpecies(Species.LAPRAS, 1, false, false, false, "Transport Pokémon", Type.WATER, Type.ICE, 2.5, 220, Abilities.WATER_ABSORB, Abilities.SHELL_ARMOR, Abilities.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, GrowthRate.SLOW, 50, false, true, new PokemonSpecies(Species.LAPRAS, 1, false, false, false, "Transport Pokémon", Type.WATER, Type.ICE, 2.5, 220, Abilities.WATER_ABSORB, Abilities.SHELL_ARMOR, Abilities.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, GrowthRate.SLOW, 50, false, true,
new PokemonForm("Normal", "", Type.WATER, Type.ICE, 2.5, 220, Abilities.WATER_ABSORB, Abilities.SHELL_ARMOR, Abilities.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, false, null, true), new PokemonForm("Normal", "", Type.WATER, Type.ICE, 2.5, 220, Abilities.WATER_ABSORB, Abilities.SHELL_ARMOR, Abilities.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.ICE, 24, 220, Abilities.WATER_ABSORB, Abilities.SHELL_ARMOR, Abilities.HYDRATION, 635, 160, 95, 110, 95, 125, 50, 45, 50, 187), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.ICE, 24, 220, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 635, 170, 85, 95, 115, 110, 60, 45, 50, 187),
), ),
new PokemonSpecies(Species.DITTO, 1, false, false, false, "Transform Pokémon", Type.NORMAL, null, 0.3, 4, Abilities.LIMBER, Abilities.NONE, Abilities.IMPOSTER, 288, 48, 48, 48, 48, 48, 48, 35, 50, 101, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.DITTO, 1, false, false, false, "Transform Pokémon", Type.NORMAL, null, 0.3, 4, Abilities.LIMBER, Abilities.NONE, Abilities.IMPOSTER, 288, 48, 48, 48, 48, 48, 48, 35, 50, 101, GrowthRate.MEDIUM_FAST, null, false),
new PokemonSpecies(Species.EEVEE, 1, false, false, false, "Evolution Pokémon", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, GrowthRate.MEDIUM_FAST, 87.5, false, true, new PokemonSpecies(Species.EEVEE, 1, false, false, false, "Evolution Pokémon", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, GrowthRate.MEDIUM_FAST, 87.5, false, true,
new PokemonForm("Normal", "", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, false, null, true), new PokemonForm("Normal", "", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, false, null, true),
new PokemonForm("Partner", "partner", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 435, 65, 75, 70, 65, 85, 75, 45, 50, 65, false, null, true), new PokemonForm("Partner", "partner", Type.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 435, 65, 75, 70, 65, 85, 75, 45, 50, 65, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.NORMAL, null, 18, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 425, 70, 75, 80, 60, 95, 45, 45, 50, 65), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.NORMAL, null, 18, 6.5, Abilities.PROTEAN, Abilities.PROTEAN, Abilities.PROTEAN, 535, 105, 95, 70, 95, 85, 85, 45, 50, 65), //+100 BST from Partner Form
), ),
new PokemonSpecies(Species.VAPOREON, 1, false, false, false, "Bubble Jet Pokémon", Type.WATER, null, 1, 29, Abilities.WATER_ABSORB, Abilities.NONE, Abilities.HYDRATION, 525, 130, 65, 60, 110, 95, 65, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), new PokemonSpecies(Species.VAPOREON, 1, false, false, false, "Bubble Jet Pokémon", Type.WATER, null, 1, 29, Abilities.WATER_ABSORB, Abilities.NONE, Abilities.HYDRATION, 525, 130, 65, 60, 110, 95, 65, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false),
new PokemonSpecies(Species.JOLTEON, 1, false, false, false, "Lightning Pokémon", Type.ELECTRIC, null, 0.8, 24.5, Abilities.VOLT_ABSORB, Abilities.NONE, Abilities.QUICK_FEET, 525, 65, 65, 60, 110, 95, 130, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), new PokemonSpecies(Species.JOLTEON, 1, false, false, false, "Lightning Pokémon", Type.ELECTRIC, null, 0.8, 24.5, Abilities.VOLT_ABSORB, Abilities.NONE, Abilities.QUICK_FEET, 525, 65, 65, 60, 110, 95, 130, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false),
@ -1122,7 +1122,7 @@ export function initSpecies() {
), ),
new PokemonSpecies(Species.SNORLAX, 1, false, false, false, "Sleeping Pokémon", Type.NORMAL, null, 2.1, 460, Abilities.IMMUNITY, Abilities.THICK_FAT, Abilities.GLUTTONY, 540, 160, 110, 65, 65, 110, 30, 25, 50, 189, GrowthRate.SLOW, 87.5, false, true, new PokemonSpecies(Species.SNORLAX, 1, false, false, false, "Sleeping Pokémon", Type.NORMAL, null, 2.1, 460, Abilities.IMMUNITY, Abilities.THICK_FAT, Abilities.GLUTTONY, 540, 160, 110, 65, 65, 110, 30, 25, 50, 189, GrowthRate.SLOW, 87.5, false, true,
new PokemonForm("Normal", "", Type.NORMAL, null, 2.1, 460, Abilities.IMMUNITY, Abilities.THICK_FAT, Abilities.GLUTTONY, 540, 160, 110, 65, 65, 110, 30, 25, 50, 189, false, null, true), new PokemonForm("Normal", "", Type.NORMAL, null, 2.1, 460, Abilities.IMMUNITY, Abilities.THICK_FAT, Abilities.GLUTTONY, 540, 160, 110, 65, 65, 110, 30, 25, 50, 189, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.NORMAL, null, 35, 460, Abilities.IMMUNITY, Abilities.THICK_FAT, Abilities.GLUTTONY, 640, 200, 130, 85, 75, 130, 20, 25, 50, 189), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.NORMAL, Type.GRASS, 35, 460, Abilities.THICK_FAT, Abilities.THICK_FAT, Abilities.THICK_FAT, 640, 200, 135, 85, 80, 125, 15, 25, 50, 189),
), ),
new PokemonSpecies(Species.ARTICUNO, 1, true, false, false, "Freeze Pokémon", Type.ICE, Type.FLYING, 1.7, 55.4, Abilities.PRESSURE, Abilities.NONE, Abilities.SNOW_CLOAK, 580, 90, 85, 100, 95, 125, 85, 3, 35, 290, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.ARTICUNO, 1, true, false, false, "Freeze Pokémon", Type.ICE, Type.FLYING, 1.7, 55.4, Abilities.PRESSURE, Abilities.NONE, Abilities.SNOW_CLOAK, 580, 90, 85, 100, 95, 125, 85, 3, 35, 290, GrowthRate.SLOW, null, false),
new PokemonSpecies(Species.ZAPDOS, 1, true, false, false, "Electric Pokémon", Type.ELECTRIC, Type.FLYING, 1.6, 52.6, Abilities.PRESSURE, Abilities.NONE, Abilities.STATIC, 580, 90, 90, 85, 125, 90, 100, 3, 35, 290, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.ZAPDOS, 1, true, false, false, "Electric Pokémon", Type.ELECTRIC, Type.FLYING, 1.6, 52.6, Abilities.PRESSURE, Abilities.NONE, Abilities.STATIC, 580, 90, 90, 85, 125, 90, 100, 3, 35, 290, GrowthRate.SLOW, null, false),
@ -1762,7 +1762,7 @@ export function initSpecies() {
new PokemonSpecies(Species.TRUBBISH, 5, false, false, false, "Trash Bag Pokémon", Type.POISON, null, 0.6, 31, Abilities.STENCH, Abilities.STICKY_HOLD, Abilities.AFTERMATH, 329, 50, 50, 62, 40, 62, 65, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.TRUBBISH, 5, false, false, false, "Trash Bag Pokémon", Type.POISON, null, 0.6, 31, Abilities.STENCH, Abilities.STICKY_HOLD, Abilities.AFTERMATH, 329, 50, 50, 62, 40, 62, 65, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.GARBODOR, 5, false, false, false, "Trash Heap Pokémon", Type.POISON, null, 1.9, 107.3, Abilities.STENCH, Abilities.WEAK_ARMOR, Abilities.AFTERMATH, 474, 80, 95, 82, 60, 82, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonSpecies(Species.GARBODOR, 5, false, false, false, "Trash Heap Pokémon", Type.POISON, null, 1.9, 107.3, Abilities.STENCH, Abilities.WEAK_ARMOR, Abilities.AFTERMATH, 474, 80, 95, 82, 60, 82, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true,
new PokemonForm("Normal", "", Type.POISON, null, 1.9, 107.3, Abilities.STENCH, Abilities.WEAK_ARMOR, Abilities.AFTERMATH, 474, 80, 95, 82, 60, 82, 75, 60, 50, 166, false, null, true), new PokemonForm("Normal", "", Type.POISON, null, 1.9, 107.3, Abilities.STENCH, Abilities.WEAK_ARMOR, Abilities.AFTERMATH, 474, 80, 95, 82, 60, 82, 75, 60, 50, 166, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.POISON, null, 21, 107.3, Abilities.STENCH, Abilities.WEAK_ARMOR, Abilities.AFTERMATH, 574, 100, 125, 102, 80, 102, 65, 60, 50, 166), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.POISON, Type.STEEL, 21, 107.3, Abilities.TOXIC_DEBRIS, Abilities.TOXIC_DEBRIS, Abilities.TOXIC_DEBRIS, 574, 135, 125, 102, 57, 102, 53, 60, 50, 166),
), ),
new PokemonSpecies(Species.ZORUA, 5, false, false, false, "Tricky Fox Pokémon", Type.DARK, null, 0.7, 12.5, Abilities.ILLUSION, Abilities.NONE, Abilities.NONE, 330, 40, 65, 40, 80, 40, 65, 75, 50, 66, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.ZORUA, 5, false, false, false, "Tricky Fox Pokémon", Type.DARK, null, 0.7, 12.5, Abilities.ILLUSION, Abilities.NONE, Abilities.NONE, 330, 40, 65, 40, 80, 40, 65, 75, 50, 66, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.ZOROARK, 5, false, false, false, "Illusion Fox Pokémon", Type.DARK, null, 1.6, 81.1, Abilities.ILLUSION, Abilities.NONE, Abilities.NONE, 510, 60, 105, 60, 120, 60, 105, 45, 50, 179, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.ZOROARK, 5, false, false, false, "Illusion Fox Pokémon", Type.DARK, null, 1.6, 81.1, Abilities.ILLUSION, Abilities.NONE, Abilities.NONE, 510, 60, 105, 60, 120, 60, 105, 45, 50, 179, GrowthRate.MEDIUM_SLOW, 87.5, false),
@ -2236,25 +2236,25 @@ export function initSpecies() {
new PokemonSpecies(Species.MELTAN, 7, false, false, true, "Hex Nut Pokémon", Type.STEEL, null, 0.2, 8, Abilities.MAGNET_PULL, Abilities.NONE, Abilities.NONE, 300, 46, 65, 65, 55, 35, 34, 3, 0, 150, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.MELTAN, 7, false, false, true, "Hex Nut Pokémon", Type.STEEL, null, 0.2, 8, Abilities.MAGNET_PULL, Abilities.NONE, Abilities.NONE, 300, 46, 65, 65, 55, 35, 34, 3, 0, 150, GrowthRate.SLOW, null, false),
new PokemonSpecies(Species.MELMETAL, 7, false, false, true, "Hex Nut Pokémon", Type.STEEL, null, 2.5, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, GrowthRate.SLOW, null, false, true, new PokemonSpecies(Species.MELMETAL, 7, false, false, true, "Hex Nut Pokémon", Type.STEEL, null, 2.5, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, GrowthRate.SLOW, null, false, true,
new PokemonForm("Normal", "", Type.STEEL, null, 2.5, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, false, null, true), new PokemonForm("Normal", "", Type.STEEL, null, 2.5, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, null, 25, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 700, 170, 165, 165, 95, 75, 30, 3, 0, 300), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, null, 25, 800, Abilities.IRON_FIST, Abilities.IRON_FIST, Abilities.IRON_FIST, 700, 175, 165, 155, 85, 75, 45, 3, 0, 300),
), ),
new PokemonSpecies(Species.GROOKEY, 8, false, false, false, "Chimp Pokémon", Type.GRASS, null, 0.3, 5, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 310, 50, 65, 50, 40, 40, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.GROOKEY, 8, false, false, false, "Chimp Pokémon", Type.GRASS, null, 0.3, 5, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 310, 50, 65, 50, 40, 40, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.THWACKEY, 8, false, false, false, "Beat Pokémon", Type.GRASS, null, 0.7, 14, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 420, 70, 85, 70, 55, 60, 80, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.THWACKEY, 8, false, false, false, "Beat Pokémon", Type.GRASS, null, 0.7, 14, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 420, 70, 85, 70, 55, 60, 80, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.RILLABOOM, 8, false, false, false, "Drummer Pokémon", Type.GRASS, null, 2.1, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonSpecies(Species.RILLABOOM, 8, false, false, false, "Drummer Pokémon", Type.GRASS, null, 2.1, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true,
new PokemonForm("Normal", "", Type.GRASS, null, 2.1, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, false, null, true), new PokemonForm("Normal", "", Type.GRASS, null, 2.1, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, null, 28, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 630, 125, 150, 115, 75, 90, 75, 45, 50, 265), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, null, 28, 90, Abilities.GRASSY_SURGE, Abilities.GRASSY_SURGE, Abilities.GRASSY_SURGE, 630, 125, 150, 115, 65, 95, 80, 45, 50, 265),
), ),
new PokemonSpecies(Species.SCORBUNNY, 8, false, false, false, "Rabbit Pokémon", Type.FIRE, null, 0.3, 4.5, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 310, 50, 71, 40, 40, 40, 69, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.SCORBUNNY, 8, false, false, false, "Rabbit Pokémon", Type.FIRE, null, 0.3, 4.5, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 310, 50, 71, 40, 40, 40, 69, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.RABOOT, 8, false, false, false, "Rabbit Pokémon", Type.FIRE, null, 0.6, 9, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 420, 65, 86, 60, 55, 60, 94, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.RABOOT, 8, false, false, false, "Rabbit Pokémon", Type.FIRE, null, 0.6, 9, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 420, 65, 86, 60, 55, 60, 94, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.CINDERACE, 8, false, false, false, "Striker Pokémon", Type.FIRE, null, 1.4, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonSpecies(Species.CINDERACE, 8, false, false, false, "Striker Pokémon", Type.FIRE, null, 1.4, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true,
new PokemonForm("Normal", "", Type.FIRE, null, 1.4, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, false, null, true), new PokemonForm("Normal", "", Type.FIRE, null, 1.4, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, null, 27, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 630, 100, 145, 90, 75, 90, 130, 45, 50, 265), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, null, 27, 33, Abilities.LIBERO, Abilities.LIBERO, Abilities.LIBERO, 630, 90, 151, 85, 85, 85, 134, 45, 50, 265),
), ),
new PokemonSpecies(Species.SOBBLE, 8, false, false, false, "Water Lizard Pokémon", Type.WATER, null, 0.3, 4, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 310, 50, 40, 40, 70, 40, 70, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.SOBBLE, 8, false, false, false, "Water Lizard Pokémon", Type.WATER, null, 0.3, 4, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 310, 50, 40, 40, 70, 40, 70, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.DRIZZILE, 8, false, false, false, "Water Lizard Pokémon", Type.WATER, null, 0.7, 11.5, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 420, 65, 60, 55, 95, 55, 90, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.DRIZZILE, 8, false, false, false, "Water Lizard Pokémon", Type.WATER, null, 0.7, 11.5, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 420, 65, 60, 55, 95, 55, 90, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.INTELEON, 8, false, false, false, "Secret Agent Pokémon", Type.WATER, null, 1.9, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonSpecies(Species.INTELEON, 8, false, false, false, "Secret Agent Pokémon", Type.WATER, null, 1.9, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true,
new PokemonForm("Normal", "", Type.WATER, null, 1.9, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, false, null, true), new PokemonForm("Normal", "", Type.WATER, null, 1.9, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 40, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 630, 90, 100, 90, 150, 90, 110, 45, 50, 265), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 40, 45.2, Abilities.SNIPER, Abilities.SNIPER, Abilities.SNIPER, 630, 90, 90, 85, 150, 85, 130, 45, 50, 265),
), ),
new PokemonSpecies(Species.SKWOVET, 8, false, false, false, "Cheeky Pokémon", Type.NORMAL, null, 0.3, 2.5, Abilities.CHEEK_POUCH, Abilities.NONE, Abilities.GLUTTONY, 275, 70, 55, 55, 35, 35, 25, 255, 50, 55, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.SKWOVET, 8, false, false, false, "Cheeky Pokémon", Type.NORMAL, null, 0.3, 2.5, Abilities.CHEEK_POUCH, Abilities.NONE, Abilities.GLUTTONY, 275, 70, 55, 55, 35, 35, 25, 255, 50, 55, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.GREEDENT, 8, false, false, false, "Greedy Pokémon", Type.NORMAL, null, 0.6, 6, Abilities.CHEEK_POUCH, Abilities.NONE, Abilities.GLUTTONY, 460, 120, 95, 95, 55, 75, 20, 90, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.GREEDENT, 8, false, false, false, "Greedy Pokémon", Type.NORMAL, null, 0.6, 6, Abilities.CHEEK_POUCH, Abilities.NONE, Abilities.GLUTTONY, 460, 120, 95, 95, 55, 75, 20, 90, 50, 161, GrowthRate.MEDIUM_FAST, 50, false),
@ -2262,13 +2262,13 @@ export function initSpecies() {
new PokemonSpecies(Species.CORVISQUIRE, 8, false, false, false, "Raven Pokémon", Type.FLYING, null, 0.8, 16, Abilities.KEEN_EYE, Abilities.UNNERVE, Abilities.BIG_PECKS, 365, 68, 67, 55, 43, 55, 77, 120, 50, 128, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.CORVISQUIRE, 8, false, false, false, "Raven Pokémon", Type.FLYING, null, 0.8, 16, Abilities.KEEN_EYE, Abilities.UNNERVE, Abilities.BIG_PECKS, 365, 68, 67, 55, 43, 55, 77, 120, 50, 128, GrowthRate.MEDIUM_SLOW, 50, false),
new PokemonSpecies(Species.CORVIKNIGHT, 8, false, false, false, "Raven Pokémon", Type.FLYING, Type.STEEL, 2.2, 75, Abilities.PRESSURE, Abilities.UNNERVE, Abilities.MIRROR_ARMOR, 495, 98, 87, 105, 53, 85, 67, 45, 50, 248, GrowthRate.MEDIUM_SLOW, 50, false, true, new PokemonSpecies(Species.CORVIKNIGHT, 8, false, false, false, "Raven Pokémon", Type.FLYING, Type.STEEL, 2.2, 75, Abilities.PRESSURE, Abilities.UNNERVE, Abilities.MIRROR_ARMOR, 495, 98, 87, 105, 53, 85, 67, 45, 50, 248, GrowthRate.MEDIUM_SLOW, 50, false, true,
new PokemonForm("Normal", "", Type.FLYING, Type.STEEL, 2.2, 75, Abilities.PRESSURE, Abilities.UNNERVE, Abilities.MIRROR_ARMOR, 495, 98, 87, 105, 53, 85, 67, 45, 50, 248, false, null, true), new PokemonForm("Normal", "", Type.FLYING, Type.STEEL, 2.2, 75, Abilities.PRESSURE, Abilities.UNNERVE, Abilities.MIRROR_ARMOR, 495, 98, 87, 105, 53, 85, 67, 45, 50, 248, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FLYING, Type.STEEL, 14, 75, Abilities.PRESSURE, Abilities.UNNERVE, Abilities.MIRROR_ARMOR, 595, 125, 100, 135, 60, 95, 80, 45, 50, 248), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FLYING, Type.STEEL, 14, 75, Abilities.MIRROR_ARMOR, Abilities.MIRROR_ARMOR, Abilities.MIRROR_ARMOR, 595, 128, 102, 140, 53, 95, 77, 45, 50, 248),
), ),
new PokemonSpecies(Species.BLIPBUG, 8, false, false, false, "Larva Pokémon", Type.BUG, null, 0.4, 8, Abilities.SWARM, Abilities.COMPOUND_EYES, Abilities.TELEPATHY, 180, 25, 20, 20, 25, 45, 45, 255, 50, 36, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.BLIPBUG, 8, false, false, false, "Larva Pokémon", Type.BUG, null, 0.4, 8, Abilities.SWARM, Abilities.COMPOUND_EYES, Abilities.TELEPATHY, 180, 25, 20, 20, 25, 45, 45, 255, 50, 36, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.DOTTLER, 8, false, false, false, "Radome Pokémon", Type.BUG, Type.PSYCHIC, 0.4, 19.5, Abilities.SWARM, Abilities.COMPOUND_EYES, Abilities.TELEPATHY, 335, 50, 35, 80, 50, 90, 30, 120, 50, 117, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.DOTTLER, 8, false, false, false, "Radome Pokémon", Type.BUG, Type.PSYCHIC, 0.4, 19.5, Abilities.SWARM, Abilities.COMPOUND_EYES, Abilities.TELEPATHY, 335, 50, 35, 80, 50, 90, 30, 120, 50, 117, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.ORBEETLE, 8, false, false, false, "Seven Spot Pokémon", Type.BUG, Type.PSYCHIC, 0.4, 40.8, Abilities.SWARM, Abilities.FRISK, Abilities.TELEPATHY, 505, 60, 45, 110, 80, 120, 90, 45, 50, 253, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonSpecies(Species.ORBEETLE, 8, false, false, false, "Seven Spot Pokémon", Type.BUG, Type.PSYCHIC, 0.4, 40.8, Abilities.SWARM, Abilities.FRISK, Abilities.TELEPATHY, 505, 60, 45, 110, 80, 120, 90, 45, 50, 253, GrowthRate.MEDIUM_FAST, 50, false, true,
new PokemonForm("Normal", "", Type.BUG, Type.PSYCHIC, 0.4, 40.8, Abilities.SWARM, Abilities.FRISK, Abilities.TELEPATHY, 505, 60, 45, 110, 80, 120, 90, 45, 50, 253, false, null, true), new PokemonForm("Normal", "", Type.BUG, Type.PSYCHIC, 0.4, 40.8, Abilities.SWARM, Abilities.FRISK, Abilities.TELEPATHY, 505, 60, 45, 110, 80, 120, 90, 45, 50, 253, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.PSYCHIC, 14, 40.8, Abilities.SWARM, Abilities.FRISK, Abilities.TELEPATHY, 605, 75, 50, 140, 90, 150, 100, 45, 50, 253), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.PSYCHIC, 14, 40.8, Abilities.TRACE, Abilities.TRACE, Abilities.TRACE, 605, 90, 45, 130, 110, 140, 90, 45, 50, 253),
), ),
new PokemonSpecies(Species.NICKIT, 8, false, false, false, "Fox Pokémon", Type.DARK, null, 0.6, 8.9, Abilities.RUN_AWAY, Abilities.UNBURDEN, Abilities.STAKEOUT, 245, 40, 28, 28, 47, 52, 50, 255, 50, 49, GrowthRate.FAST, 50, false), new PokemonSpecies(Species.NICKIT, 8, false, false, false, "Fox Pokémon", Type.DARK, null, 0.6, 8.9, Abilities.RUN_AWAY, Abilities.UNBURDEN, Abilities.STAKEOUT, 245, 40, 28, 28, 47, 52, 50, 255, 50, 49, GrowthRate.FAST, 50, false),
new PokemonSpecies(Species.THIEVUL, 8, false, false, false, "Fox Pokémon", Type.DARK, null, 1.2, 19.9, Abilities.RUN_AWAY, Abilities.UNBURDEN, Abilities.STAKEOUT, 455, 70, 58, 58, 87, 92, 90, 127, 50, 159, GrowthRate.FAST, 50, false), new PokemonSpecies(Species.THIEVUL, 8, false, false, false, "Fox Pokémon", Type.DARK, null, 1.2, 19.9, Abilities.RUN_AWAY, Abilities.UNBURDEN, Abilities.STAKEOUT, 455, 70, 58, 58, 87, 92, 90, 127, 50, 159, GrowthRate.FAST, 50, false),
@ -2279,7 +2279,7 @@ export function initSpecies() {
new PokemonSpecies(Species.CHEWTLE, 8, false, false, false, "Snapping Pokémon", Type.WATER, null, 0.3, 8.5, Abilities.STRONG_JAW, Abilities.SHELL_ARMOR, Abilities.SWIFT_SWIM, 284, 50, 64, 50, 38, 38, 44, 255, 50, 57, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.CHEWTLE, 8, false, false, false, "Snapping Pokémon", Type.WATER, null, 0.3, 8.5, Abilities.STRONG_JAW, Abilities.SHELL_ARMOR, Abilities.SWIFT_SWIM, 284, 50, 64, 50, 38, 38, 44, 255, 50, 57, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.DREDNAW, 8, false, false, false, "Bite Pokémon", Type.WATER, Type.ROCK, 1, 115.5, Abilities.STRONG_JAW, Abilities.SHELL_ARMOR, Abilities.SWIFT_SWIM, 485, 90, 115, 90, 48, 68, 74, 75, 50, 170, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonSpecies(Species.DREDNAW, 8, false, false, false, "Bite Pokémon", Type.WATER, Type.ROCK, 1, 115.5, Abilities.STRONG_JAW, Abilities.SHELL_ARMOR, Abilities.SWIFT_SWIM, 485, 90, 115, 90, 48, 68, 74, 75, 50, 170, GrowthRate.MEDIUM_FAST, 50, false, true,
new PokemonForm("Normal", "", Type.WATER, Type.ROCK, 1, 115.5, Abilities.STRONG_JAW, Abilities.SHELL_ARMOR, Abilities.SWIFT_SWIM, 485, 90, 115, 90, 48, 68, 74, 75, 50, 170, false, null, true), new PokemonForm("Normal", "", Type.WATER, Type.ROCK, 1, 115.5, Abilities.STRONG_JAW, Abilities.SHELL_ARMOR, Abilities.SWIFT_SWIM, 485, 90, 115, 90, 48, 68, 74, 75, 50, 170, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.ROCK, 24, 115.5, Abilities.STRONG_JAW, Abilities.SHELL_ARMOR, Abilities.SWIFT_SWIM, 585, 115, 150, 110, 55, 85, 70, 75, 50, 170), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.ROCK, 24, 115.5, Abilities.STRONG_JAW, Abilities.STRONG_JAW, Abilities.STRONG_JAW, 585, 115, 145, 115, 43, 83, 84, 75, 50, 170),
), ),
new PokemonSpecies(Species.YAMPER, 8, false, false, false, "Puppy Pokémon", Type.ELECTRIC, null, 0.3, 13.5, Abilities.BALL_FETCH, Abilities.NONE, Abilities.RATTLED, 270, 59, 45, 50, 40, 50, 26, 255, 50, 54, GrowthRate.FAST, 50, false), new PokemonSpecies(Species.YAMPER, 8, false, false, false, "Puppy Pokémon", Type.ELECTRIC, null, 0.3, 13.5, Abilities.BALL_FETCH, Abilities.NONE, Abilities.RATTLED, 270, 59, 45, 50, 40, 50, 26, 255, 50, 54, GrowthRate.FAST, 50, false),
new PokemonSpecies(Species.BOLTUND, 8, false, false, false, "Dog Pokémon", Type.ELECTRIC, null, 1, 34, Abilities.STRONG_JAW, Abilities.NONE, Abilities.COMPETITIVE, 490, 69, 90, 60, 90, 60, 121, 45, 50, 172, GrowthRate.FAST, 50, false), new PokemonSpecies(Species.BOLTUND, 8, false, false, false, "Dog Pokémon", Type.ELECTRIC, null, 1, 34, Abilities.STRONG_JAW, Abilities.NONE, Abilities.COMPETITIVE, 490, 69, 90, 60, 90, 60, 121, 45, 50, 172, GrowthRate.FAST, 50, false),
@ -2287,21 +2287,21 @@ export function initSpecies() {
new PokemonSpecies(Species.CARKOL, 8, false, false, false, "Coal Pokémon", Type.ROCK, Type.FIRE, 1.1, 78, Abilities.STEAM_ENGINE, Abilities.FLAME_BODY, Abilities.FLASH_FIRE, 410, 80, 60, 90, 60, 70, 50, 120, 50, 144, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.CARKOL, 8, false, false, false, "Coal Pokémon", Type.ROCK, Type.FIRE, 1.1, 78, Abilities.STEAM_ENGINE, Abilities.FLAME_BODY, Abilities.FLASH_FIRE, 410, 80, 60, 90, 60, 70, 50, 120, 50, 144, GrowthRate.MEDIUM_SLOW, 50, false),
new PokemonSpecies(Species.COALOSSAL, 8, false, false, false, "Coal Pokémon", Type.ROCK, Type.FIRE, 2.8, 310.5, Abilities.STEAM_ENGINE, Abilities.FLAME_BODY, Abilities.FLASH_FIRE, 510, 110, 80, 120, 80, 90, 30, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false, true, new PokemonSpecies(Species.COALOSSAL, 8, false, false, false, "Coal Pokémon", Type.ROCK, Type.FIRE, 2.8, 310.5, Abilities.STEAM_ENGINE, Abilities.FLAME_BODY, Abilities.FLASH_FIRE, 510, 110, 80, 120, 80, 90, 30, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false, true,
new PokemonForm("Normal", "", Type.ROCK, Type.FIRE, 2.8, 310.5, Abilities.STEAM_ENGINE, Abilities.FLAME_BODY, Abilities.FLASH_FIRE, 510, 110, 80, 120, 80, 90, 30, 45, 50, 255, false, null, true), new PokemonForm("Normal", "", Type.ROCK, Type.FIRE, 2.8, 310.5, Abilities.STEAM_ENGINE, Abilities.FLAME_BODY, Abilities.FLASH_FIRE, 510, 110, 80, 120, 80, 90, 30, 45, 50, 255, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ROCK, Type.FIRE, 42, 310.5, Abilities.STEAM_ENGINE, Abilities.FLAME_BODY, Abilities.FLASH_FIRE, 610, 140, 95, 150, 95, 105, 25, 45, 50, 255), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ROCK, Type.FIRE, 42, 310.5, Abilities.STEAM_ENGINE, Abilities.STEAM_ENGINE, Abilities.STEAM_ENGINE, 610, 140, 95, 130, 95, 110, 40, 45, 50, 255),
), ),
new PokemonSpecies(Species.APPLIN, 8, false, false, false, "Apple Core Pokémon", Type.GRASS, Type.DRAGON, 0.2, 0.5, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.BULLETPROOF, 260, 40, 40, 80, 40, 40, 20, 255, 50, 52, GrowthRate.ERRATIC, 50, false), new PokemonSpecies(Species.APPLIN, 8, false, false, false, "Apple Core Pokémon", Type.GRASS, Type.DRAGON, 0.2, 0.5, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.BULLETPROOF, 260, 40, 40, 80, 40, 40, 20, 255, 50, 52, GrowthRate.ERRATIC, 50, false),
new PokemonSpecies(Species.FLAPPLE, 8, false, false, false, "Apple Wing Pokémon", Type.GRASS, Type.DRAGON, 0.3, 1, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.HUSTLE, 485, 70, 110, 80, 95, 60, 70, 45, 50, 170, GrowthRate.ERRATIC, 50, false, true, new PokemonSpecies(Species.FLAPPLE, 8, false, false, false, "Apple Wing Pokémon", Type.GRASS, Type.DRAGON, 0.3, 1, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.HUSTLE, 485, 70, 110, 80, 95, 60, 70, 45, 50, 170, GrowthRate.ERRATIC, 50, false, true,
new PokemonForm("Normal", "", Type.GRASS, Type.DRAGON, 0.3, 1, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.HUSTLE, 485, 70, 110, 80, 95, 60, 70, 45, 50, 170, false, null, true), new PokemonForm("Normal", "", Type.GRASS, Type.DRAGON, 0.3, 1, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.HUSTLE, 485, 70, 110, 80, 95, 60, 70, 45, 50, 170, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.DRAGON, 24, 1, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.HUSTLE, 585, 90, 140, 90, 120, 75, 70, 45, 50, 170), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.DRAGON, 24, 1, Abilities.HUSTLE, Abilities.HUSTLE, Abilities.HUSTLE, 585, 90, 130, 100, 85, 80, 100, 45, 50, 170),
), ),
new PokemonSpecies(Species.APPLETUN, 8, false, false, false, "Apple Nectar Pokémon", Type.GRASS, Type.DRAGON, 0.4, 13, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.THICK_FAT, 485, 110, 85, 80, 100, 80, 30, 45, 50, 170, GrowthRate.ERRATIC, 50, false, true, new PokemonSpecies(Species.APPLETUN, 8, false, false, false, "Apple Nectar Pokémon", Type.GRASS, Type.DRAGON, 0.4, 13, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.THICK_FAT, 485, 110, 85, 80, 100, 80, 30, 45, 50, 170, GrowthRate.ERRATIC, 50, false, true,
new PokemonForm("Normal", "", Type.GRASS, Type.DRAGON, 0.4, 13, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.THICK_FAT, 485, 110, 85, 80, 100, 80, 30, 45, 50, 170, false, null, true), new PokemonForm("Normal", "", Type.GRASS, Type.DRAGON, 0.4, 13, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.THICK_FAT, 485, 110, 85, 80, 100, 80, 30, 45, 50, 170, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.DRAGON, 24, 13, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.THICK_FAT, 585, 140, 95, 95, 135, 95, 25, 45, 50, 170), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.DRAGON, 24, 13, Abilities.THICK_FAT, Abilities.THICK_FAT, Abilities.THICK_FAT, 585, 130, 75, 115, 125, 115, 25, 45, 50, 170),
), ),
new PokemonSpecies(Species.SILICOBRA, 8, false, false, false, "Sand Snake Pokémon", Type.GROUND, null, 2.2, 7.6, Abilities.SAND_SPIT, Abilities.SHED_SKIN, Abilities.SAND_VEIL, 315, 52, 57, 75, 35, 50, 46, 255, 50, 63, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.SILICOBRA, 8, false, false, false, "Sand Snake Pokémon", Type.GROUND, null, 2.2, 7.6, Abilities.SAND_SPIT, Abilities.SHED_SKIN, Abilities.SAND_VEIL, 315, 52, 57, 75, 35, 50, 46, 255, 50, 63, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.SANDACONDA, 8, false, false, false, "Sand Snake Pokémon", Type.GROUND, null, 3.8, 65.5, Abilities.SAND_SPIT, Abilities.SHED_SKIN, Abilities.SAND_VEIL, 510, 72, 107, 125, 65, 70, 71, 120, 50, 179, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonSpecies(Species.SANDACONDA, 8, false, false, false, "Sand Snake Pokémon", Type.GROUND, null, 3.8, 65.5, Abilities.SAND_SPIT, Abilities.SHED_SKIN, Abilities.SAND_VEIL, 510, 72, 107, 125, 65, 70, 71, 120, 50, 179, GrowthRate.MEDIUM_FAST, 50, false, true,
new PokemonForm("Normal", "", Type.GROUND, null, 3.8, 65.5, Abilities.SAND_SPIT, Abilities.SHED_SKIN, Abilities.SAND_VEIL, 510, 72, 107, 125, 65, 70, 71, 120, 50, 179, false, null, true), new PokemonForm("Normal", "", Type.GROUND, null, 3.8, 65.5, Abilities.SAND_SPIT, Abilities.SHED_SKIN, Abilities.SAND_VEIL, 510, 72, 107, 125, 65, 70, 71, 120, 50, 179, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GROUND, null, 22, 65.5, Abilities.SAND_SPIT, Abilities.SHED_SKIN, Abilities.SAND_VEIL, 610, 90, 135, 150, 75, 80, 80, 120, 50, 179), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GROUND, null, 22, 65.5, Abilities.SAND_SPIT, Abilities.SAND_SPIT, Abilities.SAND_SPIT, 610, 117, 137, 140, 55, 80, 81, 120, 50, 179),
), ),
new PokemonSpecies(Species.CRAMORANT, 8, false, false, false, "Gulp Pokémon", Type.FLYING, Type.WATER, 0.8, 18, Abilities.GULP_MISSILE, Abilities.NONE, Abilities.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, false, new PokemonSpecies(Species.CRAMORANT, 8, false, false, false, "Gulp Pokémon", Type.FLYING, Type.WATER, 0.8, 18, Abilities.GULP_MISSILE, Abilities.NONE, Abilities.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, false,
new PokemonForm("Normal", "", Type.FLYING, Type.WATER, 0.8, 18, Abilities.GULP_MISSILE, Abilities.NONE, Abilities.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166, false, null, true), new PokemonForm("Normal", "", Type.FLYING, Type.WATER, 0.8, 18, Abilities.GULP_MISSILE, Abilities.NONE, Abilities.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166, false, null, true),
@ -2314,12 +2314,12 @@ export function initSpecies() {
new PokemonSpecies(Species.TOXTRICITY, 8, false, false, false, "Punk Pokémon", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.PLUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, GrowthRate.MEDIUM_SLOW, 50, false, true, new PokemonSpecies(Species.TOXTRICITY, 8, false, false, false, "Punk Pokémon", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.PLUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, GrowthRate.MEDIUM_SLOW, 50, false, true,
new PokemonForm("Amped Form", "amped", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.PLUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "", true), new PokemonForm("Amped Form", "amped", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.PLUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "", true),
new PokemonForm("Low-Key Form", "lowkey", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.MINUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "lowkey", true), new PokemonForm("Low-Key Form", "lowkey", Type.ELECTRIC, Type.POISON, 1.6, 40, Abilities.PUNK_ROCK, Abilities.MINUS, Abilities.TECHNICIAN, 502, 75, 98, 70, 114, 70, 75, 45, 50, 176, false, "lowkey", true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, Type.POISON, 24, 40, Abilities.PUNK_ROCK, Abilities.MINUS, Abilities.TECHNICIAN, 602, 95, 118, 80, 144, 80, 85, 45, 50, 176), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, Type.POISON, 24, 40, Abilities.PUNK_ROCK, Abilities.PUNK_ROCK, Abilities.PUNK_ROCK, 602, 114, 98, 82, 144, 82, 82, 45, 50, 176),
), ),
new PokemonSpecies(Species.SIZZLIPEDE, 8, false, false, false, "Radiator Pokémon", Type.FIRE, Type.BUG, 0.7, 1, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 305, 50, 65, 45, 50, 50, 45, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.SIZZLIPEDE, 8, false, false, false, "Radiator Pokémon", Type.FIRE, Type.BUG, 0.7, 1, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 305, 50, 65, 45, 50, 50, 45, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.CENTISKORCH, 8, false, false, false, "Radiator Pokémon", Type.FIRE, Type.BUG, 3, 120, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 525, 100, 115, 65, 90, 90, 65, 75, 50, 184, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonSpecies(Species.CENTISKORCH, 8, false, false, false, "Radiator Pokémon", Type.FIRE, Type.BUG, 3, 120, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 525, 100, 115, 65, 90, 90, 65, 75, 50, 184, GrowthRate.MEDIUM_FAST, 50, false, true,
new PokemonForm("Normal", "", Type.FIRE, Type.BUG, 3, 120, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 525, 100, 115, 65, 90, 90, 65, 75, 50, 184, false, null, true), new PokemonForm("Normal", "", Type.FIRE, Type.BUG, 3, 120, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 525, 100, 115, 65, 90, 90, 65, 75, 50, 184, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, Type.BUG, 75, 120, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 625, 125, 145, 75, 105, 105, 70, 75, 50, 184), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, Type.BUG, 75, 120, Abilities.FLASH_FIRE, Abilities.FLASH_FIRE, Abilities.FLASH_FIRE, 625, 140, 145, 75, 90, 100, 75, 75, 50, 184),
), ),
new PokemonSpecies(Species.CLOBBOPUS, 8, false, false, false, "Tantrum Pokémon", Type.FIGHTING, null, 0.6, 4, Abilities.LIMBER, Abilities.NONE, Abilities.TECHNICIAN, 310, 50, 68, 60, 50, 50, 32, 180, 50, 62, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.CLOBBOPUS, 8, false, false, false, "Tantrum Pokémon", Type.FIGHTING, null, 0.6, 4, Abilities.LIMBER, Abilities.NONE, Abilities.TECHNICIAN, 310, 50, 68, 60, 50, 50, 32, 180, 50, 62, GrowthRate.MEDIUM_SLOW, 50, false),
new PokemonSpecies(Species.GRAPPLOCT, 8, false, false, false, "Jujitsu Pokémon", Type.FIGHTING, null, 1.6, 39, Abilities.LIMBER, Abilities.NONE, Abilities.TECHNICIAN, 480, 80, 118, 90, 70, 80, 42, 45, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.GRAPPLOCT, 8, false, false, false, "Jujitsu Pokémon", Type.FIGHTING, null, 1.6, 39, Abilities.LIMBER, Abilities.NONE, Abilities.TECHNICIAN, 480, 80, 118, 90, 70, 80, 42, 45, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false),
@ -2335,13 +2335,13 @@ export function initSpecies() {
new PokemonSpecies(Species.HATTREM, 8, false, false, false, "Serene Pokémon", Type.PSYCHIC, null, 0.6, 4.8, Abilities.HEALER, Abilities.ANTICIPATION, Abilities.MAGIC_BOUNCE, 370, 57, 40, 65, 86, 73, 49, 120, 50, 130, GrowthRate.SLOW, 0, false), new PokemonSpecies(Species.HATTREM, 8, false, false, false, "Serene Pokémon", Type.PSYCHIC, null, 0.6, 4.8, Abilities.HEALER, Abilities.ANTICIPATION, Abilities.MAGIC_BOUNCE, 370, 57, 40, 65, 86, 73, 49, 120, 50, 130, GrowthRate.SLOW, 0, false),
new PokemonSpecies(Species.HATTERENE, 8, false, false, false, "Silent Pokémon", Type.PSYCHIC, Type.FAIRY, 2.1, 5.1, Abilities.HEALER, Abilities.ANTICIPATION, Abilities.MAGIC_BOUNCE, 510, 57, 90, 95, 136, 103, 29, 45, 50, 255, GrowthRate.SLOW, 0, false, true, new PokemonSpecies(Species.HATTERENE, 8, false, false, false, "Silent Pokémon", Type.PSYCHIC, Type.FAIRY, 2.1, 5.1, Abilities.HEALER, Abilities.ANTICIPATION, Abilities.MAGIC_BOUNCE, 510, 57, 90, 95, 136, 103, 29, 45, 50, 255, GrowthRate.SLOW, 0, false, true,
new PokemonForm("Normal", "", Type.PSYCHIC, Type.FAIRY, 2.1, 5.1, Abilities.HEALER, Abilities.ANTICIPATION, Abilities.MAGIC_BOUNCE, 510, 57, 90, 95, 136, 103, 29, 45, 50, 255, false, null, true), new PokemonForm("Normal", "", Type.PSYCHIC, Type.FAIRY, 2.1, 5.1, Abilities.HEALER, Abilities.ANTICIPATION, Abilities.MAGIC_BOUNCE, 510, 57, 90, 95, 136, 103, 29, 45, 50, 255, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.PSYCHIC, Type.FAIRY, 26, 5.1, Abilities.HEALER, Abilities.ANTICIPATION, Abilities.MAGIC_BOUNCE, 610, 70, 105, 110, 160, 125, 40, 45, 50, 255), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.PSYCHIC, Type.FAIRY, 26, 5.1, Abilities.MAGIC_BOUNCE, Abilities.MAGIC_BOUNCE, Abilities.MAGIC_BOUNCE, 610, 97, 90, 105, 146, 122, 50, 45, 50, 255),
), ),
new PokemonSpecies(Species.IMPIDIMP, 8, false, false, false, "Wily Pokémon", Type.DARK, Type.FAIRY, 0.4, 5.5, Abilities.PRANKSTER, Abilities.FRISK, Abilities.PICKPOCKET, 265, 45, 45, 30, 55, 40, 50, 255, 50, 53, GrowthRate.MEDIUM_FAST, 100, false), new PokemonSpecies(Species.IMPIDIMP, 8, false, false, false, "Wily Pokémon", Type.DARK, Type.FAIRY, 0.4, 5.5, Abilities.PRANKSTER, Abilities.FRISK, Abilities.PICKPOCKET, 265, 45, 45, 30, 55, 40, 50, 255, 50, 53, GrowthRate.MEDIUM_FAST, 100, false),
new PokemonSpecies(Species.MORGREM, 8, false, false, false, "Devious Pokémon", Type.DARK, Type.FAIRY, 0.8, 12.5, Abilities.PRANKSTER, Abilities.FRISK, Abilities.PICKPOCKET, 370, 65, 60, 45, 75, 55, 70, 120, 50, 130, GrowthRate.MEDIUM_FAST, 100, false), new PokemonSpecies(Species.MORGREM, 8, false, false, false, "Devious Pokémon", Type.DARK, Type.FAIRY, 0.8, 12.5, Abilities.PRANKSTER, Abilities.FRISK, Abilities.PICKPOCKET, 370, 65, 60, 45, 75, 55, 70, 120, 50, 130, GrowthRate.MEDIUM_FAST, 100, false),
new PokemonSpecies(Species.GRIMMSNARL, 8, false, false, false, "Bulk Up Pokémon", Type.DARK, Type.FAIRY, 1.5, 61, Abilities.PRANKSTER, Abilities.FRISK, Abilities.PICKPOCKET, 510, 95, 120, 65, 95, 75, 60, 45, 50, 255, GrowthRate.MEDIUM_FAST, 100, false, true, new PokemonSpecies(Species.GRIMMSNARL, 8, false, false, false, "Bulk Up Pokémon", Type.DARK, Type.FAIRY, 1.5, 61, Abilities.PRANKSTER, Abilities.FRISK, Abilities.PICKPOCKET, 510, 95, 120, 65, 95, 75, 60, 45, 50, 255, GrowthRate.MEDIUM_FAST, 100, false, true,
new PokemonForm("Normal", "", Type.DARK, Type.FAIRY, 1.5, 61, Abilities.PRANKSTER, Abilities.FRISK, Abilities.PICKPOCKET, 510, 95, 120, 65, 95, 75, 60, 45, 50, 255, false, null, true), new PokemonForm("Normal", "", Type.DARK, Type.FAIRY, 1.5, 61, Abilities.PRANKSTER, Abilities.FRISK, Abilities.PICKPOCKET, 510, 95, 120, 65, 95, 75, 60, 45, 50, 255, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.DARK, Type.FAIRY, 32, 61, Abilities.PRANKSTER, Abilities.FRISK, Abilities.PICKPOCKET, 610, 120, 155, 75, 110, 85, 65, 45, 50, 255), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.DARK, Type.FAIRY, 32, 61, Abilities.PRANKSTER, Abilities.PRANKSTER, Abilities.PRANKSTER, 610, 135, 138, 77, 110, 85, 65, 45, 50, 255),
), ),
new PokemonSpecies(Species.OBSTAGOON, 8, false, false, false, "Blocking Pokémon", Type.DARK, Type.NORMAL, 1.6, 46, Abilities.RECKLESS, Abilities.GUTS, Abilities.DEFIANT, 520, 93, 90, 101, 60, 81, 95, 45, 50, 260, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.OBSTAGOON, 8, false, false, false, "Blocking Pokémon", Type.DARK, Type.NORMAL, 1.6, 46, Abilities.RECKLESS, Abilities.GUTS, Abilities.DEFIANT, 520, 93, 90, 101, 60, 81, 95, 45, 50, 260, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.PERRSERKER, 8, false, false, false, "Viking Pokémon", Type.STEEL, null, 0.8, 28, Abilities.BATTLE_ARMOR, Abilities.TOUGH_CLAWS, Abilities.STEELY_SPIRIT, 440, 70, 110, 100, 50, 60, 50, 90, 50, 154, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.PERRSERKER, 8, false, false, false, "Viking Pokémon", Type.STEEL, null, 0.8, 28, Abilities.BATTLE_ARMOR, Abilities.TOUGH_CLAWS, Abilities.STEELY_SPIRIT, 440, 70, 110, 100, 50, 60, 50, 90, 50, 154, GrowthRate.MEDIUM_FAST, 50, false),
@ -2360,7 +2360,7 @@ export function initSpecies() {
new PokemonForm("Ruby Swirl", "ruby-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), new PokemonForm("Ruby Swirl", "ruby-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true),
new PokemonForm("Caramel Swirl", "caramel-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), new PokemonForm("Caramel Swirl", "caramel-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true),
new PokemonForm("Rainbow Swirl", "rainbow-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), new PokemonForm("Rainbow Swirl", "rainbow-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FAIRY, null, 30, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 595, 85, 70, 85, 140, 150, 65, 100, 50, 173), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FAIRY, null, 30, 0.5, Abilities.MISTY_SURGE, Abilities.MISTY_SURGE, Abilities.MISTY_SURGE, 595, 135, 60, 75, 130, 131, 64, 100, 50, 173),
), ),
new PokemonSpecies(Species.FALINKS, 8, false, false, false, "Formation Pokémon", Type.FIGHTING, null, 3, 62, Abilities.BATTLE_ARMOR, Abilities.NONE, Abilities.DEFIANT, 470, 65, 100, 100, 70, 60, 75, 45, 50, 165, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.FALINKS, 8, false, false, false, "Formation Pokémon", Type.FIGHTING, null, 3, 62, Abilities.BATTLE_ARMOR, Abilities.NONE, Abilities.DEFIANT, 470, 65, 100, 100, 70, 60, 75, 45, 50, 165, GrowthRate.MEDIUM_FAST, null, false),
new PokemonSpecies(Species.PINCURCHIN, 8, false, false, false, "Sea Urchin Pokémon", Type.ELECTRIC, null, 0.3, 1, Abilities.LIGHTNING_ROD, Abilities.NONE, Abilities.ELECTRIC_SURGE, 435, 48, 101, 95, 91, 85, 15, 75, 50, 152, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.PINCURCHIN, 8, false, false, false, "Sea Urchin Pokémon", Type.ELECTRIC, null, 0.3, 1, Abilities.LIGHTNING_ROD, Abilities.NONE, Abilities.ELECTRIC_SURGE, 435, 48, 101, 95, 91, 85, 15, 75, 50, 152, GrowthRate.MEDIUM_FAST, 50, false),
@ -2382,7 +2382,7 @@ export function initSpecies() {
new PokemonSpecies(Species.CUFANT, 8, false, false, false, "Copperderm Pokémon", Type.STEEL, null, 1.2, 100, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 330, 72, 80, 49, 40, 49, 40, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.CUFANT, 8, false, false, false, "Copperderm Pokémon", Type.STEEL, null, 1.2, 100, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 330, 72, 80, 49, 40, 49, 40, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.COPPERAJAH, 8, false, false, false, "Copperderm Pokémon", Type.STEEL, null, 3, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonSpecies(Species.COPPERAJAH, 8, false, false, false, "Copperderm Pokémon", Type.STEEL, null, 3, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, GrowthRate.MEDIUM_FAST, 50, false, true,
new PokemonForm("Normal", "", Type.STEEL, null, 3, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, false, null, true), new PokemonForm("Normal", "", Type.STEEL, null, 3, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, null, 23, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 600, 150, 160, 80, 90, 80, 40, 90, 50, 175), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, Type.GROUND, 23, 650, Abilities.MOLD_BREAKER, Abilities.MOLD_BREAKER, Abilities.MOLD_BREAKER, 600, 167, 155, 89, 80, 89, 20, 90, 50, 175),
), ),
new PokemonSpecies(Species.DRACOZOLT, 8, false, false, false, "Fossil Pokémon", Type.ELECTRIC, Type.DRAGON, 1.8, 190, Abilities.VOLT_ABSORB, Abilities.HUSTLE, Abilities.SAND_RUSH, 505, 90, 100, 90, 80, 70, 75, 45, 50, 177, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.DRACOZOLT, 8, false, false, false, "Fossil Pokémon", Type.ELECTRIC, Type.DRAGON, 1.8, 190, Abilities.VOLT_ABSORB, Abilities.HUSTLE, Abilities.SAND_RUSH, 505, 90, 100, 90, 80, 70, 75, 45, 50, 177, GrowthRate.SLOW, null, false),
new PokemonSpecies(Species.ARCTOZOLT, 8, false, false, false, "Fossil Pokémon", Type.ELECTRIC, Type.ICE, 2.3, 150, Abilities.VOLT_ABSORB, Abilities.STATIC, Abilities.SLUSH_RUSH, 505, 90, 100, 90, 90, 80, 55, 45, 50, 177, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.ARCTOZOLT, 8, false, false, false, "Fossil Pokémon", Type.ELECTRIC, Type.ICE, 2.3, 150, Abilities.VOLT_ABSORB, Abilities.STATIC, Abilities.SLUSH_RUSH, 505, 90, 100, 90, 90, 80, 55, 45, 50, 177, GrowthRate.SLOW, null, false),
@ -2390,7 +2390,7 @@ export function initSpecies() {
new PokemonSpecies(Species.ARCTOVISH, 8, false, false, false, "Fossil Pokémon", Type.WATER, Type.ICE, 2, 175, Abilities.WATER_ABSORB, Abilities.ICE_BODY, Abilities.SLUSH_RUSH, 505, 90, 90, 100, 80, 90, 55, 45, 50, 177, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.ARCTOVISH, 8, false, false, false, "Fossil Pokémon", Type.WATER, Type.ICE, 2, 175, Abilities.WATER_ABSORB, Abilities.ICE_BODY, Abilities.SLUSH_RUSH, 505, 90, 90, 100, 80, 90, 55, 45, 50, 177, GrowthRate.SLOW, null, false),
new PokemonSpecies(Species.DURALUDON, 8, false, false, false, "Alloy Pokémon", Type.STEEL, Type.DRAGON, 1.8, 40, Abilities.LIGHT_METAL, Abilities.HEAVY_METAL, Abilities.STALWART, 535, 70, 95, 115, 120, 50, 85, 45, 50, 187, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonSpecies(Species.DURALUDON, 8, false, false, false, "Alloy Pokémon", Type.STEEL, Type.DRAGON, 1.8, 40, Abilities.LIGHT_METAL, Abilities.HEAVY_METAL, Abilities.STALWART, 535, 70, 95, 115, 120, 50, 85, 45, 50, 187, GrowthRate.MEDIUM_FAST, 50, false, true,
new PokemonForm("Normal", "", Type.STEEL, Type.DRAGON, 1.8, 40, Abilities.LIGHT_METAL, Abilities.HEAVY_METAL, Abilities.STALWART, 535, 70, 95, 115, 120, 50, 85, 45, 50, 187, false, null, true), new PokemonForm("Normal", "", Type.STEEL, Type.DRAGON, 1.8, 40, Abilities.LIGHT_METAL, Abilities.HEAVY_METAL, Abilities.STALWART, 535, 70, 95, 115, 120, 50, 85, 45, 50, 187, false, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, Type.DRAGON, 43, 40, Abilities.LIGHT_METAL, Abilities.HEAVY_METAL, Abilities.STALWART, 635, 90, 110, 145, 140, 60, 90, 45, 50, 187), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, Type.DRAGON, 43, 40, Abilities.LIGHTNING_ROD, Abilities.LIGHTNING_ROD, Abilities.LIGHTNING_ROD, 635, 100, 105, 119, 166, 57, 88, 45, 50, 187),
), ),
new PokemonSpecies(Species.DREEPY, 8, false, false, false, "Lingering Pokémon", Type.DRAGON, Type.GHOST, 0.5, 2, Abilities.CLEAR_BODY, Abilities.INFILTRATOR, Abilities.CURSED_BODY, 270, 28, 60, 30, 40, 30, 82, 45, 50, 54, GrowthRate.SLOW, 50, false), new PokemonSpecies(Species.DREEPY, 8, false, false, false, "Lingering Pokémon", Type.DRAGON, Type.GHOST, 0.5, 2, Abilities.CLEAR_BODY, Abilities.INFILTRATOR, Abilities.CURSED_BODY, 270, 28, 60, 30, 40, 30, 82, 45, 50, 54, GrowthRate.SLOW, 50, false),
new PokemonSpecies(Species.DRAKLOAK, 8, false, false, false, "Caretaker Pokémon", Type.DRAGON, Type.GHOST, 1.4, 11, Abilities.CLEAR_BODY, Abilities.INFILTRATOR, Abilities.CURSED_BODY, 410, 68, 80, 50, 60, 50, 102, 45, 50, 144, GrowthRate.SLOW, 50, false), new PokemonSpecies(Species.DRAKLOAK, 8, false, false, false, "Caretaker Pokémon", Type.DRAGON, Type.GHOST, 1.4, 11, Abilities.CLEAR_BODY, Abilities.INFILTRATOR, Abilities.CURSED_BODY, 410, 68, 80, 50, 60, 50, 102, 45, 50, 144, GrowthRate.SLOW, 50, false),
@ -2411,8 +2411,8 @@ export function initSpecies() {
new PokemonSpecies(Species.URSHIFU, 8, true, false, false, "Wushu Pokémon", Type.FIGHTING, Type.DARK, 1.9, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, GrowthRate.SLOW, 87.5, false, true, new PokemonSpecies(Species.URSHIFU, 8, true, false, false, "Wushu Pokémon", Type.FIGHTING, Type.DARK, 1.9, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, GrowthRate.SLOW, 87.5, false, true,
new PokemonForm("Single Strike Style", "single-strike", Type.FIGHTING, Type.DARK, 1.9, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, false, "", true), new PokemonForm("Single Strike Style", "single-strike", Type.FIGHTING, Type.DARK, 1.9, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, false, "", true),
new PokemonForm("Rapid Strike Style", "rapid-strike", Type.FIGHTING, Type.WATER, 1.9, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, false, null, true), new PokemonForm("Rapid Strike Style", "rapid-strike", Type.FIGHTING, Type.WATER, 1.9, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, false, null, true),
new PokemonForm("G-Max Single Strike Style", SpeciesFormKey.GIGANTAMAX_SINGLE, Type.FIGHTING, Type.DARK, 29, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 650, 125, 160, 120, 75, 70, 100, 3, 50, 275), new PokemonForm("G-Max Single Strike Style", SpeciesFormKey.GIGANTAMAX_SINGLE, Type.FIGHTING, Type.DARK, 29, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 650, 125, 150, 115, 73, 70, 117, 3, 50, 275),
new PokemonForm("G-Max Rapid Strike Style", SpeciesFormKey.GIGANTAMAX_RAPID, Type.FIGHTING, Type.WATER, 26, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 650, 125, 160, 120, 75, 70, 100, 3, 50, 275), new PokemonForm("G-Max Rapid Strike Style", SpeciesFormKey.GIGANTAMAX_RAPID, Type.FIGHTING, Type.WATER, 26, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 650, 125, 150, 115, 73, 70, 117, 3, 50, 275),
), ),
new PokemonSpecies(Species.ZARUDE, 8, false, false, true, "Rogue Monkey Pokémon", Type.DARK, Type.GRASS, 1.8, 70, Abilities.LEAF_GUARD, Abilities.NONE, Abilities.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, GrowthRate.SLOW, null, false, false, new PokemonSpecies(Species.ZARUDE, 8, false, false, true, "Rogue Monkey Pokémon", Type.DARK, Type.GRASS, 1.8, 70, Abilities.LEAF_GUARD, Abilities.NONE, Abilities.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, GrowthRate.SLOW, null, false, false,
new PokemonForm("Normal", "", Type.DARK, Type.GRASS, 1.8, 70, Abilities.LEAF_GUARD, Abilities.NONE, Abilities.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, false, null, true), new PokemonForm("Normal", "", Type.DARK, Type.GRASS, 1.8, 70, Abilities.LEAF_GUARD, Abilities.NONE, Abilities.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, false, null, true),
@ -3622,7 +3622,7 @@ export const starterPassiveAbilities = {
[Species.YAMASK]: Abilities.PURIFYING_SALT, [Species.YAMASK]: Abilities.PURIFYING_SALT,
[Species.TIRTOUGA]: Abilities.WATER_ABSORB, [Species.TIRTOUGA]: Abilities.WATER_ABSORB,
[Species.ARCHEN]: Abilities.MULTISCALE, [Species.ARCHEN]: Abilities.MULTISCALE,
[Species.TRUBBISH]: Abilities.TOXIC_DEBRIS, [Species.TRUBBISH]: Abilities.NEUTRALIZING_GAS,
[Species.ZORUA]: Abilities.DARK_AURA, [Species.ZORUA]: Abilities.DARK_AURA,
[Species.MINCCINO]: Abilities.FUR_COAT, [Species.MINCCINO]: Abilities.FUR_COAT,
[Species.GOTHITA]: Abilities.UNNERVE, [Species.GOTHITA]: Abilities.UNNERVE,
@ -3783,7 +3783,7 @@ export const starterPassiveAbilities = {
[Species.SINISTEA]: Abilities.SHADOW_SHIELD, [Species.SINISTEA]: Abilities.SHADOW_SHIELD,
[Species.HATENNA]: Abilities.FAIRY_AURA, [Species.HATENNA]: Abilities.FAIRY_AURA,
[Species.IMPIDIMP]: Abilities.FUR_COAT, [Species.IMPIDIMP]: Abilities.FUR_COAT,
[Species.MILCERY]: Abilities.MISTY_SURGE, [Species.MILCERY]: Abilities.REGENERATOR,
[Species.FALINKS]: Abilities.PARENTAL_BOND, [Species.FALINKS]: Abilities.PARENTAL_BOND,
[Species.PINCURCHIN]: Abilities.ELECTROMORPHOSIS, [Species.PINCURCHIN]: Abilities.ELECTROMORPHOSIS,
[Species.SNOM]: Abilities.SNOW_WARNING, [Species.SNOM]: Abilities.SNOW_WARNING,

View File

@ -3,7 +3,7 @@ import BattleScene, { AnySound } from "../battle-scene";
import { Variant, VariantSet, variantColorCache } from "#app/data/variant"; import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
import { variantData } from "#app/data/variant"; import { variantData } from "#app/data/variant";
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info"; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info";
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, StatusMoveTypeImmunityAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr, OneHitKOAccuracyAttr } from "../data/move"; import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr } from "../data/move";
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species"; import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
import { Constructor } from "#app/utils"; import { Constructor } from "#app/utils";
import * as Utils from "../utils"; import * as Utils from "../utils";
@ -22,7 +22,7 @@ import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoo
import { WeatherType } from "../data/weather"; import { WeatherType } from "../data/weather";
import { TempBattleStat } from "../data/temp-battle-stat"; import { TempBattleStat } from "../data/temp-battle-stat";
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "../data/arena-tag"; import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "../data/arena-tag";
import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldBattleStatMultiplierAbAttrs, FieldMultiplyBattleStatAbAttr, AddSecondStrikeAbAttr, IgnoreOpponentEvasionAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr } from "../data/ability"; import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldBattleStatMultiplierAbAttrs, FieldMultiplyBattleStatAbAttr, AddSecondStrikeAbAttr, IgnoreOpponentEvasionAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr } from "../data/ability";
import PokemonData from "../system/pokemon-data"; import PokemonData from "../system/pokemon-data";
import { BattlerIndex } from "../battle"; import { BattlerIndex } from "../battle";
import { Mode } from "../ui/ui"; import { Mode } from "../ui/ui";
@ -1208,60 +1208,83 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
/** /**
* Calculates the effectiveness of a move against the Pokémon. * Calculates the type of a move when used by this Pokemon after
* * type-changing move and ability attributes have applied.
* @param source - The Pokémon using the move. * @param move {@linkcode Move} The move being used.
* @param move - The move being used. * @param simulated If `true`, prevents showing abilities applied in this calculation.
* @returns The type damage multiplier or 1 if it's a status move * @returns the {@linkcode Type} of the move after attributes are applied
*/ */
getMoveEffectiveness(source: Pokemon, move: PokemonMove): TypeDamageMultiplier { getMoveType(move: Move, simulated: boolean = true): Type {
if (move.getMove().category === MoveCategory.STATUS) { const moveTypeHolder = new Utils.NumberHolder(move.type);
return 1;
}
return this.getAttackMoveEffectiveness(source, move, !this.battleData?.abilityRevealed); applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder);
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder);
return moveTypeHolder.value as Type;
} }
/** /**
* Calculates the effectiveness of an attack move against the Pokémon. * Calculates the effectiveness of a move against the Pokémon.
* *
* @param source - The attacking Pokémon. * @param source {@linkcode Pokemon} The attacking Pokémon.
* @param pokemonMove - The move being used by the attacking Pokémon. * @param move {@linkcode Move} The move being used by the attacking Pokémon.
* @param ignoreAbility - Whether to check for abilities that might affect type effectiveness or immunity. * @param ignoreAbility Whether to ignore abilities that might affect type effectiveness or immunity (defaults to `false`).
* @param simulated Whether to apply abilities via simulated calls (defaults to `true`)
* @param cancelled {@linkcode Utils.BooleanHolder} Stores whether the move was cancelled by a non-type-based immunity.
* Currently only used by {@linkcode Pokemon.apply} to determine whether a "No effect" message should be shown.
* @returns The type damage multiplier, indicating the effectiveness of the move * @returns The type damage multiplier, indicating the effectiveness of the move
*/ */
getAttackMoveEffectiveness(source: Pokemon, pokemonMove: PokemonMove, ignoreAbility: boolean = false): TypeDamageMultiplier { getMoveEffectiveness(source: Pokemon, move: Move, ignoreAbility: boolean = false, simulated: boolean = true, cancelled?: Utils.BooleanHolder): TypeDamageMultiplier {
const move = pokemonMove.getMove(); if (move.hasAttr(TypelessAttr)) {
const typeless = move.hasAttr(TypelessAttr); return 1;
const typeMultiplier = new Utils.NumberHolder(this.getAttackTypeEffectiveness(move, source));
const cancelled = new Utils.BooleanHolder(false);
applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier);
if (!typeless && !ignoreAbility) {
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, move, cancelled, true, typeMultiplier);
} }
if (!cancelled.value && !ignoreAbility) { const moveType = source.getMoveType(move);
applyPreDefendAbAttrs(MoveImmunityAbAttr, this, source, move, cancelled, true, typeMultiplier);
const typeMultiplier = new Utils.NumberHolder((move.category !== MoveCategory.STATUS || move.hasAttr(RespectAttackTypeImmunityAttr))
? this.getAttackTypeEffectiveness(moveType, source, false, simulated)
: 1);
applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier);
if (this.getTypes().find(t => move.isTypeImmune(source, this, t))) {
typeMultiplier.value = 0;
} }
return (!cancelled.value ? Number(typeMultiplier.value) : 0) as TypeDamageMultiplier; const cancelledHolder = cancelled ?? new Utils.BooleanHolder(false);
if (!ignoreAbility) {
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, move, cancelledHolder, simulated, typeMultiplier);
if (!cancelledHolder.value) {
applyPreDefendAbAttrs(MoveImmunityAbAttr, this, source, move, cancelledHolder, simulated, typeMultiplier);
}
if (!cancelledHolder.value) {
const defendingSidePlayField = this.isPlayer() ? this.scene.getPlayerField() : this.scene.getEnemyField();
defendingSidePlayField.forEach((p) => applyPreDefendAbAttrs(FieldPriorityMoveImmunityAbAttr, p, source, move, cancelledHolder));
}
}
const immuneTags = this.findTags(tag => tag instanceof TypeImmuneTag && tag.immuneType === moveType);
for (const tag of immuneTags) {
if (move && !move.getAttrs(HitsTagAttr).some(attr => attr.tagType === tag.tagType)) {
typeMultiplier.value = 0;
break;
}
}
return (!cancelledHolder.value ? typeMultiplier.value : 0) as TypeDamageMultiplier;
} }
/** /**
* Calculates the type effectiveness multiplier for an attack type * Calculates the type effectiveness multiplier for an attack type
* @param moveOrType The move being used, or a type if the move is unknown * @param moveType {@linkcode Type} the type of the move being used
* @param source the Pokemon using the move * @param source {@linkcode Pokemon} the Pokemon using the move
* @param ignoreStrongWinds whether or not this ignores strong winds (anticipation, forewarn, stealth rocks) * @param ignoreStrongWinds whether or not this ignores strong winds (anticipation, forewarn, stealth rocks)
* @param simulated tag to only apply the strong winds effect message when the move is used * @param simulated tag to only apply the strong winds effect message when the move is used
* @returns a multiplier for the type effectiveness * @returns a multiplier for the type effectiveness
*/ */
getAttackTypeEffectiveness(moveOrType: Move | Type, source?: Pokemon, ignoreStrongWinds: boolean = false, simulated: boolean = true): TypeDamageMultiplier { getAttackTypeEffectiveness(moveType: Type, source?: Pokemon, ignoreStrongWinds: boolean = false, simulated: boolean = true): TypeDamageMultiplier {
const move = (moveOrType instanceof Move)
? moveOrType
: undefined;
const moveType = (moveOrType instanceof Move)
? move!.type // TODO: is this bang correct?
: moveOrType;
if (moveType === Type.STELLAR) { if (moveType === Type.STELLAR) {
return this.isTerastallized() ? 2 : 1; return this.isTerastallized() ? 2 : 1;
} }
@ -1281,7 +1304,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (source) { if (source) {
const ignoreImmunity = new Utils.BooleanHolder(false); const ignoreImmunity = new Utils.BooleanHolder(false);
if (source.isActive(true) && source.hasAbilityWithAttr(IgnoreTypeImmunityAbAttr)) { if (source.isActive(true) && source.hasAbilityWithAttr(IgnoreTypeImmunityAbAttr)) {
applyAbAttrs(IgnoreTypeImmunityAbAttr, source, ignoreImmunity, false, moveType, defType); applyAbAttrs(IgnoreTypeImmunityAbAttr, source, ignoreImmunity, simulated, moveType, defType);
} }
if (ignoreImmunity.value) { if (ignoreImmunity.value) {
return 1; return 1;
@ -1303,15 +1326,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.scene.queueMessage(i18next.t("weather:strongWindsEffectMessage")); this.scene.queueMessage(i18next.t("weather:strongWindsEffectMessage"));
} }
} }
const immuneTags = this.findTags(tag => tag instanceof TypeImmuneTag && tag.immuneType === moveType);
for (const tag of immuneTags) {
if (move && !move.getAttrs(HitsTagAttr).some(attr => attr.tagType === tag.tagType)) {
multiplier = 0;
break;
}
}
return multiplier as TypeDamageMultiplier; return multiplier as TypeDamageMultiplier;
} }
@ -1959,29 +1973,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
let result: HitResult; let result: HitResult;
const damage = new Utils.NumberHolder(0); const damage = new Utils.NumberHolder(0);
const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
const defendingSidePlayField = this.isPlayer() ? this.scene.getPlayerField() : this.scene.getEnemyField();
const variableCategory = new Utils.IntegerHolder(move.category); const variableCategory = new Utils.NumberHolder(move.category);
applyMoveAttrs(VariableMoveCategoryAttr, source, this, move, variableCategory); applyMoveAttrs(VariableMoveCategoryAttr, source, this, move, variableCategory);
const moveCategory = variableCategory.value as MoveCategory; const moveCategory = variableCategory.value as MoveCategory;
applyMoveAttrs(VariableMoveTypeAttr, source, this, move); /** The move's type after type-changing effects are applied */
const types = this.getTypes(true, true); const moveType = source.getMoveType(move);
/** If `value` is `true`, cancels the move and suppresses "No Effect" messages */
const cancelled = new Utils.BooleanHolder(false); const cancelled = new Utils.BooleanHolder(false);
const power = move.calculateBattlePower(source, this);
const typeless = move.hasAttr(TypelessAttr);
const typeMultiplier = new Utils.NumberHolder(!typeless && (moveCategory !== MoveCategory.STATUS || move.getAttrs(StatusMoveTypeImmunityAttr).find(attr => types.includes(attr.immuneType))) /**
? this.getAttackTypeEffectiveness(move, source, false, false) * The effectiveness of the move being used. Along with type matchups, this
: 1); * accounts for changes in effectiveness from the move's attributes and the
applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier); * abilities of both the source and this Pokemon.
if (typeless) { */
typeMultiplier.value = 1; const typeMultiplier = this.getMoveEffectiveness(source, move, false, false, cancelled);
}
if (types.find(t => move.isTypeImmune(source, this, t))) {
typeMultiplier.value = 0;
}
switch (moveCategory) { switch (moveCategory) {
case MoveCategory.PHYSICAL: case MoveCategory.PHYSICAL:
@ -1989,27 +1997,44 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const isPhysical = moveCategory === MoveCategory.PHYSICAL; const isPhysical = moveCategory === MoveCategory.PHYSICAL;
const sourceTeraType = source.getTeraType(); const sourceTeraType = source.getTeraType();
if (!typeless) { const power = move.calculateBattlePower(source, this);
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, move, cancelled, false, typeMultiplier);
applyMoveAttrs(NeutralDamageAgainstFlyingTypeMultiplierAttr, source, this, move, typeMultiplier);
}
if (!cancelled.value) {
applyPreDefendAbAttrs(MoveImmunityAbAttr, this, source, move, cancelled, false, typeMultiplier);
defendingSidePlayField.forEach((p) => applyPreDefendAbAttrs(FieldPriorityMoveImmunityAbAttr, p, source, move, cancelled, false, typeMultiplier));
}
if (cancelled.value) { if (cancelled.value) {
// Cancelled moves fail silently
source.stopMultiHit(this); source.stopMultiHit(this);
result = HitResult.NO_EFFECT; return HitResult.NO_EFFECT;
} else { } else {
const typeBoost = source.findTag(t => t instanceof TypeBoostTag && t.boostedType === move.type) as TypeBoostTag; const typeBoost = source.findTag(t => t instanceof TypeBoostTag && t.boostedType === moveType) as TypeBoostTag;
if (typeBoost?.oneUse) { if (typeBoost?.oneUse) {
source.removeTag(typeBoost.tagType); source.removeTag(typeBoost.tagType);
} }
const arenaAttackTypeMultiplier = new Utils.NumberHolder(this.scene.arena.getAttackTypeMultiplier(move.type, source.isGrounded())); /** Combined damage multiplier from field effects such as weather, terrain, etc. */
const arenaAttackTypeMultiplier = new Utils.NumberHolder(this.scene.arena.getAttackTypeMultiplier(moveType, source.isGrounded()));
applyMoveAttrs(IgnoreWeatherTypeDebuffAttr, source, this, move, arenaAttackTypeMultiplier); applyMoveAttrs(IgnoreWeatherTypeDebuffAttr, source, this, move, arenaAttackTypeMultiplier);
/**
* Whether or not this Pokemon is immune to the incoming move.
* Note that this isn't fully resolved in `getMoveEffectiveness` because
* of possible type-suppressing field effects (e.g. Desolate Land's effect on Water-type attacks).
*/
const isTypeImmune = (typeMultiplier * arenaAttackTypeMultiplier.value) === 0;
if (isTypeImmune) {
// Moves with no effect that were not cancelled queue a "no effect" message before failing
source.stopMultiHit(this);
result = (move.id === Moves.SHEER_COLD)
? HitResult.IMMUNE
: HitResult.NO_EFFECT;
if (result === HitResult.IMMUNE) {
this.scene.queueMessage(i18next.t("battle:hitResultImmune", { pokemonName: this.name }));
} else {
this.scene.queueMessage(i18next.t("battle:hitResultNoEffect", { pokemonName: getPokemonNameWithAffix(this) }));
}
return result;
}
const glaiveRushModifier = new Utils.IntegerHolder(1); const glaiveRushModifier = new Utils.IntegerHolder(1);
if (this.getTag(BattlerTagType.RECEIVE_DOUBLE_DAMAGE)) { if (this.getTag(BattlerTagType.RECEIVE_DOUBLE_DAMAGE)) {
glaiveRushModifier.value = 2; glaiveRushModifier.value = 2;
@ -2059,13 +2084,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (!isCritical) { if (!isCritical) {
this.scene.arena.applyTagsForSide(WeakenMoveScreenTag, defendingSide, move.category, this.scene.currentBattle.double, screenMultiplier); this.scene.arena.applyTagsForSide(WeakenMoveScreenTag, defendingSide, move.category, this.scene.currentBattle.double, screenMultiplier);
} }
const isTypeImmune = (typeMultiplier.value * arenaAttackTypeMultiplier.value) === 0;
const sourceTypes = source.getTypes(); const sourceTypes = source.getTypes();
const matchesSourceType = sourceTypes[0] === move.type || (sourceTypes.length > 1 && sourceTypes[1] === move.type); const matchesSourceType = sourceTypes[0] === moveType || (sourceTypes.length > 1 && sourceTypes[1] === moveType);
const stabMultiplier = new Utils.NumberHolder(1); const stabMultiplier = new Utils.NumberHolder(1);
if (sourceTeraType === Type.UNKNOWN && matchesSourceType) { if (sourceTeraType === Type.UNKNOWN && matchesSourceType) {
stabMultiplier.value += 0.5; stabMultiplier.value += 0.5;
} else if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === move.type) { } else if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === moveType) {
stabMultiplier.value += 0.5; stabMultiplier.value += 0.5;
} }
@ -2075,8 +2099,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
stabMultiplier.value = Math.min(stabMultiplier.value + 0.5, 2.25); stabMultiplier.value = Math.min(stabMultiplier.value + 0.5, 2.25);
} }
const targetCount = getMoveTargets(source, move.id).targets.length; // 25% damage debuff on moves hitting more than one non-fainted target (regardless of immunities)
const targetMultiplier = targetCount > 1 ? 0.75 : 1; // 25% damage debuff on multi-target hits (even if it's immune) const { targets, multiple } = getMoveTargets(source, move.id);
const targetMultiplier = (multiple && targets.length > 1) ? 0.75 : 1;
applyMoveAttrs(VariableAtkAttr, source, this, move, sourceAtk); applyMoveAttrs(VariableAtkAttr, source, this, move, sourceAtk);
applyMoveAttrs(VariableDefAttr, source, this, move, targetDef); applyMoveAttrs(VariableDefAttr, source, this, move, targetDef);
@ -2094,7 +2119,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const randomMultiplier = ((this.scene.randBattleSeedInt(16) + 85) / 100); const randomMultiplier = ((this.scene.randBattleSeedInt(16) + 85) / 100);
damage.value = Utils.toDmgValue((((levelMultiplier * power * sourceAtk.value / targetDef.value) / 50) + 2) damage.value = Utils.toDmgValue((((levelMultiplier * power * sourceAtk.value / targetDef.value) / 50) + 2)
* stabMultiplier.value * stabMultiplier.value
* typeMultiplier.value * typeMultiplier
* arenaAttackTypeMultiplier.value * arenaAttackTypeMultiplier.value
* screenMultiplier.value * screenMultiplier.value
* twoStrikeMultiplier.value * twoStrikeMultiplier.value
@ -2128,7 +2153,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}); });
} }
if (this.scene.arena.terrain?.terrainType === TerrainType.MISTY && this.isGrounded() && move.type === Type.DRAGON) { if (this.scene.arena.terrain?.terrainType === TerrainType.MISTY && this.isGrounded() && moveType === Type.DRAGON) {
damage.value = Utils.toDmgValue(damage.value / 2); damage.value = Utils.toDmgValue(damage.value / 2);
} }
@ -2142,22 +2167,18 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
result = result!; // telling TS compiler that result is defined! result = result!; // telling TS compiler that result is defined!
if (!result) { if (!result) {
if (!typeMultiplier.value) { const isOneHitKo = new Utils.BooleanHolder(false);
result = move.id === Moves.SHEER_COLD ? HitResult.IMMUNE : HitResult.NO_EFFECT; applyMoveAttrs(OneHitKOAttr, source, this, move, isOneHitKo);
if (isOneHitKo.value) {
result = HitResult.ONE_HIT_KO;
isCritical = false;
damage.value = this.hp;
} else if (typeMultiplier >= 2) {
result = HitResult.SUPER_EFFECTIVE;
} else if (typeMultiplier >= 1) {
result = HitResult.EFFECTIVE;
} else { } else {
const isOneHitKo = new Utils.BooleanHolder(false); result = HitResult.NOT_VERY_EFFECTIVE;
applyMoveAttrs(OneHitKOAttr, source, this, move, isOneHitKo);
if (isOneHitKo.value) {
result = HitResult.ONE_HIT_KO;
isCritical = false;
damage.value = this.hp;
} else if (typeMultiplier.value >= 2) {
result = HitResult.SUPER_EFFECTIVE;
} else if (typeMultiplier.value >= 1) {
result = HitResult.EFFECTIVE;
} else {
result = HitResult.NOT_VERY_EFFECTIVE;
}
} }
} }
@ -2224,15 +2245,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
case HitResult.NOT_VERY_EFFECTIVE: case HitResult.NOT_VERY_EFFECTIVE:
this.scene.queueMessage(i18next.t("battle:hitResultNotVeryEffective")); this.scene.queueMessage(i18next.t("battle:hitResultNotVeryEffective"));
break; break;
case HitResult.NO_EFFECT:
this.scene.queueMessage(i18next.t("battle:hitResultNoEffect", { pokemonName: getPokemonNameWithAffix(this) }));
break;
case HitResult.IMMUNE:
this.scene.queueMessage(i18next.t("battle:hitResultImmune", { pokemonName: this.name }));
break;
case HitResult.ONE_HIT_KO: case HitResult.ONE_HIT_KO:
this.scene.queueMessage(i18next.t("battle:hitResultOneHitKO")); this.scene.queueMessage(i18next.t("battle:hitResultOneHitKO"));
break; break;
case HitResult.IMMUNE:
case HitResult.NO_EFFECT:
console.error("Unhandled move immunity!");
break;
} }
} }
@ -2244,23 +2263,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
if (damage) { if (damage) {
const attacker = this.scene.getPokemonById(source.id)!; // TODO: is this bang correct? destinyTag?.lapse(source, BattlerTagLapseType.CUSTOM);
destinyTag?.lapse(attacker, BattlerTagLapseType.CUSTOM);
} }
} }
break; break;
case MoveCategory.STATUS: case MoveCategory.STATUS:
if (!typeless) { if (!cancelled.value && typeMultiplier === 0) {
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, move, cancelled, false, typeMultiplier);
}
if (!cancelled.value) {
applyPreDefendAbAttrs(MoveImmunityAbAttr, this, source, move, cancelled, false, typeMultiplier);
defendingSidePlayField.forEach((p) => applyPreDefendAbAttrs(FieldPriorityMoveImmunityAbAttr, p, source, move, cancelled, false, typeMultiplier));
}
if (!typeMultiplier.value) {
this.scene.queueMessage(i18next.t("battle:hitResultNoEffect", { pokemonName: getPokemonNameWithAffix(this) })); this.scene.queueMessage(i18next.t("battle:hitResultNoEffect", { pokemonName: getPokemonNameWithAffix(this) }));
} }
result = cancelled.value || !typeMultiplier.value ? HitResult.NO_EFFECT : HitResult.STATUS; result = (typeMultiplier === 0) ? HitResult.NO_EFFECT : HitResult.STATUS;
break; break;
} }
@ -3917,7 +3928,7 @@ export class EnemyPokemon extends Pokemon {
* Attack moves are given extra multipliers to their base benefit score based on * Attack moves are given extra multipliers to their base benefit score based on
* the move's type effectiveness against the target and whether the move is a STAB move. * the move's type effectiveness against the target and whether the move is a STAB move.
*/ */
const effectiveness = target.getAttackMoveEffectiveness(this, pokemonMove); const effectiveness = target.getMoveEffectiveness(this, move, !target.battleData?.abilityRevealed);
if (target.isPlayer() !== this.isPlayer()) { if (target.isPlayer() !== this.isPlayer()) {
targetScore *= effectiveness; targetScore *= effectiveness;
if (this.isOfType(move.type)) { if (this.isOfType(move.type)) {

View File

@ -2913,7 +2913,7 @@
}, },
"zippyZap": { "zippyZap": {
"name": "Zippy Zap", "name": "Zippy Zap",
"effect": "The user attacks the target with bursts of electricity at high speed. This move always goes first and raises the user's evasiveness." "effect": "The user attacks the target with bursts of electricity at high speed. This move always goes first and results in a critical hit."
}, },
"splishySplash": { "splishySplash": {
"name": "Splishy Splash", "name": "Splishy Splash",
@ -3807,4 +3807,4 @@
"name": "Malignant Chain", "name": "Malignant Chain",
"effect": "The user pours toxins into the target by wrapping them in a toxic, corrosive chain. This may also leave the target badly poisoned." "effect": "The user pours toxins into the target by wrapping them in a toxic, corrosive chain. This may also leave the target badly poisoned."
} }
} }

View File

@ -16,7 +16,7 @@
"invalidLoginUsername": "El usuario no es válido", "invalidLoginUsername": "El usuario no es válido",
"invalidRegisterUsername": "El usuario solo puede contener letras, números y guiones bajos", "invalidRegisterUsername": "El usuario solo puede contener letras, números y guiones bajos",
"invalidLoginPassword": "La contraseña no es válida", "invalidLoginPassword": "La contraseña no es válida",
"invalidRegisterPassword": "Contraseña debe tener 6 o más caracter.", "invalidRegisterPassword": "La contraseña debe tener 6 o más caracteres.",
"usernameAlreadyUsed": "El usuario ya está en uso", "usernameAlreadyUsed": "El usuario ya está en uso",
"accountNonExistent": "El usuario no existe", "accountNonExistent": "El usuario no existe",
"unmatchingPassword": "La contraseña no coincide", "unmatchingPassword": "La contraseña no coincide",
@ -37,12 +37,19 @@
"weeklyRankings": "Rankings Semanales", "weeklyRankings": "Rankings Semanales",
"noRankings": "Sin Rankings", "noRankings": "Sin Rankings",
"positionIcon": "#", "positionIcon": "#",
"usernameScoreboard": "Usuario",
"score": "Puntos",
"wave": "Oleada",
"loading": "Cargando…", "loading": "Cargando…",
"loadingAsset": "Cargando recurso: {{assetName}}", "loadingAsset": "Cargando recurso: {{assetName}}",
"playersOnline": "Jugadores en Línea", "playersOnline": "Jugadores en Línea",
"yes": "Sí", "yes": "Sí",
"no": "No", "no": "No",
"disclaimer": "AVISO", "disclaimer": "AVISO",
"disclaimerDescription": "Este juego es un producto inacabado; puede tener problemas de jugabilidad (incluyendo la posible pérdida\n de datos de guardado),cambiar sin avisar, y puede o no puede ser actualizado hasta ser completado.", "disclaimerDescription": "Este juego es un producto inacabado; puede tener problemas de jugabilidad (incluyendo la posible pérdida\n de datos de guardado), cambiar sin avisar, y puede o no puede ser actualizado hasta ser completado.",
"errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta,\nel juego se reconectará automáticamente." "choosePokemon": "Elige un Pokémon.",
} "renamePokemon": "Renombrar Pokémon.",
"rename": "Renombrar",
"nickname": "Apodo",
"errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta, el juego se reconectará automáticamente."
}

View File

@ -97,6 +97,10 @@
"name": "MT{{moveId}} - {{moveName}}", "name": "MT{{moveId}} - {{moveName}}",
"description": "Enseña {{moveName}} a un Pokémon." "description": "Enseña {{moveName}} a un Pokémon."
}, },
"TmModifierTypeWithInfo": {
"name": "MT{{moveId}} - {{moveName}}",
"description": "Enseña {{moveName}} a un Pokémon\n(Mantén pulsado C o Shift para más info)."
},
"EvolutionItemModifierType": { "EvolutionItemModifierType": {
"description": "Hace que ciertos Pokémon evolucionen." "description": "Hace que ciertos Pokémon evolucionen."
}, },
@ -129,12 +133,12 @@
"name": "Caramelorarísimo" "name": "Caramelorarísimo"
}, },
"MEGA_BRACELET": { "MEGA_BRACELET": {
"name": "Mega-aro", "name": "Megapulsera",
"description": "Las Megapiedras están disponibles." "description": "Las megapiedras se vuelven disponibles."
}, },
"DYNAMAX_BAND": { "DYNAMAX_BAND": {
"name": "Maximuñequera", "name": "Maximuñequera",
"description": "Las Maxisetas están disponibles." "description": "Las maxisetas se vuelven disponibles."
}, },
"TERA_ORB": { "TERA_ORB": {
"name": "Orbe Teracristal", "name": "Orbe Teracristal",
@ -154,42 +158,42 @@
"name": "Hiperpoción" "name": "Hiperpoción"
}, },
"MAX_POTION": { "MAX_POTION": {
"name": "Máx. Poción" "name": "Máx. poción"
}, },
"FULL_RESTORE": { "FULL_RESTORE": {
"name": "Restau. Todo" "name": "Restau. todo"
}, },
"REVIVE": { "REVIVE": {
"name": "Revivir" "name": "Revivir"
}, },
"MAX_REVIVE": { "MAX_REVIVE": {
"name": "Máx. Revivir" "name": "Máx. revivir"
}, },
"FULL_HEAL": { "FULL_HEAL": {
"name": "Cura Total" "name": "Cura total"
}, },
"SACRED_ASH": { "SACRED_ASH": {
"name": "Cen. Sagrada" "name": "Ceniza sagrada"
}, },
"REVIVER_SEED": { "REVIVER_SEED": {
"name": "Semilla Revivir", "name": "Semilla revivir",
"description": "Revive al portador con la mitad de sus PS al debilitarse por un golpe directo." "description": "Revive al portador con la mitad de sus PS al debilitarse por un golpe directo."
}, },
"WHITE_HERB": { "WHITE_HERB": {
"name": "White Herb", "name": "Hierba blanca",
"description": "An item to be held by a Pokémon. It will restore any lowered stat in battle." "description": "Un objeto que puede llevar un Pokémon. Restaurará cualquier estadística reducida en combate."
}, },
"ETHER": { "ETHER": {
"name": "Éter" "name": "Éter"
}, },
"MAX_ETHER": { "MAX_ETHER": {
"name": "Éter Máx." "name": "Éter máx."
}, },
"ELIXIR": { "ELIXIR": {
"name": "Elixir" "name": "Elixir"
}, },
"MAX_ELIXIR": { "MAX_ELIXIR": {
"name": "Elixir Máx." "name": "Elixir máx."
}, },
"PP_UP": { "PP_UP": {
"name": "Más PP" "name": "Más PP"
@ -204,10 +208,10 @@
"name": "Superincienso" "name": "Superincienso"
}, },
"MAX_LURE": { "MAX_LURE": {
"name": "Incienso Máximo" "name": "Incienso máximo"
}, },
"MEMORY_MUSHROOM": { "MEMORY_MUSHROOM": {
"name": "Seta Recuerdo", "name": "Seta recuerdo",
"description": "Recuerda un movimiento olvidado de un Pokémon." "description": "Recuerda un movimiento olvidado de un Pokémon."
}, },
"EXP_SHARE": { "EXP_SHARE": {
@ -215,8 +219,8 @@
"description": "Los que no combatan reciben el 20% de la EXP." "description": "Los que no combatan reciben el 20% de la EXP."
}, },
"EXP_BALANCE": { "EXP_BALANCE": {
"name": "Equilibrar EXP", "name": "Equilibrador EXP",
"description": "Da mayor parte de la EXP recibida a los miembros del equipo que tengan menos nivel." "description": "Da una mayor parte de la EXP recibida a los miembros del equipo que tengan menos nivel."
}, },
"OVAL_CHARM": { "OVAL_CHARM": {
"name": "Amuleto Oval", "name": "Amuleto Oval",
@ -232,13 +236,13 @@
"name": "Amuleto EXP Dorado" "name": "Amuleto EXP Dorado"
}, },
"LUCKY_EGG": { "LUCKY_EGG": {
"name": "Huevo Suerte" "name": "Huevo suerte"
}, },
"GOLDEN_EGG": { "GOLDEN_EGG": {
"name": "Huevo Dorado" "name": "Huevo dorado"
}, },
"SOOTHE_BELL": { "SOOTHE_BELL": {
"name": "Camp. Alivio" "name": "Camp. alivio"
}, },
"SCOPE_LENS": { "SCOPE_LENS": {
"name": "Periscopio", "name": "Periscopio",
@ -249,7 +253,7 @@
"description": "Puerro muy largo y duro que aumenta la probabilidad de asestar un golpe crítico. Debe llevarlo Farfetch'd." "description": "Puerro muy largo y duro que aumenta la probabilidad de asestar un golpe crítico. Debe llevarlo Farfetch'd."
}, },
"EVIOLITE": { "EVIOLITE": {
"name": "Mineral Evolutivo", "name": "Mineral evolutivo",
"description": "Roca misteriosa. El Pokémon portador aumentará su Defensa y su Defensa Especial si aún puede evolucionar." "description": "Roca misteriosa. El Pokémon portador aumentará su Defensa y su Defensa Especial si aún puede evolucionar."
}, },
"SOUL_DEW": { "SOUL_DEW": {
@ -266,7 +270,7 @@
"name": "Real de oro" "name": "Real de oro"
}, },
"AMULET_COIN": { "AMULET_COIN": {
"name": "Moneda Amuleto", "name": "Moneda amuleto",
"description": "Aumenta el dinero ganado en un 20%." "description": "Aumenta el dinero ganado en un 20%."
}, },
"GOLDEN_PUNCH": { "GOLDEN_PUNCH": {
@ -279,10 +283,10 @@
}, },
"LOCK_CAPSULE": { "LOCK_CAPSULE": {
"name": "Cápsula candado", "name": "Cápsula candado",
"description": "Le permite bloquear las rarezas de los objetos al cambiar de objetos." "description": "Permite bloquear las rarezas de los objetos al refrescar objetos."
}, },
"GRIP_CLAW": { "GRIP_CLAW": {
"name": "Garra Garfio" "name": "Garra garfio"
}, },
"WIDE_LENS": { "WIDE_LENS": {
"name": "Lupa" "name": "Lupa"
@ -294,20 +298,24 @@
"name": "Amuleto curación", "name": "Amuleto curación",
"description": "Aumenta la efectividad de los movimientos y objetos de curacion de PS en un 10% (excepto revivir)." "description": "Aumenta la efectividad de los movimientos y objetos de curacion de PS en un 10% (excepto revivir)."
}, },
"CANDY_JAR": {
"name": "Tarrón de caramelos",
"description": "Aumenta la cantidad de niveles otorgados por los ítems Caramelos Raros en 1."
},
"BERRY_POUCH": { "BERRY_POUCH": {
"name": "Saco Bayas", "name": "Saco bayas",
"description": "Agrega un 30% de posibilidades de que una baya usada no se consuma." "description": "Añade un 30% de posibilidades de que una baya no se gaste al usarla."
}, },
"FOCUS_BAND": { "FOCUS_BAND": {
"name": "Cinta Focus", "name": "Banda aguante",
"description": "Agrega un 10% de probabilidad de resistir un ataque que lo debilitaría." "description": "Agrega un 10% de probabilidad de resistir un ataque que lo debilitaría."
}, },
"QUICK_CLAW": { "QUICK_CLAW": {
"name": "Garra Rápida", "name": "Garra rápida",
"description": "Agrega un 10% de probabilidad de atacar primero independientemente de la velocidad (después de la prioridad)." "description": "Agrega un 10% de probabilidad de atacar primero independientemente de la velocidad (después de la prioridad)."
}, },
"KINGS_ROCK": { "KINGS_ROCK": {
"name": "Roca del Rey", "name": "Roca del rey",
"description": "Agrega un 10% de probabilidad de que un ataque haga que el oponente retroceda." "description": "Agrega un 10% de probabilidad de que un ataque haga que el oponente retroceda."
}, },
"LEFTOVERS": { "LEFTOVERS": {
@ -315,7 +323,7 @@
"description": "Cura 1/16 de los PS máximo de un Pokémon cada turno." "description": "Cura 1/16 de los PS máximo de un Pokémon cada turno."
}, },
"SHELL_BELL": { "SHELL_BELL": {
"name": "Camp Concha", "name": "Cascabel concha",
"description": "Cura 1/8 del daño infligido por un Pokémon." "description": "Cura 1/8 del daño infligido por un Pokémon."
}, },
"TOXIC_ORB": { "TOXIC_ORB": {
@ -327,15 +335,15 @@
"description": "Extraña esfera que causa quemaduras a quien la usa en combate." "description": "Extraña esfera que causa quemaduras a quien la usa en combate."
}, },
"BATON": { "BATON": {
"name": "Relevo", "name": "Testigo",
"description": "Permite pasar los efectos al cambiar de Pokémon, también evita las trampas." "description": "Permite pasar los efectos al cambiar de Pokémon, también evita las trampas."
}, },
"SHINY_CHARM": { "SHINY_CHARM": {
"name": "Amuleto Iris", "name": "Amuleto iris",
"description": "Aumenta drásticamente la posibilidad de que un Pokémon salvaje sea Shiny." "description": "Aumenta drásticamente la posibilidad de que un Pokémon salvaje sea Shiny."
}, },
"ABILITY_CHARM": { "ABILITY_CHARM": {
"name": "Amuleto Habilidad", "name": "Amuleto habilidad",
"description": "Aumenta drásticamente la posibilidad de que un Pokémon salvaje tenga una habilidad oculta." "description": "Aumenta drásticamente la posibilidad de que un Pokémon salvaje tenga una habilidad oculta."
}, },
"IV_SCANNER": { "IV_SCANNER": {
@ -346,60 +354,60 @@
"name": "Punta ADN" "name": "Punta ADN"
}, },
"MINI_BLACK_HOLE": { "MINI_BLACK_HOLE": {
"name": "Mini Agujero Negro" "name": "Mini agujero negro"
}, },
"GOLDEN_POKEBALL": { "GOLDEN_POKEBALL": {
"name": "Poké Ball Dorada", "name": "Poké Ball Dorada",
"description": "Agrega 1 opción de objeto extra al final de cada combate." "description": "Agrega 1 opción de objeto extra al final de cada combate."
}, },
"ENEMY_DAMAGE_BOOSTER": { "ENEMY_DAMAGE_BOOSTER": {
"name": "Ficha Daño", "name": "Ficha de daño",
"description": "Aumenta el daño en un 5%." "description": "Aumenta el daño en un 5%."
}, },
"ENEMY_DAMAGE_REDUCTION": { "ENEMY_DAMAGE_REDUCTION": {
"name": "Ficha Protección", "name": "Ficha de protección",
"description": "Reduce el daño recibido en un 2,5%." "description": "Reduce el daño recibido en un 2,5%."
}, },
"ENEMY_HEAL": { "ENEMY_HEAL": {
"name": "Ficha Curación", "name": "Ficha de curación",
"description": "Cura el 2% de los PS máximo en cada turno." "description": "Cura el 2% de los PS máximo en cada turno."
}, },
"ENEMY_ATTACK_POISON_CHANCE": { "ENEMY_ATTACK_POISON_CHANCE": {
"name": "Ficha Veneno" "name": "Ficha veneno"
}, },
"ENEMY_ATTACK_PARALYZE_CHANCE": { "ENEMY_ATTACK_PARALYZE_CHANCE": {
"name": "Ficha Parálisis" "name": "Ficha parálisis"
}, },
"ENEMY_ATTACK_BURN_CHANCE": { "ENEMY_ATTACK_BURN_CHANCE": {
"name": "Ficha Quemadura" "name": "Ficha quemadura"
}, },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { "ENEMY_STATUS_EFFECT_HEAL_CHANCE": {
"name": "Ficha Cura Total", "name": "Ficha cura total",
"description": "Agrega un 2.5% de probabilidad cada turno de curar un problema de estado." "description": "Agrega un 2.5% de probabilidad cada turno de curar un problema de estado."
}, },
"ENEMY_ENDURE_CHANCE": { "ENEMY_ENDURE_CHANCE": {
"name": "Ficha Aguante" "name": "Ficha aguante"
}, },
"ENEMY_FUSED_CHANCE": { "ENEMY_FUSED_CHANCE": {
"name": "Ficha Fusión", "name": "Ficha fusión",
"description": "Agrega un 1% de probabilidad de que un Pokémon salvaje sea una fusión." "description": "Agrega un 1% de probabilidad de que un Pokémon salvaje sea una fusión."
} }
}, },
"SpeciesBoosterItem": { "SpeciesBoosterItem": {
"LIGHT_BALL": { "LIGHT_BALL": {
"name": "Bola Luminosa", "name": "Bola luminosa",
"description": "Asombrosa esfera que aumenta el Ataque y el Ataque Especial. Debe llevarla Pikachu." "description": "Asombrosa esfera que aumenta el Ataque y el Ataque Especial. Debe llevarla Pikachu."
}, },
"THICK_CLUB": { "THICK_CLUB": {
"name": "Hueso Grueso", "name": "Hueso grueso",
"description": "Extraño tipo de hueso que potencia los ataques físicos. Debe llevarlo Cubone o Marowak." "description": "Extraño tipo de hueso que potencia los ataques físicos. Debe llevarlo Cubone o Marowak."
}, },
"METAL_POWDER": { "METAL_POWDER": {
"name": "Polvo Metálico", "name": "Polvo metálico",
"description": "Polvo muy fino, pero a la vez poderoso, que aumenta la Defensa. Debe llevarlo Ditto." "description": "Polvo muy fino, pero a la vez poderoso, que aumenta la Defensa. Debe llevarlo Ditto."
}, },
"QUICK_POWDER": { "QUICK_POWDER": {
"name": "Polvo Veloz", "name": "Polvo veloz",
"description": "Polvo muy fino, pero a la vez poderoso, que aumenta la Velocidad. Debe llevarlo Ditto." "description": "Polvo muy fino, pero a la vez poderoso, que aumenta la Velocidad. Debe llevarlo Ditto."
} }
}, },
@ -413,35 +421,35 @@
"dire_hit": "Crítico X" "dire_hit": "Crítico X"
}, },
"TempBattleStatBoosterStatName": { "TempBattleStatBoosterStatName": {
"ATK": "Attack", "ATK": "Ataque",
"DEF": "Defense", "DEF": "Defensa",
"SPATK": "Sp. Atk", "SPATK": "Ataq. Esp.",
"SPDEF": "Sp. Def", "SPDEF": "Def. Esp.",
"SPD": "Speed", "SPD": "Velocidad",
"ACC": "Accuracy", "ACC": "Precisión",
"CRIT": "Critical Hit Ratio", "CRIT": "Tasa de crítico",
"EVA": "Evasiveness", "EVA": "Evasión",
"DEFAULT": "???" "DEFAULT": "???"
}, },
"AttackTypeBoosterItem": { "AttackTypeBoosterItem": {
"silk_scarf": "Pañuelo Seda", "silk_scarf": "Pañuelo seda",
"black_belt": "Cinturón Negro", "black_belt": "Cinturón negro",
"sharp_beak": "Pico Afilado", "sharp_beak": "Pico afilado",
"poison_barb": "Flecha Venenosa", "poison_barb": "Flecha venenosa",
"soft_sand": "Arena Fina", "soft_sand": "Arena fina",
"hard_stone": "Piedra Dura", "hard_stone": "Piedra dura",
"silver_powder": "Polvo Plata", "silver_powder": "Polvo plata",
"spell_tag": "Hechizo", "spell_tag": "Hechizo",
"metal_coat": "Rev. Metálico", "metal_coat": "Revest. metálico",
"charcoal": "Carbón", "charcoal": "Carbón",
"mystic_water": "Agua Mística", "mystic_water": "Agua mística",
"miracle_seed": "Semilla Milagro", "miracle_seed": "Semilla milagro",
"magnet": "Imán", "magnet": "Imán",
"twisted_spoon": "Cuchara Torcida", "twisted_spoon": "Cuchara torcida",
"never_melt_ice": "Antiderretir", "never_melt_ice": "Antiderretir",
"dragon_fang": "Colmillo Dragón", "dragon_fang": "Colmillo dragón",
"black_glasses": "Gafas de Sol", "black_glasses": "Gafas de sol",
"fairy_feather": "Pluma Hada" "fairy_feather": "Pluma feérica"
}, },
"BaseStatBoosterItem": { "BaseStatBoosterItem": {
"hp_up": "Más PS", "hp_up": "Más PS",
@ -452,38 +460,38 @@
"carbos": "Carburante" "carbos": "Carburante"
}, },
"EvolutionItem": { "EvolutionItem": {
"NONE": "None", "NONE": "Ninguno",
"LINKING_CORD": "Cordón Unión", "LINKING_CORD": "Cordón unión",
"SUN_STONE": "Piedra Solar", "SUN_STONE": "Piedra solar",
"MOON_STONE": "Piedra Lunar", "MOON_STONE": "Piedra lunar",
"LEAF_STONE": "Piedra Hoja", "LEAF_STONE": "Piedra hoja",
"FIRE_STONE": "Piedra Fuego", "FIRE_STONE": "Piedra fuego",
"WATER_STONE": "Piedra Agua", "WATER_STONE": "Piedra agua",
"THUNDER_STONE": "Piedra Trueno", "THUNDER_STONE": "Piedra trueno",
"ICE_STONE": "Piedra Hielo", "ICE_STONE": "Piedra hielo",
"DUSK_STONE": "Piedra Noche", "DUSK_STONE": "Piedra noche",
"DAWN_STONE": "Piedra Alba", "DAWN_STONE": "Piedra alba",
"SHINY_STONE": "Piedra Día", "SHINY_STONE": "Piedra día",
"CRACKED_POT": "Tetera Agrietada", "CRACKED_POT": "Tetera agrietada",
"SWEET_APPLE": "Manzana Dulce", "SWEET_APPLE": "Manzana dulce",
"TART_APPLE": "Manzana Ácida", "TART_APPLE": "Manzana ácida",
"STRAWBERRY_SWEET": "Confite Fresa", "STRAWBERRY_SWEET": "Confite fresa",
"UNREMARKABLE_TEACUP": "Cuenco Mediocre", "UNREMARKABLE_TEACUP": "Cuenco mediocre",
"CHIPPED_POT": "Tetera Rota", "CHIPPED_POT": "Tetera rota",
"BLACK_AUGURITE": "Mineral Negro", "BLACK_AUGURITE": "Mineral negro",
"GALARICA_CUFF": "Brazal Galanuez", "GALARICA_CUFF": "Brazal galanuez",
"GALARICA_WREATH": "Corona Galanuez", "GALARICA_WREATH": "Corona galanuez",
"PEAT_BLOCK": "Bloque de Turba", "PEAT_BLOCK": "Bloque de turba",
"AUSPICIOUS_ARMOR": "Armadura Auspiciosa", "AUSPICIOUS_ARMOR": "Armadura auspiciosa",
"MALICIOUS_ARMOR": "Armadura Maldita", "MALICIOUS_ARMOR": "Armadura maldita",
"MASTERPIECE_TEACUP": "Cuenco Exquisito", "MASTERPIECE_TEACUP": "Cuenco exquisito",
"METAL_ALLOY": "Metal Compuesto", "METAL_ALLOY": "Metal compuesto",
"SCROLL_OF_DARKNESS": "Manuscrito Sombras", "SCROLL_OF_DARKNESS": "Manuscrito sombras",
"SCROLL_OF_WATERS": "Manuscrito Aguas", "SCROLL_OF_WATERS": "Manuscrito aguas",
"SYRUPY_APPLE": "Manzana Melosa" "SYRUPY_APPLE": "Manzana melosa"
}, },
"FormChangeItem": { "FormChangeItem": {
"NONE": "None", "NONE": "Ninguno",
"ABOMASITE": "Abomasnowita", "ABOMASITE": "Abomasnowita",
"ABSOLITE": "Absolita", "ABSOLITE": "Absolita",
"AERODACTYLITE": "Aerodactylita", "AERODACTYLITE": "Aerodactylita",
@ -532,70 +540,70 @@
"SWAMPERTITE": "Swampertita", "SWAMPERTITE": "Swampertita",
"TYRANITARITE": "Tyranitarita", "TYRANITARITE": "Tyranitarita",
"VENUSAURITE": "Venusaurita", "VENUSAURITE": "Venusaurita",
"BLUE_ORB": "Prisma Azul", "BLUE_ORB": "Prisma azul",
"RED_ORB": "Prisma Rojo", "RED_ORB": "Prisma rojo",
"SHARP_METEORITE": "Meteorito Afilado", "SHARP_METEORITE": "Meteorito afilado",
"HARD_METEORITE": "Meteorito Duro", "HARD_METEORITE": "Meteorito duro",
"SMOOTH_METEORITE": "Meteorito Suave", "SMOOTH_METEORITE": "Meteorito suave",
"ADAMANT_CRYSTAL": "Gran Diamansfera", "ADAMANT_CRYSTAL": "Gran diamansfera",
"LUSTROUS_GLOBE": "Gran Lustresfera", "LUSTROUS_GLOBE": "Gran lustresfera",
"GRISEOUS_CORE": "Gran Griseosfera", "GRISEOUS_CORE": "Gran griseosfera",
"REVEAL_GLASS": "Espejo Veraz", "REVEAL_GLASS": "Espejo veraz",
"GRACIDEA": "Gracídea", "GRACIDEA": "Gracídea",
"MAX_MUSHROOMS": "MaxiSetas", "MAX_MUSHROOMS": "Maxisetas",
"DARK_STONE": "Piedra Oscura", "DARK_STONE": "Orbe oscuro",
"LIGHT_STONE": "Piedra Luminosa", "LIGHT_STONE": "Orbe claro",
"PRISON_BOTTLE": "Vasija Castigo", "PRISON_BOTTLE": "Vasija castigo",
"N_LUNARIZER": "Necroluna", "N_LUNARIZER": "Necroluna",
"N_SOLARIZER": "Necrosol", "N_SOLARIZER": "Necrosol",
"RUSTED_SWORD": "Espada Oxidada", "RUSTED_SWORD": "Espada oxidada",
"RUSTED_SHIELD": "Escudo Oxidado", "RUSTED_SHIELD": "Escudo oxidado",
"ICY_REINS_OF_UNITY": "Riendas Unión Heladas", "ICY_REINS_OF_UNITY": "Riendas unión heladas",
"SHADOW_REINS_OF_UNITY": "Riendas Unión Oscuras", "SHADOW_REINS_OF_UNITY": "Riendas unión oscuras",
"WELLSPRING_MASK": "Máscara Fuente", "WELLSPRING_MASK": "Máscara fuente",
"HEARTHFLAME_MASK": "Máscara Horno", "HEARTHFLAME_MASK": "Máscara horno",
"CORNERSTONE_MASK": "Máscara Cimiento", "CORNERSTONE_MASK": "Máscara cimiento",
"SHOCK_DRIVE": "FulgoROM", "SHOCK_DRIVE": "FulgoROM",
"BURN_DRIVE": "PiroROM", "BURN_DRIVE": "PiroROM",
"CHILL_DRIVE": "CrioROM", "CHILL_DRIVE": "CrioROM",
"DOUSE_DRIVE": "HidroROM", "DOUSE_DRIVE": "HidroROM",
"ULTRANECROZIUM_Z": "Ultranecrostal Z", "ULTRANECROZIUM_Z": "Ultranecrostal Z",
"FIST_PLATE": "Tabla Fuerte", "FIST_PLATE": "Tabla fuerte",
"SKY_PLATE": "Tabla Cielo", "SKY_PLATE": "Tabla cielo",
"TOXIC_PLATE": "Tabla Tóxica", "TOXIC_PLATE": "Tabla tóxica",
"EARTH_PLATE": "Tabla Terrax", "EARTH_PLATE": "Tabla terrax",
"STONE_PLATE": "Tabla Pétrea", "STONE_PLATE": "Tabla pétrea",
"INSECT_PLATE": "Tabla Bicho", "INSECT_PLATE": "Tabla bicho",
"SPOOKY_PLATE": "Tabla Terror", "SPOOKY_PLATE": "Tabla terror",
"IRON_PLATE": "Tabla Acero", "IRON_PLATE": "Tabla acero",
"FLAME_PLATE": "Tabla Llama", "FLAME_PLATE": "Tabla llama",
"SPLASH_PLATE": "Tabla Linfa", "SPLASH_PLATE": "Tabla linfa",
"MEADOW_PLATE": "Tabla Pradal", "MEADOW_PLATE": "Tabla pradal",
"ZAP_PLATE": "Tabla Trueno", "ZAP_PLATE": "Tabla trueno",
"MIND_PLATE": "Tabla Mental", "MIND_PLATE": "Tabla mental",
"ICICLE_PLATE": "Tabla Helada", "ICICLE_PLATE": "Tabla helada",
"DRACO_PLATE": "Tabla Draco", "DRACO_PLATE": "Tabla draco",
"DREAD_PLATE": "Tabla Oscura", "DREAD_PLATE": "Tabla oscura",
"PIXIE_PLATE": "Tabla Duende", "PIXIE_PLATE": "Tabla duende",
"BLANK_PLATE": "Tabla Neutra", "BLANK_PLATE": "Tabla neutra",
"LEGEND_PLATE": "Tabla Legendaria", "LEGEND_PLATE": "Tabla legendaria",
"FIGHTING_MEMORY": "Disco Lucha", "FIGHTING_MEMORY": "Disco lucha",
"FLYING_MEMORY": "Disco Volador", "FLYING_MEMORY": "Disco volador",
"POISON_MEMORY": "Disco Veneno", "POISON_MEMORY": "Disco veneno",
"GROUND_MEMORY": "Disco Tierra", "GROUND_MEMORY": "Disco tierra",
"ROCK_MEMORY": "Disco Roca", "ROCK_MEMORY": "Disco roca",
"BUG_MEMORY": "Disco Bicho", "BUG_MEMORY": "Disco bicho",
"GHOST_MEMORY": "Disco Fantasma", "GHOST_MEMORY": "Disco fantasma",
"STEEL_MEMORY": "Disco Acero", "STEEL_MEMORY": "Disco acero",
"FIRE_MEMORY": "Disco Fuego", "FIRE_MEMORY": "Disco fuego",
"WATER_MEMORY": "Disco Agua", "WATER_MEMORY": "Disco agua",
"GRASS_MEMORY": "Disco Planta", "GRASS_MEMORY": "Disco planta",
"ELECTRIC_MEMORY": "Disco Eléctrico", "ELECTRIC_MEMORY": "Disco eléctrico",
"PSYCHIC_MEMORY": "Disco Psíquico", "PSYCHIC_MEMORY": "Disco psíquico",
"ICE_MEMORY": "Disco Hielo", "ICE_MEMORY": "Disco hielo",
"DRAGON_MEMORY": "Disco Dragón", "DRAGON_MEMORY": "Disco dragón",
"DARK_MEMORY": "Disco Siniestro", "DARK_MEMORY": "Disco siniestro",
"FAIRY_MEMORY": "Disco Hada", "FAIRY_MEMORY": "Disco hada",
"BLANK_MEMORY": "Disco Blanco" "BLANK_MEMORY": "Disco en blanco"
} }
} }

View File

@ -3807,4 +3807,4 @@
"name": "Cadena Virulenta", "name": "Cadena Virulenta",
"effect": "Apresa al objetivo con una cadena hecha de ponzoña que le inocula toxinas para minarle las fuerzas. Puede envenenar gravemente." "effect": "Apresa al objetivo con una cadena hecha de ponzoña que le inocula toxinas para minarle las fuerzas. Puede envenenar gravemente."
} }
} }

View File

@ -12,7 +12,7 @@
"typeImmunityHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", "typeImmunityHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !",
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} évite\nles dégâts avec {{abilityName}} !", "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} évite\nles dégâts avec {{abilityName}} !",
"disguiseAvoidedDamage": "Le déguisement de {{pokemonNameWithAffix}}\ntombe !", "disguiseAvoidedDamage": "Le déguisement de {{pokemonNameWithAffix}}\ntombe !",
"moveImmunity": "Ça n'affecte pas {{pokemonNameWithAffix}}…", "moveImmunity": "Ça naffecte pas {{pokemonNameWithAffix}}…",
"reverseDrain": "{{pokemonNameWithAffix}} aspire\nle suintement !", "reverseDrain": "{{pokemonNameWithAffix}} aspire\nle suintement !",
"postDefendTypeChange": "{{abilityName}} de {{pokemonNameWithAffix}}\nle transforme en type {{typeName}} !", "postDefendTypeChange": "{{abilityName}} de {{pokemonNameWithAffix}}\nle transforme en type {{typeName}} !",
"postDefendContactDamage": "{{pokemonNameWithAffix}} est blessé\npar son talent {{abilityName}} !", "postDefendContactDamage": "{{pokemonNameWithAffix}} est blessé\npar son talent {{abilityName}} !",
@ -23,7 +23,7 @@
"postAttackStealHeldItem": "{{pokemonNameWithAffix}} vole\nlobjet {{stolenItemType}} de {{defenderName}} !", "postAttackStealHeldItem": "{{pokemonNameWithAffix}} vole\nlobjet {{stolenItemType}} de {{defenderName}} !",
"postDefendStealHeldItem": "{{pokemonNameWithAffix}} vole\nlobjet {{stolenItemType}} de {{attackerName}} !", "postDefendStealHeldItem": "{{pokemonNameWithAffix}} vole\nlobjet {{stolenItemType}} de {{attackerName}} !",
"copyFaintedAllyAbility": "{{pokemonNameWithAffix}} reçoit\nle talent {{abilityName}} !", "copyFaintedAllyAbility": "{{pokemonNameWithAffix}} reçoit\nle talent {{abilityName}} !",
"intimidateImmunity": "{{abilityName}} de {{pokemonNameWithAffix}}\nlempêche d'être intimidé !", "intimidateImmunity": "{{abilityName}} de {{pokemonNameWithAffix}}\nlempêche dêtre intimidé !",
"postSummonAllyHeal": "{{pokemonNameWithAffix}} boit le thé\npréparé par {{pokemonName}} !", "postSummonAllyHeal": "{{pokemonNameWithAffix}} boit le thé\npréparé par {{pokemonName}} !",
"postSummonClearAllyStats": "Les stats de {{pokemonNameWithAffix}}\nsont revenues à la normale!", "postSummonClearAllyStats": "Les stats de {{pokemonNameWithAffix}}\nsont revenues à la normale!",
"postSummonTransform": "{{pokemonNameWithAffix}} prend\nlapparence de {{targetName}} !", "postSummonTransform": "{{pokemonNameWithAffix}} prend\nlapparence de {{targetName}} !",
@ -59,4 +59,4 @@
"postSummonTabletsOfRuin": "Le Bois du Fléau de {{pokemonNameWithAffix}}\naffaiblit l{{statName}} des Pokémon alentour !", "postSummonTabletsOfRuin": "Le Bois du Fléau de {{pokemonNameWithAffix}}\naffaiblit l{{statName}} des Pokémon alentour !",
"postSummonBeadsOfRuin": "Les Perles du Fléau de {{pokemonNameWithAffix}}\naffaiblissent la {{statName}} des Pokémon alentour !", "postSummonBeadsOfRuin": "Les Perles du Fléau de {{pokemonNameWithAffix}}\naffaiblissent la {{statName}} des Pokémon alentour !",
"preventBerryUse": "{{pokemonNameWithAffix}} est tendu\net ne peut plus manger de Baies !" "preventBerryUse": "{{pokemonNameWithAffix}} est tendu\net ne peut plus manger de Baies !"
} }

View File

@ -469,11 +469,11 @@
}, },
"honeyGather": { "honeyGather": {
"name": "Cherche Miel", "name": "Cherche Miel",
"description": "The Pokémon gathers Honey after a battle. The Honey is then sold for money." "description": "Le Pokémon trouve du Miel après un combat et est directement revendu contre de largent."
}, },
"frisk": { "frisk": {
"name": "Fouille", "name": "Fouille",
"description": "Lorsqu'il entre en combat, le Pokémon peut vérifier la capacité d'un Pokémon adverse." "description": "Lorsquil entre en combat, le Pokémon peut vérifier la capacité dun Pokémon adverse."
}, },
"reckless": { "reckless": {
"name": "Téméraire", "name": "Téméraire",
@ -1239,4 +1239,4 @@
"name": "Emprise Toxique", "name": "Emprise Toxique",
"description": "Lorsque Pêchaminus empoisonne un Pokémon grâce à lune de ses capacités, ce dernier devient également confus." "description": "Lorsque Pêchaminus empoisonne un Pokémon grâce à lune de ses capacités, ce dernier devient également confus."
} }
} }

View File

@ -62,7 +62,7 @@
"name": "Caïd" "name": "Caïd"
}, },
"HealAchv": { "HealAchv": {
"description": "Soigner {{healAmount}} {{HP}} en une fois avec une capacité, un talent ou un objet tenu." "description": "Soigner {{healAmount}} {{HP}} en une fois avec une capacité,\nun talent ou un objet tenu."
}, },
"1000_HEAL": { "1000_HEAL": {
"name": "Médecin" "name": "Médecin"
@ -261,4 +261,4 @@
"name": "Du premier coup !", "name": "Du premier coup !",
"description": "Terminer un challenge « Nouveau départ »." "description": "Terminer un challenge « Nouveau départ »."
} }
} }

View File

@ -36,7 +36,7 @@
"name": "One Punch Man" "name": "One Punch Man"
}, },
"HealAchv": { "HealAchv": {
"description": "Soigner {{healAmount}} {{HP}} en une fois avec une capacité, un talent ou un objet tenu." "description": "Soigner {{healAmount}} {{HP}} en une fois avec une capacité,\nun talent ou un objet tenu."
}, },
"250_HEAL": { "250_HEAL": {
"name": "Infirmier" "name": "Infirmier"
@ -261,4 +261,4 @@
"name": "Du premier coup !", "name": "Du premier coup !",
"description": "Terminer un challenge « Nouveau départ »." "description": "Terminer un challenge « Nouveau départ »."
} }
} }

View File

@ -1,3 +1,3 @@
{ {
"generation": "Génération {{generation}}" "generation": "{{generation}}"
} }

View File

@ -1,5 +1,5 @@
{ {
"music": "Musique : ", "music": " : ",
"missing_entries": "{{name}}", "missing_entries": "{{name}}",
"battle_kanto_champion": "N2B2 - Vs. Maitre de Kanto", "battle_kanto_champion": "N2B2 - Vs. Maitre de Kanto",
"battle_johto_champion": "N2B2 - Vs. Maitre de Johto", "battle_johto_champion": "N2B2 - Vs. Maitre de Johto",
@ -83,41 +83,41 @@
"battle_galactic_boss": "DÉPS - Vs. Hélio", "battle_galactic_boss": "DÉPS - Vs. Hélio",
"battle_plasma_boss": "N2B2 - Vs. Ghetis", "battle_plasma_boss": "N2B2 - Vs. Ghetis",
"battle_flare_boss": "XY - Vs. Lysandre", "battle_flare_boss": "XY - Vs. Lysandre",
"abyss": "PDM EdS - Cratère Obscur", "abyss": "PDM EdC - Cratère Obscur",
"badlands": "PDM EdS - Vallée Stérile", "badlands": "PDM EdC - Vallée Stérile",
"beach": "PDM EdS - Falaise Trempée", "beach": "PDM EdC - Falaise Trempée",
"cave": "PDM EdS - Pic Céleste (grotte)", "cave": "PDM EdC - Pic Céleste (grotte)",
"construction_site": "PDM EdS - Carrière Rocher", "construction_site": "PDM EdC - Carrière Rocher",
"desert": "PDM EdS - Désert du Nord", "desert": "PDM EdC - Désert du Nord",
"dojo": "PDM EdS - Dojo Ossatueur", "dojo": "PDM EdC - Dojo Ossatueur",
"end": "PDM EdS - Tour Céleste", "end": "PDM EdC - Tour Céleste",
"factory": "PDM EdS - Ruines Cachées", "factory": "PDM EdC - Ruines Cachées",
"fairy_cave": "PDM EdS - Caverne Étoile", "fairy_cave": "PDM EdC - Caverne Étoile",
"forest": "PDM EdS - Forêt Crépuscule", "forest": "PDM EdC - Forêt Crépuscule",
"grass": "PDM EdS - Bois aux Pommes", "grass": "PDM EdC - Bois aux Pommes",
"graveyard": "PDM EdS - Forêt Trompeuse", "graveyard": "PDM EdC - Forêt Trompeuse",
"ice_cave": "PDM EdS - Montagne Glacier", "ice_cave": "PDM EdC - Montagne Glacier",
"island": "PDM EdS - Côte Escarpée", "island": "PDM EdC - Côte Escarpée",
"jungle": "Lmz - Jungle", "jungle": "Lmz - Jungle",
"laboratory": "Firel - Laboratory", "laboratory": "Firel - Laboratory",
"lake": "PDM EdS - Caverne Cristal", "lake": "PDM EdC - Caverne Cristal",
"meadow": "PDM EdS - Pic Céleste (forêt)", "meadow": "PDM EdC - Pic Céleste (forêt)",
"metropolis": "Firel - Metropolis", "metropolis": "Firel - Metropolis",
"mountain": "PDM EdS - Mt Corne", "mountain": "PDM EdC - Mont Corne",
"plains": "PDM EdS - Pic Céleste (prairie)", "plains": "PDM EdC - Pic Céleste (prairie)",
"power_plant": "PDM EdS - Plaines Élek", "power_plant": "PDM EdC - Plaines Élek",
"ruins": "PDM EdS - Ruine Scellée", "ruins": "PDM EdC - Ruine Scellée",
"sea": "Andr06 - Marine Mystique", "sea": "Andr06 - Marine Mystique",
"seabed": "Firel - Seabed", "seabed": "Firel - Seabed",
"slum": "Andr06 - Sneaky Snom", "slum": "Andr06 - Sneaky Snom",
"snowy_forest": "PDM EdS - Pic Céleste (plaine enneigée)", "snowy_forest": "PDM EdC - Pic Céleste (plaine enneigée)",
"space": "Firel - Aether", "space": "Firel - Aether",
"swamp": "PDM EdS - Mer Fermée", "swamp": "PDM EdC - Mer Fermée",
"tall_grass": "PDM EdS - Forêt Brumeuse", "tall_grass": "PDM EdC - Forêt Brumeuse",
"temple": "PDM EdS - Grotte Égide", "temple": "PDM EdC - Grotte Égide",
"town": "PDM EdS - Donjon aléatoire - Thème 3", "town": "PDM EdC - Donjon aléatoire - Thème 3",
"volcano": "PDM EdS - Grotte Étuve", "volcano": "PDM EdC - Grotte Étuve",
"wasteland": "PDM EdS - Terres Illusoires", "wasteland": "PDM EdC - Terres Illusoires",
"encounter_ace_trainer": "NB - Regards croisés (Topdresseur·euse)", "encounter_ace_trainer": "NB - Regards croisés (Topdresseur·euse)",
"encounter_backpacker": "NB - Regards croisés (Randonneur·euse)", "encounter_backpacker": "NB - Regards croisés (Randonneur·euse)",
"encounter_clerk": "NB - Regards croisés (Employé·e)", "encounter_clerk": "NB - Regards croisés (Employé·e)",
@ -133,6 +133,6 @@
"encounter_twins": "NB - Regards croisés (Jumelles)", "encounter_twins": "NB - Regards croisés (Jumelles)",
"encounter_youngster": "NB - Regards croisés (Gamin)", "encounter_youngster": "NB - Regards croisés (Gamin)",
"heal": "NB - Soin de Pokémon", "heal": "NB - Soin de Pokémon",
"menu": "PDM EdS - Bienvenue dans le monde de Pokémon !", "menu": "PDM EdC - Bienvenue dans le monde de Pokémon !",
"title": "PDM EdS - Menu Principal" "title": "PDM EdC - Menu Principal"
} }

View File

@ -1,7 +1,7 @@
{ {
"blue_red_double": { "blue_red_double": {
"encounter": { "encounter": {
"1": "Blue : Hé Red, montrons-leur de quel bois on se chauffe !\n$Red : …\n$Blue : Voilà la puissance du Bourg Palette !" "1": "Blue : Hé Red, montrons-lui de quel bois on se chauffe !\n$Red : …\n$Blue : Voilà la puissance du Bourg Palette !"
}, },
"victory": { "victory": {
"1": "Blue : Cétait un magnifique combat !\n$Red : …" "1": "Blue : Cétait un magnifique combat !\n$Red : …"
@ -79,4 +79,4 @@
"1": "Peterson : Ça cest du rock !\n$Rosemary : Frérot…" "1": "Peterson : Ça cest du rock !\n$Rosemary : Frérot…"
} }
} }
} }

View File

@ -1,7 +1,7 @@
{ {
"blue_red_double": { "blue_red_double": {
"encounter": { "encounter": {
"1": "Blue : Hé Red, montrons-leur de quel bois on se chauffe !\n$Red : …\n$Blue : Voilà la puissance du Bourg Palette !" "1": "Blue : Hé Red, montrons-lui de quel bois on se chauffe !\n$Red : …\n$Blue : Voilà la puissance du Bourg Palette !"
}, },
"victory": { "victory": {
"1": "Blue : Cétait un magnifique combat !\n$Red : …" "1": "Blue : Cétait un magnifique combat !\n$Red : …"
@ -79,4 +79,4 @@
"1": "Peterson : Ça cest du rock !\n$Rosemary : Frérot…" "1": "Peterson : Ça cest du rock !\n$Rosemary : Frérot…"
} }
} }
} }

View File

@ -38,7 +38,7 @@
"3": "Je te connais pas. Ça te dis de te battre ?", "3": "Je te connais pas. Ça te dis de te battre ?",
"4": "Prenons du bon temps avec ce combat Pokémon !", "4": "Prenons du bon temps avec ce combat Pokémon !",
"5": "Je vais tapprendre à te battre avec tes Pokémon !", "5": "Je vais tapprendre à te battre avec tes Pokémon !",
"6": "Un combat doit être pris au sérieux. Tes prête à te battre ?", "6": "Un combat doit toujours être pris au sérieux.\nTes prête à te battre ?",
"7": "Tu seras pas jeune éternellement. Tas quune chance pendant un combat. Bientôt, tu seras plus quun souvenir.", "7": "Tu seras pas jeune éternellement. Tas quune chance pendant un combat. Bientôt, tu seras plus quun souvenir.",
"8": "Tu ferais mieux dy aller doucement avec moi. Mais je vais me battre sérieusement !", "8": "Tu ferais mieux dy aller doucement avec moi. Mais je vais me battre sérieusement !",
"9": "Je mennuie à lécole. Ya rien à y faire. *Baille*\nJe me bats juste pour passer le temps." "9": "Je mennuie à lécole. Ya rien à y faire. *Baille*\nJe me bats juste pour passer le temps."
@ -69,7 +69,7 @@
"defeat": { "defeat": {
"1": "Tu ne devrais pas ténerver sur tes Pokémon, même après une défaite.", "1": "Tu ne devrais pas ténerver sur tes Pokémon, même après une défaite.",
"2": "Alors ? Pas mal mes Pokémon, hein ? Je suis fait pour ça.", "2": "Alors ? Pas mal mes Pokémon, hein ? Je suis fait pour ça.",
"3": "Peut importe à quel point taimes tes Pokémon, il faut toujours de la discipline sils se comportent mal." "3": "Peu importe à quel point taimes tes Pokémon, il faut toujours de la discipline sils se comportent mal."
} }
}, },
"breeder_female": { "breeder_female": {
@ -148,7 +148,7 @@
}, },
"victory": { "victory": {
"1": "Très bien… Tas de bons Pokémon…", "1": "Très bien… Tas de bons Pokémon…",
"2": "Quoi ?! Mais c'est moi le génie des combats !", "2": "Quoi ?! Mais cest moi le génie des combats !",
"3": "Évidemment que tes le personnage principal !", "3": "Évidemment que tes le personnage principal !",
"4": "OK ! OK ! Tu pourrais être une Topdresseuse !" "4": "OK ! OK ! Tu pourrais être une Topdresseuse !"
}, },
@ -169,50 +169,98 @@
}, },
"rocket_grunt": { "rocket_grunt": {
"encounter": { "encounter": {
"1": "Nous sommes de retour !" "1": "Nous sommes de retour !",
"2": "Ça bosse dur, ici ! Alors du balai !",
"3": "File-nous tes Pokémon ou tu vas gouter à la colère de la Team Rocket !",
"4": "Sois témoin de ce quest une vraie terreur de la Team Rocket!",
"5": "Hé gamine ! Moi être guy member of la Team Rocket !"
}, },
"victory": { "victory": {
"1": "Une fois de plus la Team Rocket senvole vers dautres cieux !" "1": "Une fois de plus la Team Rocket senvole vers dautres cieux !",
"2": "Mince! Jai laissé tomber\nla Clé Ascenseur !",
"3": "Jai tout foiré !",
"4": "Mes compagnons vont me venger !",
"5": "Toi dire quoi ? Forget que tu mas vu !\nYou nas rien seen !"
} }
}, },
"magma_grunt": { "magma_grunt": {
"encounter": { "encounter": {
"1": "Nespère pas recevoir de la pitié si tu te mets sur le chemin de la Team Magma !" "1": "Nespère pas recevoir de la pitié si tu te mets sur le chemin de la Team Magma !",
"2": "Ne te mêle pas de nos affaires ! On va rendre ce monde meilleur !",
"3": "Hors de mon chemin ! La Team Magma na pas de temps pour les gamins !",
"4": "Jespère que tas quelques marshmallows, car ça va chauffer !",
"5": "On va utiliser le puissance dun volcan ! Ça va être… explosif ! Tu las… ? Héhé !"
}, },
"victory": { "victory": {
"1": "Je…?\nJai perdu ?!" "1": "Je…?\nJai perdu ?!",
"2": "Je peux pas croire que jai pas pris mon déjeuner juste pour ça…",
"3": "Impossible ! Tes quune gosse !",
"4": "Aahhh…\nJaurais dû directement rentrer à la planque…",
"5": "Tu mas démoli… Tu crois que le boss va suspendre mon salaire ?"
} }
}, },
"aqua_grunt": { "aqua_grunt": {
"encounter": { "encounter": {
"1": "Aucune pitié si tu te mets sur le chemin de la Team Aqua, même pour une gamine !" "1": "Aucune pitié si tu te mets sur le chemin de la Team Aqua, même pour un gamin !",
"2": "Grrr…\nTu as eu le culot de topposer à la Team Aqua !",
"3": "Je vais te liquéfier !\nEt ce sera pas quà cause des mes Pokémon Eau !",
"4": "Nous, la Team Aqua, existons pour le bien commun !",
"5": "Prépare-toi à te faire emporter par le courant de…\nEuh… Mes Pokémon ! Oui, mes Pokémon !"
}, },
"victory": { "victory": {
"1": "Comment ça ?" "1": "Comment ça ?",
"2": "Ah, javais pas prévu dêtre gêné par un mouflet qui se mêle de tout !",
"3": "Jai perdu ?! Super, jai plus quà nager jusquà la planque maintenant…",
"4": "Oh non quelle angoisse…\nLe boss va me démonter…",
"5": "Je suis battu… Tu penses que le boss va me faire subir le supplice de la planche ?…"
} }
}, },
"galactic_grunt": { "galactic_grunt": {
"encounter": { "encounter": {
"1": "Ne te mets pas en travers de la Team Galaxie !" "1": "Ne te mets pas en travers de la Team Galaxie !",
"2": "Sois témoin de la puissance de notre technologie et du futur qui se profile !",
"3": "Au nom de la Team Galaxie, jéliminerai quiconque se mettera sur notre route !",
"4": "Prépare ta défaite !",
"5": "Jespère que tes prête à te prendre une raclée de lespace !"
}, },
"victory": { "victory": {
"1": "Désactivation…" "1": "Désactivation…",
"2": "Cet échec nest quune poussière face à nos ambitions débordantes.",
"3": "Notre projet est bien plus important que cette défaite.",
"4": "Comment ?!",
"5": "Note à moi-même :\nMentrainer aux combats Pokémon. Ça urge…"
} }
}, },
"plasma_grunt": { "plasma_grunt": {
"encounter": { "encounter": {
"1": "Pas de quatiers à ceux qui ne suivent pas notre idéal !" "1": "Pas de quatiers à ceux qui ne suivent pas notre idéal !",
"2": "Si je gagne, tu relâches tous tes Pokémon !",
"3": "Si tu te mets en travers de la Team Plasma, je moccuperai de toi personnellement !",
"4": "La Team Plasma va libérer les Pokémon de tous les humains égoïstes dans ton genre !",
"5": "Nos coupes sont lunaires… Mais en combat ?\nTu vas vite le découvrir."
}, },
"victory": { "victory": {
"1": "Plasmaaaaaaaaa !" "1": "Plasmaaaaaaaaa !",
"2": "Comment ai-je pu perdre…",
"3": "… Ce Pokémon est nul, jvais aller en voler de meilleurs !",
"4": "Les plans ambitieux connaissent toujours leurs lots dinterruptions.",
"5": "Cest mauvais… MAUVAIS MAUVAIS MAUVAIS MAUVAIS !\nVa falloir battre en retraite, cest la méga cata !"
} }
}, },
"flare_grunt": { "flare_grunt": {
"encounter": { "encounter": {
"1": "Le style et le bon gout, il ny a que ça qui compte !" "1": "Tes Pokémon ne sont pas dignes de lélégance de la Team Flare.",
"2": "Tas des lunettes de soleil jespère ?\nCar prépare-toi à être éblouie !",
"3": "La Team Flare va purifier ce monde de toute imperfection !",
"4": "Prépare-toi à découvrir lindiscutable sens du style de la Team Flare !",
"5": "La mode, cest important !"
}, },
"victory": { "victory": {
"1": "Mon futur me semble guère radieux." "1": "Mon futur na pas lair si radieux.",
"2": "Les combats semblent être plus complexes que je le pensais.\nRetour aux planches à dessin.",
"3": "Ehhhh ?! Jai perdu ?!",
"4": "Même dans la défaite, lélégance de la Team Flare continue de rayonner sur ce monde.",
"5": "Jappelle pas ça perdre, jappelle ça échouer avec panache !"
} }
}, },
"rocket_boss_giovanni_1": { "rocket_boss_giovanni_1": {
@ -223,7 +271,7 @@
"1": "QUOI ? IMPOSSIBLE !" "1": "QUOI ? IMPOSSIBLE !"
}, },
"defeat": { "defeat": {
"1": "Retiens bien. Ton incapacité à évaluer ta propre force est\nla démonstration claire que tu n'es encore quune gamine." "1": "Retiens bien. Ton incapacité à évaluer ta propre force est\nla démonstration claire que tu nes encore quune gamine."
} }
}, },
"rocket_boss_giovanni_2": { "rocket_boss_giovanni_2": {
@ -336,6 +384,77 @@
"1": "Les Pokémon… Ne devraient plus exister." "1": "Les Pokémon… Ne devraient plus exister."
} }
}, },
"brock": {
"encounter": {
"1": "Mon expertise des types Roche va te mettre au sol ! En garde !",
"2": "Tu veux toujours te battre avec moi ? Même en sachant que tu vas perdre ?",
"3": "Laisse-moi de montrer la véritable force de mes Pokémon Roche !"
},
"victory": {
"1": "Jétais trop sûr de moi, cest pour ça que jai perdu.",
"2": "Ce monde est vaste ! Je suis honoré davoir pu taffronter.",
"3": "Peut-être bien que je naurais pas dû abandonner ma vocation dÉleveur…"
},
"defeat": {
"1": "La défense est la meilleure des attaques !\nTelle est ma méthode !",
"2": "Viens étudier des roches avec moi la prochaine fois si tu veux apprendre à mieux les aborder !",
"3": "Tout ce temps à voyager autour du monde paie enfin !"
}
},
"misty": {
"encounter": {
"1": "Ma tactique ? Attaquer avec des Pokémon Eau !",
"2": "Je vais te prouver le tsunami que sont mes Pokémon aquatiques !",
"3": "Mon rêve, cétait de voyager et de défier des Dresseurs super forts. Seras-tu à la hauteur ?"
},
"victory": {
"1": "OK. Tes pas naze… Je le reconnais…",
"2": "Pfff… Tas juste eu de la chance hein ?!",
"3": "Ouah ! Tes super balèze !"
},
"defeat": {
"1": "Quen dis-tu? Cest ça, la puissance des Pokémon Eau !",
"2": "Jespère que tas pris note des élégantes techniques de nage de mes Pokémon !",
"3": "Tes Pokémon ne jouent visiblement pas dans le même bassin…"
}
},
"lt_surge": {
"encounter": {
"1": "Tas pas froid aux yeux, soldat ! Les combats Pokémon, cest la guerre !",
"2": "Tu as du guts pour venir me fight ici ! Je vais te shock !",
"3": "Compte tes dents, tu vas morfler !\nMes Pokémon Électrik vont tatomiser !"
},
"victory": {
"1": "Whoo ! Tiras loin toi.",
"2": "Oh noes ! Mes tricks électriques sont à plat…\nYou are very fortiche!",
"3": "Tu es very costaud ! Je vais training very dur mes Pokémon, moi too, et on sera Number One !"
},
"defeat": {
"1": "Oh yeah !\nMes Pokémon Électrik sont les best du monde !",
"2": "Oh yeah, baby ! I am trop fort !",
"3": "Une combat Pokémon, cest comme une guerre et tas eu droit à une bataille de premier ordre !"
}
},
"erika": {
"encounter": {
"1": "Il fait beau, aujourdhui, nest-ce pas… ?\nQuoi un combat… ? Très bien…",
"2": "Larrangement floral est ma spécialité, et mes Pokémon sont de type Plante. Quoi ? Tu veux te battre ?",
"3": "Il fait beau… Le soleil brille… Les plantes bourgeonnent… Je mennuie…",
"4": "Voir un tel jardin rempli de fleurs est si apaisant…"
},
"victory": {
"1": "Bien joué, cest mértié.",
"2": "Dommage, on samusait si bien…",
"3": "Oh non, le combat est terminé…",
"4": "Aaah, ça fait du bien !\nMerci, jen avais besoin."
},
"defeat": {
"1": "Jai failli mendormir…",
"2": "Oh non… Mes Pokémon Plante ont lair de tavoir bien endormie…",
"3": "Ce combat était si apaisant…",
"4": "Oh non… Cest tout ?"
}
},
"flare_boss_lysandre_2": { "flare_boss_lysandre_2": {
"encounter": { "encounter": {
"1": "Ton futur ou le mien…\nVoyons lequel mérite plus daboutir." "1": "Ton futur ou le mien…\nVoyons lequel mérite plus daboutir."
@ -349,7 +468,7 @@
}, },
"rival": { "rival": {
"encounter": { "encounter": {
"1": "@c{smile}Ah, je te cherchais ! Je savais que tétais pressée de partir, mais je mattendais quand même à un au revoir…\n$@c{smile_eclosed}Tas finalement décidé de réaliser ton rêve ?\nJai peine à y croire.\n$@c{serious_smile_fists}Vu que tes là, ça te dis un petit combat ?\nJe voudrais quand même massurer que tes prête.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que tas !" "1": "@c{smile}Ah, te voilà ! Je tai cherchée partout ! Je savais que tétais pressée de partir, mais je mattendais quand même à un au revoir…\n$@c{smile_eclosed}Tas finalement décidé de réaliser ton rêve ?\nJai peine à y croire.\n$@c{serious_smile_fists}Vu que tes là, ça te dis un petit combat ?\nJe voudrais quand même massurer que tes prête.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que tas !"
}, },
"victory": { "victory": {
"1": "@c{shock}Wah… Tu mas vraiment lavé.\nTes vraiment une débutante ?\n$@c{smile}Tas peut-être eu de la chance, mais…\nPeut-être que tarriveras jusquau bout du chemin.\n$Dailleurs, le prof ma demandé de te filer ces objets.\nIls ont lair sympas.\n$@c{serious_smile_fists}Bonne chance à toi !" "1": "@c{shock}Wah… Tu mas vraiment lavé.\nTes vraiment une débutante ?\n$@c{smile}Tas peut-être eu de la chance, mais…\nPeut-être que tarriveras jusquau bout du chemin.\n$Dailleurs, le prof ma demandé de te filer ces objets.\nIls ont lair sympas.\n$@c{serious_smile_fists}Bonne chance à toi !"
@ -441,7 +560,7 @@
}, },
"rival_6": { "rival_6": {
"encounter": { "encounter": {
"1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}Jai eu du temps pour réfléchir à tout ça.\nIl y a une raison à pourquoi tout semble étrange.\n$@c{neutral_eclosed}Ton rêve, ma volonté de te battre…\nFont partie de quelque chose de plus grand.\n$@c{serious}Cest même pas à propos de moi, ni de toi… Mais du monde, @c{serious_mhalf_fists}et te repousser dans tes limites est ma mission.\n$@c{neutral_eclosed}Jignore si je serai capable de laccomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il ma lair familier, comme si jy avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et cest comme si quelque chose ici me parlait.\n$Comme si cétait tout ce que ce monde avait toujours connu.\n$Ces précieux moments ensemble semblent si proches ne sont rien de plus quun lointain souvenir.\n$@c{neutral_eclosed}Dailleurs, qui peut dire aujourdhui quils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu tarrêtes, ça n'aura jamais de fin et tes la seule à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que cest la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens à pas me battre ici et maintenant, tu nas aucune chance." "1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}Jai eu du temps pour réfléchir à tout ça.\nIl y a une raison à pourquoi tout semble étrange.\n$@c{neutral_eclosed}Ton rêve, ma volonté de te battre…\nFont partie de quelque chose de plus grand.\n$@c{serious}Cest même pas à propos de moi, ni de toi… Mais du monde, @c{serious_mhalf_fists}et te repousser dans tes limites est ma mission.\n$@c{neutral_eclosed}Jignore si je serai capable de laccomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il ma lair familier, comme si jy avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et cest comme si quelque chose ici me parlait.\n$Comme si cétait tout ce que ce monde avait toujours connu.\n$Ces précieux moments ensemble semblent si proches ne sont rien de plus quun lointain souvenir.\n$@c{neutral_eclosed}Dailleurs, qui peut dire aujourdhui quils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu tarrêtes, ça naura jamais de fin et tes la seule à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que cest la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens à pas me battre ici et maintenant, tu nas aucune chance."
}, },
"victory": { "victory": {
"1": "@c{smile_eclosed}Jai fait ce que javais à faire.\n$Promets-moi juste une chose.\n@c{smile}Après avoir réparé ce monde… Rentre à la maison." "1": "@c{smile_eclosed}Jai fait ce que javais à faire.\n$Promets-moi juste une chose.\n@c{smile}Après avoir réparé ce monde… Rentre à la maison."
@ -455,4 +574,4 @@
"1": "@c{smile_ehalf}Je… Je crois que jai rempli ma mission…\n$@c{smile_eclosed}Promets-moi… Après avoir réparé ce monde… Reviens à la maison saine et sauve.\n$@c{smile_ehalf}… Merci." "1": "@c{smile_ehalf}Je… Je crois que jai rempli ma mission…\n$@c{smile_eclosed}Promets-moi… Après avoir réparé ce monde… Reviens à la maison saine et sauve.\n$@c{smile_ehalf}… Merci."
} }
} }
} }

View File

@ -38,7 +38,7 @@
"3": "Je te connais pas. Ça te dis de te battre ?", "3": "Je te connais pas. Ça te dis de te battre ?",
"4": "Prenons du bon temps avec ce combat Pokémon !", "4": "Prenons du bon temps avec ce combat Pokémon !",
"5": "Je vais tapprendre à te battre avec tes Pokémon !", "5": "Je vais tapprendre à te battre avec tes Pokémon !",
"6": "Un combat doit être pris au sérieux. Tes prêt à te battre ?", "6": "Un combat doit toujours être pris au sérieux.\nTes prêt à te battre ?",
"7": "Tu seras pas jeune éternellement. Tas quune chance pendant un combat. Bientôt, tu seras plus quun souvenir.", "7": "Tu seras pas jeune éternellement. Tas quune chance pendant un combat. Bientôt, tu seras plus quun souvenir.",
"8": "Tu ferais mieux dy aller doucement avec moi. Mais je vais me battre sérieusement !", "8": "Tu ferais mieux dy aller doucement avec moi. Mais je vais me battre sérieusement !",
"9": "Je mennuie à lécole. Ya rien à y faire. *Baille*\nJe me bats juste pour passer le temps." "9": "Je mennuie à lécole. Ya rien à y faire. *Baille*\nJe me bats juste pour passer le temps."
@ -69,7 +69,7 @@
"defeat": { "defeat": {
"1": "Tu ne devrais pas ténerver sur tes Pokémon, même après une défaite.", "1": "Tu ne devrais pas ténerver sur tes Pokémon, même après une défaite.",
"2": "Alors ? Pas mal mes Pokémon, hein ? Je suis fait pour ça.", "2": "Alors ? Pas mal mes Pokémon, hein ? Je suis fait pour ça.",
"3": "Peut importe à quel point taimes tes Pokémon, il faut toujours de la discipline sils se comportent mal." "3": "Peu importe à quel point taimes tes Pokémon, il faut toujours de la discipline sils se comportent mal."
} }
}, },
"breeder_female": { "breeder_female": {
@ -93,7 +93,7 @@
"encounter": { "encounter": {
"1": "Aaah non ! Javais une touche !\nTu comptes faire quoi pour arranger ça ?", "1": "Aaah non ! Javais une touche !\nTu comptes faire quoi pour arranger ça ?",
"2": "Bouge de là ! Tu fais peur aux Pokémon !", "2": "Bouge de là ! Tu fais peur aux Pokémon !",
"3": "Voyons si t'arrives à ferrer une victoire !" "3": "Voyons si tarrives à ferrer une victoire !"
}, },
"victory": { "victory": {
"1": "Vas-y là, oublie.", "1": "Vas-y là, oublie.",
@ -148,7 +148,7 @@
}, },
"victory": { "victory": {
"1": "Très bien… Tas de bons Pokémon…", "1": "Très bien… Tas de bons Pokémon…",
"2": "Quoi ?! Mais c'est moi le génie des combats !", "2": "Quoi ?! Mais cest moi le génie des combats !",
"3": "Évidemment que tes le personnage principal !", "3": "Évidemment que tes le personnage principal !",
"4": "OK ! OK ! Tu pourrais être un Topdresseur !" "4": "OK ! OK ! Tu pourrais être un Topdresseur !"
}, },
@ -170,81 +170,97 @@
"rocket_grunt": { "rocket_grunt": {
"encounter": { "encounter": {
"1": "Nous sommes de retour !", "1": "Nous sommes de retour !",
"2": "We're pulling a big job here! Get lost, kid!", "2": "Ça bosse dur, ici ! Alors du balai !",
"3": "Hand over your Pokémon, or face the wrath of Team Rocket!", "3": "File-nous tes Pokémon ou tu vas gouter à la colère de la Team Rocket !",
"4": "You're about to experience the true terror of Team Rocket!", "4": "Sois témoin de ce quest une vraie terreur de la Team Rocket!",
"5": "Hey, kid! Me am a Team Rocket member kind of guy!" "5": "Hé gamin ! Moi être guy member of la Team Rocket !"
}, },
"victory": { "victory": {
"1": "Une fois de plus la Team Rocket senvole vers dautres cieux !", "1": "Une fois de plus la Team Rocket senvole vers dautres cieux !",
"2": "Oh no! I dropped the Lift Key!", "2": "Mince! Jai laissé tomber\nla Clé Ascenseur !",
"3": "I blew it!", "3": "Jai tout foiré !",
"4": "My associates won't stand for this!", "4": "Mes compagnons vont me venger !",
"5": "You say what? Team Rocket bye-bye a go-go? Broken it is says you?" "5": "Toi dire quoi ? Forget que tu mas vu !\nYou nas rien seen !"
} }
}, },
"magma_grunt": { "magma_grunt": {
"encounter": { "encounter": {
"1": "Nespère pas recevoir de la pitié si tu te mets sur le chemin de la Team Magma !", "1": "Nespère pas recevoir de la pitié si tu te mets sur le chemin de la Team Magma !",
"2": "You'd better not interfere with our plans! We're making the world a better place!", "2": "Ne te mêle pas de nos affaires ! On va rendre ce monde meilleur !",
"3": "You're in the way! Team Magma has no time for kids like you!", "3": "Hors de mon chemin ! La Team Magma na pas de temps pour les gamins !",
"4": "I hope you brought marshmallows because things are about to heat up!", "4": "Jespère que tas quelques marshmallows, car ça va chauffer !",
"5": "We're going to use the power of a volcano! It's gonna be... explosive! Get it? Heh heh!" "5": "On va utiliser le puissance dun volcan ! Ça va être… explosif ! Tu las… ? Héhé !"
}, },
"victory": { "victory": {
"1": "Je…?\nJai perdu ?!", "1": "Je…?\nJai perdu ?!",
"2": "I can't believe I lost! I even skipped lunch for this", "2": "Je peux pas croire que jai pas pris mon déjeuner juste pour ça…",
"3": "No way! You're just a kid!", "3": "Impossible ! Tes quun gosse !",
"4": "Urrrgh... I should've ducked into our hideout right away...", "4": "Aahhh…\nJaurais dû directement rentrer à la planque…",
"5": "You beat me... Do you think the boss will dock my pay for this?" "5": "Tu mas démoli… Tu crois que le boss va suspendre mon salaire ?"
} }
}, },
"aqua_grunt": { "aqua_grunt": {
"encounter": { "encounter": {
"1": "Aucune pitié si tu te mets sur le chemin de la Team Aqua, même pour un gamin !", "1": "Aucune pitié si tu te mets sur le chemin de la Team Aqua, même pour un gamin !",
"2": "Grrr... You've got some nerve meddling with Team Aqua!", "2": "Grrr…\nTu as eu le culot de topposer à la Team Aqua !",
"3": "You're about to get soaked! And not just from my water Pokémon!", "3": "Je vais te liquéfier !\nEt ce sera pas quà cause des mes Pokémon Eau !",
"4": "We, Team Aqua, exist for the good of all!", "4": "Nous, la Team Aqua, existons pour le bien commun !",
"5": "Prepare to be washed away by the tides of my... uh, Pokémon! Yeah, my Pokémon!" "5": "Prépare-toi à te faire emporter par le courant de…\nEuh… Mes Pokémon ! Oui, mes Pokémon !"
}, },
"victory": { "victory": {
"1": "Comment ça ?", "1": "Comment ça ?",
"2": "Arrgh, I didn't count on being meddled with by some meddling kid!", "2": "Ah, javais pas prévu dêtre gêné par un mouflet qui se mêle de tout !",
"3": "I lost?! Guess I'll have to swim back to the hideout now...", "3": "Jai perdu ?! Super, jai plus quà nager jusquà la planque maintenant…",
"4": "Oh, man, what a disaster... The boss is going to be furious...", "4": "Oh non quelle angoisse…\nLe boss va me démonter…",
"5": "You beat me... Do you think the boss will make me walk the plank for this?" "5": "Je suis battu… Tu penses que le boss va me faire subir le supplice de la planche ?…"
} }
}, },
"galactic_grunt": { "galactic_grunt": {
"encounter": { "encounter": {
"1": "Ne te mets pas en travers de la Team Galaxie !", "1": "Ne te mets pas en travers de la Team Galaxie !",
"2": "Witness the power of our technology and the future we envision!", "2": "Sois témoin de la puissance de notre technologie et du futur qui se profile !",
"3": "In the name of Team Galactic, I'll eliminate anyone who stands in our way!", "3": "Au nom de la Team Galaxie, jéliminerai quiconque se mettera sur notre route !",
"4": "Get ready to lose!", "4": "Prépare ta défaite !",
"5": "Hope you're ready for a cosmic beatdown!" "5": "Jespère que tes prêt à te prendre une raclée de lespace !"
}, },
"victory": { "victory": {
"1": "Désactivation…", "1": "Désactivation…",
"2": "This setback means nothing in the grand scheme.", "2": "Cet échec nest quune poussière face à nos ambitions débordantes.",
"3": "Our plans are bigger than this defeat.", "3": "Notre projet est bien plus important que cette défaite.",
"4": "How?!", "4": "Comment ?!",
"5": "Note to self: practice Pokémon battling, ASAP." "5": "Note à moi-même :\nMentrainer aux combats Pokémon. Ça urge…"
} }
}, },
"plasma_grunt": { "plasma_grunt": {
"encounter": { "encounter": {
"1": "Pas de quatiers à ceux qui ne suivent pas notre idéal !", "1": "Pas de quatiers à ceux qui ne suivent pas notre idéal !",
"2": "If I win against you, release your Pokémon!", "2": "Si je gagne, tu relâches tous tes Pokémon !",
"3": "If you get in the way of Team Plasma, I'll take care of you!", "3": "Si tu te mets en travers de la Team Plasma, je moccuperai de toi personnellement !",
"4": "Team Plasma will liberate Pokémon from selfish humans like you!", "4": "La Team Plasma va libérer les Pokémon de tous les humains égoïstes dans ton genre !",
"5": "Our hairstyles are out of this world... but our battling skills? You'll find out soon enough." "5": "Nos coupes sont lunaires… Mais en combat ?\nTu vas vite le découvrir."
}, },
"victory": { "victory": {
"1": "Plasmaaaaaaaaa !", "1": "Plasmaaaaaaaaa !",
"2": "How could I lose...", "2": "Comment ai-je pu perdre…",
"3": "...What a weak Pokémon, I'll just have to go steal some better ones!", "3": "… Ce Pokémon est nul, jvais aller en voler de meilleurs !",
"4": "Great plans are always interrupted.", "4": "Les plans ambitieux connaissent toujours leurs lots dinterruptions.",
"5": "This is bad... Badbadbadbadbadbadbad! Bad for Team Plasma! Or Plasbad, for short!" "5": "Cest mauvais… MAUVAIS MAUVAIS MAUVAIS MAUVAIS !\nVa falloir battre en retraite, cest la méga cata !"
}
},
"flare_grunt": {
"encounter": {
"1": "Tes Pokémon ne sont pas dignes de lélégance de la Team Flare.",
"2": "Tas des lunettes de soleil jespère ?\nCar prépare-toi à être ébloui !",
"3": "La Team Flare va purifier ce monde de toute imperfection !",
"4": "Prépare-toi à découvrir lindiscutable sens du style de la Team Flare !",
"5": "La mode, cest important !"
},
"victory": {
"1": "Mon futur na pas lair si radieux.",
"2": "Les combats semblent être plus complexes que je le pensais.\nRetour aux planches à dessin.",
"3": "Ehhhh ?! Jai perdu ?!",
"4": "Même dans la défaite, lélégance de la Team Flare continue de rayonner sur ce monde.",
"5": "Jappelle pas ça perdre, jappelle ça échouer avec panache !"
} }
}, },
"rocket_boss_giovanni_1": { "rocket_boss_giovanni_1": {
@ -379,6 +395,77 @@
"1": "Les ignorants sans aucune vision nauront donc de cesse de souiller ce monde." "1": "Les ignorants sans aucune vision nauront donc de cesse de souiller ce monde."
} }
}, },
"brock": {
"encounter": {
"1": "Mon expertise des types Roche va te mettre au sol ! En garde !",
"2": "Tu veux toujours te battre avec moi ? Même en sachant que tu vas perdre ?",
"3": "Laisse-moi de montrer la véritable force de mes Pokémon Roche !"
},
"victory": {
"1": "Jétais trop sûr de moi, cest pour ça que jai perdu.",
"2": "Ce monde est vaste ! Je suis honoré davoir pu taffronter.",
"3": "Peut-être bien que je naurais pas dû abandonner ma vocation dÉleveur…"
},
"defeat": {
"1": "La défense est la meilleure des attaques !\nTelle est ma méthode !",
"2": "Viens étudier des roches avec moi la prochaine fois si tu veux apprendre à mieux les aborder !",
"3": "Tout ce temps à voyager autour du monde paie enfin !"
}
},
"misty": {
"encounter": {
"1": "Ma tactique ? Attaquer avec des Pokémon Eau !",
"2": "Je vais te prouver le tsunami que sont mes Pokémon aquatiques !",
"3": "Mon rêve, cétait de voyager et de défier des Dresseurs super forts. Seras-tu à la hauteur ?"
},
"victory": {
"1": "OK. Tes pas naze… Je le reconnais…",
"2": "Pfff… Tas juste eu de la chance hein ?!",
"3": "Ouah ! Tes super balèze !"
},
"defeat": {
"1": "Quen dis-tu? Cest ça, la puissance des Pokémon Eau !",
"2": "Jespère que tas pris note des élégantes techniques de nage de mes Pokémon !",
"3": "Tes Pokémon ne jouent visiblement pas dans le même bassin…"
}
},
"lt_surge": {
"encounter": {
"1": "Tas pas froid aux yeux, soldat ! Les combats Pokémon, cest la guerre !",
"2": "Tu as du guts pour venir me fight ici ! Je vais te shock !",
"3": "Compte tes dents, tu vas morfler !\nMes Pokémon Électrik vont tatomiser !"
},
"victory": {
"1": "Whoo ! Tiras loin toi.",
"2": "Oh noes ! Mes tricks électriques sont à plat…\nYou are very fortiche!",
"3": "Tu es very costaud ! Je vais training very dur mes Pokémon, moi too, et on sera Number One !"
},
"defeat": {
"1": "Oh yeah !\nMes Pokémon Électrik sont les best du monde !",
"2": "Oh yeah, baby ! I am trop fort !",
"3": "Une combat Pokémon, cest comme une guerre et tas eu droit à une bataille de premier ordre !"
}
},
"erika": {
"encounter": {
"1": "Il fait beau, aujourdhui, nest-ce pas… ?\nQuoi un combat… ? Très bien…",
"2": "Larrangement floral est ma spécialité, et mes Pokémon sont de type Plante. Quoi ? Tu veux te battre ?",
"3": "Il fait beau… Le soleil brille… Les plantes bourgeonnent… Je mennuie…",
"4": "Voir un tel jardin rempli de fleurs est si apaisant…"
},
"victory": {
"1": "Bien joué, cest mértié.",
"2": "Dommage, on samusait si bien…",
"3": "Oh non, le combat est terminé…",
"4": "Aaah, ça fait du bien !\nMerci, jen avais besoin."
},
"defeat": {
"1": "Jai failli mendormir…",
"2": "Oh non… Mes Pokémon Plante ont lair de tavoir bien endormi…",
"3": "Ce combat était si apaisant…",
"4": "Oh non… Cest tout ?"
}
},
"alder": { "alder": {
"encounter": { "encounter": {
"1": "Prépare-toi pour un combat contre le meilleur Dresseur dUnys !" "1": "Prépare-toi pour un combat contre le meilleur Dresseur dUnys !"
@ -411,7 +498,7 @@
}, },
"rival_female": { "rival_female": {
"encounter": { "encounter": {
"1": "@c{smile_wave}Ah, je te cherchais ! Je tai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}Tas décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de mavoir oubliée,\nà une conditon. @c{smile_wave_wink}Que tu maffronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant davoir commencé, hein ?" "1": "@c{smile_wave}Ah, te voilà ! Je tai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}Tas décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de mavoir oubliée,\nà une conditon. @c{smile_wave_wink}Que tu maffronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant davoir commencé, hein ?"
}, },
"victory": { "victory": {
"1": "@c{shock}Tu viens de commencer et tes déjà si fort ?!@d{96}\n@c{angry}Tas triché non ? Avoue !\n$@c{smile_wave_wink}Jdéconne !@d{64} @c{smile_eclosed}Jai perdu dans les règles…\nJai le sentiment que tu vas très bien ten sortir.\n$@c{smile}Dailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !\n$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !" "1": "@c{shock}Tu viens de commencer et tes déjà si fort ?!@d{96}\n@c{angry}Tas triché non ? Avoue !\n$@c{smile_wave_wink}Jdéconne !@d{64} @c{smile_eclosed}Jai perdu dans les règles…\nJai le sentiment que tu vas très bien ten sortir.\n$@c{smile}Dailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !\n$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !"
@ -509,4 +596,4 @@
"1": "@c{smile_ehalf}Je… Je crois que jai rempli ma mission…\n$@c{smile_eclosed}Promets-moi… Après avoir réparé ce monde… Reviens à la maison sain et sauf.\n$@c{smile_ehalf}… Merci." "1": "@c{smile_ehalf}Je… Je crois que jai rempli ma mission…\n$@c{smile_eclosed}Promets-moi… Après avoir réparé ce monde… Reviens à la maison sain et sauf.\n$@c{smile_ehalf}… Merci."
} }
} }
} }

View File

@ -4,23 +4,23 @@
"ultraTier": "Épique", "ultraTier": "Épique",
"masterTier": "Légendaire", "masterTier": "Légendaire",
"defaultTier": "Commun", "defaultTier": "Commun",
"hatchWavesMessageSoon": "Il fait du bruit. Il va éclore !", "hatchWavesMessageSoon": "Il fait du bruit. Il va éclore !",
"hatchWavesMessageClose": "Il bouge de temps en temps. Il devrait bientôt éclore.", "hatchWavesMessageClose": "Il bouge de temps en temps. Il devrait bientôt éclore.",
"hatchWavesMessageNotClose": "Quest-ce qui va en sortir ? Ça va mettre du temps.", "hatchWavesMessageNotClose": "Quest-ce qui va en sortir ? Ça va mettre du temps.",
"hatchWavesMessageLongTime": "Cet Œuf va sûrement mettre du temps à éclore.", "hatchWavesMessageLongTime": "Cet Œuf va surement mettre du temps à éclore.",
"gachaTypeLegendary": "Taux de Légendaires élevé", "gachaTypeLegendary": "Taux de Légendaires élevé",
"gachaTypeMove": "Taux de Capacité Œuf Rare élevé", "gachaTypeMove": "Taux de Capacité Œuf Rare élevé",
"gachaTypeShiny": "Taux de Chromatiques élevé", "gachaTypeShiny": "Taux de Chromatiques élevé",
"selectMachine": "Sélectionnez une machine.", "selectMachine": "Sélectionnez une machine.",
"notEnoughVouchers": "Vous navez pas assez de coupons !", "notEnoughVouchers": "Vous navez pas assez de coupons !",
"tooManyEggs": "Vous avez trop dŒufs !", "tooManyEggs": "Vous avez trop dŒufs !",
"pull": "Tirage", "pull": "Tirage",
"pulls": "Tirages", "pulls": "Tirages",
"sameSpeciesEgg": "{{species}} sortira de cet Œuf !", "sameSpeciesEgg": "{{species}} sortira de cet Œuf !",
"hatchFromTheEgg": "{{pokemonName}} sort de lŒuf !", "hatchFromTheEgg": "{{pokemonName}} sort de lŒuf !",
"eggMoveUnlock": "Capacité Œuf débloquée :\n{{moveName}}", "eggMoveUnlock": "Capacité Œuf débloquée :\n{{moveName}}",
"rareEggMoveUnlock": "Capacité Œuf Rare débloquée :\n{{moveName}}", "rareEggMoveUnlock": "Capacité Œuf Rare débloquée :\n{{moveName}}",
"moveUPGacha": "Bonus Capacité\nŒuf Rare !", "moveUPGacha": "Bonus Capacité\nŒuf Rare !",
"shinyUPGacha": "Bonus\nChromatique !", "shinyUPGacha": "Bonus\nChromatique !",
"legendaryUPGacha": "Bonus !" "legendaryUPGacha": "Bonus !"
} }

View File

@ -42,14 +42,14 @@
"wave": "Vague", "wave": "Vague",
"loading": "Chargement…", "loading": "Chargement…",
"loadingAsset": "Chargement de la ressource : {{assetName}}", "loadingAsset": "Chargement de la ressource : {{assetName}}",
"playersOnline": "Joueurs Connectés", "playersOnline": "Joueurs connectés",
"yes": "Oui", "yes": "Oui",
"no": "Non", "no": "Non",
"disclaimer": "AVERTISSEMENT", "disclaimer": "AVERTISSEMENT",
"disclaimerDescription": "Ce jeu nest pas un produit fini et peut contenir des problèmes de jouabilité, dont de possibles pertes de sauvegardes,\ndes modifications sans avertissement et pourrait ou non encore être mis à jour ou terminé.", "disclaimerDescription": "Ce jeu nest pas un produit fini et peut contenir des problèmes de jouabilité, dont de possibles pertes de sauvegardes,\ndes modifications sans avertissement et pourrait ou non encore être mis à jour ou terminé.",
"choosePokemon": "Sélectionnez un Pokémon.", "choosePokemon": "Sélectionnez un Pokémon.",
"renamePokemon": "Renommer Pokémon", "renamePokemon": "Renommer le Pokémon",
"rename": "Renommer", "rename": "Renommer",
"nickname": "Surnom", "nickname": "Surnom",
"errorServerDown": "Oupsi ! Un problème de connexion au serveur est survenu.\n\nVous pouvez garder cette fenêtre ouverte,\nle jeu se reconnectera automatiquement." "errorServerDown": "Oupsi ! Un problème de connexion au serveur est survenu.\n\nVous pouvez garder cette fenêtre ouverte,\nle jeu se reconnectera automatiquement."
} }

View File

@ -11,7 +11,7 @@
"PokemonHeldItemModifierType": { "PokemonHeldItemModifierType": {
"extra": { "extra": {
"inoperable": "{{pokemonName}} ne peut pas\nporter cet objet !", "inoperable": "{{pokemonName}} ne peut pas\nporter cet objet !",
"tooMany": "{{pokemonName}} possède trop\ndexemplaires de cet objet !" "tooMany": "{{pokemonName}} porte trop\ndexemplaires de cet objet !"
} }
}, },
"PokemonHpRestoreModifierType": { "PokemonHpRestoreModifierType": {
@ -108,7 +108,7 @@
"description": "Permet à certains Pokémon de changer de forme." "description": "Permet à certains Pokémon de changer de forme."
}, },
"FusePokemonModifierType": { "FusePokemonModifierType": {
"description": "Fusionne deux Pokémon (transfère le talent, sépare les stats de base et les types, partage le movepool)." "description": "Fusionne deux Pokémon (transfère le talent, sépare les stats de base et les types, partage les capacités)."
}, },
"TerastallizeModifierType": { "TerastallizeModifierType": {
"name": "Téra-Éclat {{teraType}}", "name": "Téra-Éclat {{teraType}}",
@ -194,7 +194,7 @@
"RELIC_GOLD": { "name": "Vieux Ducat" }, "RELIC_GOLD": { "name": "Vieux Ducat" },
"AMULET_COIN": { "name": "Pièce Rune", "description": "Augmente de 20% les gains dargent." }, "AMULET_COIN": { "name": "Pièce Rune", "description": "Augmente de 20% les gains dargent." },
"GOLDEN_PUNCH": { "name": "Poing Doré", "description": "50% des dégâts infligés sont convertis en argent." }, "GOLDEN_PUNCH": { "name": "Poing Doré", "description": "La moitié des dégâts infligés sont convertis en argent." },
"COIN_CASE": { "name": "Boite Jetons", "description": "Tous les 10 combats, recevez 10% de votre argent en intérêts." }, "COIN_CASE": { "name": "Boite Jetons", "description": "Tous les 10 combats, recevez 10% de votre argent en intérêts." },
"LOCK_CAPSULE": { "name": "Poké Écrin", "description": "Permet de conserver la rareté des objets si vous relancez les objets proposés." }, "LOCK_CAPSULE": { "name": "Poké Écrin", "description": "Permet de conserver la rareté des objets si vous relancez les objets proposés." },
@ -205,13 +205,13 @@
"MULTI_LENS": { "name": "Lentille Multi" }, "MULTI_LENS": { "name": "Lentille Multi" },
"HEALING_CHARM": { "name": "Charme Soin", "description": "Augmente de 10% lefficacité des capacités et objets de soin de PV (hors Rappels)." }, "HEALING_CHARM": { "name": "Charme Soin", "description": "Augmente de 10% lefficacité des capacités et objets de soin de PV (hors Rappels)." },
"CANDY_JAR": { "name": "Bonbonnière", "description": "Augmente de 1 le nombre de niveaux gagnés à lutilisation dun Super Bonbon." }, "CANDY_JAR": { "name": "Bonbonnière", "description": "Augmente de 1 le nombre de niveaux gagnés à lutilisation dun Super Bonbon ou dun Hyper Bonbon." },
"BERRY_POUCH": { "name": "Sac à Baies", "description": "Ajoute 30% de chances quune Baie utilisée ne soit pas consommée." }, "BERRY_POUCH": { "name": "Sac à Baies", "description": "Ajoute 30% de chances quune Baie utilisée ne soit pas consommée." },
"FOCUS_BAND": { "name": "Bandeau", "description": "Ajoute 10% de chances de survivre avec 1 PV si les dégâts reçus pouvaient mettre K.O. ." }, "FOCUS_BAND": { "name": "Bandeau", "description": "Ajoute 10% de chances de survivre avec 1 PV si les dégâts reçus pouvaient mettre K.O. ." },
"QUICK_CLAW": { "name": "Vive Griffe", "description": "Ajoute 10% de chances dagir en premier, indépendamment de la vitesse (après la priorité)." }, "QUICK_CLAW": { "name": "Vive Griffe", "description": "Ajoute 10% de chances dagir en premier, indépendamment de la Vitesse (après la priorité)." },
"KINGS_ROCK": { "name": "Roche Royale", "description": "Ajoute 10% de chances quune capacité offensive apeure ladversaire." }, "KINGS_ROCK": { "name": "Roche Royale", "description": "Ajoute 10% de chances quune capacité offensive apeure ladversaire." },
@ -261,14 +261,14 @@
}, },
"TempBattleStatBoosterStatName": { "TempBattleStatBoosterStatName": {
"ATK": "Attaque", "ATK": "lAttaque",
"DEF": "Défense", "DEF": "la Défense",
"SPATK": "Atq. Spé.", "SPATK": "lAtq. Spé.",
"SPDEF": "Déf. Spé.", "SPDEF": "la Déf. Spé.",
"SPD": "Vitesse", "SPD": "la Vitesse",
"ACC": "Précision", "ACC": "la précision",
"CRIT": "Taux de critique", "CRIT": "le taux de critique",
"EVA": "Esquive", "EVA": "lesquive",
"DEFAULT": "???" "DEFAULT": "???"
}, },
@ -452,4 +452,4 @@
"FAIRY_MEMORY": "ROM Fée", "FAIRY_MEMORY": "ROM Fée",
"BLANK_MEMORY": "ROM Vierge" "BLANK_MEMORY": "ROM Vierge"
} }
} }

View File

@ -3,10 +3,10 @@
"turnHealApply": "Les PV de {{pokemonNameWithAffix}}\nsont un peu restaurés par les {{typeName}} !", "turnHealApply": "Les PV de {{pokemonNameWithAffix}}\nsont un peu restaurés par les {{typeName}} !",
"hitHealApply": "Les PV de {{pokemonNameWithAffix}}\nsont un peu restaurés par le {{typeName}} !", "hitHealApply": "Les PV de {{pokemonNameWithAffix}}\nsont un peu restaurés par le {{typeName}} !",
"pokemonInstantReviveApply": "{{pokemonNameWithAffix}} a repris connaissance\navec sa {{typeName}} et est prêt à se battre de nouveau !", "pokemonInstantReviveApply": "{{pokemonNameWithAffix}} a repris connaissance\navec sa {{typeName}} et est prêt à se battre de nouveau !",
"pokemonResetNegativeStatStageApply": "{{pokemonNameWithAffix}}'s lowered stats were restored\nby its {{typeName}}!", "pokemonResetNegativeStatStageApply": "Les stats baissées de {{pokemonNameWithAffix}}\nsont restaurées par l{{typeName}} !",
"moneyInterestApply": "La {{typeName}} vous rapporte\n{{moneyAmount}}  dintérêts !", "moneyInterestApply": "La {{typeName}} vous rapporte\n{{moneyAmount}}  dintérêts !",
"turnHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est absorbé·e\npar le {{typeName}} de {{pokemonName}} !", "turnHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est absorbé·e\npar le {{typeName}} de {{pokemonName}} !",
"contactHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est volé·e\npar l{{typeName}} de {{pokemonName}} !", "contactHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est volé·e\npar l{{typeName}} de {{pokemonName}} !",
"enemyTurnHealApply": "{{pokemonNameWithAffix}}\nrestaure un peu ses PV !", "enemyTurnHealApply": "{{pokemonNameWithAffix}}\nrestaure un peu ses PV !",
"bypassSpeedChanceApply": "{{itemName}} de {{pokemonName}}\nlui permet dagir plus vite que dhabitude!" "bypassSpeedChanceApply": "{{itemName}} de {{pokemonName}}\nlui permet dagir plus vite que dhabitude!"
} }

View File

@ -25,7 +25,7 @@
}, },
"firePunch": { "firePunch": {
"name": "Poing Feu", "name": "Poing Feu",
"effect": "Un coup de poing enflammé vient frapper la cible, ce qui peut la brûler (10% de chances)." "effect": "Un coup de poing enflammé vient frapper la cible, ce qui peut la bruler (10% de chances)."
}, },
"icePunch": { "icePunch": {
"name": "Poing Glace", "name": "Poing Glace",
@ -205,11 +205,11 @@
}, },
"ember": { "ember": {
"name": "Flammèche", "name": "Flammèche",
"effect": "La cible est attaquée par une faible flamme qui peut aussi la brûler." "effect": "La cible est attaquée par une faible flamme qui peut aussi la bruler."
}, },
"flamethrower": { "flamethrower": {
"name": "Lance-Flammes", "name": "Lance-Flammes",
"effect": "La cible reçoit un torrent de flammes qui peut aussi la brûler (10% de chances)." "effect": "La cible reçoit un torrent de flammes qui peut aussi la bruler (10% de chances)."
}, },
"mist": { "mist": {
"name": "Brume", "name": "Brume",
@ -356,7 +356,7 @@
"effect": "Le lanceur provoque un tremblement de terre touchant tous les Pokémon autour de lui." "effect": "Le lanceur provoque un tremblement de terre touchant tous les Pokémon autour de lui."
}, },
"fissure": { "fissure": {
"name": "Abîme", "name": "Abime",
"effect": "Le lanceur fait tomber la cible dans une crevasse. Si cette attaque réussit, elle met K.O. sur le coup." "effect": "Le lanceur fait tomber la cible dans une crevasse. Si cette attaque réussit, elle met K.O. sur le coup."
}, },
"dig": { "dig": {
@ -489,7 +489,7 @@
}, },
"smog": { "smog": {
"name": "Purédpois", "name": "Purédpois",
"effect": "Le lanceur attaque à l'aide d'une éruption de gaz répugnants qui peuvent aussi empoisonner la cible." "effect": "Le lanceur attaque à laide dune éruption de gaz répugnants qui peuvent aussi empoisonner la cible."
}, },
"sludge": { "sludge": {
"name": "Détritus", "name": "Détritus",
@ -501,7 +501,7 @@
}, },
"fireBlast": { "fireBlast": {
"name": "Déflagration", "name": "Déflagration",
"effect": "Un déluge de flammes ardentes submerge la cible, ce qui peut aussi la brûler (10% de chances)." "effect": "Un déluge de flammes ardentes submerge la cible, ce qui peut aussi la bruler (10% de chances)."
}, },
"waterfall": { "waterfall": {
"name": "Cascade", "name": "Cascade",
@ -581,7 +581,7 @@
}, },
"dizzyPunch": { "dizzyPunch": {
"name": "Uppercut", "name": "Uppercut",
"effect": "Un enchaînement de coups de poing cadencés frappe lennemi. Peut aussi le rendre confus." "effect": "Un enchainement de coups de poing cadencés frappe lennemi. Peut aussi le rendre confus."
}, },
"spore": { "spore": {
"name": "Spore", "name": "Spore",
@ -632,7 +632,7 @@
"effect": "Le lanceur mord lennemi à laide de ses incisives aiguisées. Peut aussi lapeurer (10% de chances)." "effect": "Le lanceur mord lennemi à laide de ses incisives aiguisées. Peut aussi lapeurer (10% de chances)."
}, },
"sharpen": { "sharpen": {
"name": "Affûtage", "name": "Affutage",
"effect": "Le lanceur réduit son nombre de polygones pour accentuer ses angles et augmenter son Attaque." "effect": "Le lanceur réduit son nombre de polygones pour accentuer ses angles et augmenter son Attaque."
}, },
"conversion": { "conversion": {
@ -641,7 +641,7 @@
}, },
"triAttack": { "triAttack": {
"name": "Triplattaque", "name": "Triplattaque",
"effect": "Le lanceur envoie trois boules dénergie simultanément qui peuvent aussi paralyser, brûler ou geler la cible (6.67% de chances)." "effect": "Le lanceur envoie trois boules dénergie simultanément qui peuvent aussi paralyser, bruler ou geler la cible (6.67% de chances)."
}, },
"superFang": { "superFang": {
"name": "Croc Fatal", "name": "Croc Fatal",
@ -661,7 +661,7 @@
}, },
"sketch": { "sketch": {
"name": "Gribouille", "name": "Gribouille",
"effect": "Le lanceur apprend la dernière capacité utilisée par la cible. Gribouille disparaît après utilisation." "effect": "Le lanceur apprend la dernière capacité utilisée par la cible. Gribouille disparait après utilisation."
}, },
"tripleKick": { "tripleKick": {
"name": "Triple Pied", "name": "Triple Pied",
@ -685,7 +685,7 @@
}, },
"flameWheel": { "flameWheel": {
"name": "Roue de Feu", "name": "Roue de Feu",
"effect": "Le lanceur sentoure de feu et charge la cible, ce qui peut aussi la brûler (10% de chances)." "effect": "Le lanceur sentoure de feu et charge la cible, ce qui peut aussi la bruler (10% de chances)."
}, },
"snore": { "snore": {
"name": "Ronflement", "name": "Ronflement",
@ -881,7 +881,7 @@
}, },
"sacredFire": { "sacredFire": {
"name": "Feu Sacré", "name": "Feu Sacré",
"effect": "Le lanceur génère un feu mystique dune intensité redoutable pour attaquer lennemi. Peut aussi le brûler (50% de chances)." "effect": "Le lanceur génère un feu mystique dune intensité redoutable pour attaquer lennemi. Peut aussi le bruler (50% de chances)."
}, },
"magnitude": { "magnitude": {
"name": "Ampleur", "name": "Ampleur",
@ -1025,7 +1025,7 @@
}, },
"heatWave": { "heatWave": {
"name": "Canicule", "name": "Canicule",
"effect": "Le lanceur provoque une vague de chaleur qui peut aussi brûler la cible (10% de chances)." "effect": "Le lanceur provoque une vague de chaleur qui peut aussi bruler la cible (10% de chances)."
}, },
"hail": { "hail": {
"name": "Grêle", "name": "Grêle",
@ -1041,7 +1041,7 @@
}, },
"willOWisp": { "willOWisp": {
"name": "Feu Follet", "name": "Feu Follet",
"effect": "Le lanceur projette des flammes maléfiques à la cible pour lui infliger une brûlure." "effect": "Le lanceur projette des flammes maléfiques à la cible pour lui infliger une brulure."
}, },
"memento": { "memento": {
"name": "Souvenir", "name": "Souvenir",
@ -1049,7 +1049,7 @@
}, },
"facade": { "facade": {
"name": "Façade", "name": "Façade",
"effect": "Une capacité dont la puissance double lorsque le lanceur est empoisonné, paralysé ou brûlé." "effect": "Une capacité dont la puissance double lorsque le lanceur est empoisonné, paralysé ou brulé."
}, },
"focusPunch": { "focusPunch": {
"name": "Mitra-Poing", "name": "Mitra-Poing",
@ -1145,7 +1145,7 @@
}, },
"refresh": { "refresh": {
"name": "Régénération", "name": "Régénération",
"effect": "Le lanceur se repose pour guérir dun empoisonnement, dune brûlure ou dune paralysie." "effect": "Le lanceur se repose pour guérir dun empoisonnement, dune brulure ou dune paralysie."
}, },
"grudge": { "grudge": {
"name": "Rancune", "name": "Rancune",
@ -1192,8 +1192,8 @@
"effect": "Danse qui rend confus tous les Pokémon autour du lanceur." "effect": "Danse qui rend confus tous les Pokémon autour du lanceur."
}, },
"blazeKick": { "blazeKick": {
"name": "Pied Brûleur", "name": "Pied Bruleur",
"effect": "Le lanceur envoie un coup de pied au taux de critiques élevé. Peut aussi brûler la cible (10% de chances)." "effect": "Le lanceur envoie un coup de pied au taux de critiques élevé. Peut aussi bruler la cible (10% de chances)."
}, },
"mudSport": { "mudSport": {
"name": "Lance-Boue", "name": "Lance-Boue",
@ -1573,7 +1573,7 @@
}, },
"flareBlitz": { "flareBlitz": {
"name": "Boutefeu", "name": "Boutefeu",
"effect": "Le lanceur sembrase avant de charger la cible, ce qui peut la brûler (10% de chances). Le choc blesse aussi gravement le lanceur." "effect": "Le lanceur sembrase avant de charger la cible, ce qui peut la bruler (10% de chances). Le choc blesse aussi gravement le lanceur."
}, },
"forcePalm": { "forcePalm": {
"name": "Forte-Paume", "name": "Forte-Paume",
@ -1693,7 +1693,7 @@
}, },
"fireFang": { "fireFang": {
"name": "Crocs Feu", "name": "Crocs Feu",
"effect": "Le lanceur utilise une morsure enflammée qui peut aussi brûler (10% de chances) ou apeurer (10% de chances) la cible." "effect": "Le lanceur utilise une morsure enflammée qui peut aussi bruler (10% de chances) ou apeurer (10% de chances) la cible."
}, },
"shadowSneak": { "shadowSneak": {
"name": "Ombre Portée", "name": "Ombre Portée",
@ -1741,7 +1741,7 @@
}, },
"lavaPlume": { "lavaPlume": {
"name": "Ébullilave", "name": "Ébullilave",
"effect": "Des flammes sabattent sur tous les Pokémon autour du lanceur, ce qui peut aussi les brûler (10% de chances)." "effect": "Des flammes sabattent sur tous les Pokémon autour du lanceur, ce qui peut aussi les bruler (10% de chances)."
}, },
"leafStorm": { "leafStorm": {
"name": "Tempête Verte", "name": "Tempête Verte",
@ -1796,7 +1796,7 @@
"effect": "Le lanceur libère une myriade de rayons de lumière. Le type varie selon la plaque que tient le lanceur." "effect": "Le lanceur libère une myriade de rayons de lumière. Le type varie selon la plaque que tient le lanceur."
}, },
"bugBite": { "bugBite": {
"name": "Piqûre", "name": "Piqure",
"effect": "Le lanceur pique la cible. Si celle-ci tient une Baie, le lanceur la dévore et obtient son effet." "effect": "Le lanceur pique la cible. Si celle-ci tient une Baie, le lanceur la dévore et obtient son effet."
}, },
"chargeBeam": { "chargeBeam": {
@ -1865,7 +1865,7 @@
}, },
"shadowForce": { "shadowForce": {
"name": "Revenant", "name": "Revenant",
"effect": "Le lanceur disparaît au premier tour et frappe la cible au deuxième. Cette capacité fonctionne même si la cible se protège." "effect": "Le lanceur disparait au premier tour et frappe la cible au deuxième. Cette capacité fonctionne même si la cible se protège."
}, },
"honeClaws": { "honeClaws": {
"name": "Aiguisage", "name": "Aiguisage",
@ -2009,7 +2009,7 @@
}, },
"scald": { "scald": {
"name": "Ébullition", "name": "Ébullition",
"effect": "Le lanceur projette un jet deau bouillante sur la cible, ce qui peut aussi la brûler (30% de chances)." "effect": "Le lanceur projette un jet deau bouillante sur la cible, ce qui peut aussi la bruler (30% de chances)."
}, },
"shellSmash": { "shellSmash": {
"name": "Exuviation", "name": "Exuviation",
@ -2037,7 +2037,7 @@
}, },
"incinerate": { "incinerate": {
"name": "Calcination", "name": "Calcination",
"effect": "Des flammes calcinent la cible. Si elle tient un objet, une Baie par exemple, celui-ci est brûlé et devient inutilisable." "effect": "Des flammes calcinent la cible. Si elle tient un objet, une Baie par exemple, celui-ci est brulé et devient inutilisable."
}, },
"quash": { "quash": {
"name": "À la Queue", "name": "À la Queue",
@ -2065,19 +2065,19 @@
}, },
"inferno": { "inferno": {
"name": "Feu dEnfer", "name": "Feu dEnfer",
"effect": "La cible est entourée dun torrent de flammes ardentes qui la brûlent." "effect": "La cible est entourée dun torrent de flammes ardentes qui la brulent."
}, },
"waterPledge": { "waterPledge": {
"name": "Aire dEau", "name": "Aire dEau",
"effect": "Une masse deau sabat sur la cible. Si cette capacité est utilisée en même temps quAire de Feu, la puissance augmente et un arc-en-ciel apparaît." "effect": "Une masse deau sabat sur la cible. Si cette capacité est utilisée en même temps quAire de Feu, la puissance augmente et un arc-en-ciel apparait."
}, },
"firePledge": { "firePledge": {
"name": "Aire de Feu", "name": "Aire de Feu",
"effect": "Une masse de feu sabat sur la cible. Si cette capacité est utilisée en même temps quAire dHerbe, la puissance augmente et une mer de feu apparaît." "effect": "Une masse de feu sabat sur la cible. Si cette capacité est utilisée en même temps quAire dHerbe, la puissance augmente et une mer de feu apparait."
}, },
"grassPledge": { "grassPledge": {
"name": "Aire dHerbe", "name": "Aire dHerbe",
"effect": "Une masse végétale sabat sur la cible. Si cette capacité est utilisée en même temps quAire dEau, la puissance augmente et un marécage apparaît." "effect": "Une masse végétale sabat sur la cible. Si cette capacité est utilisée en même temps quAire dEau, la puissance augmente et un marécage apparait."
}, },
"voltSwitch": { "voltSwitch": {
"name": "Change Éclair", "name": "Change Éclair",
@ -2177,7 +2177,7 @@
}, },
"searingShot": { "searingShot": {
"name": "Incendie", "name": "Incendie",
"effect": "Des boules de feu sabattent sur tous les Pokémon autour du lanceur. Peut aussi les brûler (30% de chances)." "effect": "Des boules de feu sabattent sur tous les Pokémon autour du lanceur. Peut aussi les bruler (30% de chances)."
}, },
"technoBlast": { "technoBlast": {
"name": "Techno-Buster", "name": "Techno-Buster",
@ -2201,7 +2201,7 @@
}, },
"blueFlare": { "blueFlare": {
"name": "Flamme Bleue", "name": "Flamme Bleue",
"effect": "De magnifiques et redoutables flammes bleues fondent sur lennemi. Peut aussi le brûler (20% de chances)." "effect": "De magnifiques et redoutables flammes bleues fondent sur lennemi. Peut aussi le bruler (20% de chances)."
}, },
"fieryDance": { "fieryDance": {
"name": "Danse du Feu", "name": "Danse du Feu",
@ -2213,7 +2213,7 @@
}, },
"iceBurn": { "iceBurn": {
"name": "Feu Glacé", "name": "Feu Glacé",
"effect": "Au second tour, le lanceur projette un souffle de vent glacial dévastateur sur lennemi. Peut aussi le brûler (30% de chances)." "effect": "Au second tour, le lanceur projette un souffle de vent glacial dévastateur sur lennemi. Peut aussi le bruler (30% de chances)."
}, },
"snarl": { "snarl": {
"name": "Aboiement", "name": "Aboiement",
@ -2261,7 +2261,7 @@
}, },
"phantomForce": { "phantomForce": {
"name": "Hantise", "name": "Hantise",
"effect": "Le lanceur disparaît au premier tour et frappe au second. Cette attaque passe outre les protections." "effect": "Le lanceur disparait au premier tour et frappe au second. Cette attaque passe outre les protections."
}, },
"trickOrTreat": { "trickOrTreat": {
"name": "Halloween", "name": "Halloween",
@ -2333,7 +2333,7 @@
}, },
"fairyWind": { "fairyWind": {
"name": "Vent Féérique", "name": "Vent Féérique",
"effect": "Le lanceur déchaîne un vent magique qui cingle la cible." "effect": "Le lanceur déchaine un vent magique qui cingle la cible."
}, },
"moonblast": { "moonblast": {
"name": "Pouvoir Lunaire", "name": "Pouvoir Lunaire",
@ -2345,7 +2345,7 @@
}, },
"fairyLock": { "fairyLock": {
"name": "Verrou Enchanté", "name": "Verrou Enchanté",
"effect": "Des chaînes entourent la zone de combat, empêchant tous les Pokémon de quitter le terrain au tour suivant." "effect": "Des chaines entourent la zone de combat, empêchant tous les Pokémon de quitter le terrain au tour suivant."
}, },
"kingsShield": { "kingsShield": {
"name": "Bouclier Royal", "name": "Bouclier Royal",
@ -2365,7 +2365,7 @@
}, },
"steamEruption": { "steamEruption": {
"name": "Jet de Vapeur", "name": "Jet de Vapeur",
"effect": "Le lanceur projette de la vapeur extrêmement chaude sur la cible, ce qui peut aussi la brûler (30% de chances)." "effect": "Le lanceur projette de la vapeur extrêmement chaude sur la cible, ce qui peut aussi la bruler (30% de chances)."
}, },
"hyperspaceHole": { "hyperspaceHole": {
"name": "TrouDimensionnel", "name": "TrouDimensionnel",
@ -2377,7 +2377,7 @@
}, },
"mysticalFire": { "mysticalFire": {
"name": "Feu Ensorcelé", "name": "Feu Ensorcelé",
"effect": "Le lanceur attaque en soufflant des flammes brûlantes par la bouche et diminue lAttaque Spéciale de la cible." "effect": "Le lanceur attaque en soufflant des flammes brulantes par la bouche et diminue lAttaque Spéciale de la cible."
}, },
"spikyShield": { "spikyShield": {
"name": "Pico-Défense", "name": "Pico-Défense",
@ -2517,7 +2517,7 @@
}, },
"tectonicRagePhysical": { "tectonicRagePhysical": {
"name": "Éruption Géo-Sismique", "name": "Éruption Géo-Sismique",
"effect": "Le Pokémon utilise la Force Z pour entraîner ladversaire dans les profondeurs de la terre. La puissance varie selon celle de la capacité originale." "effect": "Le Pokémon utilise la Force Z pour entrainer ladversaire dans les profondeurs de la terre. La puissance varie selon celle de la capacité originale."
}, },
"tectonicRageSpecial": { "tectonicRageSpecial": {
"name": "Éruption Géo-Sismique", "name": "Éruption Géo-Sismique",
@ -2653,7 +2653,7 @@
}, },
"sparklingAria": { "sparklingAria": {
"name": "Aria de lÉcume", "name": "Aria de lÉcume",
"effect": "Le lanceur émet plusieurs bulles en chantant. Soigne les brûlures des Pokémon touchés par ces bulles." "effect": "Le lanceur émet plusieurs bulles en chantant. Soigne les brulures des Pokémon touchés par ces bulles."
}, },
"iceHammer": { "iceHammer": {
"name": "Marteau de Glace", "name": "Marteau de Glace",
@ -2757,7 +2757,7 @@
}, },
"beakBlast": { "beakBlast": {
"name": "Bec-Canon", "name": "Bec-Canon",
"effect": "Le lanceur fait chauffer son bec avant dattaquer. Sil subit une attaque directe pendant la montée en température, lattaquant sera brûlé." "effect": "Le lanceur fait chauffer son bec avant dattaquer. Sil subit une attaque directe pendant la montée en température, lattaquant sera brulé."
}, },
"clangingScales": { "clangingScales": {
"name": "Vibrécaille", "name": "Vibrécaille",
@ -2789,7 +2789,7 @@
}, },
"guardianOfAlola": { "guardianOfAlola": {
"name": "Colère du Gardien dAlola", "name": "Colère du Gardien dAlola",
"effect": "Le Pokémon Tutélaire utilise la Force Z et déchaîne toute la puissance dAlola sur sa cible. Inflige des dégâts en fonction des PV restants de celle-ci." "effect": "Le Pokémon Tutélaire utilise la Force Z et déchaine toute la puissance dAlola sur sa cible. Inflige des dégâts en fonction des PV restants de celle-ci."
}, },
"soulStealing7StarStrike": { "soulStealing7StarStrike": {
"name": "Fauche-Âme des Sept Étoiles", "name": "Fauche-Âme des Sept Étoiles",
@ -2865,7 +2865,7 @@
}, },
"naturesMadness": { "naturesMadness": {
"name": "Ire de la Nature", "name": "Ire de la Nature",
"effect": "Le lanceur déchaîne toute la colère de la nature pour baisser les PV de la cible de moitié." "effect": "Le lanceur déchaine toute la colère de la nature pour baisser les PV de la cible de moitié."
}, },
"multiAttack": { "multiAttack": {
"name": "Coup Varia-Type", "name": "Coup Varia-Type",
@ -2873,7 +2873,7 @@
}, },
"tenMillionVoltThunderbolt": { "tenMillionVoltThunderbolt": {
"name": "Giga-Tonnerre", "name": "Giga-Tonnerre",
"effect": "Le Pikachu à casquette utilise la Force Z pour augmenter sa puissance électrique avant de la déchaîner sur la cible. Taux de critique élevé." "effect": "Le Pikachu à casquette utilise la Force Z pour augmenter sa puissance électrique avant de la déchainer sur la cible. Taux de critique élevé."
}, },
"mindBlown": { "mindBlown": {
"name": "Caboche-Kaboum", "name": "Caboche-Kaboum",
@ -2893,11 +2893,11 @@
}, },
"searingSunrazeSmash": { "searingSunrazeSmash": {
"name": "Hélio-Choc Dévastateur", "name": "Hélio-Choc Dévastateur",
"effect": "Baigné dans la Force Z, Solgaleo attaque en déchaînant toute sa puissance. Ignore le talent de la cible." "effect": "Baigné dans la Force Z, Solgaleo attaque en déchainant toute sa puissance. Ignore le talent de la cible."
}, },
"menacingMoonrazeMaelstrom": { "menacingMoonrazeMaelstrom": {
"name": "Rayons Séléno-Explosifs", "name": "Rayons Séléno-Explosifs",
"effect": "Baigné dans la Force Z, Lunala attaque en déchaînant toute sa puissance. Ignore le talent de la cible." "effect": "Baigné dans la Force Z, Lunala attaque en déchainant toute sa puissance. Ignore le talent de la cible."
}, },
"letsSnuggleForever": { "letsSnuggleForever": {
"name": "Patati-Patattrape", "name": "Patati-Patattrape",
@ -2913,7 +2913,7 @@
}, },
"zippyZap": { "zippyZap": {
"name": "Pika-Sprint", "name": "Pika-Sprint",
"effect": "Une attaque électrique rapide comme léclair qui augmente lesquive. Frappe en priorité." "effect": "Une attaque électrique rapide comme léclair qui inflige un coup critique à coup sûr. Frappe en priorité."
}, },
"splishySplash": { "splishySplash": {
"name": "Pika-Splash", "name": "Pika-Splash",
@ -2937,7 +2937,7 @@
}, },
"sizzlySlide": { "sizzlySlide": {
"name": "Évo-Flambo", "name": "Évo-Flambo",
"effect": "Évoli sembrase et percure violemment ladversaire. Brûle aussi lennemi." "effect": "Évoli sembrase et percure violemment ladversaire. Brule aussi lennemi."
}, },
"glitzyGlow": { "glitzyGlow": {
"name": "Évo-Psycho", "name": "Évo-Psycho",
@ -2961,7 +2961,7 @@
}, },
"veeveeVolley": { "veeveeVolley": {
"name": "Évo-Chardasso", "name": "Évo-Chardasso",
"effect": "Le lanceur lance une attaque dès lors quun signe apparaît sur le terrain. Les dégâts infligés sont proportionnels à laffection de votre Pokémon" "effect": "Le lanceur lance une attaque dès lors quun signe apparait sur le terrain. Les dégâts infligés sont proportionnels à laffection de votre Pokémon"
}, },
"doubleIronBash": { "doubleIronBash": {
"name": "Écrous dPoing", "name": "Écrous dPoing",
@ -3005,7 +3005,7 @@
}, },
"teatime": { "teatime": {
"name": "Thérémonie", "name": "Thérémonie",
"effect": "Le lanceur invite tous les Pokémon sur le terrain à prendre le goûter autour dune tasse de thé. Ceux qui tiennent une Baie la mangent." "effect": "Le lanceur invite tous les Pokémon sur le terrain à prendre le gouter autour dune tasse de thé. Ceux qui tiennent une Baie la mangent."
}, },
"octolock": { "octolock": {
"name": "Octoprise", "name": "Octoprise",
@ -3105,7 +3105,7 @@
}, },
"decorate": { "decorate": {
"name": "Nappage", "name": "Nappage",
"effect": "Augmente fortement lAttaque et lAttaque Spéciale du lanceur." "effect": "Augmente fortement lAttaque et lAttaque Spéciale de la cible."
}, },
"drumBeating": { "drumBeating": {
"name": "Tambour Battant", "name": "Tambour Battant",
@ -3116,8 +3116,8 @@
"effect": "Bloque lennemi pendant 4 à 5 tours." "effect": "Bloque lennemi pendant 4 à 5 tours."
}, },
"pyroBall": { "pyroBall": {
"name": "Ballon Brûlant", "name": "Ballon Brulant",
"effect": "Le lanceur attaque avec un ballon fait à partir dun caillou enflammé. Peut aussi brûler la cible (10% de chances)." "effect": "Le lanceur attaque avec un ballon fait à partir dun caillou enflammé. Peut aussi bruler la cible (10% de chances)."
}, },
"behemothBlade": { "behemothBlade": {
"name": "Gladius Maximus", "name": "Gladius Maximus",
@ -3189,7 +3189,7 @@
}, },
"steelRoller": { "steelRoller": {
"name": "Métalliroue", "name": "Métalliroue",
"effect": "Une attaque qui inflige des dégâts et fait disparaître le champ actif, mais qui échoue sil ny en a pas à ce moment." "effect": "Une attaque qui inflige des dégâts et fait disparaitre le champ actif, mais qui échoue sil ny en a pas à ce moment."
}, },
"scaleShot": { "scaleShot": {
"name": "Rafale Écailles", "name": "Rafale Écailles",
@ -3225,7 +3225,7 @@
}, },
"burningJealousy": { "burningJealousy": {
"name": "Feu Envieux", "name": "Feu Envieux",
"effect": "Le lanceur attaque sa cible avec toute sa jalousie. Cette capacité brûle tout Pokémon dont les stats ont augmenté pendant ce tour." "effect": "Le lanceur attaque sa cible avec toute sa jalousie. Cette capacité brule tout Pokémon dont les stats ont augmenté pendant ce tour."
}, },
"lashOut": { "lashOut": {
"name": "Cent Rancunes", "name": "Cent Rancunes",
@ -3257,7 +3257,7 @@
}, },
"scorchingSands": { "scorchingSands": {
"name": "Sable Ardent", "name": "Sable Ardent",
"effect": "Le lanceur projette du sable chauffé à blanc sur la cible, ce qui peut aussi la brûler (30% de chances)." "effect": "Le lanceur projette du sable chauffé à blanc sur la cible, ce qui peut aussi la bruler (30% de chances)."
}, },
"jungleHealing": { "jungleHealing": {
"name": "Selve Salvatrice", "name": "Selve Salvatrice",
@ -3265,11 +3265,11 @@
}, },
"wickedBlow": { "wickedBlow": {
"name": "Poing Obscur", "name": "Poing Obscur",
"effect": "Le lanceur assène un coup puissant à la cible. Cette technique qui inflige toujours un coup critique est réservée à ceux qui maîtrisent la puissance des Ténèbres." "effect": "Le lanceur assène un coup puissant à la cible. Cette technique qui inflige toujours un coup critique est réservée à ceux qui maitrisent la puissance des Ténèbres."
}, },
"surgingStrikes": { "surgingStrikes": {
"name": "Torrent de Coups", "name": "Torrent de Coups",
"effect": "Le lanceur assène trois coups fluides à la cible. Cette technique qui inflige toujours un coup critique est réservée à ceux qui maîtrisent la puissance de lEau." "effect": "Le lanceur assène trois coups fluides à la cible. Cette technique qui inflige toujours un coup critique est réservée à ceux qui maitrisent la puissance de lEau."
}, },
"thunderCage": { "thunderCage": {
"name": "Voltageôle", "name": "Voltageôle",
@ -3285,7 +3285,7 @@
}, },
"fieryWrath": { "fieryWrath": {
"name": "Fureur Ardente", "name": "Fureur Ardente",
"effect": "Le lanceur canalise sa colère et la transforme en émanation brûlante, avec laquelle il attaque la cible, ce qui peut aussi apeurer celle-ci (20% de chances)." "effect": "Le lanceur canalise sa colère et la transforme en émanation brulante, avec laquelle il attaque la cible, ce qui peut aussi apeurer celle-ci (20% de chances)."
}, },
"thunderousKick": { "thunderousKick": {
"name": "Coup Fulgurant", "name": "Coup Fulgurant",
@ -3329,7 +3329,7 @@
}, },
"ragingFury": { "ragingFury": {
"name": "Grand Courroux", "name": "Grand Courroux",
"effect": "Le lanceur se déchaîne et attaque en projetant de violentes flammes pendant deux ou trois tours. Il devient ensuite confus." "effect": "Le lanceur se déchaine et attaque en projetant de violentes flammes pendant deux ou trois tours. Il devient ensuite confus."
}, },
"waveCrash": { "waveCrash": {
"name": "Aquatacle", "name": "Aquatacle",
@ -3373,7 +3373,7 @@
}, },
"infernalParade": { "infernalParade": {
"name": "Cortège Funèbre", "name": "Cortège Funèbre",
"effect": "Une multitude de boules de feu frappent la cible, ce qui peut aussi la brûler (30% de chances et 50% en Style Puissant). La puissance est doublée si celle-ci souffre dune altération de statut." "effect": "Une multitude de boules de feu frappent la cible, ce qui peut aussi la bruler (30% de chances et 50% en Style Puissant). La puissance est doublée si celle-ci souffre dune altération de statut."
}, },
"ceaselessEdge": { "ceaselessEdge": {
"name": "Vagues à Lames", "name": "Vagues à Lames",
@ -3389,7 +3389,7 @@
}, },
"sandsearStorm": { "sandsearStorm": {
"name": "Typhon Pyrosable", "name": "Typhon Pyrosable",
"effect": "Le lanceur déclenche un violent typhon mêlé à du sable ardent qui sabat sur la cible, ce qui peut la brûler (30% de chances et 50% en Style Puissant)." "effect": "Le lanceur déclenche un violent typhon mêlé à du sable ardent qui sabat sur la cible, ce qui peut la bruler (30% de chances et 50% en Style Puissant)."
}, },
"lunarBlessing": { "lunarBlessing": {
"name": "Prière Lunaire", "name": "Prière Lunaire",
@ -3529,7 +3529,7 @@
}, },
"gMaxRapidFlow": { "gMaxRapidFlow": {
"name": "Multicoup G-Max", "name": "Multicoup G-Max",
"effect": "Une attaque de type Eau que seul un Shifours Gigamax peut utiliser. Cet enchaînement de coups permet dignorer la capacité Gardomax." "effect": "Une attaque de type Eau que seul un Shifours Gigamax peut utiliser. Cet enchainement de coups permet dignorer la capacité Gardomax."
}, },
"teraBlast": { "teraBlast": {
"name": "Téra Explosion", "name": "Téra Explosion",
@ -3712,8 +3712,8 @@
"effect": "Le lanceur projette de leau pressurisée qui entaille la cible comme une lame. Taux de critiques élevé." "effect": "Le lanceur projette de leau pressurisée qui entaille la cible comme une lame. Taux de critiques élevé."
}, },
"blazingTorque": { "blazingTorque": {
"name": "Crash Brûlant", "name": "Crash Brulant",
"effect": "Crash Brûlant inflige des dégâts et possède 30 % de chances de brûler ladversaire." "effect": "Crash Brulant inflige des dégâts et possède 30 % de chances de bruler ladversaire."
}, },
"wickedTorque": { "wickedTorque": {
"name": "Crash Obscur", "name": "Crash Obscur",
@ -3737,7 +3737,7 @@
}, },
"matchaGotcha": { "matchaGotcha": {
"name": "Mortier Matcha", "name": "Mortier Matcha",
"effect": "Le lanceur remue son thé et en bombarde la cible. La moitié des dégâts infligés sont convertis en PV pour le lanceur. Cette capacité peut aussi brûler la cible." "effect": "Le lanceur remue son thé et en bombarde la cible. La moitié des dégâts infligés sont convertis en PV pour le lanceur. Cette capacité peut aussi bruler la cible."
}, },
"syrupBomb": { "syrupBomb": {
"name": "Bombe au Sirop", "name": "Bombe au Sirop",
@ -3760,8 +3760,8 @@
"effect": "Le lanceur attaque en tirant un rayon lumineux. Il arrive parfois que toutes les têtes agissent ensemble, ce qui double la puissance de la capacité." "effect": "Le lanceur attaque en tirant un rayon lumineux. Il arrive parfois que toutes les têtes agissent ensemble, ce qui double la puissance de la capacité."
}, },
"burningBulwark": { "burningBulwark": {
"name": "Rempart Brûlant", "name": "Rempart Brulant",
"effect": "Le lanceur se protège contre les attaques grâce à son pelage incandescent, et si un assaillant utilise une attaque directe contre lui, il le brûle." "effect": "Le lanceur se protège contre les attaques grâce à son pelage incandescent, et si un assaillant utilise une attaque directe contre lui, il le brule."
}, },
"thunderclap": { "thunderclap": {
"name": "Vif Éclair", "name": "Vif Éclair",
@ -3784,7 +3784,7 @@
"effect": "Le lanceur galvanise ses alliés avec un encouragement draconique qui augmente leur taux de critiques. Leffet est plus puissant si les alliés ont le type Dragon." "effect": "Le lanceur galvanise ses alliés avec un encouragement draconique qui augmente leur taux de critiques. Leffet est plus puissant si les alliés ont le type Dragon."
}, },
"alluringVoice": { "alluringVoice": {
"name": "Voix Envoûtante", "name": "Voix Envoutante",
"effect": "Le lanceur attaque la cible avec sa voix angélique. Cette capacité rend la cible confuse si ses stats ont augmenté pendant ce tour." "effect": "Le lanceur attaque la cible avec sa voix angélique. Cette capacité rend la cible confuse si ses stats ont augmenté pendant ce tour."
}, },
"temperFlare": { "temperFlare": {
@ -3804,7 +3804,7 @@
"effect": "Le lanceur réagit instinctivement au moindre mouvement et donne un coup de paume qui apeure la cible. Échoue si cette dernière na pas utilisé une attaque prioritaire." "effect": "Le lanceur réagit instinctivement au moindre mouvement et donne un coup de paume qui apeure la cible. Échoue si cette dernière na pas utilisé une attaque prioritaire."
}, },
"malignantChain": { "malignantChain": {
"name": "Chaîne Malsaine", "name": "Chaine Malsaine",
"effect": "Le lanceur ligote la cible avec une chaîne faite de poison et lui injecte un venin corrosif, ce qui peut aussi gravement lempoisonner." "effect": "Le lanceur ligote la cible avec une chaine faite de poison et lui injecte un venin corrosif, ce qui peut aussi gravement lempoisonner."
} }
} }

View File

@ -11,7 +11,7 @@
"baker": "Boulangère", "baker": "Boulangère",
"battle_girl": "Combattante", "battle_girl": "Combattante",
"beauty": "Canon", "beauty": "Canon",
"beginners": "Beginners", "beginners": "Débutants",
"biker": "Motard", "biker": "Motard",
"black_belt": "Karatéka", "black_belt": "Karatéka",
"breeder": "Éleveur", "breeder": "Éleveur",
@ -29,7 +29,7 @@
"depot_agent": "Cheminot", "depot_agent": "Cheminot",
"doctor": "Docteur", "doctor": "Docteur",
"doctor_female": "Docteure", "doctor_female": "Docteure",
"firebreather": "Firebreather", "firebreather": "Crache-Feu",
"fisherman": "Pêcheur", "fisherman": "Pêcheur",
"fisherman_female": "Pêcheuse", "fisherman_female": "Pêcheuse",
"gentleman": "Gentleman", "gentleman": "Gentleman",
@ -68,7 +68,7 @@
"pokémon_rangers": "Pokémon Rangers", "pokémon_rangers": "Pokémon Rangers",
"ranger": "Ranger", "ranger": "Ranger",
"restaurant_staff": "Serveurs", "restaurant_staff": "Serveurs",
"rich": "Rich", "rich": "Gentleman",
"rich_female": "Mondaine", "rich_female": "Mondaine",
"rich_boy": "Gentleman", "rich_boy": "Gentleman",
"rich_couple": "Couple de Bourgeois", "rich_couple": "Couple de Bourgeois",
@ -118,4 +118,4 @@
"flare_grunt": "Sbire de la Team Flare", "flare_grunt": "Sbire de la Team Flare",
"flare_grunt_female": "Sbire de la Team Flare", "flare_grunt_female": "Sbire de la Team Flare",
"flare_grunts": "Sbires de la Team Flare" "flare_grunts": "Sbires de la Team Flare"
} }

View File

@ -2913,7 +2913,7 @@
}, },
"zippyZap": { "zippyZap": {
"name": "Sprintaboom", "name": "Sprintaboom",
"effect": "Un attacco elettrico ad altissima velocità. Questa mossa ha priorità alta e aumenta l'elusione dell'utilizzatore." "effect": "Un attacco elettrico ad altissima velocità. Questa mossa ha priorità alta e infligge sicuramente un brutto colpo."
}, },
"splishySplash": { "splishySplash": {
"name": "Surfasplash", "name": "Surfasplash",
@ -3807,4 +3807,4 @@
"name": "Intossicatena", "name": "Intossicatena",
"effect": "Il Pokémon logora il bersaglio avvolgendolo con le sue catene fatte di veleno e iniettandogli delle tossine che possono anche iperavvelenarlo." "effect": "Il Pokémon logora il bersaglio avvolgendolo con le sue catene fatte di veleno e iniettandogli delle tossine che possono anche iperavvelenarlo."
} }
} }

View File

@ -1 +1,42 @@
{} {
"SEND_OUT": "Manda in campo",
"SUMMARY": "Sommario",
"CANCEL": "Annulla",
"RELEASE": "Rilascia",
"APPLY": "Applica",
"TEACH": "Insegna",
"SPLICE": "Unisci",
"UNSPLICE": "Dividi",
"ACTIVATE": "Attiva",
"DEACTIVATE": "Disattiva",
"TRANSFER": "Trasferisci",
"ALL": "Tutto",
"PASS_BATON": "Staffetta",
"UNPAUSE_EVOLUTION": "Consenti evoluzione",
"REVIVE": "Revitalizza",
"RENAME": "Rinomina",
"choosePokemon": "Scegli un Pokémon.",
"doWhatWithThisPokemon": "Hai selezionato questo Pokémon.",
"noEnergy": "{{pokemonName}} non ha più energie\nper lottare!",
"hasEnergy": "{{pokemonName}} ha ancora energie\nper lottare!",
"cantBeUsed": "{{pokemonName}} non può essere usato\nin questa sfida!",
"tooManyItems": "{{pokemonName}} possiede già\nquest'oggetto in abbondanza!",
"anyEffect": "Non avrebbe alcun effetto.",
"unpausedEvolutions": "{{pokemonName}} può di nuovo evolversi.",
"unspliceConfirmation": "Vuoi davvero dividere {{fusionName}}\nda {{pokemonName}}? {{fusionName}} andrà perduto.",
"wasReverted": "{{fusionName}} è tornato ad essere {{pokemonName}}.",
"releaseConfirmation": "Vuoi davvero liberare {{pokemonName}}?",
"releaseInBattle": "Non puoi liberare un Pokémon che sta combattendo!",
"selectAMove": "Scegli una mossa.",
"changeQuantity": "Scegli un oggetto da trasferire.\nUsa < e > per cambiarne la quantità.",
"selectAnotherPokemonToSplice": "Scegli un altro Pokémon da unire.",
"cancel": "Annulla",
"goodbye": "Addio, {{pokemonName}}!",
"byebye": "Ciao ciao, {{pokemonName}}!",
"farewell": "Arrivederci, {{pokemonName}}!",
"soLong": "È stato bello, {{pokemonName}}!",
"thisIsWhereWePart": "Le nostre strade si dividono, {{pokemonName}}!",
"illMissYou": "Mi mancherai, {{pokemonName}}!",
"illNeverForgetYou": "Non ti dimenticherò, {{pokemonName}}!",
"untilWeMeetAgain": "Alla prossima, {{pokemonName}}!"
}

View File

@ -10,5 +10,5 @@
"eternamaxChange": "{{preName}} si Dynamaxxa infinitamente\nin {{pokemonName}}!", "eternamaxChange": "{{preName}} si Dynamaxxa infinitamente\nin {{pokemonName}}!",
"revertChange": "{{pokemonName}} è tornato\nalla sua forma originaria!", "revertChange": "{{pokemonName}} è tornato\nalla sua forma originaria!",
"formChange": "{{preName}} ha cambiato forma!", "formChange": "{{preName}} ha cambiato forma!",
"disguiseChange": "Its disguise served it as a decoy!" "disguiseChange": "Il costume ha assorbito lattacco!"
} }

View File

@ -1,6 +1,6 @@
{ {
"confirmStartTeam": "Vuoi iniziare con questi Pokémon?", "confirmStartTeam": "Vuoi iniziare con questi Pokémon?",
"confirmExit": "Do you want to exit?", "confirmExit": "Vuoi tornare alla schermata principale?",
"invalidParty": "Questo squadra iniziale non è valida!", "invalidParty": "Questo squadra iniziale non è valida!",
"gen1": "1ª", "gen1": "1ª",
"gen2": "2ª", "gen2": "2ª",
@ -21,13 +21,13 @@
"toggleIVs": "Vedi/Nascondi IV", "toggleIVs": "Vedi/Nascondi IV",
"manageMoves": "Gestisci mosse", "manageMoves": "Gestisci mosse",
"manageNature": "Gestisci natura", "manageNature": "Gestisci natura",
"addToFavorites": "Add to Favorites", "addToFavorites": "Aggiungi ai preferiti",
"removeFromFavorites": "Remove from Favorites", "removeFromFavorites": "Rimuovi dai preferiti",
"useCandies": "Usa caramelle", "useCandies": "Usa caramelle",
"selectNature": "Seleziona natura.", "selectNature": "Seleziona natura.",
"selectMoveSwapOut": "Seleziona una mossa da scambiare.", "selectMoveSwapOut": "Seleziona una mossa da scambiare.",
"selectMoveSwapWith": "Seleziona una mossa da scambiare con", "selectMoveSwapWith": "Seleziona una mossa da scambiare con",
"sameSpeciesEgg": "Buy an Egg", "sameSpeciesEgg": "Compra un uovo",
"unlockPassive": "Sblocca passiva", "unlockPassive": "Sblocca passiva",
"reduceCost": "Riduci costo", "reduceCost": "Riduci costo",
"cycleShiny": ": Shiny", "cycleShiny": ": Shiny",
@ -36,7 +36,7 @@
"cycleAbility": ": Abilità", "cycleAbility": ": Abilità",
"cycleNature": ": Natura", "cycleNature": ": Natura",
"cycleVariant": ": Variante", "cycleVariant": ": Variante",
"goFilter": ": Go to filters", "goFilter": ": Vai ai filtri",
"enablePassive": "Attiva passiva", "enablePassive": "Attiva passiva",
"disablePassive": "Disattiva passiva", "disablePassive": "Disattiva passiva",
"locked": "Bloccato", "locked": "Bloccato",

View File

@ -1 +1,16 @@
{} {
"misty": "Nebbioso",
"mistyStartMessage": "Ai piedi dei Pokémon si addensa la nebbia.",
"mistyClearMessage": "La nebbia si dissolve.",
"mistyBlockMessage": "Il Campo Nebbioso protegge {{pokemonNameWithAffix}}!",
"electric": "Elettrico",
"electricStartMessage": "Ai piedi dei Pokémon si accumula dellelettricità.",
"electricClearMessage": "Lelettricità svanisce.",
"grassy": "Erboso",
"grassyStartMessage": "Ai piedi dei Pokémon cresce rigogliosa lerba.",
"grassyClearMessage": "Lerba sparisce.",
"psychic": "Psichico",
"psychicStartMessage": "Nel campo si avverte una strana sensazione...",
"psychicClearMessage": "La strana sensazione nel campo è svanita!",
"defaultBlockMessage": "Il Campo {{terrainName}} protegge {{pokemonNameWithAffix}}!"
}

View File

@ -124,25 +124,25 @@
"rival": "Finn", "rival": "Finn",
"rival_female": "Ivy", "rival_female": "Ivy",
"archer": "Archer", "archer": "Archer",
"ariana": "Ariana", "ariana": "Atena",
"proton": "Proton", "proton": "Milas",
"petrel": "Petrel", "petrel": "Maxus",
"tabitha": "Tabitha", "tabitha": "Ottavio",
"courtney": "Courtney", "courtney": "Rossella",
"shelly": "Shelly", "shelly": "Ada",
"matt": "Matt", "matt": "Alan",
"mars": "Mars", "mars": "Martes",
"jupiter": "Jupiter", "jupiter": "Giovia",
"saturn": "Saturn", "saturn": "Saturno",
"zinzolin": "Zinzolin", "zinzolin": "Violante",
"rood": "Rood", "rood": "Ross",
"xerosic": "Xerosic", "xerosic": "Xante",
"bryony": "Bryony", "bryony": "Bromelia",
"maxie": "Maxie", "maxie": "Max",
"archie": "Archie", "archie": "Ivan",
"cyrus": "Cyrus", "cyrus": "Cyrus",
"ghetsis": "Ghetsis", "ghetsis": "Ghecis",
"lysandre": "Lysandre", "lysandre": "Elisio",
"blue_red_double": "Blu & Rosso", "blue_red_double": "Blu & Rosso",
"red_blue_double": "Rosso & Blu", "red_blue_double": "Rosso & Blu",
"tate_liza_double": "Tell & Pat", "tate_liza_double": "Tell & Pat",

View File

@ -10,22 +10,22 @@
"rival": "Rivale", "rival": "Rivale",
"professor": "Professore", "professor": "Professore",
"frontier_brain": "Asso lotta", "frontier_brain": "Asso lotta",
"rocket_boss": "Team Rocket Boss", "rocket_boss": "Capo Rocket",
"magma_boss": "Team Magma Boss", "magma_boss": "Capo Magma",
"aqua_boss": "Team Aqua Boss", "aqua_boss": "Capo Idro",
"galactic_boss": "Team Galactic Boss", "galactic_boss": "Capo Galassia",
"plasma_boss": "Team Plasma Boss", "plasma_boss": "Capo Plasma",
"flare_boss": "Team Flare Boss", "flare_boss": "Capo Flare",
"rocket_admin": "Team Rocket Admin", "rocket_admin": "Tenente Team Rocket",
"rocket_admin_female": "Team Rocket Admin", "rocket_admin_female": "Tenente Team Rocket",
"magma_admin": "Team Magma Admin", "magma_admin": "Magmatenente",
"magma_admin_female": "Team Magma Admin", "magma_admin_female": "Magmatenente",
"aqua_admin": "Team Aqua Admin", "aqua_admin": "Idrotenente",
"aqua_admin_female": "Team Aqua Admin", "aqua_admin_female": "Idrotenente",
"galactic_commander": "Team Galactic Commander", "galactic_commander": "Comandante Galassia",
"galactic_commander_female": "Team Galactic Commander", "galactic_commander_female": "Comandante Galassia",
"plasma_sage": "Team Plasma Sage", "plasma_sage": "Saggio Team Plasma",
"plasma_admin": "Team Plasma Admin", "plasma_admin": "Tenente Team Plasma",
"flare_admin": "Team Flare Admin", "flare_admin": "Ufficiale Team Flare",
"flare_admin_female": "Team Flare Admin" "flare_admin_female": "Ufficiale Team Flare"
} }

View File

@ -2913,7 +2913,7 @@
}, },
"zippyZap": { "zippyZap": {
"name": "파찌파찌액셀", "name": "파찌파찌액셀",
"effect": "맹렬한 속도의 전격 공격. 반드시 선제공격할 수 있고 자신의 회피율을 높인다." "effect": "맹렬한 속도의 전격 공격. 반드시 선제공격할 수 있고 급소에 맞는다."
}, },
"splishySplash": { "splishySplash": {
"name": "참방참방서핑", "name": "참방참방서핑",
@ -3807,4 +3807,4 @@
"name": "악독사슬", "name": "악독사슬",
"effect": "독으로 된 사슬로 상대를 휘감은 뒤 독소를 흘려보내어 해치운다. 맹독 상태로 만들 때가 있다." "effect": "독으로 된 사슬로 상대를 휘감은 뒤 독소를 흘려보내어 해치운다. 맹독 상태로 만들 때가 있다."
} }
} }

View File

@ -2913,7 +2913,7 @@
}, },
"zippyZap": { "zippyZap": {
"name": "Zippy Zap", "name": "Zippy Zap",
"effect": "O usuário ataca o alvo com rajadas de eletricidade em alta velocidade. Esse movimento sempre vai primeiro e aumenta a Evasão do usuário." "effect": "O usuário ataca o alvo com rajadas de eletricidade em alta velocidade. Esse movimento sempre vai primeiro e resulta em um golpe crítico."
}, },
"splishySplash": { "splishySplash": {
"name": "Splishy Splash", "name": "Splishy Splash",
@ -3807,4 +3807,4 @@
"name": "Malignant Chain", "name": "Malignant Chain",
"effect": "O usuário derrama toxinas no alvo envolvendo-o em uma corrente tóxica e corrosiva. Isso também pode deixar o alvo seriamente envenenado." "effect": "O usuário derrama toxinas no alvo envolvendo-o em uma corrente tóxica e corrosiva. Isso também pode deixar o alvo seriamente envenenado."
} }
} }

View File

@ -2913,7 +2913,7 @@
}, },
"zippyZap": { "zippyZap": {
"name": "电电加速", "name": "电电加速",
"effect": "迅猛无比的电击。必定能够先制攻击,\n并且提高自己的闪避率。" "effect": "迅猛无比的电击。必定能够先制攻击,击中对方的要害。"
}, },
"splishySplash": { "splishySplash": {
"name": "滔滔冲浪", "name": "滔滔冲浪",
@ -3807,4 +3807,4 @@
"name": "邪毒锁链", "name": "邪毒锁链",
"effect": "用由毒形成的锁链缠住对手注入毒\n素加以侵蚀。有时会让对手陷入剧毒状态" "effect": "用由毒形成的锁链缠住对手注入毒\n素加以侵蚀。有时会让对手陷入剧毒状态"
} }
} }

View File

@ -311,8 +311,6 @@ export class MoveEffectPhase extends PokemonPhase {
} }
end() { end() {
const move = this.move.getMove();
move.type = move.defaultType;
const user = this.getUserPokemon(); const user = this.getUserPokemon();
/** /**
* If this phase isn't for the invoked move's last strike, * If this phase isn't for the invoked move's last strike,

View File

@ -1,19 +1,18 @@
import { Abilities } from "#app/enums/abilities.js";
import GameManager from "#test/utils/gameManager";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { SPLASH_ONLY } from "#test/utils/testUtils";
import { WeatherType } from "#app/enums/weather-type";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase"; import { allAbilities } from "#app/data/ability";
import { Abilities } from "#app/enums/abilities";
import { WeatherType } from "#app/enums/weather-type";
import { DamagePhase } from "#app/phases/damage-phase"; import { DamagePhase } from "#app/phases/damage-phase";
import { MovePhase } from "#app/phases/move-phase"; import { MovePhase } from "#app/phases/move-phase";
import { PostSummonPhase } from "#app/phases/post-summon-phase"; import { PostSummonPhase } from "#app/phases/post-summon-phase";
import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase";
import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { VictoryPhase } from "#app/phases/victory-phase"; import { Moves } from "#enums/moves";
import { allAbilities } from "#app/data/ability"; import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager";
import { SPLASH_ONLY } from "#test/utils/testUtils";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
describe("Abilities - Forecast", () => { describe("Abilities - Forecast", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -31,7 +30,7 @@ describe("Abilities - Forecast", () => {
* @param initialForm The initial form pre form change * @param initialForm The initial form pre form change
*/ */
const testWeatherFormChange = async (game: GameManager, weather: WeatherType, form: number, initialForm?: number) => { const testWeatherFormChange = async (game: GameManager, weather: WeatherType, form: number, initialForm?: number) => {
game.override.weather(weather).starterForms({[Species.CASTFORM]: initialForm}); game.override.weather(weather).starterForms({ [Species.CASTFORM]: initialForm });
await game.startBattle([Species.CASTFORM]); await game.startBattle([Species.CASTFORM]);
game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH);
@ -53,54 +52,6 @@ describe("Abilities - Forecast", () => {
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(NORMAL_FORM); expect(game.scene.getPlayerPokemon()?.formIndex).toBe(NORMAL_FORM);
}; };
/**
* Tests transforming back to match the weather when Cloud Nine/Air Lock user is fainted
* @param {GameManager} game The game manager instance
* @param {Abilities} ability The ability that will go out of battle (faint)
*/
const testTransformAfterAbilityFaint = async (game: GameManager, ability: Abilities) => {
game.override.enemyAbility(ability).weather(WeatherType.SNOW).enemySpecies(Species.SHUCKLE);
await game.startBattle([Species.CASTFORM]);
const castform = game.scene.getPlayerPokemon();
expect(castform?.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.TACKLE);
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
await game.phaseInterceptor.to(DamagePhase);
await game.doKillOpponents();
await game.phaseInterceptor.to(VictoryPhase);
expect(castform?.formIndex).toBe(SNOWY_FORM);
};
/**
* Tests transforming back to match the weather when Cloud Nine/Air Lock user is switched out
* @param {GameManager} game The game manager instance
* @param {Abilities} ability The ability that will go out of battle (switched out)
*/
const testTransformAfterAbilitySwitchOut = async (game: GameManager, ability: Abilities) => {
game.override
.weather(WeatherType.SNOW)
.enemySpecies(Species.CASTFORM)
.enemyAbility(Abilities.FORECAST)
.ability(ability);
await game.startBattle([Species.PICHU, Species.PIKACHU]);
const castform = game.scene.getEnemyPokemon();
// We mock the return value of the second Pokemon to be other than Air Lock/Cloud Nine
vi.spyOn(game.scene.getParty()[1]!, "getAbility").mockReturnValue(allAbilities[Abilities.BALL_FETCH]);
expect(game.scene.getParty()[1]?.hasAbility(Abilities.BALL_FETCH));
expect(castform?.formIndex).toBe(NORMAL_FORM);
game.doSwitchPokemon(1);
await game.phaseInterceptor.to(MovePhase);
expect(castform?.formIndex).toBe(SNOWY_FORM);
};
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -113,55 +64,127 @@ describe("Abilities - Forecast", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override.moveset([ Moves.SPLASH, Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.TACKLE ]) game.override
.moveset([Moves.SPLASH, Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.TACKLE])
.enemySpecies(Species.MAGIKARP)
.enemyMoveset(SPLASH_ONLY) .enemyMoveset(SPLASH_ONLY)
.enemyAbility(Abilities.BALL_FETCH); .enemyAbility(Abilities.BALL_FETCH);
}); });
it("changes to Sunny Form during Harsh Sunlight", async () => { it("changes form based on weather", async () => {
await testWeatherFormChange(game, WeatherType.SUNNY, SUNNY_FORM); game.override
}); .moveset([Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.SNOWSCAPE, Moves.SPLASH])
.battleType("double")
.starterForms({
[Species.KYOGRE]: 1,
[Species.GROUDON]: 1,
[Species.RAYQUAZA]: 1
});
await game.startBattle([Species.CASTFORM, Species.FEEBAS, Species.KYOGRE, Species.GROUDON, Species.RAYQUAZA, Species.ALTARIA]);
it("changes to Sunny Form during Extreme Harsh Sunlight", async () => { vi.spyOn(game.scene.getParty()[5], "getAbility").mockReturnValue(allAbilities[Abilities.CLOUD_NINE]);
await testWeatherFormChange(game, WeatherType.HARSH_SUN, SUNNY_FORM);
});
it("changes to Rainy Form during Rain", async () => { const castform = game.scene.getPlayerField()[0];
await testWeatherFormChange(game, WeatherType.RAIN, RAINY_FORM); expect(castform.formIndex).toBe(NORMAL_FORM);
});
it("changes to Rainy Form during Heavy Rain", async () => { game.move.select(Moves.RAIN_DANCE);
await testWeatherFormChange(game, WeatherType.HEAVY_RAIN, RAINY_FORM); game.move.select(Moves.SPLASH, 1);
}); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
it("changes to Snowy Form during Hail", async () => { expect(castform.formIndex).toBe(RAINY_FORM);
await testWeatherFormChange(game, WeatherType.HAIL, SNOWY_FORM);
});
it("changes to Snowy Form during Snow", async () => { game.move.select(Moves.SUNNY_DAY);
await testWeatherFormChange(game, WeatherType.SNOW, SNOWY_FORM); game.move.select(Moves.SPLASH, 1);
}); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
it("reverts to Normal Form during Sandstorm", async () => { expect(castform.formIndex).toBe(SUNNY_FORM);
await testWeatherFormChange(game, WeatherType.SANDSTORM, NORMAL_FORM, SUNNY_FORM);
});
it("reverts to Normal Form during Fog", async () => { game.move.select(Moves.SNOWSCAPE);
await testWeatherFormChange(game, WeatherType.FOG, NORMAL_FORM, SUNNY_FORM); game.move.select(Moves.SPLASH, 1);
}); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
it("reverts to Normal Form during Strong Winds", async () => { expect(castform.formIndex).toBe(SNOWY_FORM);
await testWeatherFormChange(game, WeatherType.STRONG_WINDS, NORMAL_FORM, SUNNY_FORM);
}); game.override.moveset([Moves.HAIL, Moves.SANDSTORM, Moves.SNOWSCAPE, Moves.SPLASH]);
game.move.select(Moves.SANDSTORM);
game.move.select(Moves.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.HAIL);
game.move.select(Moves.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(SNOWY_FORM);
game.move.select(Moves.SPLASH);
game.doSwitchPokemon(2); // Feebas now 2, Kyogre 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(RAINY_FORM);
game.move.select(Moves.SPLASH);
game.doSwitchPokemon(3); // Kyogre now 3, Groudon 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(SUNNY_FORM);
game.move.select(Moves.SPLASH);
game.doSwitchPokemon(4); // Groudon now 4, Rayquaza 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.SPLASH);
game.doSwitchPokemon(2); // Rayquaza now 2, Feebas 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.SNOWSCAPE);
game.move.select(Moves.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(SNOWY_FORM);
game.move.select(Moves.SPLASH);
game.doSwitchPokemon(5); // Feebas now 5, Altaria 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.SPLASH);
game.doSwitchPokemon(5); // Altaria now 5, Feebas 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(SNOWY_FORM);
game.scene.arena.trySetWeather(WeatherType.FOG, false);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
await game.phaseInterceptor.to("TurnStartPhase");
expect(castform.formIndex).toBe(NORMAL_FORM);
}, 30 * 1000);
it("reverts to Normal Form during Clear weather", async () => { it("reverts to Normal Form during Clear weather", async () => {
await testWeatherFormChange(game, WeatherType.NONE, NORMAL_FORM, SUNNY_FORM); await testWeatherFormChange(game, WeatherType.NONE, NORMAL_FORM, SUNNY_FORM);
}); });
it("reverts to Normal Form if a Pokémon on the field has Cloud Nine", async () => {
await testRevertFormAgainstAbility(game, Abilities.CLOUD_NINE);
});
it("reverts to Normal Form if a Pokémon on the field has Air Lock", async () => { it("reverts to Normal Form if a Pokémon on the field has Air Lock", async () => {
await testRevertFormAgainstAbility(game, Abilities.AIR_LOCK); await testRevertFormAgainstAbility(game, Abilities.AIR_LOCK);
}); });
@ -177,93 +200,50 @@ describe("Abilities - Forecast", () => {
expect(game.scene.getEnemyPokemon()?.formIndex).not.toBe(RAINY_FORM); expect(game.scene.getEnemyPokemon()?.formIndex).not.toBe(RAINY_FORM);
}); });
it("cannot be copied", async () => { it("reverts to Normal Form when Castform loses Forecast, changes form to match the weather when it regains it", async () => {
game.override.enemyAbility(Abilities.TRACE); game.override.moveset([Moves.SKILL_SWAP, Moves.WORRY_SEED, Moves.SPLASH]).weather(WeatherType.RAIN).battleType("double");
await game.startBattle([Species.CASTFORM]); await game.startBattle([Species.CASTFORM, Species.FEEBAS]);
game.move.select(Moves.SPLASH); const castform = game.scene.getPlayerField()[0];
expect(game.scene.getEnemyPokemon()?.hasAbility(Abilities.FORECAST)).toBe(false); expect(castform.formIndex).toBe(RAINY_FORM);
});
it("(Skill Swap) reverts to Normal Form when Castform loses Forecast, changes form to match the weather when it regains it", async () => { game.move.select(Moves.SKILL_SWAP, 0, BattlerIndex.PLAYER_2);
game.override.moveset([Moves.SKILL_SWAP]).weather(WeatherType.RAIN); game.move.select(Moves.SKILL_SWAP, 1, BattlerIndex.PLAYER);
await game.startBattle([Species.CASTFORM]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
const castform = game.scene.getPlayerPokemon();
expect(castform?.formIndex).toBe(RAINY_FORM); await game.phaseInterceptor.to("MoveEndPhase");
expect(castform.formIndex).toBe(NORMAL_FORM);
// First turn - loses Forecast await game.phaseInterceptor.to("MoveEndPhase");
game.move.select(Moves.SKILL_SWAP); expect(castform.formIndex).toBe(RAINY_FORM);
await game.phaseInterceptor.to(TurnEndPhase);
expect(castform?.formIndex).toBe(NORMAL_FORM);
// Second turn - regains Forecast
game.move.select(Moves.SKILL_SWAP);
await game.phaseInterceptor.to(TurnEndPhase);
expect(castform?.formIndex).toBe(RAINY_FORM);
});
it("(Worry Seed) reverts to Normal Form when Castform loses Forecast, changes form to match the weather when it regains it", async () => {
game.override.enemyMoveset(Array(4).fill(Moves.WORRY_SEED)).weather(WeatherType.RAIN);
await game.startBattle([Species.CASTFORM, Species.PIKACHU]);
const castform = game.scene.getPlayerPokemon();
expect(castform?.formIndex).toBe(RAINY_FORM);
// First turn - loses Forecast
game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
expect(castform?.formIndex).toBe(NORMAL_FORM);
await game.toNextTurn(); await game.toNextTurn();
// Second turn - switch out Castform, regains Forecast game.move.select(Moves.SPLASH);
game.doSwitchPokemon(1); game.move.select(Moves.WORRY_SEED, 1, BattlerIndex.PLAYER);
await game.toNextTurn(); await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to("MoveEndPhase");
// Third turn - switch in Castform expect(castform.formIndex).toBe(NORMAL_FORM);
game.doSwitchPokemon(1);
await game.phaseInterceptor.to(MovePhase);
expect(castform?.formIndex).toBe(RAINY_FORM);
});
it("reverts to Normal Form when active weather ends", async () => {
await game.startBattle([Species.CASTFORM]);
const castform = game.scene.getPlayerPokemon();
game.move.select(Moves.SUNNY_DAY);
await game.phaseInterceptor.to(TurnEndPhase);
while (game.scene.arena.weather && game.scene.arena.weather.turnsLeft > 0) {
game.move.select(Moves.SPLASH);
expect(castform?.formIndex).toBe(SUNNY_FORM);
await game.toNextTurn();
}
expect(castform?.formIndex).toBe(NORMAL_FORM);
}); });
it("reverts to Normal Form when Forecast is suppressed, changes form to match the weather when it regains it", async () => { it("reverts to Normal Form when Forecast is suppressed, changes form to match the weather when it regains it", async () => {
game.override.enemyMoveset(Array(4).fill(Moves.GASTRO_ACID)).weather(WeatherType.RAIN); game.override.enemyMoveset(Array(4).fill(Moves.GASTRO_ACID)).weather(WeatherType.RAIN);
await game.startBattle([Species.CASTFORM, Species.PIKACHU]); await game.startBattle([Species.CASTFORM, Species.PIKACHU]);
const castform = game.scene.getPlayerPokemon(); const castform = game.scene.getPlayerPokemon()!;
expect(castform?.formIndex).toBe(RAINY_FORM); expect(castform.formIndex).toBe(RAINY_FORM);
// First turn - Forecast is suppressed // First turn - Forecast is suppressed
game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH);
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.move.forceHit(); await game.move.forceHit();
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(castform?.summonData.abilitySuppressed).toBe(true); expect(castform.summonData.abilitySuppressed).toBe(true);
expect(castform?.formIndex).toBe(NORMAL_FORM); expect(castform.formIndex).toBe(NORMAL_FORM);
await game.toNextTurn(); await game.toNextTurn();
@ -275,21 +255,8 @@ describe("Abilities - Forecast", () => {
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
await game.phaseInterceptor.to(MovePhase); await game.phaseInterceptor.to(MovePhase);
expect(castform?.summonData.abilitySuppressed).toBe(false); expect(castform.summonData.abilitySuppressed).toBe(false);
expect(castform?.formIndex).toBe(RAINY_FORM); expect(castform.formIndex).toBe(RAINY_FORM);
});
it("if a Pokémon transforms into Castform, the Pokémon will remain in the same form as the target Castform, regardless of the weather", async () => {
game.override.enemyMoveset(Array(4).fill(Moves.TRANSFORM));
await game.startBattle([Species.CASTFORM]);
game.move.select(Moves.SUNNY_DAY);
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
await game.phaseInterceptor.to(TurnEndPhase);
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(SUNNY_FORM);
expect(game.scene.getEnemyPokemon()?.formIndex).toBe(NORMAL_FORM);
}); });
it("does not change Castform's form until after Stealth Rock deals damage", async () => { it("does not change Castform's form until after Stealth Rock deals damage", async () => {
@ -304,31 +271,15 @@ describe("Abilities - Forecast", () => {
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
await game.phaseInterceptor.to(PostSummonPhase); await game.phaseInterceptor.to(PostSummonPhase);
const castform = game.scene.getPlayerPokemon(); const castform = game.scene.getPlayerPokemon()!;
// Damage phase should come first // Damage phase should come first
await game.phaseInterceptor.to(DamagePhase); await game.phaseInterceptor.to(DamagePhase);
expect(castform?.hp).toBeLessThan(castform?.getMaxHp() ?? 0); expect(castform.hp).toBeLessThan(castform.getMaxHp());
// Then change form // Then change form
await game.phaseInterceptor.to(QuietFormChangePhase); await game.phaseInterceptor.to(QuietFormChangePhase);
expect(castform?.formIndex).toBe(RAINY_FORM); expect(castform.formIndex).toBe(RAINY_FORM);
});
it("transforms to weather-based form when Pokemon with Air Lock is fainted", async () => {
await testTransformAfterAbilityFaint(game, Abilities.AIR_LOCK);
});
it("transforms to weather-based form when Pokemon with Cloud Nine is fainted", async () => {
await testTransformAfterAbilityFaint(game, Abilities.CLOUD_NINE);
});
it("transforms to weather-based form when Pokemon with Air Lock is switched out", async () => {
await testTransformAfterAbilitySwitchOut(game, Abilities.AIR_LOCK);
});
it("transforms to weather-based form when Pokemon with Cloud Nine is switched out", async () => {
await testTransformAfterAbilitySwitchOut(game, Abilities.CLOUD_NINE);
}); });
it("should be in Normal Form after the user is switched out", async () => { it("should be in Normal Form after the user is switched out", async () => {

View File

@ -0,0 +1,133 @@
import { BattlerIndex } from "#app/battle";
import { allMoves } from "#app/data/move";
import { Type } from "#app/data/type";
import { Abilities } from "#app/enums/abilities";
import { Moves } from "#app/enums/moves";
import { Species } from "#app/enums/species";
import { HitResult } from "#app/field/pokemon";
import GameManager from "#test/utils/gameManager";
import { SPLASH_ONLY } from "#test/utils/testUtils";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - Galvanize", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.battleType("single")
.startingLevel(100)
.ability(Abilities.GALVANIZE)
.moveset([Moves.TACKLE, Moves.REVELATION_DANCE, Moves.FURY_SWIPES])
.enemySpecies(Species.DUSCLOPS)
.enemyAbility(Abilities.BALL_FETCH)
.enemyMoveset(SPLASH_ONLY)
.enemyLevel(100);
});
it("should change Normal-type attacks to Electric type and boost their power", async () => {
await game.startBattle();
const playerPokemon = game.scene.getPlayerPokemon()!;
vi.spyOn(playerPokemon, "getMoveType");
const enemyPokemon = game.scene.getEnemyPokemon()!;
vi.spyOn(enemyPokemon, "apply");
const move = allMoves[Moves.TACKLE];
vi.spyOn(move, "calculateBattlePower");
game.move.select(Moves.TACKLE);
await game.phaseInterceptor.to("BerryPhase", false);
expect(playerPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC);
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.EFFECTIVE);
expect(move.calculateBattlePower).toHaveReturnedWith(48);
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
}, TIMEOUT);
it("should cause Normal-type attacks to activate Volt Absorb", async () => {
game.override.enemyAbility(Abilities.VOLT_ABSORB);
await game.startBattle();
const playerPokemon = game.scene.getPlayerPokemon()!;
vi.spyOn(playerPokemon, "getMoveType");
const enemyPokemon = game.scene.getEnemyPokemon()!;
vi.spyOn(enemyPokemon, "apply");
enemyPokemon.hp = Math.floor(enemyPokemon.getMaxHp() * 0.8);
game.move.select(Moves.TACKLE);
await game.phaseInterceptor.to("BerryPhase", false);
expect(playerPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC);
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.NO_EFFECT);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
}, TIMEOUT);
it("should not change the type of variable-type moves", async () => {
game.override.enemySpecies(Species.MIGHTYENA);
await game.startBattle([Species.ESPEON]);
const playerPokemon = game.scene.getPlayerPokemon()!;
vi.spyOn(playerPokemon, "getMoveType");
const enemyPokemon = game.scene.getEnemyPokemon()!;
vi.spyOn(enemyPokemon, "apply");
game.move.select(Moves.REVELATION_DANCE);
await game.phaseInterceptor.to("BerryPhase", false);
expect(playerPokemon.getMoveType).not.toHaveLastReturnedWith(Type.ELECTRIC);
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.NO_EFFECT);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
}, TIMEOUT);
it("should affect all hits of a Normal-type multi-hit move", async () => {
await game.startBattle();
const playerPokemon = game.scene.getPlayerPokemon()!;
vi.spyOn(playerPokemon, "getMoveType");
const enemyPokemon = game.scene.getEnemyPokemon()!;
vi.spyOn(enemyPokemon, "apply");
game.move.select(Moves.FURY_SWIPES);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
await game.move.forceHit();
await game.phaseInterceptor.to("MoveEffectPhase");
expect(playerPokemon.turnData.hitCount).toBeGreaterThan(1);
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
while (playerPokemon.turnData.hitsLeft > 0) {
const enemyStartingHp = enemyPokemon.hp;
await game.phaseInterceptor.to("MoveEffectPhase");
expect(playerPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC);
expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp);
}
expect(enemyPokemon.apply).not.toHaveReturnedWith(HitResult.NO_EFFECT);
}, TIMEOUT);
});

View File

@ -76,7 +76,7 @@ describe("Abilities - Libero", () => {
expect(leadPokemon.summonData.abilitiesApplied.filter((a) => a === Abilities.LIBERO)).toHaveLength(1); expect(leadPokemon.summonData.abilitiesApplied.filter((a) => a === Abilities.LIBERO)).toHaveLength(1);
const leadPokemonType = Type[leadPokemon.getTypes()[0]]; const leadPokemonType = Type[leadPokemon.getTypes()[0]];
const moveType = Type[allMoves[Moves.AGILITY].defaultType]; const moveType = Type[allMoves[Moves.AGILITY].type];
expect(leadPokemonType).not.toBe(moveType); expect(leadPokemonType).not.toBe(moveType);
await game.toNextTurn(); await game.toNextTurn();
@ -249,7 +249,7 @@ describe("Abilities - Libero", () => {
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
leadPokemon.summonData.types = [allMoves[Moves.SPLASH].defaultType]; leadPokemon.summonData.types = [allMoves[Moves.SPLASH].type];
game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
@ -357,6 +357,6 @@ function testPokemonTypeMatchesDefaultMoveType(pokemon: PlayerPokemon, move: Mov
expect(pokemon.summonData.abilitiesApplied).toContain(Abilities.LIBERO); expect(pokemon.summonData.abilitiesApplied).toContain(Abilities.LIBERO);
expect(pokemon.getTypes()).toHaveLength(1); expect(pokemon.getTypes()).toHaveLength(1);
const pokemonType = Type[pokemon.getTypes()[0]], const pokemonType = Type[pokemon.getTypes()[0]],
moveType = Type[allMoves[move].defaultType]; moveType = Type[allMoves[move].type];
expect(pokemonType).toBe(moveType); expect(pokemonType).toBe(moveType);
} }

View File

@ -76,7 +76,7 @@ describe("Abilities - Protean", () => {
expect(leadPokemon.summonData.abilitiesApplied.filter((a) => a === Abilities.PROTEAN)).toHaveLength(1); expect(leadPokemon.summonData.abilitiesApplied.filter((a) => a === Abilities.PROTEAN)).toHaveLength(1);
const leadPokemonType = Type[leadPokemon.getTypes()[0]]; const leadPokemonType = Type[leadPokemon.getTypes()[0]];
const moveType = Type[allMoves[Moves.AGILITY].defaultType]; const moveType = Type[allMoves[Moves.AGILITY].type];
expect(leadPokemonType).not.toBe(moveType); expect(leadPokemonType).not.toBe(moveType);
await game.toNextTurn(); await game.toNextTurn();
@ -249,7 +249,7 @@ describe("Abilities - Protean", () => {
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
leadPokemon.summonData.types = [allMoves[Moves.SPLASH].defaultType]; leadPokemon.summonData.types = [allMoves[Moves.SPLASH].type];
game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
@ -357,6 +357,6 @@ function testPokemonTypeMatchesDefaultMoveType(pokemon: PlayerPokemon, move: Mov
expect(pokemon.summonData.abilitiesApplied).toContain(Abilities.PROTEAN); expect(pokemon.summonData.abilitiesApplied).toContain(Abilities.PROTEAN);
expect(pokemon.getTypes()).toHaveLength(1); expect(pokemon.getTypes()).toHaveLength(1);
const pokemonType = Type[pokemon.getTypes()[0]], const pokemonType = Type[pokemon.getTypes()[0]],
moveType = Type[allMoves[move].defaultType]; moveType = Type[allMoves[move].type];
expect(pokemonType).toBe(moveType); expect(pokemonType).toBe(moveType);
} }

View File

@ -0,0 +1,70 @@
import { allMoves } from "#app/data/move";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { TrainerSlot } from "#app/data/trainer-config";
import { Abilities } from "#app/enums/abilities";
import { Moves } from "#app/enums/moves";
import { Species } from "#app/enums/species";
import * as Messages from "#app/messages";
import GameManager from "#test/utils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
function testMoveEffectiveness(game: GameManager, move: Moves, targetSpecies: Species,
expected: number, targetAbility: Abilities = Abilities.BALL_FETCH): void {
// Suppress getPokemonNameWithAffix because it calls on a null battle spec
vi.spyOn(Messages, "getPokemonNameWithAffix").mockReturnValue("");
game.override.enemyAbility(targetAbility);
const user = game.scene.addPlayerPokemon(getPokemonSpecies(Species.SNORLAX), 5);
const target = game.scene.addEnemyPokemon(getPokemonSpecies(targetSpecies), 5, TrainerSlot.NONE);
expect(target.getMoveEffectiveness(user, allMoves[move])).toBe(expected);
}
describe("Moves - Type Effectiveness", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
game = new GameManager(phaserGame);
game.override.ability(Abilities.BALL_FETCH);
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
it("Normal-type attacks are neutrally effective against Normal-type Pokemon",
() => testMoveEffectiveness(game, Moves.TACKLE, Species.SNORLAX, 1)
);
it("Normal-type attacks are not very effective against Steel-type Pokemon",
() => testMoveEffectiveness(game, Moves.TACKLE, Species.REGISTEEL, 0.5)
);
it("Normal-type attacks are doubly resisted by Steel/Rock-type Pokemon",
() => testMoveEffectiveness(game, Moves.TACKLE, Species.AGGRON, 0.25)
);
it("Normal-type attacks have no effect on Ghost-type Pokemon",
() => testMoveEffectiveness(game, Moves.TACKLE, Species.DUSCLOPS, 0)
);
it("Normal-type status moves are not affected by type matchups",
() => testMoveEffectiveness(game, Moves.GROWL, Species.DUSCLOPS, 1)
);
it("Electric-type attacks are super-effective against Water-type Pokemon",
() => testMoveEffectiveness(game, Moves.THUNDERBOLT, Species.BLASTOISE, 2)
);
it("Electric-type attacks are doubly super-effective against Water/Flying-type Pokemon",
() => testMoveEffectiveness(game, Moves.THUNDERBOLT, Species.GYARADOS, 4)
);
it("Electric-type attacks are negated by Volt Absorb",
() => testMoveEffectiveness(game, Moves.THUNDERBOLT, Species.GYARADOS, 0, Abilities.VOLT_ABSORB)
);
});

View File

@ -0,0 +1,83 @@
import { StatusEffect } from "#app/enums/status-effect.js";
import { CommandPhase } from "#app/phases/command-phase.js";
import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager";
import { SPLASH_ONLY } from "#test/utils/testUtils";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
describe("Moves - Lunar Blessing", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({ type: Phaser.HEADLESS });
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override.battleType("double");
game.override.enemySpecies(Species.SHUCKLE);
game.override.enemyMoveset(SPLASH_ONLY);
game.override.enemyAbility(Abilities.BALL_FETCH);
game.override.moveset([Moves.LUNAR_BLESSING, Moves.SPLASH]);
game.override.ability(Abilities.BALL_FETCH);
});
it("should restore 25% HP of the user and its ally", async () => {
await game.startBattle([Species.RATTATA, Species.RATTATA]);
const [leftPlayer, rightPlayer] = game.scene.getPlayerField();
vi.spyOn(leftPlayer, "getMaxHp").mockReturnValue(100);
vi.spyOn(rightPlayer, "getMaxHp").mockReturnValue(100);
const initialHp = 1;
leftPlayer["hp"] = initialHp;
rightPlayer["hp"] = initialHp;
const expectedHeal = 25;
vi.spyOn(leftPlayer, "heal");
vi.spyOn(rightPlayer, "heal");
game.move.select(Moves.LUNAR_BLESSING, 0);
await game.phaseInterceptor.to(CommandPhase);
game.move.select(Moves.SPLASH, 1);
await game.toNextTurn();
expect(leftPlayer.heal).toHaveBeenCalledOnce();
expect(leftPlayer.heal).toHaveReturnedWith(expectedHeal);
expect(rightPlayer.heal).toHaveBeenCalledOnce();
expect(rightPlayer.heal).toHaveReturnedWith(expectedHeal);
});
it("should cure status effect of the user and its ally", async () => {
game.override.statusEffect(StatusEffect.BURN);
await game.startBattle([Species.RATTATA, Species.RATTATA]);
const [leftPlayer, rightPlayer] = game.scene.getPlayerField();
vi.spyOn(leftPlayer, "resetStatus");
vi.spyOn(rightPlayer, "resetStatus");
game.move.select(Moves.LUNAR_BLESSING, 0);
await game.phaseInterceptor.to(CommandPhase);
game.move.select(Moves.SPLASH, 1);
await game.toNextTurn();
expect(leftPlayer.resetStatus).toHaveBeenCalledOnce();
expect(rightPlayer.resetStatus).toHaveBeenCalledOnce();
expect(leftPlayer.status?.effect).toBeUndefined();
expect(rightPlayer.status?.effect).toBeUndefined();
});
});

View File

@ -1,7 +1,7 @@
import { getMoveTargets } from "#app/data/move"; import { BattlerIndex } from "#app/battle";
import { Abilities } from "#app/enums/abilities"; import { Abilities } from "#app/enums/abilities";
import { Species } from "#app/enums/species"; import { Species } from "#app/enums/species";
import { TurnEndPhase } from "#app/phases/turn-end-phase"; import * as Utils from "#app/utils";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import { SPLASH_ONLY } from "#test/utils/testUtils"; import { SPLASH_ONLY } from "#test/utils/testUtils";
@ -10,7 +10,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000; const TIMEOUT = 20 * 1000;
describe("Moves - Multi target", () => { describe("Multi-target damage reduction", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
@ -21,160 +21,111 @@ describe("Moves - Multi target", () => {
}); });
afterEach(() => { afterEach(() => {
afterTrial(game); game.phaseInterceptor.restoreOg();
}); });
beforeEach(() => { beforeEach(() => {
game = beforeTrial(phaserGame); game = new GameManager(phaserGame);
game.override
.disableCrits()
.battleType("double")
.enemyLevel(100)
.startingLevel(100)
.enemySpecies(Species.POLIWAG)
.enemyMoveset(SPLASH_ONLY)
.enemyAbility(Abilities.BALL_FETCH)
.moveset([Moves.TACKLE, Moves.DAZZLING_GLEAM, Moves.EARTHQUAKE, Moves.SPLASH])
.ability(Abilities.BALL_FETCH);
}); });
it("2v2 - target all near others - check modifier", () => checkTargetMultiplier(game, Moves.EARTHQUAKE, false, false, true), TIMEOUT); it("should reduce d.gleam damage when multiple enemies but not tackle", async () => {
await game.startBattle([Species.MAGIKARP, Species.FEEBAS]);
it("2v2 - target all near others - damage decrase", () => checkDamageDecrease(game, Moves.EARTHQUAKE, false, false, true), TIMEOUT); const [enemy1, enemy2] = game.scene.getEnemyField();
it("2v1 - target all near others - check modifier", () => checkTargetMultiplier(game, Moves.EARTHQUAKE, false, true, true), TIMEOUT); game.move.select(Moves.DAZZLING_GLEAM);
game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to("MoveEndPhase");
it("2v1 - target all near others - damage decrase", () => checkDamageDecrease(game, Moves.EARTHQUAKE, false, true, true), TIMEOUT); const gleam1 = enemy1.getMaxHp() - enemy1.hp;
enemy1.hp = enemy1.getMaxHp();
it("1v2 - target all near others - check modifier", () => checkTargetMultiplier(game, Moves.EARTHQUAKE, true, false, true), TIMEOUT); await game.phaseInterceptor.to("MoveEndPhase");
it("1v2 - target all near others - damage decrase", () => checkDamageDecrease(game, Moves.EARTHQUAKE, true, false, true), TIMEOUT); const tackle1 = enemy1.getMaxHp() - enemy1.hp;
enemy1.hp = enemy1.getMaxHp();
it("1v1 - target all near others - check modifier", () => checkTargetMultiplier(game, Moves.EARTHQUAKE, true, true, false), TIMEOUT); await game.killPokemon(enemy2);
await game.toNextTurn();
it("2v2 (immune) - target all near others - check modifier", () => checkTargetMultiplier(game, Moves.EARTHQUAKE, false, false, true, Abilities.LEVITATE), TIMEOUT); game.move.select(Moves.DAZZLING_GLEAM);
game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]);
it("2v2 (immune) - target all near others - damage decrase", () => checkDamageDecrease(game, Moves.EARTHQUAKE, false, false, true, Abilities.LEVITATE), TIMEOUT); await game.phaseInterceptor.to("MoveEndPhase");
it("2v2 - target all near enemies - check modifier", () => checkTargetMultiplier(game, Moves.HYPER_VOICE, false, false, true), TIMEOUT); const gleam2 = enemy1.getMaxHp() - enemy1.hp;
enemy1.hp = enemy1.getMaxHp();
it("2v2 - target all near enemies - damage decrase", () => checkDamageDecrease(game, Moves.HYPER_VOICE, false, false, true), TIMEOUT); await game.phaseInterceptor.to("MoveEndPhase");
const tackle2 = enemy1.getMaxHp() - enemy1.hp;
it("2v1 - target all near enemies - check modifier", () => checkTargetMultiplier(game, Moves.HYPER_VOICE, false, true, false), TIMEOUT); // Single target moves don't get reduced
expect(tackle1).toBe(tackle2);
// Moves that target all enemies get reduced if there's more than one enemy
expect(gleam1).toBeLessThanOrEqual(Utils.toDmgValue(gleam2 * 0.75) + 1);
expect(gleam1).toBeGreaterThanOrEqual(Utils.toDmgValue(gleam2 * 0.75) - 1);
}, TIMEOUT);
it("2v1 - target all near enemies - no damage decrase", () => checkDamageDecrease(game, Moves.HYPER_VOICE, false, true, false), TIMEOUT); it("should reduce earthquake when more than one pokemon other than user is not fainted", async () => {
await game.startBattle([Species.MAGIKARP, Species.FEEBAS]);
it("1v2 - target all near enemies - check modifier", () => checkTargetMultiplier(game, Moves.HYPER_VOICE, true, false, true), TIMEOUT); const player2 = game.scene.getParty()[1];
const [enemy1, enemy2] = game.scene.getEnemyField();
it("1v2 - target all near enemies - damage decrase", () => checkDamageDecrease(game, Moves.HYPER_VOICE, true, false, true), TIMEOUT); game.move.select(Moves.EARTHQUAKE);
it("1v1 - target all near enemies - check modifier", () => checkTargetMultiplier(game, Moves.HYPER_VOICE, true, true, false), TIMEOUT);
it("2v2 (immune) - target all near enemies - check modifier", () => checkTargetMultiplier(game, Moves.HYPER_VOICE, false, false, true, Abilities.SOUNDPROOF), TIMEOUT);
it("2v2 (immune) - target all near enemies - damage decrase", () => checkDamageDecrease(game, Moves.HYPER_VOICE, false, false, true, Abilities.SOUNDPROOF), TIMEOUT);
});
async function checkTargetMultiplier(game: GameManager, attackMove: Moves, killAlly: boolean, killSecondEnemy: boolean, shouldMultiplied: boolean, oppAbility?: Abilities) {
// play an attack and check target count
game.override.enemyAbility(oppAbility ? oppAbility : Abilities.BALL_FETCH);
await game.startBattle();
const playerPokemonRepr = game.scene.getPlayerField();
killAllyAndEnemy(game, killAlly, killSecondEnemy);
const targetCount = getMoveTargets(playerPokemonRepr[0], attackMove).targets.length;
const targetMultiplier = targetCount > 1 ? 0.75 : 1;
if (shouldMultiplied) {
expect(targetMultiplier).toBe(0.75);
} else {
expect(targetMultiplier).toBe(1);
}
}
async function checkDamageDecrease(game: GameManager, attackMove: Moves, killAlly: boolean, killSecondEnemy: boolean, shouldDecreased: boolean, ability?: Abilities) {
// Tested combination on first turn, 1v1 on second turn
await game.classicMode.runToSummon([Species.EEVEE, Species.EEVEE]);
if (ability !== undefined) {
game.scene.getPlayerField()[1].abilityIndex = ability;
game.scene.getEnemyField()[1].abilityIndex = ability;
}
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
await game.phaseInterceptor.to(TurnEndPhase);
killAllyAndEnemy(game, killAlly, killSecondEnemy);
await game.toNextTurn();
const initialHp = game.scene.getEnemyField()[0].hp;
game.move.select(attackMove);
if (!killAlly) {
game.move.select(Moves.SPLASH, 1); game.move.select(Moves.SPLASH, 1);
} await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("MoveEndPhase");
const afterHp = game.scene.getEnemyField()[0].hp;
killAllyAndEnemy(game, true, true); const damagePlayer2Turn1 = player2.getMaxHp() - player2.hp;
await game.toNextTurn(); const damageEnemy1Turn1 = enemy1.getMaxHp() - enemy1.hp;
game.scene.getEnemyField()[0].hp = initialHp; player2.hp = player2.getMaxHp();
enemy1.hp = enemy1.getMaxHp();
const initialHp1v1 = game.scene.getEnemyField()[0].hp; await game.killPokemon(enemy2);
game.move.select(attackMove); await game.toNextTurn();
await game.phaseInterceptor.to(TurnEndPhase); game.move.select(Moves.EARTHQUAKE);
const afterHp1v1 = game.scene.getEnemyField()[0].hp; game.move.select(Moves.SPLASH, 1);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]);
if (shouldDecreased) { await game.phaseInterceptor.to("MoveEndPhase");
expect(initialHp - afterHp).toBeLessThan(0.75 * (initialHp1v1 - afterHp1v1) + 2);
expect(initialHp - afterHp).toBeGreaterThan(0.75 * (initialHp1v1 - afterHp1v1) - 2);
} else {
expect(initialHp - afterHp).toBeLessThan(initialHp1v1 - afterHp1v1 + 2);
expect(initialHp - afterHp).toBeGreaterThan(initialHp1v1 - afterHp1v1 - 2);
}
} const damagePlayer2Turn2 = player2.getMaxHp() - player2.hp;
const damageEnemy1Turn2 = enemy1.getMaxHp() - enemy1.hp;
// To simulate the situation where all of the enemies or the player's Pokemons dies except for one. enemy1.hp = enemy1.getMaxHp();
function killAllyAndEnemy(game: GameManager, killAlly: boolean, killSecondEnemy: boolean) {
if (killAlly) {
leaveOnePlayerPokemon(game);
expect(game.scene.getPlayerField().filter(p => p.isActive()).length).toBe(1);
}
if (killSecondEnemy) {
leaveOneEnemyPokemon(game);
expect(game.scene.getEnemyField().filter(p => p.isActive()).length).toBe(1);
}
}
function leaveOnePlayerPokemon(game: GameManager) { // Turn 1: 3 targets, turn 2: 2 targets
const playerPokemons = game.scene.getParty(); // Both should have damage reduction
for (let i = 1; i < playerPokemons.length; i++) { expect(damageEnemy1Turn1).toBe(damageEnemy1Turn2);
playerPokemons[i].hp = 0; expect(damagePlayer2Turn1).toBe(damagePlayer2Turn2);
}
expect(playerPokemons.filter(pokemon => pokemon.hp > 0).length).toBe(1);
}
function leaveOneEnemyPokemon(game: GameManager) { await game.killPokemon(player2);
const enemyPokemons = game.scene.getEnemyParty(); await game.toNextTurn();
for (let i = 1; i < enemyPokemons.length; i++) {
enemyPokemons[i].hp = 0;
}
}
function beforeTrial(phaserGame: Phaser.Game, single: boolean = false) { game.move.select(Moves.EARTHQUAKE);
const game = new GameManager(phaserGame); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
game.override
.battleType("double")
.moveset([Moves.EARTHQUAKE, Moves.HYPER_VOICE, Moves.SURF, Moves.SPLASH])
.ability(Abilities.BALL_FETCH)
.passiveAbility(Abilities.UNNERVE)
.enemyMoveset(SPLASH_ONLY)
.disableCrits()
.startingLevel(50)
.enemyLevel(40)
.enemySpecies(Species.EEVEE);
return game;
}
function afterTrial(game: GameManager) { await game.phaseInterceptor.to("MoveEndPhase");
game.phaseInterceptor.restoreOg();
} const damageEnemy1Turn3 = enemy1.getMaxHp() - enemy1.hp;
// Turn 3: 1 target, should be no damage reduction
expect(damageEnemy1Turn1).toBeLessThanOrEqual(Utils.toDmgValue(damageEnemy1Turn3 * 0.75) + 1);
expect(damageEnemy1Turn1).toBeGreaterThanOrEqual(Utils.toDmgValue(damageEnemy1Turn3 * 0.75) - 1);
}, TIMEOUT);
});

View File

@ -62,9 +62,6 @@ describe("Moves - Tera Blast", () => {
it("increases power if user is Stellar tera type", async () => { it("increases power if user is Stellar tera type", async () => {
game.override.startingHeldItems([{ name: "TERA_SHARD", type: Type.STELLAR }]); game.override.startingHeldItems([{ name: "TERA_SHARD", type: Type.STELLAR }]);
const stellarTypeMultiplier = 2;
const stellarTypeDmgBonus = 20;
const basePower = moveToCheck.power;
await game.startBattle(); await game.startBattle();
@ -72,9 +69,25 @@ describe("Moves - Tera Blast", () => {
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith((basePower + stellarTypeDmgBonus) * stellarTypeMultiplier); expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(100);
}, 20000); }, 20000);
it("is super effective against terastallized targets if user is Stellar tera type", async () => {
game.override.startingHeldItems([{ name: "TERA_SHARD", type: Type.STELLAR }]);
await game.startBattle();
const enemyPokemon = game.scene.getEnemyPokemon()!;
vi.spyOn(enemyPokemon, "apply");
vi.spyOn(enemyPokemon, "isTerastallized").mockReturnValue(true);
game.move.select(Moves.TERA_BLAST);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.SUPER_EFFECTIVE);
});
// Currently abilities are bugged and can't see when a move's category is changed // Currently abilities are bugged and can't see when a move's category is changed
it.skip("uses the higher stat of the user's Atk and SpAtk for damage calculation", async () => { it.skip("uses the higher stat of the user's Atk and SpAtk for damage calculation", async () => {
game.override.enemyAbility(Abilities.TOXIC_DEBRIS); game.override.enemyAbility(Abilities.TOXIC_DEBRIS);

View File

@ -0,0 +1,102 @@
import { StatusEffect } from "#app/data/status-effect";
import { Abilities } from "#app/enums/abilities";
import { EnemyPokemon } from "#app/field/pokemon";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { SPLASH_ONLY } from "../utils/testUtils";
const TIMEOUT = 20 * 1000;
describe("Moves - Thunder Wave", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.battleType("single")
.starterSpecies(Species.PIKACHU)
.moveset([Moves.THUNDER_WAVE])
.enemyMoveset(SPLASH_ONLY);
});
// References: https://bulbapedia.bulbagarden.net/wiki/Thunder_Wave_(move)
it("paralyzes non-statused Pokemon that are not Ground types", async () => {
game.override.enemySpecies(Species.MAGIKARP);
await game.startBattle();
const enemyPokemon: EnemyPokemon = game.scene.getEnemyPokemon()!;
game.move.select(Moves.THUNDER_WAVE);
await game.move.forceHit();
await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status?.effect).toBe(StatusEffect.PARALYSIS);
}, TIMEOUT);
it("does not paralyze if the Pokemon is a Ground-type", async () => {
game.override.enemySpecies(Species.DIGLETT);
await game.startBattle();
const enemyPokemon: EnemyPokemon = game.scene.getEnemyPokemon()!;
game.move.select(Moves.THUNDER_WAVE);
await game.move.forceHit();
await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status).toBeUndefined();
}, TIMEOUT);
it("does not paralyze if the Pokemon already has a status effect", async () => {
game.override.enemySpecies(Species.MAGIKARP).enemyStatusEffect(StatusEffect.BURN);
await game.startBattle();
const enemyPokemon: EnemyPokemon = game.scene.getEnemyPokemon()!;
game.move.select(Moves.THUNDER_WAVE);
await game.move.forceHit();
await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status?.effect).not.toBe(StatusEffect.PARALYSIS);
}, TIMEOUT);
it("affects Ground types if the user has Normalize", async () => {
game.override.ability(Abilities.NORMALIZE).enemySpecies(Species.DIGLETT);
await game.startBattle();
const enemyPokemon: EnemyPokemon = game.scene.getEnemyPokemon()!;
game.move.select(Moves.THUNDER_WAVE);
await game.move.forceHit();
await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status?.effect).toBe(StatusEffect.PARALYSIS);
}, TIMEOUT);
it("does not affect Ghost types if the user has Normalize", async () => {
game.override.ability(Abilities.NORMALIZE).enemySpecies(Species.HAUNTER);
await game.startBattle();
const enemyPokemon: EnemyPokemon = game.scene.getEnemyPokemon()!;
game.move.select(Moves.THUNDER_WAVE);
await game.move.forceHit();
await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status).toBeUndefined();
}, TIMEOUT);
});

View File

@ -25,7 +25,7 @@ export default class AchvBar extends Phaser.GameObjects.Container {
} }
setup(): void { setup(): void {
this.defaultWidth = 160; this.defaultWidth = 200;
this.defaultHeight = 40; this.defaultHeight = 40;
this.bg = this.scene.add.nineslice(0, 0, "achv_bar", undefined, this.defaultWidth, this.defaultHeight, 41, 6, 16, 4); this.bg = this.scene.add.nineslice(0, 0, "achv_bar", undefined, this.defaultWidth, this.defaultHeight, 41, 6, 16, 4);

View File

@ -15,6 +15,16 @@ enum Page {
VOUCHERS VOUCHERS
} }
interface LanguageSetting {
TextSize: string,
}
const languageSettings: { [key: string]: LanguageSetting } = {
"de":{
TextSize: "80px"
}
};
export default class AchvsUiHandler extends MessageUiHandler { export default class AchvsUiHandler extends MessageUiHandler {
private readonly ROWS = 4; private readonly ROWS = 4;
private readonly COLS = 17; private readonly COLS = 17;
@ -105,8 +115,13 @@ export default class AchvsUiHandler extends MessageUiHandler {
titleBg.setOrigin(0, 0); titleBg.setOrigin(0, 0);
this.titleText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW); this.titleText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW);
const textSize = languageSettings[i18next.language]?.TextSize ?? this.titleText.style.fontSize;
this.titleText.setFontSize(textSize);
this.titleText.setOrigin(0, 0); this.titleText.setOrigin(0, 0);
this.titleText.setPositionRelative(titleBg, 8, 4); const titleBgCenterX = titleBg.x + titleBg.width / 2;
const titleBgCenterY = titleBg.y + titleBg.height / 2;
this.titleText.setOrigin(0.5, 0.5);
this.titleText.setPosition(titleBgCenterX, titleBgCenterY);
const scoreBg = addWindow(this.scene, titleBg.x + titleBg.width, titleBg.y, 46, 24); const scoreBg = addWindow(this.scene, titleBg.x + titleBg.width, titleBg.y, 46, 24);
scoreBg.setOrigin(0, 0); scoreBg.setOrigin(0, 0);

View File

@ -35,6 +35,8 @@ export default class GameChallengesUiHandler extends UiHandler {
private startCursor: Phaser.GameObjects.NineSlice; private startCursor: Phaser.GameObjects.NineSlice;
private optionsWidth: number;
constructor(scene: BattleScene, mode: Mode | null = null) { constructor(scene: BattleScene, mode: Mode | null = null) {
super(scene, mode); super(scene, mode);
} }
@ -74,18 +76,19 @@ export default class GameChallengesUiHandler extends UiHandler {
// difficultyName.setOrigin(0, 0); // difficultyName.setOrigin(0, 0);
// difficultyName.setPositionRelative(difficultyBg, difficultyBg.width - difficultyName.displayWidth - 8, 4); // difficultyName.setPositionRelative(difficultyBg, difficultyBg.width - difficultyName.displayWidth - 8, 4);
this.optionsBg = addWindow(this.scene, 0, headerBg.height, (this.scene.game.canvas.width / 9), (this.scene.game.canvas.height / 6) - headerBg.height - 2); this.optionsWidth = this.scene.scaledCanvas.width * 0.6;
this.optionsBg = addWindow(this.scene, 0, headerBg.height, this.optionsWidth, this.scene.scaledCanvas.height - headerBg.height - 2);
this.optionsBg.setName("window-options-bg"); this.optionsBg.setName("window-options-bg");
this.optionsBg.setOrigin(0, 0); this.optionsBg.setOrigin(0, 0);
const descriptionBg = addWindow(this.scene, 0, headerBg.height, (this.scene.game.canvas.width / 18) - 2, (this.scene.game.canvas.height / 6) - headerBg.height - 26); const descriptionBg = addWindow(this.scene, 0, headerBg.height, this.scene.scaledCanvas.width - this.optionsWidth, this.scene.scaledCanvas.height - headerBg.height - 26);
descriptionBg.setName("window-desc-bg"); descriptionBg.setName("window-desc-bg");
descriptionBg.setOrigin(0, 0); descriptionBg.setOrigin(0, 0);
descriptionBg.setPositionRelative(this.optionsBg, this.optionsBg.width, 0); descriptionBg.setPositionRelative(this.optionsBg, this.optionsBg.width, 0);
this.descriptionText = new BBCodeText(this.scene, descriptionBg.x + 6, descriptionBg.y + 4, "", { this.descriptionText = new BBCodeText(this.scene, descriptionBg.x + 6, descriptionBg.y + 4, "", {
fontFamily: "emerald", fontFamily: "emerald",
fontSize: 96, fontSize: 84,
color: Color.ORANGE, color: Color.ORANGE,
padding: { padding: {
bottom: 6 bottom: 6
@ -109,12 +112,12 @@ export default class GameChallengesUiHandler extends UiHandler {
const startText = addTextObject(this.scene, 0, 0, i18next.t("common:start"), TextStyle.SETTINGS_LABEL); const startText = addTextObject(this.scene, 0, 0, i18next.t("common:start"), TextStyle.SETTINGS_LABEL);
startText.setName("text-start"); startText.setName("text-start");
startText.setOrigin(0, 0); startText.setOrigin(0, 0);
startText.setPositionRelative(startBg, 8, 4); startText.setPositionRelative(startBg, (startBg.width - startText.displayWidth) / 2, 4);
this.startCursor = this.scene.add.nineslice(0, 0, "summary_moves_cursor", undefined, (this.scene.game.canvas.width / 18) - 10, 16, 1, 1, 1, 1); this.startCursor = this.scene.add.nineslice(0, 0, "summary_moves_cursor", undefined, descriptionBg.width - 8, 16, 1, 1, 1, 1);
this.startCursor.setName("9s-start-cursor"); this.startCursor.setName("9s-start-cursor");
this.startCursor.setOrigin(0, 0); this.startCursor.setOrigin(0, 0);
this.startCursor.setPositionRelative(startBg, 4, 4); this.startCursor.setPositionRelative(startBg, 4, 3);
this.startCursor.setVisible(false); this.startCursor.setVisible(false);
this.valuesContainer = this.scene.add.container(0, 0); this.valuesContainer = this.scene.add.container(0, 0);
@ -140,7 +143,7 @@ export default class GameChallengesUiHandler extends UiHandler {
}; };
} }
this.monoTypeValue = this.scene.add.sprite(8, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); this.monoTypeValue = this.scene.add.sprite(8, 98, Utils.getLocalizedSpriteKey("types"));
this.monoTypeValue.setName("challenge-value-monotype-sprite"); this.monoTypeValue.setName("challenge-value-monotype-sprite");
this.monoTypeValue.setScale(0.86); this.monoTypeValue.setScale(0.86);
this.monoTypeValue.setVisible(false); this.monoTypeValue.setVisible(false);
@ -355,7 +358,7 @@ export default class GameChallengesUiHandler extends UiHandler {
let ret = super.setCursor(cursor); let ret = super.setCursor(cursor);
if (!this.cursorObj) { if (!this.cursorObj) {
this.cursorObj = this.scene.add.nineslice(0, 0, "summary_moves_cursor", undefined, (this.scene.game.canvas.width / 9) - 10, 16, 1, 1, 1, 1); this.cursorObj = this.scene.add.nineslice(0, 0, "summary_moves_cursor", undefined, this.optionsWidth - 8, 16, 1, 1, 1, 1);
this.cursorObj.setOrigin(0, 0); this.cursorObj.setOrigin(0, 0);
this.valuesContainer.add(this.cursorObj); this.valuesContainer.add(this.cursorObj);
} }

View File

@ -44,7 +44,7 @@ export default class FightUiHandler extends UiHandler {
this.moveInfoContainer.setName("move-info"); this.moveInfoContainer.setName("move-info");
ui.add(this.moveInfoContainer); ui.add(this.moveInfoContainer);
this.typeIcon = this.scene.add.sprite(this.scene.scaledCanvas.width - 57, -36, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, "unknown"); this.typeIcon = this.scene.add.sprite(this.scene.scaledCanvas.width - 57, -36, Utils.getLocalizedSpriteKey("types"), "unknown");
this.typeIcon.setVisible(false); this.typeIcon.setVisible(false);
this.moveInfoContainer.add(this.typeIcon); this.moveInfoContainer.add(this.typeIcon);
@ -179,15 +179,20 @@ export default class FightUiHandler extends UiHandler {
if (hasMove) { if (hasMove) {
const pokemonMove = moveset[cursor]!; // TODO: is the bang correct? const pokemonMove = moveset[cursor]!; // TODO: is the bang correct?
this.typeIcon.setTexture(`types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[pokemonMove.getMove().type].toLowerCase()).setScale(0.8); const moveType = pokemon.getMoveType(pokemonMove.getMove());
this.moveCategoryIcon.setTexture("categories", MoveCategory[pokemonMove.getMove().category].toLowerCase()).setScale(1.0); const textureKey = Utils.getLocalizedSpriteKey("types");
this.typeIcon.setTexture(textureKey, Type[moveType].toLowerCase()).setScale(0.8);
const moveCategory = pokemonMove.getMove().category;
this.moveCategoryIcon.setTexture("categories", MoveCategory[moveCategory].toLowerCase()).setScale(1.0);
const power = pokemonMove.getMove().power; const power = pokemonMove.getMove().power;
const accuracy = pokemonMove.getMove().accuracy; const accuracy = pokemonMove.getMove().accuracy;
const maxPP = pokemonMove.getMovePp(); const maxPP = pokemonMove.getMovePp();
const pp = maxPP - pokemonMove.ppUsed; const pp = maxPP - pokemonMove.ppUsed;
this.ppText.setText(`${Utils.padInt(pp, 2, " ")}/${Utils.padInt(maxPP, 2, " ")}`); const ppLeftStr = Utils.padInt(pp, 2, " ");
const ppMaxStr = Utils.padInt(maxPP, 2, " ");
this.ppText.setText(`${ppLeftStr}/${ppMaxStr}`);
this.powerText.setText(`${power >= 0 ? power : "---"}`); this.powerText.setText(`${power >= 0 ? power : "---"}`);
this.accuracyText.setText(`${accuracy >= 0 ? accuracy : "---"}`); this.accuracyText.setText(`${accuracy >= 0 ? accuracy : "---"}`);
@ -231,7 +236,7 @@ export default class FightUiHandler extends UiHandler {
* Returns undefined if it's a status move * Returns undefined if it's a status move
*/ */
private getEffectivenessText(pokemon: Pokemon, opponent: Pokemon, pokemonMove: PokemonMove): string | undefined { private getEffectivenessText(pokemon: Pokemon, opponent: Pokemon, pokemonMove: PokemonMove): string | undefined {
const effectiveness = opponent.getMoveEffectiveness(pokemon, pokemonMove); const effectiveness = opponent.getMoveEffectiveness(pokemon, pokemonMove.getMove(), !opponent.battleData?.abilityRevealed);
if (effectiveness === undefined) { if (effectiveness === undefined) {
return undefined; return undefined;
} }
@ -274,7 +279,7 @@ export default class FightUiHandler extends UiHandler {
} }
const moveColors = opponents const moveColors = opponents
.map((opponent) => opponent.getMoveEffectiveness(pokemon, pokemonMove)) .map((opponent) => opponent.getMoveEffectiveness(pokemon, pokemonMove.getMove(), !opponent.battleData.abilityRevealed))
.sort((a, b) => b - a) .sort((a, b) => b - a)
.map((effectiveness) => getTypeDamageMultiplierColor(effectiveness ?? 0, "offense")); .map((effectiveness) => getTypeDamageMultiplierColor(effectiveness ?? 0, "offense"));

View File

@ -410,7 +410,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
if (index === 0 || index === 19) { if (index === 0 || index === 19) {
return; return;
} }
const typeSprite = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); const typeSprite = this.scene.add.sprite(0, 0, Utils.getLocalizedSpriteKey("types"));
typeSprite.setScale(0.5); typeSprite.setScale(0.5);
typeSprite.setFrame(type.toLowerCase()); typeSprite.setFrame(type.toLowerCase());
typeOptions.push(new DropDownOption(this.scene, index, new DropDownLabel("", typeSprite))); typeOptions.push(new DropDownOption(this.scene, index, new DropDownLabel("", typeSprite)));
@ -668,12 +668,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
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);
this.type1Icon = this.scene.add.sprite(8, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); this.type1Icon = this.scene.add.sprite(8, 98, Utils.getLocalizedSpriteKey("types"));
this.type1Icon.setScale(0.5); this.type1Icon.setScale(0.5);
this.type1Icon.setOrigin(0, 0); this.type1Icon.setOrigin(0, 0);
this.starterSelectContainer.add(this.type1Icon); this.starterSelectContainer.add(this.type1Icon);
this.type2Icon = this.scene.add.sprite(26, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); this.type2Icon = this.scene.add.sprite(26, 98, Utils.getLocalizedSpriteKey("types"));
this.type2Icon.setScale(0.5); this.type2Icon.setScale(0.5);
this.type2Icon.setOrigin(0, 0); this.type2Icon.setOrigin(0, 0);
this.starterSelectContainer.add(this.type2Icon); this.starterSelectContainer.add(this.type2Icon);

View File

@ -716,7 +716,8 @@ export default class SummaryUiHandler extends UiHandler {
const getTypeIcon = (index: integer, type: Type, tera: boolean = false) => { const getTypeIcon = (index: integer, type: Type, tera: boolean = false) => {
const xCoord = typeLabel.width * typeLabel.scale + 9 + 34 * index; const xCoord = typeLabel.width * typeLabel.scale + 9 + 34 * index;
const typeIcon = !tera const typeIcon = !tera
? this.scene.add.sprite(xCoord, 42, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[type].toLowerCase()) : this.scene.add.sprite(xCoord, 42, "type_tera"); ? this.scene.add.sprite(xCoord, 42, Utils.getLocalizedSpriteKey("types"), Type[type].toLowerCase())
: this.scene.add.sprite(xCoord, 42, "type_tera");
if (tera) { if (tera) {
typeIcon.setScale(0.5); typeIcon.setScale(0.5);
const typeRgb = getTypeRgb(type); const typeRgb = getTypeRgb(type);
@ -934,10 +935,14 @@ export default class SummaryUiHandler extends UiHandler {
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) { if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
this.extraMoveRowContainer.setVisible(true); this.extraMoveRowContainer.setVisible(true);
const newMoveTypeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[this.newMove?.type!].toLowerCase()); // TODO: is this bang correct?
newMoveTypeIcon.setOrigin(0, 1);
this.extraMoveRowContainer.add(newMoveTypeIcon);
if (this.newMove && this.pokemon) {
const spriteKey = Utils.getLocalizedSpriteKey("types");
const moveType = this.pokemon.getMoveType(this.newMove);
const newMoveTypeIcon = this.scene.add.sprite(0, 0, spriteKey, Type[moveType].toLowerCase());
newMoveTypeIcon.setOrigin(0, 1);
this.extraMoveRowContainer.add(newMoveTypeIcon);
}
const ppOverlay = this.scene.add.image(163, -1, "summary_moves_overlay_pp"); const ppOverlay = this.scene.add.image(163, -1, "summary_moves_overlay_pp");
ppOverlay.setOrigin(0, 1); ppOverlay.setOrigin(0, 1);
this.extraMoveRowContainer.add(ppOverlay); this.extraMoveRowContainer.add(ppOverlay);
@ -956,8 +961,11 @@ export default class SummaryUiHandler extends UiHandler {
const moveRowContainer = this.scene.add.container(0, 16 * m); const moveRowContainer = this.scene.add.container(0, 16 * m);
this.moveRowsContainer.add(moveRowContainer); this.moveRowsContainer.add(moveRowContainer);
if (move) { if (move && this.pokemon) {
const typeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[move.getMove().type].toLowerCase()); typeIcon.setOrigin(0, 1); const spriteKey = Utils.getLocalizedSpriteKey("types");
const moveType = this.pokemon.getMoveType(move.getMove());
const typeIcon = this.scene.add.sprite(0, 0, spriteKey, Type[moveType].toLowerCase());
typeIcon.setOrigin(0, 1);
moveRowContainer.add(typeIcon); moveRowContainer.add(typeIcon);
} }

View File

@ -574,3 +574,12 @@ export function isNullOrUndefined(object: any): boolean {
export function toDmgValue(value: number, minValue: number = 1) { export function toDmgValue(value: number, minValue: number = 1) {
return Math.max(Math.floor(value), minValue); return Math.max(Math.floor(value), minValue);
} }
/**
* Helper method to localize a sprite key (e.g. for types)
* @param baseKey the base key of the sprite (e.g. `type`)
* @returns the localized sprite key
*/
export function getLocalizedSpriteKey(baseKey: string) {
return `${baseKey}${verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`;
}