diff --git a/package.json b/package.json index dc851e05c92..b85ac639a1b 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "test:cov": "vitest run --project pre && vitest run --project main --coverage", "test:watch": "vitest run --project pre && vitest watch --project main --coverage", "test:silent": "vitest run --project pre && vitest run --project main --silent", + "typecheck": "tsc --noEmit", "eslint": "eslint --fix .", "eslint-ci": "eslint .", "docs": "typedoc", diff --git a/public/images/ui/favorite.png b/public/images/ui/favorite.png new file mode 100644 index 00000000000..d86dd58f5ab Binary files /dev/null and b/public/images/ui/favorite.png differ diff --git a/public/images/ui/legacy/favorite.png b/public/images/ui/legacy/favorite.png new file mode 100644 index 00000000000..d86dd58f5ab Binary files /dev/null and b/public/images/ui/legacy/favorite.png differ diff --git a/src/data/ability.ts b/src/data/ability.ts index b896b12fe56..0e027d443a2 100755 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -6,7 +6,7 @@ import { BattleStat, getBattleStatName } from "./battle-stat"; import { MovePhase, PokemonHealPhase, ShowAbilityPhase, StatChangePhase } from "../phases"; import { getPokemonNameWithAffix } from "../messages"; import { Weather, WeatherType } from "./weather"; -import { BattlerTag, GroundedTag, GulpMissileTag } from "./battler-tags"; +import { BattlerTag, GroundedTag, GulpMissileTag, SemiInvulnerableTag } from "./battler-tags"; import { StatusEffect, getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect"; 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"; @@ -517,7 +517,7 @@ export class PostDefendGulpMissileAbAttr extends PostDefendAbAttr { */ applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean | Promise { const battlerTag = pokemon.getTag(GulpMissileTag); - if (!battlerTag || move.category === MoveCategory.STATUS) { + if (!battlerTag || move.category === MoveCategory.STATUS || pokemon.getTag(SemiInvulnerableTag)) { return false; } @@ -5257,9 +5257,7 @@ export function initAbilities() { .attr(NoFusionAbilityAbAttr) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) - .attr(PostDefendGulpMissileAbAttr) - // Does not transform when Surf/Dive misses/is protected - .partial(), + .attr(PostDefendGulpMissileAbAttr), new Ability(Abilities.STALWART, 8) .attr(BlockRedirectAbAttr), new Ability(Abilities.STEAM_ENGINE, 8) diff --git a/src/data/battle-anims.ts b/src/data/battle-anims.ts index d9fc87c67c7..634c39b7d66 100644 --- a/src/data/battle-anims.ts +++ b/src/data/battle-anims.ts @@ -1,6 +1,6 @@ //import { battleAnimRawData } from "./battle-anim-raw-data"; import BattleScene from "../battle-scene"; -import { AttackMove, ChargeAttr, DelayedAttackAttr, MoveFlags, SelfStatusMove, allMoves } from "./move"; +import { AttackMove, BeakBlastHeaderAttr, ChargeAttr, DelayedAttackAttr, MoveFlags, SelfStatusMove, allMoves } from "./move"; import Pokemon from "../field/pokemon"; import * as Utils from "../utils"; import { BattlerIndex } from "../battle"; @@ -485,7 +485,8 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise { const fetchAnimAndResolve = (move: Moves) => { scene.cachedFetch(`./battle-anims/${moveName}.json`) .then(response => { - if (!response.ok) { + const contentType = response.headers.get("content-type"); + if (!response.ok || contentType?.indexOf("application/json") === -1) { console.error(`Could not load animation file for move '${moveName}'`, response.status, response.statusText); populateMoveAnim(move, moveAnims.get(defaultMoveAnim)); return resolve(); @@ -499,7 +500,9 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise { } else { populateMoveAnim(move, ba); } - const chargeAttr = allMoves[move].getAttrs(ChargeAttr)[0] || allMoves[move].getAttrs(DelayedAttackAttr)[0]; + const chargeAttr = allMoves[move].getAttrs(ChargeAttr)[0] + || allMoves[move].getAttrs(DelayedAttackAttr)[0] + || allMoves[move].getAttrs(BeakBlastHeaderAttr)[0]; if (chargeAttr) { initMoveChargeAnim(scene, chargeAttr.chargeAnim).then(() => resolve()); } else { @@ -570,7 +573,9 @@ export function loadMoveAnimAssets(scene: BattleScene, moveIds: Moves[], startLo return new Promise(resolve => { const moveAnimations = moveIds.map(m => moveAnims.get(m) as AnimConfig).flat(); for (const moveId of moveIds) { - const chargeAttr = allMoves[moveId].getAttrs(ChargeAttr)[0] || allMoves[moveId].getAttrs(DelayedAttackAttr)[0]; + const chargeAttr = allMoves[moveId].getAttrs(ChargeAttr)[0] + || allMoves[moveId].getAttrs(DelayedAttackAttr)[0] + || allMoves[moveId].getAttrs(BeakBlastHeaderAttr)[0]; if (chargeAttr) { const moveChargeAnims = chargeAnims.get(chargeAttr.chargeAnim); moveAnimations.push(moveChargeAnims instanceof AnimConfig ? moveChargeAnims : moveChargeAnims![0]); // TODO: is the bang correct? diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index c25407d0599..16dd4914ed4 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1,4 +1,4 @@ -import { CommonAnim, CommonBattleAnim } from "./battle-anims"; +import { ChargeAnim, CommonAnim, CommonBattleAnim, MoveChargeAnim } from "./battle-anims"; import { CommonAnimPhase, MoveEffectPhase, MovePhase, PokemonHealPhase, ShowAbilityPhase, StatChangeCallback, StatChangePhase } from "../phases"; import { getPokemonNameWithAffix } from "../messages"; import Pokemon, { MoveResult, HitResult } from "../field/pokemon"; @@ -118,6 +118,44 @@ export class RechargingTag extends BattlerTag { } } +/** + * BattlerTag representing the "charge phase" of Beak Blast + * Pokemon with this tag will inflict BURN status on any attacker that makes contact. + * @see {@link https://bulbapedia.bulbagarden.net/wiki/Beak_Blast_(move) | Beak Blast} + */ +export class BeakBlastChargingTag extends BattlerTag { + constructor() { + super(BattlerTagType.BEAK_BLAST_CHARGING, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.TURN_END ], 1, Moves.BEAK_BLAST); + } + + onAdd(pokemon: Pokemon): void { + // Play Beak Blast's charging animation + new MoveChargeAnim(ChargeAnim.BEAK_BLAST_CHARGING, this.sourceMove, pokemon).play(pokemon.scene); + + // Queue Beak Blast's header message + pokemon.scene.queueMessage(i18next.t("moveTriggers:startedHeatingUpBeak", { pokemonName: getPokemonNameWithAffix(pokemon) })); + } + + /** + * Inflicts `BURN` status on attackers that make contact, and causes this tag + * to be removed after the source makes a move (or the turn ends, whichever comes first) + * @param pokemon {@linkcode Pokemon} the owner of this tag + * @param lapseType {@linkcode BattlerTagLapseType} the type of functionality invoked in battle + * @returns `true` if invoked with the CUSTOM lapse type; `false` otherwise + */ + lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { + if (lapseType === BattlerTagLapseType.CUSTOM) { + const effectPhase = pokemon.scene.getCurrentPhase(); + if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) { + const attacker = effectPhase.getPokemon(); + attacker.trySetStatus(StatusEffect.BURN, true, pokemon); + } + return true; + } + return super.lapse(pokemon, lapseType); + } +} + export class TrappedTag extends BattlerTag { constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: number, sourceMove: Moves, sourceId: number) { super(tagType, lapseType, turnCount, sourceMove, sourceId); @@ -1738,6 +1776,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source switch (tagType) { case BattlerTagType.RECHARGING: return new RechargingTag(sourceMove); + case BattlerTagType.BEAK_BLAST_CHARGING: + return new BeakBlastChargingTag(); case BattlerTagType.FLINCHED: return new FlinchedTag(sourceMove); case BattlerTagType.INTERRUPTED: diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 5f17fdedb78..18cc58ddaf1 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -273,11 +273,9 @@ export abstract class Challenge { * @param valid {@link Utils.BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed. * @param dexAttr {@link DexAttrProps} The dex attributes of the pokemon. * @param soft {@link boolean} If true, allow it if it could become a valid pokemon. - * @param checkEvolutions {@link boolean} If true, check the pokemon's future evolutions - * @param checkForms {@link boolean} If true, check the pokemon's alternative forms * @returns {@link boolean} Whether this function did anything. */ - applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false, checkEvolutions?: boolean, checkForms?: boolean): boolean { + applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean { return false; } @@ -405,14 +403,13 @@ export class SingleGenerationChallenge extends Challenge { super(Challenges.SINGLE_GENERATION, 9); } - applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false, checkEvolutions?: boolean): boolean { + applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean { const generations = [pokemon.generation]; - const checkPokemonEvolutions = checkEvolutions ?? true as boolean; if (soft) { const speciesToCheck = [pokemon.speciesId]; while (speciesToCheck.length) { const checking = speciesToCheck.pop(); - if (checking && pokemonEvolutions.hasOwnProperty(checking) && checkPokemonEvolutions) { + if (checking && pokemonEvolutions.hasOwnProperty(checking)) { pokemonEvolutions[checking].forEach(e => { speciesToCheck.push(e.speciesId); generations.push(getPokemonSpecies(e.speciesId).generation); @@ -533,22 +530,20 @@ export class SingleTypeChallenge extends Challenge { super(Challenges.SINGLE_TYPE, 18); } - applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false, checkEvolutions?: boolean, checkForms?: boolean): boolean { + applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean { const speciesForm = getPokemonSpeciesForm(pokemon.speciesId, dexAttr.formIndex); const types = [speciesForm.type1, speciesForm.type2]; - const checkPokemonEvolutions = checkEvolutions ?? true as boolean; - const checkPokemonForms = checkForms ?? true as boolean; if (soft) { const speciesToCheck = [pokemon.speciesId]; while (speciesToCheck.length) { const checking = speciesToCheck.pop(); - if (checking && pokemonEvolutions.hasOwnProperty(checking) && checkPokemonEvolutions) { + if (checking && pokemonEvolutions.hasOwnProperty(checking)) { pokemonEvolutions[checking].forEach(e => { speciesToCheck.push(e.speciesId); types.push(getPokemonSpecies(e.speciesId).type1, getPokemonSpecies(e.speciesId).type2); }); } - if (checking && pokemonFormChanges.hasOwnProperty(checking) && checkPokemonForms) { + if (checking && pokemonFormChanges.hasOwnProperty(checking)) { pokemonFormChanges[checking].forEach(f1 => { getPokemonSpecies(checking).forms.forEach(f2 => { if (f1.formKey === f2.formKey) { @@ -746,7 +741,7 @@ export class LowerStarterPointsChallenge extends Challenge { * @param soft {@link boolean} If true, allow it if it could become a valid pokemon. * @returns True if any challenge was successfully applied. */ -export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.STARTER_CHOICE, pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean, checkEvolutions?: boolean, checkForms?: boolean): boolean; +export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.STARTER_CHOICE, pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean): boolean; /** * Apply all challenges that modify available total starter points. * @param gameMode {@link GameMode} The current gameMode @@ -854,7 +849,7 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType if (c.value !== 0) { switch (challengeType) { case ChallengeType.STARTER_CHOICE: - ret ||= c.applyStarterChoice(args[0], args[1], args[2], args[3], args[4], args[5]); + ret ||= c.applyStarterChoice(args[0], args[1], args[2], args[3]); break; case ChallengeType.STARTER_POINTS: ret ||= c.applyStarterPoints(args[0]); diff --git a/src/data/move.ts b/src/data/move.ts index b0fe0f8c015..507e56d23bd 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1021,6 +1021,22 @@ export class MessageHeaderAttr extends MoveHeaderAttr { } } +/** + * Header attribute to implement the "charge phase" of Beak Blast at the + * beginning of a turn. + * @see {@link https://bulbapedia.bulbagarden.net/wiki/Beak_Blast_(move) | Beak Blast} + * @see {@linkcode BeakBlastChargingTag} + */ +export class BeakBlastHeaderAttr extends MoveHeaderAttr { + /** Required to initialize Beak Blast's charge animation correctly */ + public chargeAnim = ChargeAnim.BEAK_BLAST_CHARGING; + + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + user.addTag(BattlerTagType.BEAK_BLAST_CHARGING); + return true; + } +} + export class PreMoveMessageAttr extends MoveAttr { private message: string | ((user: Pokemon, target: Pokemon, move: Move) => string); @@ -2391,24 +2407,21 @@ export class ChargeAttr extends OverrideMoveEffectAttr { private chargeText: string; private tagType: BattlerTagType | null; private chargeEffect: boolean; - public sameTurn: boolean; public followUpPriority: integer | null; - constructor(chargeAnim: ChargeAnim, chargeText: string, tagType?: BattlerTagType | null, chargeEffect: boolean = false, sameTurn: boolean = false, followUpPriority?: integer) { + constructor(chargeAnim: ChargeAnim, chargeText: string, tagType?: BattlerTagType | null, chargeEffect: boolean = false) { super(); this.chargeAnim = chargeAnim; this.chargeText = chargeText; this.tagType = tagType!; // TODO: is this bang correct? this.chargeEffect = chargeEffect; - this.sameTurn = sameTurn; - this.followUpPriority = followUpPriority!; // TODO: is this bang correct? } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { return new Promise(resolve => { const lastMove = user.getLastXMoves().find(() => true); - if (!lastMove || lastMove.move !== move.id || (lastMove.result !== MoveResult.OTHER && (this.sameTurn || lastMove.turn !== user.scene.currentBattle.turn))) { + if (!lastMove || lastMove.move !== move.id || (lastMove.result !== MoveResult.OTHER && lastMove.turn !== user.scene.currentBattle.turn)) { (args[0] as Utils.BooleanHolder).value = true; new MoveChargeAnim(this.chargeAnim, move.id, user).play(user.scene, () => { user.scene.queueMessage(this.chargeText.replace("{TARGET}", getPokemonNameWithAffix(target)).replace("{USER}", getPokemonNameWithAffix(user))); @@ -2420,13 +2433,6 @@ export class ChargeAttr extends OverrideMoveEffectAttr { } user.pushMoveHistory({ move: move.id, targets: [ target.getBattlerIndex() ], result: MoveResult.OTHER }); user.getMoveQueue().push({ move: move.id, targets: [ target.getBattlerIndex() ], ignorePP: true }); - if (this.sameTurn) { - let movesetMove = user.moveset.find(m => m?.moveId === move.id); - if (!movesetMove) { // account for any move that calls a ChargeAttr move when the ChargeAttr move does not exist in moveset - movesetMove = new PokemonMove(move.id, 0, 0, true); - } - user.scene.pushMovePhase(new MovePhase(user.scene, user, [ target.getBattlerIndex() ], movesetMove, true), this.followUpPriority!); // TODO: is this bang correct? - } user.addTag(BattlerTagType.CHARGING, 1, move.id, user.id); resolve(true); }); @@ -2736,21 +2742,34 @@ export class InvertStatsAttr extends MoveEffectAttr { } export class ResetStatsAttr extends MoveEffectAttr { + private targetAllPokemon: boolean; + constructor(targetAllPokemon: boolean) { + super(); + this.targetAllPokemon = targetAllPokemon; + } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { if (!super.apply(user, target, move, args)) { return false; } - for (let s = 0; s < target.summonData.battleStats.length; s++) { - target.summonData.battleStats[s] = 0; + if (this.targetAllPokemon) { // Target all pokemon on the field when Freezy Frost or Haze are used + const activePokemon = user.scene.getField(true); + activePokemon.forEach(p => this.resetStats(p)); + target.scene.queueMessage(i18next.t("moveTriggers:statEliminated")); + } else { // Affects only the single target when Clear Smog is used + this.resetStats(target); + target.scene.queueMessage(i18next.t("moveTriggers:resetStats", {pokemonName: getPokemonNameWithAffix(target)})); } - target.updateInfo(); - user.updateInfo(); - - target.scene.queueMessage(i18next.t("moveTriggers:resetStats", {pokemonName: getPokemonNameWithAffix(target)})); return true; } + + resetStats(pokemon: Pokemon) { + for (let s = 0; s < pokemon.summonData.battleStats.length; s++) { + pokemon.summonData.battleStats[s] = 0; + } + pokemon.updateInfo(); + } } /** @@ -4350,7 +4369,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr { */ export class GulpMissileTagAttr extends MoveEffectAttr { constructor() { - super(true, MoveEffectTrigger.POST_APPLY); + super(true); } /** @@ -6434,9 +6453,8 @@ export function initMoves() { new StatusMove(Moves.LIGHT_SCREEN, Type.PSYCHIC, -1, 30, -1, 0, 1) .attr(AddArenaTagAttr, ArenaTagType.LIGHT_SCREEN, 5, true) .target(MoveTarget.USER_SIDE), - new StatusMove(Moves.HAZE, Type.ICE, -1, 30, -1, 0, 1) - .target(MoveTarget.BOTH_SIDES) - .attr(ResetStatsAttr), + new SelfStatusMove(Moves.HAZE, Type.ICE, -1, 30, -1, 0, 1) + .attr(ResetStatsAttr, true), new StatusMove(Moves.REFLECT, Type.PSYCHIC, -1, 20, -1, 0, 1) .attr(AddArenaTagAttr, ArenaTagType.REFLECT, 5, true) .target(MoveTarget.USER_SIDE), @@ -6951,7 +6969,7 @@ export function initMoves() { .makesContact(false) .partial(), new AttackMove(Moves.DIVE, Type.WATER, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 3) - .attr(ChargeAttr, ChargeAnim.DIVE_CHARGING, i18next.t("moveTriggers:hidUnderwater", {pokemonName: "{USER}"}), BattlerTagType.UNDERWATER) + .attr(ChargeAttr, ChargeAnim.DIVE_CHARGING, i18next.t("moveTriggers:hidUnderwater", {pokemonName: "{USER}"}), BattlerTagType.UNDERWATER, true) .attr(GulpMissileTagAttr) .ignoresVirtual(), new AttackMove(Moves.ARM_THRUST, Type.FIGHTING, MoveCategory.PHYSICAL, 15, 100, 20, -1, 0, 3) @@ -7523,7 +7541,7 @@ export function initMoves() { new AttackMove(Moves.CHIP_AWAY, Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 5) .attr(IgnoreOpponentStatChangesAttr), new AttackMove(Moves.CLEAR_SMOG, Type.POISON, MoveCategory.SPECIAL, 50, -1, 15, -1, 0, 5) - .attr(ResetStatsAttr), + .attr(ResetStatsAttr, false), new AttackMove(Moves.STORED_POWER, Type.PSYCHIC, MoveCategory.SPECIAL, 20, 100, 10, -1, 0, 5) .attr(StatChangeCountPowerAttr), new StatusMove(Moves.QUICK_GUARD, Type.FIGHTING, -1, 15, -1, 3, 5) @@ -8084,11 +8102,10 @@ export function initMoves() { .attr(StatChangeAttr, BattleStat.ATK, -1), new StatusMove(Moves.INSTRUCT, Type.PSYCHIC, -1, 15, -1, 0, 7) .unimplemented(), - new AttackMove(Moves.BEAK_BLAST, Type.FLYING, MoveCategory.PHYSICAL, 100, 100, 15, -1, 5, 7) - .attr(ChargeAttr, ChargeAnim.BEAK_BLAST_CHARGING, i18next.t("moveTriggers:startedHeatingUpBeak", {pokemonName: "{USER}"}), undefined, false, true, -3) + new AttackMove(Moves.BEAK_BLAST, Type.FLYING, MoveCategory.PHYSICAL, 100, 100, 15, -1, -3, 7) + .attr(BeakBlastHeaderAttr) .ballBombMove() - .makesContact(false) - .partial(), + .makesContact(false), new AttackMove(Moves.CLANGING_SCALES, Type.DRAGON, MoveCategory.SPECIAL, 110, 100, 5, -1, 0, 7) .attr(StatChangeAttr, BattleStat.DEF, -1, true, null, true, false, MoveEffectTrigger.HIT, true) .soundBased() @@ -8230,7 +8247,7 @@ export function initMoves() { .makesContact(false) .attr(AddBattlerTagAttr, BattlerTagType.SEEDED), new AttackMove(Moves.FREEZY_FROST, Type.ICE, MoveCategory.SPECIAL, 100, 90, 10, -1, 0, 7) - .attr(ResetStatsAttr), + .attr(ResetStatsAttr, true), new AttackMove(Moves.SPARKLY_SWIRL, Type.FAIRY, MoveCategory.SPECIAL, 120, 85, 5, -1, 0, 7) .attr(PartyStatusCureAttr, null, Abilities.NONE), new AttackMove(Moves.VEEVEE_VOLLEY, Type.NORMAL, MoveCategory.PHYSICAL, -1, -1, 20, -1, 0, 7) diff --git a/src/data/status-effect.ts b/src/data/status-effect.ts index 828c52cae13..4381db5c2c6 100644 --- a/src/data/status-effect.ts +++ b/src/data/status-effect.ts @@ -115,11 +115,11 @@ export function getRandomStatusEffect(statusEffectA: StatusEffect, statusEffectB * @param statusA The first Status * @param statusB The second Status */ -export function getRandomStatus(statusA: Status, statusB: Status): Status { - if (statusA === undefined || statusA.effect === StatusEffect.NONE || statusA.effect === StatusEffect.FAINT) { +export function getRandomStatus(statusA: Status | null, statusB: Status | null): Status | null { + if (!statusA || statusA.effect === StatusEffect.NONE || statusA.effect === StatusEffect.FAINT) { return statusB; } - if (statusB === undefined || statusB.effect === StatusEffect.NONE || statusB.effect === StatusEffect.FAINT) { + if (!statusB || statusB.effect === StatusEffect.NONE || statusB.effect === StatusEffect.FAINT) { return statusA; } diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 405e8cc4822..fd1455eab6c 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -66,5 +66,6 @@ export enum BattlerTagType { IGNORE_GHOST = "IGNORE_GHOST", IGNORE_DARK = "IGNORE_DARK", GULP_MISSILE_ARROKUDA = "GULP_MISSILE_ARROKUDA", - GULP_MISSILE_PIKACHU = "GULP_MISSILE_PIKACHU" + GULP_MISSILE_PIKACHU = "GULP_MISSILE_PIKACHU", + BEAK_BLAST_CHARGING = "BEAK_BLAST_CHARGING" } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 0666ee1c6cc..c323226b591 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1271,6 +1271,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { (Overrides.OPP_PASSIVE_ABILITY_OVERRIDE !== Abilities.NONE && !this.isPlayer())) { return true; } + + // Final boss does not have passive + if (this.scene.currentBattle?.battleSpec === BattleSpec.FINAL_BOSS && this instanceof EnemyPokemon) { + return false; + } + return this.passive || this.isBoss(); } @@ -3801,7 +3807,7 @@ export class PlayerPokemon extends Pokemon { if (!this.isFainted()) { // If this Pokemon hasn't fainted, make sure the HP wasn't set over the new maximum this.hp = Math.min(this.hp, this.stats[Stat.HP]); - this.status = getRandomStatus(this.status!, pokemon.status!); // Get a random valid status between the two // TODO: are the bangs correct? + this.status = getRandomStatus(this.status, pokemon.status); // Get a random valid status between the two } else if (!pokemon.isFainted()) { // If this Pokemon fainted but the other hasn't, make sure the HP wasn't set to zero this.hp = Math.max(this.hp, 1); diff --git a/src/form-change-phase.ts b/src/form-change-phase.ts index 55bf655081b..5acbc4fb77c 100644 --- a/src/form-change-phase.ts +++ b/src/form-change-phase.ts @@ -11,6 +11,7 @@ import { BattleSpec } from "#enums/battle-spec"; import { BattlePhase, MovePhase, PokemonHealPhase } from "./phases"; import { getTypeRgb } from "./data/type"; import { getPokemonNameWithAffix } from "./messages"; +import { SemiInvulnerableTag } from "./data/battler-tags"; export class FormChangePhase extends EvolutionPhase { private formChange: SpeciesFormChange; @@ -194,7 +195,7 @@ export class QuietFormChangePhase extends BattlePhase { const preName = getPokemonNameWithAffix(this.pokemon); - if (!this.pokemon.isOnField()) { + if (!this.pokemon.isOnField() || this.pokemon.getTag(SemiInvulnerableTag)) { this.pokemon.changeForm(this.formChange).then(() => { this.scene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), 1500); }); diff --git a/src/loading-scene.ts b/src/loading-scene.ts index c00112318c8..9021f638cea 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -93,6 +93,7 @@ export class LoadingScene extends SceneBase { this.loadImage("shiny_star_small", "ui", "shiny_small.png"); this.loadImage("shiny_star_small_1", "ui", "shiny_small_1.png"); this.loadImage("shiny_star_small_2", "ui", "shiny_small_2.png"); + this.loadImage("favorite", "ui", "favorite.png"); this.loadImage("passive_bg", "ui", "passive_bg.png"); this.loadAtlas("shiny_icons", "ui"); this.loadImage("ha_capsule", "ui", "ha_capsule.png"); diff --git a/src/locales/ca-ES/ability-trigger.ts b/src/locales/ca_ES/ability-trigger.ts similarity index 100% rename from src/locales/ca-ES/ability-trigger.ts rename to src/locales/ca_ES/ability-trigger.ts diff --git a/src/locales/ca-ES/ability.ts b/src/locales/ca_ES/ability.ts similarity index 100% rename from src/locales/ca-ES/ability.ts rename to src/locales/ca_ES/ability.ts diff --git a/src/locales/ca-ES/achv.ts b/src/locales/ca_ES/achv.ts similarity index 100% rename from src/locales/ca-ES/achv.ts rename to src/locales/ca_ES/achv.ts diff --git a/src/locales/ca-ES/arena-flyout.ts b/src/locales/ca_ES/arena-flyout.ts similarity index 100% rename from src/locales/ca-ES/arena-flyout.ts rename to src/locales/ca_ES/arena-flyout.ts diff --git a/src/locales/ca-ES/arena-tag.ts b/src/locales/ca_ES/arena-tag.ts similarity index 100% rename from src/locales/ca-ES/arena-tag.ts rename to src/locales/ca_ES/arena-tag.ts diff --git a/src/locales/ca-ES/battle-info.ts b/src/locales/ca_ES/battle-info.ts similarity index 100% rename from src/locales/ca-ES/battle-info.ts rename to src/locales/ca_ES/battle-info.ts diff --git a/src/locales/ca-ES/battle-message-ui-handler.ts b/src/locales/ca_ES/battle-message-ui-handler.ts similarity index 100% rename from src/locales/ca-ES/battle-message-ui-handler.ts rename to src/locales/ca_ES/battle-message-ui-handler.ts diff --git a/src/locales/ca-ES/battle.ts b/src/locales/ca_ES/battle.ts similarity index 100% rename from src/locales/ca-ES/battle.ts rename to src/locales/ca_ES/battle.ts diff --git a/src/locales/ca-ES/battler-tags.ts b/src/locales/ca_ES/battler-tags.ts similarity index 100% rename from src/locales/ca-ES/battler-tags.ts rename to src/locales/ca_ES/battler-tags.ts diff --git a/src/locales/ca-ES/berry.ts b/src/locales/ca_ES/berry.ts similarity index 100% rename from src/locales/ca-ES/berry.ts rename to src/locales/ca_ES/berry.ts diff --git a/src/locales/ca-ES/bgm-name.ts b/src/locales/ca_ES/bgm-name.ts similarity index 100% rename from src/locales/ca-ES/bgm-name.ts rename to src/locales/ca_ES/bgm-name.ts diff --git a/src/locales/ca-ES/biome.ts b/src/locales/ca_ES/biome.ts similarity index 100% rename from src/locales/ca-ES/biome.ts rename to src/locales/ca_ES/biome.ts diff --git a/src/locales/ca-ES/challenges.ts b/src/locales/ca_ES/challenges.ts similarity index 100% rename from src/locales/ca-ES/challenges.ts rename to src/locales/ca_ES/challenges.ts diff --git a/src/locales/ca-ES/command-ui-handler.ts b/src/locales/ca_ES/command-ui-handler.ts similarity index 100% rename from src/locales/ca-ES/command-ui-handler.ts rename to src/locales/ca_ES/command-ui-handler.ts diff --git a/src/locales/ca-ES/common.ts b/src/locales/ca_ES/common.ts similarity index 100% rename from src/locales/ca-ES/common.ts rename to src/locales/ca_ES/common.ts diff --git a/src/locales/ca-ES/config.ts b/src/locales/ca_ES/config.ts similarity index 100% rename from src/locales/ca-ES/config.ts rename to src/locales/ca_ES/config.ts diff --git a/src/locales/ca-ES/dialogue.ts b/src/locales/ca_ES/dialogue.ts similarity index 100% rename from src/locales/ca-ES/dialogue.ts rename to src/locales/ca_ES/dialogue.ts diff --git a/src/locales/ca-ES/egg.ts b/src/locales/ca_ES/egg.ts similarity index 100% rename from src/locales/ca-ES/egg.ts rename to src/locales/ca_ES/egg.ts diff --git a/src/locales/ca-ES/fight-ui-handler.ts b/src/locales/ca_ES/fight-ui-handler.ts similarity index 100% rename from src/locales/ca-ES/fight-ui-handler.ts rename to src/locales/ca_ES/fight-ui-handler.ts diff --git a/src/locales/ca-ES/filter-bar.ts b/src/locales/ca_ES/filter-bar.ts similarity index 91% rename from src/locales/ca-ES/filter-bar.ts rename to src/locales/ca_ES/filter-bar.ts index 7a3174957ea..1c731d1deaa 100644 --- a/src/locales/ca-ES/filter-bar.ts +++ b/src/locales/ca_ES/filter-bar.ts @@ -16,6 +16,9 @@ export const filterBar: SimpleTranslationEntries = { "costReduction": "Cost Reduction", "costReductionUnlocked": "Cost Reduction Unlocked", "costReductionLocked": "Cost Reduction Locked", + "favorite": "Favorite", + "isFavorite": "Favorite - Yes", + "notFavorite": "Favorite - No", "ribbon": "Ribbon", "hasWon": "Ribbon - Yes", "hasNotWon": "Ribbon - No", diff --git a/src/locales/ca-ES/game-mode.ts b/src/locales/ca_ES/game-mode.ts similarity index 100% rename from src/locales/ca-ES/game-mode.ts rename to src/locales/ca_ES/game-mode.ts diff --git a/src/locales/ca-ES/game-stats-ui-handler.ts b/src/locales/ca_ES/game-stats-ui-handler.ts similarity index 100% rename from src/locales/ca-ES/game-stats-ui-handler.ts rename to src/locales/ca_ES/game-stats-ui-handler.ts diff --git a/src/locales/ca-ES/growth.ts b/src/locales/ca_ES/growth.ts similarity index 100% rename from src/locales/ca-ES/growth.ts rename to src/locales/ca_ES/growth.ts diff --git a/src/locales/ca-ES/menu-ui-handler.ts b/src/locales/ca_ES/menu-ui-handler.ts similarity index 100% rename from src/locales/ca-ES/menu-ui-handler.ts rename to src/locales/ca_ES/menu-ui-handler.ts diff --git a/src/locales/ca-ES/menu.ts b/src/locales/ca_ES/menu.ts similarity index 100% rename from src/locales/ca-ES/menu.ts rename to src/locales/ca_ES/menu.ts diff --git a/src/locales/ca-ES/modifier-select-ui-handler.ts b/src/locales/ca_ES/modifier-select-ui-handler.ts similarity index 100% rename from src/locales/ca-ES/modifier-select-ui-handler.ts rename to src/locales/ca_ES/modifier-select-ui-handler.ts diff --git a/src/locales/ca-ES/modifier-type.ts b/src/locales/ca_ES/modifier-type.ts similarity index 100% rename from src/locales/ca-ES/modifier-type.ts rename to src/locales/ca_ES/modifier-type.ts diff --git a/src/locales/ca-ES/modifier.ts b/src/locales/ca_ES/modifier.ts similarity index 100% rename from src/locales/ca-ES/modifier.ts rename to src/locales/ca_ES/modifier.ts diff --git a/src/locales/ca-ES/move-trigger.ts b/src/locales/ca_ES/move-trigger.ts similarity index 98% rename from src/locales/ca-ES/move-trigger.ts rename to src/locales/ca_ES/move-trigger.ts index b85f27228be..dc6028b116e 100644 --- a/src/locales/ca-ES/move-trigger.ts +++ b/src/locales/ca_ES/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "{{pokemonName}}'s Healing Wish\nwas granted!", "invertStats": "{{pokemonName}}'s stat changes\nwere all reversed!", "resetStats": "{{pokemonName}}'s stat changes\nwere eliminated!", + "statEliminated": "All stat changes were eliminated!", "faintCountdown": "{{pokemonName}}\nwill faint in {{turnCount}} turns.", "copyType": "{{pokemonName}}'s type became the same as\n{{targetPokemonName}}'s type!", "suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!", diff --git a/src/locales/ca-ES/move.ts b/src/locales/ca_ES/move.ts similarity index 100% rename from src/locales/ca-ES/move.ts rename to src/locales/ca_ES/move.ts diff --git a/src/locales/ca-ES/nature.ts b/src/locales/ca_ES/nature.ts similarity index 100% rename from src/locales/ca-ES/nature.ts rename to src/locales/ca_ES/nature.ts diff --git a/src/locales/ca-ES/party-ui-handler.ts b/src/locales/ca_ES/party-ui-handler.ts similarity index 100% rename from src/locales/ca-ES/party-ui-handler.ts rename to src/locales/ca_ES/party-ui-handler.ts diff --git a/src/locales/ca-ES/pokeball.ts b/src/locales/ca_ES/pokeball.ts similarity index 100% rename from src/locales/ca-ES/pokeball.ts rename to src/locales/ca_ES/pokeball.ts diff --git a/src/locales/ca-ES/pokemon-form.ts b/src/locales/ca_ES/pokemon-form.ts similarity index 100% rename from src/locales/ca-ES/pokemon-form.ts rename to src/locales/ca_ES/pokemon-form.ts diff --git a/src/locales/ca-ES/pokemon-info-container.ts b/src/locales/ca_ES/pokemon-info-container.ts similarity index 100% rename from src/locales/ca-ES/pokemon-info-container.ts rename to src/locales/ca_ES/pokemon-info-container.ts diff --git a/src/locales/ca-ES/pokemon-info.ts b/src/locales/ca_ES/pokemon-info.ts similarity index 100% rename from src/locales/ca-ES/pokemon-info.ts rename to src/locales/ca_ES/pokemon-info.ts diff --git a/src/locales/ca-ES/pokemon-summary.ts b/src/locales/ca_ES/pokemon-summary.ts similarity index 100% rename from src/locales/ca-ES/pokemon-summary.ts rename to src/locales/ca_ES/pokemon-summary.ts diff --git a/src/locales/ca-ES/pokemon.ts b/src/locales/ca_ES/pokemon.ts similarity index 100% rename from src/locales/ca-ES/pokemon.ts rename to src/locales/ca_ES/pokemon.ts diff --git a/src/locales/ca-ES/save-slot-select-ui-handler.ts b/src/locales/ca_ES/save-slot-select-ui-handler.ts similarity index 100% rename from src/locales/ca-ES/save-slot-select-ui-handler.ts rename to src/locales/ca_ES/save-slot-select-ui-handler.ts diff --git a/src/locales/ca-ES/settings.ts b/src/locales/ca_ES/settings.ts similarity index 100% rename from src/locales/ca-ES/settings.ts rename to src/locales/ca_ES/settings.ts diff --git a/src/locales/ca-ES/splash-messages.ts b/src/locales/ca_ES/splash-messages.ts similarity index 100% rename from src/locales/ca-ES/splash-messages.ts rename to src/locales/ca_ES/splash-messages.ts diff --git a/src/locales/ca-ES/starter-select-ui-handler.ts b/src/locales/ca_ES/starter-select-ui-handler.ts similarity index 94% rename from src/locales/ca-ES/starter-select-ui-handler.ts rename to src/locales/ca_ES/starter-select-ui-handler.ts index deb4236c8ba..476ee46ae8e 100644 --- a/src/locales/ca-ES/starter-select-ui-handler.ts +++ b/src/locales/ca_ES/starter-select-ui-handler.ts @@ -28,6 +28,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "Toggle IVs", "manageMoves": "Manage Moves", "manageNature": "Manage Nature", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", "useCandies": "Use Candies", "selectNature": "Select nature.", "selectMoveSwapOut": "Select a move to swap out.", diff --git a/src/locales/ca-ES/status-effect.ts b/src/locales/ca_ES/status-effect.ts similarity index 100% rename from src/locales/ca-ES/status-effect.ts rename to src/locales/ca_ES/status-effect.ts diff --git a/src/locales/ca-ES/trainers.ts b/src/locales/ca_ES/trainers.ts similarity index 100% rename from src/locales/ca-ES/trainers.ts rename to src/locales/ca_ES/trainers.ts diff --git a/src/locales/ca-ES/tutorial.ts b/src/locales/ca_ES/tutorial.ts similarity index 100% rename from src/locales/ca-ES/tutorial.ts rename to src/locales/ca_ES/tutorial.ts diff --git a/src/locales/ca-ES/voucher.ts b/src/locales/ca_ES/voucher.ts similarity index 100% rename from src/locales/ca-ES/voucher.ts rename to src/locales/ca_ES/voucher.ts diff --git a/src/locales/ca-ES/weather.ts b/src/locales/ca_ES/weather.ts similarity index 100% rename from src/locales/ca-ES/weather.ts rename to src/locales/ca_ES/weather.ts diff --git a/src/locales/de/ability-trigger.ts b/src/locales/de/ability-trigger.ts index ac80160cef6..30d08d6665b 100644 --- a/src/locales/de/ability-trigger.ts +++ b/src/locales/de/ability-trigger.ts @@ -1,7 +1,7 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; export const abilityTriggers: SimpleTranslationEntries = { - "blockRecoilDamage" : "{{pokemonName}} wurde durch {{abilityName}} vor Rückstoß geschützt!", + "blockRecoilDamage": "{{pokemonName}} wurde durch {{abilityName}} vor Rückstoß geschützt!", "badDreams": "{{pokemonName}} ist in einem Alptraum gefangen!", "costar": "{{pokemonName}} kopiert die Statusveränderungen von {{allyName}}!", "iceFaceAvoidedDamage": "{{pokemonName}} wehrt Schaden mit {{abilityName}} ab!", diff --git a/src/locales/de/filter-bar.ts b/src/locales/de/filter-bar.ts index 1094b0fd43a..7ed7098820b 100644 --- a/src/locales/de/filter-bar.ts +++ b/src/locales/de/filter-bar.ts @@ -16,6 +16,9 @@ export const filterBar: SimpleTranslationEntries = { "costReduction": "Cost Reduction", "costReductionUnlocked": "Cost Reduction Unlocked", "costReductionLocked": "Cost Reduction Locked", + "favorite": "Favorite", + "isFavorite": "Favorite - Yes", + "notFavorite": "Favorite - No", "ribbon": "Band", "hasWon": "Hat Klassik-Modus gewonnen", "hasNotWon": "Hat Klassik-Modus nicht gewonnen", diff --git a/src/locales/de/move-trigger.ts b/src/locales/de/move-trigger.ts index 53c9c847b38..4af494dea3c 100644 --- a/src/locales/de/move-trigger.ts +++ b/src/locales/de/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "Das Heilopfer von {{pokemonName}} erreicht sein Ziel!", "invertStats": "Alle Statusveränderungen von {{pokemonName}} wurden invertiert!", "resetStats": "Die Statusveränderungen von {{pokemonName}} wurden aufgehoben!", + "statEliminated": "Alle Statusveränderungen wurden aufgehoben!", "faintCountdown": "{{pokemonName}} geht nach {{turnCount}} Runden K.O.!", "copyType": "{{pokemonName}} hat den Typ von {{targetPokemonName}} angenommen!", "suppressAbilities": "Die Fähigkeit von {{pokemonName}} wirkt nicht mehr!", diff --git a/src/locales/de/pokemon-info-container.ts b/src/locales/de/pokemon-info-container.ts index 1f82cf2cd83..9540d858cd8 100644 --- a/src/locales/de/pokemon-info-container.ts +++ b/src/locales/de/pokemon-info-container.ts @@ -5,4 +5,5 @@ export const pokemonInfoContainer: SimpleTranslationEntries = { "gender": "Geschlecht:", "ability": "Fähigkeit:", "nature": "Wesen:", + "form": "Form:", } as const; diff --git a/src/locales/de/pokemon-info.ts b/src/locales/de/pokemon-info.ts index 08a23de2b3a..b926c0c5115 100644 --- a/src/locales/de/pokemon-info.ts +++ b/src/locales/de/pokemon-info.ts @@ -3,6 +3,7 @@ import { PokemonInfoTranslationEntries } from "#app/interfaces/locales"; export const pokemonInfo: PokemonInfoTranslationEntries = { Stat: { "HP": "KP", + "HPStat": "KP", "HPshortened": "KP", "ATK": "Angriff", "ATKshortened": "Ang", diff --git a/src/locales/de/starter-select-ui-handler.ts b/src/locales/de/starter-select-ui-handler.ts index e8ae4ed201e..284152bbd33 100644 --- a/src/locales/de/starter-select-ui-handler.ts +++ b/src/locales/de/starter-select-ui-handler.ts @@ -28,6 +28,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "DVs anzeigen/verbergen", "manageMoves": "Attacken ändern", "manageNature": "Wesen ändern", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", "useCandies": "Bonbons verwenden", "selectNature": "Wähle das neue Wesen.", "selectMoveSwapOut": "Wähle die zu ersetzende Attacke.", @@ -41,6 +43,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleAbility": ": Fähigkeit", "cycleNature": ": Wesen", "cycleVariant": ": Seltenheit", + "goFilter": ": Zu den Filtern", "enablePassive": "Passiv-Skill aktivieren", "disablePassive": "Passiv-Skill deaktivieren", "locked": "Gesperrt", diff --git a/src/locales/en/filter-bar.ts b/src/locales/en/filter-bar.ts index 0961df9f058..1dd0c3b2b64 100644 --- a/src/locales/en/filter-bar.ts +++ b/src/locales/en/filter-bar.ts @@ -16,6 +16,9 @@ export const filterBar: SimpleTranslationEntries = { "costReduction": "Cost Reduction", "costReductionUnlocked": "Cost Reduction Unlocked", "costReductionLocked": "Cost Reduction Locked", + "favorite": "Favorite", + "isFavorite": "Favorite - Yes", + "notFavorite": "Favorite - No", "ribbon": "Ribbon", "hasWon": "Ribbon - Yes", "hasNotWon": "Ribbon - No", diff --git a/src/locales/en/move-trigger.ts b/src/locales/en/move-trigger.ts index b85f27228be..dc6028b116e 100644 --- a/src/locales/en/move-trigger.ts +++ b/src/locales/en/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "{{pokemonName}}'s Healing Wish\nwas granted!", "invertStats": "{{pokemonName}}'s stat changes\nwere all reversed!", "resetStats": "{{pokemonName}}'s stat changes\nwere eliminated!", + "statEliminated": "All stat changes were eliminated!", "faintCountdown": "{{pokemonName}}\nwill faint in {{turnCount}} turns.", "copyType": "{{pokemonName}}'s type became the same as\n{{targetPokemonName}}'s type!", "suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!", diff --git a/src/locales/en/starter-select-ui-handler.ts b/src/locales/en/starter-select-ui-handler.ts index deb4236c8ba..5e82abc8187 100644 --- a/src/locales/en/starter-select-ui-handler.ts +++ b/src/locales/en/starter-select-ui-handler.ts @@ -28,6 +28,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "Toggle IVs", "manageMoves": "Manage Moves", "manageNature": "Manage Nature", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", "useCandies": "Use Candies", "selectNature": "Select nature.", "selectMoveSwapOut": "Select a move to swap out.", @@ -41,6 +43,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleAbility": ": Ability", "cycleNature": ": Nature", "cycleVariant": ": Variant", + "goFilter": ": Go to filters", "enablePassive": "Enable Passive", "disablePassive": "Disable Passive", "locked": "Locked", diff --git a/src/locales/es/filter-bar.ts b/src/locales/es/filter-bar.ts index b55a35c1adf..b0eae7542ff 100644 --- a/src/locales/es/filter-bar.ts +++ b/src/locales/es/filter-bar.ts @@ -16,6 +16,9 @@ export const filterBar: SimpleTranslationEntries = { "costReduction": "Cost Reduction", "costReductionUnlocked": "Cost Reduction Unlocked", "costReductionLocked": "Cost Reduction Locked", + "favorite": "Favorite", + "isFavorite": "Favorite - Yes", + "notFavorite": "Favorite - No", "ribbon": "Ribbon", "hasWon": "Ya ha ganado", "hasNotWon": "Aún no ha ganado", diff --git a/src/locales/es/move-trigger.ts b/src/locales/es/move-trigger.ts index a1d9f2e3185..e9bd5523c71 100644 --- a/src/locales/es/move-trigger.ts +++ b/src/locales/es/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "{{pokemonName}}'s Healing Wish\nwas granted!", "invertStats": "{{pokemonName}}'s stat changes\nwere all reversed!", "resetStats": "{{pokemonName}}'s stat changes\nwere eliminated!", + "statEliminated": "¡Los cambios en estadísticas fueron eliminados!", "faintCountdown": "{{pokemonName}}\nwill faint in {{turnCount}} turns.", "copyType": "{{pokemonName}}'s type\nchanged to match {{targetPokemonName}}'s!", "suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!", diff --git a/src/locales/es/starter-select-ui-handler.ts b/src/locales/es/starter-select-ui-handler.ts index d7c203f49c4..1a2be0d8b75 100644 --- a/src/locales/es/starter-select-ui-handler.ts +++ b/src/locales/es/starter-select-ui-handler.ts @@ -28,6 +28,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "Mostrar IVs", "manageMoves": "Cambiar movs.", "manageNature": "Cambiar natur.", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", "useCandies": "Usar Caramelos", "selectNature": "Elige Natur.", "selectMoveSwapOut": "Elige el movimiento que sustituir.", @@ -41,6 +43,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleAbility": ": Habilidad", "cycleNature": ": Naturaleza", "cycleVariant": ": Variante", + "goFilter": ": Ir a filtros", "enablePassive": "Activar Pasiva", "disablePassive": "Desactivar Pasiva", "locked": "Bloqueado", diff --git a/src/locales/fr/filter-bar.ts b/src/locales/fr/filter-bar.ts index 13656192116..0c086c8e52c 100644 --- a/src/locales/fr/filter-bar.ts +++ b/src/locales/fr/filter-bar.ts @@ -16,6 +16,9 @@ export const filterBar: SimpleTranslationEntries = { "costReduction": "Cost Reduction", "costReductionUnlocked": "Cost Reduction Unlocked", "costReductionLocked": "Cost Reduction Locked", + "favorite": "Favorite", + "isFavorite": "Favorite - Yes", + "notFavorite": "Favorite - No", "ribbon": "Ruban", "hasWon": "Ruban - Oui", "hasNotWon": "Ruban - Non", diff --git a/src/locales/fr/move-trigger.ts b/src/locales/fr/move-trigger.ts index 7f9f3a471c6..0bec4de6467 100644 --- a/src/locales/fr/move-trigger.ts +++ b/src/locales/fr/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "Le Vœu Soin est exaucé et profite\nà {{pokemonName}} !", "invertStats": "Les changements de stats\nde {{pokemonName}} sont inversés !", "resetStats": "Les changements de stats\nde {{pokemonName}} ont tous été annulés !", + "statEliminated": "Les changements de stats ont tous été annulés !", "faintCountdown": "{{pokemonName}}\nsera K.O. dans {{turnCount}} tours !", "copyType": "{{pokemonName}} prend le type\nde {{targetPokemonName}} !", "suppressAbilities": "Le talent de {{pokemonName}}\na été rendu inactif !", diff --git a/src/locales/fr/starter-select-ui-handler.ts b/src/locales/fr/starter-select-ui-handler.ts index dbd056cbf2a..aea207b140d 100644 --- a/src/locales/fr/starter-select-ui-handler.ts +++ b/src/locales/fr/starter-select-ui-handler.ts @@ -28,6 +28,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "Voir les IV", "manageMoves": "Modifier les Capacités", "manageNature": "Modifier la Nature", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", "useCandies": "Utiliser des Bonbons", "selectNature": "Sélectionnez une nature.", "selectMoveSwapOut": "Sélectionnez la capacité à échanger.", @@ -41,6 +43,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleAbility": ": Talent", "cycleNature": ": Nature", "cycleVariant": ": Variant", + "goFilter": ": Aller aux filtres", "enablePassive": "Activer Passif", "disablePassive": "Désactiver Passif", "locked": "Verrouillé", diff --git a/src/locales/it/filter-bar.ts b/src/locales/it/filter-bar.ts index c6fcb2f0623..fff93ad02d4 100644 --- a/src/locales/it/filter-bar.ts +++ b/src/locales/it/filter-bar.ts @@ -16,6 +16,9 @@ export const filterBar: SimpleTranslationEntries = { "costReduction": "Cost Reduction", "costReductionUnlocked": "Cost Reduction Unlocked", "costReductionLocked": "Cost Reduction Locked", + "favorite": "Favorite", + "isFavorite": "Favorite - Yes", + "notFavorite": "Favorite - No", "ribbon": "Ribbon", "hasWon": "Ribbon - Yes", "hasNotWon": "Ribbon - No", diff --git a/src/locales/it/move-trigger.ts b/src/locales/it/move-trigger.ts index badf2777d6f..ab17000a95d 100644 --- a/src/locales/it/move-trigger.ts +++ b/src/locales/it/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "{{pokemonName}} riceve i benefici\neffetti di Curardore!", "invertStats": "Le modifiche alle statistiche di {{pokemonName}}\nvengono invertite!", "resetStats": "Tutte le modifiche alle statistiche sono state annullate!", + "statEliminated": "All stat changes were eliminated!", "faintCountdown": "{{pokemonName}}\nandrà KO dopo {{turnCount}} turni.", "copyType": "{{pokemonName}} assume il tipo\ndi {{targetPokemonName}}!", "suppressAbilities": "L’abilità di {{pokemonName}}\nperde ogni efficacia!", diff --git a/src/locales/it/starter-select-ui-handler.ts b/src/locales/it/starter-select-ui-handler.ts index 6f43b9415e0..f92fb5b9f67 100644 --- a/src/locales/it/starter-select-ui-handler.ts +++ b/src/locales/it/starter-select-ui-handler.ts @@ -28,6 +28,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "Vedi/Nascondi IV", "manageMoves": "Gestisci mosse", "manageNature": "Gestisci natura", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", "useCandies": "Usa caramelle", "selectNature": "Seleziona natura.", "selectMoveSwapOut": "Seleziona una mossa da scambiare.", @@ -41,6 +43,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleAbility": ": Abilità", "cycleNature": ": Natura", "cycleVariant": ": Variante", + "goFilter": ": Go to filters", "enablePassive": "Attiva passiva", "disablePassive": "Disattiva passiva", "locked": "Bloccato", diff --git a/src/locales/ja/ability-trigger.ts b/src/locales/ja/ability-trigger.ts index 445f09cbab7..a1ef05407be 100644 --- a/src/locales/ja/ability-trigger.ts +++ b/src/locales/ja/ability-trigger.ts @@ -1,62 +1,63 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; export const abilityTriggers: SimpleTranslationEntries = { - "blockRecoilDamage" : "{{pokemonName}}は {{abilityName}}で\nはんどうダメージを うけない!", - "badDreams": "{{pokemonName}}は ナイトメアに うなされている!", - "costar": "{{pokemonName}} copied {{allyName}}'s stat changes!", - "iceFaceAvoidedDamage": "{{pokemonName}}は\n{{abilityName}}で ダメージを うけない!", - "perishBody": "{{pokemonName}}の {{abilityName}}で\nおたがいは 3ターンごに ほろびてしまう!", - "poisonHeal": "{{pokemonName}}は {{abilityName}}で\nかいふくした!", - "trace": "{{pokemonName}} copied {{targetName}}'s\n{{abilityName}}!", - "windPowerCharged": "{{pokemonName}}は\n{{moveName}}を うけて じゅうでんした!", - "quickDraw": "{{pokemonName}} can act faster than normal, thanks to its Quick Draw!", - "blockItemTheft": "{{pokemonNameWithAffix}}'s {{abilityName}}\nprevents item theft!", - "typeImmunityHeal": "{{pokemonNameWithAffix}}'s {{abilityName}}\nrestored its HP a little!", - "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} avoided damage\nwith {{abilityName}}!", - "postDefendDisguise": "{{pokemonNameWithAffix}}'s disguise was busted!", - "moveImmunity": "It doesn't affect {{pokemonNameWithAffix}}!", - "reverseDrain": "{{pokemonNameWithAffix}} sucked up the liquid ooze!", - "postDefendTypeChange": "{{pokemonNameWithAffix}}'s {{abilityName}}\nmade it the {{typeName}} type!", - "postDefendContactDamage": "{{pokemonNameWithAffix}}'s {{abilityName}}\nhurt its attacker!", - "postDefendAbilitySwap": "{{pokemonNameWithAffix}} swapped\nabilities with its target!", - "postDefendAbilityGive": "{{pokemonNameWithAffix}} gave its target\n{{abilityName}}!", - "postDefendMoveDisable": "{{pokemonNameWithAffix}}'s {{moveName}}\nwas disabled!", - "pokemonTypeChange": "{{pokemonNameWithAffix}} transformed into the {{moveType}} type!", - "postAttackStealHeldItem": "{{pokemonNameWithAffix}} stole\n{{defenderName}}'s {{stolenItemType}}!", - "postDefendStealHeldItem": "{{pokemonNameWithAffix}} stole\n{{attackerName}}'s {{stolenItemType}}!", - "copyFaintedAllyAbility": "{{pokemonNameWithAffix}}'s {{abilityName}} was taken over!", - "intimidateImmunity": "{{pokemonNameWithAffix}}'s {{abilityName}} prevented it from being Intimidated!", - "postSummonAllyHeal": "{{pokemonNameWithAffix}} drank down all the\nmatcha that {{pokemonName}} made!", - "postSummonClearAllyStats": "{{pokemonNameWithAffix}}'s stat changes\nwere removed!", - "postSummonTransform": "{{pokemonNameWithAffix}} transformed\ninto {{targetName}}!", - "protectStat": "{{pokemonNameWithAffix}}'s {{abilityName}}\nprevents lowering its {{statName}}!", - "statusEffectImmunityWithName": "{{pokemonNameWithAffix}}'s {{abilityName}}\nprevents {{statusEffectName}}!", - "statusEffectImmunity": "{{pokemonNameWithAffix}}'s {{abilityName}}\nprevents status problems!", - "battlerTagImmunity": "{{pokemonNameWithAffix}}'s {{abilityName}}\nprevents {{battlerTagName}}!", - "forewarn": "{{pokemonNameWithAffix}} was forewarned about {{moveName}}!", - "frisk": "{{pokemonNameWithAffix}} frisked {{opponentName}}'s {{opponentAbilityName}}!", - "postWeatherLapseHeal": "{{pokemonNameWithAffix}}'s {{abilityName}}\nrestored its HP a little!", - "postWeatherLapseDamage": "{{pokemonNameWithAffix}} is hurt\nby its {{abilityName}}!", - "postTurnLootCreateEatenBerry": "{{pokemonNameWithAffix}} harvested one {{berryName}}!", - "postTurnHeal": "{{pokemonNameWithAffix}}'s {{abilityName}}\nrestored its HP a little!", - "fetchBall": "{{pokemonNameWithAffix}} found a\n{{pokeballName}}!", - "healFromBerryUse": "{{pokemonNameWithAffix}}'s {{abilityName}}\nrestored its HP!", - "arenaTrap": "{{pokemonNameWithAffix}}'s {{abilityName}}\nprevents switching!", - "postBattleLoot": "{{pokemonNameWithAffix}} picked up\n{{itemName}}!", - "postFaintContactDamage": "{{pokemonNameWithAffix}}'s {{abilityName}}\nhurt its attacker!", - "postFaintHpDamage": "{{pokemonNameWithAffix}}'s {{abilityName}}\nhurt its attacker!", - "postSummonPressure": "{{pokemonNameWithAffix}} is exerting its Pressure!", - "postSummonMoldBreaker": "{{pokemonNameWithAffix}} breaks the mold!", - "postSummonAnticipation": "{{pokemonNameWithAffix}} shuddered!", - "postSummonTurboblaze": "{{pokemonNameWithAffix}} is radiating a blazing aura!", - "postSummonTeravolt": "{{pokemonNameWithAffix}} is radiating a bursting aura!", - "postSummonDarkAura": "{{pokemonNameWithAffix}} is radiating a Dark Aura!", - "postSummonFairyAura": "{{pokemonNameWithAffix}} is radiating a Fairy Aura!", - "postSummonNeutralizingGas": "{{pokemonNameWithAffix}}'s Neutralizing Gas filled the area!", - "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} has two Abilities!", - "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} has two Abilities!", - "postSummonVesselOfRuin": "{{pokemonNameWithAffix}}'s Vessel of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", - "postSummonSwordOfRuin": "{{pokemonNameWithAffix}}'s Sword of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", - "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}'s Tablets of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", - "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}'s Beads of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", + "blockRecoilDamage" : "{{pokemonName}}は {{abilityName}}で 反動ダメージを 受けない!", + "badDreams": "{{pokemonName}}は ナイトメアに うなされている!", + "costar": "{{pokemonName}}は {{allyName}}の\n能力変化を コピーした!", + "iceFaceAvoidedDamage": "{{pokemonName}}は\n{{abilityName}}で ダメージを 受けない!", + "perishBody": "{{pokemonName}}の {{abilityName}}で\nおたがいは 3ターン後に ほろびいてしまう!", + "poisonHeal": "{{pokemonName}}は {{abilityName}}で 回復した!", + "trace": "{{pokemonName}}は 相手の {{targetName}}の\n{{abilityName}}を トレースした!", + "windPowerCharged": "{{pokemonName}}は\n{{moveName}}を 受けて じゅうでんした!", + "quickDraw": "{{pokemonName}}は クイックドロウで\n行動が はやくなった!", + "blockItemTheft": "{{pokemonNameWithAffix}}の {{abilityName}}で\n道具を うばわれない!", + "typeImmunityHeal": "{{pokemonNameWithAffix}}は {{abilityName}}で\n体力を 回復した!", + "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}}は {{abilityName}}で\nダメージを 受けない。", + "postDefendDisguise": "{{pokemonNameWithAffix}}の\nばけのかわが はがれた!", + "moveImmunity": "{{pokemonNameWithAffix}}には\n効果が ないようだ…", + "reverseDrain": "{{pokemonNameWithAffix}}は\nヘドロえきを 吸い取った!", + "postDefendTypeChange": "{{pokemonNameWithAffix}}は {{abilityName}}で\n{{typeName}}タイプに なった!", + "postDefendContactDamage": "{{pokemonNameWithAffix}}は {{abilityName}}で\n相手を キズつけた!", + "postDefendAbilitySwap": "{{pokemonNameWithAffix}}は\nおたがいの 特性を 入れ替えた!", + "postDefendAbilityGive": "{{pokemonNameWithAffix}}は\n特性が {{abilityName}}に なっちゃった!", + "postDefendMoveDisable": "{{pokemonNameWithAffix}}の\n{{moveName}}を 封じこめた!", + "pokemonTypeChange": "{{pokemonNameWithAffix}}は\n{{moveType}}タイプに なった!", + "postAttackStealHeldItem": "{{pokemonNameWithAffix}}は {{defenderName}}から\n{{stolenItemType}}を うばいとった!", + "postDefendStealHeldItem": "{{pokemonNameWithAffix}}は {{attackerName}}から\n{{stolenItemType}}を うばいとった!", + "copyFaintedAllyAbility": "{{pokemonNameWithAffix}}の\n{{abilityName}}を 引き継いだ!", + "intimidateImmunity": "{{pokemonNameWithAffix}}は\n{{abilityName}}の 効果で 能力が 下がらない!", + "postSummonAllyHeal": "{{pokemonNameWithAffix}}が たてた お茶を\n{{pokemonName}}は 飲みほした!", + "postSummonClearAllyStats": "{{pokemonNameWithAffix}}の\n能力変化が 元に戻った!", + "postSummonTransform": "{{pokemonNameWithAffix}}は\n{{targetName}}に 変身した!", + "protectStat": "{{pokemonNameWithAffix}}は {{abilityName}}の 効果で\n{{statName}}が 下がらない!", + "statusEffectImmunityWithName": "{{pokemonNameWithAffix}}は {{abilityName}}で\{{statusEffectName}}に ならない!", + "statusEffectImmunity": "{{pokemonNameWithAffix}}は {{abilityName}}で\n状態異常に ならない!", + "battlerTagImmunity": "{{pokemonNameWithAffix}}は {{abilityName}}で]\n{{battlerTagName}}を 無視した!", + "forewarn": "{{pokemonNameWithAffix}}の\n{{moveName}}を 読み取った!", + "frisk": "{{pokemonNameWithAffix}}は {{opponentName}}の\n{{opponentAbilityName}}を お見通しだ!", + "postWeatherLapseHeal": "{{pokemonNameWithAffix}}は {{abilityName}}で\n体力を 回復した!", + "postWeatherLapseDamage": "{{pokemonNameWithAffix}}は\n{{abilityName}}の ダメージを 受けた!", + "postTurnLootCreateEatenBerry": "{{pokemonNameWithAffix}}は\n{{berryName}}を 収穫した!", + "postTurnHeal": "{{pokemonNameWithAffix}}は {{abilityName}}で\n体力を 回復した!", + "fetchBall": "{{pokemonNameWithAffix}}は\n{{pokeballName}}を 拾ってきた!", + "healFromBerryUse": "{{pokemonNameWithAffix}}は {{abilityName}}で\n体力を 回復した!", + "arenaTrap": "{{pokemonNameWithAffix}}の {{abilityName}}で\n入れ替えることが できない!", + "postBattleLoot": "{{pokemonNameWithAffix}}は\n{{itemName}}を 拾った!", + "postFaintContactDamage": "{{pokemonNameWithAffix}}は {{abilityName}}で\n相手に ダメージを 与えた!", + "postFaintHpDamage": "{{pokemonNameWithAffix}}は {{abilityName}}で\n相手に ダメージを 与えた!", + "postSummonPressure": "{{pokemonNameWithAffix}}は\nプレッシャーを 放っている!", + "postSummonMoldBreaker": "{{pokemonNameWithAffix}}は\nかたやぶりだ!", + "postSummonAnticipation": "{{pokemonNameWithAffix}}は\nみぶるいした!", + "postSummonTurboblaze": "{{pokemonNameWithAffix}}は\n燃え盛(もえさか)る オーラを 放っている!", + "postSummonTeravolt": "{{pokemonNameWithAffix}}は\n弾(はじ)ける オーラを 放っている!", + "postSummonDarkAura": "{{pokemonNameWithAffix}}は\nダークオーラを 放っている!", + "postSummonFairyAura": "{{pokemonNameWithAffix}}は\nフェアリーオーラを 放っている!", + "postSummonNeutralizingGas": "あたりに かがくへんかガスが 充満した!", + "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}}は\nふたつの 特性を あわせ持つ!", + "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}}は\nふたつの 特性を あわせ持つ!", + "postSummonVesselOfRuin": "{{pokemonNameWithAffix}}の わざわいのうつわで\nまわりの {{statName}}が 弱まった!", + "postSummonSwordOfRuin": "{{pokemonNameWithAffix}}の わざわいのつるぎで\nまわりの {{statName}}が 弱まった!", + "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}の わざわいのおふだ\nまわりの {{statName}}が 弱まった!", + "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}の わざわいのたまで\nまわりの {{statName}}が 弱まった!", + "preventBerryUse": "{{pokemonNameWithAffix}}は 緊張して\nきのみが 食べられなくなった!", } as const; diff --git a/src/locales/ja/achv.ts b/src/locales/ja/achv.ts index 7e8d41c9808..9693a16cdc0 100644 --- a/src/locales/ja/achv.ts +++ b/src/locales/ja/achv.ts @@ -3,171 +3,171 @@ import { AchievementTranslationEntries } from "#app/interfaces/locales.js"; // Achievement translations for the when the player character is male export const PGMachv: AchievementTranslationEntries = { "Achievements": { - name: "Achievements", + name: "実績", }, "Locked": { - name: "Locked", + name: "なし", }, "MoneyAchv": { - description: "Accumulate a total of ₽{{moneyAmount}}", + description: "一回の ランで ₽{{moneyAmount}}を 稼ぐ", }, "10K_MONEY": { - name: "Money Haver", + name: "お金を持つ人", }, "100K_MONEY": { - name: "Rich", + name: "富豪", }, "1M_MONEY": { - name: "Millionaire", + name: "百万長者", }, "10M_MONEY": { - name: "One Percenter", + name: "超富裕層", }, "DamageAchv": { - description: "Inflict {{damageAmount}} damage in one hit", + description: "一撃で {{damageAmount}}ダメージを 与える", }, "250_DMG": { - name: "Hard Hitter", + name: "力持ち", }, "1000_DMG": { - name: "Harder Hitter", + name: "強者", }, "2500_DMG": { - name: "That's a Lotta Damage!", + name: "カカロット", }, "10000_DMG": { - name: "One Punch Man", + name: "ワンパンマン", }, "HealAchv": { - description: "Heal {{healAmount}} {{HP}} at once with a move, ability, or held item", + description: "一つの 技や 特性や 持っているアイテムで {{healAmount}}{{HP}}を 一気に 回復する", }, "250_HEAL": { - name: "Novice Healer", + name: "回復発見者", }, "1000_HEAL": { - name: "Big Healer", + name: "大いなる治療者", }, "2500_HEAL": { - name: "Cleric", + name: "回復達人", }, "10000_HEAL": { - name: "Recovery Master", + name: "ジョーイさん", }, "LevelAchv": { - description: "Level up a Pokémon to Lv{{level}}", + description: "一つの ポケモンを Lv{{level}}まで レベルアップする", }, "LV_100": { - name: "But Wait, There's More!", + name: "まだまだだよ", }, "LV_250": { - name: "Elite", + name: "天王", }, "LV_1000": { - name: "To Go Even Further Beyond", + name: "向こうの向こうを超え", }, "RibbonAchv": { - description: "Accumulate a total of {{ribbonAmount}} Ribbons", + description: "{{ribbonAmount}}巻の リボンを 積もる", }, "10_RIBBONS": { - name: "Pokémon League Champion", + name: "ポケモンリーグチャンピオン", }, "25_RIBBONS": { - name: "Great League Champion", + name: "スーパーリーグチャンピオン", }, "50_RIBBONS": { - name: "Ultra League Champion", + name: "ハイパーリーグチャンピオン", }, "75_RIBBONS": { - name: "Rogue League Champion", + name: "ローグリーグチャンピオン", }, "100_RIBBONS": { - name: "Master League Champion", + name: "マスターリーグチャンピオン", }, "TRANSFER_MAX_BATTLE_STAT": { - name: "Teamwork", - description: "Baton pass to another party member with at least one stat maxed out", + name: "同力", + description: "少なくとも 一つの 能力を 最大まで あげて 他の 手持ちポケモンに バトンタッチする", }, "MAX_FRIENDSHIP": { - name: "Friendmaxxing", - description: "Reach max friendship on a Pokémon", + name: "マブ達", + description: "一つの 手持ちポケモンの 仲良し度を 最大に 上げる", }, "MEGA_EVOLVE": { - name: "Megamorph", - description: "Mega evolve a Pokémon", + name: "ザ・アブソリュート", + description: "一つの 手持ちポケモンを メガシンカさせる", }, "GIGANTAMAX": { - name: "Absolute Unit", - description: "Gigantamax a Pokémon", + name: "太―くて 堪らない", + description: "一つの 手持ちポケモンを キョダイマックスさせる", }, "TERASTALLIZE": { - name: "STAB Enthusiast", - description: "Terastallize a Pokémon", + name: "一致好き", + description: "一つの 手持ちポケモンを テラスタルさせる", }, "STELLAR_TERASTALLIZE": { - name: "The Hidden Type", - description: "Stellar Terastallize a Pokémon", + name: "隠れたタイプ", + description: "一つの 手持ちポケモンを ステラ・テラスタルさせる", }, "SPLICE": { - name: "Infinite Fusion", - description: "Splice two Pokémon together with DNA Splicers", + name: "インフィニット・フュジョン", + description: "いでんしのくさびで 二つの ポケモンを 吸収合体させる", }, "MINI_BLACK_HOLE": { - name: "A Hole Lot of Items", - description: "Acquire a Mini Black Hole", + name: "アイテムホーリック", + description: "ミニブラックホールを 手に入れる", }, "CATCH_MYTHICAL": { - name: "Mythical", - description: "Catch a mythical Pokémon", + name: "幻", + description: "幻の ポケモンを 捕まえる", }, "CATCH_SUB_LEGENDARY": { - name: "(Sub-)Legendary", - description: "Catch a sub-legendary Pokémon", + name: "準・伝説", + description: "準伝説の ポケモンを 捕まえる", }, "CATCH_LEGENDARY": { - name: "Legendary", - description: "Catch a legendary Pokémon", + name: "ザ・伝説", + description: "伝説の ポケモンを 捕まえる", }, "SEE_SHINY": { - name: "Shiny", - description: "Find a shiny Pokémon in the wild", + name: "色とりどりに光る", + description: "野生の 色違いポケモンを みつける", }, "SHINY_PARTY": { - name: "That's Dedication", - description: "Have a full party of shiny Pokémon", + name: "きらきら努力家", + description: "手持ちポケモンは 全員 色違いポケモンに する", }, "HATCH_MYTHICAL": { - name: "Mythical Egg", - description: "Hatch a mythical Pokémon from an egg", + name: "幻のタマゴ", + description: "幻の ポケモンを タマゴから 生まれる", }, "HATCH_SUB_LEGENDARY": { - name: "Sub-Legendary Egg", - description: "Hatch a sub-legendary Pokémon from an egg", + name: "準伝説のタマゴ", + description: "準伝説の ポケモンを タマゴから 生まれる", }, "HATCH_LEGENDARY": { - name: "Legendary Egg", - description: "Hatch a legendary Pokémon from an egg", + name: "伝説のタマゴ", + description: "伝説の ポケモンを タマゴから 生まれる", }, "HATCH_SHINY": { - name: "Shiny Egg", - description: "Hatch a shiny Pokémon from an egg", + name: "色違いタマゴ", + description: "色違いポケモンを タマゴから 生まれる", }, "HIDDEN_ABILITY": { - name: "Hidden Potential", - description: "Catch a Pokémon with a hidden ability", + name: "底力", + description: "隠れ特性がある ポケモンを 捕まえる", }, "PERFECT_IVS": { - name: "Certificate of Authenticity", - description: "Get perfect IVs on a Pokémon", + name: "個体値の賞状", + description: "一つの ポケモンの 個体値を すべて 最大に する", }, "CLASSIC_VICTORY": { - name: "Undefeated", - description: "Beat the game in classic mode", + name: "無双", + description: "クラシックモードを クリアする", }, "UNEVOLVED_CLASSIC_VICTORY": { name: "Bring Your Child To Work Day", @@ -175,102 +175,102 @@ export const PGMachv: AchievementTranslationEntries = { }, "MONO_GEN_ONE": { - name: "The Original Rival", - description: "Complete the generation one only challenge.", + name: "原始", + description: "1世代の 単一世代チャレンジを クリアする", }, "MONO_GEN_TWO": { - name: "Generation 1.5", - description: "Complete the generation two only challenge.", + name: "懐かしいカンジョウ", + description: "2世代の 単一世代チャレンジを クリアする", }, "MONO_GEN_THREE": { - name: "Too much water?", - description: "Complete the generation three only challenge.", + name: "水浸し", + description: "3世代の 単一世代チャレンジを クリアする", }, "MONO_GEN_FOUR": { - name: "Is she really the hardest?", - description: "Complete the generation four only challenge.", + name: "神々の地", + description: "4世代の 単一世代チャレンジを クリアする", }, "MONO_GEN_FIVE": { - name: "All Original", - description: "Complete the generation five only challenge.", + name: "ニューヨーカー", + description: "5世代の 単一世代チャレンジを クリアする", }, "MONO_GEN_SIX": { - name: "Almost Royalty", - description: "Complete the generation six only challenge.", + name: "サヴァ・サヴァ", + description: "6世代の 単一世代チャレンジを クリアする", }, "MONO_GEN_SEVEN": { - name: "Only Technically", - description: "Complete the generation seven only challenge.", + name: "アローラ・オエ", + description: "7世代の 単一世代チャレンジを クリアする", }, "MONO_GEN_EIGHT": { - name: "A Champion Time!", - description: "Complete the generation eight only challenge.", + name: "チャンピオン タイムを 楽しめ!", + description: "8世代の 単一世代チャレンジを クリアする", }, "MONO_GEN_NINE": { - name: "She was going easy on you", - description: "Complete the generation nine only challenge.", + name: "ネモに甘えたでしょう", + description: "9世代の 単一世代チャレンジを クリアする", }, "MonoType": { - description: "Complete the {{type}} monotype challenge.", + description: "{{type}}タイプの 単一タイプチャレンジを クリアする", }, "MONO_NORMAL": { - name: "Extra Ordinary", + name: "凡人", }, "MONO_FIGHTING": { - name: "I Know Kung Fu", + name: "八千以上だ!!", }, "MONO_FLYING": { - name: "Angry Birds", + name: "翼をください", }, "MONO_POISON": { - name: "Kanto's Favourite", + name: "カントーの名物", }, "MONO_GROUND": { - name: "Forecast: Earthquakes", + name: "自信でユラユラ", }, "MONO_ROCK": { - name: "Brock Hard", + name: "タケシの挑戦状", }, "MONO_BUG": { - name: "You Like Jazz?", + name: "チョウチョウせん者", }, "MONO_GHOST": { - name: "Who You Gonna Call?", + name: "貞子ちゃん", }, "MONO_STEEL": { - name: "Iron Giant", + name: "ハガネーター", }, "MONO_FIRE": { - name: "I Cast Fireball!", + name: "NIGHT OF FIRE", }, "MONO_WATER": { - name: "When It Rains, It Pours", + name: "土砂降リスト", }, "MONO_GRASS": { - name: "Can't Touch This", + name: "www", }, "MONO_ELECTRIC": { - name: "Aim For The Horn!", + name: "パチピカペコ", }, "MONO_PSYCHIC": { - name: "Big Brain Energy", + name: "陽キャ", }, "MONO_ICE": { - name: "Walking On Thin Ice", + name: "ありのまま", }, "MONO_DRAGON": { - name: "Pseudo-Legend Club", + name: "龍が如く", }, "MONO_DARK": { - name: "It's Just A Phase", + name: "陰キャ", }, "MONO_FAIRY": { - name: "Hey! Listen!", + name: "あらハート満タンになった", }, "FRESH_START": { - name: "First Try!", - description: "Complete the fresh start challenge." + name: "一発で!", + description: "出直しチャレンジを クリアする" } } as const; diff --git a/src/locales/ja/battle.ts b/src/locales/ja/battle.ts index aed24a710df..7e9313ebaf8 100644 --- a/src/locales/ja/battle.ts +++ b/src/locales/ja/battle.ts @@ -1,159 +1,159 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; export const battle: SimpleTranslationEntries = { - "bossAppeared": "{{bossName}}が あらわれた!", - "trainerAppeared": "{{trainerName}}が\nしょうぶを しかけてきた!", - "trainerAppearedDouble": "{{trainerName}}が\nしょうぶを しかけてきた!", - "trainerSendOut": "{{trainerName}}は\n{{pokemonName}}を くりだした!", - "singleWildAppeared": "あっ! やせいの\n{{pokemonName}}が とびだしてきた!", - "multiWildAppeared": "あっ! やせいの {{pokemonName1}}と\n{{pokemonName2}}が とびだしてきた!", - "playerComeBack": "{{pokemonName}}! もどれ!", - "trainerComeBack": "{{trainerName}}は\n{{pokemonName}}を ひっこめた!", + "bossAppeared": "{{bossName}}が 現れた!", + "trainerAppeared": "{{trainerName}}が\n勝負を しかけてきた!", + "trainerAppearedDouble": "{{trainerName}}が\n勝負を しかけてきた!", + "trainerSendOut": "{{trainerName}}は\n{{pokemonName}}を 繰り出した!", + "singleWildAppeared": "あっ! 野生の {{pokemonName}}が 飛び出してきた!", + "multiWildAppeared": "あっ! 野生の {{pokemonName1}}と\n{{pokemonName2}}が 飛び出してきた!", + "playerComeBack": "{{pokemonName}}! 戻れ!", + "trainerComeBack": "{{trainerName}}は\n{{pokemonName}}を 引っ込めた!", "playerGo": "ゆけっ! {{pokemonName}}!", - "trainerGo": "{{trainerName}}は\n{{pokemonName}}を くりだした!", - "switchQuestion": "{{pokemonName}}を\nいれかえますか?", - "trainerDefeated": "{{trainerName}}\nとの しょうぶに かった!", - "moneyWon": "しょうきんとして\n₽{{moneyAmount}} てにいれた!", - "moneyPickedUp": "₽{{moneyAmount}}を ひろった!", - "pokemonCaught": "{{pokemonName}}を\nつかまえたぞ!", - "addedAsAStarter": "{{pokemonName}} has been\nadded as a starter!", - "partyFull": "てもちがいっぱいです。\n{{pokemonName}}をいれるために ポケモンを ひとり てばなしますか?", + "trainerGo": "{{trainerName}}は\n{{pokemonName}}を 繰り出した!", + "switchQuestion": "{{pokemonName}}を\n入れ替えますか?", + "trainerDefeated": "{{trainerName}} との 勝負に 勝った!", + "moneyWon": "賞金として ₽{{moneyAmount}}を 手に入れた!", + "moneyPickedUp": "₽{{moneyAmount}}を 拾った!", + "pokemonCaught": "{{pokemonName}}を 捕まえたぞ!", + "addedAsAStarter": "今から {{pokemonName}}は 最初のパートナーとして 選べられる!", + "partyFull": "手持ちが いっぱいです。\n{{pokemonName}}を入れる ために ポケモンを 一つ 逃がすか?", "pokemon": "ポケモン", - "sendOutPokemon": "がんばれ! {{pokemonName}}!", - "hitResultCriticalHit": "きゅうしょに あたった!", - "hitResultSuperEffective": "こうかは ばつぐんだ!", - "hitResultNotVeryEffective": "こうかは いまひとつの ようだ……", - "hitResultNoEffect": "{{pokemonName}}には こうかが ないようだ…", - "hitResultOneHitKO": "いちげき ひっさつ!", - "attackFailed": "しかし うまく きまらなかった!!", - "attackMissed": "{{pokemonNameWithAffix}}には あたらなかった!", - "attackHitsCount": "{{count}}かい あたった!", - "rewardGain": "{{modifierName}}を\nてにいれた!", - "expGain": "{{pokemonName}}は\n{{exp}}けいけんちを もらった!", - "levelUp": "{{pokemonName}}は\nレベル{{level}} に あがった!", - "learnMove": "{{pokemonName}}は あたらしく\n{{moveName}}を おぼえた!", - "learnMovePrompt": "{{pokemonName}}は あたらしく\n{{moveName}}を おぼえたい……", - "learnMoveLimitReached": "しかし {{pokemonName}}は わざを 4つ\nおぼえるので せいいっぱいだ!", - "learnMoveReplaceQuestion": "{{moveName}}の かわりに\nほかの わざを わすれさせますか?", - "learnMoveStopTeaching": "それでは…… {{moveName}}を\nおぼえるのを あきらめますか?", - "learnMoveNotLearned": "{{pokemonName}}は {{moveName}}を\nおぼえずに おわった!", - "learnMoveForgetQuestion": "どの わざを\nわすれさせたい?", - "learnMoveForgetSuccess": "{{pokemonName}}は {{moveName}}の\nつかいかたを きれいに わすれた!", + "sendOutPokemon": "頑張れ! {{pokemonName}}!", + "hitResultCriticalHit": "急所に 当たった!", + "hitResultSuperEffective": "効果は バツグンだ!", + "hitResultNotVeryEffective": "効果は 今ひとつの ようだ……", + "hitResultNoEffect": "{{pokemonName}}には 効果が ないようだ…", + "hitResultOneHitKO": "一撃必殺!", + "attackFailed": "しかし うまく 決まらなかった!!", + "attackMissed": "{{pokemonNameWithAffix}}には 当たらなかった!", + "attackHitsCount": "{{count}}かい 当たった!", + "rewardGain": "{{modifierName}}を 手に入れた!", + "expGain": "{{pokemonName}}は\n{{exp}}経験値を もらった!", + "levelUp": "{{pokemonName}}は\nレベル{{level}}に 上がった!", + "learnMove": "{{pokemonName}}は 新しく\n{{moveName}}を 覚えた!", + "learnMovePrompt": "{{pokemonName}}は 新しく\n{{moveName}}を 覚えたい……", + "learnMoveLimitReached": "しかし {{pokemonName}}は 技を 4つ\n覚えるので せいいっぱいだ!", + "learnMoveReplaceQuestion": "{{moveName}}の 代わりに\n他の 技を 忘れさせますか?", + "learnMoveStopTeaching": "それでは {{moveName}}を\n覚えるのを 諦めますか?", + "learnMoveNotLearned": "{{pokemonName}}は {{moveName}}を\n覚えずに 終わった!", + "learnMoveForgetQuestion": "どの 技を\n忘れさせたい?", + "learnMoveForgetSuccess": "{{pokemonName}}は {{moveName}}の\n使い方を きれいに 忘れた!", "countdownPoof": "@d{32}1 @d{15}2の @d{15}… @d{15}… @d{15}… @d{15}@s{pb_bounce_1}ポカン!", "learnMoveAnd": "そして…", - "levelCapUp": "レベルキャップの\n{{levelCap}}に あがった!", - "moveNotImplemented": "{{moveName}}は まだじっそうされておらず、せんたくできません。", - "moveNoPP": "しかし わざの\nのこりポイントが なかった!", - "moveDisabled": "かなしばりで\n{{moveName}}が だせない!", - "noPokeballForce": "みえない ちからの せいで\nボールを なげられない!", - "noPokeballTrainer": "ひとのものを\nとったら どろぼう!", - "noPokeballMulti": "あいての ポケモンが ひとつしか\n いないまえに ボールが つかえない!", - "noPokeballStrong": "あいての ポケモンが つよすぎて つかまえられない!\nまずは よわらせよう!", - "noEscapeForce": "みえない ちからの せいで\nにげることが できない!", - "noEscapeTrainer": "ダメだ! しょうぶのさいちゅうに\nあいてに せなかを みせられない!", - "noEscapePokemon": "{{pokemonName}}の {{moveName}}で {{escapeVerb}}!", - "runAwaySuccess": " うまく にげきれた!", - "runAwayCannotEscape": "にげることが できない!", - "escapeVerbSwitch": "いれかえることが できない", - "escapeVerbFlee": "にげることが できない", - "notDisabled": "{{pokemonName}}の かなしばりが とけた!\nまた {{moveName}}が つかえられる!", - "turnEndHpRestore": "{{pokemonName}}の たいりょくが かいふくした!", - "hpIsFull": "{{pokemonName}}の\nHPが まんたんだ!", - "skipItemQuestion": "ほんとに アイテムを とらない?", + "levelCapUp": "レベルキャップの\n{{levelCap}}に 上がった!", + "moveNotImplemented": "{{moveName}}は まだ 実装されておらず 選択できません。", + "moveNoPP": "しかし 技の\n残りポイントが なかった!", + "moveDisabled": "かなしばりで\n{{moveName}}が 出せない!", + "noPokeballForce": "見えない 力の せいで\nボールが 投げられない!", + "noPokeballTrainer": "人の ものを 取ったら 泥棒!", + "noPokeballMulti": "相手の ポケモンが 一つしか\nいない 前に ボールが 使えない!", + "noPokeballStrong": "相手の ポケモンが 強すぎて 捕まえられない!\nまずは 弱めよう!", + "noEscapeForce": "見えない 力の せいで\n逃げることが できない!", + "noEscapeTrainer": "ダメだ! 勝負の最中に\n相手に 背中を 見せられない!", + "noEscapePokemon": "{{pokemonName}}の {{moveName}}で {{escapeVerb}}!", + "runAwaySuccess": " うまく 逃げ切れた!", + "runAwayCannotEscape": "逃げることが できない!", + "escapeVerbSwitch": "入れ替えることが できない", + "escapeVerbFlee": "逃げることが できない", + "notDisabled": "{{pokemonName}}の かなしばりが 溶けた!\nまた {{moveName}}が 使えられる!", + "turnEndHpRestore": "{{pokemonName}}の 体力が 回復した!", + "hpIsFull": "{{pokemonName}}の\n体力が 満タンだ!", + "skipItemQuestion": "本当に アイテムを 取らずに 進みますか?", "eggHatching": "おや?", - "ivScannerUseQuestion": "{{pokemonName}}を\nこたいちスキャナーで そうさする?", - "wildPokemonWithAffix": "やせいの {{pokemonName}}", - "foePokemonWithAffix": "あいての {{pokemonName}}", - "useMove": "{{pokemonNameWithAffix}}の {{moveName}}!", - "drainMessage": "{{pokemonName}}から\nたいりょくを すいとった!", - "regainHealth": "{{pokemonName}}は\nたいりょくを かいふくした!", - "stealEatBerry": "{{pokemonName}}は {{targetName}}の\n{{berryName}}を うばって たべた!", - "ppHealBerry": "{{pokemonNameWithAffix}}は {{berryName}}で {{moveName}}のPPを かいふくした!", - "hpHealBerry": "{{pokemonNameWithAffix}}は {{berryName}}で たいりょくを かいふくした!", - "fainted": "{{pokemonNameWithAffix}}は たおれた!", + "ivScannerUseQuestion": "{{pokemonName}}を\n個体値スキャナーで 操作しますか?", + "wildPokemonWithAffix": "野生の {{pokemonName}}", + "foePokemonWithAffix": "相手の {{pokemonName}}", + "useMove": "{{pokemonNameWithAffix}}の {{moveName}}!", + "drainMessage": "{{pokemonName}}から\n体力を 吸い取った!", + "regainHealth": "{{pokemonName}}は\n体力を 回復した!", + "stealEatBerry": "{{pokemonName}}は {{targetName}}の\n{{berryName}}を うばって 食べた!", + "ppHealBerry": "{{pokemonNameWithAffix}}は {{berryName}}で {{moveName}}のPPを 回復した!", + "hpHealBerry": "{{pokemonNameWithAffix}}は {{berryName}}で 体力を 回復した!", + "fainted": "{{pokemonNameWithAffix}}は 倒れた!", "statsAnd": "と ", - "stats": "のうりょく", - "statRose_one": "{{pokemonNameWithAffix}}の {{stats}}が あがった!", - "statRose_other": "{{pokemonNameWithAffix}}の {{stats}}が あがった!", - "statSharplyRose_one": "{{pokemonNameWithAffix}}の {{stats}}が ぐーんと あがった!", - "statSharplyRose_other": "{{pokemonNameWithAffix}}の {{stats}}が ぐーんと あがった!", - "statRoseDrastically_one": "{{pokemonNameWithAffix}}の {{stats}}が ぐぐーんと あがった!", - "statRoseDrastically_other": "{{pokemonNameWithAffix}}の {{stats}}が ぐぐーんと あがった!", - "statWontGoAnyHigher_one": "{{pokemonNameWithAffix}}の {{stats}}が もう あがらない!", - "statWontGoAnyHigher_other": "{{pokemonNameWithAffix}}の {{stats}}が もう あがらない!", - "statFell_one": "{{pokemonNameWithAffix}}の {{stats}}が さがった!", - "statFell_other": "{{pokemonNameWithAffix}}の {{stats}}が さがった!", - "statHarshlyFell_one": "{{pokemonNameWithAffix}}の {{stats}}が がくっと さがった!", - "statHarshlyFell_other": "{{pokemonNameWithAffix}}の {{stats}}が がくっと さがった!", - "statSeverelyFell_one": "{{pokemonNameWithAffix}}の {{stats}}が がくーんと さがった!", - "statSeverelyFell_other": "{{pokemonNameWithAffix}}の {{stats}}が がくーんと さがった!", - "statWontGoAnyLower_one": "{{pokemonNameWithAffix}}の {{stats}}が もう さがらない!", - "statWontGoAnyLower_other": "{{pokemonNameWithAffix}}の {{stats}}が もう さがらない!", - "transformedIntoType": "{{pokemonName}}は\n{{type}}タイプに へんしんした!", - "retryBattle": "このせんとうの はじまりから やりなおす?", + "stats": "能力", + "statRose_one": "{{pokemonNameWithAffix}}の {{stats}}が 上がった!", + "statRose_other": "{{pokemonNameWithAffix}}の {{stats}}が 上がった!", + "statSharplyRose_one": "{{pokemonNameWithAffix}}の {{stats}}が ぐーんと 上がった!", + "statSharplyRose_other": "{{pokemonNameWithAffix}}の {{stats}}が ぐーんと 上がった!", + "statRoseDrastically_one": "{{pokemonNameWithAffix}}の {{stats}}が ぐぐーんと 上がった!", + "statRoseDrastically_other": "{{pokemonNameWithAffix}}の {{stats}}が ぐぐーんと 上がった!", + "statWontGoAnyHigher_one": "{{pokemonNameWithAffix}}の {{stats}}が もう 上がらない!", + "statWontGoAnyHigher_other": "{{pokemonNameWithAffix}}の {{stats}}が もう 上がらない!", + "statFell_one": "{{pokemonNameWithAffix}}の {{stats}}が 下がった!", + "statFell_other": "{{pokemonNameWithAffix}}の {{stats}}が 下がった!", + "statHarshlyFell_one": "{{pokemonNameWithAffix}}の {{stats}}が がくっと 下がった!", + "statHarshlyFell_other": "{{pokemonNameWithAffix}}の {{stats}}が がくっと 下がった!", + "statSeverelyFell_one": "{{pokemonNameWithAffix}}の {{stats}}が がくーんと 下がった!", + "statSeverelyFell_other": "{{pokemonNameWithAffix}}の {{stats}}が がくーんと 下がった!", + "statWontGoAnyLower_one": "{{pokemonNameWithAffix}}の {{stats}}が もう 下がらない!", + "statWontGoAnyLower_other": "{{pokemonNameWithAffix}}の {{stats}}が もう 下がらない!", + "transformedIntoType": "{{pokemonName}}は\n{{type}}タイプに 変身した!", + "retryBattle": "このバトルの 始まりから やり直しますか?", "unlockedSomething": "{{unlockedThing}}\nを アンロックした!", "congratulations": "おめでとうございます!!", - "beatModeFirstTime": "はじめて {{speciesName}}が {{gameMode}}モードを クリアした!\n{{newModifier}}を てにいれた!", - "ppReduced": "{{targetName}}の {{moveName}}を {{reduction}}けずった!", - "battlerTagsRechargingLapse": "{{pokemonNameWithAffix}}は こうげきの はんどうで うごけない!", - "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}}は もう にげられない!", - "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}}は\n{{moveName}}の こうかが とけた!", - "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}}は ひるんで わざが だせない!", - "battlerTagsConfusedOnAdd": "{{pokemonNameWithAffix}}は こんらん した!", - "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}}の こんらんが とけた!", - "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}}は すでに こんらん している!", - "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}}は こんらん している!", - "battlerTagsConfusedLapseHurtItself": "わけも わからず じぶんを こうげきした!", + "beatModeFirstTime": "初めて {{speciesName}}が {{gameMode}}モードを クリアした!\n{{newModifier}}を 手に入れた!", + "ppReduced": "{{targetName}}の {{moveName}}を {{reduction}}削った!", + "battlerTagsRechargingLapse": "{{pokemonNameWithAffix}}は 攻撃の 反動で 動けない!", + "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}}は もう 逃げられない!", + "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}}は\n{{moveName}}の 効果が 解けた!", + "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}}は ひるんで 技が出せない!", + "battlerTagsConfusedOnAdd": "{{pokemonNameWithAffix}}は 混乱 した!", + "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}}の 混乱が 解けた!", + "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}}は すでに 混乱している!", + "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}}は 混乱している!", + "battlerTagsConfusedLapseHurtItself": "わけも わからず 自分を 攻撃した!", "battlerTagsDestinyBondLapseIsBoss": "{{pokemonNameWithAffix}}を みちづれに できない!", - "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}}は あいてを みちづれに した!", - "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}}は {{sourcePokemonName}}に メロメロに なった!", + "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}}は 相手を みちづれに した!", + "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}}は {{sourcePokemonName}}に メロメロに なった!", "battlerTagsInfatuatedOnOverlap": "{{pokemonNameWithAffix}}は すでに メロメロだ!", "battlerTagsInfatuatedLapse": "{{pokemonNameWithAffix}}は {{sourcePokemonName}}に メロメロだ!", - "battlerTagsInfatuatedLapseImmobilize": "{{pokemonNameWithAffix}}は\nメロメロで わざが だせなかった!", - "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}}は メロメロじょうたいが なおった!", - "battlerTagsSeededOnAdd": "{{pokemonNameWithAffix}}に たねを うえつけた!", - "battlerTagsSeededLapse": "やどりぎが {{pokemonNameWithAffix}}の たいりょくを うばう!", - "battlerTagsSeededLapseShed": "{{pokemonNameWithAffix}}は ヘドロえきを すいとった!", - "battlerTagsNightmareOnAdd": "{{pokemonNameWithAffix}}は あくむを みはじめた!", - "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}}は すでに うなされている!", - "battlerTagsNightmareLapse": "{{pokemonNameWithAffix}}は あくむに うなされている!", - "battlerTagsEncoreOnAdd": "{{pokemonNameWithAffix}}は アンコールをうけた!", - "battlerTagsEncoreOnRemove": "{{pokemonNameWithAffix}}の アンコールじょうたいが とけた!", - "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}}は {{pokemonName}}を\nてだすけする たいせいに はいった!", - "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}}は ねから\n ようぶんを すいとった!", - "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}}は ねを はった!", - "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}}は みずのリングを まとった!", - "battlerTagsAquaRingLapse": "{{pokemonName}}は {{moveName}}で\nたいりょくを かいふくした!", - "battlerTagsDrowsyOnAdd": "{{pokemonNameWithAffix}} の ねむけを さそった!", - "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}}は {{moveName}}の ダメージを うけた!", - "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}}は {{sourcePokemonName}}に しめつけられた!", - "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}}は {{sourcePokemonName}}に まきつかれた!", - "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}}は うずの なかに とじこめられた!", - "battlerTagsClampOnTrap": "{{pokemonName}}は {{sourcePokemonNameWithAffix}}の\nからに はさまれた!", - "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}}は {{moveName}}に とらわれた!", - "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}}は マグマの\n うずに とじこめられた!", - "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}}は トラバサミに とらわれた!", - "battlerTagsThunderCageOnTrap": "{{sourcePokemonNameWithAffix}}は {{pokemonNameWithAffix}}に とじこめられた!", + "battlerTagsInfatuatedLapseImmobilize": "{{pokemonNameWithAffix}}は\nメロメロで わざが 出せなかった!", + "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}}は メロメロ状態が 治った!", + "battlerTagsSeededOnAdd": "{{pokemonNameWithAffix}}に 種を 植(う)えつけた!", + "battlerTagsSeededLapse": "やどりぎが {{pokemonNameWithAffix}}の 体力を うばう!", + "battlerTagsSeededLapseShed": "{{pokemonNameWithAffix}}は ヘドロえきを 吸い取った!", + "battlerTagsNightmareOnAdd": "{{pokemonNameWithAffix}}は あくむを 見始めた!", + "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}}は すでに うなされている!", + "battlerTagsNightmareLapse": "{{pokemonNameWithAffix}}は あくむに うなされている!", + "battlerTagsEncoreOnAdd": "{{pokemonNameWithAffix}}は アンコールを 受けた!", + "battlerTagsEncoreOnRemove": "{{pokemonNameWithAffix}}の アンコール状態が 解けた!", + "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}}は {{pokemonName}}を\nてだすけする 体制に 入った!", + "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}}は 根から\n養分(ようぶん)を 吸い取った!", + "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}}は 根を 張った!", + "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}}は 水のリングを まとった!", + "battlerTagsAquaRingLapse": "{{pokemonName}}は {{moveName}}で\n体力を 回復した!", + "battlerTagsDrowsyOnAdd": "{{pokemonNameWithAffix}} の ねむけを 誘(さそ)った!", + "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}}は {{moveName}}の ダメージを 受けた!", + "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}}は {{sourcePokemonName}}に 締め付けられた!", + "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}}は {{sourcePokemonName}}に 巻き付かれた!", + "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}}は 渦(うず)の中に 閉じ込められた!", + "battlerTagsClampOnTrap": "{{pokemonName}}は {{sourcePokemonNameWithAffix}}の\nからに 挟まれた!", + "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}}は {{moveName}}に 捕らわれた!", + "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}}は マグマの\n 渦(うず)に 閉じ込められた!", + "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}}は トラバサミに 捕らわれた!", + "battlerTagsThunderCageOnTrap": "{{sourcePokemonNameWithAffix}}は {{pokemonNameWithAffix}}に 閉じ込められた!", "battlerTagsInfestationOnTrap": "{{pokemonNameWithAffix}}は {{sourcePokemonNameWithAffix}}に まとわりつかれた!", - "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}}は\nまもりの たいせいに はいった!", - "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}}は\nこうげきから みを まもった!", - "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}}は\nこらえる たいせいに はいった!", - "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}}は\nこうげきを こらえた!", - "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}}は\nこうげきを こらえた!", - "battlerTagsPerishSongLapse": "{{pokemonNameWithAffix}}の ほろびのカウントが {{turnCount}}になった!", - "battlerTagsCenterOfAttentionOnAdd": "{{pokemonNameWithAffix}}は ちゅうもくの まとになった!", - "battlerTagsTruantLapse": "{{pokemonNameWithAffix}}は なまけている!", - "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}}は ちょうしが あがらない!", - "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}}は ちょうしを とりもどした!", - "battlerTagsHighestStatBoostOnAdd": "{{pokemonNameWithAffix}}の {{statName}}が\nあがっている じょうたいに なった!", - "battlerTagsHighestStatBoostOnRemove": "{{pokemonNameWithAffix}}の {{abilityName}}の こうかが なくなった!", - "battlerTagsMagnetRisenOnAdd": "{{pokemonNameWithAffix}}は でんじりょくで うかびあがった!", - "battlerTagsMagnetRisenOnRemove": "{{pokemonNameWithAffix}}は でんじりょくが なくなった!", - "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}}は はりきっている!", - "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}}は おちついた。", + "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}}は\nまもりの 体制に 入った!", + "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}}は\n攻撃から 身を守った!", + "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}}は\nこらえる 体制に 入った!", + "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}}は\n攻撃を こらえた!", + "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}}は\n攻撃を こらえた!", + "battlerTagsPerishSongLapse": "{{pokemonNameWithAffix}}の ほろびのカウントが {{turnCount}}になった!", + "battlerTagsCenterOfAttentionOnAdd": "{{pokemonNameWithAffix}}は 注目の 的になった!", + "battlerTagsTruantLapse": "{{pokemonNameWithAffix}}は 怠(なま)けている!", + "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}}は 調子が 上がらない!", + "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}}は 調子を 取り戻した!", + "battlerTagsHighestStatBoostOnAdd": "{{pokemonNameWithAffix}}の {{statName}}が\n上がっている 状態に なった!", + "battlerTagsHighestStatBoostOnRemove": "{{pokemonNameWithAffix}}の {{abilityName}}の 効果が なくなった!", + "battlerTagsMagnetRisenOnAdd": "{{pokemonNameWithAffix}}は 電磁力(でんじりょく)で 浮かび上がった!", + "battlerTagsMagnetRisenOnRemove": "{{pokemonNameWithAffix}}は 電磁力(でんじりょく)が なくなった!", + "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}}は 張り切っている!", + "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}}は 落ち着いた。", "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}}は しおづけに なった!", - "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}}は {{moveName}}の\n ダメージを うけている", - "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}は じぶんの たいりょくを けずって\n{{pokemonName}}に のろいを かけた!", - "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}は のろわれている!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}は {{stockpiledCount}}つ たくわえた!" + "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}}は {{moveName}}の\n ダメージを 受けている", + "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}は 自分の 体力を 削って\n{{pokemonName}}に のろいを かけた!", + "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}は のろわれている!", + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}は {{stockpiledCount}}つ たくわえた!" } as const; diff --git a/src/locales/ja/challenges.ts b/src/locales/ja/challenges.ts index 1383ea021b1..71925baf7b8 100644 --- a/src/locales/ja/challenges.ts +++ b/src/locales/ja/challenges.ts @@ -1,32 +1,32 @@ import { TranslationEntries } from "#app/interfaces/locales"; export const challenges: TranslationEntries = { - "title": "チャレンジ じょうけん せってい", - "illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!", + "title": "チャレンジを 設定", + "illegalEvolution": "{{pokemon}}は このチャレンジで\n対象外の ポケモンに なってしまった!", "singleGeneration": { - "name": "Mono Gen", - "desc": "You can only use Pokémon from Generation {{gen}}.", - "desc_default": "You can only use Pokémon from the chosen generation.", - "gen_1": "one", - "gen_2": "two", - "gen_3": "three", - "gen_4": "four", - "gen_5": "five", - "gen_6": "six", - "gen_7": "seven", - "gen_8": "eight", - "gen_9": "nine", + "name": "単一世代", + "desc": "{{gen}}世代からの ポケモンしか 使えません", + "desc_default": "選んだ 世代からの ポケモンしか 使えません", + "gen_1": "1", + "gen_2": "2", + "gen_3": "3", + "gen_4": "4", + "gen_5": "5", + "gen_6": "6", + "gen_7": "7", + "gen_8": "8", + "gen_9": "9", }, "singleType": { - "name": "Mono Type", - "desc": "You can only use Pokémon with the {{type}} type.", - "desc_default": "You can only use Pokémon of the chosen type." + "name": "単一タイプ", + "desc": "{{type}}タイプの ポケモンしか 使えません", + "desc_default": "選んだ タイプの ポケモンしか 使えません" //types in pokemon-info }, "freshStart": { - "name": "Fresh Start", - "desc": "You can only use the original starters, and only as if you had just started pokerogue.", - "value.0": "Off", - "value.1": "On", + "name": "出直し", + "desc": "ポケローグを 始めた ばかりの ような ままで ゲーム開始の 最初のパートナーしか 使えません", + "value.0": "オフ", + "value.1": "オン", }, } as const; diff --git a/src/locales/ja/filter-bar.ts b/src/locales/ja/filter-bar.ts index 60c6ffb1bbc..1dd0c3b2b64 100644 --- a/src/locales/ja/filter-bar.ts +++ b/src/locales/ja/filter-bar.ts @@ -3,16 +3,31 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; export const filterBar: SimpleTranslationEntries = { "genFilter": "Gen", "typeFilter": "Type", + "caughtFilter": "Caught", "unlocksFilter": "Unlocks", - "winFilter": "Win", + "miscFilter": "Misc", "sortFilter": "Sort", "all": "All", - "normal": "Normal", + "normal": "Not Shiny", "uncaught": "Uncaught", + "passive": "Passive", "passiveUnlocked": "Passive Unlocked", "passiveLocked": "Passive Locked", - "hasWon": "Yes", - "hasNotWon": "No", + "costReduction": "Cost Reduction", + "costReductionUnlocked": "Cost Reduction Unlocked", + "costReductionLocked": "Cost Reduction Locked", + "favorite": "Favorite", + "isFavorite": "Favorite - Yes", + "notFavorite": "Favorite - No", + "ribbon": "Ribbon", + "hasWon": "Ribbon - Yes", + "hasNotWon": "Ribbon - No", + "hiddenAbility": "Hidden Ability", + "hasHiddenAbility": "Hidden Ability - Yes", + "noHiddenAbility": "Hidden Ability - No", + "pokerus": "Pokerus", + "hasPokerus": "Pokerus - Yes", + "noPokerus": "Pokerus - No", "sortByNumber": "No.", "sortByCost": "Cost", "sortByCandies": "Candy Count", diff --git a/src/locales/ja/move-trigger.ts b/src/locales/ja/move-trigger.ts index 7c794379f55..dd741643888 100644 --- a/src/locales/ja/move-trigger.ts +++ b/src/locales/ja/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "{{pokemonName}}の\nねがいごとが かなった!", "invertStats": "{{pokemonName}}の\nのうりょくへんかが ぎゃくてんした!", "resetStats": "{{pokemonName}}の\nのうりょくへんかが もとにもどった!", + "statEliminated": "All stat changes were eliminated!", "faintCountdown": "{{pokemonName}}は\n{{turnCount}}ターンごに ほろびてしまう!", "copyType": "{{pokemonName}}は {{targetPokemonName}}と\n同じタイプに なった!", "suppressAbilities": "{{pokemonName}}の とくせいが きかなくなった!", diff --git a/src/locales/ja/starter-select-ui-handler.ts b/src/locales/ja/starter-select-ui-handler.ts index 095ceeb0ca1..fe4495a3a2f 100644 --- a/src/locales/ja/starter-select-ui-handler.ts +++ b/src/locales/ja/starter-select-ui-handler.ts @@ -28,6 +28,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "個体値を ひょうじ", "manageMoves": "わざを ならびかえ", "manageNature": "せいかくを ならびかえ", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", "useCandies": "アメを つかう", "selectNature": "せいかくをえらんでください", "selectMoveSwapOut": "交換する技を選択してください", diff --git a/src/locales/ja/status-effect.ts b/src/locales/ja/status-effect.ts index 5914fc27298..b15907f3b33 100644 --- a/src/locales/ja/status-effect.ts +++ b/src/locales/ja/status-effect.ts @@ -2,7 +2,7 @@ import { StatusEffectTranslationEntries } from "#app/interfaces/locales.js"; export const statusEffect: StatusEffectTranslationEntries = { none: { - name: "None", + name: "なし", description: "", obtain: "", obtainSource: "", @@ -11,57 +11,57 @@ export const statusEffect: StatusEffectTranslationEntries = { heal: "" }, poison: { - name: "Poison", - description: "poisoning", - obtain: "{{pokemonNameWithAffix}}\nwas poisoned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas poisoned by the {{sourceText}}!", - activation: "{{pokemonNameWithAffix}} is hurt\nby poison!", - overlap: "{{pokemonNameWithAffix}} is\nalready poisoned!", - heal: "{{pokemonNameWithAffix}} was\ncured of its poison!" + name: "どく", + description: "どく", + obtain: "{{pokemonNameWithAffix}}は\n毒を あびた!", + obtainSource: "{{pokemonNameWithAffix}}は\n{{sourceText}}で 毒を あびた!", + activation: "{{pokemonNameWithAffix}}は\n毒の ダメージを 受けた!", + overlap: "{{pokemonNameWithAffix}}は すでに\n毒を あびている", + heal: "{{pokemonNameWithAffix}}の 毒は\nきれいさっぱり なくなった!" }, toxic: { - name: "Toxic", - description: "poisoning", - obtain: "{{pokemonNameWithAffix}}\nwas badly poisoned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas badly poisoned by the {{sourceText}}!", - activation: "{{pokemonNameWithAffix}} is hurt\nby poison!", - overlap: "{{pokemonNameWithAffix}} is\nalready poisoned!", - heal: "{{pokemonNameWithAffix}} was\ncured of its poison!" + name: "もうどく", + description: "もうどく", + obtain: "{{pokemonNameWithAffix}}は\n猛毒を あびた!", + obtainSource: "{{pokemonNameWithAffix}}は\n{{sourceText}}で 猛毒を あびた!", + activation: "{{pokemonNameWithAffix}}は\n毒の ダメージを受けた!", + overlap: "{{pokemonNameWithAffix}}は すでに\n毒を あびている", + heal: "{{pokemonNameWithAffix}}の 毒は\nきれいさっぱり なくなった!" }, paralysis: { - name: "Paralysis", - description: "paralysis", - obtain: "{{pokemonNameWithAffix}} was paralyzed,\nIt may be unable to move!", - obtainSource: "{{pokemonNameWithAffix}} was paralyzed by the {{sourceText}}!\nIt may be unable to move!", - activation: "{{pokemonNameWithAffix}} is paralyzed!\nIt can't move!", - overlap: "{{pokemonNameWithAffix}} is\nalready paralyzed!", - heal: "{{pokemonNameWithAffix}} was\nhealed of paralysis!" + name: "まひ", + description: "まひ", + obtain: "{{pokemonNameWithAffix}}は まひして\n技が でにくくなった!", + obtainSource: "{{pokemonNameWithAffix}}は {{sourceText}}で まひして\n技が でにくくなった!", + activation: "{{pokemonNameWithAffix}}は\n体が しびれて 動けない!", + overlap: "{{pokemonNameWithAffix}}は\nすでに まひしている", + heal: "{{pokemonNameWithAffix}}の\nしびれが とれた!" }, sleep: { - name: "Sleep", - description: "sleep", - obtain: "{{pokemonNameWithAffix}}\nfell asleep!", - obtainSource: "{{pokemonNameWithAffix}}\nfell asleep from the {{sourceText}}!", - activation: "{{pokemonNameWithAffix}} is fast asleep.", - overlap: "{{pokemonNameWithAffix}} is\nalready asleep!", - heal: "{{pokemonNameWithAffix}} woke up!" + name: "ねむり", + description: "ねむり", + obtain: "{{pokemonNameWithAffix}}は\n眠ってしまった!", + obtainSource: "{{pokemonNameWithAffix}}は\n{{sourceText}}で 眠ってしまった!", + activation: "{{pokemonNameWithAffix}}は\nぐうぐう 眠っている", + overlap: "{{pokemonNameWithAffix}}は\nすでに 眠っている", + heal: "{{pokemonNameWithAffix}}は\n目を 覚ました!" }, freeze: { - name: "Freeze", - description: "freezing", - obtain: "{{pokemonNameWithAffix}}\nwas frozen solid!", - obtainSource: "{{pokemonNameWithAffix}}\nwas frozen solid by the {{sourceText}}!", - activation: "{{pokemonNameWithAffix}} is\nfrozen solid!", - overlap: "{{pokemonNameWithAffix}} is\nalready frozen!", - heal: "{{pokemonNameWithAffix}} was\ndefrosted!" + name: "こおり", + description: "こおり", + obtain: "{{pokemonNameWithAffix}}は\n凍りついた!", + obtainSource: "{{pokemonNameWithAffix}}は\n{{sourceText}}で 凍りついた!", + activation: "{{pokemonNameWithAffix}}は\n凍ってしまって 動けない!", + overlap: "{{pokemonNameWithAffix}}は\nすでに 凍っている", + heal: "{{pokemonNameWithAffix}}は\nこおり状態が 治った!" }, burn: { - name: "Burn", - description: "burn", - obtain: "{{pokemonNameWithAffix}}\nwas burned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas burned by the {{sourceText}}!", - activation: "{{pokemonNameWithAffix}} is hurt\nby its burn!", - overlap: "{{pokemonNameWithAffix}} is\nalready burned!", - heal: "{{pokemonNameWithAffix}} was\nhealed of its burn!" + name: "やけど", + description: "やけど", + obtain: "{{pokemonNameWithAffix}}は\nやけどを 負った!", + obtainSource: "{{pokemonNameWithAffix}}は\n{{sourceText}}で やけどを 負った!", + activation: "{{pokemonNameWithAffix}}は\nやけどの ダメージを 受けた!", + overlap: "{{pokemonNameWithAffix}}は すでに\nやけどを 負っている", + heal: "{{pokemonNameWithAffix}}の\nやけどが 治った!" }, } as const; diff --git a/src/locales/ko/filter-bar.ts b/src/locales/ko/filter-bar.ts index b4dcb48b581..2724b1ea3ac 100644 --- a/src/locales/ko/filter-bar.ts +++ b/src/locales/ko/filter-bar.ts @@ -13,9 +13,12 @@ export const filterBar: SimpleTranslationEntries = { "passive": "패시브", "passiveUnlocked": "패시브 해금", "passiveLocked": "패시브 잠김", - "costReduction": "코스트 줄이기", - "costReductionUnlocked": "코스트 절감됨", - "costReductionLocked": "코스트 절감 없음", + "costReduction": "코스트 감소", + "costReductionUnlocked": "코스트 감소됨", + "costReductionLocked": "코스트 감소 없음", + "favorite": "즐겨찾기", + "isFavorite": "즐겨찾기 등록됨", + "notFavorite": "즐겨찾기 제외됨", "ribbon": "클리어 여부", "hasWon": "클리어 완료", "hasNotWon": "클리어 안함", diff --git a/src/locales/ko/move-trigger.ts b/src/locales/ko/move-trigger.ts index 4c32e5b5b9f..ec4edb8d2ca 100644 --- a/src/locales/ko/move-trigger.ts +++ b/src/locales/ko/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "{{pokemonName}}의\n치유소원이 이루어졌다!", "invertStats": "{{pokemonName}}[[는]]\n능력 변화가 뒤집혔다!", "resetStats": "{{pokemonName}}의 모든 상태가\n원래대로 되돌아왔다!", + "statEliminated": "모든 상태가 원래대로 되돌아왔다!", "faintCountdown": "{{pokemonName}}[[는]]\n{{turnCount}}턴 후에 쓰러져 버린다!", "copyType": "{{pokemonName}}[[는]]\n{{targetPokemonName}}[[와]] 같은 타입이 되었다!", "suppressAbilities": "{{pokemonName}}의\n특성이 효과를 발휘하지 못하게 되었다!", diff --git a/src/locales/ko/starter-select-ui-handler.ts b/src/locales/ko/starter-select-ui-handler.ts index 25bb006059e..9a33f8f1baf 100644 --- a/src/locales/ko/starter-select-ui-handler.ts +++ b/src/locales/ko/starter-select-ui-handler.ts @@ -28,6 +28,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "개체값 토글", "manageMoves": "기술 관리", "manageNature": "성격 관리", + "addToFavorites": "즐겨찾기에 추가", + "removeFromFavorites": "즐겨찾기에서 제외", "useCandies": "사탕 사용", "selectNature": "교체할 성격을 선택해주세요.", "selectMoveSwapOut": "교체할 기술을 선택해주세요.", @@ -41,6 +43,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleAbility": ": 특성", "cycleNature": ": 성격", "cycleVariant": ": 색상", + "goFilter": ": 필터로 이동", "enablePassive": "패시브 활성화", "disablePassive": "패시브 비활성화", "locked": "잠김", diff --git a/src/locales/pt_BR/achv.ts b/src/locales/pt_BR/achv.ts index 5874616bcdc..59aae596f83 100644 --- a/src/locales/pt_BR/achv.ts +++ b/src/locales/pt_BR/achv.ts @@ -171,7 +171,7 @@ export const PGMachv: AchievementTranslationEntries = { }, "UNEVOLVED_CLASSIC_VICTORY": { name: "Tire as Crianças da Sala", - description: "Vença o jogo no Modo Clássico com pelo menos um membro da equipe não evoluído.." + description: "Vença o jogo no Modo Clássico com pelo menos um membro da equipe não evoluído." }, "MONO_GEN_ONE": { @@ -445,8 +445,8 @@ export const PGFachv: AchievementTranslationEntries = { description: "Vença o jogo no modo clássico", }, "UNEVOLVED_CLASSIC_VICTORY": { - name: "Bring Your Child To Work Day", - description: "Beat the game in Classic Mode with at least one unevolved party member." + name: "Tire as Crianças da Sala", + description: "Vença o jogo no Modo Clássico com pelo menos um membro da equipe não evoluído." }, "MONO_GEN_ONE": { diff --git a/src/locales/pt_BR/dialogue.ts b/src/locales/pt_BR/dialogue.ts index 88018c7fcda..d128dea29ea 100644 --- a/src/locales/pt_BR/dialogue.ts +++ b/src/locales/pt_BR/dialogue.ts @@ -1,6 +1,6 @@ import { DialogueTranslationEntries, SimpleTranslationEntries } from "#app/interfaces/locales"; -// Diálogo dos NPCs no jogo quando o personagem do jogador é masculino (ou não definido) +// Dialogue of the NPCs in the game when the player character is male (or unset) export const PGMdialogue: DialogueTranslationEntries = { "youngster": { "encounter": { @@ -385,295 +385,278 @@ export const PGMdialogue: DialogueTranslationEntries = { }, "archer": { "encounter": { - 1: "Before you go any further, let's see how you far against us, Team Rocket!", - 2: "I have received reports that your skills are not insignificant. Let's see if they are true.", - 3: "I am Archer, an Admin of Team Rocket. And I do not go easy on enemies of our organization." + 1: "Antes de você ir mais longe, vamos ver como você se sai contra nós, Equipe Rocket!", + 2: "Eu tenho recebido relatórios de que suas habilidades não são insignificantes. Vamos ver se são verdadeiros.", + 3: "Eu sou Archer, um Admin da Equipe Rocket. E não tenho piedade dos inimigos da nossa organização." }, "victory": { - 1: "What a blunder!", - 2: "With my current skills, I was not up to the task after all.", - 3: "F-forgive me, Giovanni... For me to be defeated by a mere trainer..." + 1: "Que vexame!", + 2: "Com minhas habilidades atuais, eu não estava à altura da tarefa, afinal.", + 3: "M-me perdoe, Giovanni... Por ser derrotado por um mero treinador..." }, }, "ariana": { "encounter": { - 1: `Hold it right there! We can't someone on the loose." - $It's harmful to Team Rocket's pride, you see.`, - 2: `I don't know or care if what I'm doing is right or wrong... - $I just put my faith in Giovanni and do as I am told`, - 3: "Your trip ends here. I'm going to take you down!" + 1: "Pera aí! Não podemos deixar alguém solto por aí. Isso é prejudicial para o orgulho da Equipe Rocket, entende?", + 2: "Eu não sei ou me importo se o que estou fazendo é certo ou errado... Eu apenas coloco minha fé em Giovanni e faço o que me é dito.", + 3: "Sua viagem termina aqui. Vou te derrubar!" }, "victory": { - 1: `Tch, you really are strong. It's too bad. - $If you were to join Team Rocket, you could become an Executive.`, - 2: "I... I'm shattered...", - 3: "Aaaieeeee! This can't be happening! I fought hard, but I still lost…" + 1: "Uau, você é forte. Que desperdício. Se você se juntasse à Equipe Rocket, poderia se tornar um Executivo.", + 2: "Eu... Eu estou arrasada...", + 3: "Aaaieeeee! Isso não pode estar acontecendo! Eu lutei muito, mas ainda perdi…" }, }, "proton": { "encounter": { - 1: "What do you want? If you interrupt our work, don't expect any mercy!", - 2: `What do we have here? I am often labeled as the scariest and cruelest guy in Team Rocket… - $I strongly urge you not to interfere with our business!`, - 3: "I am Proton, an Admin of Team Rocket. I am here to put an end to your meddling!" + 1: "O que você quer? Se você interromper nosso trabalho, não espere misericórdia!", + 2: "O que temos aqui? Costumam me chamar de o cara mais assustador e cruel da Equipe Rocket… Eu recomendo fortemente que você não interfira nos nossos negócios!", + 3: "Eu sou Proton, um Admin da Equipe Rocket. Estou aqui para acabar com a sua intromissão!" }, "victory": { - 1: "The fortress came down!", - 2: "You may have won this time… But all you did was make Team Rocket's wrath grow…", - 3: "I am defeated… But I will not forget this!" + 1: "A fortaleza caiu!", + 2: "Você pode ter vencido desta vez… Mas tudo o que fez foi aumentar a ira da Equipe Rocket…", + 3: "Fui derrotado… Mas não esquecerei disso!" }, }, - "petrel": { "encounter": { - 1: `Muhahaha, we've been waiting for you. Me? You don't know who I am? It is me, Giovanni. - $The majestic Giovanni himself! Wahahaha! …Huh? I don't sound anything like Giovanni? - $I don't even look like Giovanni? How come? I've worked so hard to mimic him!`, - 2: "I am Petrel, an Admin of Team Rocket. I will not allow you to interfere with our plans!", - 3: "Rocket Executive Petrel will deal with this intruder!" + 1: "Muhahaha, estávamos esperando por você. Eu? Você não sabe quem eu sou? Sou eu, Giovanni. O majestoso Giovanni em pessoa! Wahahaha! ...Huh? Eu não pareço nada com Giovanni? Eu nem mesmo pareço com Giovanni? Como assim? Trabalhei tanto para imitá-lo!", + 2: "Eu sou Petrel, um Admin da Equipe Rocket. Não permitirei que você interfira em nossos planos!", + 3: "O Executivo da Rocket, Petrel, vai lidar com este intruso!" }, "victory": { - 1: "OK, OK. I'll tell you where he is.", - 2: "I… I couldn't do a thing… Giovanni, please forgive me…", - 3: "No, I can't let this affect me. I have to inform the others…" + 1: "OK, OK. Vou te contar onde ele está.", + 2: "Eu... Eu não consegui fazer nada... Giovanni, por favor, me perdoe...", + 3: "Não, eu não posso deixar isso me afetar. Tenho que informar os outros…" }, }, "tabitha": { "encounter": { - 1: "Hehehe! So you've come all the way here! But you're too late!", - 2: `Hehehe... Got here already, did you? We underestimated you! But this is it! - $I'm a cut above the Grunts you've seen so far. I'm not stalling for time. - $I'm going to pulverize you!`, - 3: "I'm going to give you a little taste of pain! Resign yourself to it!" + 1: "Hehehe! Então você veio até aqui! Mas você chegou tarde demais!", + 2: "Hehehe... Já chegou aqui, não é? Nós subestimamos você! Mas é isso! Eu sou um passo acima dos Capangas que você viu até agora. Não estou ganhando tempo. Vou te pulverizar!", + 3: "Vou te dar um gostinho da dor! Resigne-se a isso!" }, "victory": { - 1: `Hehehe! You might have beaten me, but you don't stand a chance against the Boss! - $If you get lost now, you won't have to face a sound whipping!`, - 2: "Hehehe... So, I lost, too...", - 3: "Ahya! How could this be? For an Admin like me to lose to some random trainer..." + 1: "Hehehe! Você pode ter me derrotado, mas não tem chance contra o Chefe! Se você se perder agora, não terá que enfrentar uma surra sonora!", + 2: "Hehehe... Então, eu também perdi...", + 3: "Ahya! Como isso pode ser? Para um Admin como eu perder para um treinador qualquer..." }, }, "courtney": { "encounter": { - 1: "The thing...The thing that you hold...That is what... That's what we of Team Magma seek...", - 2: "... Well then...Deleting...", - 3: "...Ha. ...Analyzing... ...Hah♪" + 1: "A coisa... A coisa que você segura... É o que... É o que nós da Equipe Magma procuramos...", + 2: "... Bem então... Deletando...", + 3: "...Ha. ...Analisando... ...Hah♪" }, "victory": { - 1: "... ...Change...the world.", - 2: `As anticipated. Unanticipated. You. Target lock...completed. - $Commencing...experiment. You. Forever. Aha... ♪`, - 3: "...Again? That's unanticipated. ...I knew it. You...are interesting! ...Haha. ♪" + 1: "... ...Mudar...o mundo.", + 2: "Como antecipado. Não antecipado. Você. Bloqueio de alvo... concluído. Iniciando... experimento. Você. Para sempre. Aha... ♪", + 3: "... De novo? Isso não foi antecipado. ...Eu sabia. Você... é interessante! ...Haha. ♪" }, }, "shelly": { "encounter": { - 1: `Ahahahaha! You're going to meddle in Team Aqua's affairs? - $You're either absolutely fearless, simply ignorant, or both! - $You're so cute, you're disgusting! I'll put you down`, - 2: "What's this? Who's this spoiled brat?", - 3: "Cool your jets. Be patient. I'll crush you shortly." + 1: "Ahahahaha! Você vai se meter nos assuntos da Equipe Aqua? Você é absolutamente destemido, simplesmente ignorante ou ambos! Você é tão fofo que chega a ser nojento! Vou te derrubar", + 2: "O que é isso? Quem é essa criança mimada?", + 3: "Relaxe. Seja paciente. Vou te esmagar em breve." }, "victory": { - 1: `Ahahahaha! We got meddled with unexpectedly! We're out of options. - $We'll have to pull out. But this isn't the last you'll see of Team Aqua! - $We have other plans! Don't you forget it!`, - 2: "Ahhh?! Did I go too easy on you?!", - 3: `Uh. Are you telling me you've upped your game even more during the fight? - $You're a brat with a bright future… My Pokémon and I don't have any strength left to fight… - $Go on… Go and be destroyed by Archie.` + 1: "Ahahahaha! Fomos surpreendidos inesperadamente! Estamos sem opções. Teremos que recuar. Mas esta não é a última vez que você verá a Equipe Aqua! Temos outros planos! Não se esqueça disso!", + 2: "Ahhh?! Fui muito fácil com você?!", + 3: "Uh. Você está me dizendo que melhorou seu jogo ainda mais durante a luta? Você é um pirralho com um futuro brilhante… Meu Pokémon e eu não temos mais forças para lutar… Vá em frente… Vá e seja destruído por Archie." }, }, "matt": { "encounter": { - 1: "Hoohahaha! What, you got a screw loose or something? Look at you, little Makuhita person!", - 2: "Oho! You! You're that funny kid!", - 3: "What are you doing here? Did you follow us?" + 1: "Hoohahaha! O que, você tem um parafuso solto ou algo assim? Olhe para você, pequena pessoa Makuhita!", + 2: "Oho! Você! Você é aquela criança engraçada!", + 3: "O que você está fazendo aqui? Você nos seguiu?" }, "victory": { - 1: "All right then, until the Boss has time for you, I'll be your opponent!", - 2: `I can feel it! I can feel it, all right! The strength coming offa you! - $More! I still want more! But looks like we're outta time...`, - 3: "That was fun! I knew you'd show me a good time! I look forward to facing you again someday!" + 1: "Muito bem, até que o Chefe tenha tempo para você, serei seu oponente!", + 2: "Posso sentir! Posso sentir, tudo bem! A força saindo de você! Mais! Eu ainda quero mais! Mas parece que estamos sem tempo...", + 3: "Isso foi divertido! Eu sabia que você me mostraria um bom tempo! Estou ansioso para enfrentá-lo novamente algum dia!" }, }, "mars": { "encounter": { - 1: "I'm Mars, one of Team Galactic's top Commanders.", - 2: "Team Galactic's vision for the future is unwavering. Opposition will be crushed without mercy!", - 3: "Feeling nervous? You should be!" + 1: "Sou Mars, uma das principais Comandantes da Equipe Galáctica.", + 2: "A visão da Equipe Galáctica para o futuro é inabalável. A oposição será esmagada sem piedade!", + 3: "Sentindo-se nervoso? Você deveria estar!" }, "victory": { - 1: "This can't be happening! How did I lose?!", - 2: "You have some skill, I'll give you that.", - 3: "Defeated... This was a costly mistake." + 1: "Isso não pode estar acontecendo! Como eu perdi?!", + 2: "Você tem alguma habilidade, eu admito isso.", + 3: "Derrotada... Este foi um erro caro." } }, "jupiter": { "encounter": { - 1: "Jupiter, Commander of Team Galactic, at your service.", - 2: "Resistance is futile. Team Galactic will prevail!", - 3: "You're trembling... scared already?" + 1: "Júpiter, Comandante da Equipe Galáctica, ao seu serviço.", + 2: "A resistência é inútil. A Equipe Galáctica prevalecerá!", + 3: "Você está tremendo... já está com medo?" }, "victory": { - 1: "No way... I lost?!", - 2: "Impressive, you've got guts!", - 3: "Losing like this... How embarrassing." + 1: "De jeito nenhum... Eu perdi?!", + 2: "Impressionante, você tem coragem!", + 3: "Perder assim... Que embaraço." } }, "saturn": { "encounter": { - 1: "I am Saturn, Commander of Team Galactic.", - 2: "Our mission is absolute. Any hindrance will be obliterated!", - 3: "Is that fear I see in your eyes?" + 1: "Eu sou Saturno, Comandante da Equipe Galáctica.", + 2: "Nossa missão é absoluta. Qualquer obstáculo será obliterado!", + 3: "É medo o que vejo em seus olhos?" }, "victory": { - 1: "Impossible... Defeated by you?!", - 2: "You have proven yourself a worthy adversary.", - 3: "Bestowed in defeat... This is unacceptable." - }}, + 1: "Impossível... Derrotado por você?!", + 2: "Você provou ser um adversário digno.", + 3: "Derrotado... Isso é inaceitável." + } + }, "zinzolin": { "encounter": { - 1: "You could become a threat to Team Plasma, so we will eliminate you here and now!", - 2: "Oh, for crying out loud... I didn't expect to have to battle in this freezing cold!", - 3: "You're an impressive Trainer to have made it this far. But it ends here." + 1: "Você poderia se tornar uma ameaça para a Equipe Plasma, então vamos eliminá-lo aqui e agora!", + 2: "Oh, pelo amor de Deus... Eu não esperava ter que lutar neste frio congelante!", + 3: "Você é um treinador impressionante para ter chegado tão longe. Mas termina aqui." }, "victory": { - 1: "Ghetsis... I have failed you...", - 2: "It's bitter cold. I'm shivering. I'm suffering. Yet, I still stand victorious.", - 3: "Hmph. You're a smarter Trainer than I expected, but not smart enough." + 1: "Ghetsis... Eu falhei com você...", + 2: "Está amargamente frio. Estou tremendo. Estou sofrendo. Ainda assim, estou vitorioso.", + 3: "Hmph. Você é um treinador mais esperto do que eu esperava, mas não esperto o suficiente." } }, "rood": { "encounter": { - 1: "You are a threat to Team Plasma. We cannot let you walk away from here and now!", - 2: "Oh, this icy wind... I never thought I'd have to fight here!", - 3: "You are a remarkable Trainer to have made it this far. But this is where it ends." + 1: "Você é uma ameaça para a Equipe Plasma. Não podemos deixá-lo ir embora daqui e agora!", + 2: "Oh, este vento gelado... Eu nunca pensei que teria que lutar aqui!", + 3: "Você é um treinador notável para ter chegado tão longe. Mas é aqui que termina." }, "victory": { - 1: "Ghetsis... I have failed my mission...", - 2: "The cold is piercing. I'm shivering. I'm suffering. Yet, I have triumphed.", - 3: "Hm. You are a talented Trainer, but unfortunately not talented enough." + 1: "Ghetsis... Eu falhei em minha missão...", + 2: "O frio é penetrante. Estou tremendo. Estou sofrendo. Ainda assim, triunfei.", + 3: "Hm. Você é um treinador talentoso, mas infelizmente não talentoso o suficiente." } }, "xerosic": { "encounter": { - 1: "Ah ha ha! It would be my pleasure. Come on, little Trainer! Let's see what you've got!", - 2: "Hmm... You're more powerful than you look. I wonder how much energy there is inside you.", - 3: "I've been waiting for you! I need to do a little research on you! Come, let us begin!" + 1: "Ah ha ha! Será um prazer. Vamos lá, pequeno treinador! Vamos ver o que você tem!", + 2: "Hmm... Você é mais poderoso do que parece. Eu me pergunto quanta energia há dentro de você.", + 3: "Eu estava esperando por você! Preciso fazer uma pequena pesquisa sobre você! Vamos começar!" }, "victory": { - 1: "Ah, you're quite strong. Oh yes—very strong, indeed.", - 2: "Ding-ding-ding! You did it! To the victor go the spoils!", - 3: "Wonderful! Amazing! You have tremendous skill and bravery!" + 1: "Ah, você é bastante forte. Oh sim—muito forte, de fato.", + 2: "Ding-ding-ding! Você conseguiu! Ao vencedor, os despojos!", + 3: "Maravilhoso! Incrível! Você tem uma tremenda habilidade e coragem!" } }, "bryony": { "encounter": { - 1: "I am Bryony, and it would be my pleasure to battle you. Show me what you've got.", - 2: "Impressive... You're more powerful than you appear. Let's see the true extent of your energy.", - 3: "I've anticipated your arrival. It's time for a little test. Shall we begin?" + 1: "Eu sou Bryony, e será um prazer lutar com você. Mostre-me o que você tem.", + 2: "Impressionante... Você é mais poderoso do que parece. Vamos ver a verdadeira extensão de sua energia.", + 3: "Eu antecipei sua chegada. É hora de um pequeno teste. Vamos começar?" }, "victory": { - 1: "You're quite strong. Oh yes—very strong, indeed.", - 2: "Ding-ding-ding! You've done well. Victory is yours.", - 3: "Wonderful! Remarkable! Your skill and bravery are commendable." + 1: "Você é bastante forte. Oh sim—muito forte, de fato.", + 2: "Ding-ding-ding! Você se saiu bem. A vitória é sua.", + 3: "Maravilhoso! Notável! Sua habilidade e coragem são admiráveis." } }, "rocket_grunt": { "encounter": { 1: "Se prepara pra encrenca!", - 2: "We're pulling a big job here! Get lost, kid!", - 3: "Hand over your Pokémon, or face the wrath of Team Rocket!", - 4: "You're about to experience the true terror of Team Rocket!", - 5: "Hey, kid! Me am a Team Rocket member kind of guy!" //Use of wrong grammar is deliberate + 2: "Estamos realizando um grande trabalho aqui! Cai fora, moleque!", + 3: "Entregue seus Pokémon ou enfrente a ira da Equipe Rocket!", + 4: "Você está prestes a experimentar o verdadeiro terror da Equipe Rocket!", + 5: "Ei, moleque! Eu sou um tipo de cara da Equipe Rocket!" //Uso de gramática incorreta é proposital }, "victory": { 1: "Equipe Rocket decolando de novo!", - 2: "Oh no! I dropped the Lift Key!", - 3: "I blew it!", - 4: "My associates won't stand for this!", - 5: "You say what? Team Rocket bye-bye a go-go? Broken it is says you?" //Use of wrong grammar is deliberate. + 2: "Oh não! Eu deixei a Chave de Elevação cair!", + 3: "Eu estraguei tudo!", + 4: "Meus associados não vão tolerar isso!", + 5: "Você diz o que? Equipe Rocket tchau-tchau a vai-vai? Quebrado é diz você?" //Uso de gramática incorreta é proposital }, }, "magma_grunt": { "encounter": { 1: "Se você se meter com a Equipe Magma, não teremos piedade!", - 2: "You'd better not interfere with our plans! We're making the world a better place!", - 3: "You're in the way! Team Magma has no time for kids like you!", - 4: "I hope you brought marshmallows because things are about to heat up!", - 5: "We're going to use the power of a volcano! It's gonna be... explosive! Get it? Heh heh!" + 2: "É melhor você não interferir em nossos planos! Estamos tornando o mundo um lugar melhor!", + 3: "Você está no caminho! A Equipe Magma não tem tempo para crianças como você!", + 4: "Espero que você tenha trazido marshmallows porque as coisas estão prestes a esquentar!", + 5: "Vamos usar o poder de um vulcão! Vai ser... explosivo! Entendeu? Heh heh!" }, "victory": { 1: "Ahn? Eu perdi?!", - 2: "I can't believe I lost! I even skipped lunch for this", - 3: "No way! You're just a kid!", - 4: "Urrrgh... I should've ducked into our hideout right away...", - 5: "You beat me... Do you think the boss will dock my pay for this?" + 2: "Não posso acreditar que perdi! Até pulei o almoço por isso.", + 3: "De jeito nenhum! Você é apenas uma criança!", + 4: "Urrrgh... Eu deveria ter me escondido em nosso esconderijo imediatamente...", + 5: "Você me venceu... Você acha que o chefe vai cortar meu salário por isso?" }, }, "aqua_grunt": { "encounter": { 1: "Não pegamos leve com quem se mete com a Equipe Aqua, nem mesmo crianças!", - 2: "Grrr... You've got some nerve meddling with Team Aqua!", - 3: "You're about to get soaked! And not just from my water Pokémon!", - 4: "We, Team Aqua, exist for the good of all!", - 5: "Prepare to be washed away by the tides of my... uh, Pokémon! Yeah, my Pokémon!" + 2: "Grrr... Você tem coragem de se intrometer com a Equipe Aqua!", + 3: "Você está prestes a se molhar! E não apenas por causa dos meus Pokémon aquáticos!", + 4: "Nós, da Equipe Aqua, existimos para o bem de todos!", + 5: "Prepare-se para ser levado pelas ondas do meu... uh, Pokémon! Sim, meu Pokémon!" }, "victory": { 1: "Tá de brincadeira!", - 2: "Arrgh, I didn't count on being meddled with by some meddling kid!", - 3: "I lost?! Guess I'll have to swim back to the hideout now...", - 4: "Oh, man, what a disaster... The boss is going to be furious...", - 5: "You beat me... Do you think the boss will make me walk the plank for this?" + 2: "Arrgh, eu não contei que seria atrapalhado por uma criança intrometida!", + 3: "Eu perdi?! Acho que vou ter que nadar de volta para o esconderijo agora...", + 4: "Oh, cara, que desastre... O chefe vai ficar furioso...", + 5: "Você me venceu... Você acha que o chefe vai me fazer andar na prancha por isso?" }, }, "galactic_grunt": { "encounter": { - 1: "Não mexe com a Equipe Galáctica!", - 2: "Witness the power of our technology and the future we envision!", - 3: "In the name of Team Galactic, I'll eliminate anyone who stands in our way!", - 4: "Get ready to lose!", - 5: "Hope you're ready for a cosmic beatdown!" + 1: "Não mexa com a Equipe Galáctica!", + 2: "Presencie o poder da nossa tecnologia e o futuro que vislumbramos!", + 3: "Em nome da Equipe Galáctica, eliminarei qualquer um que ficar em nosso caminho!", + 4: "Prepare-se para perder!", + 5: "Espero que você esteja pronto para uma surra cósmica!" }, "victory": { 1: "Fui amassado...", - 2: "This setback means nothing in the grand scheme.", - 3: "Our plans are bigger than this defeat.", - 4: "How?!", - 5: "Note to self: practice Pokémon battling, ASAP." + 2: "Este contratempo não significa nada no grande esquema.", + 3: "Nossos planos são maiores que esta derrota.", + 4: "Como?!", + 5: "Nota para mim mesmo: praticar batalhas Pokémon, o mais rápido possível." }, }, "plasma_grunt": { "encounter": { 1: "Não toleramos pessoas que pensam diferente de nós!", - 2: "If I win against you, release your Pokémon!", - 3: "If you get in the way of Team Plasma, I'll take care of you!", - 4: "Team Plasma will liberate Pokémon from selfish humans like you!", - 5: "Our hairstyles are out of this world... but our battling skills? You'll find out soon enough." + 2: "Se eu ganhar de você, liberte seus Pokémon!", + 3: "Se você atrapalhar a Equipe Plasma, eu cuidarei de você!", + 4: "A Equipe Plasma vai libertar os Pokémon de humanos egoístas como você!", + 5: "Nossos penteados são de outro mundo... mas nossas habilidades de batalha? Você descobrirá em breve." }, "victory": { 1: "Plasmaaaaaaaaa!", - 2: "How could I lose...", - 3: "...What a weak Pokémon, I'll just have to go steal some better ones!", - 4: "Great plans are always interrupted.", - 5: "This is bad... Badbadbadbadbadbadbad! Bad for Team Plasma! Or Plasbad, for short!" + 2: "Como eu pude perder...", + 3: "...Que Pokémon fraco, vou ter que roubar alguns melhores!", + 4: "Grandes planos são sempre interrompidos.", + 5: "Isso é ruim... Ruim ruim ruim ruim ruim ruim ruim! Ruim para a Equipe Plasma! Ou Plasruim, para abreviar!" }, }, "flare_grunt": { "encounter": { - 1: "Your Pokémon are no match for the elegance of Team Flare.", - 2: "Hope you brought your sunglasses, because things are about to get bright!", - 3: "Team Flare will cleanse the world of imperfection!", - 4: "Prepare to face the brilliance of Team Flare!", - 5: "Fashion is most important to us!" + 1: "Seus Pokémon não são páreo para a elegância da Equipe Flare.", + 2: "Espero que você tenha trazido seus óculos de sol, porque as coisas vão ficar brilhantes!", + 3: "A Equipe Flare vai purificar o mundo da imperfeição!", + 4: "Prepare-se para enfrentar o brilho da Equipe Flare!", + 5: "A moda é o mais importante para nós!" }, "victory": { - 1: "The future doesn't look bright for me.", - 2: "Perhaps there's more to battling than I thought. Back to the drawing board.", - 3: "Gahh?! I lost?!", - 4: "Even in defeat, Team Flare's elegance shines through.", - 5: "You may have beaten me, but when I lose, I go out in style!" + 1: "O futuro não parece brilhante para mim.", + 2: "Talvez haja mais na batalha do que eu pensei. De volta à prancheta.", + 3: "Gahh?! Eu perdi?!", + 4: "Mesmo na derrota, a elegância da Equipe Flare brilha.", + 5: "Você pode ter me vencido, mas quando eu perco, eu saio com estilo!" }, }, "rocket_boss_giovanni_1": { @@ -1105,8 +1088,8 @@ export const PGMdialogue: DialogueTranslationEntries = { }, "crasher_wake": { "encounter": { - 1: "Crash! Crash! Cuidado!\nCrasher Wake… está… aqui!", - 2: "Crash! Crash! Crasher Wake!", + 1: "Crash! Crash! Cuidado!\nDemolidor Wake… está… aqui!", + 2: "Crash! Crash! Demolidor Wake!", 3: "Sou a onda de poder que vai te lavar!" }, "victory": { @@ -1448,7 +1431,7 @@ export const PGMdialogue: DialogueTranslationEntries = { }, "allister": { "encounter": { - 1: "'M Allister.\nA-aqui... vou eu..." + 1: "Sou Allister.\nA-aqui... vou eu..." }, "victory": { 1: `Quase perdi minha máscara de tanto choque... Isso foi… @@ -1579,7 +1562,7 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Eu… Eu não… acredito…" }, "defeat": { - 1: "Isso foi por pouco. Me pergunto o que você está faltando." + 1: "Isso foi por pouco. Me pergunto o que está faltando em você." } }, "malva": { @@ -2004,7 +1987,7 @@ export const PGMdialogue: DialogueTranslationEntries = { "encounter": { 1: `Sabe de uma coisa? Estou realmente ansiosa para ter batalhas sérias com Treinadores fortes! $Quero dizer, vamos lá! Os Treinadores que chegam aqui são Treinadores que desejam a vitória com todas as fibras do seu ser! - #E eles estão batalhando ao lado de Pokémon que passaram por inúmeras batalhas difíceis! + $E eles estão batalhando ao lado de Pokémon que passaram por inúmeras batalhas difíceis! $Se eu batalhar com pessoas assim, não só eu ficarei mais forte, meus Pokémon também! $E nós vamos nos conhecer ainda melhor! OK! Prepare-se! $Sou Iris, a Campeã da Liga Pokémon, e vou te derrotar!`, @@ -2288,7 +2271,7 @@ export const PGMdialogue: DialogueTranslationEntries = { "encounter": { 1: `Oh, se não é um jovem Treinador… É adorável conhecê-lo assim. $Então, suponho que você ganhou o direito a uma batalha, como recompensa por seus esforços. - $O elusivo Fada pode parecer frágil como a brisa e delicado como uma flor, mas é forte.`, + $Uma elusiva Fada pode parecer frágil como a brisa e delicado como uma flor, mas é forte.`, }, "victory": { 1: "Espero que você encontre coisas para sorrir amanhã…" @@ -2458,7 +2441,7 @@ export const PGMdialogue: DialogueTranslationEntries = { }, "victory": { 1: "Não acredito que perdi... Mas você mereceu essa vitória. Bem feito!", - 2: "Parece que ainda tenho muito a aprender. Grande batalha, porém!" + 2: "Parece que ainda tenho muito a aprender. Porém, grande batalha!" }, "defeat": { 1: "Você lutou bem, mas eu tenho a vantagem! Melhor sorte na próxima vez!", @@ -2649,7 +2632,7 @@ export const PGMdialogue: DialogueTranslationEntries = { $@c{serious_mopen_fists}Prepare-se.` }, "victory": { - 1: "@c{neutral}O que…@d{64} O que você é?" + 1: "@c{neutral}O que…@d{64} O que é você?" }, }, "rival_4_female": { @@ -2664,7 +2647,7 @@ export const PGMdialogue: DialogueTranslationEntries = { $@c{angry_mopen}Prepare-se.` }, "victory": { - 1: "@c{neutral}O que…@d{64} O que você é?" + 1: "@c{neutral}O que…@d{64} O que é você?" }, "defeat": { 1: "$@c{smile}Você deveria se orgulhar de até onde chegou." @@ -2736,7 +2719,7 @@ export const PGMdialogue: DialogueTranslationEntries = { }; -// Diálogo dos NPCs no jogo quando o personagem do jogador é feminino. Para idiomas que não possuem pronomes de gênero, isso pode ser definido como PGMdialogue. +// Dialogue of the NPCs in the game when the player character is female. For languages that do not have gendered pronouns, this can be set to PGMdialogue. export const PGFdialogue: DialogueTranslationEntries = { "youngster": { "encounter": { @@ -2794,90 +2777,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 9: "Estou realmente cansando de batalhar… Deve haver algo novo para fazer…" } }, - "breeder": { - "encounter": { - 1: "Pokémon obedientes, Pokémon egoístas… Pokémon têm características únicas.", - 2: "Embora minha criação e comportamento sejam ruins, criei meus Pokémon bem.", - 3: "Hmm, você disciplina seus Pokémon? Mimar demais não é bom." - }, - "victory": { - 1: "É importante nutrir e treinar as características de cada Pokémon.", - 2: "Ao contrário do meu lado diabólico, esses são bons Pokémon.", - 3: "Muito elogio pode estragar tanto Pokémon quanto pessoas." - }, - "defeat": { - 1: "Você não deve ficar com raiva dos seus Pokémon, mesmo se perder uma batalha.", - 2: "Certo? Pokémon bons, né? Eu sou adequado para criar coisas.", - 3: "Não importa o quanto você ame seus Pokémon, ainda precisa discipliná-los quando se comportam mal." - } - }, - "breeder_female": { - "encounter": { - 1: "Pokémon nunca te traem. Eles retribuem todo o amor que você dá a eles.", - 2: "Quer uma dica para treinar bons Pokémon?", - 3: "Eu criei esses Pokémon muito especiais usando um método especial." - }, - "victory": { - 1: "Ugh… Não era para ser assim. Será que administrei a mistura errada?", - 2: "Como isso aconteceu com meus Pokémon… O que você está dando de comer aos seus Pokémon?", - 3: "Se eu perder, isso significa que eu estava só matando o tempo. Não machuca meu ego nem um pouco." - }, - "defeat": { - 1: "Isso prova que meus Pokémon aceitaram meu amor.", - 2: "O verdadeiro truque para treinar bons Pokémon é capturar bons Pokémon.", - 3: "Pokémon serão fortes ou fracos dependendo de como você os cria." - } - }, - "fisherman": { - "encounter": { - 1: "Anem! Você me fez perder uma fisgada!\nO que vai fazer sobre isso?", - 2: "Sai daqui! Você está assustando os Pokémon!", - 3: "Vamos ver se você consegue fisgar uma vitória!", - }, - "victory": { - 1: "Esqueça isso.", - 2: "Da próxima vez, eu vou pescar a vitória!", - 3: "Acho que subestimei a força das correntes dessa vez.", - }, - }, - "fisherman_female": { - "encounter": { - 1: "Uau! Peguei um grande!", - 2: "Linha lançada, pronta para pescar o sucesso!", - 3: "Pronta para fazer ondas!" - }, - "victory": { - 1: "Vou voltar com um anzol mais forte.", - 2: "Vou pescar a vitória na próxima vez.", - 3: "Estou só afiando meus anzóis para a revanche!" - }, - }, - "swimmer": { - "encounter": { - 1: "Hora de mergulhar!", - 2: "Vamos surfar nas ondas da vitória!", - 3: "Pronto para fazer um splash!", - }, - "victory": { - 1: "Molhado na derrota!", - 2: "Uma onda de derrota!", - 3: "De volta à praia, eu acho.", - }, - }, - "backpacker": { - "encounter": { - 1: "Prepare-se, vamos começar!", - 2: "Vamos ver se você consegue acompanhar!", - 3: "Prepare-se, desafiante!", - 4: "Passei 20 anos tentando me encontrar… Mas onde estou?" - }, - "victory": { - 1: "Dessa vez tropecei!", - 2: "Ah, acho que estou perdido.", - 3: "Caminho sem saída!", - 4: "Espere um segundo! Ei! Você não sabe quem eu sou?" - }, - }, "ace_trainer": { "encounter": { 1: "Você parece bastante confiante.", @@ -2898,14 +2797,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 4: "Claro que sou forte e não perco. É importante ganhar com graça." } }, - "parasol_lady": { - "encounter": { - 1: "Hora de embelezar o campo de batalha com elegância e postura!", - }, - "victory": { - 1: "Minha elegância permanece inabalável!", - } - }, "twins": { "encounter": { 1: "Prepare-se, porque quando nos unimos, é o dobro do problema!", @@ -2923,18 +2814,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 3: "Dobro de sorrisos, dobro da dança da vitória!" } }, - "cyclist": { - "encounter": { - 1: "Prepare-se para comer poeira!", - 2: "Prepare-se, desafiante! Estou prestes a te deixar para trás!", - 3: "Pé no pedal, vamos ver se você consegue acompanhar!" - }, - "victory": { - 1: "As rodas podem estar paradas, mas a determinação continua a pedalar.", - 2: "Fui mais rápido!", - 3: "O caminho para a vitória tem muitas curvas e voltas para explorar." - }, - }, "black_belt": { "encounter": { 1: "Elogio sua coragem ao me desafiar! Pois eu sou o que tem o chute mais forte!", @@ -2945,100 +2824,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 2: "Hmmm… Se eu ia perder de qualquer maneira, esperava ficar totalmente destruído no processo." }, }, - "battle_girl": { - "encounter": { - 1: "Você não precisa tentar me impressionar. Você pode perder contra mim.", - }, - "victory": { - 1: "É difícil dizer adeus, mas estamos ficando sem tempo…", - }, - }, - "hiker": { - "encounter": { - 1: "Minha barriga de meia-idade me deu tanta gravidade quanto as montanhas que eu escalo!", - 2: "Herdei esse corpo ossudo dos meus pais… Sou como uma cadeia de montanhas viva…", - }, - "victory": { - 1: "Pelo menos não posso perder quando se trata de IMC!", - 2: "Não é suficiente… Nunca é suficiente. Meu colesterol ruim não está alto o suficiente…" - }, - }, - "ranger": { - "encounter": { - 1: "Quando estou cercado pela natureza, a maioria das outras coisas deixa de importar.", - 2: "Quando estou vivendo sem natureza na minha vida, às vezes sinto uma crise de ansiedade se aproximando." - }, - "victory": { - 1: "Não importa para a vastidão da natureza se eu ganhar ou perder…", - 2: "Algo assim é bastante trivial comparado aos sentimentos sufocantes da vida na cidade." - }, - "defeat": { - 1: "Ganhei a batalha. Mas a vitória não é nada comparada à vastidão da natureza…", - 2: "Tenho certeza de que como você se sente não é tão ruim se comparar aos meus ataques de ansiedade…" - } - }, - "scientist": { - "encounter": { - 1: "Minha pesquisa levará este mundo à paz e alegria.", - }, - "victory": { - 1: "Sou um gênio… Não devo perder para alguém como você…", - }, - }, - "school_kid": { - "encounter": { - 1: "Heehee. Estou confiante nos meus cálculos e análises.", - 2: "Estou ganhando o máximo de experiência que posso porque quero ser um Líder de Ginásio um dia." - }, - "victory": { - 1: "Aff… Cálculo e análise talvez não sejam páreo para o acaso…", - 2: "Até experiências difíceis e desafiadoras têm seu propósito, eu acho." - } - }, - "artist": { - "encounter": { - 1: "Eu costumava ser popular, mas agora estou acabado.", - }, - "victory": { - 1: "À medida que os tempos mudam, os valores também mudam. Percebi isso tarde demais.", - }, - }, - "guitarist": { - "encounter": { - 1: "Prepare-se para sentir o ritmo da derrota enquanto eu toco minha vitória!", - }, - "victory": { - 1: "Silenciado por agora, mas minha melodia de resiliência continuará a tocar.", - }, - }, - "worker": { - "encounter": { - 1: "Me incomoda que as pessoas sempre me entendam mal. Sou muito mais puro do que todos pensam.", - }, - "victory": { - 1: "Eu realmente não quero que minha pele queime, então quero ficar na sombra enquanto trabalho.", - }, - }, - "worker_female": { - "encounter": { - 1: `Me incomoda que as pessoas sempre me entendam mal. - $Sou muito mais pura do que todos pensam.` - }, - "victory": { - 1: "Eu realmente não quero que minha pele queime, então quero ficar na sombra enquanto trabalho." - }, - "defeat": { - 1: "Meu corpo e mente nem sempre estão necessariamente em sincronia." - } - }, - "worker_double": { - "encounter": { - 1: "Vou te mostrar que podemos te quebrar. Estamos treinando no campo!", - }, - "victory": { - 1: "Que estranho… Como isso pode ser… Não deveria ter sido superado.", - }, - }, "hex_maniac": { "encounter": { 1: "Normalmente, só escuto música clássica, mas se eu perder, acho que vou tentar um pouco de new age!", @@ -3050,35 +2835,9 @@ export const PGFdialogue: DialogueTranslationEntries = { }, "defeat": { 1: "New age se refere simplesmente aos compositores clássicos do século XX, certo?", - 2: "Não fique preso na tristeza ou frustração. Você pode usar seus rancores para se motivar." + 2: "Não fique presa na tristeza ou frustração. Você pode usar seus rancores para se motivar." } }, - "psychic": { - "encounter": { - 1: "Oi! Concentre-se!", - }, - "victory": { - 1: "Perdi minha concentração!", - }, - }, - "officer": { - "encounter": { - 1: "Prepare-se, porque a justiça está prestes a ser servida!", - 2: "Pronto para defender a lei e servir a justiça no campo de batalha!" - }, - "victory": { - 1: "O peso da justiça parece mais pesado do que nunca…", - 2: "As sombras da derrota pairam no distrito." - } - }, - "beauty": { - "encounter": { - 1: "Minha última batalha… É assim que eu gostaria que víssemos esta partida…", - }, - "victory": { - 1: "Foi divertido… Vamos ter outra última batalha algum dia…", - }, - }, "baker": { "encounter": { 1: "Espero que esteja pronta para saborear a derrota!" @@ -3087,31 +2846,11 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Vou assar uma revanche." }, }, - "biker": { - "encounter": { - 1: "Hora de acelerar e te deixar na poeira!" - }, - "victory": { - 1: "Vou me ajustar para a próxima corrida." - }, - }, - "firebreather": { - "encounter": { - 1: "Minhas chamas irão te consumir!", - 2: "Minha alma está pegando fogo. Irei te mostrar como queima!", - 3: "Cola aqui e dá uma olhada!" - }, - "victory": { - 1: "Fui reduzido a cinzas…", - 2: "Uau! Isso foi quente!", - 3: "Ai! Queimei minha língua!" - }, - }, "sailor": { "encounter": { 1: "Mano, você vai andar na prancha se perder!", 2: "Vem com tudo! Sou um marinheiro com orgulho!", - 3: "Ahoy marujo! Tá enjoado, é?!" + 3: "Ahoy maruja! Tá enjoada, é?!" }, "victory": { 1: "Argh! Perdi pra uma criança!", @@ -3119,21 +2858,155 @@ export const PGFdialogue: DialogueTranslationEntries = { 3: "Estou achando que quem tá enjoado sou eu..." }, }, - "brock": { + "ariana": { "encounter": { - 1: "Minha especialidade em Pokémon do tipo Pedra vai te derrubar! Vamos lá!", - 2: "Minha vontade firme como pedra vai te sobrecarregar!", - 3: "Permita-me mostrar a verdadeira força dos meus Pokémon!" + 1: "Pera aí! Não podemos deixar alguém solto por aí. Isso é prejudicial para o orgulho da Equipe Rocket, entende?", + 2: "Eu não sei ou me importo se o que estou fazendo é certo ou errado... Eu apenas coloco minha fé em Giovanni e faço o que me é dito.", + 3: "Sua viagem termina aqui. Vou te derrubar!" }, "victory": { - 1: "A força dos seus Pokémon superou minhas defesas de pedra!", - 2: "O mundo é enorme! Estou feliz por ter tido a chance de batalhar com você.", - 3: "Talvez eu deva voltar a perseguir meu sonho de ser Criador de Pokémon…" + 1: "Uau, você é forte. Que desperdício. Se você se juntasse à Equipe Rocket, poderia se tornar uma Executiva.", + 2: "Eu... Eu estou arrasada...", + 3: "Aaaieeeee! Isso não pode estar acontecendo! Eu lutei muito, mas ainda perdi…" + }, + }, + "tabitha": { + "encounter": { + 1: "Hehehe! Então você veio até aqui! Mas você chegou tarde demais!", + 2: "Hehehe... Já chegou aqui, não é? Nós subestimamos você! Mas é isso! Eu sou um passo acima dos Capangas que você viu até agora. Não estou ganhando tempo. Vou te pulverizar!", + 3: "Vou te dar um gostinho da dor! Resigne-se a isso!" + }, + "victory": { + 1: "Hehehe! Você pode ter me derrotado, mas não tem chance contra o Chefe! Se você se perder agora, não terá que enfrentar uma surra sonora!", + 2: "Hehehe... Então, eu também perdi...", + 3: "Ahya! Como isso pode ser? Para um Admin como eu perder para uma treinadora qualquer..." + }, + }, + "shelly": { + "encounter": { + 1: "Ahahahaha! Você vai se meter nos assuntos da Equipe Aqua? Você é absolutamente destemida, simplesmente ignorante ou ambos! Você é tão fofa que chega a ser nojenta! Vou te derrubar", + 2: "O que é isso? Quem é essa criança mimada?", + 3: "Relaxe. Seja paciente. Vou te esmagar em breve." + }, + "victory": { + 1: "Ahahahaha! Fomos surpreendidos inesperadamente! Estamos sem opções. Teremos que recuar. Mas esta não é a última vez que você verá a Equipe Aqua! Temos outros planos! Não se esqueça disso!", + 2: "Ahhh?! Fui muito fácil com você?!", + 3: "Uh. Você está me dizendo que melhorou seu jogo ainda mais durante a luta? Você é uma pirralha com um futuro brilhante… Meu Pokémon e eu não temos mais forças para lutar… Vá em frente… Vá e seja destruída por Archie." + }, + }, + "matt": { + "encounter": { + 1: "Hoohahaha! O que, você tem um parafuso solto ou algo assim? Olhe para você, pequena pessoa Makuhita!", + 2: "Oho! Você! Você é aquela criança engraçada!", + 3: "O que você está fazendo aqui? Você nos seguiu?" + }, + "victory": { + 1: "Muito bem, até que o Chefe tenha tempo para você, serei seu oponente!", + 2: "Posso sentir! Posso sentir, tudo bem! A força saindo de você! Mais! Eu ainda quero mais! Mas parece que estamos sem tempo...", + 3: "Isso foi divertido! Eu sabia que você me mostraria um bom tempo! Estou ansioso para enfrentá-la novamente algum dia!" + }, + }, + "mars": { + "encounter": { + 1: "Sou Mars, uma das principais Comandantes da Equipe Galáctica.", + 2: "A visão da Equipe Galáctica para o futuro é inabalável. A oposição será esmagada sem piedade!", + 3: "Sentindo-se nervosa? Você deveria estar!" + }, + "victory": { + 1: "Isso não pode estar acontecendo! Como eu perdi?!", + 2: "Você tem alguma habilidade, eu admito isso.", + 3: "Derrotada... Este foi um erro caro." + } + }, + "zinzolin": { + "encounter": { + 1: "Você poderia se tornar uma ameaça para a Equipe Plasma, então vamos eliminá-la aqui e agora!", + 2: "Oh, pelo amor de Deus... Eu não esperava ter que lutar neste frio congelante!", + 3: "Você é uma treinadora impressionante para ter chegado tão longe. Mas termina aqui." + }, + "victory": { + 1: "Ghetsis... Eu falhei com você...", + 2: "Está amargamente frio. Estou tremendo. Estou sofrendo. Ainda assim, estou vitorioso.", + 3: "Hmph. Você é uma treinadora mais esperta do que eu esperava, mas não esperta o suficiente." + } + }, + "rood": { + "encounter": { + 1: "Você é uma ameaça para a Equipe Plasma. Não podemos deixá-la ir embora daqui e agora!", + 2: "Oh, este vento gelado... Eu nunca pensei que teria que lutar aqui!", + 3: "Você é uma treinadora notável para ter chegado tão longe. Mas é aqui que termina." + }, + "victory": { + 1: "Ghetsis... Eu falhei em minha missão...", + 2: "O frio é penetrante. Estou tremendo. Estou sofrendo. Ainda assim, triunfei.", + 3: "Hm. Você é uma treinadora talentosa, mas infelizmente não talentosa o suficiente." + } + }, + "xerosic": { + "encounter": { + 1: "Ah ha ha! Será um prazer. Vamos lá, pequena treinadora! Vamos ver o que você tem!", + 2: "Hmm... Você é mais poderosa do que parece. Eu me pergunto quanta energia há dentro de você.", + 3: "Eu estava esperando por você! Preciso fazer uma pequena pesquisa sobre você! Vamos começar!" + }, + "victory": { + 1: "Ah, você é bastante forte. Oh sim—muito forte, de fato.", + 2: "Ding-ding-ding! Você conseguiu! À vencedora, os despojos!", + 3: "Maravilhoso! Incrível! Você tem uma tremenda habilidade e coragem!" + } + }, + "bryony": { + "encounter": { + 1: "Eu sou Bryony, e será um prazer lutar com você. Mostre-me o que você tem.", + 2: "Impressionante... Você é mais poderosa do que parece. Vamos ver a verdadeira extensão de sua energia.", + 3: "Eu antecipei sua chegada. É hora de um pequeno teste. Vamos começar?" + }, + "victory": { + 1: "Você é bastante forte. Oh sim—muito forte, de fato.", + 2: "Ding-ding-ding! Você se saiu bem. A vitória é sua.", + 3: "Maravilhoso! Notável! Sua habilidade e coragem são admiráveis." + } + }, + "rocket_grunt": { + "encounter": { + 1: "Se prepara pra encrenca!", + 2: "Estamos realizando um grande trabalho aqui! Cai fora, garota!", + 3: "Entregue seus Pokémon ou enfrente a ira da Equipe Rocket!", + 4: "Você está prestes a experimentar o verdadeiro terror da Equipe Rocket!", + 5: "Ei, garota! Eu sou um tipo de cara da Equipe Rocket!" // Uso de gramática incorreta é proposital + }, + "victory": { + 1: "Equipe Rocket decolando de novo!", + 2: "Oh não! Eu deixei a Chave de Elevação cair!", + 3: "Eu estraguei tudo!", + 4: "Meus associados não vão tolerar isso!", + 5: "Você diz o que? Equipe Rocket tchau-tchau a vai-vai? Quebrado é diz você?" // Uso de gramática incorreta é proposital + }, + }, + "galactic_grunt": { + "encounter": { + 1: "Não mexa com a Equipe Galáctica!", + 2: "Presencie o poder da nossa tecnologia e o futuro que vislumbramos!", + 3: "Em nome da Equipe Galáctica, eliminarei qualquer um que ficar em nosso caminho!", + 4: "Prepare-se para perder!", + 5: "Espero que você esteja pronta para uma surra cósmica!" + }, + "victory": { + 1: "Fui amassado...", + 2: "Este contratempo não significa nada no grande esquema.", + 3: "Nossos planos são maiores que esta derrota.", + 4: "Como?!", + 5: "Nota para mim mesmo: praticar batalhas Pokémon, o mais rápido possível." + }, + }, + "galactic_boss_cyrus_1": { + "encounter": { + 1: "Você foi compelida a vir aqui por tal sentimentalismo vazio\nEu farei você se arrepender de ter ouvido seu coração!" + }, + "victory": { + 1: "Interessante. E bastante curioso." }, "defeat": { - 1: "A melhor defesa é um bom ataque!\nEssa é a minha maneira de fazer as coisas!", - 2: "Venha estudar rochas comigo da próxima vez para aprender melhor a combatê-las!", - 3: "Hah, todas as minhas viagens pelas regiões estão valendo a pena!" + 1: "Eu criarei meu novo mundo..." } }, "misty": { @@ -3170,77 +3043,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 3: "Uma batalha de Pokémon é guerra, e eu te mostrei combate em primeira mão!" } }, - "erika": { - "encounter": { - 1: "Ah, o tempo está adorável aqui…\nOh, uma batalha? Muito bem então.", - 2: "Minhas habilidades de batalha Pokémon rivalizam com minhas habilidades de arranjo de flores.", - 3: "Oh, espero que o aroma agradável dos meus Pokémon não me faça dormir de novo…", - 4: "Ver flores em um jardim é tão calmante." - }, - "victory": { - 1: "Oh! Eu concedo a derrota.", - 2: "Aquela partida foi muito agradável.", - 3: "Ah, parece que perdi…", - 4: "Oh, meu Deus." - }, - "defeat": { - 1: "Tinha medo de adormecer…", - 2: "Oh, meu Deus, parece que meus Pokémon de Grama te dominaram.", - 3: "Essa batalha foi uma experiência tão calmante.", - 4: "Oh… É só isso?" - } - }, - "janine": { - "encounter": { - 1: "Estou dominando a arte dos ataques venenosos.\nVou lutar com você hoje!", - 2: "Meu pai confia que posso me defender.\nVou provar que ele está certo!", - 3: "Minhas técnicas de ninja só perdem para as do meu pai!\nVocê consegue acompanhar?" - }, - "victory": { - 1: "Ainda preciso de treinamento… Entendi.", - 2: "Sua técnica de batalha superou a minha.", - 3: "Vou me aplicar de verdade e melhorar minhas habilidades." - }, - "defeat": { - 1: "Hehe… o veneno drenou todas as suas forças para lutar.", - 2: "Ha! Você não teve chance contra minhas habilidades superiores de ninja!", - 3: "A fé do meu pai em mim não foi mal colocada." - } - }, - "sabrina": { - "encounter": { - 1: "Através da minha habilidade psíquica, tive uma visão da sua chegada!", - 2: "Não gosto de lutar, mas se você quiser, vou mostrar meus poderes!", - 3: "Posso sentir grande ambição em você. Vou ver se não é infundada." - }, - "victory": { - 1: "Seu poder… Ele supera o que eu previa…", - 2: "Não consegui prever seu poder com precisão.", - 3: "Mesmo com meus imensos poderes psíquicos, não consigo sentir outro tão forte quanto você." - }, - "defeat": { - 1: "Essa vitória… É exatamente como previ nas minhas visões!", - 2: "Talvez fosse outra pessoa que eu sentisse um grande desejo…", - 3: "Aprimore suas habilidades antes de entrar em batalha precipitadamente.\nVocê nunca sabe o que o futuro pode reservar se fizer isso…" - } - }, - "blaine": { - "encounter": { - 1: "Hah! Espero que tenha trazido uma Cura de Queimadura!", - 2: "Meus Pokémon de Fogo vão incinerar todos os desafiantes!", - 3: "Prepare-se para brincar com fogo!" - }, - "victory": { - 1: "Queimei até não restar nada! Nem cinzas sobraram!", - 2: "Não acendi as chamas alto o suficiente?", - 3: "Estou completamente exausto… Mas isso faz minha motivação para melhorar queimar ainda mais!" - }, - "defeat": { - 1: "Meu inferno ardente não pode ser apagado!", - 2: "Meus Pokémon foram fortalecidos com o calor desta vitória!", - 3: "Hah! Minha paixão queima mais do que a sua!" - } - }, "giovanni": { "encounter": { 1: "Eu, o líder da Equipe Rocket, vou te fazer sentir um mundo de dor!", @@ -3258,23 +3060,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 3: "Espero que entenda o quão tolo foi me desafiar." } }, - "roxanne": { - "encounter": { - 1: "Você poderia gentilmente demonstrar como batalha?", - 2: "Você pode aprender muitas coisas batalhando com muitos treinadores.", - 3: "Oh, você me pegou estrategizando.\nGostaria de batalhar?" - }, - "victory": { - 1: "Oh, parece que perdi.\nEu entendo.", - 2: "Parece que ainda tenho muito mais a aprender quando se trata de batalhas.", - 3: "Vou levar o que aprendi aqui hoje a sério." - }, - "defeat": { - 1: "Aprendi muitas coisas com nossa batalha.\nEspero que você também tenha aprendido.", - 2: "Espero batalhar com você novamente.\nEspero que use o que aprendeu aqui.", - 3: "Venci devido a tudo o que aprendi." - } - }, "brawly": { "encounter": { 1: "Oh cara, uma desafiante!\nVamos ver o que você pode fazer!", @@ -3304,45 +3089,11 @@ export const PGFdialogue: DialogueTranslationEntries = { 3: "Obrigado pela emoção!\nWahahahaha!" }, "defeat": { - 1: "Você está totalmente carregado agora!\nWahahahaha!", + 1: "Você está totalmente carregada agora!\nWahahahaha!", 2: "Espero ver você faíscando em batalhas futuras!\nWahahahaha!", 3: "Wahahahaha! Que batalha eletrizante!" } }, - "flannery": { - "encounter": { - 1: "Meus Pokémon de fogo estão prontos para queimar a concorrência!\nVamos nessa!", - 2: "Prepare-se para sentir o calor da minha determinação!\nNão vou segurar nada!", - 3: "Minhas habilidades vão incinerar você!\nPrepare-se para a batalha mais quente da sua vida!" - }, - "victory": { - 1: "Essa derrota só faz minha determinação queimar mais!", - 2: "Essa perda não apagará minhas chamas!\nEstarei de volta mais forte!", - 3: "Vou usar essa experiência para reacender meu espírito competitivo!" - }, - "defeat": { - 1: "Minhas chamas nunca se apagarão!\nSou muito apaixonada por isso!", - 2: "Você foi incrível!\nVamos fazer isso de novo algum dia!", - 3: "Que batalha ardente!\nMal posso esperar pela próxima!" - } - }, - "norman": { - "encounter": { - 1: "Você está pronta para enfrentar a força pura do meu time?\nVou te mostrar o poder do equilíbrio!", - 2: "Minha experiência em batalha vai fazer você suar!\nPrepare-se!", - 3: "Treinei meu time rigorosamente.\nVamos ver se você consegue igualar!" - }, - "victory": { - 1: "Parece que subestimei você.\nFoi uma batalha dura.", - 2: "Você é forte, mas ainda há muito para aprender.", - 3: "Essa derrota não abalará minha determinação.\nEstarei de volta mais forte!" - }, - "defeat": { - 1: "Você lutou bravamente!\nEspero batalhar com você novamente.", - 2: "Sua força é incrível!\nNão posso esperar pela nossa próxima batalha.", - 3: "Foi uma honra batalhar com você!\nAté a próxima!" - } - }, "winona": { "encounter": { 1: "Tenho sobrevoado os céus em busca de presas...\nE você é meu alvo!", @@ -3362,7 +3113,7 @@ export const PGFdialogue: DialogueTranslationEntries = { }, "tate": { "encounter": { - 1: "Hehehe... Ficou surpreso de me ver sem minha irmã?", + 1: "Hehehe... Ficou surpresa de me ver sem minha irmã?", 2: "Posso ver o que você está pensando...\nVocê quer batalhar!", 3: "Como você pode derrotar alguém...\nQue sabe todos os seus movimentos?" }, @@ -3379,7 +3130,7 @@ export const PGFdialogue: DialogueTranslationEntries = { }, "liza": { "encounter": { - 1: "Fufufu... Ficou surpreso de me ver sem meu irmão?", + 1: "Fufufu... Ficou surpresa de me ver sem meu irmão?", 2: "Posso determinar o que você deseja...\nVocê quer batalhar, não quer?", 3: "Como você pode derrotar alguém...\nQue é um com seus Pokémon?" }, @@ -3394,60 +3145,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 3: "Tudo graças ao meu treinamento rigoroso com Tate.\nPosso me sincronizar com meus Pokémon." } }, - "juan": { - "encounter": { - 1: "Agora não é hora de agir timidamente.\nVamos batalhar!", - 2: "Ahahaha, você será testemunha da minha arte com Pokémon de Água!", - 3: "Um tufão se aproxima!\nVocê será capaz de me testar?", - 4: "Por favor, você será testemunha da nossa arte.\nUma grande ilusão de água esculpida por meus Pokémon e por mim!" - }, - "victory": { - 1: "Você pode ser um gênio que pode enfrentar Wallace!", - 2: "Eu me concentrei na elegância enquanto você treinava.\nÉ natural que você me derrotasse.", - 3: "Ahahaha!\nMuito bem, você venceu desta vez.", - 4: "De você, sinto o brilho brilhante da habilidade que superará tudo." - }, - "defeat": { - 1: "Meus Pokémon e eu esculpimos uma ilusão de Água e saímos vitoriosos.", - 2: "Ahahaha, eu venci, e você perdeu.", - 3: "Posso emprestar meu traje? Pode te ajudar a batalhar!\nAhahaha, estou brincando!", - 4: "Eu sou o vencedor! O que quer dizer, você perdeu." - } - }, - "crasher_wake": { - "encounter": { - 1: "Crash! Crash! Cuidado!\nCrasher Wake… está… aqui!", - 2: "Crash! Crash! Crasher Wake!", - 3: "Sou a onda de poder que vai te lavar!" - }, - "victory": { - 1: "Isso coloca um sorriso no meu rosto!\nGuhahaha! Foi uma explosão!", - 2: "Hunwah! Acabou e terminou!\nComo vou dizer isso...\nQuero mais! Queria batalhar muito mais!", - 3: "O QUÊ?!" - }, - "defeat": { - 1: "Siiiiim! Isso mesmo!", - 2: "Eu venci, mas quero mais! Queria batalhar muito mais!", - 3: "Até logo!" - } - }, - "falkner": { - "encounter": { - 1: "Vou mostrar o verdadeiro poder dos magníficos Pokémon pássaros!", - 2: "Ventos, fiquem comigo!", - 3: "Pai! Espero que esteja vendo minha batalha de cima!" - }, - "victory": { - 1: "Eu entendo... Vou sair graciosamente.", - 2: "Uma derrota é uma derrota. Você é realmente forte.", - 3: "...Droga! Sim, eu perdi." - }, - "defeat": { - 1: "Pai! Venci com seus amados Pokémon pássaros...", - 2: "Pokémon pássaros são os melhores afinal!", - 3: "Sinto que estou alcançando meu pai!" - } - }, "nessa": { "encounter": { 1: "Não importa que tipo de plano sua mente refinada possa estar tramando, meu parceiro e eu vamos afundá-la.", @@ -3485,11 +3182,11 @@ export const PGFdialogue: DialogueTranslationEntries = { "marlon": { "encounter": { 1: "Você parece forte! Vamos começar!", - 2: "Sou forte como a amplitude do oceano. Você vai ser varrido, com certeza.", + 2: "Sou forte como a amplitude do oceano. Você vai ser varrida, com certeza.", 3: "Oh ho, então estou enfrentando você! Isso é fora do comum." }, "victory": { - 1: "Você foi incrível! Está criando alguns Pokémon incríveis. Você dominou a coisa de Treinador!", + 1: "Você foi incrível! Está criando alguns Pokémon incríveis. Você dominou a coisa de Treinadora!", 2: "Você não apenas parece forte, você é forte de verdade! Eh, eu também fui varrido!", 3: "Você é forte como uma onda impressionante!" }, @@ -3518,7 +3215,7 @@ export const PGFdialogue: DialogueTranslationEntries = { }, "marshal": { "encounter": { - 1: "Meu mentor, Alder, vê seu potencial como Treinadora e está interessado em você.\nMeu objetivo é testá-lo—levar você aos limites da sua força. Kiai!", + 1: "Meu mentor, Alder, vê seu potencial como Treinadora e está interessado em você.\nMeu objetivo é testá-la—levar você aos limites da sua força. Kiai!", 2: "Vitória, vitória decisiva, é meu objetivo! Desafiante, aqui vou eu!", 3: "Em mim mesmo, procuro desenvolver a força de um lutador e eliminar qualquer fraqueza em mim!\nPrevalecendo com a força de minhas convicções!" }, @@ -3550,40 +3247,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 3: "Cheguei onde estou porque os Pokémon estavam ao meu lado.\nTalvez precisemos pensar por que os Pokémon nos ajudam, não em termos de Pokémon e Treinadores, mas como uma relação entre seres vivos." } }, - "chili": { - "encounter": { - 1: "Ihuuu! Hora de brincar com FOGO!! Sou o mais forte dos nossos irmãos!", - 2: "Ta-da! O incendiário do tipo Fogo Chili—sou eu—será seu oponente!", - 3: "Vou mostrar o que eu e meus tipos de Fogo podemos fazer!" - }, - "victory": { - 1: "Você me pegou. Estou... queimado...", - 2: "Uau! Você está pegando fogo!", - 3: "Ai! Você me pegou!" - }, - "defeat": { - 1: "Estou pegando fogo! Jogue comigo, e você se queimará!", - 2: "Quando você brinca com fogo, você se queima!", - 3: "Quero dizer, vamos lá, seu oponente era eu! Você não tinha chance!" - } - }, - "cilan": { - "encounter": { - 1: "Nada pessoal... Sem ressentimentos... Eu e meus Pokémon do tipo Grama vamos...\nUm... Vamos batalhar, aconteça o que acontecer.", - 2: "Então, hum, se você está bem comigo, vou, hum, colocar tudo o que tenho em ser, er, você sabe, seu oponente.", - 3: "OK… Então, hum, eu sou o Cilan, gosto de Pokémon do tipo Grama." - }, - "victory": { - 1: "Er... Acabou agora?", - 2: "…Que surpresa. Você é muito forte, não é?\nAcho que meus irmãos também não teriam sido capazes de te derrotar...", - 3: "…Huh. Parece que meu timing estava, hum, errado?" - }, - "defeat": { - 1: "Huh? Ganhei?", - 2: "Acho...\nSuponho que ganhei, porque competi com meus irmãos Chili e Cress, e todos conseguimos ficar mais fortes.", - 3: "Foi... uma experiência bastante emocionante..." - } - }, "roark": { "encounter": { 1: "Preciso ver seu potencial como Treinadora. E, vou precisar ver a dureza dos Pokémon que batalham com você!", @@ -3615,7 +3278,7 @@ export const PGFdialogue: DialogueTranslationEntries = { }, "victory": { 1: "Ainda não sou bom o suficiente...", - 2: "Eu vejo... Sua jornada o levou a lugares distantes e você testemunhou muito mais do que eu.\nEu invejo você por isso...", + 2: "Eu vejo... Sua jornada a levou a lugares distantes e você testemunhou muito mais do que eu.\nEu invejo você por isso...", 3: "Como isso é possível...", 4: "Não acho que nossos potenciais sejam tão diferentes.\nMas você parece ter algo mais do que isso... Que seja.", 5: "Acho que preciso de mais treinamento.", @@ -3630,42 +3293,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 6: "Eu sabia que venceria!" } }, - "crispin": { - "encounter": { - 1: "Quero vencer, então é exatamente isso que vou fazer!", - 2: "Eu batalho porque quero batalhar! E sabe de uma coisa? É assim que deve ser!" - }, - "victory": { - 1: "Queria vencer... mas perdi!", - 2: "Eu perdi... porque não consegui vencer!" - }, - "defeat": { - 1: "Ei, espere um segundo. Eu acabei de vencer? Acho que acabei de vencer! Que satisfação!", - 2: "Uou! Isso foi incrível!" - } - }, - "amarys": { - "encounter": { - 1: "Quero ser a pessoa a ajudar alguém em particular. Sendo assim, não posso me dar ao luxo de perder.\n... Nossa batalha começa agora." - }, - "victory": { - 1: "Eu sou... não o suficiente, eu vejo." - }, - "defeat": { - 1: "A vitória pertence a mim. Bem lutado." - } - }, - "lacey": { - "encounter": { - 1: "Vou enfrentar você com meu time usual como membro da Elite dos Quatro." - }, - "victory": { - 1: "Foi uma excelente batalha. Estou ansiosa para o próximo desafio." - }, - "defeat": { - 1: "Fufufu... Nada mal.\nDesafiantes que derrotam a Elite dos Quatro são dignos de notar." - } - }, "drayton": { "encounter": { 1: `Cara, eu amo cadeiras. Você não ama cadeiras? Que salva-vidas. @@ -3675,7 +3302,7 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Acho que deveria ter esperado por isso!" }, "defeat": { - 1: "Heh heh! Não ligue para mim, só pegando uma vitória aqui. Entendo se você estiver chateado, mas não vá dar uma de Kieran comigo, OK?" + 1: "Heh heh! Não ligue para mim, só pegando uma vitória aqui. Entendo se você estiver chateada, mas não vá dar uma de Kieran comigo, OK?" } }, "ramos": { @@ -3690,23 +3317,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Hohoho... De fato. Pequenas lâminas frágeis de grama conseguem quebrar até mesmo concreto." } }, - "viola": { - "encounter": { - 1: `Seja as lágrimas de frustração que seguem uma derrota ou o florescer da alegria que vem com a vitória… - $Ambos são ótimos temas para minha câmera! Fantástico! Isso vai ser simplesmente fantástico! - $Agora venha para cima de mim!`, - 2: "Minha lente está sempre focada na vitória – não vou deixar nada estragar esta foto!" - }, - "victory": { - 1: "Você e seus Pokémon me mostraram uma nova profundidade de campo! Fantástico! Simplesmente fantástico!", - 2: `O mundo que você vê através de uma lente, e o mundo que você vê com um Pokémon ao seu lado… - $O mesmo mundo pode parecer completamente diferente dependendo do seu ponto de vista.` - }, - "defeat": { - 1: "A foto do momento da minha vitória vai ser um verdadeiro sucesso!", - 2: "Sim! Tirei ótimas fotos!" - } - }, "candice": { "encounter": { 1: `Você quer desafiar a Candice? Com certeza! Eu estava esperando por alguém forte! @@ -3735,40 +3345,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Sim! Meus Pokémon e eu somos perfeitamente bons!" } }, - "aaron": { - "encounter": { - 1: "Ok! Deixe-me enfrentar você!" - }, - "victory": { - 1: "Batalhar é um assunto profundo e complexo..." - }, - "defeat": { - 1: "Vencer um membro da Elite dos Quatro não é fácil." - } - }, - "cress": { - "encounter": { - 1: "Isso mesmo! Serei eu e meus estimados tipos Água que você deve enfrentar na batalha!" - }, - "victory": { - 1: "Perder? Eu? Não acredito nisso." - }, - "defeat": { - 1: "Este é o resultado apropriado quando eu sou seu oponente." - } - }, - "allister": { - "encounter": { - 1: "'M Allister.\nA-aqui... vou eu..." - }, - "victory": { - 1: `Quase perdi minha máscara de tanto choque... Isso foi… - $Uau. Posso ver sua habilidade pelo que ela é.`, - }, - "defeat": { - 1: "I-isso foi incrível!" - } - }, "clay": { "encounter": { 1: "Harrumph! Me deixou esperando, não foi, garota? Tudo bem, hora de ver o que você pode fazer!" @@ -3786,75 +3362,12 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Vou te servir um prato completo de Pokémon do tipo Água! Mas não tente comê-los!" }, "victory": { - 1: "Vaultin' Veluza! Você é animada, não é! Um pouco ANIMADO DEMAIS, se me permite dizer!" + 1: "Vaultin' Veluza! Você é animada, não é! Um pouco ANIMADA DEMAIS, se me permite dizer!" }, "defeat": { 1: "Volte para me ver novamente, ouviu?" } }, - "tulip": { - "encounter": { - 1: "Permita-me usar minhas habilidades para deixar seus lindos Pokémon ainda mais bonitos!" - }, - "victory": { - 1: "Sua força tem uma magia que não pode ser apagada." - }, - "defeat": { - 1: "Você sabe, na minha linha de trabalho, pessoas que carecem de talento em uma área ou outra frequentemente desaparecem rapidamente - nunca mais se ouve falar delas." - } - }, - "sidney": { - "encounter": { - 1: `Gostei desse olhar que você me deu. Acho que você vai ser um bom desafio. - $Isso é ótimo! Parece muito bom! Vamos nessa! - $Você e eu, vamos curtir uma batalha que só pode acontecer aqui!`, - }, - "victory": { - 1: "E aí, gostou? Eu perdi! Mas foi divertido, então não importa." - }, - "defeat": { - 1: "Sem ressentimentos, beleza?" - } - }, - "phoebe": { - "encounter": { - 1: `Enquanto treinava, adquiri a habilidade de me comunicar com Pokémon do tipo Fantasma. - $Sim, o vínculo que desenvolvi com os Pokémon é extremamente forte. - $Então, vamos lá, tente ver se você consegue até mesmo causar dano aos meus Pokémon!`, - }, - "victory": { - 1: "Ah, droga. Eu perdi." - }, - "defeat": { - 1: "Estou ansiosa para batalhar com você de novo algum dia!" - } - }, - "glacia": { - "encounter": { - 1: `Tudo o que vi foram desafios de Treinadores fracos e seus Pokémon. - $E você? Ficaria extremamente satisfeita se pudesse dar tudo de mim contra você!`, - }, - "victory": { - 1: `Você e seus Pokémon… Como seus espíritos queimam! - $O calor consumido é esmagador. - $Não é surpresa que minhas habilidades geladas falharam em te machucar.`, - }, - "defeat": { - 1: "Uma batalha intensamente apaixonada, sem dúvida." - } - }, - "drake": { - "encounter": { - 1: `Para nós, batalhar com Pokémon como parceiros, você sabe o que é necessário? Você sabe o que precisa? - $Se não souber, nunca prevalecerá contra mim!`, - }, - "victory": { - 1: "Excelente, deve-se dizer." - }, - "defeat": { - 1: "Dei meu máximo nessa batalha!" - } - }, "wallace": { "encounter": { 1: `Há algo em você… Uma diferença na sua postura. @@ -3863,7 +3376,7 @@ export const PGFdialogue: DialogueTranslationEntries = { }, "victory": { 1: `Bravo. Agora percebo sua autenticidade e magnificência como Treinadora de Pokémon. - $Tenho muita alegria em ter conhecido você e seus Pokémon. Você se mostrou digno.`, + $Tenho muita alegria em ter conhecido você e seus Pokémon. Você se mostrou digna.`, }, "defeat": { 1: "Uma grande ilusão!" @@ -3878,7 +3391,7 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Como ousa!" }, "defeat": { - 1: "Não há nada que você possa fazer quando está congelado." + 1: "Não há nada que você possa fazer quando está congelada." } }, "will": { @@ -3890,7 +3403,7 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Eu… Eu não… acredito…" }, "defeat": { - 1: "Isso foi por pouco. Me pergunto o que você está faltando." + 1: "Isso foi por pouco. Me pergunto o que está faltando em você." } }, "malva": { @@ -3905,17 +3418,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Estou encantada! Sim, encantada por poder esmagar você sob meu calcanhar." } }, - "hala": { - "encounter": { - 1: "O velho Hala está aqui para fazer você gritar!" - }, - "victory": { - 1: "Pude sentir o poder que você ganhou na sua jornada." - }, - "defeat": { - 1: "Haha! Que batalha deliciosa!" - } - }, "molayne": { "encounter": { 1: `Dei a posição de capitão ao meu primo Sophocles, mas estou confiante na minha habilidade. @@ -3939,17 +3441,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Nahahaha! Você realmente é algo mais, garota!" } }, - "bruno": { - "encounter": { - 1: "Nós vamos te triturar com nosso poder superior! Hoo hah!" - }, - "victory": { - 1: "Por quê? Como eu poderia perder?" - }, - "defeat": { - 1: "Você pode me desafiar o quanto quiser, mas os resultados nunca vão mudar!" - } - }, "bugsy": { "encounter": { 1: "Sou Bugsy! Eu nunca perco quando se trata de Pokémon do tipo Inseto!" @@ -3961,33 +3452,9 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Obrigado! Graças à nossa batalha, eu também pude fazer progressos na minha pesquisa!" } }, - "koga": { - "encounter": { - 1: "Fwahahahaha! Pokémon não são apenas sobre força bruta--você verá em breve!" - }, - "victory": { - 1: "Ah! Você provou seu valor!" - }, - "defeat": { - 1: "Você aprendeu a temer as técnicas do ninja?" - } - }, - "bertha": { - "encounter": { - 1: "Bem, você mostraria a esta velha senhora o quanto aprendeu?" - }, - "victory": { - 1: `Bem! Querida criança, devo dizer, isso foi muito impressionante. - $Seus Pokémon acreditaram em você e fizeram o melhor para te dar a vitória. - $Mesmo tendo perdido, me encontro com esse sorriso bobo!`, - }, - "defeat": { - 1: "Hahahahah! Parece que esta velha senhora ganhou!" - } - }, "lenora": { "encounter": { - 1: "Bem, desafiador, vou pesquisar como você batalha com os Pokémon que criou com tanto carinho!" + 1: "Bem, desafiadora, vou pesquisar como você batalha com os Pokémon que criou com tanto carinho!" }, "victory": { 1: "Minha teoria sobre você estava correta. Você é mais do que talentosa… Você é motivada! Eu te saúdo!" @@ -3996,18 +3463,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Ah ha ha! Se você perder, certifique-se de analisar o porquê e use esse conhecimento na próxima batalha!" } }, - "siebold": { - "encounter": { - 1: "Enquanto eu estiver vivo, continuarei em busca da culinária suprema... e dos oponentes mais fortes em batalha!" - }, - "victory": { - 1: "Guardarei minha memória de você e seus Pokémon para sempre em meu coração." - }, - "defeat": { - 1: `Nossa batalha Pokémon foi como alimento para minha alma. Isso vai me manter em frente. - $É assim que vou prestar meus respeitos a você por dar tudo de si na batalha!`, - } - }, "roxie": { "encounter": { 1: "Prepare-se! Vou arrancar algum senso de você!" @@ -4019,40 +3474,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Ei, vamos lá! Seja séria! Você tem que dar mais de si!" } }, - "olivia": { - "encounter": { - 1: "Não precisa de introdução aqui. Hora de batalhar comigo, Olivia!" - }, - "victory": { - 1: "Realmente encantador… Tanto você quanto seus Pokémon…" - }, - "defeat": { - 1: "Mmm-hmm." - } - }, - "poppy": { - "encounter": { - 1: "Oooh! Você quer ter uma batalha Pokémon comigo?" - }, - "victory": { - 1: "Uagh?! Mmmuuuggghhh…" - }, - "defeat": { - 1: `Yaaay! Eu consegui! Eu der-ro-tei você! Você pode vir para… Para… Uma revanche? - $Venha para uma revanche quando quiser!`, - } - }, - "agatha": { - "encounter": { - 1: "Pokémon são para batalhas! Vou te mostrar como um verdadeiro Treinador batalha!" - }, - "victory": { - 1: "Oh meu! Você é algo especial, criança!" - }, - "defeat": { - 1: "Bahaha. É assim que uma batalha adequada é feita!" - } - }, "flint": { "encounter": { 1: "Espero que você esteja aquecida, porque aqui vem o Big Bang!" @@ -4064,17 +3485,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Huh? Isso é tudo? Acho que você precisa de um pouco mais de paixão." } }, - "grimsley": { - "encounter": { - 1: "O vencedor leva tudo, e não sobra nada para o perdedor." - }, - "victory": { - 1: "Quando se perde, perde-se tudo… A próxima coisa que vou procurar será a vitória, também!" - }, - "defeat": { - 1: "Se alguém vence, a pessoa que lutou contra essa pessoa perde." - } - }, "caitlin": { "encounter": { 1: `Sou eu que apareci quando a flor se abriu. Você que estava esperando… @@ -4089,29 +3499,17 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Aspiro a reivindicar a vitória com elegância e graça." } }, - "diantha": { - "encounter": { - 1: `Batalhar contra você e seus Pokémon, todos vocês cheios de esperança para o futuro… - $Honestamente, isso apenas me enche da energia que preciso para continuar enfrentando cada novo dia! Sim!`, - }, - "victory": { - 1: "Testemunhar os espíritos nobres de você e seus Pokémon em batalha realmente tocou meu coração…" - }, - "defeat": { - 1: "Oh, fantástico! O que achou? Minha equipe foi bem legal, né?" - } - }, "wikstrom": { "encounter": { - 1: `Bem encontrado, jovem desafiador! Verdadeiramente sou a lâmina famosa de aço endurecido, Duque Wikstrom! + 1: `Bem encontrado, jovem desafiadora! Verdadeiramente sou a lâmina famosa de aço endurecido, Duque Wikstrom! $Que a batalha comece! En garde!`, }, "victory": { - 1: "Glorioso! A confiança que você compartilha com seu honrado Pokémon supera até mesmo a minha!" + 1: "Gloriosa! A confiança que você compartilha com seu honrado Pokémon supera até mesmo a minha!" }, "defeat": { 1: `Que tipo de magia é essa? Meu coração bate incessantemente no meu peito! - $Vencer contra um oponente tão digno dá asas à minha alma--assim eu voo!`, + $Vencer contra uma oponente tão digna dá asas à minha alma--assim eu voo!`, } }, "acerola": { @@ -4125,18 +3523,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Ehaha! Que vitória incrível!" } }, - "larry_elite": { - "encounter": { - 1: `Olá… Sou eu, Larry. - $Eu também sou membro da Elite dos Quatro, sim… Infelizmente para mim.`, - }, - "victory": { - 1: "Bem, isso tirou o vento debaixo das nossas asas…" - }, - "defeat": { - 1: "É hora de uma reunião com o chefe." - } - }, "lance": { "encounter": { 1: "Estive esperando por você. Permita-me testar suas habilidades.", @@ -4144,28 +3530,11 @@ export const PGFdialogue: DialogueTranslationEntries = { }, "victory": { 1: "Você me pegou. Você é magnífica!", - 2: "Nunca esperei que outro Treinador me derrotasse… Estou surpreso." + 2: "Nunca esperei que outra Treinadora me derrotasse… Estou surpreso." }, "defeat": { 1: "Isso foi por pouco. Quer tentar de novo?", - 2: "Não é que você seja fraco. Não se incomode com isso." - } - }, - "karen": { - "encounter": { - 1: "Eu sou Karen. Você gostaria de um duelo com meus Pokémon do tipo Sombrio?", - 2: "Sou diferente daqueles que você já conheceu.", - 3: "Você montou uma equipe charmosa. Nossa batalha deve ser boa." - }, - "victory": { - 1: "Não! Eu não posso vencer. Como você ficou tão forte?", - 2: "Não me desviarei do meu caminho escolhido.", - 3: "O Campeão está ansioso para te conhecer." - }, - "defeat": { - 1: "Isso era o que eu esperava.", - 2: "Bem, isso foi relativamente divertido.", - 3: "Venha me visitar a qualquer momento." + 2: "Não é que você seja fraca. Não se incomode com isso." } }, "milo": { @@ -4175,26 +3544,12 @@ export const PGFdialogue: DialogueTranslationEntries = { $Vou ter que usar a Dynamax no meu Pokémon se eu quiser vencer!`, }, "victory": { - 1: "O poder da Grama murchou… Que desafiador incrível!" + 1: "O poder da Grama murchou… Que desafiadora incrível!" }, "defeat": { 1: "Isso realmente vai te deixar em choque e admiração." } }, - "lucian": { - "encounter": { - 1: `Só um momento, por favor. O livro que estou lendo está quase no clímax emocionante… - $O herói obteve uma espada mística e está prestes a enfrentar sua prova final… Ah, tanto faz. - $Já que você chegou tão longe, vou deixar isso de lado e batalhar com você. - $Deixe-me ver se você alcançará tanta glória quanto o herói do meu livro!`, - }, - "victory": { - 1: "Eu vejo… Parece que você me colocou em xeque-mate." - }, - "defeat": { - 1: "Tenho uma reputação a manter." - } - }, "drasna": { "encounter": { 1: `Você deve ser uma Treinadora forte. Sim, bastante forte… @@ -4207,29 +3562,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Como isso é possível?" } }, - "kahili": { - "encounter": { - 1: "Então, aqui está você… Por que não vemos para quem os ventos favorecem hoje, você… ou eu?" - }, - "victory": { - 1: "É frustrante para mim como membro da Elite dos Quatro, mas parece que sua força é real." - }, - "defeat": { - 1: "Essa foi uma jogada de mestre!" - } - }, - "hassel": { - "encounter": { - 1: "Prepare-se para aprender em primeira mão como é a respiração ardente de uma batalha feroz!" - }, - "victory": { - 1: `A sorte sorriu para mim desta vez, mas… - $Julgando pelo andamento da luta, quem sabe se serei tão sortudo na próxima vez.`, - }, - "defeat": { - 1: "Essa foi uma jogada de mestre!" - } - }, "blue": { "encounter": { 1: "Você deve ser muito boa para chegar tão longe." @@ -4241,39 +3573,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Viu? Meu poder é o que me trouxe até aqui." } }, - "piers": { - "encounter": { - 1: "Prepare-se para uma mosh pit comigo e minha galera! Spikemuth, é hora de roquear!" - }, - "victory": { - 1: "Eu e minha equipe demos o nosso melhor. Vamos nos encontrar novamente para uma batalha algum dia…" - }, - "defeat": { - 1: "Minha garganta está desgastada de tanto gritar… Mas essa foi uma batalha empolgante!" - } - }, - "red": { - "encounter": { - 1: "…!" - }, - "victory": { - 1: "…?" - }, - "defeat": { - 1: "…!" - } - }, - "jasmine": { - "encounter": { - 1: "Oh… Seus Pokémon são impressionantes. Acho que vou gostar disso." - }, - "victory": { - 1: "Você é realmente forte. Vou ter que me esforçar muito mais também." - }, - "defeat": { - 1: "Eu nunca esperei ganhar." - } - }, "lance_champion": { "encounter": { 1: "Ainda sou o Campeão. Não vou segurar nada." @@ -4285,96 +3584,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Defendi com sucesso meu Campeonato." } }, - "steven": { - "encounter": { - 1: `Diga-me… O que você viu na sua jornada com seus Pokémon? - $O que você sentiu, encontrando tantos outros Treinadores por aí? - $Viajar por esta terra rica… Isso despertou algo dentro de você? - $Quero que você venha até mim com tudo o que aprendeu. - $Meus Pokémon e eu responderemos com tudo o que sabemos!`, - }, - "victory": { - 1: "Então eu, o Campeão, caio em derrota…" - }, - "defeat": { - 1: "Esse tempo foi bem gasto! Obrigado!" - } - }, - "cynthia": { - "encounter": { - 1: "Eu, Cynthia, aceito seu desafio! Não haverá nenhuma trégua da minha parte!" - }, - "victory": { - 1: "Não importa o quão divertida a batalha seja, ela sempre terminará algum dia…" - }, - "defeat": { - 1: "Mesmo que você perca, nunca perca o amor pelos Pokémon." - } - }, - "iris": { - "encounter": { - 1: `Sabe de uma coisa? Estou realmente ansiosa para ter batalhas sérias com Treinadores fortes! - $Quero dizer, vamos lá! Os Treinadores que chegam aqui são Treinadores que desejam a vitória com todas as fibras do seu ser! - #E eles estão batalhando ao lado de Pokémon que passaram por inúmeras batalhas difíceis! - $Se eu batalhar com pessoas assim, não só eu ficarei mais forte, meus Pokémon também! - $E nós vamos nos conhecer ainda melhor! OK! Prepare-se! - $Sou Iris, a Campeã da Liga Pokémon, e vou te derrotar!`, - }, - "victory": { - 1: "Aghhhh… Eu dei o meu melhor, mas nós perdemos…" - }, - "defeat": { - 1: "Yay! Nós vencemos!" - } - }, - "hau": { - "encounter": { - 1: `Eu me pergunto se um Treinador batalha de maneira diferente dependendo se ele é de uma região quente ou fria. - $Vamos testar isso!`, - }, - "victory": { - 1: "Isso foi incrível! Acho que entendi um pouco melhor seu estilo agora!" - }, - "defeat": { - 1: "Cara, essa foi uma batalha e tanto!" - } - }, - "geeta": { - "encounter": { - 1: `Decidi entrar na batalha mais uma vez. - $Venha agora… Mostre-me os frutos do seu treinamento.`, - }, - "victory": { - 1: "Estou ansiosa para notícias de todas as suas conquistas!" - }, - "defeat": { - 1: "Qual o problema? Isso é tudo?" - } - }, - "nemona": { - "encounter": { - 1: "Yesss! Estou tão empolgada! Hora de soltar tudo!" - }, - "victory": { - 1: "Bem, isso foi ruim, mas ainda me diverti! Eu te pego na próxima!" - }, - "defeat": { - 1: "Bem, essa foi uma ótima batalha! Frutífera, com certeza." - } - }, - "leon": { - "encounter": { - 1: "Vamos ter um tempo absolutamente campeão!" - }, - "victory": { - 1: `Meu tempo como Campeão acabou… - $Mas que tempo campeão foi! - $Obrigado pela melhor batalha que já tive!`, - }, - "defeat": { - 1: "Um tempo absolutamente campeão, foi!" - } - }, "whitney": { "encounter": { 1: "Eai! Você não acha que os Pokémon são, tipo, super fofos?" @@ -4408,28 +3617,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Coma, meu adorável Vivillon!" } }, - "pryce": { - "encounter": { - 1: "A juventude sozinha não garante a vitória! Experiência é o que conta." - }, - "victory": { - 1: "Excelente! Isso foi perfeito. Tente não esquecer o que sente agora." - }, - "defeat": { - 1: "Exatamente como eu imaginei." - } - }, - "clair": { - "encounter": { - 1: "Você sabe quem eu sou? E ainda se atreve a me desafiar?" - }, - "victory": { - 1: "Eu me pergunto até onde você pode ir com seu nível de habilidade. Isso deve ser fascinante." - }, - "defeat": { - 1: "E é isso." - } - }, "maylene": { "encounter": { 1: `Vim desafiá-la agora e não vou segurar nada. @@ -4442,18 +3629,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Isso foi incrível." } }, - "fantina": { - "encounter": { - 1: `Você vai me desafiar, não é? Mas eu vou ganhar. - $É o que a Líder do Ginásio de Hearthome faz, não?`, - }, - "victory": { - 1: "Você é tão incrivelmente forte. Sei porque perdi." - }, - "defeat": { - 1: "Estou tão, tão, muito feliz!" - } - }, "byron": { "encounter": { 1: `Treinadora! Você é jovem, assim como meu filho, Roark. @@ -4467,17 +3642,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Gwahahaha! Como foram meus Pokémon robustos?!" } }, - "olympia": { - "encounter": { - 1: "Um costume antigo decidindo o destino de alguém. A batalha começa!" - }, - "victory": { - 1: "Crie seu próprio caminho. Não deixe nada te atrapalhar. Seu destino, seu futuro." - }, - "defeat": { - 1: "Nosso caminho está claro agora." - } - }, "volkner": { "encounter": { 1: `Já que você chegou tão longe, deve ser bastante forte… @@ -4493,113 +3657,11 @@ export const PGFdialogue: DialogueTranslationEntries = { $Isso não é o que eu queria!`, } }, - "burgh": { - "encounter": { - 1: `M'hm… Se eu ganhar esta batalha, sinto que posso desenhar um quadro diferente de qualquer outro. - $OK! Posso ouvir minha musa da batalha claramente. Vamos direto ao ponto!`, - 2: `Claro, estou realmente orgulhoso de todos os meus Pokémon! - $Bem agora… Vamos direto ao ponto!` - }, - "victory": { - 1: "Acabou? Minha musa me abandonou?", - 2: "Hmm… Acabou! Você é incrível!" - }, - "defeat": { - 1: "Uau… É bonito de alguma forma, não é…", - 2: `Às vezes ouço as pessoas dizerem que foi uma vitória feia. - $Acho que se você está dando o seu melhor, qualquer vitória é bonita.` - } - }, - "elesa": { - "encounter": { - 1: `C'est fini! Quando tenho certeza disso, sinto um choque elétrico percorrer meu corpo! - $Quero sentir essa sensação, então agora meus amados Pokémon vão fazer sua cabeça girar!`, - }, - "victory": { - 1: "Eu queria fazer sua cabeça girar, mas você me surpreendeu." - }, - "defeat": { - 1: "Isso foi insatisfatório de alguma forma… Você dará tudo de si na próxima vez?" - } - }, - "skyla": { - "encounter": { - 1: `Finalmente é hora do confronto! Isso significa a batalha Pokémon que decide quem está no topo, certo? - $Eu amo estar no topo! Porque você pode ver para sempre e sempre de lugares altos! - $Então, que tal nós nos divertirmos?`, - }, - "victory": { - 1: "Ser seu oponente na batalha é uma nova fonte de força para mim. Obrigada!" - }, - "defeat": { - 1: "Ganhar ou perder, você sempre ganha algo com uma batalha, certo?" - } - }, - "brycen": { - "encounter": { - 1: `Há também força em estar com outras pessoas e Pokémon. - $Receber o apoio deles te fortalece. Vou te mostrar esse poder!`, - }, - "victory": { - 1: "A maravilhosa combinação de você e seus Pokémon! Que amizade linda!" - }, - "defeat": { - 1: "Condições extremas realmente testam e treinam você!" - } - }, - "drayden": { - "encounter": { - 1: `O que eu quero encontrar é um jovem Treinador que possa me mostrar um futuro brilhante. - $Vamos batalhar com tudo o que temos: sua habilidade, minha experiência e o amor com que criamos nossos Pokémon!`, - }, - "victory": { - 1: "Esse sentimento intenso que me invade após uma derrota… Não sei como descrevê-lo." - }, - "defeat": { - 1: "Harrumph! Sei que sua habilidade é maior que isso!" - } - }, - "grant": { - "encounter": { - 1: `Só há uma coisa que desejo. - $Que, superando um ao outro, encontremos um caminho para alturas ainda maiores.`, - }, - "victory": { - 1: "Você é uma parede que não consigo superar!" - }, - "defeat": { - 1: `Não desista. - $Isso é tudo o que realmente importa. - $As lições mais importantes da vida são simples.`, - } - }, - "korrina": { - "encounter": { - 1: "Hora da grande aparição de Lady Korrina!" - }, - "victory": { - 1: "É o seu próprio ser que permite que seus Pokémon evoluam!" - }, - "defeat": { - 1: "Que batalha explosiva!" - } - }, - "clemont": { - "encounter": { - 1: "Oh! Estou feliz por termos nos encontrado!" - }, - "victory": { - 1: "Sua paixão pela batalha me inspira!" - }, - "defeat": { - 1: "Parece que minha Máquina Treinadora-Crescer-Forte, Mach 2 está realmente funcionando!" - } - }, "valerie": { "encounter": { - 1: `Oh, se não é uma jovem Treinadora… É adorável conhecê-lo assim. + 1: `Oh, se não é uma jovem Treinadora… É adorável conhecê-la assim. $Então, suponho que você ganhou o direito a uma batalha, como recompensa por seus esforços. - $O elusivo Fada pode parecer frágil como a brisa e delicado como uma flor, mas é forte.`, + $Uma elusiva Fada pode parecer frágil como a brisa e delicado como uma flor, mas é forte.`, }, "victory": { 1: "Espero que você encontre coisas para sorrir amanhã…" @@ -4668,42 +3730,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Bom trabalho, eu suponho." } }, - "gordie": { - "encounter": { - 1: "Então, vamos acabar com isso." - }, - "victory": { - 1: "Eu só quero me enterrar em um buraco… Bem, acho que seria mais como cair daqui." - }, - "defeat": { - 1: "Batalhe como sempre faz, a vitória seguirá!" - } - }, - "marnie": { - "encounter": { - 1: `A verdade é que, quando tudo está dito e feito… Eu realmente só quero me tornar Campeã por mim mesma! - $Então, não leve para o pessoal quando eu chutar seu traseiro!`, - }, - "victory": { - 1: "OK, então eu perdi… Mas consegui ver muitos dos pontos bons de você e seus Pokémon!" - }, - "defeat": { - 1: "Espero que você tenha gostado das nossas táticas de batalha." - } - }, - "raihan": { - "encounter": { - 1: "Vou derrotar o Campeão, vencer todo o torneio e provar ao mundo o quão forte o grande Raihan realmente é!" - }, - "victory": { - 1: `Eu pareço bem mesmo quando perco. - $É uma verdadeira maldição. - $Acho que é hora de mais uma selfie!`, - }, - "defeat": { - 1: "Vamos tirar uma selfie para lembrar disso." - } - }, "brassius": { "encounter": { 1: "Pressuponho que você está pronta? Que nossa obra de arte colaborativa comece!" @@ -4729,17 +3755,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Seus olhos são MEUS!" } }, - "larry": { - "encounter": { - 1: "Quando tudo está dito e feito, a simplicidade é mais forte." - }, - "victory": { - 1: "Uma porção de derrota, hein?" - }, - "defeat": { - 1: "Vou encerrar o dia." - } - }, "ryme": { "encounter": { 1: "Vamos lá, baby! Me agite até os ossos!" @@ -4751,31 +3766,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Até mais, baby!" } }, - "grusha": { - "encounter": { - 1: "Tudo o que preciso fazer é garantir que o poder do meu Pokémon te arrependa até os ossos!" - }, - "victory": { - 1: "Sua paixão ardente... Eu meio que gosto, para ser honesto." - }, - "defeat": { - 1: "As coisas não esquentaram para você." - } - }, - "marnie_elite": { - "encounter": { - 1: "Você chegou até aqui, hein? Vamos ver se você pode lidar com meus Pokémon!", - 2: "Vou dar o meu melhor, mas não pense que vou pegar leve com você!" - }, - "victory": { - 1: "Não acredito que perdi... Mas você mereceu essa vitória. Bem feito!", - 2: "Parece que ainda tenho muito a aprender. Grande batalha, porém!" - }, - "defeat": { - 1: "Você lutou bem, mas eu tenho a vantagem! Melhor sorte na próxima vez!", - 2: "Parece que meu treinamento valeu a pena. Obrigado pela batalha!" - } - }, "nessa_elite": { "encounter": { 1: "As marés estão mudando a meu favor. Pronta para ser levada pela corrente?", @@ -4790,20 +3780,6 @@ export const PGFdialogue: DialogueTranslationEntries = { 2: "Você lutou bem, mas o poder do oceano é imparável!" } }, - "bea_elite": { - "encounter": { - 1: "Prepare-se! Meu espírito de luta brilha intensamente!", - 2: "Vamos ver se você consegue acompanhar meu ritmo implacável!" - }, - "victory": { - 1: "Sua força... É impressionante. Você realmente merece essa vitória.", - 2: "Nunca senti essa intensidade antes. Trabalho incrível!" - }, - "defeat": { - 1: "Outra vitória para meu rigoroso regime de treinamento! Bem feito!", - 2: "Você tem força, mas eu treinei mais. Grande batalha!" - } - }, "allister_elite": { "encounter": { 1: "As sombras caem... Você está pronta para enfrentar seus medos?", @@ -4829,33 +3805,7 @@ export const PGFdialogue: DialogueTranslationEntries = { }, "defeat": { 1: "Outra tempestade enfrentada, outra vitória conquistada! Bem lutado!", - 2: "Você foi pego na minha tempestade! Melhor sorte na próxima vez!" - } - }, - "alder": { - "encounter": { - 1: "Se prepare para uma batalha contra o Treinador mais forte de Unova!" - }, - "victory": { - 1: "Muito bem! Você certamente é um talento incomparável." - }, - "defeat": { - 1: `Um vento fresco sopra em meu coração... - $Que esforço extraordinário!` - } - }, - "kieran": { - "encounter": { - 1: `Através do trabalho duro, eu me torno cada vez mais forte! - $Eu não perco.` - }, - "victory": { - 1: `Eu não acredito... - $Que batalha divertida e emocionante!` - }, - "defeat": { - 1: `Uau, que batalha! - $Hora de você treinar ainda mais.` + 2: "Você foi pega na minha tempestade! Melhor sorte na próxima vez!" } }, "rival": { @@ -4904,7 +3854,7 @@ export const PGFdialogue: DialogueTranslationEntries = { }, "rival_2_female": { "encounter": { - 1: `@c{smile_wave}Oh, que surpresa te encontrar aqui. Parece que você ainda está invicto. @c{angry_mopen}Hum… Nada mal! + 1: `@c{smile_wave}Oh, que surpresa te encontrar aqui. Parece que você ainda está invicta. @c{angry_mopen}Hum… Nada mal! $@c{angry_mopen}Eu sei o que você está pensando, e não, eu não estava te espionando. @c{smile_eclosed}Acontece que eu estava na área. $@c{smile_ehalf}Estou feliz por você, mas só quero te avisar que está tudo bem perder às vezes. $@c{smile}Aprendemos com nossos erros, muitas vezes mais do que se continuássemos vencendo. @@ -4923,7 +3873,7 @@ export const PGFdialogue: DialogueTranslationEntries = { }, "rival_3": { "encounter": { - 1: `@c{smile}Eai, olha quem é! Faz um tempo.\n@c{neutral}Você… ainda está invicto? Hum. + 1: `@c{smile}Eai, olha quem é! Faz um tempo.\n@c{neutral}Você… ainda está invicta? Hum. $@c{neutral_eclosed}As coisas têm sido meio… estranhas.\nNão é a mesma coisa em casa sem você. $@c{serious}Eu sei que é egoísta, mas preciso desabafar.\n@c{neutral_eclosed}Acho que você está se metendo em algo grande demais aqui. $@c{serious}Nunca perder é irrealista.\nPrecisamos perder às vezes para crescer. @@ -4960,7 +3910,7 @@ export const PGFdialogue: DialogueTranslationEntries = { $@c{serious_mopen_fists}Prepare-se.` }, "victory": { - 1: "@c{neutral}O que…@d{64} O que você é?" + 1: "@c{neutral}O que…@d{64} O que é você?" }, }, "rival_4_female": { @@ -4975,7 +3925,7 @@ export const PGFdialogue: DialogueTranslationEntries = { $@c{angry_mopen}Prepare-se.` }, "victory": { - 1: "@c{neutral}O que…@d{64} O que você é?" + 1: "@c{neutral}O que…@d{64} O que é você?" }, "defeat": { 1: "$@c{smile}Você deveria se orgulhar de até onde chegou." @@ -5046,7 +3996,7 @@ export const PGFdialogue: DialogueTranslationEntries = { }, }; -// Diálogo do chefe final do jogo quando o personagem do jogador é masculino (ou não definido) +// Dialogue of the endboss of the game when the player character is male (Or unset) export const PGMbattleSpecDialogue: SimpleTranslationEntries = { "encounter": `Parece que a hora finalmente chegou novamente.\nVocê sabe por que veio aqui, não sabe? $Você foi atraído para cá, porque já esteve aqui antes.\nInúmeras vezes. @@ -5061,7 +4011,7 @@ export const PGMbattleSpecDialogue: SimpleTranslationEntries = { "secondStageWin": "…Magnífico." }; -// Diálogo do chefe final do jogo quando o personagem do jogador é feminino. Para idiomas que não possuem pronomes de gênero, isso pode ser definido como PGMbattleSpecDialogue. +// Dialogue of the endboss of the game when the player character is female. For languages that do not have gendered pronouns, this can be set to PGMbattleSpecDialogue. export const PGFbattleSpecDialogue: SimpleTranslationEntries = { "encounter": `Parece que a hora finalmente chegou novamente.\nVocê sabe por que veio aqui, não sabe? $Você foi atraída para cá, porque já esteve aqui antes.\nInúmeras vezes. @@ -5076,10 +4026,10 @@ export const PGFbattleSpecDialogue: SimpleTranslationEntries = { "secondStageWin": "…Magnífico." }; -// Diálogo que não se enquadra em nenhuma outra categoria (por exemplo, mensagens de tutorial ou o final do jogo). Para quando o personagem do jogador é masculino +// Dialogue that does not fit into any other category (e.g. tutorial messages, or the end of the game). For when the player character is male export const PGMmiscDialogue: SimpleTranslationEntries = { "ending": - `@c{smile}Oh? Você venceu?@d{96} @c{smile_eclosed}Acho que eu deveria saber.\nMas, você está de volta agora. + `@c{smile}Oh? Você venceu?@d{96} @c{smile_eclosed}Acho que eu deveria saber.\nMas, você está de volta agora. $@c{smile}Acabou.@d{64} Você quebrou o ciclo. $@c{serious_smile_fists}Você também realizou seu sonho, não é?\nVocê não perdeu nenhuma vez. $@c{neutral}Eu sou o único que vai lembrar o que você fez.@d{96}\nAcho que está tudo bem, não é? @@ -5087,7 +4037,7 @@ export const PGMmiscDialogue: SimpleTranslationEntries = { $@c{smile_eclosed}Enfim, já tive o suficiente deste lugar, não é? Vamos para casa. $@c{serious_smile_fists}Talvez quando voltarmos, possamos ter outra batalha?\nSe você estiver disposto.`, "ending_female": - `@c{shock}Você está de volta?@d{32} Isso significa que…@d{96} você venceu?!\n@c{smile_ehalf}Eu deveria saber que você conseguiria. + `@c{shock}Você está de volta?@d{32} Isso significa que…@d{96} você venceu?!\n@c{smile_ehalf}Eu deveria saber que você conseguiria. $@c{smile_eclosed}Claro… Eu sempre tive essa sensação.\n@c{smile}Acabou agora, certo? Você quebrou o ciclo. $@c{smile_ehalf}Você também realizou seu sonho, não foi?\nVocê não perdeu nenhuma vez. $Eu serei a única a lembrar o que você fez.\n@c{angry_mopen}Eu tentarei não esquecer! @@ -5098,10 +4048,10 @@ export const PGMmiscDialogue: SimpleTranslationEntries = { "ending_name": "Desenvolvedores" }; -// Diálogo que não se enquadra em nenhuma outra categoria (por exemplo, mensagens de tutorial ou o final do jogo). Para quando o personagem do jogador é feminino. Para idiomas que não possuem pronomes de gênero, isso pode ser definido como PGMmiscDialogue. +// Dialogue that does not fit into any other category (e.g. tutorial messages, or the end of the game). For when the player character is female. For languages that do not have gendered pronouns, this can be set to PGMmiscDialogue. export const PGFmiscDialogue: SimpleTranslationEntries = { "ending": - `@c{smile}Oh? Você venceu?@d{96} @c{smile_eclosed}Acho que eu deveria saber.\nMas, você está de volta agora. + `@c{smile}Oh? Você venceu?@d{96} @c{smile_eclosed}Acho que eu deveria saber.\nMas, você está de volta agora. $@c{smile}Acabou.@d{64} Você quebrou o ciclo. $@c{serious_smile_fists}Você também realizou seu sonho, não é?\nVocê não perdeu nenhuma vez. $@c{neutral}Eu sou o único que vai lembrar o que você fez.@d{96}\nAcho que está tudo bem, não é? @@ -5109,7 +4059,7 @@ export const PGFmiscDialogue: SimpleTranslationEntries = { $@c{smile_eclosed}Enfim, já tive o suficiente deste lugar, não é? Vamos para casa. $@c{serious_smile_fists}Talvez quando voltarmos, possamos ter outra batalha?\nSe você estiver disposta.`, "ending_female": - `@c{shock}Você está de volta?@d{32} Isso significa que…@d{96} você venceu?!\n@c{smile_ehalf}Eu deveria saber que você conseguiria. + `@c{shock}Você está de volta?@d{32} Isso significa que…@d{96} você venceu?!\n@c{smile_ehalf}Eu deveria saber que você conseguiria. $@c{smile_eclosed}Claro… Eu sempre tive essa sensação.\n@c{smile}Acabou agora, certo? Você quebrou o ciclo. $@c{smile_ehalf}Você também realizou seu sonho, não foi?\nVocê não perdeu nenhuma vez. $Eu serei a única a lembrar o que você fez.\n@c{angry_mopen}Eu tentarei não esquecer! @@ -5121,7 +4071,7 @@ export const PGFmiscDialogue: SimpleTranslationEntries = { }; -// Diálogo das batalhas duplas nomeadas no jogo. Para quando o jogador é masculino (ou não definido). +// Dialogue of the named double battles in the game. For when the player is male (or unset). export const PGMdoubleBattleDialogue: DialogueTranslationEntries = { "blue_red_double": { "encounter": { @@ -5196,41 +4146,41 @@ export const PGMdoubleBattleDialogue: DialogueTranslationEntries = { }, "alder_iris_double": { "encounter": { - 1: `Alder: Somos os treinadores mais fortes de Unova! + 1: `Alder: Somos os treinadores mais fortes de Unova! $Iris: Lutas contra treinadores fortes são as melhores!`, }, "victory": { - 1: `Alder: Uau! Você é super forte! + 1: `Alder: Uau! Você é super forte! $Iris: Vamos vencer da próxima vez!`, }, }, "iris_alder_double": { "encounter": { - 1: `Iris: Bem-vindo, Desafiante! Eu sou A Campeã de Unova! + 1: `Iris: Bem-vindo, Desafiante! Eu sou A Campeã de Unova! $Alder: Iris, você não está um pouco empolgada demais?`, }, "victory": { - 1: `Iris: Uma derrota como essa não é fácil de engolir... + 1: `Iris: Uma derrota como essa não é fácil de engolir... $Alder: Mas só ficaremos mais fortes a cada derrota!`, }, }, "piers_marnie_double": { "encounter": { - 1: `Marnie: Irmão, vamos mostrar a eles o poder de Spikemuth! + 1: `Marnie: Irmão, vamos mostrar a eles o poder de Spikemuth! $Piers: Nós trazemos a escuridão!`, }, "victory": { - 1: `Marnie: Você trouxe luz para nossa escuridão! + 1: `Marnie: Você trouxe luz para nossa escuridão! $Piers: Está muito claro...`, }, }, "marnie_piers_double": { "encounter": { - 1: `Piers: Prontos para um show? + 1: `Piers: Prontos para um show? $Marnie: Irmão... Eles estão aqui para lutar, não para cantar...`, }, "victory": { - 1: `Piers: Agora esse foi um ótimo show! + 1: `Piers: Agora esse foi um ótimo show! $Marnie: Irmão...`, }, }, @@ -5312,41 +4262,41 @@ export const PGFdoubleBattleDialogue: DialogueTranslationEntries = { }, "alder_iris_double": { "encounter": { - 1: `Alder: Somos os treinadores mais fortes de Unova! + 1: `Alder: Somos os treinadores mais fortes de Unova! $Iris: Lutas contra treinadores fortes são as melhores!`, }, "victory": { - 1: `Alder: Uau! Você é super forte! + 1: `Alder: Uau! Você é super forte! $Iris: Vamos vencer da próxima vez!`, }, }, "iris_alder_double": { "encounter": { - 1: `Iris: Bem-vinda, Desafiante! Eu sou A Campeã de Unova! + 1: `Iris: Bem-vinda, Desafiante! Eu sou A Campeã de Unova! $Alder: Iris, você não está um pouco empolgada demais?`, }, "victory": { - 1: `Iris: Uma derrota como essa não é fácil de engolir... + 1: `Iris: Uma derrota como essa não é fácil de engolir... $Alder: Mas só ficaremos mais fortes a cada derrota!`, }, }, "piers_marnie_double": { "encounter": { - 1: `Marnie: Irmão, vamos mostrar a eles o poder de Spikemuth! + 1: `Marnie: Irmão, vamos mostrar a eles o poder de Spikemuth! $Piers: Nós trazemos a escuridão!`, }, "victory": { - 1: `Marnie: Você trouxe luz para nossa escuridão! + 1: `Marnie: Você trouxe luz para nossa escuridão! $Piers: Está muito claro...`, }, }, "marnie_piers_double": { "encounter": { - 1: `Piers: Prontos para um show? + 1: `Piers: Prontos para um show? $Marnie: Irmão... Eles estão aqui para lutar, não para cantar...`, }, "victory": { - 1: `Piers: Agora esse foi um ótimo show! + 1: `Piers: Agora esse foi um ótimo show! $Marnie: Irmão...`, }, }, diff --git a/src/locales/pt_BR/filter-bar.ts b/src/locales/pt_BR/filter-bar.ts index d08d2d28707..3ee41c6ead9 100644 --- a/src/locales/pt_BR/filter-bar.ts +++ b/src/locales/pt_BR/filter-bar.ts @@ -16,6 +16,9 @@ export const filterBar: SimpleTranslationEntries = { "costReduction": "Redução de Custo", "costReductionUnlocked": "Redução de Custo Desbloq.", "costReductionLocked": "Redução de Custo Bloq.", + "favorite": "Favorite", + "isFavorite": "Favorite - Yes", + "notFavorite": "Favorite - No", "ribbon": "Fita", "hasWon": "Fita - Sim", "hasNotWon": "Fita - Não", diff --git a/src/locales/pt_BR/move-trigger.ts b/src/locales/pt_BR/move-trigger.ts index a96cdb27953..a6a6e198b8f 100644 --- a/src/locales/pt_BR/move-trigger.ts +++ b/src/locales/pt_BR/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "O Healing Wish de {{pokemonName}}\nfoi concedido!", "invertStats": "As mudanças de atributo de {{pokemonName}}\nforam revertidas!", "resetStats": "As mudanças de atributo de {{pokemonName}}\nforam eliminadas!", + "statEliminated": "Todas as mudanças de atributo foram eliminadas!", "faintCountdown": "{{pokemonName}}\nirá desmaiar em {{turnCount}} turnos.", "copyType": "O tipo de {{pokemonName}}\nmudou para combinar com {{targetPokemonName}}!", "suppressAbilities": "A habilidade de {{pokemonName}}\nfoi suprimida!", diff --git a/src/locales/pt_BR/starter-select-ui-handler.ts b/src/locales/pt_BR/starter-select-ui-handler.ts index 660076da413..2cec9a5335e 100644 --- a/src/locales/pt_BR/starter-select-ui-handler.ts +++ b/src/locales/pt_BR/starter-select-ui-handler.ts @@ -28,6 +28,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "Mostrar IVs", "manageMoves": "Mudar Movimentos", "manageNature": "Mudar Natureza", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", "useCandies": "Usar Doces", "selectNature": "Escolha uma natureza.", "selectMoveSwapOut": "Escolha um movimento para substituir.", @@ -41,6 +43,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleAbility": ": » Habilidade", "cycleNature": ": » Natureza", "cycleVariant": ": » Variante", + "goFilter": ": Ir para filtros", "enablePassive": "Ativar Passiva", "disablePassive": "Desativar Passiva", "locked": "Bloqueada", diff --git a/src/locales/pt_BR/trainers.ts b/src/locales/pt_BR/trainers.ts index e920d07a22a..41932cd1b9a 100644 --- a/src/locales/pt_BR/trainers.ts +++ b/src/locales/pt_BR/trainers.ts @@ -20,18 +20,18 @@ export const titles: SimpleTranslationEntries = { "plasma_boss": "Chefe da Equipe Plasma", "flare_boss": "Chefe da Equipe Flare", - "rocket_admin": "Team Rocket Admin", - "rocket_admin_female": "Team Rocket Admin", - "magma_admin": "Team Magma Admin", - "magma_admin_female": "Team Magma Admin", - "aqua_admin": "Team Aqua Admin", - "aqua_admin_female": "Team Aqua Admin", - "galactic_commander": "Team Galactic Commander", - "galactic_commander_female": "Team Galactic Commander", - "plasma_sage": "Team Plasma Sage", - "plasma_admin": "Team Plasma Admin", - "flare_admin": "Team Flare Admin", - "flare_admin_female": "Team Flare Admin", + "rocket_admin": "Admin da Equipe Rocket", + "rocket_admin_female": "Admin da Equipe Rocket", + "magma_admin": "Admin da Equipe Magma", + "magma_admin_female": "Admin da Equipe Magma", + "aqua_admin": "Admin da Equipe Aqua", + "aqua_admin_female": "Admin da Equipe Aqua", + "galactic_commander": "Comandante da Equipe Galáctica", + "galactic_commander_female": "Comandante da Equipe Galáctica", + "plasma_sage": "Sábio da Equipe Plasma", + "plasma_admin": "Admin da Equipe Plasma", + "flare_admin": "Admin da Equipe Flare", + "flare_admin_female": "Admin da Equipe Flare", // Maybe if we add the evil teams we can add "Team Rocket" and "Team Aqua" etc. here as well as "Team Rocket Boss" and "Team Aqua Admin" etc. } as const; @@ -138,24 +138,24 @@ export const trainerClasses: SimpleTranslationEntries = { "worker_female": "Operária", "workers": "Operários", "youngster": "Jovem", - "rocket_grunt": "Recruta da Equipe Rocket", - "rocket_grunt_female": "Recruta da Equipe Rocket", - "rocket_grunts": "Recrutas da Equipe Rocket", - "magma_grunt": "Recruta da Equipe Magma", - "magma_grunt_female": "Recruta da Equipe Magma", - "magma_grunts": "Recrutas da Equipe Magma", - "aqua_grunt": "Recruta da Equipe Aqua", - "aqua_grunt_female": "Recruta da Equipe Aqua", - "aqua_grunts": "Recrutas da Equipe Aqua", - "galactic_grunt": "Recruta da Equipe Galáctica", - "galactic_grunt_female": "Recruta da Equipe Galáctica", - "galactic_grunts": "Recrutas da Equipe Galáctica", - "plasma_grunt": "Recruta da Equipe Plasma", - "plasma_grunt_female": "Recruta da Equipe Plasma", - "plasma_grunts": "Recrutas da Equipe Plasma", - "flare_grunt": "Recruta da Equipe Flare", - "flare_grunt_female": "Recruta da Equipe Flare", - "flare_grunts": "Recrutas da Equipe Flare", + "rocket_grunt": "Capanga da Equipe Rocket", + "rocket_grunt_female": "Capanga da Equipe Rocket", + "rocket_grunts": "Capangas da Equipe Rocket", + "magma_grunt": "Capanga da Equipe Magma", + "magma_grunt_female": "Capanga da Equipe Magma", + "magma_grunts": "Capangas da Equipe Magma", + "aqua_grunt": "Capanga da Equipe Aqua", + "aqua_grunt_female": "Capanga da Equipe Aqua", + "aqua_grunts": "Capangas da Equipe Aqua", + "galactic_grunt": "Capanga da Equipe Galáctica", + "galactic_grunt_female": "Capanga da Equipe Galáctica", + "galactic_grunts": "Capangas da Equipe Galáctica", + "plasma_grunt": "Capanga da Equipe Plasma", + "plasma_grunt_female": "Capanga da Equipe Plasma", + "plasma_grunts": "Capangas da Equipe Plasma", + "flare_grunt": "Capanga da Equipe Flare", + "flare_grunt_female": "Capanga da Equipe Flare", + "flare_grunts": "Capangas da Equipe Flare", } as const; // Names of special trainers like gym leaders, elite four, and the champion diff --git a/src/locales/zh_CN/filter-bar.ts b/src/locales/zh_CN/filter-bar.ts index 6f484fc8635..820091af06c 100644 --- a/src/locales/zh_CN/filter-bar.ts +++ b/src/locales/zh_CN/filter-bar.ts @@ -16,6 +16,9 @@ export const filterBar: SimpleTranslationEntries = { "costReduction": "费用降低", "costReductionUnlocked": "已降费", "costReductionLocked": "未降费", + "favorite": "Favorite", + "isFavorite": "Favorite - Yes", + "notFavorite": "Favorite - No", "ribbon": "缎带", "hasWon": "有缎带", "hasNotWon": "无缎带", diff --git a/src/locales/zh_CN/move-trigger.ts b/src/locales/zh_CN/move-trigger.ts index d46ef1e313e..334e66ee33a 100644 --- a/src/locales/zh_CN/move-trigger.ts +++ b/src/locales/zh_CN/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "{{pokemonName}}的\n治愈之愿实现了!", "invertStats": "{{pokemonName}}的\n能力变化颠倒过来了!", "resetStats": "{{pokemonName}}的\n能力变化复原了!", + "statEliminated": "所有能力都复原了!", "faintCountdown": "{{pokemonName}}\n将在{{turnCount}}回合后灭亡!", "copyType": "{{pokemonName}}\n变成了{{targetPokemonName}}的属性!", "suppressAbilities": "{{pokemonName}}的特性\n变得无效了!", diff --git a/src/locales/zh_CN/starter-select-ui-handler.ts b/src/locales/zh_CN/starter-select-ui-handler.ts index c9c1cf501ef..2b4fc4434da 100644 --- a/src/locales/zh_CN/starter-select-ui-handler.ts +++ b/src/locales/zh_CN/starter-select-ui-handler.ts @@ -28,6 +28,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "显示个体", "manageMoves": "管理招式", "manageNature": "管理性格", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", "useCandies": "使用糖果", "selectNature": "选择性格", "selectMoveSwapOut": "选择要替换的招式。", @@ -41,6 +43,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleAbility": ": 特性", "cycleNature": ": 性格", "cycleVariant": ": 变种", + "goFilter": ": 转到筛选", "enablePassive": "启用被动", "disablePassive": "禁用被动", "locked": "未解锁", diff --git a/src/locales/zh_TW/filter-bar.ts b/src/locales/zh_TW/filter-bar.ts index 8916088d884..18c09b629b0 100644 --- a/src/locales/zh_TW/filter-bar.ts +++ b/src/locales/zh_TW/filter-bar.ts @@ -16,6 +16,9 @@ export const filterBar: SimpleTranslationEntries = { "costReduction": "Cost Reduction", "costReductionUnlocked": "Cost Reduction Unlocked", "costReductionLocked": "Cost Reduction Locked", + "favorite": "Favorite", + "isFavorite": "Favorite - Yes", + "notFavorite": "Favorite - No", "ribbon": "緞帶", "hasWon": "有緞帶", "hasNotWon": "無緞帶", diff --git a/src/locales/zh_TW/move-trigger.ts b/src/locales/zh_TW/move-trigger.ts index 0831ef82637..5342e08ed85 100644 --- a/src/locales/zh_TW/move-trigger.ts +++ b/src/locales/zh_TW/move-trigger.ts @@ -56,6 +56,7 @@ export const moveTriggers: SimpleTranslationEntries = { "sacrificialFullRestore": "{{pokemonName}}的\n治癒之願實現了!", "invertStats": "{{pokemonName}}的\n能力變化顛倒過來了!", "resetStats": "{{pokemonName}}的\n能力變化復原了!", + "statEliminated": "所有能力都復原了!", "faintCountdown": "{{pokemonName}}\n將在{{turnCount}}回合後滅亡!", "copyType": "{{pokemonName}}變成了{{targetPokemonName}}的屬性!", "suppressAbilities": "{{pokemonName}}的特性\n變得無效了!", diff --git a/src/locales/zh_TW/starter-select-ui-handler.ts b/src/locales/zh_TW/starter-select-ui-handler.ts index 1202bf45f0e..ea4cb127fea 100644 --- a/src/locales/zh_TW/starter-select-ui-handler.ts +++ b/src/locales/zh_TW/starter-select-ui-handler.ts @@ -29,6 +29,8 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "toggleIVs": "查看個體值", "manageMoves": "管理技能", "manageNature": "管理性格", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", "useCandies": "使用糖果", "selectNature": "選擇性格", "selectMoveSwapOut": "選擇想要替換走的招式", @@ -42,6 +44,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleAbility": ": 特性", "cycleNature": ": 性格", "cycleVariant": ": 變種", + "goFilter": ": 轉到篩選", "enablePassive": "啟用被動", "disablePassive": "禁用被動", "locked": "未解鎖", diff --git a/src/phases.ts b/src/phases.ts index b106186ad8b..2bff8f0f62c 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -625,6 +625,11 @@ export class SelectStarterPhase extends Phase { if (starter.pokerus) { starterPokemon.pokerus = true; } + + if (starter.nickname) { + starterPokemon.nickname = starter.nickname; + } + if (this.scene.gameMode.isSplicedOnly) { starterPokemon.generateFusionSpecies(true); } @@ -2964,9 +2969,11 @@ export class MoveEffectPhase extends PokemonPhase { constructor(scene: BattleScene, battlerIndex: BattlerIndex, targets: BattlerIndex[], move: PokemonMove) { super(scene, battlerIndex); this.move = move; - // In double battles, if the right Pokemon selects a spread move and the left Pokemon dies - // with no party members available to switch in, then the right Pokemon takes the index - // of the left Pokemon and gets hit unless this is checked. + /** + * In double battles, if the right Pokemon selects a spread move and the left Pokemon dies + * with no party members available to switch in, then the right Pokemon takes the index + * of the left Pokemon and gets hit unless this is checked. + */ if (targets.includes(battlerIndex) && this.move.getMove().moveTarget === MoveTarget.ALL_NEAR_OTHERS) { const i = targets.indexOf(battlerIndex); targets.splice(i, i + 1); @@ -2977,40 +2984,72 @@ export class MoveEffectPhase extends PokemonPhase { start() { super.start(); + /** The Pokemon using this phase's invoked move */ const user = this.getUserPokemon(); + /** All Pokemon targeted by this phase's invoked move */ const targets = this.getTargets(); + /** If the user was somehow removed from the field, end this phase */ if (!user?.isOnField()) { return super.end(); } + /** + * Does an effect from this move override other effects on this turn? + * e.g. Charging moves (Fly, etc.) on their first turn of use. + */ const overridden = new Utils.BooleanHolder(false); + /** The {@linkcode Move} object from {@linkcode allMoves} invoked by this phase */ const move = this.move.getMove(); // Assume single target for override applyMoveAttrs(OverrideMoveEffectAttr, user, this.getTarget() ?? null, move, overridden, this.move.virtual).then(() => { - + // If other effects were overriden, stop this phase before they can be applied if (overridden.value) { return this.end(); } user.lapseTags(BattlerTagLapseType.MOVE_EFFECT); + /** + * If this phase is for the first hit of the invoked move, + * resolve the move's total hit count. This block combines the + * effects of the move itself, Parental Bond, and Multi-Lens to do so. + */ if (user.turnData.hitsLeft === undefined) { const hitCount = new Utils.IntegerHolder(1); // Assume single target for multi hit applyMoveAttrs(MultiHitAttr, user, this.getTarget() ?? null, move, hitCount); + // If Parental Bond is applicable, double the hit count applyPreAttackAbAttrs(AddSecondStrikeAbAttr, user, null, move, targets.length, hitCount, new Utils.IntegerHolder(0)); + // If Multi-Lens is applicable, multiply the hit count by 1 + the number of Multi-Lenses held by the user if (move instanceof AttackMove && !move.hasAttr(FixedDamageAttr)) { this.scene.applyModifiers(PokemonMultiHitModifier, user.isPlayer(), user, hitCount, new Utils.IntegerHolder(0)); } - user.turnData.hitsLeft = user.turnData.hitCount = hitCount.value; + // Set the user's relevant turnData fields to reflect the final hit count + user.turnData.hitCount = hitCount.value; + user.turnData.hitsLeft = hitCount.value; } + /** + * Log to be entered into the user's move history once the move result is resolved. + * Note that `result` (a {@linkcode MoveResult}) logs whether the move was successfully + * used in the sense of it not failing or missing; it does not account for the move's + * effectiveness (which is logged as a {@linkcode HitResult}). + */ const moveHistoryEntry = { move: this.move.moveId, targets: this.targets, result: MoveResult.PENDING, virtual: this.move.virtual }; + /** + * Stores results of hit checks of the invoked move against all targets, organized by battler index. + * @see {@linkcode hitCheck} + */ const targetHitChecks = Object.fromEntries(targets.map(p => [p.getBattlerIndex(), this.hitCheck(p)])); const hasActiveTargets = targets.some(t => t.isActive(true)); + /** + * If no targets are left for the move to hit (FAIL), or the invoked move is single-target + * (and not random target) and failed the hit check against its target (MISS), log the move + * as FAILed or MISSed (depending on the conditions above) and end this phase. + */ if (!hasActiveTargets || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]])) { this.stopMultiHit(); if (hasActiveTargets) { @@ -3025,6 +3064,7 @@ export class MoveEffectPhase extends PokemonPhase { return this.end(); } + /** All move effect attributes are chained together in this array to be applied asynchronously. */ const applyAttrs: Promise[] = []; // Move animation only needs one target @@ -3032,6 +3072,10 @@ export class MoveEffectPhase extends PokemonPhase { /** Has the move successfully hit a target (for damage) yet? */ let hasHit: boolean = false; for (const target of targets) { + /** + * If the move missed a target, stop all future hits against that target + * and move on to the next target (if there is one). + */ if (!targetHitChecks[target.getBattlerIndex()]) { this.stopMultiHit(target); this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(target) })); @@ -3043,18 +3087,38 @@ export class MoveEffectPhase extends PokemonPhase { continue; } + /** Is the invoked move blocked by a protection effect on the target? */ const isProtected = !this.move.getMove().checkFlag(MoveFlags.IGNORE_PROTECT, user, target) && target.findTags(t => t instanceof ProtectedTag).find(t => target.lapseTag(t.tagType)); + /** Does this phase represent the invoked move's first strike? */ const firstHit = (user.turnData.hitsLeft === user.turnData.hitCount); + // Only log the move's result on the first strike if (firstHit) { user.pushMoveHistory(moveHistoryEntry); } + /** + * Since all fail/miss checks have applied, the move is considered successfully applied. + * It's worth noting that if the move has no effect or is protected against, it's move + * result is still logged as a SUCCESS. + */ moveHistoryEntry.result = MoveResult.SUCCESS; + /** + * Stores the result of applying the invoked move to the target. + * If the target is protected, the result is always `NO_EFFECT`. + * Otherwise, the hit result is based on type effectiveness, immunities, + * and other factors that may negate the attack or status application. + * + * Internally, the call to {@linkcode Pokemon.apply} is where damage is calculated + * (for attack moves) and the target's HP is updated. However, this isn't + * made visible to the user until the resulting {@linkcode DamagePhase} + * is invoked. + */ const hitResult = !isProtected ? target.apply(user, move) : HitResult.NO_EFFECT; + /** Does {@linkcode hitResult} indicate that damage was dealt to the target? */ const dealsDamage = [ HitResult.EFFECTIVE, HitResult.SUPER_EFFECTIVE, @@ -3062,28 +3126,53 @@ export class MoveEffectPhase extends PokemonPhase { HitResult.ONE_HIT_KO ].includes(hitResult); + /** Is this target the first one hit by the move on its current strike? */ const firstTarget = dealsDamage && !hasHit; if (firstTarget) { hasHit = true; } + /** Does this phase represent the invoked move's last strike? */ const lastHit = (user.turnData.hitsLeft === 1 || !this.getTarget()?.isActive()); + /** + * If the user can change forms by using the invoked move, + * it only changes forms after the move's last hit + * (see Relic Song's interaction with Parental Bond when used by Meloetta). + */ if (lastHit) { this.scene.triggerPokemonFormChange(user, SpeciesFormChangePostMoveTrigger); } + /** + * Create a Promise that applys *all* effects from the invoked move's MoveEffectAttrs. + * These are ordered by trigger type (see {@linkcode MoveEffectTrigger}), and each trigger + * type requires different conditions to be met with respect to the move's hit result. + */ applyAttrs.push(new Promise(resolve => { + // Apply all effects with PRE_MOVE triggers (if the target isn't immune to the move) applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.PRE_APPLY && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit) && hitResult !== HitResult.NO_EFFECT, user, target, move).then(() => { + // All other effects require the move to not have failed or have been cancelled to trigger if (hitResult !== HitResult.FAIL) { + /** Are the move's effects tied to the first turn of a charge move? */ const chargeEffect = !!move.getAttrs(ChargeAttr).find(ca => ca.usedChargeEffect(user, this.getTarget() ?? null, move)); - // Charge attribute with charge effect takes all effect attributes and applies them to charge stage, so ignore them if this is present + /** + * If the invoked move's effects are meant to trigger during the move's "charge turn," + * ignore all effects after this point. + * Otherwise, apply all self-targeted POST_APPLY effects. + */ Utils.executeIf(!chargeEffect, () => applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.POST_APPLY && attr.selfTarget && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit), user, target, move)).then(() => { + // All effects past this point require the move to have hit the target if (hitResult !== HitResult.NO_EFFECT) { + // Apply all non-self-targeted POST_APPLY effects applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && (attr as MoveEffectAttr).trigger === MoveEffectTrigger.POST_APPLY && !(attr as MoveEffectAttr).selfTarget && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit), user, target, this.move.getMove()).then(() => { + /** + * If the move hit, and the target doesn't have Shield Dust, + * apply the chance to flinch the target gained from King's Rock + */ if (dealsDamage && !target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr)) { const flinched = new Utils.BooleanHolder(false); user.scene.applyModifiers(FlinchChanceModifier, user.isPlayer(), user, flinched); @@ -3091,14 +3180,23 @@ export class MoveEffectPhase extends PokemonPhase { target.addTag(BattlerTagType.FLINCHED, undefined, this.move.moveId, user.id); } } + // If the move was not protected against, apply all HIT effects Utils.executeIf(!isProtected && !chargeEffect, () => applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && (attr as MoveEffectAttr).trigger === MoveEffectTrigger.HIT && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit) && (!attr.firstTargetOnly || firstTarget), user, target, this.move.getMove()).then(() => { + // Apply the target's post-defend ability effects (as long as the target is active or can otherwise apply them) return Utils.executeIf(!target.isFainted() || target.canApplyAbility(), () => applyPostDefendAbAttrs(PostDefendAbAttr, target, user, this.move.getMove(), hitResult).then(() => { + // If the invoked move is an enemy attack, apply the enemy's status effect-inflicting tags and tokens + target.lapseTag(BattlerTagType.BEAK_BLAST_CHARGING); if (!user.isPlayer() && this.move.getMove() instanceof AttackMove) { user.scene.applyShuffledModifiers(this.scene, EnemyAttackStatusEffectChanceModifier, false, target); } })).then(() => { + // Apply the user's post-attack ability effects applyPostAttackAbAttrs(PostAttackAbAttr, user, target, this.move.getMove(), hitResult).then(() => { + /** + * If the invoked move is an attack, apply the user's chance to + * steal an item from the target granted by Grip Claw + */ if (this.move.getMove() instanceof AttackMove) { this.scene.applyModifiers(ContactHeldItemTransferChanceModifier, this.player, user, target); } @@ -3118,7 +3216,7 @@ export class MoveEffectPhase extends PokemonPhase { }); })); } - // Trigger effect which should only apply one time on the last hit after all targeted effects have already applied + // Apply the move's POST_TARGET effects on the move's last hit, after all targeted effects have resolved const postTarget = (user.turnData.hitsLeft === 1 || !this.getTarget()?.isActive()) ? applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.POST_TARGET, user, null, move) : null; @@ -3131,6 +3229,7 @@ export class MoveEffectPhase extends PokemonPhase { } } + // Wait for all move effects to finish applying, then end this phase Promise.allSettled(applyAttrs).then(() => this.end()); }); }); @@ -3140,6 +3239,13 @@ export class MoveEffectPhase extends PokemonPhase { const move = this.move.getMove(); move.type = move.defaultType; const user = this.getUserPokemon(); + /** + * If this phase isn't for the invoked move's last strike, + * unshift another MoveEffectPhase for the next strike. + * Otherwise, queue a message indicating the number of times the move has struck + * (if the move has struck more than once), then apply the heal from Shell Bell + * to the user. + */ if (user) { if (user.turnData.hitsLeft && --user.turnData.hitsLeft >= 1 && this.getTarget()?.isActive()) { this.scene.unshiftPhase(this.getNewHitPhase()); @@ -3158,6 +3264,11 @@ export class MoveEffectPhase extends PokemonPhase { super.end(); } + /** + * Resolves whether this phase's invoked move hits or misses the given target + * @param target {@linkcode Pokemon} the Pokemon targeted by the invoked move + * @returns `true` if the move does not miss the target; `false` otherwise + */ hitCheck(target: Pokemon): boolean { // Moves targeting the user and entry hazards can't miss if ([MoveTarget.USER, MoveTarget.ENEMY_SIDE].includes(this.move.getMove().moveTarget)) { @@ -3188,8 +3299,8 @@ export class MoveEffectPhase extends PokemonPhase { return true; } - const hiddenTag = target.getTag(SemiInvulnerableTag); - if (hiddenTag && !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === hiddenTag.tagType)) { + const semiInvulnerableTag = target.getTag(SemiInvulnerableTag); + if (semiInvulnerableTag && !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType)) { return false; } @@ -3205,6 +3316,7 @@ export class MoveEffectPhase extends PokemonPhase { return rand <= moveAccuracy * (accuracyMultiplier!); // TODO: is this bang correct? } + /** Returns the {@linkcode Pokemon} using this phase's invoked move */ getUserPokemon(): Pokemon | undefined { if (this.battlerIndex > BattlerIndex.ENEMY_2) { return this.scene.getPokemonById(this.battlerIndex) ?? undefined; @@ -3212,14 +3324,20 @@ export class MoveEffectPhase extends PokemonPhase { return (this.player ? this.scene.getPlayerField() : this.scene.getEnemyField())[this.fieldIndex]; } + /** Returns an array of all {@linkcode Pokemon} targeted by this phase's invoked move */ getTargets(): Pokemon[] { return this.scene.getField(true).filter(p => this.targets.indexOf(p.getBattlerIndex()) > -1); } + /** Returns the first target of this phase's invoked move */ getTarget(): Pokemon | undefined { - return this.getTargets().find(() => true); + return this.getTargets()[0]; } + /** + * Removes the given {@linkcode Pokemon} from this phase's target list + * @param target {@linkcode Pokemon} the Pokemon to be removed + */ removeTarget(target: Pokemon): void { const targetIndex = this.targets.findIndex(ind => ind === target.getBattlerIndex()); if (targetIndex !== -1) { @@ -3227,6 +3345,11 @@ export class MoveEffectPhase extends PokemonPhase { } } + /** + * Prevents subsequent strikes of this phase's invoked move from occurring + * @param target {@linkcode Pokemon} if defined, only stop subsequent + * strikes against this Pokemon + */ stopMultiHit(target?: Pokemon): void { /** If given a specific target, remove the target from subsequent strikes */ if (target) { @@ -3242,6 +3365,7 @@ export class MoveEffectPhase extends PokemonPhase { } } + /** Returns a new MoveEffectPhase with the same properties as this phase */ getNewHitPhase() { return new MoveEffectPhase(this.scene, this.battlerIndex, this.targets, this.move); } diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts index 82cde7cd2ad..33f00d22555 100644 --- a/src/plugins/i18n.ts +++ b/src/plugins/i18n.ts @@ -2,7 +2,7 @@ import i18next from "i18next"; import LanguageDetector from "i18next-browser-languagedetector"; import processor, { KoreanPostpositionProcessor } from "i18next-korean-postposition-processor"; -import { caESConfig} from "#app/locales/ca-ES/config.js"; +import { caESConfig} from "#app/locales/ca_ES/config.js"; import { deConfig } from "#app/locales/de/config.js"; import { enConfig } from "#app/locales/en/config.js"; import { esConfig } from "#app/locales/es/config.js"; diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 8b756735ee6..d64aa8f8e91 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -197,6 +197,9 @@ export interface StarterAttributes { variant?: integer; form?: integer; female?: boolean; + shiny?: boolean; + favorite?: boolean; + nickname?: string; } export interface StarterPreferences { diff --git a/src/test/abilities/gulp_missile.test.ts b/src/test/abilities/gulp_missile.test.ts index b64cbe2ef10..2647f765f6e 100644 --- a/src/test/abilities/gulp_missile.test.ts +++ b/src/test/abilities/gulp_missile.test.ts @@ -1,5 +1,6 @@ import { BattlerTagType } from "#app/enums/battler-tag-type.js"; import { + BerryPhase, MoveEndPhase, TurnEndPhase, TurnStartPhase, @@ -14,7 +15,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite import { SPLASH_ONLY } from "../utils/testUtils"; import { BattleStat } from "#app/data/battle-stat.js"; import { StatusEffect } from "#app/enums/status-effect.js"; -import { GulpMissileTag } from "#app/data/battler-tags.js"; import Pokemon from "#app/field/pokemon.js"; describe("Abilities - Gulp Missile", () => { @@ -84,6 +84,17 @@ describe("Abilities - Gulp Missile", () => { expect(cramorant.formIndex).toBe(GORGING_FORM); }); + it("changes form during Dive's charge turn", async () => { + await game.startBattle([Species.CRAMORANT]); + const cramorant = game.scene.getPlayerPokemon()!; + + game.doAttack(getMovePosition(game.scene, 0, Moves.DIVE)); + await game.phaseInterceptor.to(MoveEndPhase); + + expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); + expect(cramorant.formIndex).toBe(GULPING_FORM); + }); + it("deals ¼ of the attacker's maximum HP when hit by a damaging attack", async () => { game.override.enemyMoveset(Array(4).fill(Moves.TACKLE)); await game.startBattle([Species.CRAMORANT]); @@ -165,29 +176,16 @@ describe("Abilities - Gulp Missile", () => { }); it("does not activate the ability when underwater", async () => { - game.override - .enemyMoveset(Array(4).fill(Moves.SURF)) - .enemySpecies(Species.REGIELEKI) - .enemyAbility(Abilities.BALL_FETCH) - .enemyLevel(5); + game.override.enemyMoveset(Array(4).fill(Moves.SURF)); await game.startBattle([Species.CRAMORANT]); const cramorant = game.scene.getPlayerPokemon()!; game.doAttack(getMovePosition(game.scene, 0, Moves.DIVE)); - await game.toNextTurn(); + await game.phaseInterceptor.to(BerryPhase, false); - // Turn 2 underwater, enemy moves first - game.doAttack(getMovePosition(game.scene, 0, Moves.DIVE)); - await game.phaseInterceptor.to(MoveEndPhase); - - expect(cramorant.formIndex).toBe(NORMAL_FORM); - expect(cramorant.getTag(GulpMissileTag)).toBeUndefined(); - - // Turn 2 Cramorant comes out and changes form - await game.phaseInterceptor.to(TurnEndPhase); - expect(cramorant.formIndex).not.toBe(NORMAL_FORM); - expect(cramorant.getTag(GulpMissileTag)).toBeDefined(); + expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); + expect(cramorant.formIndex).toBe(GULPING_FORM); }); it("prevents effect damage but inflicts secondary effect on attacker with Magic Guard", async () => { diff --git a/src/test/abilities/hustle.test.ts b/src/test/abilities/hustle.test.ts index 80a71e54d0b..dde310fda2a 100644 --- a/src/test/abilities/hustle.test.ts +++ b/src/test/abilities/hustle.test.ts @@ -8,7 +8,7 @@ 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 { mockHitCheck, SPLASH_ONLY } from "#test/utils/testUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Hustle", () => { let phaserGame: Phaser.Game; @@ -44,7 +44,7 @@ describe("Abilities - Hustle", () => { vi.spyOn(pikachu, "getBattleStat"); game.doAttack(getMovePosition(game.scene, 0, Moves.TACKLE)); - await mockHitCheck(game, true); + await game.move.forceHit(); await game.phaseInterceptor.to(DamagePhase); expect(pikachu.getBattleStat).toHaveReturnedWith(atk * 1.5); diff --git a/src/test/abilities/libero.test.ts b/src/test/abilities/libero.test.ts index 6046df98243..58b4ac639cb 100644 --- a/src/test/abilities/libero.test.ts +++ b/src/test/abilities/libero.test.ts @@ -12,7 +12,7 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import { mockHitCheck, SPLASH_ONLY } from "#test/utils/testUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -192,7 +192,7 @@ describe("Abilities - Protean", () => { expect(leadPokemon).not.toBe(undefined); game.doAttack(getMovePosition(game.scene, 0, Moves.TACKLE)); - await mockHitCheck(game, false); + await game.move.forceMiss(); await game.phaseInterceptor.to(TurnEndPhase); const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/abilities/magic_guard.test.ts b/src/test/abilities/magic_guard.test.ts index f138ef77219..c86d65ca453 100644 --- a/src/test/abilities/magic_guard.test.ts +++ b/src/test/abilities/magic_guard.test.ts @@ -11,7 +11,7 @@ import { Abilities } from "#enums/abilities"; import { WeatherType } from "#app/data/weather.js"; import { StatusEffect, getStatusEffectCatchRateMultiplier } from "#app/data/status-effect"; import { BattlerTagType } from "#enums/battler-tag-type"; -import { mockHitCheck, SPLASH_ONLY } from "#test/utils/testUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; // 20 sec timeout @@ -258,7 +258,7 @@ describe("Abilities - Magic Guard", () => { const leadPokemon = game.scene.getPlayerPokemon()!; game.doAttack(getMovePosition(game.scene, 0, Moves.HIGH_JUMP_KICK)); - await mockHitCheck(game, false); + await game.move.forceMiss(); await game.phaseInterceptor.to(TurnEndPhase); diff --git a/src/test/abilities/parental_bond.test.ts b/src/test/abilities/parental_bond.test.ts index e5f0f969d10..182f780763c 100644 --- a/src/test/abilities/parental_bond.test.ts +++ b/src/test/abilities/parental_bond.test.ts @@ -10,7 +10,7 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import { mockHitCheck, SPLASH_ONLY } from "#test/utils/testUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -129,7 +129,7 @@ describe("Abilities - Parental Bond", () => { expect(enemyPokemon).not.toBe(undefined); game.doAttack(getMovePosition(game.scene, 0, Moves.DOUBLE_HIT)); - await mockHitCheck(game, true); + await game.move.forceHit(); await game.phaseInterceptor.to(BerryPhase, false); @@ -172,7 +172,7 @@ describe("Abilities - Parental Bond", () => { expect(enemyPokemon).not.toBe(undefined); game.doAttack(getMovePosition(game.scene, 0, Moves.ROLLOUT)); - await mockHitCheck(game, true); + await game.move.forceHit(); await game.phaseInterceptor.to(DamagePhase, false); @@ -368,7 +368,7 @@ describe("Abilities - Parental Bond", () => { const enemyStartingHp = enemyPokemon.hp; game.doAttack(getMovePosition(game.scene, 0, Moves.SUPER_FANG)); - await mockHitCheck(game, true); + await game.move.forceHit(); await game.phaseInterceptor.to(DamagePhase); @@ -397,7 +397,7 @@ describe("Abilities - Parental Bond", () => { const enemyStartingHp = enemyPokemon.hp; game.doAttack(getMovePosition(game.scene, 0, Moves.SEISMIC_TOSS)); - await mockHitCheck(game, true); + await game.move.forceHit(); await game.phaseInterceptor.to(DamagePhase); @@ -423,7 +423,7 @@ describe("Abilities - Parental Bond", () => { expect(enemyPokemon).not.toBe(undefined); game.doAttack(getMovePosition(game.scene, 0, Moves.HYPER_BEAM)); - await mockHitCheck(game, true); + await game.move.forceHit(); await game.phaseInterceptor.to(DamagePhase); @@ -451,7 +451,7 @@ describe("Abilities - Parental Bond", () => { expect(enemyPokemon).not.toBe(undefined); game.doAttack(getMovePosition(game.scene, 0, Moves.ANCHOR_SHOT)); - await mockHitCheck(game, true); + await game.move.forceHit(); await game.phaseInterceptor.to(DamagePhase); @@ -481,7 +481,7 @@ describe("Abilities - Parental Bond", () => { expect(enemyPokemon).not.toBe(undefined); game.doAttack(getMovePosition(game.scene, 0, Moves.SMACK_DOWN)); - await mockHitCheck(game, true); + await game.move.forceHit(); await game.phaseInterceptor.to(DamagePhase); @@ -508,7 +508,7 @@ describe("Abilities - Parental Bond", () => { expect(enemyPokemon).not.toBe(undefined); game.doAttack(getMovePosition(game.scene, 0, Moves.U_TURN)); - await mockHitCheck(game, true); + await game.move.forceHit(); await game.phaseInterceptor.to(MoveEffectPhase); expect(leadPokemon.turnData.hitCount).toBe(2); @@ -532,7 +532,7 @@ describe("Abilities - Parental Bond", () => { expect(enemyPokemon).not.toBe(undefined); game.doAttack(getMovePosition(game.scene, 0, Moves.WAKE_UP_SLAP)); - await mockHitCheck(game, true); + await game.move.forceHit(); await game.phaseInterceptor.to(DamagePhase); diff --git a/src/test/abilities/protean.test.ts b/src/test/abilities/protean.test.ts index 8022f73255f..78768ce32db 100644 --- a/src/test/abilities/protean.test.ts +++ b/src/test/abilities/protean.test.ts @@ -12,7 +12,7 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import { mockHitCheck, SPLASH_ONLY } from "#test/utils/testUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -192,7 +192,7 @@ describe("Abilities - Protean", () => { expect(leadPokemon).not.toBe(undefined); game.doAttack(getMovePosition(game.scene, 0, Moves.TACKLE)); - await mockHitCheck(game, false); + await game.move.forceMiss(); await game.phaseInterceptor.to(TurnEndPhase); const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/abilities/serene_grace.test.ts b/src/test/abilities/serene_grace.test.ts index 59e9ff723da..d46587e45c7 100644 --- a/src/test/abilities/serene_grace.test.ts +++ b/src/test/abilities/serene_grace.test.ts @@ -11,7 +11,6 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; -import { mockTurnOrder } from "../utils/testUtils"; import { BattlerIndex } from "#app/battle.js"; @@ -57,7 +56,7 @@ describe("Abilities - Serene Grace", () => { (game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); - await mockTurnOrder(game, [BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to(MoveEffectPhase, false); // Check chance of Air Slash without Serene Grace @@ -90,7 +89,7 @@ describe("Abilities - Serene Grace", () => { (game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); - await mockTurnOrder(game, [BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to(MoveEffectPhase, false); // Check chance of Air Slash with Serene Grace diff --git a/src/test/abilities/sheer_force.test.ts b/src/test/abilities/sheer_force.test.ts index 35353bc7000..50a0f0b63fb 100644 --- a/src/test/abilities/sheer_force.test.ts +++ b/src/test/abilities/sheer_force.test.ts @@ -11,7 +11,6 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; -import { mockTurnOrder } from "../utils/testUtils"; import { BattlerIndex } from "#app/battle.js"; @@ -58,7 +57,7 @@ describe("Abilities - Sheer Force", () => { (game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); - await mockTurnOrder(game, [BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to(MoveEffectPhase, false); const phase = game.scene.getCurrentPhase() as MoveEffectPhase; @@ -97,7 +96,7 @@ describe("Abilities - Sheer Force", () => { (game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); - await mockTurnOrder(game, [BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to(MoveEffectPhase, false); const phase = game.scene.getCurrentPhase() as MoveEffectPhase; @@ -136,7 +135,7 @@ describe("Abilities - Sheer Force", () => { (game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); - await mockTurnOrder(game, [BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to(MoveEffectPhase, false); const phase = game.scene.getCurrentPhase() as MoveEffectPhase; @@ -177,7 +176,7 @@ describe("Abilities - Sheer Force", () => { (game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); - await mockTurnOrder(game, [BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to(MoveEffectPhase, false); const phase = game.scene.getCurrentPhase() as MoveEffectPhase; diff --git a/src/test/abilities/shield_dust.test.ts b/src/test/abilities/shield_dust.test.ts index ded70eccb36..f1534551e92 100644 --- a/src/test/abilities/shield_dust.test.ts +++ b/src/test/abilities/shield_dust.test.ts @@ -12,7 +12,6 @@ import { Species } from "#enums/species"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { BattlerIndex } from "#app/battle.js"; -import { mockTurnOrder } from "../utils/testUtils"; describe("Abilities - Shield Dust", () => { @@ -58,7 +57,7 @@ describe("Abilities - Shield Dust", () => { (game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); - await mockTurnOrder(game, [BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to(MoveEffectPhase, false); // Shield Dust negates secondary effect diff --git a/src/test/abilities/sweet_veil.test.ts b/src/test/abilities/sweet_veil.test.ts index 5af822da061..d650455664f 100644 --- a/src/test/abilities/sweet_veil.test.ts +++ b/src/test/abilities/sweet_veil.test.ts @@ -8,7 +8,7 @@ import { getMovePosition } from "#test/utils/gameManagerUtils"; import { BattlerTagType } from "#app/enums/battler-tag-type.js"; import { Abilities } from "#app/enums/abilities.js"; import { BattlerIndex } from "#app/battle.js"; -import { mockHitCheck, SPLASH_ONLY } from "#test/utils/testUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Sweet Veil", () => { let phaserGame: Phaser.Game; @@ -80,11 +80,11 @@ describe("Abilities - Sweet Veil", () => { game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); // First pokemon move - await mockHitCheck(game, true); + await game.move.forceHit(); // Second pokemon move await game.phaseInterceptor.to(MovePhase, false); - await mockHitCheck(game, true); + await game.move.forceHit(); expect(game.scene.getPlayerField().some(p => !!p.getTag(BattlerTagType.DROWSY))).toBe(true); diff --git a/src/test/abilities/zen_mode.test.ts b/src/test/abilities/zen_mode.test.ts index fc0bf282078..1bc7a6af4ce 100644 --- a/src/test/abilities/zen_mode.test.ts +++ b/src/test/abilities/zen_mode.test.ts @@ -12,7 +12,6 @@ import { Species } from "#enums/species"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { BattlerIndex } from "#app/battle.js"; -import { mockTurnOrder } from "../utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -58,7 +57,8 @@ describe("Abilities - ZEN MODE", () => { const movePosition = getMovePosition(game.scene, 0, moveToUse); (game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); - await mockTurnOrder(game, [BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.phaseInterceptor.to(DamagePhase, false); // await game.phaseInterceptor.runFrom(DamagePhase).to(DamagePhase, false); const damagePhase = game.scene.getCurrentPhase() as DamagePhase; @@ -86,7 +86,8 @@ describe("Abilities - ZEN MODE", () => { const movePosition = getMovePosition(game.scene, 0, moveToUse); (game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); - await mockTurnOrder(game, [BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.phaseInterceptor.to(QuietFormChangePhase); await game.phaseInterceptor.to(TurnInitPhase, false); expect(game.scene.getParty()[0].hp).not.toBe(100); @@ -111,7 +112,8 @@ describe("Abilities - ZEN MODE", () => { const movePosition = getMovePosition(game.scene, 0, moveToUse); (game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false); }); - await mockTurnOrder(game, [BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.phaseInterceptor.to(DamagePhase, false); // await game.phaseInterceptor.runFrom(DamagePhase).to(DamagePhase, false); const damagePhase = game.scene.getCurrentPhase() as DamagePhase; diff --git a/src/test/final_boss.test.ts b/src/test/final_boss.test.ts index c087bd5ba82..3e1225295e0 100644 --- a/src/test/final_boss.test.ts +++ b/src/test/final_boss.test.ts @@ -56,6 +56,14 @@ describe("Final Boss", () => { expect(game.scene.getEnemyPokemon()!.species.speciesId).not.toBe(Species.ETERNATUS); }); + it("should not have passive enabled on Eternatus", async () => { + await runToFinalBossEncounter(game, [Species.BIDOOF]); + + const eternatus = game.scene.getEnemyPokemon(); + expect(eternatus?.species.speciesId).toBe(Species.ETERNATUS); + expect(eternatus?.hasPassive()).toBe(false); + }); + it.todo("should change form on direct hit down to last boss fragment", () => {}); }); diff --git a/src/test/items/leek.test.ts b/src/test/items/leek.test.ts index 7ac453f797a..4abc470c6f0 100644 --- a/src/test/items/leek.test.ts +++ b/src/test/items/leek.test.ts @@ -8,7 +8,6 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import Phase from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { mockTurnOrder } from "#test/utils/testUtils"; describe("Items - Leek", () => { let phaserGame: Phaser.Game; @@ -44,7 +43,7 @@ describe("Items - Leek", () => { game.doAttack(0); - await mockTurnOrder(game, [BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to(MoveEffectPhase); diff --git a/src/test/items/scope_lens.test.ts b/src/test/items/scope_lens.test.ts index 7e5c57c1364..4efc7ab9d05 100644 --- a/src/test/items/scope_lens.test.ts +++ b/src/test/items/scope_lens.test.ts @@ -8,7 +8,6 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import Phase from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { mockTurnOrder } from "#test/utils/testUtils"; describe("Items - Scope Lens", () => { let phaserGame: Phaser.Game; @@ -43,7 +42,8 @@ describe("Items - Scope Lens", () => { ]); game.doAttack(0); - await mockTurnOrder(game, [ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); diff --git a/src/test/moves/beak_blast.test.ts b/src/test/moves/beak_blast.test.ts new file mode 100644 index 00000000000..61a022ac9eb --- /dev/null +++ b/src/test/moves/beak_blast.test.ts @@ -0,0 +1,135 @@ +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import GameManager from "#test/utils/gameManager"; +import { Species } from "#enums/species"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { BerryPhase, MovePhase, TurnEndPhase } from "#app/phases"; +import { BattlerTagType } from "#app/enums/battler-tag-type.js"; +import { StatusEffect } from "#app/enums/status-effect.js"; + +const TIMEOUT = 20 * 1000; + +describe("Moves - Beak Blast", () => { + 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") + .ability(Abilities.UNNERVE) + .moveset([Moves.BEAK_BLAST]) + .enemySpecies(Species.SNORLAX) + .enemyAbility(Abilities.INSOMNIA) + .enemyMoveset(Array(4).fill(Moves.TACKLE)) + .startingLevel(100) + .enemyLevel(100); + }); + + it( + "should add a charge effect that burns attackers on contact", + async () => { + await game.startBattle([Species.BLASTOISE]); + + const leadPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.doAttack(getMovePosition(game.scene, 0, Moves.BEAK_BLAST)); + + await game.phaseInterceptor.to(MovePhase, false); + expect(leadPokemon.getTag(BattlerTagType.BEAK_BLAST_CHARGING)).toBeDefined(); + + await game.phaseInterceptor.to(BerryPhase, false); + expect(enemyPokemon.status?.effect).toBe(StatusEffect.BURN); + }, TIMEOUT + ); + + it( + "should still charge and burn opponents if the user is sleeping", + async () => { + game.override.statusEffect(StatusEffect.SLEEP); + + await game.startBattle([Species.BLASTOISE]); + + const leadPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.doAttack(getMovePosition(game.scene, 0, Moves.BEAK_BLAST)); + + await game.phaseInterceptor.to(MovePhase, false); + expect(leadPokemon.getTag(BattlerTagType.BEAK_BLAST_CHARGING)).toBeDefined(); + + await game.phaseInterceptor.to(BerryPhase, false); + expect(enemyPokemon.status?.effect).toBe(StatusEffect.BURN); + }, TIMEOUT + ); + + it( + "should not burn attackers that don't make contact", + async () => { + game.override.enemyMoveset(Array(4).fill(Moves.WATER_GUN)); + + await game.startBattle([Species.BLASTOISE]); + + const leadPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.doAttack(getMovePosition(game.scene, 0, Moves.BEAK_BLAST)); + + await game.phaseInterceptor.to(MovePhase, false); + expect(leadPokemon.getTag(BattlerTagType.BEAK_BLAST_CHARGING)).toBeDefined(); + + await game.phaseInterceptor.to(BerryPhase, false); + expect(enemyPokemon.status?.effect).not.toBe(StatusEffect.BURN); + }, TIMEOUT + ); + + it( + "should only hit twice with Multi-Lens", + async () => { + game.override.startingHeldItems([{name: "MULTI_LENS", count: 1}]); + + await game.startBattle([Species.BLASTOISE]); + + const leadPokemon = game.scene.getPlayerPokemon()!; + + game.doAttack(getMovePosition(game.scene, 0, Moves.BEAK_BLAST)); + + await game.phaseInterceptor.to(BerryPhase, false); + expect(leadPokemon.turnData.hitCount).toBe(2); + }, TIMEOUT + ); + + it( + "should be blocked by Protect", + async () => { + game.override.enemyMoveset(Array(4).fill(Moves.PROTECT)); + + await game.startBattle([Species.BLASTOISE]); + + const leadPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.doAttack(getMovePosition(game.scene, 0, Moves.BEAK_BLAST)); + + await game.phaseInterceptor.to(MovePhase, false); + expect(leadPokemon.getTag(BattlerTagType.BEAK_BLAST_CHARGING)).toBeDefined(); + + await game.phaseInterceptor.to(TurnEndPhase); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(leadPokemon.getTag(BattlerTagType.BEAK_BLAST_CHARGING)).toBeUndefined(); + }, TIMEOUT + ); +}); diff --git a/src/test/moves/freezy_frost.test.ts b/src/test/moves/freezy_frost.test.ts new file mode 100644 index 00000000000..3ccd31bd29e --- /dev/null +++ b/src/test/moves/freezy_frost.test.ts @@ -0,0 +1,82 @@ +import { BattleStat } from "#app/data/battle-stat"; +import { MoveEndPhase, TurnInitPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +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 { allMoves } from "#app/data/move.js"; + +describe("Moves - Freezy Frost", () => { + describe("integration tests", () => { + 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"); + + game.override.enemySpecies(Species.RATTATA); + game.override.enemyLevel(100); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.NONE); + + game.override.startingLevel(100); + game.override.moveset([Moves.FREEZY_FROST, Moves.SWORDS_DANCE, Moves.CHARM, Moves.SPLASH]); + vi.spyOn(allMoves[Moves.FREEZY_FROST], "accuracy", "get").mockReturnValue(100); + game.override.ability(Abilities.NONE); + }); + + it("Uses Swords Dance to raise own ATK by 2, Charm to lower enemy ATK by 2, player uses Freezy Frost to clear all stat changes", { timeout: 10000 }, async () => { + await game.startBattle([Species.RATTATA]); + const user = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + expect(user.summonData.battleStats[BattleStat.ATK]).toBe(0); + expect(enemy.summonData.battleStats[BattleStat.ATK]).toBe(0); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SWORDS_DANCE)); + await game.phaseInterceptor.to(TurnInitPhase); + + game.doAttack(getMovePosition(game.scene, 0, Moves.CHARM)); + await game.phaseInterceptor.to(TurnInitPhase); + const userAtkBefore = user.summonData.battleStats[BattleStat.ATK]; + const enemyAtkBefore = enemy.summonData.battleStats[BattleStat.ATK]; + expect(userAtkBefore).toBe(2); + expect(enemyAtkBefore).toBe(-2); + + game.doAttack(getMovePosition(game.scene, 0, Moves.FREEZY_FROST)); + await game.phaseInterceptor.to(TurnInitPhase); + expect(user.summonData.battleStats[BattleStat.ATK]).toBe(0); + expect(enemy.summonData.battleStats[BattleStat.ATK]).toBe(0); + }); + + it("Uses Swords Dance to raise own ATK by 2, Charm to lower enemy ATK by 2, enemy uses Freezy Frost to clear all stat changes", { timeout: 10000 }, async () => { + game.override.enemyMoveset([Moves.FREEZY_FROST, Moves.FREEZY_FROST, Moves.FREEZY_FROST, Moves.FREEZY_FROST]); + await game.startBattle([Species.SHUCKLE]); // Shuckle for slower Swords Dance on first turn so Freezy Frost doesn't affect it. + const user = game.scene.getPlayerPokemon()!; + expect(user.summonData.battleStats[BattleStat.ATK]).toBe(0); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SWORDS_DANCE)); + await game.phaseInterceptor.to(TurnInitPhase); + + const userAtkBefore = user.summonData.battleStats[BattleStat.ATK]; + expect(userAtkBefore).toBe(2); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + await game.phaseInterceptor.to(MoveEndPhase); + expect(user.summonData.battleStats[BattleStat.ATK]).toBe(0); + }); + }); +}); diff --git a/src/test/moves/fusion_flare_bolt.test.ts b/src/test/moves/fusion_flare_bolt.test.ts index 95090214962..c2214d5442b 100644 --- a/src/test/moves/fusion_flare_bolt.test.ts +++ b/src/test/moves/fusion_flare_bolt.test.ts @@ -8,7 +8,6 @@ import { allMoves } from "#app/data/move"; import { BattlerIndex } from "#app/battle"; import { Species } from "#enums/species"; import { Moves } from "#enums/moves"; -import { mockTurnOrder } from "#test/utils/testUtils"; describe("Moves - Fusion Flare and Fusion Bolt", () => { let phaserGame: Phaser.Game; @@ -56,7 +55,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.doSelectTarget(BattlerIndex.ENEMY); // Force user party to act before enemy party - await mockTurnOrder(game, [ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); @@ -82,7 +81,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.doSelectTarget(BattlerIndex.ENEMY); // Force user party to act before enemy party - await mockTurnOrder(game, [ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); @@ -108,7 +107,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.doSelectTarget(0); // Force first enemy to act (and fail) in between party - await mockTurnOrder(game, [ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); @@ -140,7 +139,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.doSelectTarget(BattlerIndex.ENEMY); // Force first enemy to act in between party - await mockTurnOrder(game, [ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); @@ -170,7 +169,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.doSelectTarget(BattlerIndex.PLAYER); // Force user party to act before enemy party - await mockTurnOrder(game, [ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); @@ -222,7 +221,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.doSelectTarget(BattlerIndex.ENEMY); // Force first enemy to act in between party - await mockTurnOrder(game, [ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); @@ -284,7 +283,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.doSelectTarget(BattlerIndex.PLAYER); // Force first enemy to act in between party - await mockTurnOrder(game, [ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); diff --git a/src/test/moves/gastro_acid.test.ts b/src/test/moves/gastro_acid.test.ts index 8c5f5f14eac..cc247890754 100644 --- a/src/test/moves/gastro_acid.test.ts +++ b/src/test/moves/gastro_acid.test.ts @@ -6,7 +6,7 @@ import { MoveResult } from "#app/field/pokemon.js"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import { mockTurnOrder, SPLASH_ONLY } from "#test/utils/testUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -75,7 +75,7 @@ describe("Moves - Gastro Acid", () => { game.doAttack(getMovePosition(game.scene, 0, Moves.CORE_ENFORCER)); // Force player to be slower to enable Core Enforcer to proc its suppression effect - await mockTurnOrder(game, [BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.phaseInterceptor.to("TurnInitPhase"); diff --git a/src/test/moves/haze.test.ts b/src/test/moves/haze.test.ts new file mode 100644 index 00000000000..092575b8000 --- /dev/null +++ b/src/test/moves/haze.test.ts @@ -0,0 +1,80 @@ +import { BattleStat } from "#app/data/battle-stat"; +import { MoveEndPhase, TurnInitPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; + +describe("Moves - Haze", () => { + describe("integration tests", () => { + 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"); + + game.override.enemySpecies(Species.RATTATA); + game.override.enemyLevel(100); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.NONE); + + game.override.startingLevel(100); + game.override.moveset([Moves.HAZE, Moves.SWORDS_DANCE, Moves.CHARM, Moves.SPLASH]); + game.override.ability(Abilities.NONE); + }); + + it("Uses Swords Dance to raise own ATK by 2, Charm to lower enemy ATK by 2, player uses Haze to clear all stat changes", { timeout: 10000 }, async () => { + await game.startBattle([Species.RATTATA]); + const user = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + expect(user.summonData.battleStats[BattleStat.ATK]).toBe(0); + expect(enemy.summonData.battleStats[BattleStat.ATK]).toBe(0); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SWORDS_DANCE)); + await game.phaseInterceptor.to(TurnInitPhase); + + game.doAttack(getMovePosition(game.scene, 0, Moves.CHARM)); + await game.phaseInterceptor.to(TurnInitPhase); + const userAtkBefore = user.summonData.battleStats[BattleStat.ATK]; + const enemyAtkBefore = enemy.summonData.battleStats[BattleStat.ATK]; + expect(userAtkBefore).toBe(2); + expect(enemyAtkBefore).toBe(-2); + + game.doAttack(getMovePosition(game.scene, 0, Moves.HAZE)); + await game.phaseInterceptor.to(TurnInitPhase); + expect(user.summonData.battleStats[BattleStat.ATK]).toBe(0); + expect(enemy.summonData.battleStats[BattleStat.ATK]).toBe(0); + }); + + it("Uses Swords Dance to raise own ATK by 2, Charm to lower enemy ATK by 2, enemy uses Haze to clear all stat changes", { timeout: 10000 }, async () => { + game.override.enemyMoveset([Moves.HAZE, Moves.HAZE, Moves.HAZE, Moves.HAZE]); + await game.startBattle([Species.SHUCKLE]); // Shuckle for slower Swords Dance on first turn so Haze doesn't affect it. + const user = game.scene.getPlayerPokemon()!; + expect(user.summonData.battleStats[BattleStat.ATK]).toBe(0); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SWORDS_DANCE)); + await game.phaseInterceptor.to(TurnInitPhase); + + const userAtkBefore = user.summonData.battleStats[BattleStat.ATK]; + expect(userAtkBefore).toBe(2); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + await game.phaseInterceptor.to(MoveEndPhase); + expect(user.summonData.battleStats[BattleStat.ATK]).toBe(0); + }); + }); +}); diff --git a/src/test/moves/hyper_beam.test.ts b/src/test/moves/hyper_beam.test.ts index 369d4cac853..f33ce4f5478 100644 --- a/src/test/moves/hyper_beam.test.ts +++ b/src/test/moves/hyper_beam.test.ts @@ -33,6 +33,7 @@ describe("Moves - Hyper Beam", () => { game.override.enemySpecies(Species.SNORLAX); game.override.enemyAbility(Abilities.BALL_FETCH); game.override.enemyMoveset(Array(4).fill(Moves.SPLASH)); + game.override.enemyLevel(100); game.override.moveset([Moves.HYPER_BEAM, Moves.TACKLE]); vi.spyOn(allMoves[Moves.HYPER_BEAM], "accuracy", "get").mockReturnValue(100); diff --git a/src/test/moves/make_it_rain.test.ts b/src/test/moves/make_it_rain.test.ts index 72386930873..a4440401c4b 100644 --- a/src/test/moves/make_it_rain.test.ts +++ b/src/test/moves/make_it_rain.test.ts @@ -1,12 +1,12 @@ import { BattleStat } from "#app/data/battle-stat.js"; -import { MoveEffectPhase, MoveEndPhase, StatChangePhase } from "#app/phases"; +import { MoveEndPhase, StatChangePhase } from "#app/phases"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; 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 { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -91,11 +91,8 @@ describe("Moves - Make It Rain", () => { game.doAttack(getMovePosition(game.scene, 0, Moves.MAKE_IT_RAIN)); game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); - await game.phaseInterceptor.to(MoveEffectPhase, false); - // Make Make It Rain miss the first target - const moveEffectPhase = game.scene.getCurrentPhase() as MoveEffectPhase; - vi.spyOn(moveEffectPhase, "hitCheck").mockReturnValueOnce(false); + await game.move.forceMiss(true); await game.phaseInterceptor.to(MoveEndPhase); diff --git a/src/test/moves/miracle_eye.test.ts b/src/test/moves/miracle_eye.test.ts index 53d575ea96d..67d4d695b62 100644 --- a/src/test/moves/miracle_eye.test.ts +++ b/src/test/moves/miracle_eye.test.ts @@ -6,6 +6,7 @@ import { SPLASH_ONLY } from "../utils/testUtils"; import { Moves } from "#app/enums/moves.js"; import { getMovePosition } from "../utils/gameManagerUtils"; import { MoveEffectPhase } from "#app/phases.js"; +import { BattlerIndex } from "#app/battle.js"; describe("Internals", () => { let phaserGame: Phaser.Game; @@ -38,6 +39,7 @@ describe("Internals", () => { const enemy = game.scene.getEnemyPokemon()!; game.doAttack(getMovePosition(game.scene, 0, Moves.CONFUSION)); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.toNextTurn(); expect(enemy.hp).toBe(enemy.getMaxHp()); diff --git a/src/test/moves/purify.test.ts b/src/test/moves/purify.test.ts index 0367cc5a9b2..7959927d63f 100644 --- a/src/test/moves/purify.test.ts +++ b/src/test/moves/purify.test.ts @@ -7,6 +7,7 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; +import { BattlerIndex } from "#app/battle.js"; const TIMEOUT = 20 * 1000; @@ -49,6 +50,7 @@ describe("Moves - Purify", () => { enemyPokemon.status = new Status(StatusEffect.BURN); game.doAttack(getMovePosition(game.scene, 0, Moves.PURIFY)); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to(MoveEndPhase); expect(enemyPokemon.status).toBeNull(); @@ -68,6 +70,7 @@ describe("Moves - Purify", () => { const playerInitialHp = playerPokemon.hp; game.doAttack(getMovePosition(game.scene, 0, Moves.PURIFY)); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to(MoveEndPhase); expect(playerPokemon.hp).toBe(playerInitialHp); diff --git a/src/test/ui/starter-select.test.ts b/src/test/ui/starter-select.test.ts index b61338bfcad..020b26b7f66 100644 --- a/src/test/ui/starter-select.test.ts +++ b/src/test/ui/starter-select.test.ts @@ -51,6 +51,9 @@ describe("UI - Starter select", () => { const handler = game.scene.ui.getHandler() as StarterSelectUiHandler; handler.processInput(Button.RIGHT); handler.processInput(Button.LEFT); + handler.processInput(Button.CYCLE_SHINY); + handler.processInput(Button.V); + handler.processInput(Button.V); handler.processInput(Button.ACTION); game.phaseInterceptor.unlock(); }); @@ -112,6 +115,9 @@ describe("UI - Starter select", () => { handler.processInput(Button.RIGHT); handler.processInput(Button.LEFT); handler.processInput(Button.CYCLE_GENDER); + handler.processInput(Button.CYCLE_SHINY); + handler.processInput(Button.V); + handler.processInput(Button.V); handler.processInput(Button.ACTION); game.phaseInterceptor.unlock(); }); @@ -176,6 +182,9 @@ describe("UI - Starter select", () => { handler.processInput(Button.CYCLE_GENDER); handler.processInput(Button.CYCLE_NATURE); handler.processInput(Button.CYCLE_ABILITY); + handler.processInput(Button.CYCLE_SHINY); + handler.processInput(Button.V); + handler.processInput(Button.V); handler.processInput(Button.ACTION); game.phaseInterceptor.unlock(); }); @@ -238,6 +247,9 @@ describe("UI - Starter select", () => { handler.processInput(Button.RIGHT); handler.processInput(Button.LEFT); handler.processInput(Button.CYCLE_GENDER); + handler.processInput(Button.CYCLE_SHINY); + handler.processInput(Button.V); + handler.processInput(Button.V); handler.processInput(Button.ACTION); game.phaseInterceptor.unlock(); }); @@ -298,7 +310,6 @@ describe("UI - Starter select", () => { const handler = game.scene.ui.getHandler() as StarterSelectUiHandler; handler.processInput(Button.RIGHT); handler.processInput(Button.LEFT); - handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.ACTION); game.phaseInterceptor.unlock(); }); @@ -358,7 +369,7 @@ describe("UI - Starter select", () => { const handler = game.scene.ui.getHandler() as StarterSelectUiHandler; handler.processInput(Button.RIGHT); handler.processInput(Button.LEFT); - handler.processInput(Button.V); + handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.V); handler.processInput(Button.ACTION); game.phaseInterceptor.unlock(); @@ -419,7 +430,7 @@ describe("UI - Starter select", () => { const handler = game.scene.ui.getHandler() as StarterSelectUiHandler; handler.processInput(Button.RIGHT); handler.processInput(Button.LEFT); - handler.processInput(Button.V); + handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.V); handler.processInput(Button.V); handler.processInput(Button.ACTION); diff --git a/src/test/utils/gameManager.ts b/src/test/utils/gameManager.ts index 771ab1e7081..c782c613bb0 100644 --- a/src/test/utils/gameManager.ts +++ b/src/test/utils/gameManager.ts @@ -28,6 +28,8 @@ import { ModifierTypeOption, modifierTypes } from "#app/modifier/modifier-type.j import overrides from "#app/overrides.js"; import { removeEnemyHeldItems } from "./testUtils"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler.js"; +import { MoveHelper } from "./moveHelper"; +import { vi } from "vitest"; /** * Class to manage the game state and transitions between phases. @@ -39,6 +41,7 @@ export default class GameManager { public textInterceptor: TextInterceptor; public inputsHandler: InputsHandler; public readonly override: OverridesHelper; + public readonly move: MoveHelper; /** * Creates an instance of GameManager. @@ -55,6 +58,7 @@ export default class GameManager { this.textInterceptor = new TextInterceptor(this.scene); this.gameWrapper.setScene(this.scene); this.override = new OverridesHelper(this); + this.move = new MoveHelper(this); } /** @@ -354,4 +358,19 @@ export default class GameManager { partyHandler.processInput(Button.ACTION); // send out (or whatever option is at the top) }); } + + /** + * Intercepts `TurnStartPhase` and mocks the getOrder's return value {@linkcode TurnStartPhase.getOrder} + * Used to modify the turn order. + * @param {BattlerIndex[]} order The turn order to set + * @example + * ```ts + * await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2]); + * ``` + */ + async setTurnOrder(order: BattlerIndex[]): Promise { + await this.phaseInterceptor.to(TurnStartPhase, false); + + vi.spyOn(this.scene.getCurrentPhase() as TurnStartPhase, "getOrder").mockReturnValue(order); + } } diff --git a/src/test/utils/gameManagerHelper.ts b/src/test/utils/gameManagerHelper.ts new file mode 100644 index 00000000000..2caa94ae5ed --- /dev/null +++ b/src/test/utils/gameManagerHelper.ts @@ -0,0 +1,12 @@ +import GameManager from "./gameManager"; + +/** + * Base class for defining all game helpers. + */ +export abstract class GameManagerHelper { + protected readonly game: GameManager; + + constructor(game: GameManager) { + this.game = game; + } +} diff --git a/src/test/utils/gameWrapper.ts b/src/test/utils/gameWrapper.ts index 7edb69aef8a..80529e47194 100644 --- a/src/test/utils/gameWrapper.ts +++ b/src/test/utils/gameWrapper.ts @@ -242,6 +242,7 @@ function createFetchResponse(data) { return { ok: true, status: 200, + headers: new Headers(), json: () => Promise.resolve(data), text: () => Promise.resolve(JSON.stringify(data)), }; @@ -251,6 +252,7 @@ function createFetchBadResponse(data) { return { ok: false, status: 404, + headers: new Headers(), json: () => Promise.resolve(data), text: () => Promise.resolve(JSON.stringify(data)), }; diff --git a/src/test/utils/mocks/mockFetch.ts b/src/test/utils/mocks/mockFetch.ts index ad364a95885..8043dd993fe 100644 --- a/src/test/utils/mocks/mockFetch.ts +++ b/src/test/utils/mocks/mockFetch.ts @@ -23,10 +23,13 @@ export const MockFetch = (input, init) => { } } - return Promise.resolve({ + const response: Partial = { ok: true, status: 200, json: responseHandler, text: responseText, - }); + headers: new Headers({}), + }; + + return Promise.resolve(response); }; diff --git a/src/test/utils/moveHelper.ts b/src/test/utils/moveHelper.ts new file mode 100644 index 00000000000..9438952aa92 --- /dev/null +++ b/src/test/utils/moveHelper.ts @@ -0,0 +1,35 @@ +import { vi } from "vitest"; +import { MoveEffectPhase } from "#app/phases.js"; +import { GameManagerHelper } from "./gameManagerHelper"; + +/** + * Helper to handle a Pokemon's move + */ +export class MoveHelper extends GameManagerHelper { + /** + * Intercepts `MoveEffectPhase` and mocks the hitCheck's + * return value to `true` {@linkcode MoveEffectPhase.hitCheck}. + * Used to force a move to hit. + */ + async forceHit(): Promise { + await this.game.phaseInterceptor.to(MoveEffectPhase, false); + vi.spyOn(this.game.scene.getCurrentPhase() as MoveEffectPhase, "hitCheck").mockReturnValue(true); + } + + /** + * Intercepts `MoveEffectPhase` and mocks the hitCheck's + * return value to `false` {@linkcode MoveEffectPhase.hitCheck}. + * Used to force a move to miss. + * @param firstTargetOnly Whether the move should force miss on the first target only, in the case of multi-target moves. + */ + async forceMiss(firstTargetOnly: boolean = false): Promise { + await this.game.phaseInterceptor.to(MoveEffectPhase, false); + const hitCheck = vi.spyOn(this.game.scene.getCurrentPhase() as MoveEffectPhase, "hitCheck"); + + if (firstTargetOnly) { + hitCheck.mockReturnValueOnce(false); + } else { + hitCheck.mockReturnValue(false); + } + } +} diff --git a/src/test/utils/overridesHelper.ts b/src/test/utils/overridesHelper.ts index e77cd49b742..dbcb02825f2 100644 --- a/src/test/utils/overridesHelper.ts +++ b/src/test/utils/overridesHelper.ts @@ -8,19 +8,13 @@ import * as GameMode from "#app/game-mode"; import { GameModes, getGameMode } from "#app/game-mode"; import { ModifierOverride } from "#app/modifier/modifier-type.js"; import Overrides from "#app/overrides"; -import GameManager from "#test/utils/gameManager"; import { vi } from "vitest"; +import { GameManagerHelper } from "./gameManagerHelper"; /** * Helper to handle overrides in tests */ -export class OverridesHelper { - private readonly game: GameManager; - - constructor(game: GameManager) { - this.game = game; - } - +export class OverridesHelper extends GameManagerHelper { /** * Override the starting biome * @warning Any event listeners that are attached to [NewArenaEvent](events\battle-scene.ts) may need to be handled down the line diff --git a/src/test/utils/testUtils.ts b/src/test/utils/testUtils.ts index d5f266cd4ae..d40efbbf016 100644 --- a/src/test/utils/testUtils.ts +++ b/src/test/utils/testUtils.ts @@ -2,8 +2,6 @@ import { Moves } from "#app/enums/moves.js"; import i18next, { type ParseKeys } from "i18next"; import { vi } from "vitest"; import GameManager from "./gameManager"; -import { BattlerIndex } from "#app/battle.js"; -import { MoveEffectPhase, TurnStartPhase } from "#app/phases.js"; /** Ready to use array of Moves.SPLASH x4 */ export const SPLASH_ONLY = [Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]; @@ -38,35 +36,3 @@ export function removeEnemyHeldItems(game: GameManager): void { game.scene.clearEnemyModifiers(); console.log("Enemy held items removed"); } - -/** - * Intercepts `TurnStartPhase` and mocks the getOrder's return value {@linkcode TurnStartPhase.getOrder} - * Used to modify the turn order. - * @param {GameManager} game The GameManager instance - * @param {BattlerIndex[]} order The turn order to set - * @example - * ```ts - * await mockTurnOrder(game, [BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2]); - * ``` - */ -export async function mockTurnOrder(game: GameManager, order: BattlerIndex[]): Promise { - await game.phaseInterceptor.to(TurnStartPhase, false); - - vi.spyOn(game.scene.getCurrentPhase() as TurnStartPhase, "getOrder").mockReturnValue(order); -} - -/** - * Intercepts `MoveEffectPhase` and mocks the hitCheck's return value {@linkcode MoveEffectPhase.hitCheck}. - * Used to force a move to either hit or miss. - * Note that this uses `mockReturnValue()`, meaning it will also apply to a - * succeeding `MoveEffectPhase` immediately following the first one - * (in the case of a multi-target move) - * - * @param {GameManager} game The GameManager instance - * @param shouldHit Whether the move should hit - */ -export async function mockHitCheck(game: GameManager, shouldHit: boolean): Promise { - await game.phaseInterceptor.to(MoveEffectPhase, false); - - vi.spyOn(game.scene.getCurrentPhase() as MoveEffectPhase, "hitCheck").mockReturnValue(shouldHit); -} diff --git a/src/ui-inputs.ts b/src/ui-inputs.ts index 9288fd35892..d514ddb7823 100644 --- a/src/ui-inputs.ts +++ b/src/ui-inputs.ts @@ -79,7 +79,7 @@ export class UiInputs { [Button.ACTION]: () => this.buttonAb(Button.ACTION), [Button.CANCEL]: () => this.buttonAb(Button.CANCEL), [Button.MENU]: () => this.buttonMenu(), - [Button.STATS]: () => this.buttonStats(true), + [Button.STATS]: () => this.buttonGoToFilter(Button.STATS), [Button.CYCLE_SHINY]: () => this.buttonCycleOption(Button.CYCLE_SHINY), [Button.CYCLE_FORM]: () => this.buttonCycleOption(Button.CYCLE_FORM), [Button.CYCLE_GENDER]: () => this.buttonCycleOption(Button.CYCLE_GENDER), @@ -139,6 +139,17 @@ export class UiInputs { p.toggleStats(pressed); } } + + buttonGoToFilter(button: Button): void { + const whitelist = [StarterSelectUiHandler]; + const uiHandler = this.scene.ui?.getHandler(); + if (whitelist.some(handler => uiHandler instanceof handler)) { + this.scene.ui.processInput(button); + } else { + this.buttonStats(true); + } + } + buttonInfo(pressed: boolean = true): void { if (this.scene.showMovesetFlyout ) { for (const p of this.scene.getField().filter(p => p?.isActive(true))) { diff --git a/src/ui/rename-form-ui-handler.ts b/src/ui/rename-form-ui-handler.ts index 2c229442ed1..e3d475742c4 100644 --- a/src/ui/rename-form-ui-handler.ts +++ b/src/ui/rename-form-ui-handler.ts @@ -36,17 +36,13 @@ export default class RenameFormUiHandler extends FormModalUiHandler { show(args: any[]): boolean { if (super.show(args)) { const config = args[0] as ModalConfig; - this.inputs[0].text = (args[1] as PlayerPokemon).getNameToRender(false); - + if (args[1] && typeof (args[1] as PlayerPokemon).getNameToRender === "function") { + this.inputs[0].text = (args[1] as PlayerPokemon).getNameToRender(false); + } else { + this.inputs[0].text = args[1]; + } this.submitAction = (_) => { this.sanitizeInputs(); - // const onFail = () => { - // this.scene.ui.setModeWithoutClear(Mode.RENAME_POKEMON, Object.assign(config)); - // this.scene.ui.playError(); - // }; - // if (!this.inputs[0].text) { - // return onFail(); - // } const sanitizedName = btoa(unescape(encodeURIComponent(this.inputs[0].text))); config.buttonActions[0](sanitizedName); return true; diff --git a/src/ui/starter-container.ts b/src/ui/starter-container.ts index ae589d138b9..ce21d13add8 100644 --- a/src/ui/starter-container.ts +++ b/src/ui/starter-container.ts @@ -10,6 +10,7 @@ export class StarterContainer extends Phaser.GameObjects.Container { public label: Phaser.GameObjects.Text; public starterPassiveBgs: Phaser.GameObjects.Image; public hiddenAbilityIcon: Phaser.GameObjects.Image; + public favoriteIcon: Phaser.GameObjects.Image; public classicWinIcon: Phaser.GameObjects.Image; public candyUpgradeIcon: Phaser.GameObjects.Image; public candyUpgradeOverlayIcon: Phaser.GameObjects.Image; @@ -66,8 +67,16 @@ export class StarterContainer extends Phaser.GameObjects.Container { this.add(abilityIcon); this.hiddenAbilityIcon = abilityIcon; + // favorite icon + const favoriteIcon = this.scene.add.image(0, 7, "favorite"); + favoriteIcon.setOrigin(0, 0); + favoriteIcon.setScale(0.5); + favoriteIcon.setVisible(false); + this.add(favoriteIcon); + this.favoriteIcon = favoriteIcon; + // classic win icon - const classicWinIcon = this.scene.add.image(2, 12, "champion_ribbon"); + const classicWinIcon = this.scene.add.image(0, 12, "champion_ribbon"); classicWinIcon.setOrigin(0, 0); classicWinIcon.setScale(0.5); classicWinIcon.setVisible(false); diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 447f5c95e46..d65abf70134 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -55,6 +55,7 @@ export interface Starter { nature: Nature; moveset?: StarterMoveset; pokerus: boolean; + nickname?: string; } interface LanguageSetting { @@ -70,8 +71,9 @@ const languageSettings: { [key: string]: LanguageSetting } = { instructionTextSize: "38px", }, "de":{ - starterInfoTextSize: "56px", + starterInfoTextSize: "48px", instructionTextSize: "35px", + starterInfoXPos: 33, }, "es":{ starterInfoTextSize: "56px", @@ -79,7 +81,7 @@ const languageSettings: { [key: string]: LanguageSetting } = { }, "fr":{ starterInfoTextSize: "54px", - instructionTextSize: "42px", + instructionTextSize: "35px", }, "it":{ starterInfoTextSize: "56px", @@ -91,9 +93,10 @@ const languageSettings: { [key: string]: LanguageSetting } = { starterInfoXPos: 33, }, "zh":{ - starterInfoTextSize: "40px", - instructionTextSize: "42px", - starterInfoYOffset: 2 + starterInfoTextSize: "47px", + instructionTextSize: "38px", + starterInfoYOffset: 1, + starterInfoXPos: 24, }, "pt":{ starterInfoTextSize: "48px", @@ -258,18 +261,21 @@ export default class StarterSelectUiHandler extends MessageUiHandler { private pokemonShinyIcon: Phaser.GameObjects.Sprite; private instructionsContainer: Phaser.GameObjects.Container; + private filterInstructionsContainer: Phaser.GameObjects.Container; private shinyIconElement: Phaser.GameObjects.Sprite; private formIconElement: Phaser.GameObjects.Sprite; private abilityIconElement: Phaser.GameObjects.Sprite; private genderIconElement: Phaser.GameObjects.Sprite; private natureIconElement: Phaser.GameObjects.Sprite; private variantIconElement: Phaser.GameObjects.Sprite; + private goFilterIconElement: Phaser.GameObjects.Sprite; private shinyLabel: Phaser.GameObjects.Text; private formLabel: Phaser.GameObjects.Text; private genderLabel: Phaser.GameObjects.Text; private abilityLabel: Phaser.GameObjects.Text; private natureLabel: Phaser.GameObjects.Text; private variantLabel: Phaser.GameObjects.Text; + private goFilterLabel: Phaser.GameObjects.Text; private starterSelectMessageBox: Phaser.GameObjects.NineSlice; private starterSelectMessageBoxContainer: Phaser.GameObjects.Container; @@ -329,7 +335,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { //variables to keep track of the dynamically rendered list of instruction prompts for starter select private instructionRowX = 0; private instructionRowY = 0; - private instructionRowTextOffset = 12; + private instructionRowTextOffset = 9; + private filterInstructionRowX = 0; + private filterInstructionRowY = 0; private starterSelectCallback: StarterSelectCallback | null; @@ -454,6 +462,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.filterBar.addFilter(DropDownColumn.UNLOCKS, i18next.t("filterBar:unlocksFilter"), new DropDown(this.scene, 0, 0, unlocksOptions, this.updateStarters, DropDownType.RADIAL)); // misc filter + const favoriteLabels = [ + new DropDownLabel(i18next.t("filterBar:favorite"), undefined, DropDownState.OFF), + new DropDownLabel(i18next.t("filterBar:isFavorite"), undefined, DropDownState.ON), + new DropDownLabel(i18next.t("filterBar:notFavorite"), undefined, DropDownState.EXCLUDE), + ]; const winLabels = [ new DropDownLabel(i18next.t("filterBar:ribbon"), undefined, DropDownState.OFF), new DropDownLabel(i18next.t("filterBar:hasWon"), undefined, DropDownState.ON), @@ -469,6 +482,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { new DropDownLabel(i18next.t("filterBar:hasPokerus"), undefined, DropDownState.ON), ]; const miscOptions = [ + new DropDownOption(this.scene, "FAVORITE", favoriteLabels), new DropDownOption(this.scene, "WIN", winLabels), new DropDownOption(this.scene, "HIDDEN_ABILITY", hiddenAbilityLabels), new DropDownOption(this.scene, "POKERUS", pokerusLabels), @@ -825,8 +839,19 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.variantLabel = addTextObject(this.scene, this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleVariant"), TextStyle.PARTY, { fontSize: instructionTextSize }); this.variantLabel.setName("text-variant-label"); + this.goFilterIconElement = new Phaser.GameObjects.Sprite(this.scene, this.filterInstructionRowX, this.filterInstructionRowY, "keyboard", "C.png"); + this.goFilterIconElement.setName("sprite-goFilter-icon-element"); + this.goFilterIconElement.setScale(0.675); + this.goFilterIconElement.setOrigin(0.0, 0.0); + this.goFilterLabel = addTextObject(this.scene, this.filterInstructionRowX + this.instructionRowTextOffset, this.filterInstructionRowY, i18next.t("starterSelectUiHandler:goFilter"), TextStyle.PARTY, { fontSize: instructionTextSize }); + this.goFilterLabel.setName("text-goFilter-label"); + this.hideInstructions(); + this.filterInstructionsContainer = this.scene.add.container(50, 5); + this.filterInstructionsContainer.setVisible(true); + this.starterSelectContainer.add(this.filterInstructionsContainer); + this.starterSelectMessageBoxContainer = this.scene.add.container(0, this.scene.game.canvas.height / 6); this.starterSelectMessageBoxContainer.setVisible(false); this.starterSelectContainer.add(this.starterSelectMessageBoxContainer); @@ -910,6 +935,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.allSpecies.forEach((species, s) => { const icon = this.starterContainers[s].icon; const dexEntry = this.scene.gameData.dexData[species.speciesId]; + this.starterPreferences[species.speciesId] = this.starterPreferences[species.speciesId] ?? {}; if (dexEntry.caughtAttr) { icon.clearTint(); @@ -1175,6 +1201,16 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.tryExit(); success = true; } + } else if (button === Button.STATS) { + // if stats button is pressed, go to filter directly + if (!this.filterMode) { + this.startCursorObj.setVisible(false); + this.starterIconsCursorObj.setVisible(false); + this.setSpecies(null); + this.filterBarCursor = 0; + this.setFilterMode(true); + this.filterBar.toggleDropDown(this.filterBarCursor); + } } else if (this.startCursorObj.visible) { // this checks to see if the start button is selected switch (button) { case Button.ACTION: @@ -1303,11 +1339,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const isPartyValid = this.isPartyValid(); const isValidForChallenge = new Utils.BooleanHolder(true); - if (isPartyValid) { - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true)), this.starterSpecies.length !== 0); - } else { - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true)), this.starterSpecies.length !== 0, false, false); - } + + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), isPartyValid); const currentPartyValue = this.starterSpecies.map(s => s.generation).reduce((total: number, gen: number, i: number) => total += this.scene.gameData.getSpeciesStarterValue(this.starterSpecies[i].speciesId), 0); const newCost = this.scene.gameData.getSpeciesStarterValue(species.speciesId); @@ -1517,6 +1550,56 @@ export default class StarterSelectUiHandler extends MessageUiHandler { }); } } + // if container.favorite is false, show the favorite option + const isFavorite = starterAttributes?.favorite ?? false; + if (!isFavorite) { + options.push({ + label: i18next.t("starterSelectUiHandler:addToFavorites"), + handler: () => { + starterAttributes.favorite = true; + starterContainer.favoriteIcon.setVisible(starterAttributes.favorite); + ui.setMode(Mode.STARTER_SELECT); + return true; + } + }); + } else { + options.push({ + label: i18next.t("starterSelectUiHandler:removeFromFavorites"), + handler: () => { + starterAttributes.favorite = false; + starterContainer.favoriteIcon.setVisible(starterAttributes.favorite); + ui.setMode(Mode.STARTER_SELECT); + return true; + } + }); + } + options.push({ + label: i18next.t("menu:rename"), + handler: () => { + ui.playSelect(); + let nickname = starterAttributes.nickname ? String(starterAttributes.nickname) : ""; + nickname = decodeURIComponent(escape(atob(nickname))); + ui.setModeWithoutClear(Mode.RENAME_POKEMON, { + buttonActions: [ + (sanitizedName: string) => { + ui.playSelect(); + starterAttributes.nickname = sanitizedName; + const name = decodeURIComponent(escape(atob(starterAttributes.nickname))); + if (name.length > 0) { + this.pokemonNameText.setText(name); + } else { + this.pokemonNameText.setText(species.name); + } + ui.setMode(Mode.STARTER_SELECT); + }, + () => { + ui.setMode(Mode.STARTER_SELECT); + } + ] + }, nickname); + return true; + } + }); const showUseCandies = () => { // this lets you use your candies const options: any[] = []; // TODO: add proper type if (!(passiveAttr & PassiveAttr.UNLOCKED)) { @@ -1661,7 +1744,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { success = true; } } else { - const props = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.dexAttrCursor); + const props = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.getCurrentDexProps(this.lastSpecies.speciesId)); // prepare persistent starter data to store changes let starterAttributes = this.starterPreferences[this.lastSpecies.speciesId]; if (!starterAttributes) { @@ -1671,8 +1754,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { case Button.CYCLE_SHINY: if (this.canCycleShiny) { const newVariant = props.variant; + starterAttributes.shiny = starterAttributes.shiny ? !starterAttributes.shiny : true; this.setSpeciesDetails(this.lastSpecies, !props.shiny, undefined, undefined, props.shiny ? 0 : undefined, undefined, undefined); - if (this.dexAttrCursor & DexAttr.SHINY) { + if (starterAttributes.shiny) { this.scene.playSound("sparkle"); // Set the variant label to the shiny tint const tint = getVariantTint(newVariant); @@ -1680,6 +1764,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonShinyIcon.setTint(tint); this.pokemonShinyIcon.setVisible(true); } else { + // starterAttributes.variant = 0; + if (starterAttributes?.variant) { + delete starterAttributes.variant; + } this.pokemonShinyIcon.setVisible(false); success = true; } @@ -1948,6 +2036,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.updateInstructions(); } + updatePartyIcon(species: PokemonSpecies, index: number) { + const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)); + this.starterIcons[index].setTexture(species.getIconAtlasKey(props.formIndex, props.shiny, props.variant)); + this.starterIcons[index].setFrame(species.getIconId(props.female, props.formIndex, props.shiny, props.variant)); + this.checkIconId(this.starterIcons[index], species, props.female, props.formIndex, props.shiny, props.variant); + } + switchMoveHandler(i: number, newMove: Moves, move: Moves) { const speciesId = this.lastSpecies.speciesId; const existingMoveIndex = this.starterMoveset?.indexOf(newMove)!; // TODO: is this bang correct? @@ -2017,6 +2112,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { case SettingKeyboard.Button_Cycle_Variant: iconPath = "V.png"; break; + case SettingKeyboard.Button_Stats: + iconPath = "C.png"; + break; default: break; } @@ -2036,11 +2134,36 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } } + updateFilterButtonIcon(iconSetting, gamepadType, iconElement, controlLabel): void { + let iconPath; + // touch controls cannot be rebound as is, and are just emulating a keyboard event. + // Additionally, since keyboard controls can be rebound (and will be displayed when they are), we need to have special handling for the touch controls + if (gamepadType === "touch") { + gamepadType = "keyboard"; + iconPath = "C.png"; + } else { + iconPath = this.scene.inputController?.getIconForLatestInputRecorded(iconSetting); + } + iconElement.setTexture(gamepadType, iconPath); + iconElement.setPosition(this.filterInstructionRowX, this.filterInstructionRowY); + controlLabel.setPosition(this.filterInstructionRowX + this.instructionRowTextOffset, this.filterInstructionRowY); + iconElement.setVisible(true); + controlLabel.setVisible(true); + this.filterInstructionsContainer.add([iconElement, controlLabel]); + this.filterInstructionRowY += 8; + if (this.filterInstructionRowY >= 24) { + this.filterInstructionRowY = 0; + this.filterInstructionRowX += 50; + } + } updateInstructions(): void { this.instructionRowX = 0; this.instructionRowY = 0; + this.filterInstructionRowX = 0; + this.filterInstructionRowY = 0; this.hideInstructions(); this.instructionsContainer.removeAll(); + this.filterInstructionsContainer.removeAll(); let gamepadType; if (this.scene.inputMethod === "gamepad") { gamepadType = this.scene.inputController.getConfig(this.scene.inputController.selectedDevice[Device.GAMEPAD]).padType; @@ -2048,6 +2171,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { gamepadType = this.scene.inputMethod; } + if (!gamepadType) { + return; + } + if (this.speciesStarterDexEntry?.caughtAttr) { if (this.canCycleShiny) { this.updateButtonIcon(SettingKeyboard.Button_Cycle_Shiny, gamepadType, this.shinyIconElement, this.shinyLabel); @@ -2068,6 +2195,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.updateButtonIcon(SettingKeyboard.Button_Cycle_Variant, gamepadType, this.variantIconElement, this.variantLabel); } } + + // if filter mode is inactivated and gamepadType is not undefined, update the button icons + if (!this.filterMode) { + this.updateFilterButtonIcon(SettingKeyboard.Button_Stats, gamepadType, this.goFilterIconElement, this.goFilterLabel); + } + } getValueLimit(): integer { @@ -2099,9 +2232,24 @@ export default class StarterSelectUiHandler extends MessageUiHandler { // pre filter for challenges if (this.scene.gameMode.modeId === GameModes.CHALLENGE) { this.starterContainers.forEach(container => { - const isValidForChallenge = new Utils.BooleanHolder(true); - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, container.species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(container.species, this.scene.gameData.getSpeciesDefaultDexAttr(container.species, false, true)), true); - if (isValidForChallenge.value) { + const species = container.species; + let allFormsValid = false; + if (species.forms?.length > 0) { + for (let i = 0; i < species.forms.length; i++) { + /* Here we are making a fake form index dex props for challenges + * Since some pokemon rely on forms to be valid (i.e. blaze tauros for fire challenges), we make a fake form and dex props to use in the challenge + */ + const tempFormProps = BigInt(Math.pow(2, i)) * DexAttr.DEFAULT_FORM; + const isValidForChallenge = new Utils.BooleanHolder(true); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, container.species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, tempFormProps), true); + allFormsValid = allFormsValid || isValidForChallenge.value; + } + } else { + const isValidForChallenge = new Utils.BooleanHolder(true); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, container.species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.scene.gameData.getSpeciesDefaultDexAttr(container.species, false, true)), true); + allFormsValid = isValidForChallenge.value; + } + if (allFormsValid) { this.validStarterContainers.push(container); } else { container.setVisible(false); @@ -2111,6 +2259,18 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.validStarterContainers = this.starterContainers; } + // this updates icons for previously saved pokemon + for (let i = 0; i < this.validStarterContainers.length; i++) { + const currentFilteredContainer = this.validStarterContainers[i]; + const starterSprite = currentFilteredContainer.icon as Phaser.GameObjects.Sprite; + + const currentDexAttr = this.getCurrentDexProps(currentFilteredContainer.species.speciesId); + const props = this.scene.gameData.getSpeciesDexAttrProps(currentFilteredContainer.species, currentDexAttr); + + starterSprite.setTexture(currentFilteredContainer.species.getIconAtlasKey(props.formIndex, props.shiny, props.variant), currentFilteredContainer.species.getIconId(props.female!, props.formIndex, props.shiny, props.variant)); + currentFilteredContainer.checkIconId(props.female, props.formIndex, props.shiny, props.variant); + } + // filter this.validStarterContainers.forEach(container => { container.setVisible(false); @@ -2128,6 +2288,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const isUncaught = !isCaught && !isVariantCaught && !isVariant2Caught && !isVariant3Caught; const isPassiveUnlocked = this.scene.gameData.starterData[container.species.speciesId].passiveAttr > 0; const isCostReduced = this.scene.gameData.starterData[container.species.speciesId].valueReduction > 0; + const isFavorite = this.starterPreferences[container.species.speciesId]?.favorite ?? false; + const isWin = this.scene.gameData.starterData[container.species.speciesId].classicWinCount > 0; const isNotWin = this.scene.gameData.starterData[container.species.speciesId].classicWinCount === 0; const isUndefined = this.scene.gameData.starterData[container.species.speciesId].classicWinCount === undefined; @@ -2171,6 +2333,18 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } }); + const fitsFavorite = this.filterBar.getVals(DropDownColumn.MISC).some(misc => { + if (misc.val === "FAVORITE" && misc.state === DropDownState.ON) { + return isFavorite; + } + if (misc.val === "FAVORITE" && misc.state === DropDownState.EXCLUDE) { + return !isFavorite; + } + if (misc.val === "FAVORITE" && misc.state === DropDownState.OFF) { + return true; + } + }); + const fitsWin = this.filterBar.getVals(DropDownColumn.MISC).some(misc => { if (container.species.speciesId < 10) { } @@ -2203,7 +2377,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } }); - if (fitsGen && fitsType && fitsCaught && fitsPassive && fitsCostReduction && fitsWin && fitsHA && fitsPokerus) { + if (fitsGen && fitsType && fitsCaught && fitsPassive && fitsCostReduction && fitsFavorite && fitsWin && fitsHA && fitsPokerus) { this.filteredStarterContainers.push(container); } }); @@ -2296,6 +2470,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { container.starterPassiveBgs.setVisible(!!this.scene.gameData.starterData[speciesId].passiveAttr); container.hiddenAbilityIcon.setVisible(!!this.scene.gameData.dexData[speciesId].caughtAttr && !!(this.scene.gameData.starterData[speciesId].abilityAttr & 4)); container.classicWinIcon.setVisible(this.scene.gameData.starterData[speciesId].classicWinCount > 0); + container.favoriteIcon.setVisible(this.starterPreferences[speciesId]?.favorite ?? false); // 'Candy Icon' mode if (this.scene.candyUpgradeDisplay === 0) { @@ -2336,9 +2511,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const species = this.filteredStarterContainers[cursor]?.species; if (species) { - const defaultDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true); + const defaultDexAttr = this.getCurrentDexProps(species.speciesId); const defaultProps = this.scene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr); - const variant = defaultProps.variant; + const variant = this.starterPreferences[species.speciesId]?.variant ? this.starterPreferences[species.speciesId].variant as Variant : defaultProps.variant; const tint = getVariantTint(variant); this.pokemonShinyIcon.setFrame(getVariantIcon(variant)); this.pokemonShinyIcon.setTint(tint); @@ -2362,6 +2537,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.setCursor(filterMode ? this.filterBarCursor : this.cursor); if (filterMode) { this.setSpecies(null); + this.updateInstructions(); } return true; @@ -2384,7 +2560,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { setSpecies(species: PokemonSpecies | null) { this.speciesStarterDexEntry = species ? this.scene.gameData.dexData[species.speciesId] : null; - this.dexAttrCursor = species ? this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true) : 0n; + this.dexAttrCursor = species ? this.getCurrentDexProps(species.speciesId) : 0n; this.abilityCursor = species ? this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species) : 0; this.natureCursor = species ? this.scene.gameData.getSpeciesDefaultNature(species) : 0; @@ -2454,7 +2630,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } if (this.lastSpecies) { - const dexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(this.lastSpecies, false, true); + const dexAttr = this.getCurrentDexProps(this.lastSpecies.speciesId); const props = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, dexAttr); const speciesIndex = this.allSpecies.indexOf(this.lastSpecies); const lastSpeciesIcon = this.starterContainers[speciesIndex].icon; @@ -2470,7 +2646,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (species && (this.speciesStarterDexEntry?.seenAttr || this.speciesStarterDexEntry?.caughtAttr)) { this.pokemonNumberText.setText(Utils.padInt(species.speciesId, 4)); - this.pokemonNameText.setText(species.name); + if (starterAttributes?.nickname) { + const name = decodeURIComponent(escape(atob(starterAttributes.nickname))); + this.pokemonNameText.setText(name); + } else { + this.pokemonNameText.setText(species.name); + } if (this.speciesStarterDexEntry?.caughtAttr) { const colorScheme = starterColors[species.speciesId]; @@ -2480,7 +2661,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonLuckText.setText(luck.toString()); this.pokemonLuckText.setTint(getVariantTint(Math.min(luck - 1, 2) as Variant)); this.pokemonLuckLabelText.setVisible(this.pokemonLuckText.visible); - this.pokemonShinyIcon.setVisible(this.pokemonLuckText.visible); + this.pokemonShinyIcon.setVisible(this.starterPreferences[species.speciesId]?.shiny ?? false); //Growth translate let growthReadable = Utils.toReadableString(GrowthRate[species.growthRate]); @@ -2504,7 +2685,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonHatchedIcon.setFrame(getEggTierForSpecies(species)); } this.pokemonHatchedCountText.setText(`${this.speciesStarterDexEntry.hatchedCount}`); - const defaultDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true); + const defaultDexAttr = this.getCurrentDexProps(species.speciesId); const defaultProps = this.scene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr); const variant = defaultProps.variant; const tint = getVariantTint(variant); @@ -2578,13 +2759,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler { props = this.scene.gameData.getSpeciesDexAttrProps(species, this.starterAttr[starterIndex]); this.setSpeciesDetails(species, props.shiny, props.formIndex, props.female, props.variant, this.starterAbilityIndexes[starterIndex], this.starterNatures[starterIndex]); } else { - const defaultDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true); + const defaultDexAttr = this.getCurrentDexProps(species.speciesId); const defaultAbilityIndex = starterAttributes?.ability ?? this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species); // load default nature from stater save data, if set const defaultNature = starterAttributes?.nature || this.scene.gameData.getSpeciesDefaultNature(species); props = this.scene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr); if (starterAttributes?.variant && !isNaN(starterAttributes.variant)) { - if (props.shiny = (starterAttributes.variant >= 0)) { + if (props.shiny) { props.variant = starterAttributes.variant as Variant; } } @@ -2679,6 +2860,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.dexAttrCursor |= this.scene.gameData.getFormAttr(formIndex !== undefined ? formIndex : (formIndex = oldProps!.formIndex)); // TODO: is this bang correct? this.abilityCursor = abilityIndex !== undefined ? abilityIndex : (abilityIndex = oldAbilityIndex); this.natureCursor = natureIndex !== undefined ? natureIndex : (natureIndex = oldNatureIndex); + const [isInParty, partyIndex]: [boolean, number] = this.isInParty(species); // we use this to firstly check if the pokemon is in the party, and if so, to get the party index in order to update the icon image + if (isInParty) { + this.updatePartyIcon(species, partyIndex); + } } this.pokemonSprite.setVisible(false); @@ -2695,7 +2880,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const dexEntry = this.scene.gameData.dexData[species.speciesId]; const abilityAttr = this.scene.gameData.starterData[species.speciesId].abilityAttr; if (!dexEntry.caughtAttr) { - const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.scene.gameData.getSpeciesDefaultDexAttr(species, forSeen, !forSeen)); + const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)); const defaultAbilityIndex = this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species); const defaultNature = this.scene.gameData.getSpeciesDefaultNature(species); if (shiny === undefined || shiny !== props.shiny) { @@ -2750,9 +2935,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const isValidForChallenge = new Utils.BooleanHolder(true); Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor), !!this.starterSpecies.length); - const starterSprite = this.filteredStarterContainers[this.cursor].icon as Phaser.GameObjects.Sprite; - starterSprite.setTexture(species.getIconAtlasKey(formIndex, shiny, variant), species.getIconId(female!, formIndex, shiny, variant)); // TODO: is this bang correct? - this.filteredStarterContainers[this.cursor].checkIconId(female, formIndex, shiny, variant); + const currentFilteredContainer = this.filteredStarterContainers.find(p => p.species.speciesId === species.speciesId)!; + const starterSprite = currentFilteredContainer.icon as Phaser.GameObjects.Sprite; + starterSprite.setTexture(species.getIconAtlasKey(formIndex, shiny, variant), species.getIconId(female!, formIndex, shiny, variant)); + currentFilteredContainer.checkIconId(female, formIndex, shiny, variant); this.canCycleShiny = !!(dexEntry.caughtAttr & DexAttr.NON_SHINY && dexEntry.caughtAttr & DexAttr.SHINY); this.canCycleGender = !!(dexEntry.caughtAttr & DexAttr.MALE && dexEntry.caughtAttr & DexAttr.FEMALE); this.canCycleAbility = [ abilityAttr & AbilityAttr.ABILITY_1, (abilityAttr & AbilityAttr.ABILITY_2) && species.ability2, abilityAttr & AbilityAttr.ABILITY_HIDDEN ].filter(a => a).length > 1; @@ -2876,6 +3062,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonAdditionalMoveCountLabel.setText(`(+${Math.max(this.speciesStarterMoves.length - 4, 0)})`); this.pokemonAdditionalMoveCountLabel.setVisible(this.speciesStarterMoves.length > 4); + this.tryUpdateValue(); + this.updateInstructions(); } @@ -2903,7 +3091,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { for (let s = 0; s < this.starterSpecies.length; s++) { const species = this.starterSpecies[s]; - const currentDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true); + const currentDexAttr = this.getCurrentDexProps(species.speciesId); const props = this.scene.gameData.getSpeciesDexAttrProps(species, currentDexAttr); this.starterIcons[s].setTexture(species.getIconAtlasKey(props.formIndex, props.shiny, props.variant)); this.starterIcons[s].setFrame(species.getIconId(props.female, props.formIndex, props.shiny, props.variant)); @@ -2984,7 +3172,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (addingToParty) { // this does a check to see if the pokemon being added is valid; if so, it will update the isPartyValid boolean const isNewPokemonValid = new Utils.BooleanHolder(true); const species = this.filteredStarterContainers[this.cursor].species; - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isNewPokemonValid, this.scene.gameData.getSpeciesDexAttrProps(species, this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true)), !!(this.starterSpecies.length), false, false); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isNewPokemonValid, this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), false); isPartyValid = isPartyValid || isNewPokemonValid.value; } @@ -3013,11 +3201,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { * we change to can AddParty value to true since the user has enough cost to choose this pokemon and this pokemon registered too. */ const isValidForChallenge = new Utils.BooleanHolder(true); - if (isPartyValid) { // we have two checks here - one for the party being valid and one for not. This comes from mono type challenges - if the party is valid it will check pokemon's evolutions and forms, and if it's not valid it won't check their evolutions and forms - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, this.allSpecies[s], isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(this.allSpecies[s], this.scene.gameData.getSpeciesDefaultDexAttr(this.allSpecies[s], false, true)), !!(this.starterSpecies.length + (add ? 1 : 0))); - } else { - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, this.allSpecies[s], isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(this.allSpecies[s], this.scene.gameData.getSpeciesDefaultDexAttr(this.allSpecies[s], false, true)), !!(this.starterSpecies.length + (add ? 1 : 0)), false, false); - } + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, this.allSpecies[s], isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(this.allSpecies[s], this.getCurrentDexProps(this.allSpecies[s].speciesId)), isPartyValid); const canBeChosen = remainValue >= speciesStarterValue && isValidForChallenge.value; @@ -3109,7 +3293,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { passive: !(thisObj.scene.gameData.starterData[starterSpecies.speciesId].passiveAttr ^ (PassiveAttr.ENABLED | PassiveAttr.UNLOCKED)), nature: thisObj.starterNatures[i] as Nature, moveset: thisObj.starterMovesets[i], - pokerus: thisObj.pokerusSpecies.includes(starterSpecies) + pokerus: thisObj.pokerusSpecies.includes(starterSpecies), + nickname: thisObj.starterPreferences[starterSpecies.speciesId]?.nickname, }; })); }; @@ -3132,12 +3317,50 @@ export default class StarterSelectUiHandler extends MessageUiHandler { for (let s = 0; s < this.starterSpecies.length; s++) { const isValidForChallenge = new Utils.BooleanHolder(true); const species = this.starterSpecies[s]; - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor), this.starterSpecies.length !== 0, false, false); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), false); canStart = canStart || isValidForChallenge.value; } return canStart; } + /* this creates a temporary dex attr props that we use to check whether a pokemon is valid for a challenge. + * when checking for certain challenges (i.e. mono type), we need to check for form changes AND evolutions + * However, since some pokemon can evolve based on their intial gender/form, we need a way to look for that + * This temporary dex attr will therefore ONLY look at gender and form, since there's no cases of shinies/variants + * having different evolutions to their non shiny/variant part, and so those can be ignored + * Since the current form and gender is stored in the starter preferences, this is where we get the values from + */ + getCurrentDexProps(speciesId: number): bigint { + let props = 0n; + + if (this.starterPreferences[speciesId]?.female) { // this checks the gender of the pokemon + props += DexAttr.FEMALE; + } else { + props += DexAttr.MALE; + } + if (this.starterPreferences[speciesId]?.shiny) { + props += DexAttr.SHINY; + if (this.starterPreferences[speciesId]?.variant) { + props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.variant)) * DexAttr.DEFAULT_VARIANT; + } else { + props += DexAttr.DEFAULT_VARIANT; + } + } else { + props += DexAttr.NON_SHINY; + if (this.starterPreferences[speciesId]?.variant) { + delete this.starterPreferences[speciesId].variant; + } + props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant + } + if (this.starterPreferences[speciesId]?.form) { // this checks for the form of the pokemon + props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.form)) * DexAttr.DEFAULT_FORM; + } else { + props += DexAttr.DEFAULT_FORM; + } + + return props; + } + toggleStatsMode(on?: boolean): void { if (on === undefined) { on = !this.statsMode; @@ -3183,6 +3406,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.natureLabel.setVisible(false); this.variantIconElement.setVisible(false); this.variantLabel.setVisible(false); + this.goFilterIconElement.setVisible(false); + this.goFilterLabel.setVisible(false); } clear(): void {